Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / activity / prop / active / ActiveProp.cs
  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 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. var item = player.ActivePropsPack.GetItemById(ItemConfig.Id);
  226. if (item == null) //没有同类型物体
  227. {
  228. if (!player.ActivePropsPack.HasVacancy()) //没有空位置, 扔掉当前道具
  229. {
  230. player.ThrowActiveProp(player.ActivePropsPack.ActiveIndex);
  231. }
  232. //替换手中的道具
  233. if (player.PickUpActiveProp(this))
  234. {
  235. Pickup();
  236. }
  237. }
  238. else
  239. {
  240. //处理同类型道具
  241. if (Superposition && item.Count < item.MaxCount) //允许叠加
  242. {
  243. if (item.Count + Count > item.MaxCount)
  244. {
  245. Count -= item.MaxCount - item.Count;
  246. item.Count = item.MaxCount;
  247. }
  248. else
  249. {
  250. item.Count += Count;
  251. Count = 0;
  252. }
  253. Destroy();
  254. }
  255. }
  256. }
  257. }
  258.  
  259. public override CheckInteractiveResult CheckInteractive(ActivityObject master)
  260. {
  261. if (master is Player player)
  262. {
  263. //查找相同类型的道具
  264. var item = player.ActivePropsPack.GetItemById(ItemConfig.Id);
  265. if (item == null) //没有同类型物体
  266. {
  267. if (player.ActivePropsPack.HasVacancy()) //还有空位, 拾起道具
  268. {
  269. return new CheckInteractiveResult(this, true, CheckInteractiveResult.InteractiveType.PickUp);
  270. }
  271.  
  272. //替换手中的道具
  273. return new CheckInteractiveResult(this, true, CheckInteractiveResult.InteractiveType.Replace);
  274. }
  275.  
  276. //处理同类型道具
  277. if (Superposition && item.Count < item.MaxCount) //允许叠加
  278. {
  279. return new CheckInteractiveResult(this, true, CheckInteractiveResult.InteractiveType.Bullet);
  280. }
  281.  
  282. //该道具不能拾起
  283. return new CheckInteractiveResult(this);
  284. }
  285.  
  286. return new CheckInteractiveResult(this);
  287. }
  288.  
  289. public override void OnPickUpItem()
  290. {
  291. }
  292.  
  293. public override void OnRemoveItem()
  294. {
  295. }
  296.  
  297. public virtual void OnActiveItem()
  298. {
  299. }
  300.  
  301. public virtual void OnConcealItem()
  302. {
  303. }
  304.  
  305. public virtual void OnOverflowItem()
  306. {
  307. }
  308. }