| @@ -1,5 +1,5 @@ | |||||
| # 规则 | # 规则 | ||||
| V5.3 | |||||
| V5.4 | |||||
| - [规则](#规则) | - [规则](#规则) | ||||
| - [简则](#简则) | - [简则](#简则) | ||||
| - [地图](#地图) | - [地图](#地图) | ||||
| @@ -201,11 +201,11 @@ $$ | |||||
| #### Assassin | #### Assassin | ||||
| - 普通攻击为 CommonAttackOfGhost | - 普通攻击为 CommonAttackOfGhost | ||||
| - 主动技能 | - 主动技能 | ||||
| - 隐身 BecomeInvisible | |||||
| 0. 隐身 BecomeInvisible | |||||
| - CD:40s 持续时间:10s | - CD:40s 持续时间:10s | ||||
| - 在持续时间内玩家隐身 | - 在持续时间内玩家隐身 | ||||
| - 使用瞬间得分15 | - 使用瞬间得分15 | ||||
| - 使用飞刀 | |||||
| 1. 使用飞刀 | |||||
| - CD:30s 持续时间:1s | - CD:30s 持续时间:1s | ||||
| - 在持续时间内,攻击类型变为飞刀 | - 在持续时间内,攻击类型变为飞刀 | ||||
| - 不直接得分 | - 不直接得分 | ||||
| @@ -213,7 +213,7 @@ $$ | |||||
| #### Klee | #### Klee | ||||
| - 普通攻击为 CommonAttackOfGhost | - 普通攻击为 CommonAttackOfGhost | ||||
| - 主动技能 | - 主动技能 | ||||
| - 蹦蹦炸弹 JumpyBomb | |||||
| 0. 蹦蹦炸弹 JumpyBomb | |||||
| - CD:15s 持续时间:3s | - CD:15s 持续时间:3s | ||||
| - 在持续时间内,攻击类型变为蹦蹦炸弹 | - 在持续时间内,攻击类型变为蹦蹦炸弹 | ||||
| - 当蹦蹦炸弹因为碰撞而爆炸,向子弹方向上加上90°,270° 发出2个小炸弹 | - 当蹦蹦炸弹因为碰撞而爆炸,向子弹方向上加上90°,270° 发出2个小炸弹 | ||||
| @@ -223,7 +223,7 @@ $$ | |||||
| #### 喧哗者ANoisyPerson | #### 喧哗者ANoisyPerson | ||||
| - 普通攻击为 CommonAttackOfGhost | - 普通攻击为 CommonAttackOfGhost | ||||
| - 主动技能 | - 主动技能 | ||||
| - 嚎叫 Howl | |||||
| 0. 嚎叫 Howl | |||||
| - CD:25s | - CD:25s | ||||
| - 使用瞬间,在视野半径范围内(不是可视区域)的学生被眩晕5500ms,自己进入800ms的后摇 | - 使用瞬间,在视野半径范围内(不是可视区域)的学生被眩晕5500ms,自己进入800ms的后摇 | ||||
| - 通过眩晕获得对应得分 | - 通过眩晕获得对应得分 | ||||
| @@ -233,7 +233,7 @@ $$ | |||||
| #### Idol | #### Idol | ||||
| - 普通攻击为 CommonAttackOfGhost | - 普通攻击为 CommonAttackOfGhost | ||||
| - 主动技能 | - 主动技能 | ||||
| - ShowTime | |||||
| 0. ShowTime | |||||
| - CD: 80s 持续时间:10s | - CD: 80s 持续时间:10s | ||||
| - 持续时间内 | - 持续时间内 | ||||
| - 使警戒范围外的学生眩晕并每200ms发送向自己移动200ms的指令(速度为学生本应速度*二者距离/警戒范围) | - 使警戒范围外的学生眩晕并每200ms发送向自己移动200ms的指令(速度为学生本应速度*二者距离/警戒范围) | ||||
| @@ -258,14 +258,14 @@ $$ | |||||
| #### 运动员 | #### 运动员 | ||||
| - 主动技能 | - 主动技能 | ||||
| - 冲撞 CanBeginToCharge | |||||
| 0. 冲撞 CanBeginToCharge | |||||
| - CD:60s 持续时间:3s | - CD:60s 持续时间:3s | ||||
| - 在持续时间内,速度变为三倍,期间撞到捣蛋鬼,会导致捣蛋鬼眩晕7.22s,学生眩晕2.09s | - 在持续时间内,速度变为三倍,期间撞到捣蛋鬼,会导致捣蛋鬼眩晕7.22s,学生眩晕2.09s | ||||
| - 通过眩晕获得对应得分 | - 通过眩晕获得对应得分 | ||||
| #### 教师 | #### 教师 | ||||
| - 主动技能 | - 主动技能 | ||||
| - 惩罚 Punish | |||||
| 0. 惩罚 Punish | |||||
| - CD:30s | - CD:30s | ||||
| - 使用瞬间,在可视范围内的翻窗、开锁门、攻击前后摇的捣蛋鬼会被眩晕(3070+300*已受伤害/基本伤害(1500000))ms, | - 使用瞬间,在可视范围内的翻窗、开锁门、攻击前后摇的捣蛋鬼会被眩晕(3070+300*已受伤害/基本伤害(1500000))ms, | ||||
| - 通过眩晕获得对应得分 | - 通过眩晕获得对应得分 | ||||
| @@ -279,22 +279,22 @@ $$ | |||||
| - 当处于可接受指令状态且不在学习时,会积累“冥想进度”,速度为40/ms | - 当处于可接受指令状态且不在学习时,会积累“冥想进度”,速度为40/ms | ||||
| - 受到攻击(并非伤害)、进入学习状态或进入不可接受指令状态(包括翻窗)冥想进度清零 | - 受到攻击(并非伤害)、进入学习状态或进入不可接受指令状态(包括翻窗)冥想进度清零 | ||||
| - 主动技能5 | - 主动技能5 | ||||
| - 写答案 WriteAnswers | |||||
| 0. 写答案 WriteAnswers | |||||
| - CD:30s | - CD:30s | ||||
| - 使用瞬间,对于可交互范围内的一间教室的作业增加冥想进度,冥想进度清零 | - 使用瞬间,对于可交互范围内的一间教室的作业增加冥想进度,冥想进度清零 | ||||
| - 通过学习获得对应得分 | - 通过学习获得对应得分 | ||||
| #### 开心果 | #### 开心果 | ||||
| - 主动技能 | - 主动技能 | ||||
| - 唤醒 Rouse | |||||
| 0. 唤醒 Rouse | |||||
| - CD:120s | - CD:120s | ||||
| - 使用瞬间,唤醒可视范围内一个沉迷中的人 | - 使用瞬间,唤醒可视范围内一个沉迷中的人 | ||||
| - 通过唤醒获得对应得分 | - 通过唤醒获得对应得分 | ||||
| - 勉励 Encourage | |||||
| 1. 勉励 Encourage | |||||
| - CD:120s | - CD:120s | ||||
| - 使用瞬间,为可视范围内随机一个毅力不足的人试图补充750000的毅力值 | - 使用瞬间,为可视范围内随机一个毅力不足的人试图补充750000的毅力值 | ||||
| - 获得勉励750000的毅力值对应得分 | - 获得勉励750000的毅力值对应得分 | ||||
| - 鼓舞 Inspire | |||||
| 2. 鼓舞 Inspire | |||||
| - CD:120s | - CD:120s | ||||
| - 使用瞬间,可视范围内学生(包括自己)获得持续6秒的1.6倍速Buff | - 使用瞬间,可视范围内学生(包括自己)获得持续6秒的1.6倍速Buff | ||||
| - 每鼓舞一个学生得分10 | - 每鼓舞一个学生得分10 | ||||
| @@ -291,7 +291,7 @@ namespace GameClass.GameObj | |||||
| } | } | ||||
| } | } | ||||
| #endregion | #endregion | ||||
| #region 状态相关的基本属性与方法 | |||||
| private PlayerStateType playerState = PlayerStateType.Null; | private PlayerStateType playerState = PlayerStateType.Null; | ||||
| public PlayerStateType PlayerState | public PlayerStateType PlayerState | ||||
| { | { | ||||
| @@ -318,7 +318,23 @@ namespace GameClass.GameObj | |||||
| private GameObj? whatInteractingWith = null; | private GameObj? whatInteractingWith = null; | ||||
| public GameObj? WhatInteractingWith => whatInteractingWith; | public GameObj? WhatInteractingWith => whatInteractingWith; | ||||
| private long threadNum = 0; | |||||
| public long ThreadNum => threadNum; | |||||
| public void ChangePlayerState(PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null) | public void ChangePlayerState(PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null) | ||||
| { | |||||
| lock (gameObjLock) | |||||
| { | |||||
| ++threadNum; | |||||
| whatInteractingWith = gameObj; | |||||
| if (value != PlayerStateType.Moving) | |||||
| IsMoving = false; | |||||
| playerState = (value == PlayerStateType.Moving) ? PlayerStateType.Null : value; | |||||
| //Debugger.Output(this,playerState.ToString()+" "+IsMoving.ToString()); | |||||
| } | |||||
| } | |||||
| public void ChangePlayerStateInOneThread(PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null) | |||||
| { | { | ||||
| lock (gameObjLock) | lock (gameObjLock) | ||||
| { | { | ||||
| @@ -334,11 +350,26 @@ namespace GameClass.GameObj | |||||
| { | { | ||||
| lock (gameObjLock) | lock (gameObjLock) | ||||
| { | { | ||||
| ++threadNum; | |||||
| whatInteractingWith = null; | whatInteractingWith = null; | ||||
| IsMoving = false; | |||||
| playerState = PlayerStateType.Null; | playerState = PlayerStateType.Null; | ||||
| } | } | ||||
| } | } | ||||
| public void RemoveFromGame(PlayerStateType playerStateType) | |||||
| { | |||||
| lock (gameObjLock) | |||||
| { | |||||
| playerState = playerStateType; | |||||
| CanMove = false; | |||||
| IsResetting = true; | |||||
| Position = GameData.PosWhoDie; | |||||
| place = PlaceType.Grass; | |||||
| } | |||||
| } | |||||
| #endregion | |||||
| private int score = 0; | private int score = 0; | ||||
| public int Score | public int Score | ||||
| { | { | ||||
| @@ -572,17 +603,6 @@ namespace GameClass.GameObj | |||||
| this.Vampire = this.OriVampire; | this.Vampire = this.OriVampire; | ||||
| } | } | ||||
| }*/ | }*/ | ||||
| public void RemoveFromGame(PlayerStateType playerStateType) | |||||
| { | |||||
| lock (gameObjLock) | |||||
| { | |||||
| playerState = playerStateType; | |||||
| CanMove = false; | |||||
| IsResetting = true; | |||||
| Position = GameData.PosWhoDie; | |||||
| place = PlaceType.Grass; | |||||
| } | |||||
| } | |||||
| public override bool IsRigid => true; | public override bool IsRigid => true; | ||||
| public override ShapeType Shape => ShapeType.Circle; | public override ShapeType Shape => ShapeType.Circle; | ||||
| @@ -79,6 +79,8 @@ namespace GameEngine | |||||
| return; | return; | ||||
| if (!obj.IsAvailable || !gameTimer.IsGaming) | if (!obj.IsAvailable || !gameTimer.IsGaming) | ||||
| return; | return; | ||||
| long threadNum = (obj.Type == GameObjType.Character) ? ((ICharacter)obj).ThreadNum : 0;//对人特殊处理 | |||||
| new Thread | new Thread | ||||
| ( | ( | ||||
| () => | () => | ||||
| @@ -123,6 +125,9 @@ namespace GameEngine | |||||
| moveVecLength = obj.MoveSpeed / GameData.numOfStepPerSecond; | moveVecLength = obj.MoveSpeed / GameData.numOfStepPerSecond; | ||||
| res = new XY(direction, moveVecLength); | res = new XY(direction, moveVecLength); | ||||
| //对人特殊处理 | |||||
| if (threadNum > 0 && ((ICharacter)obj).ThreadNum != threadNum) return false; | |||||
| // 越界情况处理:如果越界,则与越界方块碰撞 | // 越界情况处理:如果越界,则与越界方块碰撞 | ||||
| bool flag; // 循环标志 | bool flag; // 循环标志 | ||||
| do | do | ||||
| @@ -71,12 +71,13 @@ namespace Gaming | |||||
| ++generatorForFix.NumOfFixing; | ++generatorForFix.NumOfFixing; | ||||
| characterManager.SetPlayerState(player, PlayerStateType.Fixing); | characterManager.SetPlayerState(player, PlayerStateType.Fixing); | ||||
| long threadNum = player.ThreadNum; | |||||
| new Thread | new Thread | ||||
| ( | ( | ||||
| () => | () => | ||||
| { | { | ||||
| new FrameRateTaskExecutor<int>( | new FrameRateTaskExecutor<int>( | ||||
| loopCondition: () => gameMap.Timer.IsGaming && player.PlayerState == PlayerStateType.Fixing, | |||||
| loopCondition: () => gameMap.Timer.IsGaming && threadNum == player.ThreadNum, | |||||
| loopToDo: () => | loopToDo: () => | ||||
| { | { | ||||
| if (generatorForFix.Repair(player.FixSpeed * GameData.frameDuration, player)) | if (generatorForFix.Repair(player.FixSpeed * GameData.frameDuration, player)) | ||||
| @@ -170,8 +171,10 @@ namespace Gaming | |||||
| { | { | ||||
| characterManager.SetPlayerState(playerTreated, PlayerStateType.Treated); | characterManager.SetPlayerState(playerTreated, PlayerStateType.Treated); | ||||
| characterManager.SetPlayerState(player, PlayerStateType.Treating); | characterManager.SetPlayerState(player, PlayerStateType.Treating); | ||||
| long threadNum = player.ThreadNum; | |||||
| new FrameRateTaskExecutor<int>( | new FrameRateTaskExecutor<int>( | ||||
| loopCondition: () => playerTreated.PlayerState == PlayerStateType.Treated && player.PlayerState == PlayerStateType.Treating && gameMap.Timer.IsGaming, | |||||
| loopCondition: () => playerTreated.PlayerState == PlayerStateType.Treated && threadNum == player.ThreadNum && gameMap.Timer.IsGaming, | |||||
| loopToDo: () => | loopToDo: () => | ||||
| { | { | ||||
| if (playerTreated.AddDegreeOfTreatment(GameData.frameDuration * player.TreatSpeed, player)) | if (playerTreated.AddDegreeOfTreatment(GameData.frameDuration * player.TreatSpeed, player)) | ||||
| @@ -182,7 +185,7 @@ namespace Gaming | |||||
| ) | ) | ||||
| .Start(); | .Start(); | ||||
| if (player.PlayerState == PlayerStateType.Treating) characterManager.SetPlayerState(player); | |||||
| if (threadNum == player.ThreadNum) characterManager.SetPlayerState(player); | |||||
| else if (playerTreated.PlayerState == PlayerStateType.Treated) characterManager.SetPlayerState(playerTreated); | else if (playerTreated.PlayerState == PlayerStateType.Treated) characterManager.SetPlayerState(playerTreated); | ||||
| } | } | ||||
| ) | ) | ||||
| @@ -200,13 +203,14 @@ namespace Gaming | |||||
| return false; | return false; | ||||
| characterManager.SetPlayerState(player, PlayerStateType.Rescuing); | characterManager.SetPlayerState(player, PlayerStateType.Rescuing); | ||||
| characterManager.SetPlayerState(playerRescued, PlayerStateType.Rescued); | characterManager.SetPlayerState(playerRescued, PlayerStateType.Rescued); | ||||
| long threadNum = player.ThreadNum; | |||||
| new Thread | new Thread | ||||
| ( | ( | ||||
| () => | () => | ||||
| { | { | ||||
| new FrameRateTaskExecutor<int>( | new FrameRateTaskExecutor<int>( | ||||
| loopCondition: () => playerRescued.PlayerState == PlayerStateType.Rescued && player.PlayerState == PlayerStateType.Rescuing && gameMap.Timer.IsGaming, | |||||
| loopCondition: () => playerRescued.PlayerState == PlayerStateType.Rescued && threadNum == player.ThreadNum && gameMap.Timer.IsGaming, | |||||
| loopToDo: () => | loopToDo: () => | ||||
| { | { | ||||
| playerRescued.TimeOfRescue += GameData.frameDuration; | playerRescued.TimeOfRescue += GameData.frameDuration; | ||||
| @@ -228,7 +232,7 @@ namespace Gaming | |||||
| else | else | ||||
| characterManager.SetPlayerState(playerRescued, PlayerStateType.Addicted); | characterManager.SetPlayerState(playerRescued, PlayerStateType.Addicted); | ||||
| } | } | ||||
| if (player.PlayerState == PlayerStateType.Rescuing) characterManager.SetPlayerState(player); | |||||
| if (threadNum == player.ThreadNum) characterManager.SetPlayerState(player); | |||||
| playerRescued.TimeOfRescue = 0; | playerRescued.TimeOfRescue = 0; | ||||
| } | } | ||||
| ) | ) | ||||
| @@ -297,13 +301,14 @@ namespace Gaming | |||||
| // gameMap.Add(addWall); | // gameMap.Add(addWall); | ||||
| characterManager.SetPlayerState(player, PlayerStateType.ClimbingThroughWindows); | characterManager.SetPlayerState(player, PlayerStateType.ClimbingThroughWindows); | ||||
| long threadNum = player.ThreadNum; | |||||
| windowForClimb.WhoIsClimbing = player; | windowForClimb.WhoIsClimbing = player; | ||||
| new Thread | new Thread | ||||
| ( | ( | ||||
| () => | () => | ||||
| { | { | ||||
| new FrameRateTaskExecutor<int>( | new FrameRateTaskExecutor<int>( | ||||
| loopCondition: () => player.PlayerState == PlayerStateType.ClimbingThroughWindows && gameMap.Timer.IsGaming, | |||||
| loopCondition: () => threadNum == player.ThreadNum && gameMap.Timer.IsGaming, | |||||
| loopToDo: () => { }, | loopToDo: () => { }, | ||||
| timeInterval: GameData.frameDuration, | timeInterval: GameData.frameDuration, | ||||
| finallyReturn: () => 0, | finallyReturn: () => 0, | ||||
| @@ -322,7 +327,7 @@ namespace Gaming | |||||
| moveEngine.MoveObj(player, (int)(windowToPlayer.Length() * 3.0 * 1000 / player.MoveSpeed), (-1 * windowToPlayer).Angle()); | moveEngine.MoveObj(player, (int)(windowToPlayer.Length() * 3.0 * 1000 / player.MoveSpeed), (-1 * windowToPlayer).Angle()); | ||||
| new FrameRateTaskExecutor<int>( | new FrameRateTaskExecutor<int>( | ||||
| loopCondition: () => player.PlayerState == PlayerStateType.ClimbingThroughWindows && gameMap.Timer.IsGaming, | |||||
| loopCondition: () => threadNum == player.ThreadNum && gameMap.Timer.IsGaming, | |||||
| loopToDo: () => | loopToDo: () => | ||||
| { | { | ||||
| }, | }, | ||||
| @@ -336,7 +341,7 @@ namespace Gaming | |||||
| 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); | // gameMap.Remove(addWall); | ||||
| if (player.PlayerState == PlayerStateType.ClimbingThroughWindows) | |||||
| if (threadNum == player.ThreadNum) | |||||
| { | { | ||||
| characterManager.SetPlayerState(player); | characterManager.SetPlayerState(player); | ||||
| } | } | ||||
| @@ -379,12 +384,13 @@ namespace Gaming | |||||
| if (!flag) return false; | if (!flag) return false; | ||||
| characterManager.SetPlayerState(player, PlayerStateType.LockingOrOpeningTheDoor); | characterManager.SetPlayerState(player, PlayerStateType.LockingOrOpeningTheDoor); | ||||
| long threadNum = player.ThreadNum; | |||||
| new Thread | new Thread | ||||
| ( | ( | ||||
| () => | () => | ||||
| { | { | ||||
| new FrameRateTaskExecutor<int>( | new FrameRateTaskExecutor<int>( | ||||
| loopCondition: () => flag && player.PlayerState == PlayerStateType.LockingOrOpeningTheDoor && gameMap.Timer.IsGaming && doorToLock.OpenOrLockDegree < GameData.degreeOfLockingOrOpeningTheDoor, | |||||
| loopCondition: () => flag && threadNum == player.ThreadNum && gameMap.Timer.IsGaming && doorToLock.OpenOrLockDegree < GameData.degreeOfLockingOrOpeningTheDoor, | |||||
| loopToDo: () => | loopToDo: () => | ||||
| { | { | ||||
| flag = ((gameMap.PartInTheSameCell(doorToLock.Position, GameObjType.Character)) == null); | flag = ((gameMap.PartInTheSameCell(doorToLock.Position, GameObjType.Character)) == null); | ||||
| @@ -399,7 +405,7 @@ namespace Gaming | |||||
| { | { | ||||
| doorToLock.IsOpen = (!doorToLock.IsOpen); | doorToLock.IsOpen = (!doorToLock.IsOpen); | ||||
| } | } | ||||
| if (player.PlayerState == PlayerStateType.LockingOrOpeningTheDoor) | |||||
| if (threadNum == player.ThreadNum) | |||||
| characterManager.SetPlayerState(player); | characterManager.SetPlayerState(player); | ||||
| doorToLock.OpenOrLockDegree = 0; | doorToLock.OpenOrLockDegree = 0; | ||||
| } | } | ||||
| @@ -472,7 +478,7 @@ namespace Gaming | |||||
| OnCollision: (obj, collisionObj, moveVec) => | OnCollision: (obj, collisionObj, moveVec) => | ||||
| { | { | ||||
| SkillWhenColliding((Character)obj, collisionObj); | SkillWhenColliding((Character)obj, collisionObj); | ||||
| Preparation.Utility.Debugger.Output(obj, " end move with " + collisionObj.ToString()); | |||||
| //Preparation.Utility.Debugger.Output(obj, " end move with " + collisionObj.ToString()); | |||||
| //if (collisionObj is Mine) | //if (collisionObj is Mine) | ||||
| //{ | //{ | ||||
| // ActivateMine((Character)obj, (Mine)collisionObj); | // ActivateMine((Character)obj, (Mine)collisionObj); | ||||
| @@ -192,12 +192,13 @@ namespace Gaming | |||||
| if (bullet.CastTime > 0) | if (bullet.CastTime > 0) | ||||
| { | { | ||||
| characterManager.SetPlayerState(player, PlayerStateType.TryingToAttack); | characterManager.SetPlayerState(player, PlayerStateType.TryingToAttack); | ||||
| long threadNum = player.ThreadNum; | |||||
| new Thread | new Thread | ||||
| (() => | (() => | ||||
| { | { | ||||
| new FrameRateTaskExecutor<int>( | new FrameRateTaskExecutor<int>( | ||||
| loopCondition: () => player.PlayerState == PlayerStateType.TryingToAttack && gameMap.Timer.IsGaming, | |||||
| loopCondition: () => threadNum == player.ThreadNum && gameMap.Timer.IsGaming, | |||||
| loopToDo: () => | loopToDo: () => | ||||
| { | { | ||||
| }, | }, | ||||
| @@ -209,7 +210,7 @@ namespace Gaming | |||||
| if (gameMap.Timer.IsGaming) | if (gameMap.Timer.IsGaming) | ||||
| { | { | ||||
| if (player.PlayerState == PlayerStateType.TryingToAttack) | |||||
| if (threadNum == player.ThreadNum) | |||||
| { | { | ||||
| characterManager.SetPlayerState(player); | characterManager.SetPlayerState(player); | ||||
| } | } | ||||
| @@ -20,20 +20,33 @@ namespace Gaming | |||||
| public void SetPlayerState(Character player, PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null) | public void SetPlayerState(Character player, PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null) | ||||
| { | { | ||||
| switch (player.PlayerState) | |||||
| lock (player.MoveLock) | |||||
| { | { | ||||
| case PlayerStateType.OpeningTheChest: | |||||
| ((Chest)player.WhatInteractingWith).StopOpen(); | |||||
| break; | |||||
| case PlayerStateType.OpeningTheDoorway: | |||||
| Doorway doorway = (Doorway)player.WhatInteractingWith; | |||||
| doorway.OpenDegree += gameMap.Timer.nowTime() - doorway.OpenStartTime; | |||||
| doorway.OpenStartTime = 0; | |||||
| break; | |||||
| default: | |||||
| break; | |||||
| switch (player.PlayerState) | |||||
| { | |||||
| case PlayerStateType.OpeningTheChest: | |||||
| ((Chest)player.WhatInteractingWith).StopOpen(); | |||||
| player.ChangePlayerState(value, gameObj); | |||||
| break; | |||||
| case PlayerStateType.OpeningTheDoorway: | |||||
| Doorway doorway = (Doorway)player.WhatInteractingWith; | |||||
| doorway.OpenDegree += gameMap.Timer.nowTime() - doorway.OpenStartTime; | |||||
| doorway.OpenStartTime = 0; | |||||
| player.ChangePlayerState(value, gameObj); | |||||
| break; | |||||
| case PlayerStateType.Addicted: | |||||
| if (value == PlayerStateType.Rescued) | |||||
| player.ChangePlayerStateInOneThread(value, gameObj); | |||||
| break; | |||||
| case PlayerStateType.Rescued: | |||||
| if (value == PlayerStateType.Addicted) | |||||
| player.ChangePlayerStateInOneThread(value, gameObj); | |||||
| break; | |||||
| default: | |||||
| player.ChangePlayerState(value, gameObj); | |||||
| break; | |||||
| } | |||||
| } | } | ||||
| player.ChangePlayerState(value, gameObj); | |||||
| } | } | ||||
| public Character? AddPlayer(XY pos, int teamID, int playerID, CharacterType characterType, Character? parent = null) | public Character? AddPlayer(XY pos, int teamID, int playerID, CharacterType characterType, Character? parent = null) | ||||
| @@ -233,6 +246,7 @@ namespace Gaming | |||||
| } | } | ||||
| } | } | ||||
| SetPlayerState(player, PlayerStateType.Addicted); | SetPlayerState(player, PlayerStateType.Addicted); | ||||
| long threadNum = player.ThreadNum; | |||||
| new Thread | new Thread | ||||
| (() => | (() => | ||||
| { | { | ||||
| @@ -240,7 +254,7 @@ namespace Gaming | |||||
| Debugger.Output(player, " is addicted "); | Debugger.Output(player, " is addicted "); | ||||
| #endif | #endif | ||||
| new FrameRateTaskExecutor<int>( | new FrameRateTaskExecutor<int>( | ||||
| () => (player.PlayerState == PlayerStateType.Addicted || player.PlayerState == PlayerStateType.Rescued) && player.GamingAddiction < player.MaxGamingAddiction && gameMap.Timer.IsGaming, | |||||
| () => threadNum == player.ThreadNum && player.GamingAddiction < player.MaxGamingAddiction && gameMap.Timer.IsGaming, | |||||
| () => | () => | ||||
| { | { | ||||
| player.GamingAddiction += (player.PlayerState == PlayerStateType.Addicted) ? GameData.frameDuration : 0; | player.GamingAddiction += (player.PlayerState == PlayerStateType.Addicted) ? GameData.frameDuration : 0; | ||||
| @@ -269,8 +283,9 @@ namespace Gaming | |||||
| (() => | (() => | ||||
| { | { | ||||
| SetPlayerState(player, PlayerStateType.Stunned); | SetPlayerState(player, PlayerStateType.Stunned); | ||||
| long threadNum = player.ThreadNum; | |||||
| Thread.Sleep(time); | Thread.Sleep(time); | ||||
| if (player.PlayerState == PlayerStateType.Stunned) | |||||
| if (threadNum == player.ThreadNum) | |||||
| SetPlayerState(player); | SetPlayerState(player); | ||||
| } | } | ||||
| ) | ) | ||||
| @@ -358,13 +373,14 @@ namespace Gaming | |||||
| if (time <= 0) return false; | if (time <= 0) return false; | ||||
| if (player.PlayerState == PlayerStateType.Swinging || (!player.Commandable() && player.PlayerState != PlayerStateType.TryingToAttack)) return false; | if (player.PlayerState == PlayerStateType.Swinging || (!player.Commandable() && player.PlayerState != PlayerStateType.TryingToAttack)) return false; | ||||
| SetPlayerState(player, PlayerStateType.Swinging); | SetPlayerState(player, PlayerStateType.Swinging); | ||||
| long threadNum = player.ThreadNum; | |||||
| new Thread | new Thread | ||||
| (() => | (() => | ||||
| { | { | ||||
| Thread.Sleep(time); | Thread.Sleep(time); | ||||
| if (player.PlayerState == PlayerStateType.Swinging) | |||||
| if (threadNum == player.ThreadNum) | |||||
| { | { | ||||
| SetPlayerState(player); | SetPlayerState(player); | ||||
| } | } | ||||
| @@ -80,12 +80,7 @@ namespace Gaming | |||||
| Character? player = gameMap.FindPlayerToAction(playerID); | Character? player = gameMap.FindPlayerToAction(playerID); | ||||
| if (player != null) | if (player != null) | ||||
| { | { | ||||
| bool res = actionManager.MovePlayer(player, moveTimeInMilliseconds, angle); | |||||
| #if DEBUG | |||||
| Console.WriteLine($"PlayerID:{playerID} move to ({player.Position.x},{player.Position.y})!"); | |||||
| #endif | |||||
| return res; | |||||
| return actionManager.MovePlayer(player, moveTimeInMilliseconds, angle); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -14,6 +14,7 @@ namespace Preparation.Interface | |||||
| public BulletType BulletOfPlayer { get; set; } | public BulletType BulletOfPlayer { get; set; } | ||||
| public CharacterType CharacterType { get; } | public CharacterType CharacterType { get; } | ||||
| public int BulletNum { get; } | public int BulletNum { get; } | ||||
| public long ThreadNum { get; } | |||||
| public bool IsGhost(); | public bool IsGhost(); | ||||
| } | } | ||||
| @@ -1,7 +1,5 @@ | |||||
| using Protobuf; | using Protobuf; | ||||
| using System.Collections.Generic; | |||||
| using GameClass.GameObj; | using GameClass.GameObj; | ||||
| using System.Numerics; | |||||
| using Preparation.Utility; | using Preparation.Utility; | ||||
| using Gaming; | using Gaming; | ||||
| @@ -0,0 +1,7 @@ | |||||
| @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 | |||||
| ping -n 2 127.0.0.1 > NUL | |||||
| start cmd /k ..\Client\bin\Debug\net6.0-windows\Client.exe --port 8888 --characterID 114514 --type 0 --occupation 1 | |||||