using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; [XLua.LuaCallCSharp] public class StatusMgr : SingletonMonobehaviour { public struct ZhongJiInfo { public int rate; public bool onlyFirstTarget; } public static event UnityAction OnGainStatus; public static event UnityAction OnGainCantCastSkillStatus; public static event UnityAction OnReleaseCantCastSkillStatus; public static event UnityAction onReceiveStatus; public Dictionary ZhongJiDict = new Dictionary(); private Dictionary> m_StatusDict = null; private List m_AllStatus = null; private List m_OwnerList = null; [HideInInspector] public int bossBelongBuffID; [HideInInspector] public int redNameBuffID; [HideInInspector] public int yellowNameBuffID; public int ZhongJiRate; public void Init() { DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += OnServerPrepareOk; if (m_StatusDict == null) { m_StatusDict = new Dictionary>(); } if (m_OwnerList == null) { m_OwnerList = new List(); } if (m_AllStatus == null) { m_AllStatus = new List(); } FuncConfigConfig _funcConfig = FuncConfigConfig.Get("BuffCPInterface"); string[] _pair = _funcConfig.Numerical1.Split('_'); if (_pair != null && _pair.Length > 0) { if (_pair[1].Equals("BOSSAscription")) { bossBelongBuffID = int.Parse(_pair[0]); } } _pair = _funcConfig.Numerical2.Split('_'); if (_pair != null && _pair.Length > 0) { if (_pair[1].Equals("RedName")) { redNameBuffID = int.Parse(_pair[0]); } } _pair = _funcConfig.Numerical3.Split('_'); if (_pair != null && _pair.Length > 0) { if (_pair[1].Equals("YellowName")) { yellowNameBuffID = int.Parse(_pair[0]); } } } 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()); } 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()); } _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 (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 _list = null; if (!m_StatusDict.ContainsKey(h0605.ObjID)) { _list = new List(); 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 _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 _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()); } _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()); } _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 _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 m_CompleteList = new List(); 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 _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 _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 buffList) { if (buffList == null) { return; } List _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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; } }