Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / activity / prop / active / ActiveProp.cs
@lijincheng lijincheng on 8 Jul 2023 7 KB 调整道具架构
  1.  
  2. using Godot;
  3.  
  4. /// <summary>
  5. /// 主动使用道具
  6. /// </summary>
  7. public abstract partial class ActiveProp : Prop, IPackageItem
  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 ProcessOver(float delta)
  130. {
  131. CheckAutoDestroy();
  132. }
  133.  
  134. public override void PackProcess(float delta)
  135. {
  136. if (CheckAutoDestroy())
  137. {
  138. return;
  139. }
  140. //冷却
  141. if (_cooldownTimer > 0)
  142. {
  143. _cooldownTimer -= delta;
  144.  
  145. //冷却完成
  146. if (_cooldownTimer <= 0)
  147. {
  148. _cooldownTimer = 0;
  149. OnCooldownFinish();
  150. }
  151. }
  152. //自动充能
  153. if (AutoChargeSpeed > 0 && ChargeProgress < 1)
  154. {
  155. ChargeProgress += AutoChargeSpeed * delta;
  156. }
  157. }
  158.  
  159. //检测是否达到自动销毁的条件
  160. private bool CheckAutoDestroy()
  161. {
  162. if (Count == 0 && AutoDestroy) //用光了, 自动销毁
  163. {
  164. if (Master != null)
  165. {
  166. Master.ActivePropsPack.RemoveItem(this);
  167. }
  168. Destroy();
  169. return true;
  170. }
  171.  
  172. return false;
  173. }
  174. /// <summary>
  175. /// 检测是否可以使用当前道具
  176. /// </summary>
  177. public bool CheckUse()
  178. {
  179. return ChargeProgress >= 1 && _cooldownTimer <= 0 && Count > 0 && OnCheckUse();
  180. }
  181. /// <summary>
  182. /// 触发使用道具
  183. /// </summary>
  184. public void Use()
  185. {
  186. if (Master == null)
  187. {
  188. return;
  189. }
  190. if (CheckUse()) //可以使用道具
  191. {
  192. var num = OnUse();
  193. if (num != 0)
  194. {
  195. Count -= num;
  196. }
  197.  
  198. //冷却计时器
  199. _cooldownTimer = CooldownTime;
  200. }
  201. }
  202.  
  203. /// <summary>
  204. /// 获取冷却进度 0 - 1
  205. /// </summary>
  206. public float GetCooldownProgress()
  207. {
  208. if (_cooldownTimer <= 0)
  209. {
  210. return 1;
  211. }
  212.  
  213. return (CooldownTime - _cooldownTimer) / CooldownTime;
  214. }
  215.  
  216. public override void Interactive(ActivityObject master)
  217. {
  218. if (master is Player player)
  219. {
  220. var item = player.ActivePropsPack.GetItemById(ItemConfig.Id);
  221. if (item == null) //没有同类型物体
  222. {
  223. if (player.ActivePropsPack.HasVacancy()) //还有空位, 拾起道具
  224. {
  225. Pickup();
  226. player.PickUpActiveProp(this);
  227. }
  228.  
  229. //替换手中的道具
  230. player.ThrowActiveProp(player.ActivePropsPack.ActiveIndex);
  231. }
  232. else
  233. {
  234. //处理同类型道具
  235. if (Superposition && item.Count < item.MaxCount) //允许叠加
  236. {
  237. if (item.Count + Count > item.MaxCount)
  238. {
  239. Count -= item.MaxCount - item.Count;
  240. item.Count = item.MaxCount;
  241. }
  242. else
  243. {
  244. item.Count += Count;
  245. Count = 0;
  246. }
  247. }
  248. }
  249. }
  250. }
  251.  
  252. public override CheckInteractiveResult CheckInteractive(ActivityObject master)
  253. {
  254. if (master is Player player)
  255. {
  256. //查找相同类型的道具
  257. var item = player.ActivePropsPack.GetItemById(ItemConfig.Id);
  258. if (item == null) //没有同类型物体
  259. {
  260. if (player.ActivePropsPack.HasVacancy()) //还有空位, 拾起道具
  261. {
  262. return new CheckInteractiveResult(this, true, CheckInteractiveResult.InteractiveType.PickUp);
  263. }
  264.  
  265. //替换手中的道具
  266. return new CheckInteractiveResult(this, true, CheckInteractiveResult.InteractiveType.Replace);
  267. }
  268.  
  269. //处理同类型道具
  270. if (Superposition && item.Count < item.MaxCount) //允许叠加
  271. {
  272. return new CheckInteractiveResult(this, true, CheckInteractiveResult.InteractiveType.Bullet);
  273. }
  274.  
  275. //该道具不能拾起
  276. return new CheckInteractiveResult(this);
  277. }
  278.  
  279. return new CheckInteractiveResult(this);
  280. }
  281.  
  282. public override void OnPickUpItem()
  283. {
  284. }
  285.  
  286. public override void OnRemoveItem()
  287. {
  288. }
  289.  
  290. public virtual void OnActiveItem()
  291. {
  292. }
  293.  
  294. public virtual void OnConcealItem()
  295. {
  296. }
  297.  
  298. public virtual void OnOverflowItem()
  299. {
  300. }
  301. }