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 31 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  1. using System;
  2. using System.Threading;
  3. using GameClass.GameObj;
  4. using GameEngine;
  5. using Preparation.Utility;
  6. using Timothy.FrameRateTask;
  7. namespace Gaming
  8. {
  9. public partial class Game
  10. {
  11. private readonly ActionManager actionManager;
  12. private class ActionManager
  13. {
  14. public bool MovePlayer(Character playerToMove, int moveTimeInMilliseconds, double moveDirection)
  15. {
  16. if (moveTimeInMilliseconds < 5) return false;
  17. long stateNum = playerToMove.SetPlayerState(RunningStateType.Waiting, PlayerStateType.Moving);
  18. if (stateNum == -1) return false;
  19. new Thread
  20. (
  21. () =>
  22. {
  23. playerToMove.ThreadNum.WaitOne();
  24. if (!playerToMove.StartThread(stateNum, RunningStateType.RunningActively))
  25. {
  26. playerToMove.ThreadNum.Release();
  27. return;
  28. }
  29. moveEngine.MoveObj(playerToMove, moveTimeInMilliseconds, moveDirection, stateNum);
  30. }
  31. )
  32. { IsBackground = true }.Start();
  33. return true;
  34. }
  35. public bool MovePlayerWhenStunned(Character playerToMove, int moveTimeInMilliseconds, double moveDirection)
  36. {
  37. if (playerToMove.CharacterType == CharacterType.Robot) return false;
  38. long stateNum = playerToMove.SetPlayerState(RunningStateType.Waiting, PlayerStateType.Charmed);
  39. if (stateNum == -1) return false;
  40. new Thread
  41. (() =>
  42. {
  43. playerToMove.ThreadNum.WaitOne();
  44. if (!playerToMove.StartThread(stateNum, RunningStateType.RunningActively))
  45. {
  46. playerToMove.ThreadNum.Release();
  47. return;
  48. }
  49. else
  50. {
  51. moveEngine.MoveObj(playerToMove, moveTimeInMilliseconds, moveDirection, playerToMove.StateNum);
  52. Thread.Sleep(moveTimeInMilliseconds);
  53. lock (playerToMove.ActionLock)
  54. {
  55. lock (playerToMove.ActionLock)
  56. {
  57. if (stateNum == playerToMove.StateNum)
  58. playerToMove.SetPlayerStateNaturally();
  59. }
  60. }
  61. }
  62. }
  63. )
  64. { IsBackground = true }.Start();
  65. return true;
  66. }
  67. public static bool Stop(Character player)
  68. {
  69. lock (player.ActionLock)
  70. {
  71. if (player.Commandable())
  72. {
  73. player.SetPlayerState(RunningStateType.Null);
  74. return true;
  75. }
  76. }
  77. return false;
  78. }
  79. public bool Fix(Student player)// 自动检查有无发电机可修
  80. {
  81. Generator? generatorForFix = (Generator?)gameMap.OneForInteract(player.Position, GameObjType.Generator);
  82. if (generatorForFix == null) return false;
  83. long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.Fixing);
  84. if (stateNum == -1) return false;
  85. new Thread
  86. (
  87. () =>
  88. {
  89. player.ThreadNum.WaitOne();
  90. if (generatorForFix.DegreeOfRepair == GameData.degreeOfFixedGenerator)
  91. {
  92. player.ThreadNum.Release();
  93. return;
  94. }
  95. if (!player.StartThread(stateNum, RunningStateType.RunningActively))
  96. {
  97. player.ThreadNum.Release();
  98. return;
  99. }
  100. generatorForFix.AddNumOfFixing();
  101. Thread.Sleep(GameData.checkInterval);
  102. new FrameRateTaskExecutor<int>(
  103. loopCondition: () => stateNum == player.StateNum && gameMap.Timer.IsGaming,
  104. loopToDo: () =>
  105. {
  106. if (generatorForFix.Repair(player.FixSpeed * GameData.checkInterval, player))
  107. gameMap.AddNumOfRepairedGenerators();
  108. if (generatorForFix.DegreeOfRepair == GameData.degreeOfFixedGenerator)
  109. {
  110. lock (player.ActionLock)
  111. {
  112. if (stateNum == player.StateNum)
  113. player.SetPlayerState(RunningStateType.Null);
  114. }
  115. return false;
  116. }
  117. return true;
  118. },
  119. timeInterval: GameData.checkInterval,
  120. finallyReturn: () => 0
  121. )
  122. .Start();
  123. player.ThreadNum.Release();
  124. generatorForFix.SubNumOfFixing();
  125. }
  126. )
  127. { IsBackground = true }.Start();
  128. return true;
  129. }
  130. public bool OpenDoorway(Student player)
  131. {
  132. Doorway? doorwayToOpen = (Doorway?)gameMap.OneForInteract(player.Position, GameObjType.Doorway);
  133. if (doorwayToOpen == null) return false;
  134. long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.OpeningTheDoorway, doorwayToOpen);
  135. if (stateNum == -1) return false;
  136. new Thread
  137. (
  138. () =>
  139. {
  140. player.ThreadNum.WaitOne();
  141. if (!player.StartThread(stateNum, RunningStateType.RunningSleepily))
  142. {
  143. player.ThreadNum.Release();
  144. return;
  145. }
  146. doorwayToOpen.TryToOpen();
  147. Thread.Sleep(GameData.degreeOfOpenedDoorway - doorwayToOpen.OpenDegree);
  148. if (player.ResetPlayerState(stateNum))
  149. {
  150. doorwayToOpen.FinishOpenning();
  151. player.ThreadNum.Release();
  152. }
  153. }
  154. )
  155. { IsBackground = true }.Start();
  156. return true;
  157. }
  158. public bool Escape(Student player)
  159. {
  160. if (player.CharacterType == CharacterType.Robot || player.CharacterType == CharacterType.Teacher)
  161. return false;
  162. Doorway? doorwayForEscape = (Doorway?)gameMap.OneForInteract(player.Position, GameObjType.Doorway);
  163. if (doorwayForEscape != null && doorwayForEscape.IsOpen())
  164. {
  165. if (!player.TryToRemoveFromGame(PlayerStateType.Escaped)) return false;
  166. player.AddScore(GameData.StudentScoreEscape);
  167. gameMap.MapEscapeStudent();
  168. return true;
  169. }
  170. else
  171. {
  172. EmergencyExit? emergencyExit = (EmergencyExit?)gameMap.OneForInteract(player.Position, GameObjType.EmergencyExit);
  173. if (emergencyExit != null && emergencyExit.IsOpen)
  174. {
  175. if (!player.TryToRemoveFromGame(PlayerStateType.Escaped)) return false;
  176. player.AddScore(GameData.StudentScoreEscape);
  177. gameMap.MapEscapeStudent();
  178. return true;
  179. }
  180. return false;
  181. }
  182. }
  183. public bool Treat(Student player, Student? playerTreated = null)
  184. {
  185. if (player.CharacterType == CharacterType.Robot) return false;
  186. if (playerTreated == null)
  187. {
  188. playerTreated = gameMap.StudentForInteract(player.Position);
  189. if (playerTreated == null) return false;
  190. }
  191. else if (!GameData.ApproachToInteract(playerTreated.Position, player.Position)) return false;
  192. if (playerTreated.HP == playerTreated.MaxHp) return false;
  193. long stateNumTreated = playerTreated.SetPlayerState(RunningStateType.Waiting, PlayerStateType.Treated);
  194. if (stateNumTreated == -1) return false;
  195. long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.Treating);
  196. if (stateNum == -1)
  197. {
  198. lock (playerTreated.ActionLock)
  199. {
  200. if (playerTreated.StateNum == stateNumTreated)
  201. player.SetPlayerStateNaturally();
  202. }
  203. return false;
  204. }
  205. new Thread
  206. (
  207. () =>
  208. {
  209. player.ThreadNum.WaitOne();
  210. if (!player.StartThread(stateNum, RunningStateType.RunningActively))
  211. {
  212. player.ThreadNum.Release();
  213. lock (playerTreated.ActionLock)
  214. {
  215. if (playerTreated.StateNum == stateNumTreated)
  216. playerTreated.SetPlayerStateNaturally();
  217. }
  218. return;
  219. }
  220. playerTreated.ThreadNum.WaitOne();
  221. if (!playerTreated.StartThread(stateNum, RunningStateType.RunningActively))
  222. {
  223. playerTreated.ThreadNum.Release();
  224. lock (player.ActionLock)
  225. {
  226. if (player.StateNum == stateNum)
  227. player.SetPlayerStateNaturally();
  228. }
  229. player.ThreadNum.Release();
  230. return;
  231. }
  232. Thread.Sleep(GameData.checkInterval);
  233. new FrameRateTaskExecutor<int>(
  234. loopCondition: () => stateNum == player.StateNum && gameMap.Timer.IsGaming,
  235. loopToDo: () =>
  236. {
  237. lock (playerTreated.ActionLock)
  238. {
  239. if (playerTreated.StateNum == stateNumTreated)
  240. {
  241. if (playerTreated.AddDegreeOfTreatment(GameData.checkInterval * player.TreatSpeed, player))
  242. {
  243. playerTreated.SetPlayerStateNaturally();
  244. return false;
  245. }
  246. }
  247. else return false;
  248. }
  249. return true;
  250. },
  251. timeInterval: GameData.checkInterval,
  252. finallyReturn: () => 0
  253. )
  254. .Start();
  255. player.ThreadNum.Release();
  256. playerTreated.ThreadNum.Release();
  257. if (player.ResetPlayerState(stateNum))
  258. return;
  259. playerTreated.ResetPlayerState(stateNumTreated);
  260. }
  261. )
  262. { IsBackground = true }.Start();
  263. return true;
  264. }
  265. public bool Rescue(Student player, Student? playerRescued = null)
  266. {
  267. if (player.CharacterType == CharacterType.Robot) return false;
  268. if (playerRescued == null)
  269. {
  270. playerRescued = gameMap.StudentForInteract(player.Position);
  271. if (playerRescued == null) return false;
  272. }
  273. // else//no need
  274. // if (!GameData.ApproachToInteract(playerRescued.Position, player.Position)) return false;
  275. long stateNumRescued = playerRescued.SetPlayerState(RunningStateType.Waiting, PlayerStateType.Rescued);
  276. if (stateNumRescued == -1) return false;
  277. long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.Rescuing);
  278. if (stateNum == -1)
  279. {
  280. lock (playerRescued.ActionLock)
  281. {
  282. if (playerRescued.StateNum == stateNumRescued)
  283. player.SetPlayerStateNaturally();
  284. }
  285. return false;
  286. }
  287. new Thread
  288. (
  289. () =>
  290. {
  291. player.ThreadNum.WaitOne();
  292. if (!player.StartThread(stateNum, RunningStateType.RunningSleepily))
  293. {
  294. player.ThreadNum.Release();
  295. playerRescued.ResetPlayerState(stateNum);
  296. return;
  297. }
  298. playerRescued.ThreadNum.WaitOne();
  299. if (!GameData.ApproachToInteract(playerRescued.Position, player.Position)) return;
  300. if (!playerRescued.StartThread(stateNum, RunningStateType.RunningSleepily))
  301. {
  302. playerRescued.ThreadNum.Release();
  303. if (!player.ResetPlayerState(stateNum))
  304. player.ThreadNum.Release();
  305. return;
  306. }
  307. new FrameRateTaskExecutor<int>(
  308. loopCondition: () => stateNum == player.StateNum && gameMap.Timer.IsGaming,
  309. loopToDo: () =>
  310. {
  311. lock (playerRescued.ActionLock)
  312. {
  313. if (playerRescued.StateNum == stateNumRescued)
  314. {
  315. if (playerRescued.AddTimeOfRescue(GameData.checkInterval * player.TreatSpeed))
  316. {
  317. playerRescued.SetPlayerStateNaturally();
  318. playerRescued.HP = playerRescued.MaxHp / 2;
  319. player.AddScore(GameData.StudentScoreRescue);
  320. return false;
  321. }
  322. }
  323. else return false;
  324. }
  325. return true;
  326. },
  327. timeInterval: GameData.checkInterval,
  328. finallyReturn: () => 0
  329. )
  330. .Start();
  331. playerRescued.SetTimeOfRescue(0);
  332. if (player.ResetPlayerState(stateNum)) return;
  333. lock (playerRescued.ActionLock)
  334. {
  335. if (playerRescued.StateNum == stateNumRescued)
  336. {
  337. playerRescued.SetPlayerState(RunningStateType.RunningForcibly, PlayerStateType.Addicted);
  338. return;
  339. }
  340. }
  341. }
  342. )
  343. { IsBackground = true }.Start();
  344. return true;
  345. }
  346. public bool OpenChest(Character player)
  347. {
  348. Chest? chestToOpen = (Chest?)gameMap.OneForInteract(player.Position, GameObjType.Chest);
  349. if (chestToOpen == null) return false;
  350. long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.OpeningTheChest, chestToOpen);
  351. if (stateNum == -1) return false;
  352. new Thread
  353. (
  354. () =>
  355. {
  356. player.ThreadNum.WaitOne();
  357. lock (player.ActionLock)
  358. {
  359. if (!player.StartThread(stateNum, RunningStateType.RunningSleepily))
  360. {
  361. player.ThreadNum.Release();
  362. return;
  363. }
  364. else
  365. if (!chestToOpen.Open(player))
  366. {
  367. player.ThreadNum.Release();
  368. player.SetPlayerStateNaturally();
  369. return;
  370. }
  371. }
  372. Thread.Sleep(GameData.degreeOfOpenedChest / player.SpeedOfOpenChest);
  373. if (player.ResetPlayerState(stateNum))
  374. {
  375. player.ThreadNum.Release();
  376. for (int i = 0; i < GameData.maxNumOfPropInChest; ++i)
  377. {
  378. Gadget prop = chestToOpen.PropInChest[i];
  379. chestToOpen.PropInChest[i] = new NullProp();
  380. prop.ReSetPos(player.Position);
  381. gameMap.Add(prop);
  382. }
  383. }
  384. }
  385. )
  386. { IsBackground = true }.Start();
  387. return true;
  388. }
  389. public bool ClimbingThroughWindow(Character player)
  390. {
  391. Window? windowForClimb = (Window?)gameMap.OneForInteractInACross(player.Position, GameObjType.Window);
  392. if (windowForClimb == null) return false;
  393. long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.ClimbingThroughWindows, windowForClimb);
  394. if (stateNum == -1) return false;
  395. XY windowToPlayer = new(
  396. (Math.Abs(player.Position.x - windowForClimb.Position.x) > GameData.numOfPosGridPerCell / 2) ? (GameData.numOfPosGridPerCell / 2 * (player.Position.x > windowForClimb.Position.x ? 1 : -1)) : 0,
  397. (Math.Abs(player.Position.y - windowForClimb.Position.y) > GameData.numOfPosGridPerCell / 2) ? (GameData.numOfPosGridPerCell / 2 * (player.Position.y > windowForClimb.Position.y ? 1 : -1)) : 0);
  398. /* Character? characterInWindow = (Character?)gameMap.OneInTheSameCell(windowForClimb.Position - 2 * windowToPlayer, GameObjType.Character);
  399. if (characterInWindow != null)
  400. {
  401. if (player.IsGhost() && !characterInWindow.IsGhost())
  402. characterManager.BeAttacked((Student)(characterInWindow), player.Attack(characterInWindow.Position));
  403. return false;
  404. }
  405. Wall addWall = new Wall(windowForClimb.Position - 2 * windowToPlayer);
  406. gameMap.Add(addWall);*/
  407. new Thread
  408. (
  409. () =>
  410. {
  411. player.ThreadNum.WaitOne();
  412. lock (player.ActionLock)
  413. {
  414. if (!player.StartThread(stateNum, RunningStateType.RunningSleepily))
  415. {
  416. player.ThreadNum.Release();
  417. return;
  418. }
  419. if (!windowForClimb.TryToClimb(player))
  420. {
  421. player.SetPlayerStateNaturally();
  422. player.ThreadNum.Release();
  423. return;
  424. }
  425. }
  426. Thread.Sleep((int)((windowToPlayer + windowForClimb.Position - player.Position).Length() * 1000 / player.MoveSpeed));
  427. lock (player.ActionLock)
  428. {
  429. if (!player.StartThread(stateNum, RunningStateType.RunningActively)) return;
  430. player.ReSetPos(windowToPlayer + windowForClimb.Position);
  431. windowForClimb.Enter2Stage(windowForClimb.Position - 2 * windowToPlayer);
  432. }
  433. player.MoveSpeed = player.SpeedOfClimbingThroughWindows;
  434. moveEngine.MoveObj(player, (int)(GameData.numOfPosGridPerCell * 3 * 1000 / player.MoveSpeed / 2), (-1 * windowToPlayer).Angle(), stateNum);
  435. Thread.Sleep((int)(GameData.numOfPosGridPerCell * 3 * 1000 / player.MoveSpeed / 2));
  436. player.MoveSpeed = player.ReCalculateBuff(BuffType.AddSpeed, player.OrgMoveSpeed, GameData.MaxSpeed, GameData.MinSpeed);
  437. lock (player.ActionLock)
  438. {
  439. if (stateNum == player.StateNum)
  440. {
  441. player.SetPlayerStateNaturally();
  442. windowForClimb.FinishClimbing();
  443. }
  444. }
  445. }
  446. )
  447. { IsBackground = true }.Start();
  448. return true;
  449. }
  450. public bool LockDoor(Character player)
  451. {
  452. if (player.CharacterType == CharacterType.Robot) return false;
  453. Door? doorToLock = (Door?)gameMap.OneForInteract(player.Position, GameObjType.Door);
  454. if (doorToLock == null) return false;
  455. PropType propType = doorToLock.DoorNum switch
  456. {
  457. 3 => PropType.Key3,
  458. 5 => PropType.Key5,
  459. _ => PropType.Key6,
  460. };
  461. if (!player.UseTool(propType)) return false;
  462. long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.LockingTheDoor, doorToLock);
  463. if (stateNum == -1)
  464. {
  465. player.ReleaseTool(propType);
  466. return false;
  467. }
  468. new Thread
  469. (
  470. () =>
  471. {
  472. player.ThreadNum.WaitOne();
  473. if (!player.StartThread(stateNum, RunningStateType.RunningActively))
  474. {
  475. player.ReleaseTool(propType);
  476. player.ThreadNum.Release();
  477. return;
  478. }
  479. if (!doorToLock.TryLock(player))
  480. {
  481. player.ReleaseTool(propType);
  482. player.ResetPlayerState(stateNum);
  483. player.ThreadNum.Release();
  484. return;
  485. }
  486. Thread.Sleep(GameData.checkInterval);
  487. new FrameRateTaskExecutor<int>(
  488. loopCondition: () => stateNum == player.StateNum && gameMap.Timer.IsGaming && doorToLock.LockDegree < GameData.degreeOfLockingOrOpeningTheDoor,
  489. loopToDo: () =>
  490. {
  491. if ((gameMap.PartInTheSameCell(doorToLock.Position, GameObjType.Character)) != null)
  492. return false;
  493. doorToLock.LockDegree += GameData.checkInterval * player.SpeedOfOpeningOrLocking;
  494. return true;
  495. },
  496. timeInterval: GameData.checkInterval,
  497. finallyReturn: () => 0
  498. )
  499. .Start();
  500. doorToLock.StopLock();
  501. player.ReleaseTool(propType);
  502. player.ThreadNum.Release();
  503. player.ResetPlayerState(stateNum);
  504. }
  505. )
  506. { IsBackground = true }.Start();
  507. return true;
  508. }
  509. public bool OpenDoor(Character player)
  510. {
  511. if (player.CharacterType == CharacterType.Robot) return false;
  512. Door? doorToLock = (Door?)gameMap.OneForInteract(player.Position, GameObjType.Door);
  513. if (doorToLock == null) return false;
  514. PropType propType = doorToLock.DoorNum switch
  515. {
  516. 3 => PropType.Key3,
  517. 5 => PropType.Key5,
  518. _ => PropType.Key6,
  519. };
  520. if (!player.UseTool(propType)) return false;
  521. long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.OpeningTheDoor, doorToLock);
  522. if (stateNum == -1)
  523. {
  524. player.ReleaseTool(propType);
  525. return false;
  526. }
  527. new Thread
  528. (
  529. () =>
  530. {
  531. player.ThreadNum.WaitOne();
  532. if (!player.StartThread(stateNum, RunningStateType.RunningSleepily))
  533. {
  534. player.ReleaseTool(propType);
  535. player.ThreadNum.Release();
  536. return;
  537. }
  538. if (!doorToLock.TryOpen(player))
  539. {
  540. player.ReleaseTool(propType);
  541. if (player.ResetPlayerState(stateNum))
  542. player.ThreadNum.Release();
  543. return;
  544. }
  545. Thread.Sleep(GameData.degreeOfLockingOrOpeningTheDoor / player.SpeedOfOpeningOrLocking);
  546. if (player.ResetPlayerState(stateNum))
  547. {
  548. doorToLock.StopOpen();
  549. player.ReleaseTool(propType);
  550. player.ThreadNum.Release();
  551. }
  552. }
  553. )
  554. { IsBackground = true }.Start();
  555. return true;
  556. }
  557. /*
  558. private void ActivateMine(Character player, Mine mine)
  559. {
  560. gameMap.ObjListLock.EnterWriteLock();
  561. try { gameMap.ObjList.Remove(mine); }
  562. catch { }
  563. finally { gameMap.ObjListLock.ExitWriteLock(); }
  564. switch (mine.GetPropType())
  565. {
  566. case PropType.Dirt:
  567. player.AddMoveSpeed(Constant.dirtMoveSpeedDebuff, Constant.buffPropTime);
  568. break;
  569. case PropType.Attenuator:
  570. player.AddAP(Constant.attenuatorAtkDebuff, Constant.buffPropTime);
  571. break;
  572. case PropType.Divider:
  573. player.ChangeCD(Constant.dividerCdDiscount, Constant.buffPropTime);
  574. break;
  575. }
  576. }
  577. */
  578. private readonly Map gameMap;
  579. private readonly CharacterManager characterManager;
  580. public readonly MoveEngine moveEngine;
  581. public ActionManager(Map gameMap, CharacterManager characterManager)
  582. {
  583. this.gameMap = gameMap;
  584. this.moveEngine = new MoveEngine(
  585. gameMap: gameMap,
  586. OnCollision: (obj, collisionObj, moveVec) =>
  587. {
  588. Character player = (Character)obj;
  589. switch (collisionObj.Type)
  590. {
  591. case GameObjType.Bullet:
  592. if (((Bullet)collisionObj).Parent != player && ((Bullet)collisionObj).TypeOfBullet == BulletType.JumpyDumpty)
  593. {
  594. if (CharacterManager.BeStunned((Character)player, GameData.timeOfStunnedWhenJumpyDumpty) > 0)
  595. player.AddScore(GameData.TrickerScoreStudentBeStunned(GameData.timeOfStunnedWhenJumpyDumpty));
  596. gameMap.Remove((GameObj)collisionObj);
  597. }
  598. break;
  599. case GameObjType.Character:
  600. if (player.FindActiveSkill(ActiveSkillType.CanBeginToCharge).IsBeingUsed == 1 && ((Character)collisionObj).IsGhost())
  601. {
  602. if (CharacterManager.BeStunned((Character)collisionObj, GameData.timeOfGhostStunnedWhenCharge) > 0)
  603. player.AddScore(GameData.StudentScoreTrickerBeStunned(GameData.timeOfGhostStunnedWhenCharge));
  604. CharacterManager.BeStunned(player, GameData.timeOfStudentStunnedWhenCharge);
  605. }
  606. break;
  607. case GameObjType.Item:
  608. if (((Item)collisionObj).GetPropType() == PropType.CraftingBench)
  609. {
  610. ((CraftingBench)collisionObj).TryStopSkill();
  611. gameMap.Remove((Item)collisionObj);
  612. }
  613. break;
  614. default:
  615. break;
  616. }
  617. //Preparation.Utility.Debugger.Output(obj, " end move with " + collisionObj.ToString());
  618. //if (collisionObj is Mine)
  619. //{
  620. // ActivateMine((Character)obj, (Mine)collisionObj);
  621. // return MoveEngine.AfterCollision.ContinueCheck;
  622. //}
  623. return MoveEngine.AfterCollision.MoveMax;
  624. },
  625. EndMove: obj =>
  626. {
  627. obj.ThreadNum.Release();
  628. // Debugger.Output(obj, " end move at " + obj.Position.ToString() + " At time: " + Environment.TickCount64);
  629. }
  630. );
  631. this.characterManager = characterManager;
  632. }
  633. }
  634. }
  635. }