Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / activity / prop / active / ActivePropActivity.cs
@小李xl 小李xl on 13 Mar 2024 7 KB 重构buff中
  1.  
  2. using Godot;
  3.  
  4. /// <summary>
  5. /// 主动使用道具
  6. /// </summary>
  7. public abstract partial class ActivePropActivity : PropActivity, IPackageItem<Role>
  8. {
  9. public int PackageIndex { get; set; }
  10. /// <summary>
  11. /// 道具是否可以叠加
  12. /// </summary>
  13. public bool Superposition { get; set; } = false;
  14. /// <summary>
  15. /// 道具可使用次数
  16. /// </summary>
  17. public int Count
  18. {
  19. get => _count;
  20. set
  21. {
  22. var temp = _count;
  23. _count = Mathf.Clamp(value, 0, _maxCount);
  24. if (temp != _count)
  25. {
  26. OnChangeCount();
  27. }
  28. }
  29. }
  30.  
  31. private int _count = 1;
  32.  
  33. /// <summary>
  34. /// 道具最大叠加用次数
  35. /// </summary>
  36. public int MaxCount
  37. {
  38. get => _maxCount;
  39. set
  40. {
  41. var temp = _maxCount;
  42. _maxCount = Mathf.Max(1, value);
  43. if (temp != _maxCount)
  44. {
  45. OnChangeMaxCount();
  46. }
  47.  
  48. if (Count > _maxCount)
  49. {
  50. Count = _maxCount;
  51. }
  52. }
  53. }
  54.  
  55. private int _maxCount = 1;
  56.  
  57. /// <summary>
  58. /// 使用一次后的冷却时间, 单位: 秒
  59. /// </summary>
  60. public float CooldownTime { get; set; } = 2f;
  61. /// <summary>
  62. /// 当道具使用完后是否自动销毁
  63. /// </summary>
  64. public bool AutoDestroy { get; set; } = false;
  65.  
  66. /// <summary>
  67. /// 道具充能进度, 必须要充能完成才能使用, 值范围: 0 - 1
  68. /// </summary>
  69. public float ChargeProgress
  70. {
  71. get => _chargeProgress;
  72. set
  73. {
  74. var temp = _chargeProgress;
  75. _chargeProgress = Mathf.Clamp(value, 0, 1);
  76. if (temp != _chargeProgress)
  77. {
  78. OnChangeChargeProgress();
  79. }
  80. }
  81. }
  82.  
  83. private float _chargeProgress = 1;
  84. /// <summary>
  85. /// 自动充能速度, 也就是每秒充能进度, 如果为0则表示不就行自动充能
  86. /// </summary>
  87. public float AutoChargeSpeed { get; set; }
  88.  
  89. //冷却计时器
  90. private float _cooldownTimer = 0;
  91. /// <summary>
  92. /// 当检测是否可以使用时调用
  93. /// </summary>
  94. public abstract bool OnCheckUse();
  95.  
  96. /// <summary>
  97. /// 当道具被使用时调用, 函数返回值为消耗数量
  98. /// </summary>
  99. protected abstract int OnUse();
  100.  
  101. /// <summary>
  102. /// 道具数量改变时调用
  103. /// </summary>
  104. protected virtual void OnChangeCount()
  105. {
  106. }
  107.  
  108. /// <summary>
  109. /// 道具最大数量改变时调用
  110. /// </summary>
  111. protected virtual void OnChangeMaxCount()
  112. {
  113. }
  114.  
  115. /// <summary>
  116. /// 道具充能进度改变时调用
  117. /// </summary>
  118. protected virtual void OnChangeChargeProgress()
  119. {
  120. }
  121.  
  122. /// <summary>
  123. /// 冷却完成时调用
  124. /// </summary>
  125. protected virtual void OnCooldownFinish()
  126. {
  127. }
  128.  
  129. protected override void Process(float delta)
  130. {
  131. RunUpdate(delta);
  132. }
  133.  
  134. public override void PackProcess(float delta)
  135. {
  136. RunUpdate(delta);
  137. }
  138.  
  139. private void RunUpdate(float delta)
  140. {
  141. if (CheckAutoDestroy())
  142. {
  143. return;
  144. }
  145. //冷却
  146. if (_cooldownTimer > 0)
  147. {
  148. _cooldownTimer -= delta;
  149.  
  150. //冷却完成
  151. if (_cooldownTimer <= 0)
  152. {
  153. _cooldownTimer = 0;
  154. OnCooldownFinish();
  155. }
  156. }
  157. //自动充能
  158. if (AutoChargeSpeed > 0 && ChargeProgress < 1)
  159. {
  160. ChargeProgress += AutoChargeSpeed * delta;
  161. }
  162. }
  163.  
  164. //检测是否达到自动销毁的条件
  165. private bool CheckAutoDestroy()
  166. {
  167. if (Count == 0 && AutoDestroy) //用光了, 自动销毁
  168. {
  169. if (Master != null)
  170. {
  171. Master.ActivePropsPack.RemoveItem(this);
  172. }
  173. Destroy();
  174. return true;
  175. }
  176.  
  177. return false;
  178. }
  179. /// <summary>
  180. /// 检测是否可以使用当前道具
  181. /// </summary>
  182. public bool CheckUse()
  183. {
  184. return ChargeProgress >= 1 && _cooldownTimer <= 0 && Count > 0 && OnCheckUse();
  185. }
  186. /// <summary>
  187. /// 触发使用道具
  188. /// </summary>
  189. public void Use()
  190. {
  191. if (Master == null)
  192. {
  193. return;
  194. }
  195. if (CheckUse()) //可以使用道具
  196. {
  197. var num = OnUse();
  198. if (num != 0)
  199. {
  200. Count -= num;
  201. }
  202.  
  203. //冷却计时器
  204. _cooldownTimer = CooldownTime;
  205. }
  206. }
  207.  
  208. /// <summary>
  209. /// 获取冷却进度 0 - 1
  210. /// </summary>
  211. public float GetCooldownProgress()
  212. {
  213. if (_cooldownTimer <= 0)
  214. {
  215. return 1;
  216. }
  217.  
  218. return (CooldownTime - _cooldownTimer) / CooldownTime;
  219. }
  220.  
  221. public override void Interactive(ActivityObject master)
  222. {
  223. if (master is Player player)
  224. {
  225. if (player.ActivePropsPack.Capacity == 0)
  226. {
  227. //容量为0
  228. return;
  229. }
  230. var item = player.ActivePropsPack.GetItemById(ActivityBase.Id);
  231. if (item == null) //没有同类型物体
  232. {
  233. if (!player.ActivePropsPack.HasVacancy()) //没有空位置, 扔掉当前道具
  234. {
  235. player.ThrowActiveProp(player.ActivePropsPack.ActiveIndex);
  236. }
  237. //替换手中的道具
  238. if (player.PickUpActiveProp(this))
  239. {
  240. Pickup();
  241. }
  242. }
  243. else
  244. {
  245. //处理同类型道具
  246. if (Superposition && item.Count < item.MaxCount) //允许叠加
  247. {
  248. if (item.Count + Count > item.MaxCount)
  249. {
  250. Count -= item.MaxCount - item.Count;
  251. item.Count = item.MaxCount;
  252. }
  253. else
  254. {
  255. item.Count += Count;
  256. Count = 0;
  257. }
  258. Destroy();
  259. }
  260. }
  261. }
  262. }
  263.  
  264. public override CheckInteractiveResult CheckInteractive(ActivityObject master)
  265. {
  266. if (master is Player player)
  267. {
  268. if (player.ActivePropsPack.Capacity == 0)
  269. {
  270. //容量为0
  271. return new CheckInteractiveResult(this);
  272. }
  273. //查找相同类型的道具
  274. var item = player.ActivePropsPack.GetItemById(ActivityBase.Id);
  275. if (item == null) //没有同类型物体
  276. {
  277. if (player.ActivePropsPack.HasVacancy()) //还有空位, 拾起道具
  278. {
  279. return new CheckInteractiveResult(this, true, CheckInteractiveResult.InteractiveType.PickUp);
  280. }
  281.  
  282. //替换手中的道具
  283. return new CheckInteractiveResult(this, true, CheckInteractiveResult.InteractiveType.Replace);
  284. }
  285.  
  286. //处理同类型道具
  287. if (Superposition && item.Count < item.MaxCount) //允许叠加
  288. {
  289. return new CheckInteractiveResult(this, true, CheckInteractiveResult.InteractiveType.Bullet);
  290. }
  291.  
  292. //该道具不能拾起
  293. return new CheckInteractiveResult(this);
  294. }
  295.  
  296. return new CheckInteractiveResult(this);
  297. }
  298.  
  299. public override void OnPickUpItem()
  300. {
  301. }
  302.  
  303. public override void OnRemoveItem()
  304. {
  305. }
  306.  
  307. public virtual void OnActiveItem()
  308. {
  309. }
  310.  
  311. public virtual void OnConcealItem()
  312. {
  313. }
  314.  
  315. public virtual void OnOverflowItem()
  316. {
  317. Master.ThrowActiveProp(PackageIndex);
  318. }
  319. }