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, +- 特性 + 教师无法获得牵制得分 #### 学霸 - 被动技能