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();
}
}
}