Files
Main/Assets/Code/Logic/RedPointSystem/RedPointSystem.cs
2025-01-25 04:38:09 +08:00

684 lines
26 KiB
C#

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<int, RedPointFunction> _funcTable = new Dictionary<int, RedPointFunction>();
//变量对应的功能表
private Dictionary<int, List<int>>[] _funcVariableTable = new Dictionary<int, List<int>>[(int)RedPointConditionType.Count];
//待检测列表,下一帧进行检测
private List<int>[] _checkDataIds = new List<int>[(int)RedPointConditionType.Count];
private Dictionary<int, bool> _cacheCheckDic = new Dictionary<int, bool>();
private Dictionary<string, int> _cacheEquipDic = new Dictionary<string, int>();
//是否刷新数据
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<int, List<int>>();
}
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<int, RedPointConditionBase>(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<int> funcList = null;
if(!_funcVariableTable[index].TryGetValue(con.ID, out funcList))
{
funcList = new List<int>(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<int>(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<string>(_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<int>();
}
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<int>();
}
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<int>();
}
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<int>();
}
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>();
}
int itemID = (int)obj;
List<int> 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<string>(_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<int>();
}
itemID = 0;
List<int> 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<string>(_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<int>();
}
itemID = 0;
List<int> 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>();
}
int itemID = int.Parse(obj.ToString());
List<int> 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>();
}
int taskId = int.Parse(obj.ToString());
List<int> 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<int>();
}
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<int> 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<int> _list = new List<int>();
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
}
}