| @@ -976,7 +976,7 @@ namespace Client | |||||
| MoveMsg msgW = new() | MoveMsg msgW = new() | ||||
| { | { | ||||
| PlayerId = playerID, | PlayerId = playerID, | ||||
| TimeInMilliseconds = 50, | |||||
| TimeInMilliseconds = 25, | |||||
| Angle = Math.PI | Angle = Math.PI | ||||
| }; | }; | ||||
| client.Move(msgW); | client.Move(msgW); | ||||
| @@ -986,7 +986,7 @@ namespace Client | |||||
| MoveMsg msgS = new() | MoveMsg msgS = new() | ||||
| { | { | ||||
| PlayerId = playerID, | PlayerId = playerID, | ||||
| TimeInMilliseconds = 50, | |||||
| TimeInMilliseconds = 25, | |||||
| Angle = 0 | Angle = 0 | ||||
| }; | }; | ||||
| client.Move(msgS); | client.Move(msgS); | ||||
| @@ -996,7 +996,7 @@ namespace Client | |||||
| MoveMsg msgD = new() | MoveMsg msgD = new() | ||||
| { | { | ||||
| PlayerId = playerID, | PlayerId = playerID, | ||||
| TimeInMilliseconds = 50, | |||||
| TimeInMilliseconds = 25, | |||||
| Angle = Math.PI / 2 | Angle = Math.PI / 2 | ||||
| }; | }; | ||||
| client.Move(msgD); | client.Move(msgD); | ||||
| @@ -1006,7 +1006,7 @@ namespace Client | |||||
| MoveMsg msgA = new() | MoveMsg msgA = new() | ||||
| { | { | ||||
| PlayerId = playerID, | PlayerId = playerID, | ||||
| TimeInMilliseconds = 50, | |||||
| TimeInMilliseconds = 25, | |||||
| Angle = 3 * Math.PI / 2 | Angle = 3 * Math.PI / 2 | ||||
| }; | }; | ||||
| client.Move(msgA); | client.Move(msgA); | ||||
| @@ -6,69 +6,6 @@ namespace GameClass.GameObj | |||||
| { | { | ||||
| public class Student : Character | public class Student : Character | ||||
| { | { | ||||
| /// <summary> | |||||
| /// 遭受攻击 | |||||
| /// </summary> | |||||
| /// <param name="subHP"></param> | |||||
| /// <param name="hasSpear"></param> | |||||
| /// <param name="attacker">伤害来源</param> | |||||
| /// <returns>人物在受到攻击后死了吗</returns> | |||||
| 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; | protected int fixSpeed; | ||||
| /// <summary> | /// <summary> | ||||
| /// 修理电机速度 | /// 修理电机速度 | ||||
| @@ -541,7 +541,7 @@ namespace GameClass.GameObj | |||||
| return false; | return false; | ||||
| } | } | ||||
| } | } | ||||
| protected void TryActivatingLIFE() | |||||
| public void TryActivatingLIFE() | |||||
| { | { | ||||
| if (buffManager.TryActivatingLIFE()) | if (buffManager.TryActivatingLIFE()) | ||||
| { | { | ||||
| @@ -164,7 +164,7 @@ namespace Gaming | |||||
| { | { | ||||
| if (!(player.Commandable()) || player.CharacterType == CharacterType.Robot) | if (!(player.Commandable()) || player.CharacterType == CharacterType.Robot) | ||||
| return false; | 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()) | if (doorwayForEscape != null && doorwayForEscape.IsOpen()) | ||||
| { | { | ||||
| player.AddScore(GameData.StudentScoreEscape); | player.AddScore(GameData.StudentScoreEscape); | ||||
| @@ -174,7 +174,7 @@ namespace Gaming | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| EmergencyExit? emergencyExit = (EmergencyExit?)gameMap.OneForInteractInACross(player.Position, GameObjType.EmergencyExit); | |||||
| EmergencyExit? emergencyExit = (EmergencyExit?)gameMap.OneForInteract(player.Position, GameObjType.EmergencyExit); | |||||
| if (emergencyExit != null && emergencyExit.IsOpen) | if (emergencyExit != null && emergencyExit.IsOpen) | ||||
| { | { | ||||
| ++gameMap.NumOfEscapedStudent; | ++gameMap.NumOfEscapedStudent; | ||||
| @@ -353,12 +353,23 @@ namespace Gaming | |||||
| if (windowForClimb == null || windowForClimb.WhoIsClimbing != null) | if (windowForClimb == null || windowForClimb.WhoIsClimbing != null) | ||||
| return false; | 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; | player.PlayerState = PlayerStateType.ClimbingThroughWindows; | ||||
| windowForClimb.WhoIsClimbing = player; | 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 | new Thread | ||||
| ( | ( | ||||
| () => | () => | ||||
| @@ -396,6 +407,7 @@ namespace Gaming | |||||
| player.ReSetPos(PosJumpOff, gameMap.GetPlaceType(PosJumpOff)); | player.ReSetPos(PosJumpOff, gameMap.GetPlaceType(PosJumpOff)); | ||||
| player.MoveSpeed = player.ReCalculateBuff(BuffType.AddSpeed, player.OrgMoveSpeed, GameData.MaxSpeed, GameData.MinSpeed); | player.MoveSpeed = player.ReCalculateBuff(BuffType.AddSpeed, player.OrgMoveSpeed, GameData.MaxSpeed, GameData.MinSpeed); | ||||
| windowForClimb.WhoIsClimbing = null; | windowForClimb.WhoIsClimbing = null; | ||||
| gameMap.Remove(addWall); | |||||
| if (player.PlayerState == PlayerStateType.ClimbingThroughWindows) | if (player.PlayerState == PlayerStateType.ClimbingThroughWindows) | ||||
| { | { | ||||
| player.PlayerState = PlayerStateType.Null; | player.PlayerState = PlayerStateType.Null; | ||||
| @@ -494,10 +506,12 @@ namespace Gaming | |||||
| */ | */ | ||||
| private readonly Map gameMap; | private readonly Map gameMap; | ||||
| private readonly CharacterManager characterManager; | |||||
| public readonly MoveEngine moveEngine; | public readonly MoveEngine moveEngine; | ||||
| public ActionManager(Map gameMap) | |||||
| public ActionManager(Map gameMap, CharacterManager characterManager) | |||||
| { | { | ||||
| this.gameMap = gameMap; | this.gameMap = gameMap; | ||||
| this.moveEngine = new MoveEngine( | this.moveEngine = new MoveEngine( | ||||
| gameMap: gameMap, | gameMap: gameMap, | ||||
| OnCollision: (obj, collisionObj, moveVec) => | OnCollision: (obj, collisionObj, moveVec) => | ||||
| @@ -516,6 +530,7 @@ namespace Gaming | |||||
| // Debugger.Output(obj, " end move at " + obj.Position.ToString() + " At time: " + Environment.TickCount64); | // Debugger.Output(obj, " end move at " + obj.Position.ToString() + " At time: " + Environment.TickCount64); | ||||
| } | } | ||||
| ); | ); | ||||
| this.characterManager = characterManager; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -50,20 +50,7 @@ namespace Gaming | |||||
| if ((!(((Character)objBeingShot).IsGhost())) && bullet.Parent.IsGhost()) | 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) | // if (((Character)objBeingShot).IsGhost() && !bullet.Parent.IsGhost() && bullet.TypeOfBullet == BulletType.Ram) | ||||
| // BeStunned((Character)objBeingShot, bullet.AP); | // BeStunned((Character)objBeingShot, bullet.AP); | ||||
| @@ -134,7 +134,7 @@ namespace Gaming | |||||
| { | { | ||||
| if (!noise && XY.Distance(newPlayer.Position, person.Position) <= (newPlayer.AlertnessRadius / person.Concealment)) | 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)); | 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; | TimePinningDown += GameData.checkInterval; | ||||
| newPlayer.AddScore(GameData.StudentScorePinDown(TimePinningDown) - ScoreAdded); | newPlayer.AddScore(GameData.StudentScorePinDown(TimePinningDown) - ScoreAdded); | ||||
| @@ -250,6 +250,81 @@ namespace Gaming | |||||
| { IsBackground = true }.Start(); | { IsBackground = true }.Start(); | ||||
| return true; | 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; | |||||
| } | |||||
| /// <summary> | |||||
| /// 遭受攻击 | |||||
| /// </summary> | |||||
| /// <param name="subHP"></param> | |||||
| /// <param name="hasSpear"></param> | |||||
| /// <param name="attacker">伤害来源</param> | |||||
| /// <returns>人物在受到攻击后死了吗</returns> | |||||
| 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) | public static bool BackSwing(Character? player, int time) | ||||
| { | { | ||||
| if (player == null || time <= 0) return false; | if (player == null || time <= 0) return false; | ||||
| @@ -393,7 +393,7 @@ namespace Gaming | |||||
| characterManager = new CharacterManager(gameMap); | characterManager = new CharacterManager(gameMap); | ||||
| attackManager = new AttackManager(gameMap, characterManager); | attackManager = new AttackManager(gameMap, characterManager); | ||||
| actionManager = new ActionManager(gameMap); | |||||
| actionManager = new ActionManager(gameMap, characterManager); | |||||
| propManager = new PropManager(gameMap); | propManager = new PropManager(gameMap); | ||||
| skillManager = new SkillManager(gameMap, actionManager, attackManager, propManager, characterManager); | skillManager = new SkillManager(gameMap, actionManager, attackManager, propManager, characterManager); | ||||
| } | } | ||||
| @@ -147,10 +147,10 @@ namespace Gaming | |||||
| { | { | ||||
| if (character.IsGhost() && | if (character.IsGhost() && | ||||
| (character.PlayerState == PlayerStateType.TryingToAttack || character.PlayerState == PlayerStateType.Swinging | (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)) | && 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)); | player.AddScore(GameData.StudentScoreTrickerBeStunned(GameData.TimeOfGhostFaintingWhenPunish + (player.MaxHp - player.HP) / GameData.timeFactorOfGhostFainting)); | ||||
| break; | break; | ||||
| } | } | ||||
| @@ -31,7 +31,7 @@ namespace Preparation.Interface | |||||
| public class Assassin : IGhost | 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; | public int MoveSpeed => moveSpeed; | ||||
| private const int maxHp = GameData.basicHp; | private const int maxHp = GameData.basicHp; | ||||
| @@ -62,7 +62,7 @@ namespace Preparation.Interface | |||||
| } | } | ||||
| public class Klee : IGhost | 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; | public int MoveSpeed => moveSpeed; | ||||
| private const int maxHp = GameData.basicHp; | private const int maxHp = GameData.basicHp; | ||||
| @@ -93,7 +93,7 @@ namespace Preparation.Interface | |||||
| } | } | ||||
| public class ANoisyPerson : IGhost | 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; | public int MoveSpeed => moveSpeed; | ||||
| private const int maxHp = GameData.basicHp * 12 / 10; | private const int maxHp = GameData.basicHp * 12 / 10; | ||||
| @@ -124,7 +124,7 @@ namespace Preparation.Interface | |||||
| } | } | ||||
| public class Teacher : IStudent | public class Teacher : IStudent | ||||
| { | { | ||||
| private const int moveSpeed = GameData.basicMoveSpeed * 3 / 4; | |||||
| private const int moveSpeed = GameData.basicStudentMoveSpeed * 3 / 4; | |||||
| public int MoveSpeed => moveSpeed; | public int MoveSpeed => moveSpeed; | ||||
| private const int maxHp = GameData.basicHp * 10; | private const int maxHp = GameData.basicHp * 10; | ||||
| @@ -164,7 +164,7 @@ namespace Preparation.Interface | |||||
| } | } | ||||
| public class Athlete : IStudent | public class Athlete : IStudent | ||||
| { | { | ||||
| private const int moveSpeed = GameData.basicMoveSpeed * 40 / 38; | |||||
| private const int moveSpeed = GameData.basicStudentMoveSpeed * 40 / 38; | |||||
| public int MoveSpeed => moveSpeed; | public int MoveSpeed => moveSpeed; | ||||
| private const int maxHp = GameData.basicHp * 32 / 30; | private const int maxHp = GameData.basicHp * 32 / 30; | ||||
| @@ -204,7 +204,7 @@ namespace Preparation.Interface | |||||
| } | } | ||||
| public class StraightAStudent : IStudent | 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; | public int MoveSpeed => moveSpeed; | ||||
| private const int maxHp = (int)(GameData.basicHp * 1.1); | private const int maxHp = (int)(GameData.basicHp * 1.1); | ||||
| @@ -244,7 +244,7 @@ namespace Preparation.Interface | |||||
| } | } | ||||
| public class Robot : IStudent | public class Robot : IStudent | ||||
| { | { | ||||
| private const int moveSpeed = (int)(GameData.basicMoveSpeed); | |||||
| private const int moveSpeed = (int)(GameData.basicStudentMoveSpeed); | |||||
| public int MoveSpeed => moveSpeed; | public int MoveSpeed => moveSpeed; | ||||
| private const int maxHp = (int)(GameData.basicHp / 2.5); | private const int maxHp = (int)(GameData.basicHp / 2.5); | ||||
| @@ -284,7 +284,7 @@ namespace Preparation.Interface | |||||
| } | } | ||||
| public class TechOtaku : IStudent | 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; | public int MoveSpeed => moveSpeed; | ||||
| private const int maxHp = (int)(GameData.basicHp * 0.9); | private const int maxHp = (int)(GameData.basicHp * 0.9); | ||||
| @@ -324,7 +324,7 @@ namespace Preparation.Interface | |||||
| } | } | ||||
| public class Sunshine : IStudent | public class Sunshine : IStudent | ||||
| { | { | ||||
| private const int moveSpeed = GameData.basicMoveSpeed; | |||||
| private const int moveSpeed = GameData.basicStudentMoveSpeed; | |||||
| public int MoveSpeed => moveSpeed; | public int MoveSpeed => moveSpeed; | ||||
| private const int maxHp = GameData.basicHp * 32 / 30; | private const int maxHp = GameData.basicHp * 32 / 30; | ||||
| @@ -97,10 +97,11 @@ namespace Preparation.Utility | |||||
| public const int basicTimeOfRescue = 1000; | public const int basicTimeOfRescue = 1000; | ||||
| #if DEBUG | #if DEBUG | ||||
| public const int basicMoveSpeed = 9000;// 基本移动速度,单位:s-1 | |||||
| public const int basicStudentMoveSpeed = 9000;// 基本移动速度,单位:s-1 | |||||
| #else | #else | ||||
| public const int basicMoveSpeed = 1270; | |||||
| public const int basicStudentMoveSpeed = 1270; | |||||
| #endif | #endif | ||||
| public const int basicGhostMoveSpeed = (int)(basicStudentMoveSpeed * 45.0 / 38); | |||||
| public const int characterMaxSpeed = 12000; // 最大速度 | public const int characterMaxSpeed = 12000; // 最大速度 | ||||
| @@ -181,7 +182,7 @@ namespace Preparation.Utility | |||||
| public const int basicBulletMoveSpeed = 1800; // 基本子弹移动速度,单位:s-1 | public const int basicBulletMoveSpeed = 1800; // 基本子弹移动速度,单位:s-1 | ||||
| public const double basicRemoteAttackRange = 3000; // 基本远程攻击范围 | public const double basicRemoteAttackRange = 3000; // 基本远程攻击范围 | ||||
| public const double basicAttackShortRange = 900; // 基本近程攻击范围 | |||||
| public const double basicAttackShortRange = 1100; // 基本近程攻击范围 | |||||
| public const double basicBulletBombRange = 1000; // 基本子弹爆炸范围 | public const double basicBulletBombRange = 1000; // 基本子弹爆炸范围 | ||||
| #endregion | #endregion | ||||
| #region 技能相关 | #region 技能相关 | ||||
| @@ -1,6 +1,6 @@ | |||||
| @echo off | @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 | ping -n 2 127.0.0.1 > NUL | ||||
| @@ -25,8 +25,8 @@ | |||||
| - 地图上的每个格子有自己的区域类型:墙、草地、电机、出口、紧急出口、门、窗、箱子 | - 地图上的每个格子有自己的区域类型:墙、草地、电机、出口、紧急出口、门、窗、箱子 | ||||
| ### 交互 | ### 交互 | ||||
| - 除了逃离和翻窗,交互目标与交互者在一个九宫格内则为可交互 | |||||
| - 逃离或翻窗时玩家应当在目标前后左右一个格子内 | |||||
| - 除了翻窗,交互目标与交互者在一个九宫格内则为可交互 | |||||
| - 翻窗时玩家应当在目标前后左右一个格子内 | |||||
| ### 破译与逃脱 | ### 破译与逃脱 | ||||
| - 每张地图都有10台电机,求生者需要破译其中的7台,并开启任意一个大门(总所需时间为18秒)后从任意一个开启的大门逃脱,亦或者在只剩1名求生者的情况下从紧急出口逃脱; | - 每张地图都有10台电机,求生者需要破译其中的7台,并开启任意一个大门(总所需时间为18秒)后从任意一个开启的大门逃脱,亦或者在只剩1名求生者的情况下从紧急出口逃脱; | ||||
| @@ -430,7 +430,9 @@ | |||||
| public int SkillCD => GameData.commonSkillCD; | public int SkillCD => GameData.commonSkillCD; | ||||
| public int DurationTime => 0; | public int DurationTime => 0; | ||||
| ~~~ | ~~~ | ||||
| 使用瞬间,在可视范围内的使用技能状态中、攻击前后摇、开锁门、开箱的捣蛋鬼会被眩晕(3070+ 玩家损失的血量 / 1000)ms, | |||||
| 使用瞬间,在可视范围内的使用技能状态中、攻击前后摇的捣蛋鬼会被眩晕(3070)ms, | |||||
| - 特性 | |||||
| 教师无法获得牵制得分 | |||||
| #### 学霸 | #### 学霸 | ||||
| - 被动技能 | - 被动技能 | ||||