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.

AttackManager.cs 14 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. using System;
  2. using System.Threading;
  3. using System.Collections.Generic;
  4. using GameClass.GameObj;
  5. using Preparation.Utility;
  6. using GameEngine;
  7. using Preparation.Interface;
  8. using Timothy.FrameRateTask;
  9. namespace Gaming
  10. {
  11. public partial class Game
  12. {
  13. private readonly AttackManager attackManager;
  14. private class AttackManager
  15. {
  16. readonly Map gameMap;
  17. readonly MoveEngine moveEngine;
  18. public AttackManager(Map gameMap)
  19. {
  20. this.gameMap = gameMap;
  21. this.moveEngine = new MoveEngine(
  22. gameMap: gameMap,
  23. OnCollision: (obj, collisionObj, moveVec) =>
  24. {
  25. //BulletBomb((Bullet)obj, (GameObj)collisionObj);
  26. return MoveEngine.AfterCollision.Destroyed;
  27. },
  28. EndMove: obj =>
  29. {
  30. #if DEBUG
  31. Debugger.Output(obj, " end move at " + obj.Position.ToString() + " At time: " + Environment.TickCount64);
  32. #endif
  33. BulletBomb((Bullet)obj, null);
  34. }
  35. );
  36. }
  37. public void BeAddictedToGame(Character player)
  38. {
  39. new Thread
  40. (() =>
  41. {
  42. if (player.GamingAddiction > GameData.BeginGamingAddiction && player.GamingAddiction < GameData.MidGamingAddiction)
  43. player.GamingAddiction = GameData.MidGamingAddiction;
  44. player.PlayerState = PlayerStateType.IsAddicted;
  45. new FrameRateTaskExecutor<int>(
  46. () => player.PlayerState == PlayerStateType.IsAddicted && player.GamingAddiction < player.MaxGamingAddiction,
  47. () =>
  48. {
  49. player.GamingAddiction += GameData.frameDuration;
  50. },
  51. timeInterval: GameData.frameDuration,
  52. () =>
  53. {
  54. if (player.GamingAddiction == player.MaxGamingAddiction)
  55. {
  56. player.PlayerState = PlayerStateType.Null;
  57. Die(player);
  58. }
  59. else player.CanMove = true;
  60. return 0;
  61. }
  62. )
  63. .Start();
  64. }
  65. )
  66. { IsBackground = true }.Start();
  67. }
  68. public void Die(Character player)
  69. {
  70. player.CanMove = false;
  71. player.IsResetting = true;
  72. // gameMap.GameObjLockDict[GameObjType.Character].EnterWriteLock();
  73. // try
  74. //{
  75. // gameMap.GameObjDict[GameObjType.Character].Remove(playerBeingShot);
  76. // }
  77. // finally
  78. //{
  79. // gameMap.GameObjLockDict[GameObjType.Character].ExitWriteLock();
  80. // }
  81. Prop? dropProp = null;
  82. if (player.PropInventory != null) // 若角色原来有道具,则原始道具掉落在原地
  83. {
  84. dropProp = player.PropInventory;
  85. dropProp.SetNewPos(GameData.GetCellCenterPos(player.Position.x / GameData.numOfPosGridPerCell, player.Position.y / GameData.numOfPosGridPerCell));
  86. }
  87. gameMap.GameObjLockDict[GameObjType.Prop].EnterWriteLock();
  88. try
  89. {
  90. if (dropProp != null)
  91. gameMap.GameObjDict[GameObjType.Prop].Add(dropProp);
  92. }
  93. finally
  94. {
  95. gameMap.GameObjLockDict[GameObjType.Prop].ExitWriteLock();
  96. }
  97. player.Reset();
  98. // ((Character?)bullet.Parent)?.AddScore(GameData.addScoreWhenKillOneLevelPlayer); // 给击杀者加分
  99. /* new Thread
  100. (() =>
  101. {
  102. Thread.Sleep(GameData.reviveTime);
  103. playerBeingShot.AddShield(GameData.shieldTimeAtBirth); // 复活加个盾
  104. // gameMap.GameObjLockDict[GameObjType.Character].EnterWriteLock();
  105. // try
  106. //{
  107. // gameMap.GameObjDict[GameObjType.Character].Add(playerBeingShot);
  108. // }
  109. // finally { gameMap.GameObjLockDict[GameObjType.Character].ExitWriteLock(); }
  110. if (gameMap.Timer.IsGaming)
  111. {
  112. playerBeingShot.CanMove = true;
  113. }
  114. playerBeingShot.IsResetting = false;
  115. }
  116. )
  117. { IsBackground = true }.Start();
  118. */
  119. }
  120. private bool CanBeBombed(Bullet bullet, GameObjType gameObjType)
  121. {
  122. if (gameObjType == GameObjType.Character) return true;
  123. return false;
  124. }
  125. private void BombObj(Bullet bullet, GameObj objBeingShot)
  126. {
  127. switch (objBeingShot.Type)
  128. {
  129. case GameObjType.Character:
  130. Character playerBeingShot = (Character)objBeingShot;
  131. if (playerBeingShot.BeAttacked(bullet))
  132. {
  133. BeAddictedToGame(playerBeingShot);
  134. }
  135. break;
  136. }
  137. }
  138. private void BulletBomb(Bullet bullet, GameObj? objBeingShot)
  139. {
  140. #if DEBUG
  141. Debugger.Output(bullet, "bombed!");
  142. #endif
  143. bullet.CanMove = false;
  144. gameMap.GameObjLockDict[GameObjType.Bullet].EnterWriteLock();
  145. try
  146. {
  147. foreach (ObjOfCharacter _bullet in gameMap.GameObjDict[GameObjType.Bullet])
  148. {
  149. if (_bullet.ID == bullet.ID)
  150. {
  151. gameMap.GameObjLockDict[GameObjType.BombedBullet].EnterWriteLock();
  152. try
  153. {
  154. gameMap.GameObjDict[GameObjType.BombedBullet].Add(new BombedBullet(bullet));
  155. }
  156. finally
  157. {
  158. gameMap.GameObjLockDict[GameObjType.BombedBullet].ExitWriteLock();
  159. }
  160. gameMap.GameObjDict[GameObjType.Bullet].Remove(_bullet);
  161. break;
  162. }
  163. }
  164. }
  165. finally
  166. {
  167. gameMap.GameObjLockDict[GameObjType.Bullet].ExitWriteLock();
  168. }
  169. if (!bullet.IsToBomb)
  170. {
  171. if (objBeingShot == null)
  172. {
  173. if (bullet.Backswing > 0)
  174. {
  175. bullet.Parent.CanMove = false;
  176. bullet.Parent.IsMoving = false;
  177. new Thread
  178. (() =>
  179. {
  180. Thread.Sleep(bullet.Backswing);
  181. if (gameMap.Timer.IsGaming)
  182. {
  183. bullet.Parent.CanMove = true;
  184. }
  185. }
  186. )
  187. { IsBackground = true }.Start();
  188. }
  189. return;
  190. }
  191. BombObj(bullet, objBeingShot);
  192. if (bullet.RecoveryFromHit > 0)
  193. {
  194. bullet.Parent.CanMove = false;
  195. bullet.Parent.IsMoving = false;
  196. new Thread
  197. (() =>
  198. {
  199. Thread.Sleep(bullet.RecoveryFromHit);
  200. if (gameMap.Timer.IsGaming)
  201. {
  202. bullet.Parent.CanMove = true;
  203. }
  204. }
  205. )
  206. { IsBackground = true }.Start();
  207. }
  208. return;
  209. }
  210. /*if (objBeingShot != null)
  211. {
  212. else if (objBeingShot is Bullet) //子弹不能相互引爆,若要更改这一设定,取消注释即可。
  213. {
  214. new Thread(() => { BulletBomb((Bullet)objBeingShot, null); }) { IsBackground = true }.Start();
  215. }
  216. }*/
  217. // 子弹爆炸会发生的事↓↓↓
  218. var beAttackedList = new List<IGameObj>();
  219. foreach (var kvp in gameMap.GameObjDict)
  220. {
  221. if (CanBeBombed(bullet, kvp.Key))
  222. {
  223. gameMap.GameObjLockDict[kvp.Key].EnterWriteLock();
  224. try
  225. {
  226. foreach (var item in gameMap.GameObjDict[kvp.Key])
  227. if (bullet.CanAttack((GameObj)item))
  228. {
  229. beAttackedList.Add(item);
  230. }
  231. }
  232. finally
  233. {
  234. gameMap.GameObjLockDict[kvp.Key].ExitWriteLock();
  235. }
  236. }
  237. }
  238. foreach (GameObj beAttackedObj in beAttackedList)
  239. {
  240. BombObj(bullet, beAttackedObj);
  241. }
  242. if (objBeingShot == null)
  243. {
  244. if (bullet.Backswing > 0)
  245. {
  246. bullet.Parent.CanMove = false;
  247. bullet.Parent.IsMoving = false;
  248. new Thread
  249. (() =>
  250. {
  251. Thread.Sleep(bullet.Backswing);
  252. if (gameMap.Timer.IsGaming)
  253. {
  254. bullet.Parent.CanMove = true;
  255. }
  256. }
  257. )
  258. { IsBackground = true }.Start();
  259. }
  260. }
  261. else
  262. {
  263. if (bullet.RecoveryFromHit > 0)
  264. {
  265. bullet.Parent.CanMove = false;
  266. bullet.Parent.IsMoving = false;
  267. new Thread
  268. (() =>
  269. {
  270. Thread.Sleep(bullet.RecoveryFromHit);
  271. if (gameMap.Timer.IsGaming)
  272. {
  273. bullet.Parent.CanMove = true;
  274. }
  275. }
  276. )
  277. { IsBackground = true }.Start();
  278. }
  279. }
  280. beAttackedList.Clear();
  281. }
  282. public bool Attack(Character? player, double angle) // 射出去的子弹泼出去的水(狗头)
  283. { // 子弹如果没有和其他物体碰撞,将会一直向前直到超出人物的attackRange
  284. if (player == null)
  285. {
  286. #if DEBUG
  287. Console.WriteLine("the player who will attack is NULL!");
  288. #endif
  289. return false;
  290. }
  291. if (player.IsResetting)
  292. return false;
  293. Bullet? bullet = player.RemoteAttack(
  294. new XY // 子弹紧贴人物生成。
  295. (
  296. (int)((player.Radius + BulletFactory.BulletRadius(player.BulletOfPlayer)) * Math.Cos(angle)),
  297. (int)((player.Radius + BulletFactory.BulletRadius(player.BulletOfPlayer)) * Math.Sin(angle))
  298. )
  299. );
  300. if (bullet != null)
  301. {
  302. bullet.CanMove = true;
  303. gameMap.GameObjLockDict[GameObjType.Bullet].EnterWriteLock();
  304. try
  305. {
  306. gameMap.GameObjDict[GameObjType.Bullet].Add(bullet);
  307. }
  308. finally
  309. {
  310. gameMap.GameObjLockDict[GameObjType.Bullet].ExitWriteLock();
  311. }
  312. moveEngine.MoveObj(bullet, (int)((bullet.BulletAttackRange - player.Radius - BulletFactory.BulletRadius(player.BulletOfPlayer)) * 1000 / bullet.MoveSpeed), angle); // 这里时间参数除出来的单位要是ms
  313. #if DEBUG
  314. Console.WriteLine($"playerID:{player.ID} successfully attacked!");
  315. #endif
  316. return true;
  317. }
  318. else
  319. {
  320. #if DEBUG
  321. Console.WriteLine($"playerID:{player.ID} has no bullets so that he can't attack!");
  322. #endif
  323. return false;
  324. }
  325. }
  326. }
  327. }
  328. }