You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

ActionManager.cs 13 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. using System;
  2. using System.Numerics;
  3. using System.Runtime.InteropServices;
  4. using System.Threading;
  5. using GameClass.GameObj;
  6. using GameEngine;
  7. using Preparation.Utility;
  8. using Timothy.FrameRateTask;
  9. namespace Gaming
  10. {
  11. public partial class Game
  12. {
  13. private readonly ActionManager actionManager;
  14. private class ActionManager
  15. {
  16. // 人物移动
  17. public bool MovePlayer(Character playerToMove, int moveTimeInMilliseconds, double moveDirection)
  18. {
  19. if (playerToMove.PlayerState != PlayerStateType.Null) return false;
  20. moveEngine.MoveObj(playerToMove, moveTimeInMilliseconds, moveDirection);
  21. return true;
  22. }
  23. public bool Stop(Character player)
  24. {
  25. if (player.PlayerState == PlayerStateType.IsRescuing || player.PlayerState == PlayerStateType.IsRescued
  26. || player.PlayerState == PlayerStateType.IsFixing || player.PlayerState == PlayerStateType.IsMoving
  27. || player.PlayerState == PlayerStateType.IsTreated || player.PlayerState == PlayerStateType.IsTreating
  28. || player.PlayerState == PlayerStateType.IsRummagingInTheChest || player.PlayerState == PlayerStateType.IsLockingTheDoor
  29. || player.PlayerState == PlayerStateType.IsClimbingThroughWindows)
  30. {
  31. player.PlayerState = PlayerStateType.Null;
  32. return true;
  33. }
  34. return false;
  35. }
  36. public bool Fix(Student player)// 自动检查有无发电机可修
  37. {
  38. if (player.IsGhost() || (player.PlayerState != PlayerStateType.Null && player.PlayerState != PlayerStateType.IsMoving))
  39. return false;
  40. Generator? generatorForFix = null;
  41. gameMap.GameObjLockDict[GameObjType.Generator].EnterReadLock();
  42. try
  43. {
  44. foreach (Generator generator in gameMap.GameObjDict[GameObjType.Generator])
  45. {
  46. if (GameData.ApproachToInteract(generator.Position, player.Position))
  47. {
  48. generatorForFix = generator;
  49. break;
  50. }
  51. }
  52. }
  53. finally
  54. {
  55. gameMap.GameObjLockDict[GameObjType.Generator].ExitReadLock();
  56. }
  57. if (generatorForFix == null || generatorForFix.DegreeOfFRepair == GameData.degreeOfFixedGenerator)
  58. return false;
  59. player.PlayerState = PlayerStateType.IsFixing;
  60. new Thread
  61. (
  62. () =>
  63. {
  64. new FrameRateTaskExecutor<int>(
  65. loopCondition: () => player.PlayerState == PlayerStateType.IsFixing && gameMap.Timer.IsGaming && generatorForFix.DegreeOfFRepair < GameData.degreeOfFixedGenerator && GameData.ApproachToInteract(player.Position, generatorForFix.Position),
  66. loopToDo: () =>
  67. {
  68. generatorForFix.Repair(player.FixSpeed * GameData.frameDuration);
  69. },
  70. timeInterval: GameData.frameDuration,
  71. finallyReturn: () => 0
  72. )
  73. .Start();
  74. if (generatorForFix.DegreeOfFRepair == GameData.degreeOfFixedGenerator)
  75. {
  76. gameMap.GameObjLockDict[GameObjType.Generator].EnterReadLock();
  77. try
  78. {
  79. Doorway exit = (Doorway)gameMap.GameObjDict[GameObjType.Doorway][1];
  80. if (!exit.PowerSupply)
  81. {
  82. int numOfFixedGenerator = 0;
  83. foreach (Generator generator in gameMap.GameObjDict[GameObjType.Generator])
  84. if (generator.DegreeOfFRepair == GameData.degreeOfFixedGenerator)
  85. ++numOfFixedGenerator;
  86. if (numOfFixedGenerator >= GameData.numOfGeneratorRequiredForRepair)
  87. {
  88. gameMap.GameObjLockDict[GameObjType.Doorway].EnterWriteLock();
  89. try
  90. {
  91. foreach (Doorway doorway in gameMap.GameObjDict[GameObjType.Doorway])
  92. doorway.PowerSupply = true;
  93. }
  94. finally
  95. {
  96. gameMap.GameObjLockDict[GameObjType.Doorway].ExitWriteLock();
  97. }
  98. }
  99. }
  100. }
  101. finally
  102. {
  103. gameMap.GameObjLockDict[GameObjType.Generator].ExitReadLock();
  104. }
  105. }
  106. }
  107. )
  108. { IsBackground = true }.Start();
  109. return true;
  110. }
  111. public bool Escape(Student player)
  112. {
  113. if (!(player.PlayerState == PlayerStateType.Null || player.PlayerState == PlayerStateType.IsMoving) || player.IsGhost())
  114. return false;
  115. Doorway? doorwayForEscape = null;
  116. gameMap.GameObjLockDict[GameObjType.Doorway].EnterReadLock();
  117. try
  118. {
  119. foreach (Doorway doorway in gameMap.GameObjDict[GameObjType.Doorway])
  120. {
  121. if (GameData.IsInTheSameCell(doorway.Position, player.Position))
  122. {
  123. doorwayForEscape = doorway;
  124. break;
  125. }
  126. }
  127. }
  128. finally
  129. {
  130. gameMap.GameObjLockDict[GameObjType.Doorway].ExitReadLock();
  131. }
  132. if (doorwayForEscape != null && doorwayForEscape.IsOpen)
  133. {
  134. player.Die(PlayerStateType.IsEscaped);
  135. return true;
  136. }
  137. else
  138. return false;
  139. }
  140. public bool Treat(Student player, Student playerTreated)
  141. {
  142. if (playerTreated.PlayerState == PlayerStateType.Null || player.PlayerState == PlayerStateType.Null || playerTreated.HP == playerTreated.MaxHp || !GameData.ApproachToInteract(playerTreated.Position, player.Position))
  143. return false;
  144. if (playerTreated.HP + playerTreated.DegreeOfTreatment >= playerTreated.MaxHp)
  145. {
  146. playerTreated.HP = playerTreated.MaxHp;
  147. playerTreated.DegreeOfTreatment = 0;
  148. return false;
  149. }
  150. if (playerTreated.DegreeOfTreatment >= GameData.basicTreatmentDegree)
  151. {
  152. playerTreated.HP += GameData.basicTreatmentDegree;
  153. playerTreated.DegreeOfTreatment = 0;
  154. return false;
  155. }
  156. new Thread
  157. (
  158. () =>
  159. {
  160. new FrameRateTaskExecutor<int>(
  161. loopCondition: () => playerTreated.PlayerState == PlayerStateType.IsTreated && player.PlayerState == PlayerStateType.IsTreating && gameMap.Timer.IsGaming && playerTreated.HP + playerTreated.DegreeOfTreatment < playerTreated.MaxHp && playerTreated.DegreeOfTreatment >= GameData.basicTreatmentDegree && GameData.ApproachToInteract(playerTreated.Position, player.Position),
  162. loopToDo: () =>
  163. {
  164. playerTreated.DegreeOfTreatment += GameData.frameDuration * player.TreatSpeed;
  165. },
  166. timeInterval: GameData.frameDuration,
  167. finallyReturn: () => 0
  168. )
  169. .Start();
  170. if (playerTreated.PlayerState == PlayerStateType.IsTreated) playerTreated.PlayerState = PlayerStateType.Null;
  171. if (player.PlayerState == PlayerStateType.IsTreating) player.PlayerState = PlayerStateType.Null;
  172. if (playerTreated.HP + playerTreated.DegreeOfTreatment >= playerTreated.MaxHp)
  173. {
  174. playerTreated.HP = playerTreated.MaxHp;
  175. playerTreated.DegreeOfTreatment = 0;
  176. }
  177. else
  178. if (playerTreated.DegreeOfTreatment >= GameData.basicTreatmentDegree)
  179. {
  180. playerTreated.HP += GameData.basicTreatmentDegree;
  181. playerTreated.DegreeOfTreatment = 0;
  182. }
  183. }
  184. )
  185. { IsBackground = true }.Start();
  186. return true;
  187. }
  188. public bool Rescue(Student player, Student playerRescued)
  189. {
  190. if (player.PlayerState != PlayerStateType.Null || playerRescued.PlayerState != PlayerStateType.IsAddicted || !GameData.ApproachToInteract(playerRescued.Position, player.Position))
  191. return false;
  192. player.PlayerState = PlayerStateType.IsRescuing;
  193. playerRescued.PlayerState = PlayerStateType.IsRescued;
  194. int rescuedDegree = 0;
  195. new Thread
  196. (
  197. () =>
  198. {
  199. new FrameRateTaskExecutor<int>(
  200. loopCondition: () => playerRescued.PlayerState == PlayerStateType.IsRescued && player.PlayerState == PlayerStateType.IsRescuing && gameMap.Timer.IsGaming && GameData.ApproachToInteract(playerRescued.Position, player.Position),
  201. loopToDo: () =>
  202. {
  203. rescuedDegree += GameData.frameDuration;
  204. },
  205. timeInterval: GameData.frameDuration,
  206. finallyReturn: () => 0,
  207. maxTotalDuration: 1000
  208. )
  209. .Start();
  210. if (rescuedDegree == 1000)
  211. {
  212. if (playerRescued.PlayerState == PlayerStateType.IsRescued) playerRescued.PlayerState = PlayerStateType.Null;
  213. if (player.PlayerState == PlayerStateType.IsRescuing) player.PlayerState = PlayerStateType.Null;
  214. }
  215. else
  216. {
  217. if (playerRescued.PlayerState == PlayerStateType.IsRescued) playerRescued.PlayerState = PlayerStateType.Null;
  218. if (player.PlayerState == PlayerStateType.IsRescuing) player.PlayerState = PlayerStateType.IsAddicted;
  219. }
  220. }
  221. )
  222. { IsBackground = true }.Start();
  223. return true;
  224. }
  225. /*
  226. private void ActivateMine(Character player, Mine mine)
  227. {
  228. gameMap.ObjListLock.EnterWriteLock();
  229. try { gameMap.ObjList.Remove(mine); }
  230. catch { }
  231. finally { gameMap.ObjListLock.ExitWriteLock(); }
  232. switch (mine.GetPropType())
  233. {
  234. case PropType.Dirt:
  235. player.AddMoveSpeed(Constant.dirtMoveSpeedDebuff, Constant.buffPropTime);
  236. break;
  237. case PropType.Attenuator:
  238. player.AddAP(Constant.attenuatorAtkDebuff, Constant.buffPropTime);
  239. break;
  240. case PropType.Divider:
  241. player.ChangeCD(Constant.dividerCdDiscount, Constant.buffPropTime);
  242. break;
  243. }
  244. }
  245. */
  246. private readonly Map gameMap;
  247. private readonly MoveEngine moveEngine;
  248. public ActionManager(Map gameMap)
  249. {
  250. this.gameMap = gameMap;
  251. this.moveEngine = new MoveEngine(
  252. gameMap: gameMap,
  253. OnCollision: (obj, collisionObj, moveVec) =>
  254. {
  255. //if (collisionObj is Mine)
  256. //{
  257. // ActivateMine((Character)obj, (Mine)collisionObj);
  258. // return MoveEngine.AfterCollision.ContinueCheck;
  259. //}
  260. return MoveEngine.AfterCollision.MoveMax;
  261. },
  262. EndMove: obj =>
  263. {
  264. // Debugger.Output(obj, " end move at " + obj.Position.ToString() + " At time: " + Environment.TickCount64);
  265. }
  266. );
  267. }
  268. }
  269. }
  270. }