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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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 BecomeInvisible : IActiveSkill
  30. {
  31. public int SkillCD => GameData.commonSkillCD;
  32. public int DurationTime => GameData.commonSkillTime / 10 * 6;
  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.IsInvisible = true;
  40. Debugger.Output(player, "uses atombomb!");
  41. },
  42. () =>
  43. { player.IsInvisible = false; });
  44. }
  45. }
  46. public class NuclearWeapon : IActiveSkill // 核武器
  47. {
  48. public int SkillCD => GameData.commonSkillCD / 3 * 7;
  49. public int DurationTime => GameData.commonSkillTime / 10;
  50. private readonly object commonSkillLock = new object();
  51. public object ActiveSkillLock => commonSkillLock;
  52. public bool SkillEffect(Character player)
  53. {
  54. return ActiveSkillFactory.SkillEffect(this, player, () =>
  55. {
  56. player.BulletOfPlayer = BulletType.AtomBomb;
  57. Debugger.Output(player, "uses atombomb!");
  58. },
  59. () =>
  60. { player.BulletOfPlayer = player.OriBulletOfPlayer; });
  61. }
  62. }
  63. public class UseKnife : IActiveSkill
  64. {
  65. public int SkillCD => GameData.commonSkillCD / 3 * 2;
  66. public int DurationTime => GameData.commonSkillTime / 10;
  67. private readonly object commonSkillLock = new object();
  68. public object ActiveSkillLock => commonSkillLock;
  69. public bool SkillEffect(Character player)
  70. {
  71. return ActiveSkillFactory.SkillEffect(this, player, () =>
  72. {
  73. player.BulletOfPlayer = BulletType.FlyingKnife;
  74. Debugger.Output(player, "uses flyingknife!");
  75. },
  76. () =>
  77. { player.BulletOfPlayer = player.OriBulletOfPlayer; });
  78. }
  79. }
  80. public class SuperFast : IActiveSkill // 3倍速
  81. {
  82. public int SkillCD => GameData.commonSkillCD;
  83. public int DurationTime => GameData.commonSkillTime / 10 * 4;
  84. private readonly object commonSkillLock = new object();
  85. public object ActiveSkillLock => commonSkillLock;
  86. public bool SkillEffect(Character player)
  87. {
  88. return ActiveSkillFactory.SkillEffect(this, player, () =>
  89. {
  90. player.AddMoveSpeed(this.DurationTime, 3.0);
  91. Debugger.Output(player, "moves very fast!");
  92. },
  93. () =>
  94. { });
  95. }
  96. }
  97. public class NoCommonSkill : IActiveSkill // 这种情况不该发生,定义着以防意外
  98. {
  99. public int SkillCD => GameData.commonSkillCD;
  100. public int DurationTime => GameData.commonSkillTime;
  101. private readonly object commonSkillLock = new object();
  102. public object ActiveSkillLock => commonSkillLock;
  103. public bool SkillEffect(Character player)
  104. {
  105. return false;
  106. }
  107. }
  108. public static class ActiveSkillFactory
  109. {
  110. public static bool SkillEffect(IActiveSkill activeSkill, Character player, Action startSkill, Action endSkill)
  111. {
  112. lock (activeSkill.ActiveSkillLock)
  113. {
  114. ActiveSkillType activeSkillType = FindActiveSkillType(activeSkill);
  115. if (player.TimeUntilActiveSkillAvailable[activeSkillType] == 0)
  116. {
  117. player.SetTimeUntilActiveSkillAvailable(activeSkillType, activeSkill.SkillCD);
  118. new Thread
  119. (() =>
  120. {
  121. startSkill();
  122. new FrameRateTaskExecutor<int>(
  123. () => !player.IsResetting,
  124. () =>
  125. {
  126. player.AddTimeUntilActiveSkillAvailable(activeSkillType, -(int)GameData.frameDuration);
  127. },
  128. timeInterval: GameData.frameDuration,
  129. () => 0,
  130. maxTotalDuration: (long)(activeSkill.DurationTime)
  131. )
  132. {
  133. AllowTimeExceed = true,
  134. MaxTolerantTimeExceedCount = ulong.MaxValue,
  135. }
  136. .Start();
  137. endSkill();
  138. Debugger.Output(player, "return to normal.");
  139. new FrameRateTaskExecutor<int>(
  140. () => player.TimeUntilActiveSkillAvailable[activeSkillType] > 0 && !player.IsResetting,
  141. () =>
  142. {
  143. player.AddTimeUntilActiveSkillAvailable(activeSkillType, -(int)GameData.frameDuration);
  144. },
  145. timeInterval: GameData.frameDuration,
  146. () => 0,
  147. maxTotalDuration: (long)(activeSkill.SkillCD - activeSkill.DurationTime)
  148. )
  149. {
  150. AllowTimeExceed = true,
  151. MaxTolerantTimeExceedCount = ulong.MaxValue,
  152. }
  153. .Start();
  154. player.SetTimeUntilActiveSkillAvailable(activeSkillType, 0);
  155. Debugger.Output(player, "CommonSkill is ready.");
  156. }
  157. )
  158. { IsBackground = true }.Start();
  159. return true;
  160. }
  161. else
  162. {
  163. Debugger.Output(player, "CommonSkill is cooling down!");
  164. return false;
  165. }
  166. }
  167. }
  168. public static IActiveSkill FindIActiveSkill(ActiveSkillType activeSkillType)
  169. {
  170. switch (activeSkillType)
  171. {
  172. case ActiveSkillType.BecomeInvisible:
  173. return new BecomeInvisible();
  174. default:
  175. return null;
  176. }
  177. }
  178. public static ActiveSkillType FindActiveSkillType(IActiveSkill ActiveSkill)
  179. {
  180. switch (ActiveSkill)
  181. {
  182. case BecomeInvisible:
  183. return ActiveSkillType.BecomeInvisible;
  184. default:
  185. return ActiveSkillType.Null;
  186. }
  187. }
  188. }
  189. }