using Thousandto.Cfg.Data; using Thousandto.Code.Center; using Thousandto.Code.Global; using Thousandto.Core.Base; using System.Collections.Generic; using UnityEngine; using XLua; namespace Thousandto.Code.Logic { //红点系统 public class RedPointSystem { #region//私有变量 //功能对应的条件表 private Dictionary _funcTable = new Dictionary(); //变量对应的功能表 private Dictionary>[] _funcVariableTable = new Dictionary>[(int)RedPointConditionType.Count]; //待检测列表,下一帧进行检测 private List[] _checkDataIds = new List[(int)RedPointConditionType.Count]; private Dictionary _cacheCheckDic = new Dictionary(); private Dictionary _cacheEquipDic = new Dictionary(); //是否刷新数据 private bool _isRefreshData = false; public bool IsRefreshEquipCon = false; #endregion #region//公有函数 //初始化 public void Initialize() { for (int i = 0; i < _funcVariableTable.Length; ++i) { _funcVariableTable[i] = new Dictionary>(); } GameCenter.RegFixEventHandle(LogicEventDefine.EID_EVENT_FIGHT_POWER_CHANGED, OnFightPowerChanged); GameCenter.RegFixEventHandle(LogicEventDefine.EID_EVENT_PLAYER_BASE_ATTR_CHANGED, OnLevelChanged); GameCenter.RegFixEventHandle(LogicEventDefine.EVENT_COIN_CHANGE_UPDATE, OnItemChanged); GameCenter.RegFixEventHandle(LogicEventDefine.EVENT_ITEM_CHANGE_UPDATE, OnItemChanged); GameCenter.RegFixEventHandle(LogicEventDefine.EVENT_EQUIP_ADD, OnEquipAdd); GameCenter.RegFixEventHandle(LogicEventDefine.EVENT_EQUIP_DEL, OnEquipDel); GameCenter.RegFixEventHandle(LogicEventDefine.EID_EVENT_ITEM_DELETELIST_UPDATE, OnEquipListDel); GameCenter.RegFixEventHandle(LogicEventDefine.EID_EVENT_ONLINE_ITEMINFO, OnOnLineItemEvent); GameCenter.RegFixEventHandle(LogicEventDefine.EID_EVENT_TASKCHANG, OnTaskChanged); GameCenter.RegFixEventHandle(LogicEventDefine.EID_EVENT_XIANPO_BAG_ITEM_CHANGED, OnXianPoChanged); GameCenter.RegFixEventHandle(LogicEventDefine.EID_EVENT_TASKBASE_UPDATED, OnTaskUpdated); } //反初始化 public void UnInitialize() { _funcTable.Clear(); GameCenter.UnRegFixEventHandle(LogicEventDefine.EID_EVENT_FIGHT_POWER_CHANGED, OnFightPowerChanged); GameCenter.UnRegFixEventHandle(LogicEventDefine.EID_EVENT_PLAYER_BASE_ATTR_CHANGED, OnLevelChanged); GameCenter.UnRegFixEventHandle(LogicEventDefine.EVENT_COIN_CHANGE_UPDATE, OnItemChanged); GameCenter.UnRegFixEventHandle(LogicEventDefine.EVENT_ITEM_CHANGE_UPDATE, OnItemChanged); GameCenter.UnRegFixEventHandle(LogicEventDefine.EVENT_EQUIP_ADD, OnEquipAdd); GameCenter.UnRegFixEventHandle(LogicEventDefine.EVENT_EQUIP_DEL, OnEquipDel); GameCenter.UnRegFixEventHandle(LogicEventDefine.EID_EVENT_ONLINE_ITEMINFO, OnOnLineItemEvent); GameCenter.UnRegFixEventHandle(LogicEventDefine.EID_EVENT_TASKCHANG, OnTaskChanged); GameCenter.UnRegFixEventHandle(LogicEventDefine.EID_EVENT_XIANPO_BAG_ITEM_CHANGED, OnXianPoChanged); GameCenter.UnRegFixEventHandle(LogicEventDefine.EID_EVENT_TASKBASE_UPDATED, OnTaskUpdated); } public void LateUpdate() { if (_isRefreshData) { _isRefreshData = false; RefreshData(); } } //更新 public void Update() { if (Time.frameCount % 10 == 0) { //10帧检测一次红点 if (IsRefreshEquipCon) { IsRefreshEquipCon = false; RefreshEquipDic(); } _cacheCheckDic.Clear(); for (int i = 0; i < _checkDataIds.Length; ++i) { if (_checkDataIds[i] != null && _checkDataIds[i].Count > 0) { for (int j = 0; j < _checkDataIds[i].Count; ++j) { Check((RedPointConditionType)i, _checkDataIds[i][j]); } _checkDataIds[i].Clear(); } } } } //提供给lua端调用的增加条件函数 public void LuaAddFuncCondition(int funcID, long dataID, LuaTable luaData) { if (luaData == null || luaData.Length <= 0) return; RedPointConditionBase[] cons = new RedPointConditionBase[luaData.Length]; for (int i = 1; i <= luaData.Length; ++i) { RedPointConditionBase value = null; luaData.TryGet(i, out value); cons[i - 1] = value; } AddFuncCondition(funcID, dataID, cons); } //增加功能条件 public void AddFuncCondition(int funcID, long dataID, params RedPointConditionBase[] cons) { if (cons == null || cons.Length <= 0f) return; RedPointFunction func = null; if (!_funcTable.TryGetValue((int)funcID, out func)) { func = new RedPointFunction(funcID); _funcTable.Add(func.FuncID, func); } func.AddConditions(dataID, cons); _isRefreshData = true; } //删除功能中的某一个条件 public void RemoveFuncCondition(int funcID, long dataID) { RedPointFunction func = null; if (_funcTable.TryGetValue((int)funcID, out func)) { func.Remove(dataID); _isRefreshData = true; } } //清除掉某个功能的所有条件 public void CleraFuncCondition(int funcID) { RedPointFunction func = null; if (_funcTable.TryGetValue(funcID, out func)) { func.Clear(); _funcTable.Remove(funcID); _isRefreshData = true; } } //判断功能中的某一个条件是否达成 public bool OneConditionsIsReach(int funcID, long dataID) { RedPointFunction func = null; if (_funcTable.TryGetValue(funcID, out func)) { return func.OneConditionsIsReach(dataID); } return false; } //判断某个功能条件是否达成 public bool FuncConditionsIsReach(int funcID) { RedPointFunction func = null; if (_funcTable.TryGetValue(funcID, out func)) { return func.IsReach; } return false; } //取满足装备条件数量 public int EquipConditionsReachCount(string key) { if (_cacheEquipDic.ContainsKey(key)) return _cacheEquipDic[key]; else { _cacheEquipDic.Add(key, 0); RefreshEquipDic(); } return EquipConditionsReachCount(key); } #endregion #region//私有函数 //刷新数据 private void RefreshData() { for(int i = 0; i < _funcVariableTable.Length; ++i) { _funcVariableTable[i].Clear(); } var iter = _funcTable.GetEnumerator(); try { while(iter.MoveNext()) { var iterData = iter.Current.Value.Conditions.GetEnumerator(); try { while(iterData.MoveNext()) { for(int i = 0; i < iterData.Current.Value.Count; ++i) { var con = iterData.Current.Value[i]; var index = (int)con.Type; List funcList = null; if(!_funcVariableTable[index].TryGetValue(con.ID, out funcList)) { funcList = new List(32); _funcVariableTable[index].Add(con.ID, funcList); } if(con.Type == RedPointConditionType.Item) { var itCon = con as RedPointItemCondition; if (itCon.CoinID > 0 && !_funcVariableTable[index].TryGetValue(itCon.CoinID, out funcList)) { funcList = new List(32); _funcVariableTable[index].Add(itCon.CoinID, funcList); } } funcList.Add(iter.Current.Key); } } } finally { iterData.Dispose(); } } } finally { iter.Dispose(); } } private void RefreshEquipDic() { var _keyList = new List(_cacheEquipDic.Keys); for (int i = 0; i < _keyList.Count; i++) { _cacheEquipDic[_keyList[i]] = 0; } ItemContianerModel bpModel = GameCenter.ItemContianerSystem.GetBackpackModelByType(ContainerType.ITEM_LOCATION_BAG); if (null != bpModel) { var tmpList = bpModel.ItemsOfIndex; if (null != tmpList) { var enumerator = tmpList.GetEnumerator(); try { while (enumerator.MoveNext()) { var retItem = enumerator.Current.Value as Equipment; if (null != retItem) { for (int i = 0; i < _keyList.Count; i++) { var _ar = _keyList[i].Split('_'); if (_ar.Length >= 11) { if (CheckEquipQuality(_ar[0], _ar[1], retItem) && CheckEquipDegree(_ar[2], _ar[3], retItem) && CheckEquipOcc(_ar[4], _ar[5], retItem) && CheckEquipStar(_ar[6], _ar[7], retItem) && CheckEquipPower(_ar[8], retItem) && CheckEquipClassLv(_ar[9], retItem) && CheckEquipPart(_ar[10], retItem)) { _cacheEquipDic[_keyList[i]] += 1; } } } } } } finally { enumerator.Dispose(); } } } int index = (int)RedPointConditionType.Equip; if (_checkDataIds[index] == null) { _checkDataIds[index] = new List(); } if (_checkDataIds[index].Count <= 0) { _checkDataIds[index].Add(0); } } private void OnTaskChanged(object obj, object sender = null) { int index = (int)RedPointConditionType.Task; if (_checkDataIds[index] == null) { _checkDataIds[index] = new List(); } if(_checkDataIds[index].Count <= 0) { _checkDataIds[index].Add(0); } } private void OnLevelChanged(object obj, object sender = null) { PlayerPropetry propetry = obj as PlayerPropetry; if (propetry == null) return; if (propetry.CurrentChangeBasePropType == RoleBaseAttribute.Level) { int index = (int)RedPointConditionType.Level; if (_checkDataIds[index] == null) { _checkDataIds[index] = new List(); } if (_checkDataIds[index].Count <= 0) { _checkDataIds[index].Add(0); } } else if(propetry.CurrentChangeBasePropType == RoleBaseAttribute.ChangeJobLevel) { int index = (int)RedPointConditionType.ChangeJob; if (_checkDataIds[index] == null) { _checkDataIds[index] = new List(); } if (_checkDataIds[index].Count <= 0) { _checkDataIds[index].Add(0); } RefreshEquipDic(); } } //背包整体改变时全部检查一遍 private void OnOnLineItemEvent(object obj, object sender) { //加载一遍装备数据 RefreshEquipDic(); for(int i = 0; i < _checkDataIds.Length; ++i) { if(_checkDataIds[i] != null) { _checkDataIds[i].Clear(); } } var iter = _funcTable.GetEnumerator(); try { while(iter.MoveNext()) { iter.Current.Value.Check(); } } finally { iter.Dispose(); } } private void OnItemChanged(object obj, object sender = null) { int index = (int)RedPointConditionType.Item; if (_checkDataIds[index] == null) { _checkDataIds[index] = new List(); } int itemID = (int)obj; List funcList = null; if (_funcVariableTable[index].TryGetValue(itemID, out funcList) && funcList != null && funcList.Count > 0 && !_checkDataIds[index].Contains(itemID)) { _checkDataIds[index].Add(itemID); } } private void OnEquipAdd(object obj, object sender = null) { int itemID = (int)obj; var item = ItemBase.CreateItemBase(itemID); var retItem = item as Equipment; if (retItem != null) { var _keyList = new List(_cacheEquipDic.Keys); for (int i = 0; i < _keyList.Count; i++) { var _ar = _keyList[i].Split('_'); if (_ar.Length >= 11) { if (CheckEquipQuality(_ar[0], _ar[1], retItem) && CheckEquipDegree(_ar[2], _ar[3], retItem) && CheckEquipOcc(_ar[4], _ar[5], retItem) && CheckEquipStar(_ar[6], _ar[7], retItem) && CheckEquipPower(_ar[8], retItem) && CheckEquipClassLv(_ar[9], retItem) && CheckEquipPart(_ar[10], retItem)) { _cacheEquipDic[_keyList[i]] += 1; } } } } int index = (int)RedPointConditionType.Equip; if (_checkDataIds[index] == null) { _checkDataIds[index] = new List(); } itemID = 0; List funcList = null; if (_funcVariableTable[index].TryGetValue(itemID, out funcList) && funcList != null && funcList.Count > 0 && !_checkDataIds[index].Contains(itemID)) { _checkDataIds[index].Add(itemID); } } private void OnEquipDel(object obj, object sender = null) { int itemID = (int)obj; var item = ItemBase.CreateItemBase(itemID); var retItem = item as Equipment; if (retItem != null) { var _keyList = new List(_cacheEquipDic.Keys); for (int i = 0; i < _keyList.Count; i++) { var _ar = _keyList[i].Split('_'); if (_ar.Length >= 11) { if (CheckEquipQuality(_ar[0], _ar[1], retItem) && CheckEquipDegree(_ar[2], _ar[3], retItem) && CheckEquipOcc(_ar[4], _ar[5], retItem) && CheckEquipStar(_ar[6], _ar[7], retItem) && CheckEquipPower(_ar[8], retItem) && CheckEquipClassLv(_ar[9], retItem) && CheckEquipPart(_ar[10], retItem)) { _cacheEquipDic[_keyList[i]] -= 1; } } } } int index = (int)RedPointConditionType.Equip; if (_checkDataIds[index] == null) { _checkDataIds[index] = new List(); } itemID = 0; List funcList = null; if (_funcVariableTable[index].TryGetValue(itemID, out funcList) && funcList != null && funcList.Count > 0 && !_checkDataIds[index].Contains(itemID)) { _checkDataIds[index].Add(itemID); } } private void OnEquipListDel(object obj, object sender = null) { RefreshEquipDic(); } private void OnXianPoChanged(object obj, object sender = null) { int index = (int)RedPointConditionType.XianPo; if (_checkDataIds[index] == null) { _checkDataIds[index] = new List(); } int itemID = int.Parse(obj.ToString()); List funcList = null; if (_funcVariableTable[index].TryGetValue(itemID, out funcList) && funcList != null && funcList.Count > 0 && !_checkDataIds[index].Contains(itemID)) { _checkDataIds[index].Add(itemID); } } private void OnTaskUpdated(object obj, object sender = null) { int index = (int)RedPointConditionType.TaskSubmit; if (_checkDataIds[index] == null) { _checkDataIds[index] = new List(); } int taskId = int.Parse(obj.ToString()); List funcList = null; if (_funcVariableTable[index].TryGetValue(taskId, out funcList) && funcList != null && funcList.Count > 0 && !_checkDataIds[index].Contains(taskId)) { _checkDataIds[index].Add(taskId); } } private void OnFightPowerChanged(object obj, object sender = null) { int index = (int)RedPointConditionType.FightPower; if (_checkDataIds[index] == null) { _checkDataIds[index] = new List(); } if (_checkDataIds[index].Count <= 0) { _checkDataIds[index].Add(0); } } private void Check(RedPointConditionType conType, int ID) { int type = (int)conType; if (type >= 0 && type < _funcVariableTable.Length) { List funcList = null; if (_funcVariableTable[type].TryGetValue(ID, out funcList)) { for(int i = 0; i < funcList.Count; ++i) { RedPointFunction func = null; if (!_cacheCheckDic.ContainsKey(funcList[i]) && _funcTable.TryGetValue(funcList[i], out func)) { func.Check(); _cacheCheckDic.Add(funcList[i], true); } } } } } private bool CheckEquipQuality(string num, string numType, Equipment item) { var _num = 0; var _type = CompaireType.DayuDengyu; int.TryParse(num, out _num); int.TryParse(numType, out _type); bool _result = false; if (item != null) { switch (_type) { case CompaireType.Dayu: _result = item.Quality > _num; break; case CompaireType.Xiaoyu: _result = item.Quality < _num; break; case CompaireType.DayuDengyu: _result = item.Quality >= _num; break; case CompaireType.XiaoyuDengyu: _result = item.Quality <= _num; break; case CompaireType.Dengyu: _result = item.Quality == _num; break; case CompaireType.Budengyu: _result = item.Quality != _num; break; } } return _result; } private bool CheckEquipDegree(string num, string numType, Equipment item) { var _num = 0; var _type = CompaireType.DayuDengyu; int.TryParse(num, out _num); int.TryParse(numType, out _type); bool _result = false; if (item != null) { switch (_type) { case CompaireType.Dayu: _result = item.Grade > _num; break; case CompaireType.Xiaoyu: _result = item.Grade < _num; break; case CompaireType.DayuDengyu: _result = item.Grade >= _num; break; case CompaireType.XiaoyuDengyu: _result = item.Grade <= _num; break; case CompaireType.Dengyu: _result = item.Grade == _num; break; case CompaireType.Budengyu: _result = item.Grade != _num; break; } } return _result; } private bool CheckEquipOcc(string num, string numType, Equipment item) { var _type = CompaireType.DayuDengyu; int.TryParse(numType, out _type); bool _result = false; if (item != null) { switch (_type) { case CompaireType.Dengyu: _result = item.Occ.IndexOf(num) >= 0 || item.Occ.IndexOf("9") >= 0; break; case CompaireType.Budengyu: _result = item.Occ.IndexOf(num) < 0 && item.Occ.IndexOf("9") < 0; break; } } return _result; } private bool CheckEquipStar(string num, string numType, Equipment item) { var _num = 0; var _type = CompaireType.DayuDengyu; int.TryParse(num, out _num); int.TryParse(numType, out _type); bool _result = false; if (item != null) { switch (_type) { case CompaireType.Dayu: _result = item.StarNum > _num; break; case CompaireType.Xiaoyu: _result = item.StarNum < _num; break; case CompaireType.DayuDengyu: _result = item.StarNum >= _num; break; case CompaireType.XiaoyuDengyu: _result = item.StarNum <= _num; break; case CompaireType.Dengyu: _result = item.StarNum == _num; break; case CompaireType.Budengyu: _result = item.StarNum != _num; break; } } return _result; } private bool CheckEquipPower(string num, Equipment item) { var _num = 0; int.TryParse(num, out _num); bool _result = false; if (item != null) { _result = item.Power > _num; } return _result; } private bool CheckEquipClassLv(string num, Equipment item) { var _num = 0; int.TryParse(num, out _num); bool _result = true; if (item != null && _num == 1) { _result = item.CheckClass(); } return _result; } private bool CheckEquipPart(string num, Equipment item) { var _arr = num.Split(';'); List _list = new List(); for (int i = 0; i < _arr.Length; i++) { int _num = -1; int.TryParse(_arr[i], out _num); _list.Add(_num); } bool _result = true; if (item != null) { _result = _list.Contains(item.Part) || _list.Contains(-1); } return _result; } #endregion } }