Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / activity / prop / ActiveProp.cs
@小李xl 小李xl on 20 Mar 2024 15 KB 解决编译错误
  1.  
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Text.Json;
  5. using Config;
  6. using Godot;
  7.  
  8. /// <summary>
  9. /// 主动使用道具
  10. /// </summary>
  11. [Tool]
  12. public partial class ActiveProp : PropActivity, IPackageItem<Role>
  13. {
  14. /// <summary>
  15. /// 配置数据
  16. /// </summary>
  17. public ExcelConfig.ActivePropBase Attribute { get; private set; }
  18. public int PackageIndex { get; set; }
  19. /// <summary>
  20. /// 道具可使用次数
  21. /// </summary>
  22. public int Count
  23. {
  24. get => _count;
  25. set
  26. {
  27. var temp = _count;
  28. _count = Mathf.Clamp(value, 0, _maxCount);
  29. if (temp != _count)
  30. {
  31. OnChangeCount();
  32. }
  33. }
  34. }
  35.  
  36. private int _count = 1;
  37.  
  38. /// <summary>
  39. /// 道具最大叠加用次数
  40. /// </summary>
  41. public int MaxCount
  42. {
  43. get => _maxCount;
  44. set
  45. {
  46. var temp = _maxCount;
  47. _maxCount = Mathf.Max(1, value);
  48. if (temp != _maxCount)
  49. {
  50. OnChangeMaxCount();
  51. }
  52.  
  53. if (Count > _maxCount)
  54. {
  55. Count = _maxCount;
  56. }
  57. }
  58. }
  59.  
  60. private int _maxCount = 1;
  61. /// <summary>
  62. /// 道具充能进度, 必须要充能完成才能使用, 值范围: 0 - 1
  63. /// </summary>
  64. public float ChargeProgress
  65. {
  66. get => _chargeProgress;
  67. set
  68. {
  69. var temp = _chargeProgress;
  70. _chargeProgress = Mathf.Clamp(value, 0, 1);
  71. if (temp != _chargeProgress)
  72. {
  73. OnChangeChargeProgress();
  74. }
  75. }
  76. }
  77.  
  78. private float _chargeProgress = 1;
  79. /// <summary>
  80. /// 自动充能速度, 也就是每秒充能进度, 如果为0则表示不就行自动充能
  81. /// </summary>
  82. public float AutoChargeSpeed { get; set; }
  83.  
  84. /// <summary>
  85. /// 是否正使用中
  86. /// </summary>
  87. public bool IsUsing => _durationTimer > 0;
  88.  
  89. /// <summary>
  90. /// 道具使用时间进度 (0 - 1)
  91. /// </summary>
  92. public float UsingProgress => 1 - _durationTimer / Attribute.Duration;
  93.  
  94. //冷却计时器
  95. private float _cooldownTimer = 0;
  96. //持续时间计时器
  97. private float _durationTimer = 0;
  98. //被动属性
  99. private readonly List<BuffFragment> _buffFragment = new List<BuffFragment>();
  100. //条件
  101. private readonly List<ConditionFragment> _conditionFragment = new List<ConditionFragment>();
  102. //效果
  103. private readonly List<EffectFragment> _effectFragment = new List<EffectFragment>();
  104. //充能
  105. private readonly List<ChargeFragment> _chargeFragment = new List<ChargeFragment>();
  106.  
  107. public override void OnInit()
  108. {
  109. base.OnInit();
  110. var buffAttribute = GetActiveAttribute(ActivityBase.Id);
  111. Attribute = buffAttribute;
  112. //初始化buff属性
  113. if (buffAttribute.Buff != null)
  114. {
  115. foreach (var keyValuePair in buffAttribute.Buff)
  116. {
  117. var buffInfo = PropFragmentRegister.BuffFragmentInfos[keyValuePair.Key];
  118. var item = keyValuePair.Value;
  119. var buff = (BuffFragment)AddComponent(buffInfo.Type);
  120. try
  121. {
  122. buff.InitParam(item);
  123. }
  124. catch (Exception e)
  125. {
  126. Debug.LogError($"初始化道具'{ActivityBase.Id}'参数时发生异常: {e.Message}\n{e.StackTrace}");
  127. }
  128. _buffFragment.Add(buff);
  129. }
  130. }
  131.  
  132. //初始化条件属性
  133. if (buffAttribute.Condition != null)
  134. {
  135. foreach (var keyValuePair in buffAttribute.Condition)
  136. {
  137. var buffInfo = PropFragmentRegister.ConditionFragmentInfos[keyValuePair.Key];
  138. var item = keyValuePair.Value;
  139. var buff = (ConditionFragment)AddComponent(buffInfo.Type);
  140. try
  141. {
  142. buff.InitParam(item);
  143. }
  144. catch (Exception e)
  145. {
  146. Debug.LogError($"初始化道具'{ActivityBase.Id}'参数时发生异常: {e.Message}\n{e.StackTrace}");
  147. }
  148. _conditionFragment.Add(buff);
  149. }
  150. }
  151.  
  152. //初始化效果属性
  153. if (buffAttribute.Effect != null)
  154. {
  155. foreach (var keyValuePair in buffAttribute.Effect)
  156. {
  157. var buffInfo = PropFragmentRegister.EffectFragmentInfos[keyValuePair.Key];
  158. var item = keyValuePair.Value;
  159. var buff = (EffectFragment)AddComponent(buffInfo.Type);
  160. try
  161. {
  162. buff.InitParam(item);
  163. }
  164. catch (Exception e)
  165. {
  166. Debug.LogError($"初始化道具'{ActivityBase.Id}'参数时发生异常: {e.Message}\n{e.StackTrace}");
  167. }
  168. _effectFragment.Add(buff);
  169. }
  170. }
  171.  
  172. //初始化道具冷却属性数据
  173. if (!buffAttribute.IsConsumables && buffAttribute.Charge != null)
  174. {
  175. foreach (var keyValuePair in buffAttribute.Charge)
  176. {
  177. var buffInfo = PropFragmentRegister.ChargeFragmentInfos[keyValuePair.Key];
  178. var item = keyValuePair.Value;
  179. var buff = (ChargeFragment)AddComponent(buffInfo.Type);
  180. try
  181. {
  182. buff.InitParam(item);
  183. }
  184. catch (Exception e)
  185. {
  186. Debug.LogError($"初始化道具'{ActivityBase.Id}'参数时发生异常: {e.Message}\n{e.StackTrace}");
  187. }
  188. _chargeFragment.Add(buff);
  189. }
  190. }
  191. //显示纹理
  192. if (!string.IsNullOrEmpty(ActivityBase.Icon))
  193. {
  194. SetDefaultTexture(ResourceManager.LoadTexture2D(ActivityBase.Icon));
  195. }
  196.  
  197. MaxCount = (int)Attribute.MaxCount;
  198. }
  199.  
  200. /// <summary>
  201. /// 当检测是否可以使用时调用
  202. /// </summary>
  203. public virtual bool OnCheckUse()
  204. {
  205. foreach (var fragment in _conditionFragment)
  206. {
  207. if (!fragment.OnCheckUse()) return false;
  208. }
  209. foreach (var fragment in _effectFragment)
  210. {
  211. if (!fragment.OnCheckUse()) return false;
  212. }
  213.  
  214. return true;
  215. }
  216.  
  217. /// <summary>
  218. /// 当道具被使用时调用
  219. /// </summary>
  220. protected virtual void OnUse()
  221. {
  222. foreach (var fragment in _effectFragment)
  223. {
  224. fragment.OnUse();
  225. }
  226.  
  227. foreach (var fragment in _chargeFragment)
  228. {
  229. fragment.OnUse();
  230. }
  231. }
  232.  
  233. /// <summary>
  234. /// 道具使用持续时间完成时调用
  235. /// </summary>
  236. protected virtual void OnUsingFinish()
  237. {
  238. }
  239.  
  240. /// <summary>
  241. /// 道具数量改变时调用
  242. /// </summary>
  243. protected virtual void OnChangeCount()
  244. {
  245. }
  246.  
  247. /// <summary>
  248. /// 道具最大数量改变时调用
  249. /// </summary>
  250. protected virtual void OnChangeMaxCount()
  251. {
  252. }
  253.  
  254. /// <summary>
  255. /// 道具充能进度改变时调用
  256. /// </summary>
  257. protected virtual void OnChangeChargeProgress()
  258. {
  259. }
  260.  
  261. /// <summary>
  262. /// 冷却完成时调用
  263. /// </summary>
  264. protected virtual void OnCooldownFinish()
  265. {
  266. }
  267.  
  268. protected override void Process(float delta)
  269. {
  270. if (CheckAutoDestroy())
  271. {
  272. return;
  273. }
  274.  
  275. //持续时间
  276. if (_durationTimer > 0)
  277. {
  278. _durationTimer -= delta;
  279. //持续时间完成
  280. if (_durationTimer <= 0)
  281. {
  282. _durationTimer = 0;
  283. //冷却计时器
  284. _cooldownTimer = Attribute.CooldownTime;
  285. UsingFinish();
  286. }
  287. }
  288. //冷却
  289. else if (_cooldownTimer > 0)
  290. {
  291. _cooldownTimer -= delta;
  292.  
  293. //冷却完成
  294. if (_cooldownTimer <= 0)
  295. {
  296. _cooldownTimer = 0;
  297. OnCooldownFinish();
  298. }
  299. }
  300. //自动充能
  301. if (AutoChargeSpeed > 0 && ChargeProgress < 1)
  302. {
  303. ChargeProgress += AutoChargeSpeed * delta;
  304. }
  305. }
  306. //检测是否达到自动销毁的条件
  307. private bool CheckAutoDestroy()
  308. {
  309. if (Count == 0 && Attribute.IsConsumables) //用光了, 自动销毁
  310. {
  311. if (Master != null)
  312. {
  313. Master.ActivePropsPack.RemoveItem(this);
  314. }
  315. Destroy();
  316. return true;
  317. }
  318.  
  319. return false;
  320. }
  321. /// <summary>
  322. /// 检测是否可以使用当前道具
  323. /// </summary>
  324. public bool CheckUse()
  325. {
  326. return ChargeProgress >= 1 && _cooldownTimer <= 0 && Count > 0 && OnCheckUse();
  327. }
  328. /// <summary>
  329. /// 触发使用道具
  330. /// </summary>
  331. public void Use()
  332. {
  333. if (Master == null || IsUsing)
  334. {
  335. return;
  336. }
  337. if (CheckUse()) //可以使用道具
  338. {
  339. OnUse();
  340. if (Attribute.IsConsumables)
  341. {
  342. Count -= 1;
  343. }
  344.  
  345. if (Attribute.Duration > 0) //持续时间
  346. {
  347. _durationTimer = Attribute.Duration;
  348. }
  349. else
  350. {
  351. //冷却计时器
  352. _cooldownTimer = Attribute.CooldownTime;
  353. UsingFinish();
  354. }
  355. }
  356. }
  357.  
  358. /// <summary>
  359. /// 获取冷却进度 0 - 1
  360. /// </summary>
  361. public float GetCooldownProgress()
  362. {
  363. if (_cooldownTimer <= 0)
  364. {
  365. return 1;
  366. }
  367.  
  368. return (Attribute.CooldownTime - _cooldownTimer) / Attribute.CooldownTime;
  369. }
  370.  
  371. public override void Interactive(ActivityObject master)
  372. {
  373. if (master is Player player)
  374. {
  375. if (player.ActivePropsPack.Capacity == 0)
  376. {
  377. //容量为0
  378. return;
  379. }
  380. var item = player.ActivePropsPack.GetItemById(ActivityBase.Id);
  381. if (item == null) //没有同类型物体
  382. {
  383. if (!player.ActivePropsPack.HasVacancy()) //没有空位置, 扔掉当前道具
  384. {
  385. player.ThrowActiveProp(player.ActivePropsPack.ActiveIndex);
  386. }
  387. //替换手中的道具
  388. if (player.PickUpActiveProp(this))
  389. {
  390. Pickup();
  391. }
  392. }
  393. else
  394. {
  395. //处理同类型道具
  396. if (item.Count < item.MaxCount) //允许叠加
  397. {
  398. if (item.Count + Count > item.MaxCount)
  399. {
  400. Count -= item.MaxCount - item.Count;
  401. item.Count = item.MaxCount;
  402. }
  403. else
  404. {
  405. item.Count += Count;
  406. Count = 0;
  407. }
  408. Destroy();
  409. }
  410. }
  411. }
  412. }
  413.  
  414. public override CheckInteractiveResult CheckInteractive(ActivityObject master)
  415. {
  416. if (master is Player player)
  417. {
  418. if (player.ActivePropsPack.Capacity == 0)
  419. {
  420. //容量为0
  421. return new CheckInteractiveResult(this);
  422. }
  423. //查找相同类型的道具
  424. var item = player.ActivePropsPack.GetItemById(ActivityBase.Id);
  425. if (item == null) //没有同类型物体
  426. {
  427. if (player.ActivePropsPack.HasVacancy()) //还有空位, 拾起道具
  428. {
  429. return new CheckInteractiveResult(this, true, CheckInteractiveResult.InteractiveType.PickUp);
  430. }
  431.  
  432. //替换手中的道具
  433. return new CheckInteractiveResult(this, true, CheckInteractiveResult.InteractiveType.Replace);
  434. }
  435.  
  436. //处理同类型道具
  437. if (item.Count < item.MaxCount) //允许叠加
  438. {
  439. return new CheckInteractiveResult(this, true, CheckInteractiveResult.InteractiveType.Bullet);
  440. }
  441.  
  442. //该道具不能拾起
  443. return new CheckInteractiveResult(this);
  444. }
  445.  
  446. return new CheckInteractiveResult(this);
  447. }
  448.  
  449. public override void OnPickUpItem()
  450. {
  451. foreach (var buffFragment in _buffFragment)
  452. {
  453. buffFragment.OnPickUpItem();
  454. }
  455.  
  456. foreach (var conditionFragment in _conditionFragment)
  457. {
  458. conditionFragment.OnPickUpItem();
  459. }
  460. foreach (var effectFragment in _effectFragment)
  461. {
  462. effectFragment.OnPickUpItem();
  463. }
  464. foreach (var chargeFragment in _chargeFragment)
  465. {
  466. chargeFragment.OnPickUpItem();
  467. }
  468. }
  469.  
  470. public override void OnRemoveItem()
  471. {
  472. foreach (var buffFragment in _buffFragment)
  473. {
  474. buffFragment.OnRemoveItem();
  475. }
  476.  
  477. foreach (var conditionFragment in _conditionFragment)
  478. {
  479. conditionFragment.OnRemoveItem();
  480. }
  481. foreach (var effectFragment in _effectFragment)
  482. {
  483. effectFragment.OnRemoveItem();
  484. }
  485. foreach (var chargeFragment in _chargeFragment)
  486. {
  487. chargeFragment.OnRemoveItem();
  488. }
  489. }
  490.  
  491. public virtual void OnActiveItem()
  492. {
  493. }
  494.  
  495. public virtual void OnConcealItem()
  496. {
  497. }
  498.  
  499. public virtual void OnOverflowItem()
  500. {
  501. Master.ThrowActiveProp(PackageIndex);
  502. }
  503. /// <summary>
  504. /// 添加被动属性
  505. /// </summary>
  506. public void AddBuffFragment<T>(JsonElement[] arg) where T : BuffFragment, new()
  507. {
  508. var fragment = AddComponent<T>();
  509. _buffFragment.Add(fragment);
  510. try
  511. {
  512. fragment.InitParam(arg);
  513. }
  514. catch (Exception e)
  515. {
  516. Debug.LogError($"初始化道具'{ActivityBase.Id}'参数时发生异常: {e.Message}\n{e.StackTrace}");
  517. }
  518. if (Master != null)
  519. {
  520. fragment.OnPickUpItem();
  521. }
  522. }
  523.  
  524. //持续时间完成
  525. private void UsingFinish()
  526. {
  527. OnUsingFinish();
  528. foreach (var effectFragment in _effectFragment)
  529. {
  530. effectFragment.OnUsingFinish();
  531. }
  532. foreach (var chargeFragment in _chargeFragment)
  533. {
  534. chargeFragment.OnUsingFinish();
  535. }
  536. }
  537. private static bool _init = false;
  538. private static Dictionary<string, ExcelConfig.ActivePropBase> _activeAttributeMap =
  539. new Dictionary<string, ExcelConfig.ActivePropBase>();
  540.  
  541. /// <summary>
  542. /// 初始化主动道具属性数据
  543. /// </summary>
  544. public static void InitActiveAttribute()
  545. {
  546. if (_init)
  547. {
  548. return;
  549. }
  550.  
  551. _init = true;
  552. foreach (var buffAttr in ExcelConfig.ActivePropBase_List)
  553. {
  554. if (buffAttr.Activity != null)
  555. {
  556. if (!_activeAttributeMap.TryAdd(buffAttr.Activity.Id, buffAttr))
  557. {
  558. Debug.LogError("发现重复注册的主动道具属性: " + buffAttr.Id);
  559. }
  560. }
  561. }
  562. }
  563. /// <summary>
  564. /// 根据 ActivityBase.Id 获取对应主动道具的属性数据
  565. /// </summary>
  566. public static ExcelConfig.ActivePropBase GetActiveAttribute(string itemId)
  567. {
  568. if (itemId == null)
  569. {
  570. return null;
  571. }
  572. if (_activeAttributeMap.TryGetValue(itemId, out var attr))
  573. {
  574. return attr;
  575. }
  576.  
  577. throw new Exception($"主动道具'{itemId}'没有在 ActivePropBase 表中配置属性数据!");
  578. }
  579. }