using System.Collections.Generic; using cfg.BuffCfg; using Framework; using Gameplay.Area; using Gameplay.Unit; namespace Gameplay.Buff { public class UnitBuffManager { public readonly GameUnit owner; public readonly List totalBuffList; private readonly Dictionary _groupMap; private readonly List _needRemoveList; public List avoidBuffIds; public UnitBuffManager(GameUnit owner) { this.owner = owner; totalBuffList = new List(); _groupMap = new Dictionary(); _needRemoveList = new List(); avoidBuffIds = new List(); } public bool HasBuffGroup(int groupId) { return _groupMap.ContainsKey(groupId); } public void AddBuffByIds(List 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 buffIds) { for (var i = 0; i < buffIds.Count; ++i) { var buffId = buffIds[i]; RemoveBuffById(buffId); } } 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 GetBuffsByType(EBuffType buffType) { var findList = new List(); 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) { var isInList = totalBuffList.Contains(buff); if (!isInList) { return; } AddNeedRemoveBuff(buff); } public void RemoveBuffById(int buffId) { var findBuff = totalBuffList.Find(buff => buff.configData.ID == buffId); if (findBuff == null) { return; } AddNeedRemoveBuff(findBuff); } 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) { // owner.Log("增加buff:" + buff); buff.owner = owner; // 这里会调用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() { if (_needRemoveList.Count > 0) { for (var i = 0; i < _needRemoveList.Count; ++i) { var buff = _needRemoveList[i]; _RemoveBuff(buff); } _needRemoveList.Clear(); } } public void LogicUpdate(float dt) { for (var i = 0; i < totalBuffList.Count; ++i) { if (i >= totalBuffList.Count) break; // 防止在循环中删除buff导致越界 var buff = totalBuffList[i]; if (buff.needRemove) { _RemoveBuff(buff); i--; continue; } buff.LogicUpdate(dt); if (buff.needRemove) { _RemoveBuff(buff); i--; } } if (_needRemoveList.Count > 0) { for (var i = 0; i < _needRemoveList.Count; ++i) { var buff = _needRemoveList[i]; _RemoveBuff(buff); } _needRemoveList.Clear(); } } public void TriggerReload() { _InnerTrigger(ETriggerType.ON_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); } } } }