using System; using System.Collections.Generic; using System.Linq; using LitJson; using Spine.Unity; using UnityEngine; public class BattleObjectBuffMgr { public Action onBuffChanged; public Action onIsControlChanged; private Dictionary>> buffEffectDict = new Dictionary>>(); private Dictionary buffDataDict = new Dictionary(); private BattleObject battleObject; public Dictionary isControled = new Dictionary() { { BattleConst.HardControlGroup, false }, { BattleConst.SoftControlGroup, false }, { BattleConst.NormalAttackLimitGroup, false }, { BattleConst.RageAttackLimitGroup, false }, { BattleConst.PassiveSkillLimitGroup, false }, }; public void Init(BattleObject _battleObject) { battleObject = _battleObject; } public void Release() { onBuffChanged = null; RemoveAllBuff(); } public void Run() { List removeEffectList = new List(); // 跟随BattleObject foreach (var kv in buffEffectDict) { BattleEffectPlayer effectPlayer = kv.Value.Key; if (null != effectPlayer) { if (effectPlayer.isBindBone) { effectPlayer.FollowBoneXY(); return; } int[] effectPos = effectPlayer.effectConfig.effectPos; effectPlayer.transform.position = battleObject.heroRectTrans.position; if (null != effectPos && effectPos.Length >= 2) { effectPlayer.rectTrans.anchoredPosition += new Vector2(effectPos[0], effectPos[1]); } } else { removeEffectList.Add(kv.Key); } } foreach (var effectId in removeEffectList) { buffEffectDict.Remove(effectId); } } public void RemoveAllBuff() { foreach (var kv in buffEffectDict) { KeyValuePair> pair = kv.Value; battleObject.battleField.battleEffectMgr.RemoveEffect(kv.Key, pair.Key); } buffEffectDict.Clear(); buffDataDict.Clear(); OnBuffChanged(); } // 删除buff public void RemoveBuff(HB429_tagSCBuffDel vNetData) { var tempvNetData = vNetData; BuffUnmountAction buffRemoveAction = new BuffUnmountAction(battleObject.battleField, new List() { vNetData }, () => { HB428_tagSCBuffRefresh buffData = null; bool isRemove = false; if (buffDataDict.TryGetValue(tempvNetData.BuffID, out buffData)) { isRemove = true; buffDataDict.Remove(tempvNetData.BuffID); } if (!isRemove) { return; } bool isRemoveEffect = false; int remainCnt = -1; if (buffData != null) { SkillConfig skillConfig = SkillConfig.Get((int)buffData.SkillID); if (null == skillConfig || skillConfig.BuffEffect <= 0) { return; } KeyValuePair> effectPair; if (buffEffectDict.TryGetValue(skillConfig.BuffEffect, out effectPair)) { effectPair.Value.Remove(buffData.BuffID); remainCnt = effectPair.Value.Count; if (effectPair.Value.Count == 0) { // 没有这个buff了 isRemoveEffect = true; battleObject.battleField.battleEffectMgr.RemoveEffect(skillConfig.BuffEffect, effectPair.Key); buffEffectDict.Remove(skillConfig.BuffEffect); } } if (FuncConfigConfig.buffGroupStateDict[BattleConst.HardControlGroup.ToString()].Contains(skillConfig.BuffState)) { BattleDebug.LogError("[BattleObjectBuffMgr]移除对象 " + battleObject.ObjID + " 的buff id " + tempvNetData.BuffID + " BuffState is " + skillConfig.BuffState + " 是否删除了字典内的内容 " + isRemove.ToString() + " 是否删除了特效 " + isRemoveEffect.ToString() + " pack uid 是 " + vNetData.packUID); } } // 不做表现 OnBuffChanged(); }); battleObject.battleField.recordPlayer.PlayRecord(buffRemoveAction); } // 刷新buff public void RefreshBuff(HB428_tagSCBuffRefresh vNetData, bool insert = false) { if (vNetData == null) return; if (battleObject.IsDead()) { Debug.LogError("给死亡对象刷新buff 检查服务器代码"); RemoveAllBuff(); return; } // IsAdd != 0 表示是添加/覆盖,需要播放动画 if (vNetData.IsAdd != 0) { var tempvNetData = vNetData; BuffMountAction buffMountAction = new BuffMountAction( battleObject.battleField, new List { vNetData }, () => { ApplyBuffAddition(tempvNetData); OnBuffChanged(); }); if (insert) battleObject.battleField.recordPlayer.ImmediatelyPlay(buffMountAction); else battleObject.battleField.recordPlayer.PlayRecord(buffMountAction); } else { // IsAdd == 0 只是数据刷新,直接更新数据不播放动画 if (buffDataDict.ContainsKey(vNetData.BuffID)) { buffDataDict[vNetData.BuffID] = vNetData; OnBuffChanged(); } } } public void RefreshBuff(List vNetDataList, bool insert = false) { if (vNetDataList == null || vNetDataList.Count == 0) return; if (battleObject.IsDead()) { Debug.LogError("给死亡对象刷新buff(批量) 检查服务器代码"); RemoveAllBuff(); return; } var buffList = vNetDataList.Where(buff => buff != null && buff.IsAdd != 0).ToList(); var refreshList = vNetDataList.Where(buff => buff != null && buff.IsAdd == 0).ToList(); // 处理需要播放动画的buff (IsAdd != 0) if (buffList.Count > 0) { BuffMountAction buffMountAction = new BuffMountAction( battleObject.battleField, buffList, () => { foreach (var temp in buffList) ApplyBuffAddition(temp); OnBuffChanged(); }); if (insert) battleObject.battleField.recordPlayer.ImmediatelyPlay(buffMountAction); else battleObject.battleField.recordPlayer.PlayRecord(buffMountAction); } // 处理只刷新数据的buff (IsAdd == 0) if (refreshList.Count > 0) { bool hasChanged = false; foreach (var buff in refreshList) { if (buffDataDict.ContainsKey(buff.BuffID)) { buffDataDict[buff.BuffID] = buff; hasChanged = true; } } if (hasChanged) { OnBuffChanged(); } } } private void ApplyBuffAddition(HB428_tagSCBuffRefresh buffRefresh) { SkillConfig skillConfig = SkillConfig.Get((int)buffRefresh.SkillID); if (skillConfig == null) { Debug.LogError($"buff对应的技能不存在,skillId : {buffRefresh.SkillID}"); return; } if (buffDataDict.ContainsKey(buffRefresh.BuffID)) buffDataDict[buffRefresh.BuffID] = buffRefresh; else buffDataDict.Add(buffRefresh.BuffID, buffRefresh); if (battleObject.IsDead()) return; if (skillConfig.BuffEffect > 0) { if (buffEffectDict.TryGetValue(skillConfig.BuffEffect, out var pair)) { pair.Value.Add(buffRefresh.BuffID); } else { BattleEffectPlayer effect = battleObject.battleField.battleEffectMgr .PlayEffect(battleObject, skillConfig.BuffEffect, battleObject.heroRectTrans, battleObject.Camp); effect.BindBone(battleObject.motionBase.skeletonAnim, effect.effectConfig.nodeName); var buffIdSet = new HashSet { buffRefresh.BuffID }; buffEffectDict.Add( skillConfig.BuffEffect, new KeyValuePair>(effect, buffIdSet)); } } if (FuncConfigConfig.buffGroupStateDict[BattleConst.HardControlGroup.ToString()] .Contains(skillConfig.BuffState)) { BattleDebug.LogError( $"[BattleObjectBuffMgr]添加对象 {battleObject.ObjID} 的buff id {buffRefresh.BuffID} pack uid 是 {buffRefresh.packUID} BuffState is {skillConfig.BuffState}"); } } private void OnBuffChanged() { UpdateControlState(); battleObject.heroInfoBar.RefreshBuff(buffDataDict.Values.ToList()); onBuffChanged?.Invoke(); // bool isUnderControl = false; // foreach (var kv in buffDataDict) // { // HB428_tagSCBuffRefresh hB428_TagSCBuffRefresh = kv.Value; // SkillConfig skillConfig = SkillConfig.Get((int)hB428_TagSCBuffRefresh.SkillID); // if (null != skillConfig && skillConfig.IsControlBuff()) // { // isUnderControl = true; // break; // } // } } private void UpdateControlState() { UpdateControlState(BattleConst.HardControlGroup); UpdateControlState(BattleConst.SoftControlGroup); UpdateControlState(BattleConst.NormalAttackLimitGroup); UpdateControlState(BattleConst.RageAttackLimitGroup); UpdateControlState(BattleConst.PassiveSkillLimitGroup); } private void UpdateControlState(int groupType) { bool isChange = false; bool curState = isControled[groupType]; bool newState = IsUnderControl(groupType); isControled[groupType] = newState; isChange = curState != newState; if (isChange) { onIsControlChanged?.Invoke(groupType, newState); } } private bool IsUnderControl(int groupType) { foreach (var kv in buffDataDict) { HB428_tagSCBuffRefresh hB428_TagSCBuffRefresh = kv.Value; SkillConfig skillConfig = SkillConfig.Get((int)hB428_TagSCBuffRefresh.SkillID); if (null != skillConfig) { int buffState = skillConfig.BuffState; if (FuncConfigConfig.buffGroupStateDict.TryGetValue(groupType.ToString(), out List buffGroupState)) { if (buffGroupState.Contains(buffState)) { // if (groupType == 1) // { // // Debug.LogError("对象 " + battleObject.ObjID + " 受到了 " + skillConfig.SkillID + " 的控制效果,BuffState:" + buffState + " buffGroup :" + groupType + " buff id is " + hB428_TagSCBuffRefresh.BuffID + " ralate skill id is " + hB428_TagSCBuffRefresh.RelatedSkillID + " pack uid is " + hB428_TagSCBuffRefresh.packUID); // } return true; } } } } return false; } public List GetBuffList() { return buffDataDict.Values.ToList(); } public void InsertBuff(HB428_tagSCBuffRefresh vNetData) { RefreshBuff(vNetData, true); } }