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.

ActiveSkill.cs 10 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. using GameClass.GameObj;
  2. using System.Threading;
  3. using Preparation.Interface;
  4. using Preparation.Utility;
  5. using System;
  6. using Timothy.FrameRateTask;
  7. namespace GameClass.Skill
  8. {
  9. public class BecomeVampire : IActiveSkill // 化身吸血鬼
  10. {
  11. public int SkillCD => GameData.commonSkillCD / 3 * 4;
  12. public int DurationTime => GameData.commonSkillTime;
  13. private readonly object commonSkillLock = new object();
  14. public object ActiveSkillLock => commonSkillLock;
  15. public bool SkillEffect(Character player)
  16. {
  17. return ActiveSkillFactory.SkillEffect(this, player, () =>
  18. {
  19. player.Vampire += 0.5;
  20. Debugger.Output(player, "becomes vampire!");
  21. },
  22. () =>
  23. {
  24. double tempVam = player.Vampire - 0.5;
  25. player.Vampire = tempVam < player.OriVampire ? player.OriVampire : tempVam;
  26. });
  27. }
  28. }
  29. public class BeginToCharge : IActiveSkill
  30. {
  31. public int SkillCD => GameData.commonSkillCD / 3 * 4;
  32. public int DurationTime => GameData.commonSkillTime;
  33. private readonly object commonSkillLock = new object();
  34. public object ActiveSkillLock => commonSkillLock;
  35. public bool SkillEffect(Character player)
  36. {
  37. return ActiveSkillFactory.SkillEffect(this, player, () =>
  38. {
  39. player.Vampire += 0.5;
  40. Debugger.Output(player, "becomes vampire!");
  41. },
  42. () =>
  43. {
  44. double tempVam = player.Vampire - 0.5;
  45. player.Vampire = tempVam < player.OriVampire ? player.OriVampire : tempVam;
  46. });
  47. }
  48. }
  49. public class BecomeInvisible : IActiveSkill
  50. {
  51. public int SkillCD => GameData.commonSkillCD;
  52. public int DurationTime => GameData.commonSkillTime / 10 * 6;
  53. private readonly object commonSkillLock = new object();
  54. public object ActiveSkillLock => commonSkillLock;
  55. public bool SkillEffect(Character player)
  56. {
  57. return ActiveSkillFactory.SkillEffect(this, player, () =>
  58. {
  59. player.IsInvisible = true;
  60. Debugger.Output(player, "uses atombomb!");
  61. },
  62. () =>
  63. { player.IsInvisible = false; });
  64. }
  65. }
  66. public class NuclearWeapon : IActiveSkill // 核武器
  67. {
  68. public int SkillCD => GameData.commonSkillCD / 3 * 7;
  69. public int DurationTime => GameData.commonSkillTime / 10;
  70. private readonly object commonSkillLock = new object();
  71. public object ActiveSkillLock => commonSkillLock;
  72. public bool SkillEffect(Character player)
  73. {
  74. return ActiveSkillFactory.SkillEffect(this, player, () =>
  75. {
  76. player.BulletOfPlayer = BulletType.AtomBomb;
  77. Debugger.Output(player, "uses atombomb!");
  78. },
  79. () =>
  80. { player.BulletOfPlayer = player.OriBulletOfPlayer; });
  81. }
  82. }
  83. public class UseKnife : IActiveSkill
  84. {
  85. public int SkillCD => GameData.commonSkillCD / 3 * 2;
  86. public int DurationTime => GameData.commonSkillTime / 10;
  87. private readonly object commonSkillLock = new object();
  88. public object ActiveSkillLock => commonSkillLock;
  89. public bool SkillEffect(Character player)
  90. {
  91. return ActiveSkillFactory.SkillEffect(this, player, () =>
  92. {
  93. player.BulletOfPlayer = BulletType.FlyingKnife;
  94. Debugger.Output(player, "uses flyingknife!");
  95. },
  96. () =>
  97. { player.BulletOfPlayer = player.OriBulletOfPlayer; });
  98. }
  99. }
  100. public class SuperFast : IActiveSkill // 3倍速
  101. {
  102. public int SkillCD => GameData.commonSkillCD;
  103. public int DurationTime => GameData.commonSkillTime / 10 * 4;
  104. private readonly object commonSkillLock = new object();
  105. public object ActiveSkillLock => commonSkillLock;
  106. public bool SkillEffect(Character player)
  107. {
  108. return ActiveSkillFactory.SkillEffect(this, player, () =>
  109. {
  110. player.AddMoveSpeed(this.DurationTime, 3.0);
  111. Debugger.Output(player, "moves very fast!");
  112. },
  113. () =>
  114. { });
  115. }
  116. }
  117. public class NoCommonSkill : IActiveSkill // 这种情况不该发生,定义着以防意外
  118. {
  119. public int SkillCD => GameData.commonSkillCD;
  120. public int DurationTime => GameData.commonSkillTime;
  121. private readonly object commonSkillLock = new object();
  122. public object ActiveSkillLock => commonSkillLock;
  123. public bool SkillEffect(Character player)
  124. {
  125. return false;
  126. }
  127. }
  128. public static class ActiveSkillFactory
  129. {
  130. public static bool SkillEffect(IActiveSkill activeSkill, Character player, Action startSkill, Action endSkill)
  131. {
  132. lock (activeSkill.ActiveSkillLock)
  133. {
  134. ActiveSkillType activeSkillType = FindActiveSkillType(activeSkill);
  135. if (player.TimeUntilActiveSkillAvailable[activeSkillType] == 0)
  136. {
  137. player.SetTimeUntilActiveSkillAvailable(activeSkillType, activeSkill.SkillCD);
  138. new Thread
  139. (() =>
  140. {
  141. startSkill();
  142. new FrameRateTaskExecutor<int>(
  143. () => !player.IsResetting,
  144. () =>
  145. {
  146. player.AddTimeUntilActiveSkillAvailable(activeSkillType, -(int)GameData.frameDuration);
  147. },
  148. timeInterval: GameData.frameDuration,
  149. () => 0,
  150. maxTotalDuration: (long)(activeSkill.DurationTime)
  151. )
  152. {
  153. AllowTimeExceed = true,
  154. MaxTolerantTimeExceedCount = ulong.MaxValue,
  155. }
  156. .Start();
  157. endSkill();
  158. Debugger.Output(player, "return to normal.");
  159. new FrameRateTaskExecutor<int>(
  160. () => player.TimeUntilActiveSkillAvailable[activeSkillType] > 0 && !player.IsResetting,
  161. () =>
  162. {
  163. player.AddTimeUntilActiveSkillAvailable(activeSkillType, -(int)GameData.frameDuration);
  164. },
  165. timeInterval: GameData.frameDuration,
  166. () => 0,
  167. maxTotalDuration: (long)(activeSkill.SkillCD - activeSkill.DurationTime)
  168. )
  169. {
  170. AllowTimeExceed = true,
  171. MaxTolerantTimeExceedCount = ulong.MaxValue,
  172. }
  173. .Start();
  174. player.SetTimeUntilActiveSkillAvailable(activeSkillType, 0);
  175. Debugger.Output(player, "CommonSkill is ready.");
  176. }
  177. )
  178. { IsBackground = true }.Start();
  179. return true;
  180. }
  181. else
  182. {
  183. Debugger.Output(player, "CommonSkill is cooling down!");
  184. return false;
  185. }
  186. }
  187. }
  188. public static IActiveSkill? FindIActiveSkill(ActiveSkillType activeSkillType)
  189. {
  190. switch (activeSkillType)
  191. {
  192. case ActiveSkillType.BecomeInvisible:
  193. return new BecomeInvisible();
  194. default:
  195. return null;
  196. }
  197. }
  198. public static ActiveSkillType FindActiveSkillType(IActiveSkill ActiveSkill)
  199. {
  200. switch (ActiveSkill)
  201. {
  202. case BecomeInvisible:
  203. return ActiveSkillType.BecomeInvisible;
  204. case UseKnife:
  205. return ActiveSkillType.UseKnife;
  206. case BeginToCharge:
  207. return ActiveSkillType.BeginToCharge;
  208. default:
  209. return ActiveSkillType.Null;
  210. }
  211. }
  212. }
  213. }