diff --git a/logic/GameClass/GameObj/Character/Character.cs b/logic/GameClass/GameObj/Character/Character.cs index 7340b4f..dae9be8 100644 --- a/logic/GameClass/GameObj/Character/Character.cs +++ b/logic/GameClass/GameObj/Character/Character.cs @@ -318,18 +318,10 @@ namespace GameClass.GameObj private GameObj? whatInteractingWith = null; public GameObj? WhatInteractingWith => whatInteractingWith; - public void SetPlayerState(PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null) + public void ChangePlayerState(PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null) { lock (gameObjLock) { - switch (playerState) - { - case PlayerStateType.OpeningTheChest: - ((Chest)whatInteractingWith).StopOpen(); - break; - default: - break; - } whatInteractingWith = gameObj; if (value != PlayerStateType.Moving) IsMoving = false; diff --git a/logic/GameClass/GameObj/Map/Doorway.cs b/logic/GameClass/GameObj/Map/Doorway.cs index 6bb2f00..cff420b 100644 --- a/logic/GameClass/GameObj/Map/Doorway.cs +++ b/logic/GameClass/GameObj/Map/Doorway.cs @@ -35,14 +35,14 @@ namespace GameClass.GameObj } } - private bool isOpening = false; - public bool IsOpening + private int openStartTime = 0; + public int OpenStartTime { - get => isOpening; + get => openStartTime; set { lock (gameObjLock) - isOpening = value; + openStartTime = value; } } @@ -61,6 +61,6 @@ namespace GameClass.GameObj } } - public bool IsOpen() => (OpenDegree == GameData.degreeOfOpenedDoorway); + public bool IsOpen() => (openDegree == GameData.degreeOfOpenedDoorway); } } diff --git a/logic/Gaming/ActionManager.cs b/logic/Gaming/ActionManager.cs index 5fe6ed0..6c162a7 100644 --- a/logic/Gaming/ActionManager.cs +++ b/logic/Gaming/ActionManager.cs @@ -23,22 +23,22 @@ namespace Gaming { if (((Bullet)collisionObj).Parent != player && ((Bullet)collisionObj).TypeOfBullet == BulletType.JumpyDumpty) { - if (CharacterManager.BeStunned((Character)player, GameData.TimeOfStunnedWhenJumpyDumpty)) + if (characterManager.BeStunned((Character)player, GameData.TimeOfStunnedWhenJumpyDumpty)) player.AddScore(GameData.TrickerScoreStudentBeStunned(GameData.TimeOfStunnedWhenJumpyDumpty)); gameMap.Remove((GameObj)collisionObj); } } if (player.FindIActiveSkill(ActiveSkillType.CanBeginToCharge).IsBeingUsed && collisionObj.Type == GameObjType.Character && ((Character)collisionObj).IsGhost()) { - if (CharacterManager.BeStunned((Character)collisionObj, GameData.TimeOfGhostFaintingWhenCharge)) + if (characterManager.BeStunned((Character)collisionObj, GameData.TimeOfGhostFaintingWhenCharge)) player.AddScore(GameData.StudentScoreTrickerBeStunned(GameData.TimeOfGhostFaintingWhenCharge)); - CharacterManager.BeStunned(player, GameData.TimeOfStudentFaintingWhenCharge); + characterManager.BeStunned(player, GameData.TimeOfStudentFaintingWhenCharge); } } public bool MovePlayer(Character playerToMove, int moveTimeInMilliseconds, double moveDirection) { if (!playerToMove.Commandable() || !TryToStop()) return false; - playerToMove.SetPlayerState(PlayerStateType.Moving); + characterManager.SetPlayerState(playerToMove, PlayerStateType.Moving); moveEngine.MoveObj(playerToMove, moveTimeInMilliseconds, moveDirection); return true; } @@ -47,7 +47,7 @@ namespace Gaming { if (player.Commandable() || !TryToStop()) { - player.SetPlayerState(); + characterManager.SetPlayerState(player); return true; } return false; @@ -63,7 +63,7 @@ namespace Gaming return false; ++generatorForFix.NumOfFixing; - player.SetPlayerState(PlayerStateType.Fixing); + characterManager.SetPlayerState(player, PlayerStateType.Fixing); new Thread ( () => @@ -74,7 +74,7 @@ namespace Gaming { if (generatorForFix.Repair(player.FixSpeed * GameData.frameDuration, player)) { - player.SetPlayerState(); + characterManager.SetPlayerState(player); gameMap.NumOfRepairedGenerators++; } }, @@ -96,31 +96,21 @@ namespace Gaming if (!(player.Commandable()) || player.PlayerState == PlayerStateType.OpeningTheDoorway) return false; Doorway? doorwayToOpen = (Doorway?)gameMap.OneForInteract(player.Position, GameObjType.Doorway); - if (doorwayToOpen == null || doorwayToOpen.IsOpening || !doorwayToOpen.PowerSupply) + if (doorwayToOpen == null || doorwayToOpen.OpenStartTime > 0 || !doorwayToOpen.PowerSupply) return false; - player.SetPlayerState(PlayerStateType.OpeningTheDoorway); - doorwayToOpen.IsOpening = true; + characterManager.SetPlayerState(player, PlayerStateType.OpeningTheDoorway, doorwayToOpen); + int startTime = doorwayToOpen.OpenStartTime = gameMap.Timer.nowTime(); new Thread ( () => { - new FrameRateTaskExecutor( - loopCondition: () => player.PlayerState == PlayerStateType.OpeningTheDoorway && gameMap.Timer.IsGaming && doorwayToOpen.OpenDegree < GameData.degreeOfOpenedDoorway, - loopToDo: () => - { - doorwayToOpen.OpenDegree += GameData.frameDuration; - }, - timeInterval: GameData.frameDuration, - finallyReturn: () => 0 - ) + Thread.Sleep(GameData.degreeOfOpenedDoorway - doorwayToOpen.OpenDegree); - .Start(); - doorwayToOpen.IsOpening = false; - if (doorwayToOpen.OpenDegree >= GameData.degreeOfOpenedDoorway) + if (doorwayToOpen.OpenStartTime == startTime) { - if (player.PlayerState == PlayerStateType.OpeningTheDoorway) - player.SetPlayerState(); + doorwayToOpen.OpenDegree = GameData.degreeOfOpenedDoorway; + player.SetPlayerStateNaturally(); } } @@ -172,22 +162,22 @@ namespace Gaming ( () => { - playerTreated.SetPlayerState(PlayerStateType.Treated); - player.SetPlayerState(PlayerStateType.Treating); + characterManager.SetPlayerState(player, PlayerStateType.Treated); + characterManager.SetPlayerState(player, PlayerStateType.Treating); new FrameRateTaskExecutor( loopCondition: () => playerTreated.PlayerState == PlayerStateType.Treated && player.PlayerState == PlayerStateType.Treating && gameMap.Timer.IsGaming, loopToDo: () => { if (playerTreated.AddDegreeOfTreatment(GameData.frameDuration * player.TreatSpeed, player)) - playerTreated.SetPlayerState(); + characterManager.SetPlayerState(playerTreated); }, timeInterval: GameData.frameDuration, finallyReturn: () => 0 ) .Start(); - if (player.PlayerState == PlayerStateType.Treating) player.SetPlayerState(); - else if (playerTreated.PlayerState == PlayerStateType.Treated) playerTreated.SetPlayerState(); + if (player.PlayerState == PlayerStateType.Treating) characterManager.SetPlayerState(player); + else if (playerTreated.PlayerState == PlayerStateType.Treated) characterManager.SetPlayerState(playerTreated); } ) { IsBackground = true }.Start(); @@ -202,8 +192,8 @@ namespace Gaming } if ((!player.Commandable()) || playerRescued.PlayerState != PlayerStateType.Addicted || !GameData.ApproachToInteract(playerRescued.Position, player.Position)) return false; - player.SetPlayerState(PlayerStateType.Rescuing); - playerRescued.SetPlayerState(PlayerStateType.Rescued); + characterManager.SetPlayerState(player, PlayerStateType.Rescuing); + characterManager.SetPlayerState(playerRescued, PlayerStateType.Rescued); new Thread ( @@ -225,14 +215,14 @@ namespace Gaming { if (playerRescued.TimeOfRescue >= GameData.basicTimeOfRescue) { - playerRescued.SetPlayerState(); + characterManager.SetPlayerState(playerRescued); playerRescued.HP = playerRescued.MaxHp / 2; player.AddScore(GameData.StudentScoreRescue); } else - playerRescued.SetPlayerState(PlayerStateType.Addicted); + characterManager.SetPlayerState(playerRescued, PlayerStateType.Addicted); } - if (player.PlayerState == PlayerStateType.Rescuing) player.SetPlayerState(); + if (player.PlayerState == PlayerStateType.Rescuing) characterManager.SetPlayerState(player); playerRescued.TimeOfRescue = 0; } ) @@ -249,7 +239,7 @@ namespace Gaming if (chestToOpen == null || chestToOpen.OpenStartTime > 0) return false; - player.SetPlayerState(PlayerStateType.OpeningTheChest, chestToOpen); + characterManager.SetPlayerState(player, PlayerStateType.OpeningTheChest, chestToOpen); int startTime = gameMap.Timer.nowTime(); chestToOpen.Open(startTime, player); new Thread @@ -300,7 +290,7 @@ namespace Gaming //Wall addWall = new Wall(windowForClimb.Position - 2 * windowToPlayer); // gameMap.Add(addWall); - player.SetPlayerState(PlayerStateType.ClimbingThroughWindows); + characterManager.SetPlayerState(player, PlayerStateType.ClimbingThroughWindows); windowForClimb.WhoIsClimbing = player; new Thread ( @@ -342,7 +332,7 @@ namespace Gaming // gameMap.Remove(addWall); if (player.PlayerState == PlayerStateType.ClimbingThroughWindows) { - player.SetPlayerState(); + characterManager.SetPlayerState(player); } } @@ -382,7 +372,7 @@ namespace Gaming } if (!flag) return false; - player.SetPlayerState(PlayerStateType.LockingOrOpeningTheDoor); + characterManager.SetPlayerState(player, PlayerStateType.LockingOrOpeningTheDoor); new Thread ( () => @@ -405,7 +395,7 @@ namespace Gaming doorToLock.IsOpen = (!doorToLock.IsOpen); } if (player.PlayerState == PlayerStateType.LockingOrOpeningTheDoor) - player.SetPlayerState(); + characterManager.SetPlayerState(player); doorToLock.OpenOrLockDegree = 0; } diff --git a/logic/Gaming/AttackManager.cs b/logic/Gaming/AttackManager.cs index 842d53a..40995b2 100644 --- a/logic/Gaming/AttackManager.cs +++ b/logic/Gaming/AttackManager.cs @@ -81,14 +81,14 @@ namespace Gaming { if (objBeingShot == null) { - CharacterManager.BackSwing((Character?)bullet.Parent, bullet.Backswing); + characterManager.BackSwing((Character?)bullet.Parent, bullet.Backswing); return; } Debugger.Output(bullet, bullet.TypeOfBullet.ToString()); BombObj(bullet, objBeingShot); - CharacterManager.BackSwing((Character?)bullet.Parent, bullet.RecoveryFromHit); + characterManager.BackSwing((Character?)bullet.Parent, bullet.RecoveryFromHit); return; } @@ -140,10 +140,10 @@ namespace Gaming if (objBeingShot == null) { - CharacterManager.BackSwing((Character?)bullet.Parent, bullet.Backswing); + characterManager.BackSwing((Character?)bullet.Parent, bullet.Backswing); } else - CharacterManager.BackSwing((Character?)bullet.Parent, bullet.RecoveryFromHit); + characterManager.BackSwing((Character?)bullet.Parent, bullet.RecoveryFromHit); } public bool Attack(Character? player, double angle) @@ -174,7 +174,7 @@ namespace Gaming if (bullet.CastTime > 0) { - player.SetPlayerState(PlayerStateType.TryingToAttack); + characterManager.SetPlayerState(player, PlayerStateType.TryingToAttack); new Thread (() => @@ -195,7 +195,7 @@ namespace Gaming { if (player.PlayerState == PlayerStateType.TryingToAttack) { - player.SetPlayerState(); + characterManager.SetPlayerState(player); } else bullet.IsMoving = false; diff --git a/logic/Gaming/CharacterManager .cs b/logic/Gaming/CharacterManager .cs index 5d0d062..14d84b8 100644 --- a/logic/Gaming/CharacterManager .cs +++ b/logic/Gaming/CharacterManager .cs @@ -7,6 +7,7 @@ using GameEngine; using Preparation.Interface; using Timothy.FrameRateTask; using System.Numerics; +using System.Timers; namespace Gaming { @@ -21,6 +22,21 @@ namespace Gaming this.gameMap = gameMap; } + public void SetPlayerState(Character player, PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null) + { + switch (player.PlayerState) + { + case PlayerStateType.OpeningTheChest: + ((Chest)player.WhatInteractingWith).StopOpen(); + break; + case PlayerStateType.OpeningTheDoorway: + ((Doorway)player.WhatInteractingWith).OpenDegree += gameMap.Timer.nowTime() - ((Doorway)player.WhatInteractingWith).OpenStartTime; + break; + default: + break; + } + player.ChangePlayerState(value, gameObj); + } public Character? AddPlayer(XY pos, int teamID, int playerID, CharacterType characterType, Character? parent = null) { @@ -216,7 +232,7 @@ namespace Gaming return; } } - player.SetPlayerState(PlayerStateType.Addicted); + SetPlayerState(player, PlayerStateType.Addicted); new Thread (() => { @@ -246,23 +262,23 @@ namespace Gaming { IsBackground = true }.Start(); } - public static bool BeStunned(Character player, int time) + public bool BeStunned(Character player, int time) { if (player.PlayerState == PlayerStateType.Stunned || player.NoHp() || player.CharacterType == CharacterType.Robot) return false; new Thread (() => { - player.SetPlayerState(PlayerStateType.Stunned); + SetPlayerState(player, PlayerStateType.Stunned); Thread.Sleep(time); if (player.PlayerState == PlayerStateType.Stunned) - player.SetPlayerState(); + SetPlayerState(player); } ) { IsBackground = true }.Start(); return true; } - public static bool TryBeAwed(Student character, Bullet bullet) + public bool TryBeAwed(Student character, Bullet bullet) { if (character.CanBeAwed()) { @@ -337,11 +353,11 @@ namespace Gaming else TryBeAwed(student, bullet); } - public static bool BackSwing(Character? player, int time) + public bool BackSwing(Character? player, int time) { if (player == null || time <= 0) return false; if (player.PlayerState == PlayerStateType.Swinging || (!player.Commandable() && player.PlayerState != PlayerStateType.TryingToAttack)) return false; - player.SetPlayerState(PlayerStateType.Swinging); + SetPlayerState(player, PlayerStateType.Swinging); new Thread (() => @@ -350,7 +366,7 @@ namespace Gaming if (player.PlayerState == PlayerStateType.Swinging) { - player.SetPlayerState(); + SetPlayerState(player); } } ) diff --git a/logic/Gaming/Game.cs b/logic/Gaming/Game.cs index 6575102..914fd6d 100644 --- a/logic/Gaming/Game.cs +++ b/logic/Gaming/Game.cs @@ -233,7 +233,7 @@ namespace Gaming Character? player = gameMap.FindPlayerToAction(playerID); if (player != null) { - PropManager.UseProp(player, propType); + propManager.UseProp(player, propType); } } public void ThrowProp(long playerID, PropType propType = PropType.Null) @@ -375,7 +375,7 @@ namespace Gaming characterManager = new CharacterManager(gameMap); attackManager = new AttackManager(gameMap, characterManager); actionManager = new ActionManager(gameMap, characterManager); - propManager = new PropManager(gameMap); + propManager = new PropManager(gameMap, characterManager); skillManager = new SkillManager(gameMap, actionManager, attackManager, propManager, characterManager); } } diff --git a/logic/Gaming/PropManager.cs b/logic/Gaming/PropManager.cs index 3914b87..457ed44 100644 --- a/logic/Gaming/PropManager.cs +++ b/logic/Gaming/PropManager.cs @@ -16,10 +16,10 @@ namespace Gaming private class PropManager { private readonly Map gameMap; - + private readonly CharacterManager characterManager; private readonly List availableCellForGenerateProp; - public static void UseProp(Character player, PropType propType) + public void UseProp(Character player, PropType propType) { if (player.IsResetting || player.CharacterType == CharacterType.Robot) return; @@ -57,7 +57,7 @@ namespace Gaming if (player.PlayerState == PlayerStateType.Stunned) { player.AddScore(GameData.ScorePropRecoverFromDizziness); - player.SetPlayerState(); + player.SetPlayerStateNaturally(); } break; default: @@ -210,8 +210,9 @@ namespace Gaming { IsBackground = true }.Start(); */ } - public PropManager(Map gameMap) // 道具不能扔过墙 + public PropManager(Map gameMap, CharacterManager characterManager) // 道具不能扔过墙 { + this.characterManager = characterManager; this.gameMap = gameMap; /* this.moveEngine = new MoveEngine( gameMap: gameMap, diff --git a/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs b/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs index 5496e79..afebbd6 100644 --- a/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs +++ b/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs @@ -145,7 +145,7 @@ namespace Gaming { if (!character.IsGhost() && XY.Distance(character.Position, player.Position) <= player.ViewRange) { - if (CharacterManager.BeStunned(character, GameData.TimeOfStudentFaintingWhenHowl)) + if (characterManager.BeStunned(character, GameData.TimeOfStudentFaintingWhenHowl)) player.AddScore(GameData.TrickerScoreStudentBeStunned(GameData.TimeOfStudentFaintingWhenHowl)); break; } @@ -155,7 +155,7 @@ namespace Gaming { gameMap.GameObjLockDict[GameObjType.Character].ExitReadLock(); } - CharacterManager.BackSwing(player, GameData.TimeOfGhostSwingingAfterHowl); + characterManager.BackSwing(player, GameData.TimeOfGhostSwingingAfterHowl); Debugger.Output(player, "howled!"); }, () => @@ -177,7 +177,7 @@ namespace Gaming || character.PlayerState == PlayerStateType.UsingSkill) && gameMap.CanSee(player, character)) { - if (CharacterManager.BeStunned(character, GameData.TimeOfGhostFaintingWhenPunish)) + if (characterManager.BeStunned(character, GameData.TimeOfGhostFaintingWhenPunish)) player.AddScore(GameData.StudentScoreTrickerBeStunned(GameData.TimeOfGhostFaintingWhenPunish)); break; } @@ -205,7 +205,7 @@ namespace Gaming { if ((character.PlayerState == PlayerStateType.Addicted) && gameMap.CanSee(player, character)) { - character.SetPlayerState(); + characterManager.SetPlayerState(character); character.HP = GameData.RemainHpWhenAddLife; ((Student)character).TimeOfRescue = 0; player.AddScore(GameData.StudentScoreRescue); diff --git a/logic/Server/CopyInfo.cs b/logic/Server/CopyInfo.cs index a192063..a3409ce 100644 --- a/logic/Server/CopyInfo.cs +++ b/logic/Server/CopyInfo.cs @@ -32,7 +32,7 @@ namespace Server case Preparation.Utility.GameObjType.Chest: return Chest((Chest)gameObj, time); case Preparation.Utility.GameObjType.Doorway: - return Gate((Doorway)gameObj); + return Gate((Doorway)gameObj, time); case Preparation.Utility.GameObjType.EmergencyExit: if (((EmergencyExit)gameObj).CanOpen) return HiddenGate((EmergencyExit)gameObj); @@ -195,13 +195,14 @@ namespace Server msg.ClassroomMessage.Progress = generator.DegreeOfRepair; return msg; } - private static MessageOfObj Gate(Doorway doorway) + private static MessageOfObj Gate(Doorway doorway, int time) { MessageOfObj msg = new MessageOfObj(); msg.GateMessage = new(); msg.GateMessage.X = doorway.Position.x; msg.GateMessage.Y = doorway.Position.y; - msg.GateMessage.Progress = doorway.OpenDegree; + int progress = ((doorway.OpenStartTime > 0) ? (time - doorway.OpenStartTime) : 0) + doorway.OpenDegree; + msg.GateMessage.Progress = (progress > GameData.degreeOfOpenedDoorway) ? GameData.degreeOfOpenedDoorway : progress; return msg; } private static MessageOfObj HiddenGate(EmergencyExit Exit) diff --git a/logic/规则Logic.md b/logic/规则Logic.md index af2fc86..55456a2 100644 --- a/logic/规则Logic.md +++ b/logic/规则Logic.md @@ -252,7 +252,7 @@ - 特性 - 冥想 - 当玩家处于可接受指令状态且不在修机时,会积累学习进度,速度为0.3%/ms - - 受到攻击(并非伤害)或眩晕或翻窗(或攻击他人)学习进度清零 + - 受到攻击(并非伤害)或学习或进入不可接受治疗状态(包括翻窗)学习进度清零 - 主动技能5 - 写答案 - CD:30s @@ -401,6 +401,7 @@ public: ### 人物 - 被唤醒或被勉励不属于交互状态,翻窗属于交互状态 +- EndAllAction()及Move指令调用数总和一帧内不超过10次 ### 初始状态 - 玩家出生点固定且一定为空地