NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/Buff/UnitBuffManager.cs

570 lines
18 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System.Collections.Generic;
using cfg.BuffCfg;
using Framework;
using Gameplay.Area;
using Gameplay.Unit;
namespace Gameplay.Buff
{
public class UnitBuffManager
{
private const int EXPECTED_MAX_BUFFS = 10; // 预期每个单位最多携带的buff数量
private const int EXPECTED_MAX_GROUPS = 5; // 预期每个单位最多的buff分组数量
public readonly GameUnit owner;
public readonly List<BaseBuff> totalBuffList;
private readonly Dictionary<int, BaseBuff> _groupMap;
private readonly List<BaseBuff> _needRemoveList;
public List<int> avoidBuffIds;
/// <summary>
/// 伤害转移buff
/// </summary>
public BuffDamageRedirect damageRedirectBuff
{
get;
set;
}
public UnitBuffManager(GameUnit owner)
{
this.owner = owner;
totalBuffList = new List<BaseBuff>(EXPECTED_MAX_BUFFS);
_groupMap = new Dictionary<int, BaseBuff>(EXPECTED_MAX_GROUPS);
_needRemoveList = new List<BaseBuff>(EXPECTED_MAX_BUFFS);
avoidBuffIds = new List<int>(EXPECTED_MAX_BUFFS);
}
public bool HasBuffGroup(int groupId)
{
return _groupMap.ContainsKey(groupId);
}
public void AddBuffByIds(List<int> buffIds)
{
for (var i = 0; i < buffIds.Count; ++i)
{
var buffId = buffIds[i];
AddBuffById(buffId);
}
}
public void AddBuffById(int buffId)
{
var addBuff = BuffManager.instance.CreateBuffById(owner, buffId);
AddBuff(addBuff);
}
public void AddBuffById(int buffId, GameUnit creator)
{
var addBuff = BuffManager.instance.CreateBuffById(creator, buffId);
AddBuff(addBuff);
}
public void RemoveBuffByIds(List<int> buffIds, bool imdRemove = false)
{
for (var i = 0; i < buffIds.Count; ++i)
{
var buffId = buffIds[i];
RemoveBuffById(buffId, imdRemove);
}
}
public bool CheckHasBuffId(int buffId)
{
for (int i = 0; i < totalBuffList.Count; i++)
{
var buff = totalBuffList[i];
if (buff.configData.ID == buffId)
{
return true;
}
}
return false;
}
public bool CheckHasBuffType(EBuffType buffType)
{
for (var i = 0; i < totalBuffList.Count; ++i)
{
var buff = totalBuffList[i];
if (buff.configData.BuffType == buffType)
{
return true;
}
}
return false;
}
public bool CheckHasBuffTypeExcept(EBuffType buffType, BaseBuff exceptBuff)
{
for (var i = 0; i < totalBuffList.Count; ++i)
{
var buff = totalBuffList[i];
if (buff == exceptBuff)
{
continue;
}
if (buff.configData.BuffType == buffType)
{
return true;
}
}
return false;
}
public List<BaseBuff> GetBuffsByType(EBuffType buffType)
{
var findList = new List<BaseBuff>();
for (var i = 0; i < totalBuffList.Count; ++i)
{
var buff = totalBuffList[i];
if (buff.configData.BuffType == buffType)
{
findList.Add(buff);
}
}
return findList;
}
public BaseBuff GetBuffByType(EBuffType buffType)
{
for (var i = 0; i < totalBuffList.Count; ++i)
{
var buff = totalBuffList[i];
if (buff.configData.BuffType == buffType)
{
return buff;
}
}
return null;
}
public void RemoveBuff(BaseBuff buff, bool imdRemove = false)
{
var isInList = totalBuffList.Contains(buff);
if (!isInList)
{
return;
}
AddNeedRemoveBuff(buff, imdRemove);
}
public void RemoveBuffById(int buffId, bool imdRemove = false)
{
var findBuff = totalBuffList.Find(buff => buff.configData.ID == buffId);
if (findBuff == null)
{
return;
}
AddNeedRemoveBuff(findBuff, imdRemove);
}
public void AddBuff(BaseBuff buff)
{
if (buff == null)
{
DebugUtil.LogError("buff为空");
return;
}
if (avoidBuffIds.Contains(buff.configData.ID))
{
// 需要把buff返回池
BuffManager.ReturnBuff(buff);
return;
}
if (buff.configData.BuffEffectType == EBuffEffectType.NegativeBuff)
{
// 负面buff
var randomValue = UnityEngine.Random.Range(0, 1f);
var ignoreRate = owner.fightData.ignoreDebuffRate;
if (randomValue < ignoreRate)
{
// 免疫
DebugUtil.Log("触发免疫debuff");
// 需要把buff返回池
BuffManager.ReturnBuff(buff);
return;
}
}
if (!buff.configData.CanTriggerOnDead && owner.statusData.isDead)
{
// 不可添加
// 需要把buff返回池
BuffManager.ReturnBuff(buff);
return;
}
var repeatType = buff.configData.RepeatType;
var noAdd = false;
switch (repeatType)
{
case EBuffRepeatType.None:
// 不做处理
break;
case EBuffRepeatType.Replace:
{
// 找到旧的,全部删除
if (_groupMap.TryGetValue(buff.configData.GroupId, out var oldBuff))
{
// 判断强度
if (oldBuff.configData.Level == buff.configData.Level)
{
noAdd = true;
// 刷新持续时间
oldBuff.RefreshDuring();
}
else if (oldBuff.configData.Level > buff.configData.Level)
{
// 新的buff强度不够,不添加
noAdd = true;
}
else
{
AddNeedRemoveBuff(oldBuff, true);
}
}
}
break;
case EBuffRepeatType.RefreshTime:
{
// 找到旧的,刷新持续时间
if (_groupMap.TryGetValue(buff.configData.GroupId, out var oldBuff))
{
oldBuff.RefreshDuring();
noAdd = true;
}
}
break;
case EBuffRepeatType.Merge:
{
if (_groupMap.TryGetValue(buff.configData.GroupId, out var oldBuff))
{
AddNeedRemoveBuff(oldBuff);
var combineLevel = oldBuff.configData.Level + buff.configData.Level;
var searchBuffConfig = GroupBuffManager.instance.SearchBuff(buff.configData.GroupId, combineLevel);
if (searchBuffConfig == null)
{
DebugUtil.LogError("合并buff失败找不到对应的buff配置");
noAdd = true;
}
else
{
// 替换新的buff
var newBuff = BuffManager.instance.CreateBuffByConfig(owner, searchBuffConfig);
// 需要把buff返回池
BuffManager.ReturnBuff(buff);
buff = newBuff;
}
}
}
break;
default:
DebugUtil.LogError("暂未处理的repeatType:{0}", repeatType);
break;
}
if (noAdd)
{
// 需要把buff返回池
BuffManager.ReturnBuff(buff);
}
else
{
_AddBuff(buff);
}
}
public void TriggerOnAddDebuff()
{
_DebuffCountChanged();
}
public void TriggerOnRemoveDebuff()
{
_DebuffCountChanged();
}
private void _DebuffCountChanged()
{
var getBuff = GetBuffByType(EBuffType.DownScaleOnDebuff);
if (getBuff == null) return;
var buff = getBuff as BuffSetBeHitScaleOnDebuffChange;
if (buff == null)
{
DebugUtil.LogError("BuffSetBeHitScaleOnDebuffChange类型错误");
return;
}
var nowDebuffCount = GetDebuffCount();
var oldDebuffCount = buff.oldDebuffCount;
var oldChangeValue = buff.GetBeHitScale(oldDebuffCount);
owner.fightData.beDamageScale -= oldChangeValue;
var newChangeValue = buff.GetBeHitScale(nowDebuffCount);
owner.fightData.beDamageScale += newChangeValue;
buff.oldDebuffCount = nowDebuffCount;
}
public bool CheckHasAnyDebuff()
{
for (var i = 0; i < totalBuffList.Count; ++i)
{
var buff = totalBuffList[i];
if (buff.configData.BuffEffectType == EBuffEffectType.NegativeBuff)
{
return true;
}
}
return false;
}
public int GetDebuffCount()
{
var count = 0;
for (int i = 0; i < totalBuffList.Count; i++)
{
var buff = totalBuffList[i];
if (buff.configData.BuffEffectType == EBuffEffectType.NegativeBuff)
{
count++;
}
}
return count;
}
private void _AddBuff(BaseBuff buff)
{
buff.owner = owner;
// 优化:提前检查容量
if (totalBuffList.Count == totalBuffList.Capacity)
{
totalBuffList.Capacity *= 2;
}
// 这里会调用buff的OnInit方法
buff.Init();
buff.TriggerAdd();
totalBuffList.Add(buff);
if (buff.configData.GroupId != 0)
{
_groupMap[buff.configData.GroupId] = buff;
}
if (buff.configData.BuffEffectType == EBuffEffectType.NegativeBuff)
{
// 负面buff
owner.buffManager.TriggerOnAddDebuff();
}
}
private void _RemoveBuff(BaseBuff buff)
{
var index = totalBuffList.IndexOf(buff);
if (index < 0)
{
return;
}
buff.TriggerRemove();
totalBuffList.RemoveAt(index);
if (buff.configData.BuffEffectType == EBuffEffectType.NegativeBuff)
{
// 负面buff
owner.buffManager.TriggerOnRemoveDebuff();
}
BuffManager.ReturnBuff(buff);
if (buff.configData.GroupId != 0)
{
if (_groupMap.TryGetValue(buff.configData.GroupId, out var oldBuff) && oldBuff == buff)
{
// 移除
_groupMap.Remove(buff.configData.GroupId);
}
}
}
public void AddNeedRemoveBuff(BaseBuff buff, bool imdRemove = false)
{
if (imdRemove)
{
_RemoveBuff(buff);
return;
}
if (_needRemoveList.Contains(buff))
{
return;
}
_needRemoveList.Add(buff);
}
public void UpdateOnlyRemoveAdd()
{
var count = _needRemoveList.Count;
if (count > 0)
{
for (var i = 0; i < count; ++i)
{
var buff = _needRemoveList[i];
_RemoveBuff(buff);
}
_needRemoveList.Clear();
}
}
public void LogicUpdate(float dt)
{
var buffCount = totalBuffList.Count;
// 从后向前遍历,这样删除元素时不会影响到未处理的元素的索引
for (var i = buffCount - 1; i >= 0; i--)
{
if (i >= totalBuffList.Count) continue; // 安全检查
var buff = totalBuffList[i];
if (buff.needRemove)
{
_RemoveBuff(buff);
continue;
}
buff.LogicUpdate(dt);
if (buff.needRemove)
{
_RemoveBuff(buff);
}
}
// 处理待移除列表
var removeCount = _needRemoveList.Count;
if (removeCount > 0)
{
for (var i = 0; i < removeCount; ++i)
{
var buff = _needRemoveList[i];
_RemoveBuff(buff);
}
_needRemoveList.Clear();
}
}
public void TriggerPreReload()
{
_InnerTrigger(ETriggerType.ON_RELOAD);
}
public void TriggerAfterReload()
{
_InnerTrigger(ETriggerType.ON_AFTER_RELOAD);
}
public void TriggerNormalAttack()
{
_InnerTrigger(ETriggerType.ON_NORMAL_ATTACK);
}
public void TriggerEnterBattle()
{
_InnerTrigger(ETriggerType.ON_ENTER_BATTLE);
}
public void TriggerExitBattle()
{
_InnerTrigger(ETriggerType.ON_EXIT_BATTLE);
}
public void TriggerKillUnit(GameUnit unit)
{
_InnerTrigger(ETriggerType.ON_KILL_UNIT);
if (owner.debugShowInfo.cacheConfigId != 0)
{
EventManager.Instance.Send(EventManager.EventName.INFIGHT_AUDIO_KILL_ENEMY, owner.debugShowInfo.cacheConfigId);
}
if (unit.debugShowInfo.cacheConfigId != 0)
{
EventManager.Instance.Send(EventManager.EventName.INFIGHT_AUDIO_BE_ATTACK_AND_DEAD, unit.debugShowInfo.cacheConfigId);
}
}
public void TriggerCellIndexChange()
{
_InnerTrigger(ETriggerType.ON_CELLINDEX_CHANGE);
// 触发buff的特殊事件
for (int i = 0; i < totalBuffList.Count; i++)
{
var buff = totalBuffList[i];
if (buff.needRemove) continue;
buff.TriggerCellIndexChange();
}
}
public void TriggerFriendRetreat(GameUnit friendUnit)
{
var getBuff = GetBuffByType(EBuffType.AddOnFriendRetreat);
if (getBuff == null) return;
var buff = getBuff as BuffAddBuffOnFriendRetreat;
if (buff == null)
{
DebugUtil.LogError("BuffAddBuffOnFriendRetreat类型错误");
return;
}
var checkRange = buff.checkRange;
var distance = AreaManager.instance.GetDistance(friendUnit.transData.cellIndex, owner.transData.cellIndex);
if (distance <= checkRange)
{
AddBuffByIds(buff.buffIds);
}
}
public void TriggerOnRetreat()
{
_InnerTrigger(ETriggerType.ON_RETREAT);
// 触发buff的特殊事件
var allUnits = GameUnitManager.instance.infightUnits.unitList;
for (int i = 0; i < allUnits.Count; i++)
{
var unit = allUnits[i];
if (unit == owner) continue;
if (unit.commonData.troopId == owner.commonData.troopId)
{
unit.buffManager.TriggerFriendRetreat(owner);
}
}
}
public void TriggerOnTakeDamage()
{
_InnerTrigger(ETriggerType.ON_TAKEDAMAGE);
// 触发buff的特殊事件
for (int i = 0; i < totalBuffList.Count; i++)
{
var buff = totalBuffList[i];
if (buff.needRemove) continue;
buff.TriggerOnTakeDamage();
}
}
private void _InnerTrigger(ETriggerType triggerType)
{
for (int i = 0; i < totalBuffList.Count; i++)
{
var buff = totalBuffList[i];
if (buff.needRemove) continue;
buff.SpecialTrigger(triggerType);
}
}
}
}