diff --git a/logic/Client/MainWindow.xaml.cs b/logic/Client/MainWindow.xaml.cs
index 5c1f95c..3b2bd82 100644
--- a/logic/Client/MainWindow.xaml.cs
+++ b/logic/Client/MainWindow.xaml.cs
@@ -976,7 +976,7 @@ namespace Client
MoveMsg msgW = new()
{
PlayerId = playerID,
- TimeInMilliseconds = 50,
+ TimeInMilliseconds = 25,
Angle = Math.PI
};
client.Move(msgW);
@@ -986,7 +986,7 @@ namespace Client
MoveMsg msgS = new()
{
PlayerId = playerID,
- TimeInMilliseconds = 50,
+ TimeInMilliseconds = 25,
Angle = 0
};
client.Move(msgS);
@@ -996,7 +996,7 @@ namespace Client
MoveMsg msgD = new()
{
PlayerId = playerID,
- TimeInMilliseconds = 50,
+ TimeInMilliseconds = 25,
Angle = Math.PI / 2
};
client.Move(msgD);
@@ -1006,7 +1006,7 @@ namespace Client
MoveMsg msgA = new()
{
PlayerId = playerID,
- TimeInMilliseconds = 50,
+ TimeInMilliseconds = 25,
Angle = 3 * Math.PI / 2
};
client.Move(msgA);
diff --git a/logic/GameClass/GameObj/Character/Character.Student.cs b/logic/GameClass/GameObj/Character/Character.Student.cs
index c52a98e..4606393 100644
--- a/logic/GameClass/GameObj/Character/Character.Student.cs
+++ b/logic/GameClass/GameObj/Character/Character.Student.cs
@@ -6,69 +6,6 @@ namespace GameClass.GameObj
{
public class Student : Character
{
- ///
- /// 遭受攻击
- ///
- ///
- ///
- /// 伤害来源
- /// 人物在受到攻击后死了吗
- public bool BeAttacked(Bullet bullet)
- {
-#if DEBUG
- Debugger.Output(this, "is being shot!");
-#endif
- lock (beAttackedLock)
- {
- if (hp <= 0 || NoHp())
- return false; // 原来已经死了
- if (bullet.Parent.IsGhost() != this.IsGhost())
- {
-#if DEBUG
- Debugger.Output(bullet, " 's AP is " + bullet.AP.ToString());
-#endif
- if (TryUseShield())
- {
- if (bullet.HasSpear)
- {
- int subHp = TrySubHp(bullet.AP);
-#if DEBUG
- Debugger.Output(this, "is being shot! Now his hp is" + HP.ToString());
-#endif
- bullet.Parent.AddScore(GameData.TrickerScoreAttackStudent(subHp) + GameData.ScorePropUseSpear);
- bullet.Parent.HP = (int)(bullet.Parent.HP + (bullet.Parent.Vampire * subHp));
- }
- else
- return false;
- }
- else
- {
- int subHp;
- if (bullet.HasSpear)
- {
- subHp = TrySubHp(bullet.AP + GameData.ApSpearAdd);
-#if DEBUG
- Debugger.Output(this, "is being shot with Spear! Now his hp is" + HP.ToString());
-#endif
- }
- else
- {
- subHp = TrySubHp(bullet.AP);
-#if DEBUG
- Debugger.Output(this, "is being shot! Now his hp is" + HP.ToString());
-#endif
- }
- bullet.Parent.AddScore(GameData.TrickerScoreAttackStudent(subHp));
- bullet.Parent.HP = (int)(bullet.Parent.HP + (bullet.Parent.Vampire * subHp));
- }
-
- if (hp <= 0)
- TryActivatingLIFE(); // 如果有复活甲
- }
- return hp <= 0;
- }
- }
-
protected int fixSpeed;
///
/// 修理电机速度
diff --git a/logic/GameClass/GameObj/Character/Character.cs b/logic/GameClass/GameObj/Character/Character.cs
index b00d95f..65de726 100644
--- a/logic/GameClass/GameObj/Character/Character.cs
+++ b/logic/GameClass/GameObj/Character/Character.cs
@@ -541,7 +541,7 @@ namespace GameClass.GameObj
return false;
}
}
- protected void TryActivatingLIFE()
+ public void TryActivatingLIFE()
{
if (buffManager.TryActivatingLIFE())
{
diff --git a/logic/Gaming/ActionManager.cs b/logic/Gaming/ActionManager.cs
index 017e26c..ac4bed8 100644
--- a/logic/Gaming/ActionManager.cs
+++ b/logic/Gaming/ActionManager.cs
@@ -164,7 +164,7 @@ namespace Gaming
{
if (!(player.Commandable()) || player.CharacterType == CharacterType.Robot)
return false;
- Doorway? doorwayForEscape = (Doorway?)gameMap.OneForInteractInACross(player.Position, GameObjType.Doorway);
+ Doorway? doorwayForEscape = (Doorway?)gameMap.OneForInteract(player.Position, GameObjType.Doorway);
if (doorwayForEscape != null && doorwayForEscape.IsOpen())
{
player.AddScore(GameData.StudentScoreEscape);
@@ -174,7 +174,7 @@ namespace Gaming
}
else
{
- EmergencyExit? emergencyExit = (EmergencyExit?)gameMap.OneForInteractInACross(player.Position, GameObjType.EmergencyExit);
+ EmergencyExit? emergencyExit = (EmergencyExit?)gameMap.OneForInteract(player.Position, GameObjType.EmergencyExit);
if (emergencyExit != null && emergencyExit.IsOpen)
{
++gameMap.NumOfEscapedStudent;
@@ -353,12 +353,23 @@ namespace Gaming
if (windowForClimb == null || windowForClimb.WhoIsClimbing != null)
return false;
+ XY windowToPlayer = new(
+ (Math.Abs(player.Position.x - windowForClimb.Position.x) > GameData.numOfPosGridPerCell / 2) ? (GameData.numOfPosGridPerCell / 2 * (player.Position.x > windowForClimb.Position.x ? 1 : -1)) : 0,
+ (Math.Abs(player.Position.y - windowForClimb.Position.y) > GameData.numOfPosGridPerCell / 2) ? (GameData.numOfPosGridPerCell / 2 * (player.Position.y > windowForClimb.Position.y ? 1 : -1)) : 0);
+
+ Character? characterInWindow = (Character?)gameMap.OneInTheSameCell(windowForClimb.Position - 2 * windowToPlayer, GameObjType.Character);
+ if (characterInWindow != null)
+ {
+ if (player.IsGhost() && !characterInWindow.IsGhost())
+ characterManager.BeAttacked((Student)(characterInWindow), player.Attack(characterInWindow.Position, PlaceType.Null));
+ return false;
+ }
+
+ Wall addWall = new Wall(windowForClimb.Position - 2 * windowToPlayer);
+ gameMap.Add(addWall);
+
player.PlayerState = PlayerStateType.ClimbingThroughWindows;
windowForClimb.WhoIsClimbing = player;
- XY windowToPlayer = new XY(
- (Math.Abs(player.Position.x - windowForClimb.Position.x) > GameData.numOfPosGridPerCell / 2) ? (GameData.numOfPosGridPerCell / 2 * (player.Position.x > windowForClimb.Position.x ? 1 : -1)) : 0,
- (Math.Abs(player.Position.y - windowForClimb.Position.y) > GameData.numOfPosGridPerCell / 2) ? (GameData.numOfPosGridPerCell / 2 * (player.Position.y > windowForClimb.Position.y ? 1 : -1)) : 0)
- ;
new Thread
(
() =>
@@ -396,6 +407,7 @@ namespace Gaming
player.ReSetPos(PosJumpOff, gameMap.GetPlaceType(PosJumpOff));
player.MoveSpeed = player.ReCalculateBuff(BuffType.AddSpeed, player.OrgMoveSpeed, GameData.MaxSpeed, GameData.MinSpeed);
windowForClimb.WhoIsClimbing = null;
+ gameMap.Remove(addWall);
if (player.PlayerState == PlayerStateType.ClimbingThroughWindows)
{
player.PlayerState = PlayerStateType.Null;
@@ -494,10 +506,12 @@ namespace Gaming
*/
private readonly Map gameMap;
+ private readonly CharacterManager characterManager;
public readonly MoveEngine moveEngine;
- public ActionManager(Map gameMap)
+ public ActionManager(Map gameMap, CharacterManager characterManager)
{
this.gameMap = gameMap;
+
this.moveEngine = new MoveEngine(
gameMap: gameMap,
OnCollision: (obj, collisionObj, moveVec) =>
@@ -516,6 +530,7 @@ namespace Gaming
// Debugger.Output(obj, " end move at " + obj.Position.ToString() + " At time: " + Environment.TickCount64);
}
);
+ this.characterManager = characterManager;
}
}
}
diff --git a/logic/Gaming/AttackManager.cs b/logic/Gaming/AttackManager.cs
index 01ca4f6..3e6b8e7 100644
--- a/logic/Gaming/AttackManager.cs
+++ b/logic/Gaming/AttackManager.cs
@@ -50,20 +50,7 @@ namespace Gaming
if ((!(((Character)objBeingShot).IsGhost())) && bullet.Parent.IsGhost())
{
- Student whoBeAttacked = (Student)objBeingShot;
- if (whoBeAttacked.CharacterType == CharacterType.StraightAStudent)
- {
- ((WriteAnswers)whoBeAttacked.FindIActiveSkill(ActiveSkillType.WriteAnswers)).DegreeOfMeditation = 0;
- }
- if (whoBeAttacked.BeAttacked(bullet))
- {
- characterManager.BeAddictedToGame(whoBeAttacked, (Ghost)bullet.Parent);
- }
- if (whoBeAttacked.CanBeAwed())
- {
- if (CharacterManager.BeStunned(whoBeAttacked, GameData.basicStunnedTimeOfStudent))
- bullet.Parent.AddScore(GameData.TrickerScoreStudentBeStunned(GameData.basicStunnedTimeOfStudent));
- }
+ characterManager.BeAttacked((Student)objBeingShot, bullet);
}
// if (((Character)objBeingShot).IsGhost() && !bullet.Parent.IsGhost() && bullet.TypeOfBullet == BulletType.Ram)
// BeStunned((Character)objBeingShot, bullet.AP);
diff --git a/logic/Gaming/CharacterManager .cs b/logic/Gaming/CharacterManager .cs
index b579e90..e877543 100644
--- a/logic/Gaming/CharacterManager .cs
+++ b/logic/Gaming/CharacterManager .cs
@@ -134,7 +134,7 @@ namespace Gaming
{
if (!noise && XY.Distance(newPlayer.Position, person.Position) <= (newPlayer.AlertnessRadius / person.Concealment))
newPlayer.AddBgm(BgmType.GhostIsComing, (double)newPlayer.AlertnessRadius / XY.Distance(newPlayer.Position, person.Position));
- if (XY.Distance(newPlayer.Position, person.Position) <= GameData.basicViewRange)
+ if (newPlayer.CharacterType != CharacterType.Teacher && XY.Distance(newPlayer.Position, person.Position) <= GameData.basicViewRange)
{
TimePinningDown += GameData.checkInterval;
newPlayer.AddScore(GameData.StudentScorePinDown(TimePinningDown) - ScoreAdded);
@@ -250,6 +250,81 @@ namespace Gaming
{ IsBackground = true }.Start();
return true;
}
+
+ public static bool TryBeAwed(Student character, Bullet bullet)
+ {
+ if (character.CanBeAwed())
+ {
+ if (BeStunned(character, GameData.basicStunnedTimeOfStudent))
+ bullet.Parent.AddScore(GameData.TrickerScoreStudentBeStunned(GameData.basicStunnedTimeOfStudent));
+ return true;
+ }
+ return false;
+ }
+
+ ///
+ /// 遭受攻击
+ ///
+ ///
+ ///
+ /// 伤害来源
+ /// 人物在受到攻击后死了吗
+ public void BeAttacked(Student student, Bullet bullet)
+ {
+#if DEBUG
+ Debugger.Output(student, "is being shot!");
+#endif
+ if (student.NoHp()) return; // 原来已经死了
+ if (!bullet.Parent.IsGhost()) return;
+
+ if (student.CharacterType == CharacterType.StraightAStudent)
+ {
+ ((WriteAnswers)student.FindIActiveSkill(ActiveSkillType.WriteAnswers)).DegreeOfMeditation = 0;
+ }
+#if DEBUG
+ Debugger.Output(bullet, " 's AP is " + bullet.AP.ToString());
+#endif
+ if (student.TryUseShield())
+ {
+ if (bullet.HasSpear)
+ {
+ int subHp = student.TrySubHp(bullet.AP);
+#if DEBUG
+ Debugger.Output(this, "is being shot! Now his hp is" + student.HP.ToString());
+#endif
+ bullet.Parent.AddScore(GameData.TrickerScoreAttackStudent(subHp) + GameData.ScorePropUseSpear);
+ bullet.Parent.HP = (int)(bullet.Parent.HP + (bullet.Parent.Vampire * subHp));
+ }
+ else return;
+ }
+ else
+ {
+ int subHp;
+ if (bullet.HasSpear)
+ {
+ subHp = student.TrySubHp(bullet.AP + GameData.ApSpearAdd);
+#if DEBUG
+ Debugger.Output(this, "is being shot with Spear! Now his hp is" + student.HP.ToString());
+#endif
+ }
+ else
+ {
+ subHp = student.TrySubHp(bullet.AP);
+#if DEBUG
+ Debugger.Output(this, "is being shot! Now his hp is" + student.HP.ToString());
+#endif
+ }
+ bullet.Parent.AddScore(GameData.TrickerScoreAttackStudent(subHp));
+ bullet.Parent.HP = (int)(bullet.Parent.HP + (bullet.Parent.Vampire * subHp));
+ }
+ if (student.HP <= 0)
+ student.TryActivatingLIFE(); // 如果有复活甲
+
+ if (student.HP <= 0)
+ BeAddictedToGame(student, (Ghost)bullet.Parent);
+ else TryBeAwed(student, bullet);
+ }
+
public static bool BackSwing(Character? player, int time)
{
if (player == null || time <= 0) return false;
diff --git a/logic/Gaming/Game.cs b/logic/Gaming/Game.cs
index f6cc87b..709b84e 100644
--- a/logic/Gaming/Game.cs
+++ b/logic/Gaming/Game.cs
@@ -393,7 +393,7 @@ namespace Gaming
characterManager = new CharacterManager(gameMap);
attackManager = new AttackManager(gameMap, characterManager);
- actionManager = new ActionManager(gameMap);
+ actionManager = new ActionManager(gameMap, characterManager);
propManager = new PropManager(gameMap);
skillManager = new SkillManager(gameMap, actionManager, attackManager, propManager, characterManager);
}
diff --git a/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs b/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs
index 5e67ecb..16caf3a 100644
--- a/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs
+++ b/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs
@@ -147,10 +147,10 @@ namespace Gaming
{
if (character.IsGhost() &&
(character.PlayerState == PlayerStateType.TryingToAttack || character.PlayerState == PlayerStateType.Swinging
- || character.PlayerState == PlayerStateType.UsingSkill || character.PlayerState == PlayerStateType.LockingOrOpeningTheDoor || character.PlayerState == PlayerStateType.OpeningTheChest)
+ || character.PlayerState == PlayerStateType.UsingSkill)
&& gameMap.CanSee(player, character))
{
- if (CharacterManager.BeStunned(character, GameData.TimeOfGhostFaintingWhenPunish + (player.MaxHp - player.HP) / GameData.timeFactorOfGhostFainting))
+ if (CharacterManager.BeStunned(character, GameData.TimeOfGhostFaintingWhenPunish))
player.AddScore(GameData.StudentScoreTrickerBeStunned(GameData.TimeOfGhostFaintingWhenPunish + (player.MaxHp - player.HP) / GameData.timeFactorOfGhostFainting));
break;
}
diff --git a/logic/Preparation/Interface/IOccupation.cs b/logic/Preparation/Interface/IOccupation.cs
index 51ea42e..5f63c65 100644
--- a/logic/Preparation/Interface/IOccupation.cs
+++ b/logic/Preparation/Interface/IOccupation.cs
@@ -31,7 +31,7 @@ namespace Preparation.Interface
public class Assassin : IGhost
{
- private const int moveSpeed = (int)(GameData.basicMoveSpeed * 473.0 / 380);
+ private const int moveSpeed = (int)(GameData.basicGhostMoveSpeed * 1.1);
public int MoveSpeed => moveSpeed;
private const int maxHp = GameData.basicHp;
@@ -62,7 +62,7 @@ namespace Preparation.Interface
}
public class Klee : IGhost
{
- private const int moveSpeed = (int)(GameData.basicMoveSpeed * 155 / 127);
+ private const int moveSpeed = (int)(GameData.basicStudentMoveSpeed * 155 / 127);
public int MoveSpeed => moveSpeed;
private const int maxHp = GameData.basicHp;
@@ -93,7 +93,7 @@ namespace Preparation.Interface
}
public class ANoisyPerson : IGhost
{
- private const int moveSpeed = (int)(GameData.basicMoveSpeed * 1.1);
+ private const int moveSpeed = (int)(GameData.basicStudentMoveSpeed * 1.07);
public int MoveSpeed => moveSpeed;
private const int maxHp = GameData.basicHp * 12 / 10;
@@ -124,7 +124,7 @@ namespace Preparation.Interface
}
public class Teacher : IStudent
{
- private const int moveSpeed = GameData.basicMoveSpeed * 3 / 4;
+ private const int moveSpeed = GameData.basicStudentMoveSpeed * 3 / 4;
public int MoveSpeed => moveSpeed;
private const int maxHp = GameData.basicHp * 10;
@@ -164,7 +164,7 @@ namespace Preparation.Interface
}
public class Athlete : IStudent
{
- private const int moveSpeed = GameData.basicMoveSpeed * 40 / 38;
+ private const int moveSpeed = GameData.basicStudentMoveSpeed * 40 / 38;
public int MoveSpeed => moveSpeed;
private const int maxHp = GameData.basicHp * 32 / 30;
@@ -204,7 +204,7 @@ namespace Preparation.Interface
}
public class StraightAStudent : IStudent
{
- private const int moveSpeed = (int)(GameData.basicMoveSpeed * 0.8);
+ private const int moveSpeed = (int)(GameData.basicStudentMoveSpeed * 0.8);
public int MoveSpeed => moveSpeed;
private const int maxHp = (int)(GameData.basicHp * 1.1);
@@ -244,7 +244,7 @@ namespace Preparation.Interface
}
public class Robot : IStudent
{
- private const int moveSpeed = (int)(GameData.basicMoveSpeed);
+ private const int moveSpeed = (int)(GameData.basicStudentMoveSpeed);
public int MoveSpeed => moveSpeed;
private const int maxHp = (int)(GameData.basicHp / 2.5);
@@ -284,7 +284,7 @@ namespace Preparation.Interface
}
public class TechOtaku : IStudent
{
- private const int moveSpeed = (int)(GameData.basicMoveSpeed * 0.75);
+ private const int moveSpeed = (int)(GameData.basicStudentMoveSpeed * 0.75);
public int MoveSpeed => moveSpeed;
private const int maxHp = (int)(GameData.basicHp * 0.9);
@@ -324,7 +324,7 @@ namespace Preparation.Interface
}
public class Sunshine : IStudent
{
- private const int moveSpeed = GameData.basicMoveSpeed;
+ private const int moveSpeed = GameData.basicStudentMoveSpeed;
public int MoveSpeed => moveSpeed;
private const int maxHp = GameData.basicHp * 32 / 30;
diff --git a/logic/Preparation/Utility/GameData.cs b/logic/Preparation/Utility/GameData.cs
index 07634be..24a8fcc 100644
--- a/logic/Preparation/Utility/GameData.cs
+++ b/logic/Preparation/Utility/GameData.cs
@@ -97,10 +97,11 @@ namespace Preparation.Utility
public const int basicTimeOfRescue = 1000;
#if DEBUG
- public const int basicMoveSpeed = 9000;// 基本移动速度,单位:s-1
+ public const int basicStudentMoveSpeed = 9000;// 基本移动速度,单位:s-1
#else
- public const int basicMoveSpeed = 1270;
+ public const int basicStudentMoveSpeed = 1270;
#endif
+ public const int basicGhostMoveSpeed = (int)(basicStudentMoveSpeed * 45.0 / 38);
public const int characterMaxSpeed = 12000; // 最大速度
@@ -181,7 +182,7 @@ namespace Preparation.Utility
public const int basicBulletMoveSpeed = 1800; // 基本子弹移动速度,单位:s-1
public const double basicRemoteAttackRange = 3000; // 基本远程攻击范围
- public const double basicAttackShortRange = 900; // 基本近程攻击范围
+ public const double basicAttackShortRange = 1100; // 基本近程攻击范围
public const double basicBulletBombRange = 1000; // 基本子弹爆炸范围
#endregion
#region 技能相关
diff --git a/logic/cmd/gameServer.cmd b/logic/cmd/gameServer.cmd
index 0a5ce3a..b8b85f9 100644
--- a/logic/cmd/gameServer.cmd
+++ b/logic/cmd/gameServer.cmd
@@ -1,6 +1,6 @@
@echo off
-start cmd /k ..\Server\bin\Debug\net6.0\Server.exe --ip 0.0.0.0 --port 8888 --studentCount 4 --trickerCount 1 --gameTimeInSecond 600 --fileName test
+start cmd /k ..\Server\bin\Debug\net6.0\Server.exe --ip 0.0.0.0 --port 8888 --studentCount 2 --trickerCount 1 --gameTimeInSecond 600 --fileName test
ping -n 2 127.0.0.1 > NUL
diff --git a/logic/规则Logic.md b/logic/规则Logic.md
index 9fa069e..1b5068f 100644
--- a/logic/规则Logic.md
+++ b/logic/规则Logic.md
@@ -25,8 +25,8 @@
- 地图上的每个格子有自己的区域类型:墙、草地、电机、出口、紧急出口、门、窗、箱子
### 交互
-- 除了逃离和翻窗,交互目标与交互者在一个九宫格内则为可交互
- - 逃离或翻窗时玩家应当在目标前后左右一个格子内
+- 除了翻窗,交互目标与交互者在一个九宫格内则为可交互
+ - 翻窗时玩家应当在目标前后左右一个格子内
### 破译与逃脱
- 每张地图都有10台电机,求生者需要破译其中的7台,并开启任意一个大门(总所需时间为18秒)后从任意一个开启的大门逃脱,亦或者在只剩1名求生者的情况下从紧急出口逃脱;
@@ -430,7 +430,9 @@
public int SkillCD => GameData.commonSkillCD;
public int DurationTime => 0;
~~~
- 使用瞬间,在可视范围内的使用技能状态中、攻击前后摇、开锁门、开箱的捣蛋鬼会被眩晕(3070+ 玩家损失的血量 / 1000)ms,
+ 使用瞬间,在可视范围内的使用技能状态中、攻击前后摇的捣蛋鬼会被眩晕(3070)ms,
+- 特性
+ 教师无法获得牵制得分
#### 学霸
- 被动技能