fix: 🚑 fix the bug about Semaphore
tags/v0.1.0
| @@ -305,6 +305,7 @@ $$ | |||||
| - 不可救人 | - 不可救人 | ||||
| - 无牵制得分 | - 无牵制得分 | ||||
| - 不可使用道具(可以捡起和扔道具) | - 不可使用道具(可以捡起和扔道具) | ||||
| - 不沉迷,击中直接摧毁 | |||||
| #### 技术宅TechOtaku | #### 技术宅TechOtaku | ||||
| - 特性 | - 特性 | ||||
| @@ -65,4 +65,10 @@ | |||||
| # 5月21日更新 | # 5月21日更新 | ||||
| - docs:更新了 游戏机制与平衡性调整更新(基本不变版).pdf | - docs:更新了 游戏机制与平衡性调整更新(基本不变版).pdf | ||||
| - Klee小炸弹的攻击范围与放射方向调整 | |||||
| - Klee小炸弹的攻击范围与放射方向调整 | |||||
| # 5月22日11:00更新 | |||||
| - fix:修复了开校门的bug | |||||
| # 5月25日更新 | |||||
| - fix:修复了Semaphore设置错误的问题 | |||||
| @@ -1,6 +1,7 @@ | |||||
| using Preparation.Utility; | using Preparation.Utility; | ||||
| using Preparation.Interface; | using Preparation.Interface; | ||||
| using System; | using System; | ||||
| using System.Threading; | |||||
| namespace GameClass.GameObj | namespace GameClass.GameObj | ||||
| { | { | ||||
| @@ -108,16 +109,15 @@ namespace GameClass.GameObj | |||||
| private int timeOfRescue = 0; | private int timeOfRescue = 0; | ||||
| public int TimeOfRescue | public int TimeOfRescue | ||||
| { | { | ||||
| get => timeOfRescue; | |||||
| set | |||||
| { | |||||
| if (value > 0) | |||||
| lock (gameObjLock) | |||||
| timeOfRescue = (value < GameData.basicTimeOfRescue) ? value : GameData.basicTimeOfRescue; | |||||
| else | |||||
| lock (gameObjLock) | |||||
| timeOfRescue = 0; | |||||
| } | |||||
| get => Interlocked.CompareExchange(ref timeOfRescue, -1, -1); | |||||
| } | |||||
| public bool AddTimeOfRescue(int value) | |||||
| { | |||||
| return Interlocked.Add(ref timeOfRescue, value) >= GameData.basicTimeOfRescue; | |||||
| } | |||||
| public void SetTimeOfRescue(int value) | |||||
| { | |||||
| Interlocked.Exchange(ref timeOfRescue, value); | |||||
| } | } | ||||
| public Student(XY initPos, int initRadius, CharacterType characterType) : base(initPos, initRadius, characterType) | public Student(XY initPos, int initRadius, CharacterType characterType) : base(initPos, initRadius, characterType) | ||||
| @@ -418,34 +418,64 @@ namespace GameClass.GameObj | |||||
| || playerState == PlayerStateType.Null || playerState == PlayerStateType.Moving); | || playerState == PlayerStateType.Null || playerState == PlayerStateType.Moving); | ||||
| } | } | ||||
| private GameObj? whatInteractingWith = null; | private GameObj? whatInteractingWith = null; | ||||
| public GameObj? WhatInteractingWith => whatInteractingWith; | |||||
| public GameObj? WhatInteractingWith | |||||
| { | |||||
| get | |||||
| { | |||||
| lock (actionLock) | |||||
| { | |||||
| return whatInteractingWith; | |||||
| } | |||||
| } | |||||
| } | |||||
| private long ChangePlayerState(PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null) | |||||
| public bool StartThread(long stateNum, RunningStateType runningState) | |||||
| { | |||||
| lock (ActionLock) | |||||
| { | |||||
| if (this.StateNum == stateNum) | |||||
| { | |||||
| this.runningState = runningState; | |||||
| return true; | |||||
| } | |||||
| } | |||||
| return false; | |||||
| } | |||||
| private long ChangePlayerState(RunningStateType running, PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null) | |||||
| { | { | ||||
| //只能被SetPlayerState引用 | //只能被SetPlayerState引用 | ||||
| if (runningState == RunningStateType.RunningSleepily) | |||||
| { | |||||
| ThreadNum.Release(); | |||||
| } | |||||
| runningState = running; | |||||
| whatInteractingWith = gameObj; | whatInteractingWith = gameObj; | ||||
| playerState = value; | playerState = value; | ||||
| //Debugger.Output(this,playerState.ToString()+" "+IsMoving.ToString()); | |||||
| return ++stateNum; | return ++stateNum; | ||||
| } | } | ||||
| private long ChangePlayerStateInOneThread(PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null) | |||||
| private long ChangePlayerStateInOneThread(RunningStateType running, PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null) | |||||
| { | { | ||||
| if (runningState == RunningStateType.RunningSleepily) | |||||
| { | |||||
| ThreadNum.Release(); | |||||
| } | |||||
| runningState = running; | |||||
| //只能被SetPlayerState引用 | //只能被SetPlayerState引用 | ||||
| whatInteractingWith = gameObj; | whatInteractingWith = gameObj; | ||||
| playerState = value; | playerState = value; | ||||
| //Debugger.Output(this,playerState.ToString()+" "+IsMoving.ToString()); | |||||
| return stateNum; | return stateNum; | ||||
| } | } | ||||
| public long SetPlayerState(PlayerStateType value = PlayerStateType.Null, IGameObj? obj = null) | |||||
| public long SetPlayerState(RunningStateType runningState, PlayerStateType value = PlayerStateType.Null, IGameObj? obj = null) | |||||
| { | { | ||||
| GameObj? gameObj = (GameObj?)obj; | GameObj? gameObj = (GameObj?)obj; | ||||
| lock (actionLock) | lock (actionLock) | ||||
| { | { | ||||
| PlayerStateType nowPlayerState = PlayerState; | PlayerStateType nowPlayerState = PlayerState; | ||||
| if (nowPlayerState == value && value != PlayerStateType.UsingSkill) return -1; | if (nowPlayerState == value && value != PlayerStateType.UsingSkill) return -1; | ||||
| GameObj? lastObj = whatInteractingWith; | |||||
| switch (nowPlayerState) | switch (nowPlayerState) | ||||
| { | { | ||||
| case PlayerStateType.Escaped: | case PlayerStateType.Escaped: | ||||
| @@ -454,119 +484,85 @@ namespace GameClass.GameObj | |||||
| case PlayerStateType.Addicted: | case PlayerStateType.Addicted: | ||||
| if (value == PlayerStateType.Rescued) | if (value == PlayerStateType.Rescued) | ||||
| return ChangePlayerStateInOneThread(value, gameObj); | |||||
| return ChangePlayerStateInOneThread(runningState, value, gameObj); | |||||
| else if (value == PlayerStateType.Null || value == PlayerStateType.Deceased) | else if (value == PlayerStateType.Null || value == PlayerStateType.Deceased) | ||||
| return ChangePlayerState(value, gameObj); | |||||
| return ChangePlayerState(runningState, value, gameObj); | |||||
| else return -1; | else return -1; | ||||
| case PlayerStateType.Rescued: | case PlayerStateType.Rescued: | ||||
| if (value == PlayerStateType.Addicted) | if (value == PlayerStateType.Addicted) | ||||
| return ChangePlayerStateInOneThread(value, gameObj); | |||||
| return ChangePlayerStateInOneThread(runningState, value, gameObj); | |||||
| else if (value == PlayerStateType.Null || value == PlayerStateType.Deceased) | else if (value == PlayerStateType.Null || value == PlayerStateType.Deceased) | ||||
| return ChangePlayerState(value, gameObj); | |||||
| return ChangePlayerState(runningState, value, gameObj); | |||||
| else return -1; | else return -1; | ||||
| case PlayerStateType.TryingToAttack: | case PlayerStateType.TryingToAttack: | ||||
| if (value == PlayerStateType.Addicted || value == PlayerStateType.Swinging | if (value == PlayerStateType.Addicted || value == PlayerStateType.Swinging | ||||
| || value == PlayerStateType.Deceased || value == PlayerStateType.Stunned | || value == PlayerStateType.Deceased || value == PlayerStateType.Stunned | ||||
| || value == PlayerStateType.Charmed || value == PlayerStateType.Null) | || value == PlayerStateType.Charmed || value == PlayerStateType.Null) | ||||
| return ChangePlayerState(value, gameObj); | |||||
| return ChangePlayerState(runningState, value, gameObj); | |||||
| else return -1; | else return -1; | ||||
| case PlayerStateType.Stunned: | case PlayerStateType.Stunned: | ||||
| case PlayerStateType.Charmed: | case PlayerStateType.Charmed: | ||||
| if (value == PlayerStateType.Addicted || value == PlayerStateType.Deceased | if (value == PlayerStateType.Addicted || value == PlayerStateType.Deceased | ||||
| || value == PlayerStateType.Null) | || value == PlayerStateType.Null) | ||||
| return ChangePlayerState(value, gameObj); | |||||
| return ChangePlayerState(runningState, value, gameObj); | |||||
| else return -1; | else return -1; | ||||
| case PlayerStateType.Swinging: | case PlayerStateType.Swinging: | ||||
| if (value == PlayerStateType.Addicted | if (value == PlayerStateType.Addicted | ||||
| || value == PlayerStateType.Deceased || value == PlayerStateType.Stunned | || value == PlayerStateType.Deceased || value == PlayerStateType.Stunned | ||||
| || value == PlayerStateType.Charmed || value == PlayerStateType.Null) | || value == PlayerStateType.Charmed || value == PlayerStateType.Null) | ||||
| { | |||||
| try | |||||
| { | |||||
| return ChangePlayerState(value, gameObj); | |||||
| } | |||||
| finally | |||||
| { | |||||
| ThreadNum.Release(); | |||||
| } | |||||
| } | |||||
| return ChangePlayerState(runningState, value, gameObj); | |||||
| else return -1; | else return -1; | ||||
| case PlayerStateType.ClimbingThroughWindows: | case PlayerStateType.ClimbingThroughWindows: | ||||
| if (value == PlayerStateType.Addicted | if (value == PlayerStateType.Addicted | ||||
| || value == PlayerStateType.Deceased || value == PlayerStateType.Stunned | || value == PlayerStateType.Deceased || value == PlayerStateType.Stunned | ||||
| || value == PlayerStateType.Charmed || value == PlayerStateType.Null) | || value == PlayerStateType.Charmed || value == PlayerStateType.Null) | ||||
| { | { | ||||
| Window window = (Window)WhatInteractingWith!; | |||||
| try | |||||
| { | |||||
| window.FinishClimbing(); | |||||
| return ChangePlayerState(value, gameObj); | |||||
| } | |||||
| finally | |||||
| { | |||||
| if (window.Stage.x == 0) | |||||
| ThreadNum.Release(); | |||||
| else ReSetPos(window.Stage); | |||||
| } | |||||
| Window window = (Window)lastObj!; | |||||
| if (window.Stage.x != 0) ReSetPos(window.Stage); | |||||
| window.FinishClimbing(); | |||||
| return ChangePlayerState(runningState, value, gameObj); | |||||
| } | } | ||||
| else return -1; | else return -1; | ||||
| case PlayerStateType.OpeningTheChest: | case PlayerStateType.OpeningTheChest: | ||||
| ((Chest)whatInteractingWith!).StopOpen(); | |||||
| return ChangePlayerState(value, gameObj); | |||||
| if (value == PlayerStateType.Rescued) return -1; | |||||
| ((Chest)lastObj!).StopOpen(); | |||||
| return ChangePlayerState(runningState, value, gameObj); | |||||
| case PlayerStateType.OpeningTheDoorway: | case PlayerStateType.OpeningTheDoorway: | ||||
| try | |||||
| { | |||||
| Doorway doorway = (Doorway)whatInteractingWith!; | |||||
| doorway.StopOpenning(); | |||||
| return ChangePlayerState(value, gameObj); | |||||
| } | |||||
| finally | |||||
| { | |||||
| ThreadNum.Release(); | |||||
| } | |||||
| if (value == PlayerStateType.Rescued) return -1; | |||||
| Doorway doorway = (Doorway)lastObj!; | |||||
| doorway.StopOpenning(); | |||||
| return ChangePlayerState(runningState, value, gameObj); | |||||
| case PlayerStateType.OpeningTheDoor: | case PlayerStateType.OpeningTheDoor: | ||||
| Door door = (Door)whatInteractingWith!; | |||||
| try | |||||
| { | |||||
| door.StopOpen(); | |||||
| ReleaseTool(door.DoorNum switch | |||||
| { | |||||
| 3 => PropType.Key3, | |||||
| 5 => PropType.Key5, | |||||
| _ => PropType.Key6, | |||||
| } | |||||
| ); | |||||
| return ChangePlayerState(value, gameObj); | |||||
| } | |||||
| finally | |||||
| if (value == PlayerStateType.Rescued) return -1; | |||||
| Door door = (Door)lastObj!; | |||||
| door.StopOpen(); | |||||
| ReleaseTool(door.DoorNum switch | |||||
| { | { | ||||
| ThreadNum.Release(); | |||||
| 3 => PropType.Key3, | |||||
| 5 => PropType.Key5, | |||||
| _ => PropType.Key6, | |||||
| } | } | ||||
| ); | |||||
| return ChangePlayerState(runningState, value, gameObj); | |||||
| case PlayerStateType.UsingSkill: | case PlayerStateType.UsingSkill: | ||||
| { | { | ||||
| if (value == PlayerStateType.Rescued) return -1; | |||||
| switch (CharacterType) | switch (CharacterType) | ||||
| { | { | ||||
| case CharacterType.TechOtaku: | case CharacterType.TechOtaku: | ||||
| { | { | ||||
| if (typeof(CraftingBench).IsInstanceOfType(whatInteractingWith)) | |||||
| if (typeof(CraftingBench).IsInstanceOfType(lastObj)) | |||||
| { | { | ||||
| try | |||||
| { | |||||
| ((CraftingBench)whatInteractingWith!).StopSkill(); | |||||
| return ChangePlayerState(value, gameObj); | |||||
| } | |||||
| finally | |||||
| { | |||||
| ThreadNum.Release(); | |||||
| } | |||||
| ((CraftingBench)lastObj!).StopSkill(); | |||||
| return ChangePlayerState(runningState, value, gameObj); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| if (value != PlayerStateType.UsingSkill) | if (value != PlayerStateType.UsingSkill) | ||||
| ((UseRobot)FindActiveSkill(ActiveSkillType.UseRobot)).NowPlayerID = (int)playerID; | ((UseRobot)FindActiveSkill(ActiveSkillType.UseRobot)).NowPlayerID = (int)playerID; | ||||
| return ChangePlayerState(value, gameObj); | |||||
| return ChangePlayerState(runningState, value, gameObj); | |||||
| } | } | ||||
| } | } | ||||
| case CharacterType.Assassin: | case CharacterType.Assassin: | ||||
| @@ -574,14 +570,15 @@ namespace GameClass.GameObj | |||||
| else | else | ||||
| { | { | ||||
| TryDeleteInvisible(); | TryDeleteInvisible(); | ||||
| return ChangePlayerState(value, gameObj); | |||||
| return ChangePlayerState(runningState, value, gameObj); | |||||
| } | } | ||||
| default: | default: | ||||
| return ChangePlayerState(value, gameObj); | |||||
| return ChangePlayerState(runningState, value, gameObj); | |||||
| } | } | ||||
| } | } | ||||
| default: | default: | ||||
| return ChangePlayerState(value, gameObj); | |||||
| if (value == PlayerStateType.Rescued) return -1; | |||||
| return ChangePlayerState(runningState, value, gameObj); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -590,19 +587,33 @@ namespace GameClass.GameObj | |||||
| { | { | ||||
| lock (actionLock) | lock (actionLock) | ||||
| { | { | ||||
| runningState = RunningStateType.Null; | |||||
| whatInteractingWith = null; | whatInteractingWith = null; | ||||
| playerState = PlayerStateType.Null; | playerState = PlayerStateType.Null; | ||||
| return ++stateNum; | return ++stateNum; | ||||
| } | } | ||||
| } | } | ||||
| public bool ResetPlayerState(long state) | |||||
| { | |||||
| lock (actionLock) | |||||
| { | |||||
| if (state != stateNum) return false; | |||||
| runningState = RunningStateType.Null; | |||||
| whatInteractingWith = null; | |||||
| playerState = PlayerStateType.Null; | |||||
| ++stateNum; | |||||
| return true; | |||||
| } | |||||
| } | |||||
| public bool TryToRemoveFromGame(PlayerStateType playerStateType) | public bool TryToRemoveFromGame(PlayerStateType playerStateType) | ||||
| { | { | ||||
| lock (actionLock) | lock (actionLock) | ||||
| { | { | ||||
| if (!TryToRemove()) return false; | |||||
| if (SetPlayerState(RunningStateType.RunningForcibly, playerStateType) == -1) return false; | |||||
| TryToRemove(); | |||||
| ReSetCanMove(false); | ReSetCanMove(false); | ||||
| SetPlayerState(playerStateType); | |||||
| position = GameData.PosWhoDie; | position = GameData.PosWhoDie; | ||||
| } | } | ||||
| return true; | return true; | ||||
| @@ -1,5 +1,6 @@ | |||||
| using Preparation.Interface; | using Preparation.Interface; | ||||
| using Preparation.Utility; | using Preparation.Utility; | ||||
| using System; | |||||
| namespace GameClass.GameObj | namespace GameClass.GameObj | ||||
| { | { | ||||
| @@ -22,19 +23,20 @@ namespace GameClass.GameObj | |||||
| public int OpenStartTime => openStartTime; | public int OpenStartTime => openStartTime; | ||||
| private Character? whoOpen = null; | private Character? whoOpen = null; | ||||
| public Character? WhoOpen => whoOpen; | public Character? WhoOpen => whoOpen; | ||||
| public void Open(int startTime, Character character) | |||||
| public bool Open(Character character) | |||||
| { | { | ||||
| lock (GameObjReaderWriterLock) | lock (GameObjReaderWriterLock) | ||||
| { | { | ||||
| openStartTime = startTime; | |||||
| if (whoOpen != null) return false; | |||||
| openStartTime = Environment.TickCount; | |||||
| whoOpen = character; | whoOpen = character; | ||||
| } | } | ||||
| return true; | |||||
| } | } | ||||
| public void StopOpen() | public void StopOpen() | ||||
| { | { | ||||
| lock (GameObjReaderWriterLock) | lock (GameObjReaderWriterLock) | ||||
| { | { | ||||
| openStartTime = 0; | |||||
| whoOpen = null; | whoOpen = null; | ||||
| } | } | ||||
| } | } | ||||
| @@ -70,8 +70,8 @@ namespace GameClass.GameObj | |||||
| } | } | ||||
| } | } | ||||
| private long openStartTime = 0; | |||||
| public long OpenStartTime | |||||
| private int openStartTime = 0; | |||||
| public int OpenStartTime | |||||
| { | { | ||||
| get | get | ||||
| { | { | ||||
| @@ -86,7 +86,7 @@ namespace GameClass.GameObj | |||||
| { | { | ||||
| if (isOpen) return false; | if (isOpen) return false; | ||||
| if (whoLockOrOpen != null) return false; | if (whoLockOrOpen != null) return false; | ||||
| openStartTime = Environment.TickCount64; | |||||
| openStartTime = Environment.TickCount; | |||||
| whoLockOrOpen = character; | whoLockOrOpen = character; | ||||
| return true; | return true; | ||||
| } | } | ||||
| @@ -97,7 +97,7 @@ namespace GameClass.GameObj | |||||
| { | { | ||||
| if (whoLockOrOpen != null) | if (whoLockOrOpen != null) | ||||
| { | { | ||||
| if ((Environment.TickCount64 - openStartTime) >= GameData.degreeOfLockingOrOpeningTheDoor / whoLockOrOpen.SpeedOfOpeningOrLocking) | |||||
| if ((Environment.TickCount - openStartTime) >= GameData.degreeOfLockingOrOpeningTheDoor / whoLockOrOpen.SpeedOfOpeningOrLocking) | |||||
| isOpen = true; | isOpen = true; | ||||
| whoLockOrOpen = null; | whoLockOrOpen = null; | ||||
| } | } | ||||
| @@ -153,9 +153,23 @@ namespace GameClass.GameObj | |||||
| if (character != null) | if (character != null) | ||||
| { | { | ||||
| lock (character.ActionLock) | lock (character.ActionLock) | ||||
| { | |||||
| if (character.PlayerState == PlayerStateType.OpeningTheDoor) | if (character.PlayerState == PlayerStateType.OpeningTheDoor) | ||||
| character.SetPlayerState(); | |||||
| { | |||||
| character.ReleaseTool(DoorNum switch | |||||
| { | |||||
| 3 => PropType.Key3, | |||||
| 5 => PropType.Key5, | |||||
| _ => PropType.Key6, | |||||
| }); | |||||
| character.SetPlayerStateNaturally(); | |||||
| } | |||||
| else if (character.PlayerState == PlayerStateType.LockingTheDoor) | |||||
| { | |||||
| character.SetPlayerStateNaturally(); | |||||
| } | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| } | |||||
| @@ -29,6 +29,20 @@ namespace GameClass.GameObj | |||||
| } | } | ||||
| } | } | ||||
| protected RunningStateType runningState = RunningStateType.Null; | |||||
| public RunningStateType RunningState | |||||
| { | |||||
| get | |||||
| { | |||||
| lock (actionLock) return runningState; | |||||
| } | |||||
| set | |||||
| { | |||||
| lock (actionLock) | |||||
| runningState = value; | |||||
| } | |||||
| } | |||||
| public override XY Position | public override XY Position | ||||
| { | { | ||||
| get | get | ||||
| @@ -52,13 +52,7 @@ namespace GameClass.GameObj | |||||
| } | } | ||||
| public void TryStopSkill() | public void TryStopSkill() | ||||
| { | { | ||||
| lock (Parent!.ActionLock) | |||||
| { | |||||
| if (Parent!.StateNum == parentStateNum) | |||||
| { | |||||
| Parent!.SetPlayerState(); | |||||
| } | |||||
| } | |||||
| Parent!.ResetPlayerState(parentStateNum); | |||||
| } | } | ||||
| public override PropType GetPropType() => PropType.CraftingBench; | public override PropType GetPropType() => PropType.CraftingBench; | ||||
| } | } | ||||
| @@ -1,9 +1,7 @@ | |||||
| using System; | using System; | ||||
| using System.Numerics; | |||||
| using System.Threading; | using System.Threading; | ||||
| using GameClass.GameObj; | using GameClass.GameObj; | ||||
| using GameEngine; | using GameEngine; | ||||
| using Preparation.Interface; | |||||
| using Preparation.Utility; | using Preparation.Utility; | ||||
| using Timothy.FrameRateTask; | using Timothy.FrameRateTask; | ||||
| @@ -17,17 +15,19 @@ namespace Gaming | |||||
| public bool MovePlayer(Character playerToMove, int moveTimeInMilliseconds, double moveDirection) | public bool MovePlayer(Character playerToMove, int moveTimeInMilliseconds, double moveDirection) | ||||
| { | { | ||||
| if (moveTimeInMilliseconds < 5) return false; | if (moveTimeInMilliseconds < 5) return false; | ||||
| long stateNum = playerToMove.SetPlayerState(PlayerStateType.Moving); | |||||
| long stateNum = playerToMove.SetPlayerState(RunningStateType.Waiting, PlayerStateType.Moving); | |||||
| if (stateNum == -1) return false; | if (stateNum == -1) return false; | ||||
| new Thread | new Thread | ||||
| ( | ( | ||||
| () => | () => | ||||
| { | { | ||||
| playerToMove.ThreadNum.WaitOne(); | playerToMove.ThreadNum.WaitOne(); | ||||
| if (stateNum != playerToMove.StateNum) | |||||
| if (!playerToMove.StartThread(stateNum, RunningStateType.RunningActively)) | |||||
| { | |||||
| playerToMove.ThreadNum.Release(); | playerToMove.ThreadNum.Release(); | ||||
| else | |||||
| moveEngine.MoveObj(playerToMove, moveTimeInMilliseconds, moveDirection, stateNum); | |||||
| return; | |||||
| } | |||||
| moveEngine.MoveObj(playerToMove, moveTimeInMilliseconds, moveDirection, stateNum); | |||||
| } | } | ||||
| ) | ) | ||||
| { IsBackground = true }.Start(); | { IsBackground = true }.Start(); | ||||
| @@ -37,22 +37,28 @@ namespace Gaming | |||||
| public bool MovePlayerWhenStunned(Character playerToMove, int moveTimeInMilliseconds, double moveDirection) | public bool MovePlayerWhenStunned(Character playerToMove, int moveTimeInMilliseconds, double moveDirection) | ||||
| { | { | ||||
| if (playerToMove.CharacterType == CharacterType.Robot) return false; | if (playerToMove.CharacterType == CharacterType.Robot) return false; | ||||
| long stateNum = playerToMove.SetPlayerState(PlayerStateType.Charmed); | |||||
| long stateNum = playerToMove.SetPlayerState(RunningStateType.Waiting, PlayerStateType.Charmed); | |||||
| if (stateNum == -1) return false; | if (stateNum == -1) return false; | ||||
| new Thread | new Thread | ||||
| (() => | (() => | ||||
| { | { | ||||
| playerToMove.ThreadNum.WaitOne(); | playerToMove.ThreadNum.WaitOne(); | ||||
| if (stateNum != playerToMove.StateNum) | |||||
| if (!playerToMove.StartThread(stateNum, RunningStateType.RunningActively)) | |||||
| { | |||||
| playerToMove.ThreadNum.Release(); | playerToMove.ThreadNum.Release(); | ||||
| return; | |||||
| } | |||||
| else | else | ||||
| { | { | ||||
| moveEngine.MoveObj(playerToMove, moveTimeInMilliseconds, moveDirection, playerToMove.StateNum); | moveEngine.MoveObj(playerToMove, moveTimeInMilliseconds, moveDirection, playerToMove.StateNum); | ||||
| Thread.Sleep(moveTimeInMilliseconds); | Thread.Sleep(moveTimeInMilliseconds); | ||||
| lock (playerToMove.ActionLock) | lock (playerToMove.ActionLock) | ||||
| { | { | ||||
| if (stateNum == playerToMove.StateNum) | |||||
| playerToMove.SetPlayerStateNaturally(); | |||||
| lock (playerToMove.ActionLock) | |||||
| { | |||||
| if (stateNum == playerToMove.StateNum) | |||||
| playerToMove.SetPlayerStateNaturally(); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -67,7 +73,7 @@ namespace Gaming | |||||
| { | { | ||||
| if (player.Commandable()) | if (player.Commandable()) | ||||
| { | { | ||||
| player.SetPlayerState(); | |||||
| player.SetPlayerState(RunningStateType.Null); | |||||
| return true; | return true; | ||||
| } | } | ||||
| } | } | ||||
| @@ -79,21 +85,27 @@ namespace Gaming | |||||
| Generator? generatorForFix = (Generator?)gameMap.OneForInteract(player.Position, GameObjType.Generator); | Generator? generatorForFix = (Generator?)gameMap.OneForInteract(player.Position, GameObjType.Generator); | ||||
| if (generatorForFix == null) return false; | if (generatorForFix == null) return false; | ||||
| long stateNum = player.SetPlayerState(PlayerStateType.Fixing); | |||||
| long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.Fixing); | |||||
| if (stateNum == -1) return false; | if (stateNum == -1) return false; | ||||
| player.ThreadNum.WaitOne(); | |||||
| if (generatorForFix.DegreeOfRepair == GameData.degreeOfFixedGenerator) | |||||
| { | |||||
| player.ThreadNum.Release(); | |||||
| return false; | |||||
| } | |||||
| generatorForFix.AddNumOfFixing(); | |||||
| new Thread | new Thread | ||||
| ( | ( | ||||
| () => | () => | ||||
| { | { | ||||
| player.ThreadNum.WaitOne(); | |||||
| if (generatorForFix.DegreeOfRepair == GameData.degreeOfFixedGenerator) | |||||
| { | |||||
| player.ThreadNum.Release(); | |||||
| return; | |||||
| } | |||||
| if (!player.StartThread(stateNum, RunningStateType.RunningActively)) | |||||
| { | |||||
| player.ThreadNum.Release(); | |||||
| return; | |||||
| } | |||||
| generatorForFix.AddNumOfFixing(); | |||||
| Thread.Sleep(GameData.checkInterval); | Thread.Sleep(GameData.checkInterval); | ||||
| new FrameRateTaskExecutor<int>( | new FrameRateTaskExecutor<int>( | ||||
| loopCondition: () => stateNum == player.StateNum && gameMap.Timer.IsGaming, | loopCondition: () => stateNum == player.StateNum && gameMap.Timer.IsGaming, | ||||
| @@ -106,9 +118,11 @@ namespace Gaming | |||||
| lock (player.ActionLock) | lock (player.ActionLock) | ||||
| { | { | ||||
| if (stateNum == player.StateNum) | if (stateNum == player.StateNum) | ||||
| player.SetPlayerState(); | |||||
| player.SetPlayerState(RunningStateType.Null); | |||||
| } | } | ||||
| return false; | |||||
| } | } | ||||
| return true; | |||||
| }, | }, | ||||
| timeInterval: GameData.checkInterval, | timeInterval: GameData.checkInterval, | ||||
| finallyReturn: () => 0 | finallyReturn: () => 0 | ||||
| @@ -129,34 +143,27 @@ namespace Gaming | |||||
| Doorway? doorwayToOpen = (Doorway?)gameMap.OneForInteract(player.Position, GameObjType.Doorway); | Doorway? doorwayToOpen = (Doorway?)gameMap.OneForInteract(player.Position, GameObjType.Doorway); | ||||
| if (doorwayToOpen == null) return false; | if (doorwayToOpen == null) return false; | ||||
| long stateNum = player.SetPlayerState(PlayerStateType.OpeningTheDoorway, doorwayToOpen); | |||||
| long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.OpeningTheDoorway, doorwayToOpen); | |||||
| if (stateNum == -1) return false; | if (stateNum == -1) return false; | ||||
| new Thread | new Thread | ||||
| ( | ( | ||||
| () => | () => | ||||
| { | { | ||||
| player.ThreadNum.WaitOne(); | player.ThreadNum.WaitOne(); | ||||
| lock (player.ActionLock) | |||||
| if (!player.StartThread(stateNum, RunningStateType.RunningSleepily)) | |||||
| { | { | ||||
| if (stateNum != player.StateNum) | |||||
| { | |||||
| player.ThreadNum.Release(); | |||||
| return; | |||||
| } | |||||
| player.ThreadNum.Release(); | |||||
| return; | |||||
| } | } | ||||
| doorwayToOpen.TryToOpen(); | doorwayToOpen.TryToOpen(); | ||||
| Thread.Sleep(GameData.degreeOfOpenedDoorway - doorwayToOpen.OpenDegree); | Thread.Sleep(GameData.degreeOfOpenedDoorway - doorwayToOpen.OpenDegree); | ||||
| lock (player.ActionLock) | |||||
| if (player.ResetPlayerState(stateNum)) | |||||
| { | { | ||||
| if (stateNum == player.StateNum) | |||||
| { | |||||
| player.SetPlayerStateNaturally(); | |||||
| doorwayToOpen.FinishOpenning(); | |||||
| player.ThreadNum.Release(); | |||||
| } | |||||
| doorwayToOpen.FinishOpenning(); | |||||
| player.ThreadNum.Release(); | |||||
| } | } | ||||
| } | } | ||||
| ) | ) | ||||
| { IsBackground = true }.Start(); | { IsBackground = true }.Start(); | ||||
| @@ -165,14 +172,15 @@ namespace Gaming | |||||
| public bool Escape(Student player) | public bool Escape(Student player) | ||||
| { | { | ||||
| if (!(player.Commandable()) || player.CharacterType == CharacterType.Robot || player.CharacterType == CharacterType.Teacher) | |||||
| if (player.CharacterType == CharacterType.Robot || player.CharacterType == CharacterType.Teacher) | |||||
| return false; | return false; | ||||
| Doorway? doorwayForEscape = (Doorway?)gameMap.OneForInteract(player.Position, GameObjType.Doorway); | Doorway? doorwayForEscape = (Doorway?)gameMap.OneForInteract(player.Position, GameObjType.Doorway); | ||||
| if (doorwayForEscape != null && doorwayForEscape.IsOpen()) | if (doorwayForEscape != null && doorwayForEscape.IsOpen()) | ||||
| { | { | ||||
| if (!player.TryToRemoveFromGame(PlayerStateType.Escaped)) return false; | |||||
| player.AddScore(GameData.StudentScoreEscape); | player.AddScore(GameData.StudentScoreEscape); | ||||
| gameMap.MapEscapeStudent(); | gameMap.MapEscapeStudent(); | ||||
| player.TryToRemoveFromGame(PlayerStateType.Escaped); | |||||
| return true; | return true; | ||||
| } | } | ||||
| else | else | ||||
| @@ -180,9 +188,9 @@ namespace Gaming | |||||
| EmergencyExit? emergencyExit = (EmergencyExit?)gameMap.OneForInteract(player.Position, GameObjType.EmergencyExit); | EmergencyExit? emergencyExit = (EmergencyExit?)gameMap.OneForInteract(player.Position, GameObjType.EmergencyExit); | ||||
| if (emergencyExit != null && emergencyExit.IsOpen) | if (emergencyExit != null && emergencyExit.IsOpen) | ||||
| { | { | ||||
| if (!player.TryToRemoveFromGame(PlayerStateType.Escaped)) return false; | |||||
| player.AddScore(GameData.StudentScoreEscape); | player.AddScore(GameData.StudentScoreEscape); | ||||
| gameMap.MapEscapeStudent(); | gameMap.MapEscapeStudent(); | ||||
| player.TryToRemoveFromGame(PlayerStateType.Escaped); | |||||
| return true; | return true; | ||||
| } | } | ||||
| return false; | return false; | ||||
| @@ -197,38 +205,88 @@ namespace Gaming | |||||
| playerTreated = gameMap.StudentForInteract(player.Position); | playerTreated = gameMap.StudentForInteract(player.Position); | ||||
| if (playerTreated == null) return false; | if (playerTreated == null) return false; | ||||
| } | } | ||||
| if (player == playerTreated || (!player.Commandable()) || playerTreated.PlayerState == PlayerStateType.Treated || | |||||
| (!playerTreated.Commandable()) || | |||||
| playerTreated.HP == playerTreated.MaxHp || !GameData.ApproachToInteract(playerTreated.Position, player.Position)) | |||||
| else if (!GameData.ApproachToInteract(playerTreated.Position, player.Position)) return false; | |||||
| if (playerTreated.HP == playerTreated.MaxHp) return false; | |||||
| long stateNumTreated = playerTreated.SetPlayerState(RunningStateType.Waiting, PlayerStateType.Treated); | |||||
| if (stateNumTreated == -1) return false; | |||||
| long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.Treating); | |||||
| if (stateNum == -1) | |||||
| { | |||||
| lock (playerTreated.ActionLock) | |||||
| { | |||||
| if (playerTreated.StateNum == stateNumTreated) | |||||
| player.SetPlayerStateNaturally(); | |||||
| } | |||||
| return false; | return false; | ||||
| } | |||||
| new Thread | new Thread | ||||
| ( | ( | ||||
| () => | () => | ||||
| { | { | ||||
| playerTreated.SetPlayerState(PlayerStateType.Treated); | |||||
| player.SetPlayerState(PlayerStateType.Treating); | |||||
| long threadNum = player.StateNum; | |||||
| player.ThreadNum.WaitOne(); | |||||
| if (!player.StartThread(stateNum, RunningStateType.RunningActively)) | |||||
| { | |||||
| player.ThreadNum.Release(); | |||||
| lock (playerTreated.ActionLock) | |||||
| { | |||||
| if (playerTreated.StateNum == stateNumTreated) | |||||
| playerTreated.SetPlayerStateNaturally(); | |||||
| } | |||||
| return; | |||||
| } | |||||
| playerTreated.ThreadNum.WaitOne(); | |||||
| if (!playerTreated.StartThread(stateNum, RunningStateType.RunningActively)) | |||||
| { | |||||
| playerTreated.ThreadNum.Release(); | |||||
| lock (player.ActionLock) | |||||
| { | |||||
| if (player.StateNum == stateNum) | |||||
| player.SetPlayerStateNaturally(); | |||||
| } | |||||
| player.ThreadNum.Release(); | |||||
| return; | |||||
| } | |||||
| Thread.Sleep(GameData.checkInterval); | |||||
| new FrameRateTaskExecutor<int>( | new FrameRateTaskExecutor<int>( | ||||
| loopCondition: () => playerTreated.PlayerState == PlayerStateType.Treated && threadNum == player.StateNum && gameMap.Timer.IsGaming, | |||||
| loopCondition: () => stateNum == player.StateNum && gameMap.Timer.IsGaming, | |||||
| loopToDo: () => | loopToDo: () => | ||||
| { | { | ||||
| if (playerTreated.AddDegreeOfTreatment(GameData.frameDuration * player.TreatSpeed, player)) | |||||
| playerTreated.SetPlayerState();// | |||||
| lock (playerTreated.ActionLock) | |||||
| { | |||||
| if (playerTreated.StateNum == stateNumTreated) | |||||
| { | |||||
| if (playerTreated.AddDegreeOfTreatment(GameData.checkInterval * player.TreatSpeed, player)) | |||||
| { | |||||
| playerTreated.SetPlayerStateNaturally(); | |||||
| return false; | |||||
| } | |||||
| } | |||||
| else return false; | |||||
| } | |||||
| return true; | |||||
| }, | }, | ||||
| timeInterval: GameData.frameDuration, | |||||
| timeInterval: GameData.checkInterval, | |||||
| finallyReturn: () => 0 | finallyReturn: () => 0 | ||||
| ) | ) | ||||
| .Start(); | .Start(); | ||||
| player.ThreadNum.Release(); | |||||
| playerTreated.ThreadNum.Release(); | |||||
| if (player.ResetPlayerState(stateNum)) | |||||
| return; | |||||
| if (threadNum == player.StateNum) player.SetPlayerState(); | |||||
| else if (playerTreated.PlayerState == PlayerStateType.Treated) playerTreated.SetPlayerState(); | |||||
| playerTreated.ResetPlayerState(stateNumTreated); | |||||
| } | } | ||||
| ) | ) | ||||
| { IsBackground = true }.Start(); | { IsBackground = true }.Start(); | ||||
| return true; | return true; | ||||
| } | } | ||||
| public bool Rescue(Student player, Student? playerRescued = null) | public bool Rescue(Student player, Student? playerRescued = null) | ||||
| { | { | ||||
| if (player.CharacterType == CharacterType.Robot) return false; | if (player.CharacterType == CharacterType.Robot) return false; | ||||
| @@ -238,69 +296,123 @@ namespace Gaming | |||||
| playerRescued = gameMap.StudentForInteract(player.Position); | playerRescued = gameMap.StudentForInteract(player.Position); | ||||
| if (playerRescued == null) return false; | if (playerRescued == null) return false; | ||||
| } | } | ||||
| // else//no need | |||||
| // if (!GameData.ApproachToInteract(playerRescued.Position, player.Position)) return false; | |||||
| if ((!player.Commandable()) || playerRescued.PlayerState != PlayerStateType.Addicted || !GameData.ApproachToInteract(playerRescued.Position, player.Position)) | |||||
| long stateNumRescued = playerRescued.SetPlayerState(RunningStateType.Waiting, PlayerStateType.Rescued); | |||||
| if (stateNumRescued == -1) return false; | |||||
| long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.Rescuing); | |||||
| if (stateNum == -1) | |||||
| { | |||||
| lock (playerRescued.ActionLock) | |||||
| { | |||||
| if (playerRescued.StateNum == stateNumRescued) | |||||
| player.SetPlayerStateNaturally(); | |||||
| } | |||||
| return false; | return false; | ||||
| player.SetPlayerState(PlayerStateType.Rescuing); | |||||
| playerRescued.SetPlayerState(PlayerStateType.Rescued); | |||||
| long threadNum = player.StateNum; | |||||
| } | |||||
| new Thread | new Thread | ||||
| ( | ( | ||||
| () => | () => | ||||
| { | { | ||||
| player.ThreadNum.WaitOne(); | |||||
| if (!player.StartThread(stateNum, RunningStateType.RunningSleepily)) | |||||
| { | |||||
| player.ThreadNum.Release(); | |||||
| playerRescued.ResetPlayerState(stateNum); | |||||
| return; | |||||
| } | |||||
| playerRescued.ThreadNum.WaitOne(); | |||||
| if (!GameData.ApproachToInteract(playerRescued.Position, player.Position)) return; | |||||
| if (!playerRescued.StartThread(stateNum, RunningStateType.RunningSleepily)) | |||||
| { | |||||
| playerRescued.ThreadNum.Release(); | |||||
| if (!player.ResetPlayerState(stateNum)) | |||||
| player.ThreadNum.Release(); | |||||
| return; | |||||
| } | |||||
| new FrameRateTaskExecutor<int>( | new FrameRateTaskExecutor<int>( | ||||
| loopCondition: () => playerRescued.PlayerState == PlayerStateType.Rescued && threadNum == player.StateNum && gameMap.Timer.IsGaming, | |||||
| loopCondition: () => stateNum == player.StateNum && gameMap.Timer.IsGaming, | |||||
| loopToDo: () => | loopToDo: () => | ||||
| { | { | ||||
| playerRescued.TimeOfRescue += GameData.frameDuration; | |||||
| lock (playerRescued.ActionLock) | |||||
| { | |||||
| if (playerRescued.StateNum == stateNumRescued) | |||||
| { | |||||
| if (playerRescued.AddTimeOfRescue(GameData.checkInterval * player.TreatSpeed)) | |||||
| { | |||||
| playerRescued.SetPlayerStateNaturally(); | |||||
| playerRescued.HP = playerRescued.MaxHp / 2; | |||||
| player.AddScore(GameData.StudentScoreRescue); | |||||
| return false; | |||||
| } | |||||
| } | |||||
| else return false; | |||||
| } | |||||
| return true; | |||||
| }, | }, | ||||
| timeInterval: GameData.frameDuration, | |||||
| finallyReturn: () => 0, | |||||
| maxTotalDuration: GameData.basicTimeOfRescue | |||||
| timeInterval: GameData.checkInterval, | |||||
| finallyReturn: () => 0 | |||||
| ) | ) | ||||
| .Start(); | .Start(); | ||||
| playerRescued.SetTimeOfRescue(0); | |||||
| if (playerRescued.PlayerState == PlayerStateType.Rescued) | |||||
| if (player.ResetPlayerState(stateNum)) return; | |||||
| lock (playerRescued.ActionLock) | |||||
| { | { | ||||
| if (playerRescued.TimeOfRescue >= GameData.basicTimeOfRescue) | |||||
| if (playerRescued.StateNum == stateNumRescued) | |||||
| { | { | ||||
| playerRescued.SetPlayerState(); | |||||
| playerRescued.HP = playerRescued.MaxHp / 2; | |||||
| player.AddScore(GameData.StudentScoreRescue); | |||||
| playerRescued.SetPlayerState(RunningStateType.RunningForcibly, PlayerStateType.Addicted); | |||||
| return; | |||||
| } | } | ||||
| else | |||||
| playerRescued.SetPlayerState(PlayerStateType.Addicted); | |||||
| } | } | ||||
| if (threadNum == player.StateNum) player.SetPlayerState(); | |||||
| playerRescued.TimeOfRescue = 0; | |||||
| } | } | ||||
| ) | ) | ||||
| { IsBackground = true }.Start(); | { IsBackground = true }.Start(); | ||||
| return true; | return true; | ||||
| } | } | ||||
| public bool OpenChest(Character player) | public bool OpenChest(Character player) | ||||
| { | { | ||||
| if ((!player.Commandable()) || player.PlayerState == PlayerStateType.OpeningTheChest) | |||||
| return false; | |||||
| Chest? chestToOpen = (Chest?)gameMap.OneForInteract(player.Position, GameObjType.Chest); | Chest? chestToOpen = (Chest?)gameMap.OneForInteract(player.Position, GameObjType.Chest); | ||||
| if (chestToOpen == null) return false; | |||||
| if (chestToOpen == null || chestToOpen.OpenStartTime > 0) | |||||
| return false; | |||||
| long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.OpeningTheChest, chestToOpen); | |||||
| if (stateNum == -1) return false; | |||||
| player.SetPlayerState(PlayerStateType.OpeningTheChest, chestToOpen); | |||||
| int startTime = gameMap.Timer.nowTime(); | |||||
| chestToOpen.Open(startTime, player); | |||||
| new Thread | new Thread | ||||
| ( | ( | ||||
| () => | () => | ||||
| { | { | ||||
| player.ThreadNum.WaitOne(); | |||||
| lock (player.ActionLock) | |||||
| { | |||||
| if (!player.StartThread(stateNum, RunningStateType.RunningSleepily)) | |||||
| { | |||||
| player.ThreadNum.Release(); | |||||
| return; | |||||
| } | |||||
| else | |||||
| if (!chestToOpen.Open(player)) | |||||
| { | |||||
| player.ThreadNum.Release(); | |||||
| player.SetPlayerStateNaturally(); | |||||
| return; | |||||
| } | |||||
| } | |||||
| Thread.Sleep(GameData.degreeOfOpenedChest / player.SpeedOfOpenChest); | Thread.Sleep(GameData.degreeOfOpenedChest / player.SpeedOfOpenChest); | ||||
| if (chestToOpen.OpenStartTime == startTime) | |||||
| if (player.ResetPlayerState(stateNum)) | |||||
| { | { | ||||
| player.SetPlayerStateNaturally(); | |||||
| player.ThreadNum.Release(); | |||||
| for (int i = 0; i < GameData.maxNumOfPropInChest; ++i) | for (int i = 0; i < GameData.maxNumOfPropInChest; ++i) | ||||
| { | { | ||||
| Gadget prop = chestToOpen.PropInChest[i]; | Gadget prop = chestToOpen.PropInChest[i]; | ||||
| @@ -321,7 +433,7 @@ namespace Gaming | |||||
| Window? windowForClimb = (Window?)gameMap.OneForInteractInACross(player.Position, GameObjType.Window); | Window? windowForClimb = (Window?)gameMap.OneForInteractInACross(player.Position, GameObjType.Window); | ||||
| if (windowForClimb == null) return false; | if (windowForClimb == null) return false; | ||||
| long stateNum = player.SetPlayerState(PlayerStateType.ClimbingThroughWindows, windowForClimb); | |||||
| long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.ClimbingThroughWindows, windowForClimb); | |||||
| if (stateNum == -1) return false; | if (stateNum == -1) return false; | ||||
| XY windowToPlayer = new( | XY windowToPlayer = new( | ||||
| @@ -344,43 +456,43 @@ namespace Gaming | |||||
| () => | () => | ||||
| { | { | ||||
| player.ThreadNum.WaitOne(); | player.ThreadNum.WaitOne(); | ||||
| if (stateNum != player.StateNum) | |||||
| lock (player.ActionLock) | |||||
| { | { | ||||
| player.ThreadNum.Release(); | |||||
| } | |||||
| else | |||||
| { | |||||
| if (!windowForClimb.TryToClimb(player)) | |||||
| if (!player.StartThread(stateNum, RunningStateType.RunningSleepily)) | |||||
| { | { | ||||
| player.ThreadNum.Release(); | player.ThreadNum.Release(); | ||||
| player.SetPlayerStateNaturally(); | |||||
| return; | |||||
| } | } | ||||
| else | |||||
| if (!windowForClimb.TryToClimb(player)) | |||||
| { | { | ||||
| Thread.Sleep((int)((windowToPlayer + windowForClimb.Position - player.Position).Length() * 1000 / player.MoveSpeed)); | |||||
| player.SetPlayerStateNaturally(); | |||||
| player.ThreadNum.Release(); | |||||
| return; | |||||
| } | |||||
| } | |||||
| lock (player.ActionLock) | |||||
| { | |||||
| if (player.StateNum != stateNum) return; | |||||
| player.ReSetPos(windowToPlayer + windowForClimb.Position); | |||||
| windowForClimb.Enter2Stage(windowForClimb.Position - 2 * windowToPlayer); | |||||
| } | |||||
| Thread.Sleep((int)((windowToPlayer + windowForClimb.Position - player.Position).Length() * 1000 / player.MoveSpeed)); | |||||
| lock (player.ActionLock) | |||||
| { | |||||
| if (!player.StartThread(stateNum, RunningStateType.RunningActively)) return; | |||||
| player.ReSetPos(windowToPlayer + windowForClimb.Position); | |||||
| windowForClimb.Enter2Stage(windowForClimb.Position - 2 * windowToPlayer); | |||||
| } | |||||
| player.MoveSpeed = player.SpeedOfClimbingThroughWindows; | |||||
| moveEngine.MoveObj(player, (int)(GameData.numOfPosGridPerCell * 3 * 1000 / player.MoveSpeed / 2), (-1 * windowToPlayer).Angle(), stateNum); | |||||
| player.MoveSpeed = player.SpeedOfClimbingThroughWindows; | |||||
| moveEngine.MoveObj(player, (int)(GameData.numOfPosGridPerCell * 3 * 1000 / player.MoveSpeed / 2), (-1 * windowToPlayer).Angle(), stateNum); | |||||
| Thread.Sleep((int)(GameData.numOfPosGridPerCell * 3 * 1000 / player.MoveSpeed / 2)); | |||||
| Thread.Sleep((int)(GameData.numOfPosGridPerCell * 3 * 1000 / player.MoveSpeed / 2)); | |||||
| player.MoveSpeed = player.ReCalculateBuff(BuffType.AddSpeed, player.OrgMoveSpeed, GameData.MaxSpeed, GameData.MinSpeed); | |||||
| player.MoveSpeed = player.ReCalculateBuff(BuffType.AddSpeed, player.OrgMoveSpeed, GameData.MaxSpeed, GameData.MinSpeed); | |||||
| lock (player.ActionLock) | |||||
| { | |||||
| if (stateNum == player.StateNum) | |||||
| { | |||||
| player.SetPlayerState(); | |||||
| windowForClimb.FinishClimbing(); | |||||
| } | |||||
| } | |||||
| lock (player.ActionLock) | |||||
| { | |||||
| if (stateNum == player.StateNum) | |||||
| { | |||||
| player.SetPlayerStateNaturally(); | |||||
| windowForClimb.FinishClimbing(); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -404,7 +516,7 @@ namespace Gaming | |||||
| if (!player.UseTool(propType)) return false; | if (!player.UseTool(propType)) return false; | ||||
| long stateNum = player.SetPlayerState(PlayerStateType.LockingTheDoor, doorToLock); | |||||
| long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.LockingTheDoor, doorToLock); | |||||
| if (stateNum == -1) | if (stateNum == -1) | ||||
| { | { | ||||
| player.ReleaseTool(propType); | player.ReleaseTool(propType); | ||||
| @@ -416,47 +528,37 @@ namespace Gaming | |||||
| () => | () => | ||||
| { | { | ||||
| player.ThreadNum.WaitOne(); | player.ThreadNum.WaitOne(); | ||||
| if (stateNum != player.StateNum) | |||||
| if (!player.StartThread(stateNum, RunningStateType.RunningActively)) | |||||
| { | { | ||||
| player.ReleaseTool(propType); | player.ReleaseTool(propType); | ||||
| player.ThreadNum.Release(); | player.ThreadNum.Release(); | ||||
| return; | |||||
| } | } | ||||
| else | |||||
| if (!doorToLock.TryLock(player)) | |||||
| { | { | ||||
| if (!doorToLock.TryLock(player)) | |||||
| { | |||||
| player.ReleaseTool(propType); | |||||
| lock (player.ActionLock) | |||||
| { | |||||
| if (stateNum == player.StateNum) player.SetPlayerState(); | |||||
| } | |||||
| player.ThreadNum.Release(); | |||||
| } | |||||
| else | |||||
| { | |||||
| Thread.Sleep(GameData.checkInterval); | |||||
| new FrameRateTaskExecutor<int>( | |||||
| loopCondition: () => stateNum == player.StateNum && gameMap.Timer.IsGaming && doorToLock.LockDegree < GameData.degreeOfLockingOrOpeningTheDoor, | |||||
| loopToDo: () => | |||||
| { | |||||
| if ((gameMap.PartInTheSameCell(doorToLock.Position, GameObjType.Character)) != null) | |||||
| return false; | |||||
| doorToLock.LockDegree += GameData.checkInterval * player.SpeedOfOpeningOrLocking; | |||||
| return true; | |||||
| }, | |||||
| timeInterval: GameData.checkInterval, | |||||
| finallyReturn: () => 0 | |||||
| ) | |||||
| .Start(); | |||||
| doorToLock.StopLock(); | |||||
| player.ReleaseTool(propType); | |||||
| lock (player.ActionLock) | |||||
| { | |||||
| if (stateNum == player.StateNum) player.SetPlayerStateNaturally(); | |||||
| } | |||||
| player.ThreadNum.Release(); | |||||
| } | |||||
| player.ReleaseTool(propType); | |||||
| player.ResetPlayerState(stateNum); | |||||
| player.ThreadNum.Release(); | |||||
| return; | |||||
| } | } | ||||
| Thread.Sleep(GameData.checkInterval); | |||||
| new FrameRateTaskExecutor<int>( | |||||
| loopCondition: () => stateNum == player.StateNum && gameMap.Timer.IsGaming && doorToLock.LockDegree < GameData.degreeOfLockingOrOpeningTheDoor, | |||||
| loopToDo: () => | |||||
| { | |||||
| if ((gameMap.PartInTheSameCell(doorToLock.Position, GameObjType.Character)) != null) | |||||
| return false; | |||||
| doorToLock.LockDegree += GameData.checkInterval * player.SpeedOfOpeningOrLocking; | |||||
| return true; | |||||
| }, | |||||
| timeInterval: GameData.checkInterval, | |||||
| finallyReturn: () => 0 | |||||
| ) | |||||
| .Start(); | |||||
| doorToLock.StopLock(); | |||||
| player.ReleaseTool(propType); | |||||
| player.ThreadNum.Release(); | |||||
| player.ResetPlayerState(stateNum); | |||||
| } | } | ||||
| ) | ) | ||||
| { IsBackground = true }.Start(); | { IsBackground = true }.Start(); | ||||
| @@ -479,7 +581,7 @@ namespace Gaming | |||||
| if (!player.UseTool(propType)) return false; | if (!player.UseTool(propType)) return false; | ||||
| long stateNum = player.SetPlayerState(PlayerStateType.OpeningTheDoor, doorToLock); | |||||
| long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.OpeningTheDoor, doorToLock); | |||||
| if (stateNum == -1) | if (stateNum == -1) | ||||
| { | { | ||||
| player.ReleaseTool(propType); | player.ReleaseTool(propType); | ||||
| @@ -491,42 +593,29 @@ namespace Gaming | |||||
| () => | () => | ||||
| { | { | ||||
| player.ThreadNum.WaitOne(); | player.ThreadNum.WaitOne(); | ||||
| if (stateNum != player.StateNum) | |||||
| if (!player.StartThread(stateNum, RunningStateType.RunningSleepily)) | |||||
| { | { | ||||
| player.ReleaseTool(propType); | player.ReleaseTool(propType); | ||||
| player.ThreadNum.Release(); | player.ThreadNum.Release(); | ||||
| return; | |||||
| } | } | ||||
| else | |||||
| if (!doorToLock.TryOpen(player)) | |||||
| { | { | ||||
| if (!doorToLock.TryOpen(player)) | |||||
| { | |||||
| player.ReleaseTool(propType); | |||||
| lock (player.ActionLock) | |||||
| { | |||||
| if (stateNum == player.StateNum) | |||||
| { | |||||
| player.SetPlayerStateNaturally(); | |||||
| player.ThreadNum.Release(); | |||||
| } | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| Thread.Sleep(GameData.degreeOfLockingOrOpeningTheDoor / player.SpeedOfOpeningOrLocking); | |||||
| player.ReleaseTool(propType); | |||||
| if (player.ResetPlayerState(stateNum)) | |||||
| player.ThreadNum.Release(); | |||||
| return; | |||||
| } | |||||
| Thread.Sleep(GameData.degreeOfLockingOrOpeningTheDoor / player.SpeedOfOpeningOrLocking); | |||||
| lock (player.ActionLock) | |||||
| { | |||||
| if (stateNum == player.StateNum) | |||||
| { | |||||
| player.SetPlayerStateNaturally(); | |||||
| doorToLock.StopOpen(); | |||||
| player.ReleaseTool(propType); | |||||
| player.ThreadNum.Release(); | |||||
| } | |||||
| } | |||||
| } | |||||
| if (player.ResetPlayerState(stateNum)) | |||||
| { | |||||
| doorToLock.StopOpen(); | |||||
| player.ReleaseTool(propType); | |||||
| player.ThreadNum.Release(); | |||||
| } | } | ||||
| } | } | ||||
| ) | ) | ||||
| { IsBackground = true }.Start(); | { IsBackground = true }.Start(); | ||||
| @@ -30,7 +30,7 @@ namespace Gaming | |||||
| }, | }, | ||||
| EndMove: obj => | EndMove: obj => | ||||
| { | { | ||||
| 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.TickCount); | |||||
| if (obj.CanMove && ((Bullet)obj).TypeOfBullet != BulletType.JumpyDumpty) | if (obj.CanMove && ((Bullet)obj).TypeOfBullet != BulletType.JumpyDumpty) | ||||
| BulletBomb((Bullet)obj, null); | BulletBomb((Bullet)obj, null); | ||||
| obj.ReSetCanMove(false); | obj.ReSetCanMove(false); | ||||
| @@ -201,6 +201,8 @@ namespace Gaming | |||||
| public bool Attack(Character player, double angle) | public bool Attack(Character player, double angle) | ||||
| { // 子弹如果没有和其他物体碰撞,将会一直向前直到超出人物的attackRange | { // 子弹如果没有和其他物体碰撞,将会一直向前直到超出人物的attackRange | ||||
| if (!player.Commandable()) return false; | |||||
| Bullet? bullet = player.Attack(angle, gameMap.Timer.nowTime()); | Bullet? bullet = player.Attack(angle, gameMap.Timer.nowTime()); | ||||
| if (bullet != null) | if (bullet != null) | ||||
| @@ -212,14 +214,24 @@ namespace Gaming | |||||
| if (bullet.CastTime > 0) | if (bullet.CastTime > 0) | ||||
| { | { | ||||
| player.SetPlayerState(PlayerStateType.TryingToAttack); | |||||
| long threadNum = player.StateNum; | |||||
| long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.TryingToAttack); | |||||
| if (stateNum == -1) | |||||
| { | |||||
| TryRemoveBullet(bullet); | |||||
| return false; | |||||
| } | |||||
| new Thread | new Thread | ||||
| (() => | (() => | ||||
| { | { | ||||
| player.ThreadNum.WaitOne(); | |||||
| if (!player.StartThread(stateNum, RunningStateType.RunningActively)) | |||||
| { | |||||
| TryRemoveBullet(bullet); | |||||
| return; | |||||
| } | |||||
| new FrameRateTaskExecutor<int>( | new FrameRateTaskExecutor<int>( | ||||
| loopCondition: () => threadNum == player.StateNum && gameMap.Timer.IsGaming, | |||||
| loopCondition: () => stateNum == player.StateNum && gameMap.Timer.IsGaming, | |||||
| loopToDo: () => | loopToDo: () => | ||||
| { | { | ||||
| }, | }, | ||||
| @@ -231,11 +243,8 @@ namespace Gaming | |||||
| if (gameMap.Timer.IsGaming) | if (gameMap.Timer.IsGaming) | ||||
| { | { | ||||
| if (threadNum == player.StateNum) | |||||
| { | |||||
| player.SetPlayerState(); | |||||
| } | |||||
| else TryRemoveBullet(bullet); | |||||
| if (!player.ResetPlayerState(stateNum)) | |||||
| TryRemoveBullet(bullet); | |||||
| } | } | ||||
| } | } | ||||
| ) | ) | ||||
| @@ -218,11 +218,8 @@ namespace Gaming | |||||
| public void BeAddictedToGame(Student player, Ghost ghost) | public void BeAddictedToGame(Student player, Ghost ghost) | ||||
| { | { | ||||
| long stateNum = player.SetPlayerState(PlayerStateType.Addicted); | |||||
| if (stateNum == -1) | |||||
| { | |||||
| return; | |||||
| } | |||||
| long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.Addicted); | |||||
| if (stateNum == -1) return; | |||||
| if (player.CharacterType == CharacterType.Robot) | if (player.CharacterType == CharacterType.Robot) | ||||
| { | { | ||||
| @@ -278,19 +275,18 @@ namespace Gaming | |||||
| public static long BeStunned(Character player, int time) | public static long BeStunned(Character player, int time) | ||||
| { | { | ||||
| if (player.CharacterType == CharacterType.Robot) return -1; | if (player.CharacterType == CharacterType.Robot) return -1; | ||||
| long threadNum = player.SetPlayerState(PlayerStateType.Stunned); | |||||
| if (threadNum == -1) return -1; | |||||
| long stateNum = player.SetPlayerState(RunningStateType.RunningForcibly, PlayerStateType.Stunned); | |||||
| if (stateNum == -1) return -1; | |||||
| new Thread | new Thread | ||||
| (() => | (() => | ||||
| { | { | ||||
| Debugger.Output(player, " is stunned for " + time.ToString()); | Debugger.Output(player, " is stunned for " + time.ToString()); | ||||
| Thread.Sleep(time); | Thread.Sleep(time); | ||||
| if (threadNum == player.StateNum) | |||||
| player.SetPlayerState(); | |||||
| player.ResetPlayerState(stateNum); | |||||
| } | } | ||||
| ) | ) | ||||
| { IsBackground = true }.Start(); | { IsBackground = true }.Start(); | ||||
| return threadNum; | |||||
| return stateNum; | |||||
| } | } | ||||
| public bool TryBeAwed(Student character, Bullet bullet) | public bool TryBeAwed(Student character, Bullet bullet) | ||||
| @@ -378,23 +374,14 @@ namespace Gaming | |||||
| public bool BackSwing(Character player, int time) | public bool BackSwing(Character player, int time) | ||||
| { | { | ||||
| if (time <= 0) return false; | if (time <= 0) return false; | ||||
| long stateNum = player.SetPlayerState(PlayerStateType.Swinging); | |||||
| long stateNum = player.SetPlayerState(RunningStateType.RunningForcibly, PlayerStateType.Swinging); | |||||
| if (stateNum == -1) return false; | if (stateNum == -1) return false; | ||||
| new Thread | new Thread | ||||
| (() => | (() => | ||||
| { | { | ||||
| player.ThreadNum.WaitOne(); | |||||
| Thread.Sleep(time); | Thread.Sleep(time); | ||||
| lock (player.ActionLock) | |||||
| { | |||||
| if (stateNum == player.StateNum) | |||||
| { | |||||
| player.ThreadNum.Release(); | |||||
| player.SetPlayerStateNaturally(); | |||||
| } | |||||
| } | |||||
| player.ResetPlayerState(stateNum); | |||||
| } | } | ||||
| ) | ) | ||||
| { IsBackground = true }.Start(); | { IsBackground = true }.Start(); | ||||
| @@ -428,7 +415,7 @@ namespace Gaming | |||||
| lock (parent.ActionLock) | lock (parent.ActionLock) | ||||
| { | { | ||||
| if (parent.PlayerState == PlayerStateType.UsingSkill) | if (parent.PlayerState == PlayerStateType.UsingSkill) | ||||
| parent.SetPlayerState(); | |||||
| parent.SetPlayerStateNaturally(); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -225,7 +225,7 @@ namespace Gaming | |||||
| if (!gameMap.Timer.IsGaming) | if (!gameMap.Timer.IsGaming) | ||||
| return false; | return false; | ||||
| Character? player = gameMap.FindPlayerToAction(playerID); | Character? player = gameMap.FindPlayerToAction(playerID); | ||||
| if (player != null && player.Commandable()) | |||||
| if (player != null) | |||||
| { | { | ||||
| return attackManager.Attack(player, angle); | return attackManager.Attack(player, angle); | ||||
| } | } | ||||
| @@ -93,7 +93,7 @@ namespace Gaming | |||||
| public static bool BecomeInvisible(Character player) | public static bool BecomeInvisible(Character player) | ||||
| { | { | ||||
| ActiveSkill activeSkill = player.FindActiveSkill(ActiveSkillType.BecomeInvisible); | ActiveSkill activeSkill = player.FindActiveSkill(ActiveSkillType.BecomeInvisible); | ||||
| long stateNum = player.SetPlayerState(PlayerStateType.UsingSkill); | |||||
| long stateNum = player.SetPlayerState(RunningStateType.RunningForcibly, PlayerStateType.UsingSkill); | |||||
| if (stateNum == -1) | if (stateNum == -1) | ||||
| { | { | ||||
| return false; | return false; | ||||
| @@ -106,15 +106,9 @@ namespace Gaming | |||||
| }, | }, | ||||
| () => | () => | ||||
| { | { | ||||
| lock (player.ActionLock) | |||||
| { | |||||
| if (stateNum == player.StateNum) | |||||
| { | |||||
| player.SetPlayerStateNaturally(); | |||||
| } | |||||
| } | |||||
| player.ResetPlayerState(stateNum); | |||||
| } | } | ||||
| ); | |||||
| ); | |||||
| } | } | ||||
| public static bool UseRobot(Character player, int robotID) | public static bool UseRobot(Character player, int robotID) | ||||
| @@ -141,7 +135,7 @@ namespace Gaming | |||||
| activeSkill.NowPlayerID = robotID; | activeSkill.NowPlayerID = robotID; | ||||
| } | } | ||||
| else return false; | else return false; | ||||
| long stateNum = player.SetPlayerState(PlayerStateType.UsingSkill); | |||||
| long stateNum = player.SetPlayerState(RunningStateType.RunningForcibly, PlayerStateType.UsingSkill); | |||||
| if (stateNum == -1) | if (stateNum == -1) | ||||
| { | { | ||||
| activeSkill.NowPlayerID = (int)player.PlayerID; | activeSkill.NowPlayerID = (int)player.PlayerID; | ||||
| @@ -250,48 +244,48 @@ namespace Gaming | |||||
| { | { | ||||
| CraftingBench craftingBench = new(res, player, num); | CraftingBench craftingBench = new(res, player, num); | ||||
| long stateNum = player.SetPlayerState(PlayerStateType.UsingSkill, craftingBench); | |||||
| long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.UsingSkill, craftingBench); | |||||
| if (stateNum == -1) | if (stateNum == -1) | ||||
| { | { | ||||
| ((SummonGolem)activeSkill).DeleteGolem(num); | ((SummonGolem)activeSkill).DeleteGolem(num); | ||||
| return false; | return false; | ||||
| } | } | ||||
| player.ThreadNum.WaitOne(); | |||||
| if (stateNum != player.StateNum) | |||||
| { | |||||
| ((SummonGolem)activeSkill).DeleteGolem(num); | |||||
| player.ThreadNum.Release(); | |||||
| return false; | |||||
| } | |||||
| if (actionManager.moveEngine.CheckCollision(craftingBench, res) != null) | |||||
| { | |||||
| ((SummonGolem)activeSkill).DeleteGolem(num); | |||||
| player.ThreadNum.Release(); | |||||
| return false; | |||||
| } | |||||
| craftingBench.ParentStateNum = stateNum; | |||||
| gameMap.Add(craftingBench); | |||||
| return ActiveSkillEffect(activeSkill, player, () => | return ActiveSkillEffect(activeSkill, player, () => | ||||
| { | { | ||||
| player.ThreadNum.WaitOne(); | |||||
| if (!player.StartThread(stateNum, RunningStateType.RunningSleepily)) | |||||
| { | |||||
| ((SummonGolem)activeSkill).DeleteGolem(num); | |||||
| player.ThreadNum.Release(); | |||||
| } | |||||
| else | |||||
| { | |||||
| if (actionManager.moveEngine.CheckCollision(craftingBench, res) != null) | |||||
| { | |||||
| ((SummonGolem)activeSkill).DeleteGolem(num); | |||||
| if (player.ResetPlayerState(stateNum)) | |||||
| player.ThreadNum.Release(); | |||||
| } | |||||
| else | |||||
| { | |||||
| craftingBench.ParentStateNum = stateNum; | |||||
| gameMap.Add(craftingBench); | |||||
| } | |||||
| } | |||||
| }, | }, | ||||
| () => | () => | ||||
| { | { | ||||
| lock (player.ActionLock) | |||||
| if (player.ResetPlayerState(stateNum)) | |||||
| { | { | ||||
| if (stateNum == player.StateNum) | |||||
| gameMap.RemoveJustFromMap(craftingBench); | |||||
| Golem? golem = (Golem?)characterManager.AddPlayer(res, player.TeamID, (num + 1) * GameData.numOfPeople + player.PlayerID, CharacterType.Robot, player); | |||||
| if (golem == null) | |||||
| { | { | ||||
| gameMap.RemoveJustFromMap(craftingBench); | |||||
| Golem? golem = (Golem?)characterManager.AddPlayer(res, player.TeamID, (num + 1) * GameData.numOfPeople + player.PlayerID, CharacterType.Robot, player); | |||||
| if (golem == null) | |||||
| { | |||||
| ((SummonGolem)activeSkill).AddGolem(num); | |||||
| } | |||||
| player.SetPlayerStateNaturally(); | |||||
| player.ThreadNum.Release(); | |||||
| ((SummonGolem)activeSkill).AddGolem(num); | |||||
| } | } | ||||
| player.ThreadNum.Release(); | |||||
| } | } | ||||
| } | } | ||||
| ); | ); | ||||
| @@ -373,34 +367,36 @@ namespace Gaming | |||||
| public bool HaveTea(Character player, int angle1000) | public bool HaveTea(Character player, int angle1000) | ||||
| { | { | ||||
| long stateNum = player.SetPlayerState(PlayerStateType.UsingSkill); | |||||
| long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.UsingSkill); | |||||
| if (stateNum == -1) | if (stateNum == -1) | ||||
| { | { | ||||
| return false; | return false; | ||||
| } | } | ||||
| player.ThreadNum.WaitOne(); | |||||
| XY res = player.Position + new XY(angle1000 / 1000.0, GameData.distanceOfHaveTea); | |||||
| Debugger.Output(res.ToString()); | |||||
| if (actionManager.moveEngine.CheckCollision(player, res) != null) | |||||
| { | |||||
| player.ThreadNum.Release(); | |||||
| return false; | |||||
| } | |||||
| Debugger.Output("NO Collision!"); | |||||
| player.ReSetPos(res); | |||||
| lock (player.ActionLock) | |||||
| return ActiveSkillEffect(player.FindActiveSkill(ActiveSkillType.HaveTea), player, () => | |||||
| { | { | ||||
| if (player.StateNum == stateNum) | |||||
| player.ThreadNum.WaitOne(); | |||||
| XY res = player.Position + new XY(angle1000 / 1000.0, GameData.distanceOfHaveTea); | |||||
| if (!player.StartThread(stateNum, RunningStateType.RunningActively)) | |||||
| { | { | ||||
| player.SetPlayerStateNaturally(); | |||||
| player.ThreadNum.Release(); | |||||
| } | |||||
| else | |||||
| { | |||||
| if (actionManager.moveEngine.CheckCollision(player, res) != null) | |||||
| { | |||||
| player.ThreadNum.Release(); | |||||
| } | |||||
| else | |||||
| { | |||||
| Debugger.Output("NO Collision!"); | |||||
| player.ReSetPos(res); | |||||
| player.ThreadNum.Release(); | |||||
| player.ResetPlayerState(stateNum); | |||||
| Debugger.Output(player, "have tea!"); | |||||
| } | |||||
| } | } | ||||
| } | |||||
| player.ThreadNum.Release(); | |||||
| return ActiveSkillEffect(player.FindActiveSkill(ActiveSkillType.HaveTea), player, () => | |||||
| { | |||||
| Debugger.Output(player, "have tea!"); | |||||
| }, | }, | ||||
| () => | () => | ||||
| { }); | { }); | ||||
| @@ -416,13 +412,16 @@ namespace Gaming | |||||
| { | { | ||||
| foreach (Character character in gameMap.GameObjDict[GameObjType.Character]) | foreach (Character character in gameMap.GameObjDict[GameObjType.Character]) | ||||
| { | { | ||||
| if ((character.PlayerState == PlayerStateType.Addicted) && gameMap.CanSee(player, character)) | |||||
| lock (character.ActionLock) | |||||
| { | { | ||||
| character.SetPlayerState(); | |||||
| character.HP = GameData.RemainHpWhenAddLife; | |||||
| ((Student)character).TimeOfRescue = 0; | |||||
| player.AddScore(GameData.StudentScoreRescue); | |||||
| break; | |||||
| if ((character.PlayerState == PlayerStateType.Addicted) && gameMap.CanSee(player, character)) | |||||
| { | |||||
| character.SetPlayerStateNaturally(); | |||||
| character.HP = GameData.RemainHpWhenAddLife; | |||||
| ((Student)character).SetTimeOfRescue(0); | |||||
| player.AddScore(GameData.StudentScoreRescue); | |||||
| break; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -15,7 +15,8 @@ namespace Preparation.Interface | |||||
| public CharacterType CharacterType { get; } | public CharacterType CharacterType { get; } | ||||
| public ActiveSkill FindActiveSkill(ActiveSkillType activeSkillType); | public ActiveSkill FindActiveSkill(ActiveSkillType activeSkillType); | ||||
| public int UpdateBulletNum(int time); | public int UpdateBulletNum(int time); | ||||
| public long SetPlayerState(PlayerStateType value = PlayerStateType.Null, IGameObj? obj = null); | |||||
| public long SetPlayerState(RunningStateType running, PlayerStateType value = PlayerStateType.Null, IGameObj? obj = null); | |||||
| public bool ResetPlayerState(long state); | |||||
| public bool IsGhost(); | public bool IsGhost(); | ||||
| } | } | ||||
| @@ -27,6 +27,14 @@ namespace Preparation.Utility | |||||
| Charmed = 18, | Charmed = 18, | ||||
| OpeningTheDoor = 19, | OpeningTheDoor = 19, | ||||
| } | } | ||||
| public enum RunningStateType | |||||
| { | |||||
| Null = 0, | |||||
| Waiting = 1, | |||||
| RunningActively = 2, | |||||
| RunningSleepily = 3, | |||||
| RunningForcibly = 4, | |||||
| } | |||||
| public enum GameObjType | public enum GameObjType | ||||
| { | { | ||||
| Null = 0, | Null = 0, | ||||
| @@ -133,7 +133,7 @@ namespace Server | |||||
| currentGameInfo.ObjMessage.Add(currentMapMsg); | currentGameInfo.ObjMessage.Add(currentMapMsg); | ||||
| IsSpectatorJoin = false; | IsSpectatorJoin = false; | ||||
| } | } | ||||
| int time = game.GameMap.Timer.nowTime(); | |||||
| int time = Environment.TickCount; | |||||
| foreach (GameObj gameObj in gameObjList) | foreach (GameObj gameObj in gameObjList) | ||||
| { | { | ||||
| MessageOfObj? msg = CopyInfo.Auto(gameObj, time); | MessageOfObj? msg = CopyInfo.Auto(gameObj, time); | ||||