using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using LitJson;
|
using Spine.Unity;
|
using UnityEngine;
|
|
public class BattleObjectBuffMgr
|
{
|
|
public Action onBuffChanged;
|
|
public Action<int, bool> onIsControlChanged;
|
|
private Dictionary<int/*EffectId*/, KeyValuePair<BattleEffectPlayer, HashSet<uint/*BuffID*/>>> buffEffectDict = new Dictionary<int, KeyValuePair<BattleEffectPlayer, HashSet<uint>>>();
|
|
private Dictionary<uint, HB428_tagSCBuffRefresh> buffDataDict = new Dictionary<uint, HB428_tagSCBuffRefresh>();
|
|
private BattleObject battleObject;
|
|
public Dictionary<int, bool> isControled = new Dictionary<int, bool>()
|
{
|
{ 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<int> removeEffectList = new List<int>();
|
// 跟随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<BattleEffectPlayer, HashSet<uint>> 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<HB429_tagSCBuffDel>() { 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<BattleEffectPlayer, HashSet<uint>> 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<HB428_tagSCBuffRefresh> { 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<HB428_tagSCBuffRefresh> 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<uint> { buffRefresh.BuffID };
|
buffEffectDict.Add(
|
skillConfig.BuffEffect,
|
new KeyValuePair<BattleEffectPlayer, HashSet<uint>>(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<int> 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<HB428_tagSCBuffRefresh> GetBuffList()
|
{
|
return buffDataDict.Values.ToList();
|
}
|
|
public void InsertBuff(HB428_tagSCBuffRefresh vNetData)
|
{
|
RefreshBuff(vNetData, true);
|
}
|
}
|