using System;
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
using UnityEngine.Events;
|
using LitJson;
|
|
|
public class StatusMgr : SingletonMonobehaviour<StatusMgr>
|
{
|
public struct ZhongJiInfo
|
{
|
public int rate;
|
public bool onlyFirstTarget;
|
}
|
|
public static event UnityAction<int> OnGainStatus;
|
public static event UnityAction<float> OnGainCantCastSkillStatus;
|
public static event UnityAction OnReleaseCantCastSkillStatus;
|
public static event UnityAction<int> onReceiveStatus;
|
|
public Dictionary<int, ZhongJiInfo> ZhongJiDict = new Dictionary<int, ZhongJiInfo>();
|
|
private Dictionary<uint, List<Status_Base>> m_StatusDict = null;
|
private List<Status_Base> m_AllStatus = null;
|
private List<uint> m_OwnerList = null;
|
|
[HideInInspector]
|
public int bossBelongBuffID;
|
[HideInInspector]
|
public int redNameBuffID;
|
[HideInInspector]
|
public int yellowNameBuffID;
|
public int ZhongJiRate;
|
public int crossKingBuffID;
|
|
public void Init()
|
{
|
DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += OnServerPrepareOk;
|
|
if (m_StatusDict == null)
|
{
|
m_StatusDict = new Dictionary<uint, List<Status_Base>>();
|
}
|
|
if (m_OwnerList == null)
|
{
|
m_OwnerList = new List<uint>();
|
}
|
|
if (m_AllStatus == null)
|
{
|
m_AllStatus = new List<Status_Base>();
|
}
|
|
FuncConfigConfig _funcConfig = FuncConfigConfig.Get("BuffCPInterface");
|
int[] buffIDs = JsonMapper.ToObject<int[]>(_funcConfig.Numerical1);
|
|
bossBelongBuffID = buffIDs[0];
|
redNameBuffID = buffIDs[1];
|
yellowNameBuffID = buffIDs[2];
|
crossKingBuffID = buffIDs[3];
|
}
|
|
private void OnServerPrepareOk()
|
{
|
if (DTC0403_tagPlayerLoginLoadOK.neverLoginOk)
|
{
|
ReleaseActor(PlayerDatas.Instance.baseData.PlayerID);
|
ZhongJiDict.Clear();
|
}
|
}
|
|
public void AddClientBuff(uint sid, int skillId, uint srcSid, int type, int lastTime)
|
{
|
var _status = new ClientStatus();
|
_status.Init(sid, skillId, srcSid, type, lastTime);
|
|
if (!m_StatusDict.ContainsKey(sid))
|
{
|
m_StatusDict.Add(sid, new List<Status_Base>());
|
}
|
|
if (!m_StatusDict[sid].Contains(_status))
|
{
|
m_StatusDict[sid].Add(_status);
|
}
|
|
if (!m_AllStatus.Contains(_status))
|
{
|
m_AllStatus.Add(_status);
|
}
|
|
if (!m_OwnerList.Contains(sid))
|
{
|
m_OwnerList.Add(sid);
|
}
|
}
|
|
public void Request(H0605_tagObjAddBuff h0605)
|
{
|
// 修改目标状态
|
GActor _actor = GAMgr.Instance.GetBySID(h0605.ObjID);
|
if (_actor != null)
|
{
|
SkillHelper.EffectValue _effectValue;
|
if (SkillHelper.Instance.Get(h0605.SkillID).effectValue.TryGetValue(4012, out _effectValue))
|
{
|
int _count = _actor.ActorInfo.GetStatusCount((byte)_effectValue.value1, h0605.OwnerID);
|
_count += 1;
|
if (!_actor.ActorInfo.status4012.ContainsKey((byte)_effectValue.value1))
|
{
|
_actor.ActorInfo.status4012.Add((byte)_effectValue.value1, new Dictionary<uint, int>());
|
}
|
_actor.ActorInfo.status4012[(byte)_effectValue.value1][h0605.OwnerID] = _count;
|
}
|
}
|
|
if (h0605.ObjID == PlayerDatas.Instance.PlayerId)
|
{
|
AddZjInfoIfExist(h0605.SkillID);
|
}
|
|
Status_Base _status = Get(h0605.ObjID, h0605.SkillID);
|
|
if (_status == null)
|
{
|
if (IsMockingBuff(h0605.SkillID))
|
{
|
if (h0605.ObjID == PlayerDatas.Instance.PlayerId)
|
{
|
DebugEx.Log("得到了一个嘲讽buff");
|
}
|
_status = new Status_Mocking();
|
}
|
else if (bossBelongBuffID == h0605.SkillID)
|
{
|
_status = new Status_BossBelong();
|
}
|
else if (crossKingBuffID == h0605.SkillID)
|
{
|
_status = new Status_CrossKing();
|
}
|
else if (redNameBuffID == h0605.SkillID)
|
{
|
_status = new Status_RedName();
|
}
|
else if (IsInVisibleStatus(h0605.SkillID))
|
{
|
_status = new Status_InVisible();
|
}
|
else if (IsPolymorch(h0605.SkillID))
|
{
|
_status = new Status_Polymorph();
|
}
|
else
|
{
|
_status = new Status_Normal();
|
}
|
}
|
|
_status.Init(h0605.ObjID, h0605.SkillID, h0605.OwnerID, h0605.BuffType, (int)h0605.LastTime);
|
|
List<Status_Base> _list = null;
|
if (!m_StatusDict.ContainsKey(h0605.ObjID))
|
{
|
_list = new List<Status_Base>();
|
m_StatusDict.Add(h0605.ObjID, _list);
|
}
|
|
if (!m_StatusDict[h0605.ObjID].Contains(_status))
|
{
|
m_StatusDict[h0605.ObjID].Add(_status);
|
}
|
|
if (!m_AllStatus.Contains(_status))
|
{
|
m_AllStatus.Add(_status);
|
}
|
|
if (!m_OwnerList.Contains(h0605.ObjID))
|
{
|
m_OwnerList.Add(h0605.ObjID);
|
}
|
|
// 显示主英雄获取相应状态
|
if (h0605.ObjID == PlayerDatas.Instance.PlayerId)
|
{
|
if (h0605.BuffType == (int)E_BuffType.bfBuff
|
|| h0605.BuffType == (int)E_BuffType.bfProcessBuff)
|
{
|
if (OnGainStatus != null)
|
{
|
OnGainStatus(h0605.SkillID);
|
}
|
}
|
|
if (!_status.CanUseSkill())
|
{
|
if (OnGainCantCastSkillStatus != null)
|
{
|
OnGainCantCastSkillStatus(h0605.LastTime * Constants.F_DELTA);
|
}
|
}
|
}
|
|
if (onReceiveStatus != null)
|
{
|
onReceiveStatus(h0605.SkillID);
|
}
|
|
}
|
|
public bool CanCastSkill(uint sid)
|
{
|
List<Status_Base> _list = null;
|
if (m_StatusDict.TryGetValue(sid, out _list))
|
{
|
SkillHelper.SkillInfo _skillInfo = null;
|
for (int i = 0; i < _list.Count; ++i)
|
{
|
_skillInfo = SkillHelper.Instance.Get(_list[i].SkillID);
|
if (_skillInfo.config.ClientSkillSeriesLimit != 0
|
&& (_skillInfo.config.ClientSkillSeriesLimit & 2) != 0)
|
{
|
return false;
|
}
|
}
|
}
|
return true;
|
}
|
|
public void Release(uint objID, byte type)
|
{
|
List<Status_Base> _list = null;
|
|
GActor _actor = GAMgr.Instance.GetBySID(objID);
|
|
if (m_StatusDict.TryGetValue(objID, out _list))
|
{
|
for (int i = _list.Count - 1; i >= 0; --i)
|
{
|
if (_list[i].BuffType == type)
|
{
|
if (_actor != null)
|
{
|
SkillHelper.EffectValue _effectValue;
|
if (SkillHelper.Instance.Get(_list[i].SkillID).effectValue.TryGetValue(4012, out _effectValue))
|
{
|
int _count = _actor.ActorInfo.GetStatusCount((byte)_effectValue.value1, objID);
|
_count -= 1;
|
if (_count < 0)
|
{
|
_count = 0;
|
if (_actor.ActorInfo.status4012.ContainsKey((byte)_effectValue.value1))
|
{
|
if (_actor.ActorInfo.status4012[(byte)_effectValue.value1].ContainsKey(objID))
|
{
|
_actor.ActorInfo.status4012[(byte)_effectValue.value1].Remove(objID);
|
}
|
}
|
}
|
else
|
{
|
if (!_actor.ActorInfo.status4012.ContainsKey((byte)_effectValue.value1))
|
{
|
_actor.ActorInfo.status4012.Add((byte)_effectValue.value1, new Dictionary<uint, int>());
|
}
|
_actor.ActorInfo.status4012[(byte)_effectValue.value1][objID] = _count;
|
}
|
}
|
}
|
|
if (m_AllStatus.Contains(_list[i]))
|
{
|
m_AllStatus.Remove(_list[i]);
|
}
|
bool _canUseSkill = _list[i].CanUseSkill();
|
_list[i].UnInit(objID, type);
|
_list.RemoveAt(i);
|
|
if (!_canUseSkill)
|
{
|
if (OnReleaseCantCastSkillStatus != null)
|
{
|
OnReleaseCantCastSkillStatus();
|
}
|
}
|
}
|
}
|
}
|
}
|
|
public void Release(H0606_tagObjDelBuff h0606)
|
{
|
// 修改目标状态
|
GActor _actor = GAMgr.Instance.GetBySID(h0606.ObjID);
|
if (_actor != null)
|
{
|
SkillHelper.EffectValue _effectValue;
|
if (SkillHelper.Instance.Get(h0606.SkillID).effectValue.TryGetValue(4012, out _effectValue))
|
{
|
int _count = _actor.ActorInfo.GetStatusCount((byte)_effectValue.value1, h0606.ObjID);
|
_count -= 1;
|
if (_count < 0)
|
{
|
_count = 0;
|
if (_actor.ActorInfo.status4012.ContainsKey((byte)_effectValue.value1))
|
{
|
if (_actor.ActorInfo.status4012[(byte)_effectValue.value1].ContainsKey(h0606.ObjID))
|
{
|
_actor.ActorInfo.status4012[(byte)_effectValue.value1].Remove(h0606.ObjID);
|
}
|
}
|
}
|
else
|
{
|
if (!_actor.ActorInfo.status4012.ContainsKey((byte)_effectValue.value1))
|
{
|
_actor.ActorInfo.status4012.Add((byte)_effectValue.value1, new Dictionary<uint, int>());
|
}
|
_actor.ActorInfo.status4012[(byte)_effectValue.value1][h0606.ObjID] = _count;
|
}
|
}
|
}
|
|
if (h0606.ObjID == PlayerDatas.Instance.PlayerId)
|
{
|
if (ZhongJiDict.ContainsKey(h0606.SkillID))
|
{
|
ZhongJiDict.Remove(h0606.SkillID);
|
}
|
}
|
|
Status_Base _status = Get(h0606.ObjID, h0606.SkillID);
|
// var _skillInfo = SkillHelper.Instance.Get(h0606.SkillID);
|
|
if (_status == null)
|
{
|
Debug.LogWarningFormat("删除 {0} 的 buff: {1} 的时候发现这个在客户端不存在.", h0606.ObjID, h0606.SkillID);
|
return;
|
}
|
|
_status.UnInit(h0606.ObjID, h0606.BuffType);
|
|
if (m_AllStatus.Contains(_status))
|
{
|
m_AllStatus.Remove(_status);
|
}
|
|
if (m_StatusDict.ContainsKey(h0606.ObjID)
|
&& m_StatusDict[h0606.ObjID].Contains(_status))
|
{
|
m_StatusDict[h0606.ObjID].Remove(_status);
|
}
|
|
if (m_OwnerList.Contains(h0606.ObjID))
|
{
|
m_OwnerList.Remove(h0606.ObjID);
|
}
|
|
if (!_status.CanUseSkill())
|
{
|
if (_actor is GA_Hero)
|
{
|
if (OnReleaseCantCastSkillStatus != null)
|
{
|
OnReleaseCantCastSkillStatus();
|
}
|
}
|
}
|
// if (_skillInfo.effectValue.ContainsKey(2004))
|
// {
|
// if (PlayerDatas.Instance.hero != null
|
// && PlayerDatas.Instance.hero.SelectTarget == _actor)
|
// {
|
// PlayerDatas.Instance.ReCheckAttackTarget();
|
// }
|
// }
|
#if UNITY_EDITOR
|
Debug.LogFormat("删除 {0} 的Buff: {1}", h0606.ObjID, h0606.SkillID);
|
#endif
|
}
|
|
public void ReleaseActor(uint sid)
|
{
|
List<Status_Base> _list = null;
|
|
if (m_StatusDict.TryGetValue(sid, out _list))
|
{
|
for (int i = 0; i < _list.Count; ++i)
|
{
|
_list[i].UnInit(sid, 0);
|
|
if (m_AllStatus.Contains(_list[i]))
|
{
|
m_AllStatus.Remove(_list[i]);
|
}
|
}
|
|
m_StatusDict[sid].Clear();
|
m_StatusDict.Remove(sid);
|
}
|
|
if (m_OwnerList.Contains(sid))
|
{
|
m_OwnerList.Remove(sid);
|
}
|
}
|
|
List<int> m_CompleteList = new List<int>();
|
|
public void DoUpdate()
|
{
|
m_CompleteList.Clear();
|
for (int i = m_AllStatus.Count - 1; i >= 0; --i)
|
{
|
var _status = m_AllStatus[i];
|
_status.Update();
|
|
if (_status.IsComplete())
|
{
|
m_CompleteList.Add(i);
|
}
|
}
|
|
for (int i = 0; i < m_CompleteList.Count; ++i)
|
{
|
var _idx = m_CompleteList[i];
|
var _status = m_AllStatus[_idx];
|
|
_status.UnInit(_status.Sid, (byte)_status.BuffType);
|
|
if (m_StatusDict.ContainsKey(_status.Sid)
|
&& m_StatusDict[_status.Sid].Contains(_status))
|
{
|
m_StatusDict[_status.Sid].Remove(_status);
|
}
|
|
if (m_OwnerList.Contains(_status.Sid))
|
{
|
m_OwnerList.Remove(_status.Sid);
|
}
|
m_AllStatus.RemoveAt(_idx);
|
}
|
}
|
|
public Status_Base Get(uint sid, int buffID)
|
{
|
List<Status_Base> _list = null;
|
if (m_StatusDict.TryGetValue(sid, out _list))
|
{
|
for (int i = 0; i < _list.Count; ++i)
|
{
|
if (_list[i].SkillID == buffID)
|
{
|
return _list[i];
|
}
|
}
|
}
|
return null;
|
}
|
|
public bool IsExistBossBelong(uint sid)
|
{
|
return IsExist(sid, bossBelongBuffID);
|
}
|
|
public bool IsExist(uint sid, int buffID)
|
{
|
List<Status_Base> _list = null;
|
if (m_StatusDict.TryGetValue(sid, out _list))
|
{
|
for (int i = 0; i < _list.Count; ++i)
|
{
|
if (_list[i].SkillID == buffID)
|
{
|
return true;
|
}
|
}
|
}
|
return false;
|
}
|
|
public void GetBuffIds(uint sid, ref List<int> buffList)
|
{
|
if (buffList == null)
|
{
|
return;
|
}
|
|
List<Status_Base> _list = null;
|
if (m_StatusDict.TryGetValue(sid, out _list))
|
{
|
for (int i = 0; i < _list.Count; ++i)
|
{
|
buffList.Add(_list[i].SkillID);
|
}
|
}
|
}
|
|
public bool CanMove(uint sid)
|
{
|
List<Status_Base> _list = null;
|
if (m_StatusDict.TryGetValue(sid, out _list))
|
{
|
for (int i = 0; i < _list.Count; ++i)
|
{
|
if (!_list[i].CanMove())
|
{
|
return false;
|
}
|
}
|
}
|
return true;
|
}
|
|
public bool CanRide(uint sid)
|
{
|
List<Status_Base> _list = null;
|
if (m_StatusDict.TryGetValue(sid, out _list))
|
{
|
for (int i = 0; i < _list.Count; ++i)
|
{
|
if (!_list[i].CanRide())
|
{
|
return false;
|
}
|
}
|
}
|
return true;
|
}
|
|
public bool CanCollect(uint sid)
|
{
|
List<Status_Base> _list = null;
|
if (m_StatusDict.TryGetValue(sid, out _list))
|
{
|
for (int i = 0; i < _list.Count; ++i)
|
{
|
if (!_list[i].CanCollect())
|
{
|
return false;
|
}
|
}
|
}
|
return true;
|
}
|
|
public bool CanSit(uint sid)
|
{
|
List<Status_Base> _list = null;
|
if (m_StatusDict.TryGetValue(sid, out _list))
|
{
|
for (int i = 0; i < _list.Count; ++i)
|
{
|
if (!_list[i].CanSit())
|
{
|
return false;
|
}
|
}
|
}
|
return true;
|
}
|
|
public bool CanCatch(uint sid)
|
{
|
List<Status_Base> _list = null;
|
if (m_StatusDict.TryGetValue(sid, out _list))
|
{
|
for (int i = 0; i < _list.Count; ++i)
|
{
|
if (!_list[i].CanCatch())
|
{
|
return false;
|
}
|
}
|
}
|
return true;
|
}
|
|
public bool CanFish(uint sid)
|
{
|
List<Status_Base> _list = null;
|
if (m_StatusDict.TryGetValue(sid, out _list))
|
{
|
for (int i = 0; i < _list.Count; ++i)
|
{
|
if (!_list[i].CanFish())
|
{
|
return false;
|
}
|
}
|
}
|
return true;
|
}
|
|
public bool CanDance(uint sid)
|
{
|
List<Status_Base> _list = null;
|
if (m_StatusDict.TryGetValue(sid, out _list))
|
{
|
for (int i = 0; i < _list.Count; ++i)
|
{
|
if (!_list[i].CanDance())
|
{
|
return false;
|
}
|
}
|
}
|
return true;
|
}
|
|
public bool CanLook(uint sid)
|
{
|
List<Status_Base> _list = null;
|
if (m_StatusDict.TryGetValue(sid, out _list))
|
{
|
for (int i = 0; i < _list.Count; ++i)
|
{
|
if (!_list[i].CanLook())
|
{
|
return false;
|
}
|
}
|
}
|
return true;
|
}
|
|
public bool CanUseItem(uint sid)
|
{
|
List<Status_Base> _list = null;
|
if (m_StatusDict.TryGetValue(sid, out _list))
|
{
|
for (int i = 0; i < _list.Count; ++i)
|
{
|
if (!_list[i].CanUseItem())
|
{
|
return false;
|
}
|
}
|
}
|
return true;
|
}
|
|
public bool CanAttack(uint sid, SkillConfig _config)
|
{
|
List<Status_Base> _list = null;
|
if (m_StatusDict.TryGetValue(sid, out _list))
|
{
|
for (int i = 0; i < _list.Count; ++i)
|
{
|
if (!_list[i].CanAttack(_config.SkillOfSeries))
|
{
|
return false;
|
}
|
}
|
}
|
return true;
|
}
|
|
private bool IsMockingBuff(int id)
|
{
|
var _config = SkillConfig.Get(id);
|
|
if (_config != null
|
&& ((_config.Effect1 == 4012 && _config.EffectValue11 == 6)
|
|| (_config.Effect2 == 4012 && _config.EffectValue21 == 6)
|
|| (_config.Effect3 == 4012 && _config.EffectValue31 == 6)
|
|| (_config.Effect4 == 4012 && _config.EffectValue41 == 6)
|
|| (_config.Effect5 == 4012 && _config.EffectValue51 == 6)
|
|| (_config.Effect6 == 4012 && _config.EffectValue61 == 6)))
|
{
|
return true;
|
}
|
|
return false;
|
}
|
|
private void AddZjInfoIfExist(int id)
|
{
|
var _info = SkillHelper.Instance.Get(id);
|
if (_info == null)
|
{
|
return;
|
}
|
|
if (_info.effectValue.ContainsKey(4526))
|
{
|
var _zjInfo = new ZhongJiInfo
|
{
|
rate = _info.effectValue[4526].value1,
|
onlyFirstTarget = _info.effectValue[4526].value2 == 1
|
};
|
|
ZhongJiDict[id] = _zjInfo;
|
|
// #if UNITY_EDITOR
|
// Debug.LogFormat("收到一个增加重击概率的BUFF: {0}, 增加: {1}的概率", id, _zjInfo.rate);
|
// #endif
|
}
|
}
|
|
private bool IsPolymorch(int id)
|
{
|
SkillConfig _config = SkillConfig.Get(id);
|
if (_config != null
|
&& (_config.Effect1 == 1063
|
|| _config.Effect2 == 1063
|
|| _config.Effect3 == 1063
|
|| _config.Effect4 == 1063
|
|| _config.Effect5 == 1063
|
|| _config.Effect6 == 1063))
|
{
|
return true;
|
}
|
return false;
|
}
|
|
private bool IsInVisibleStatus(int id)
|
{
|
SkillHelper.SkillInfo _skillInfo = SkillHelper.Instance.Get(id);
|
|
if (_skillInfo != null
|
&& _skillInfo.effectValue.ContainsKey(1302))
|
{
|
return true;
|
}
|
|
return false;
|
}
|
|
public bool IsInvincible(uint sid)
|
{
|
List<Status_Base> _list = null;
|
if (m_StatusDict.TryGetValue(sid, out _list))
|
{
|
SkillHelper.SkillInfo _skillInfo = null;
|
for (int i = 0; i < _list.Count; ++i)
|
{
|
_skillInfo = SkillHelper.Instance.Get(_list[i].SkillID);
|
if (_skillInfo.effectValue.ContainsKey(2004))
|
{
|
return true;
|
}
|
}
|
}
|
return false;
|
}
|
|
public bool IsInvisible(uint sid)
|
{
|
List<Status_Base> _list = null;
|
if (m_StatusDict.TryGetValue(sid, out _list))
|
{
|
SkillHelper.SkillInfo _skillInfo = null;
|
for (int i = 0; i < _list.Count; ++i)
|
{
|
_skillInfo = SkillHelper.Instance.Get(_list[i].SkillID);
|
if (_skillInfo.effectValue.ContainsKey(1302))
|
{
|
return true;
|
}
|
}
|
}
|
return false;
|
}
|
|
public bool TryGetSkillEffectValue(uint sid, int skillEffectID, out SkillHelper.EffectValue effectValue)
|
{
|
effectValue = default(SkillHelper.EffectValue);
|
List<Status_Base> _list = null;
|
if (m_StatusDict.TryGetValue(sid, out _list))
|
{
|
for (int i = 0; i < _list.Count; ++i)
|
{
|
if (SkillHelper.Instance.Get(_list[i].SkillID).effectValue.ContainsKey(skillEffectID))
|
{
|
effectValue = SkillHelper.Instance.Get(_list[i].SkillID).effectValue[skillEffectID];
|
return true;
|
}
|
}
|
}
|
return false;
|
}
|
|
public bool IsBurning(uint targetSID, uint attackSID = 0)
|
{
|
List<Status_Base> _list = null;
|
if (m_StatusDict.TryGetValue(targetSID, out _list))
|
{
|
for (int i = 0; i < _list.Count; ++i)
|
{
|
if (SkillHelper.Instance.Get(_list[i].SkillID).effectValue.ContainsKey(1043))
|
{
|
if (attackSID > 0)
|
{
|
if (_list[i].Sid == attackSID)
|
{
|
return true;
|
}
|
}
|
else
|
{
|
return true;
|
}
|
}
|
}
|
}
|
return false;
|
}
|
}
|