ShieldBuff.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. using XGame.Database;
  4. using XGame.Framework;
  5. using XGame.Framework.Interfaces;
  6. using XGame.Framework.Time;
  7. namespace FL.Battle.Buffs
  8. {
  9. /// <summary>
  10. /// 护盾类buff
  11. /// </summary>
  12. public class ShieldBuff : Buff
  13. {
  14. private class ShieldDto : IReference
  15. {
  16. /// <summary>
  17. /// 吸收值
  18. /// </summary>
  19. public int absorption;
  20. public ITimer timer;
  21. void IReference.Clear()
  22. {
  23. absorption = 0;
  24. timer?.Cancel();
  25. timer = null;
  26. }
  27. }
  28. public override int LayerLimit => 1;
  29. private List<ShieldDto> _shields = new();
  30. private long _absorption;
  31. /// <summary>
  32. /// 剩余吸收值
  33. /// </summary>
  34. public long Absorption => _absorption;
  35. public override bool IsShowIcon => false;
  36. /// <summary>
  37. /// 增加吸收值
  38. /// </summary>
  39. /// <param name="absorption"></param>
  40. public void Add(int absorption)
  41. {
  42. var rate = Table.BuffTypeNum[0].ToRealFloat();
  43. absorption = Mathf.RoundToInt(Mathf.Abs(absorption) * rate);
  44. _absorption += absorption;
  45. var dto = ObjectPool.Acquire<ShieldDto>();
  46. _shields.Add(dto);
  47. dto.absorption = absorption;
  48. dto.timer = Context.Time.AddDelayTimer(Duration, () =>
  49. {
  50. //单个护盾时间到了, 减掉护盾剩余的吸收值
  51. _absorption -= dto.absorption;
  52. //移除
  53. _shields.Remove(dto);
  54. Listener?.OnShieldChanged(-dto.absorption);
  55. //回收
  56. ObjectPool.Recycle(dto);
  57. XGame.Log.Debug($"护盾{EntityId} 到时结束, 吸收值:{dto.absorption} 总吸收值:{_absorption}");
  58. });
  59. Listener?.OnShieldChanged(absorption);
  60. XGame.Log.Debug($"护盾{EntityId} 增加吸收值:{absorption} 总吸收值:{_absorption}");
  61. }
  62. /// <summary>
  63. /// 护盾吸收
  64. /// </summary>
  65. /// <param name="damage"></param>
  66. /// <returns>护盾吸收后剩余的伤害值 负数</returns>
  67. public int Reduce(int damage)
  68. {
  69. var remain = Mathf.Abs(damage);
  70. if (remain >= _absorption)
  71. { // 伤害值大于等于剩余吸收值
  72. remain = (int)(_absorption - remain);
  73. XGame.Log.Debug($"护盾{EntityId} 伤害破盾, 吸收:{_absorption} 伤害剩余:{remain}");
  74. // 没有吸收值了,护盾结束
  75. Listener?.OnCompleted(TableId);
  76. return remain;
  77. }
  78. var last = _absorption;
  79. for (var i = 0; i < _shields.Count;)
  80. {
  81. var dto = _shields[i];
  82. if (dto.absorption > remain)
  83. {
  84. dto.absorption -= remain;
  85. _absorption -= remain;
  86. break;
  87. }
  88. remain -= dto.absorption;
  89. _absorption -= dto.absorption;
  90. _shields.RemoveAt(i);
  91. ObjectPool.Recycle(dto);
  92. }
  93. Listener?.OnShieldChanged(_absorption - last);
  94. XGame.Log.Debug($"护盾{EntityId} 吸收了伤害:{damage} 护盾剩余:{_absorption} 吸收前:{last}");
  95. return 0;
  96. }
  97. protected override void OnInited()
  98. {
  99. _absorption = 0;
  100. }
  101. protected override void OnDispose()
  102. {
  103. _absorption = 0;
  104. foreach (var shield in _shields)
  105. {
  106. ObjectPool.Recycle(shield);
  107. }
  108. _shields.Clear();
  109. }
  110. }
  111. }