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

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