using System.Collections.Generic; using UnityEngine; using XGame.Database; using XGame.Framework; using XGame.Framework.Interfaces; using XGame.Framework.Time; namespace FL.Battle.Buffs { /// /// 护盾类buff /// public class ShieldBuff : Buff { private class ShieldDto : IReference { /// /// 吸收值 /// public int absorption; public ITimer timer; void IReference.Clear() { absorption = 0; timer?.Cancel(); timer = null; } } public override int LayerLimit => 1; private List _shields = new(); private long _absorption; /// /// 剩余吸收值 /// public long Absorption => _absorption; public override bool IsShowIcon => false; /// /// 增加吸收值 /// /// public void Add(int absorption) { var rate = Table.BuffTypeNum[0].ToRealFloat(); absorption = Mathf.RoundToInt(Mathf.Abs(absorption) * rate); _absorption += absorption; var dto = ObjectPool.Acquire(); _shields.Add(dto); dto.absorption = absorption; dto.timer = Context.Time.AddDelayTimer(Duration, () => { //单个护盾时间到了, 减掉护盾剩余的吸收值 _absorption -= dto.absorption; //移除 _shields.Remove(dto); Listener?.OnShieldChanged(-dto.absorption); //回收 ObjectPool.Recycle(dto); XGame.Log.Debug($"护盾{EntityId} 到时结束, 吸收值:{dto.absorption} 总吸收值:{_absorption}"); }); Listener?.OnShieldChanged(absorption); XGame.Log.Debug($"护盾{EntityId} 增加吸收值:{absorption} 总吸收值:{_absorption}"); } /// /// 护盾吸收 /// /// /// 护盾吸收后剩余的伤害值 负数 public int Reduce(int damage) { var remain = Mathf.Abs(damage); if (remain >= _absorption) { // 伤害值大于等于剩余吸收值 remain = (int)(_absorption - remain); XGame.Log.Debug($"护盾{EntityId} 伤害破盾, 吸收:{_absorption} 伤害剩余:{remain}"); // 没有吸收值了,护盾结束 Listener?.OnCompleted(TableId); return remain; } var last = _absorption; for (var i = 0; i < _shields.Count;) { var dto = _shields[i]; if (dto.absorption > remain) { dto.absorption -= remain; _absorption -= remain; break; } remain -= dto.absorption; _absorption -= dto.absorption; _shields.RemoveAt(i); ObjectPool.Recycle(dto); } Listener?.OnShieldChanged(_absorption - last); XGame.Log.Debug($"护盾{EntityId} 吸收了伤害:{damage} 护盾剩余:{_absorption} 吸收前:{last}"); return 0; } protected override void OnInited() { _absorption = 0; } protected override void OnDispose() { _absorption = 0; foreach (var shield in _shields) { ObjectPool.Recycle(shield); } _shields.Clear(); } } }