using LitJson; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; public class HappyXBModel : GameSystemManager { //寻宝产出库 private Dictionary> xbGetItemDict = new Dictionary>(); //奖池的所有物品(按类型+等级) private Dictionary> xbTypeItemDict = new Dictionary>(); //奖池的所有物品(按类型) float xbLastTime = 0; //等待服务端回复 如果太长就重置为不等待 bool m_IsWaitServerXB = false; // 等待服务端回复 public bool isXBCoolTime { get { #if UNITY_EDITOR if (Time.time - xbLastTime > 1) #else if (Time.time - xbLastTime > 10) #endif { m_IsWaitServerXB = false; return m_IsWaitServerXB; } return m_IsWaitServerXB; } set { m_IsWaitServerXB = value; xbLastTime = Time.time; } } private Dictionary xbTypeInfoDict = new Dictionary(); //抽奖状态相关的 服务器记录 public int lhQuality; public override void Init() { DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += OnBeforePlayerDataInitialize; FuncOpen.Instance.OnFuncStateChangeEvent += UpdateFuncState; PackManager.Instance.RefreshItemEvent += RefreshXBTool; TimeMgr.Instance.OnDayEvent += OnDayEvent; DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent += OnPlayerLoginOk; InvestModel.Instance.onInvestUpdate += OnInvestUpdate; xbGetItemDict.Clear(); xbTypeItemDict.Clear(); List list = XBGetItemConfig.GetValues(); for (int i = 0; i < list.Count; i++) { if (!xbGetItemDict.ContainsKey(list[i].TreasureType)) { xbGetItemDict.Add(list[i].TreasureType, new Dictionary()); } xbGetItemDict[list[i].TreasureType].Add(list[i].MinLV, list[i]); if (!xbTypeItemDict.ContainsKey(list[i].TreasureType)) { xbTypeItemDict.Add(list[i].TreasureType, new List()); } xbTypeItemDict[list[i].TreasureType].Add(list[i]); } var config = FuncConfigConfig.Get("HeroCall"); lhQuality = int.Parse(config.Numerical1); } public override void Release() { DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent -= OnBeforePlayerDataInitialize; FuncOpen.Instance.OnFuncStateChangeEvent -= UpdateFuncState; PackManager.Instance.RefreshItemEvent -= RefreshXBTool; TimeMgr.Instance.OnDayEvent -= OnDayEvent; DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent -= OnPlayerLoginOk; InvestModel.Instance.onInvestUpdate -= OnInvestUpdate; } void OnBeforePlayerDataInitialize() { isXBCoolTime = false; xbTypeInfoDict.Clear(); } void OnPlayerLoginOk() { HeroCallRedPoint(); } void OnInvestUpdate(int type) { if (type == 7) HeroCallRedPoint(); } public XBGetItemConfig GetXBItemConfigByType(int type) { int lv = 0; List configlist = null; xbTypeItemDict.TryGetValue(type, out configlist); if (configlist != null) { for (int i = configlist.Count - 1; i > -1; i--) { if (PlayerDatas.Instance.baseData.LV >= configlist[i].MinLV) { lv = configlist[i].MinLV; return configlist[i]; } } } return null; } #region 处理服务端数据 public event Action RefreshXBTypeInfoAct; public event Action RefreshXBResultAct; public int addXBScore { get; private set; } public int addXBScoreType { get; private set; } //寻宝积分货币类型 public int addXBLuckValue { get; private set; } public Dictionary xbResultDict { get; private set; } = new Dictionary(); //奖品顺序:奖品 public void GetServerXBResult(HA350_tagMCTreasureResult result) { xbResultDict.Clear(); addXBScore = result.AddMoneyValue; addXBScoreType = result.AddMoneyType; addXBLuckValue = result.AddTreasureLuck; JsonData resultData = JsonMapper.ToObject(result.TreasureResult); if (resultData.IsArray) { for (int i = 0; i < resultData.Count; i++) { if (resultData[i].IsArray) { int index = int.Parse(resultData[i][0].ToString()); int itemId = int.Parse(resultData[i][1].ToString()); int count = int.Parse(resultData[i][2].ToString()); XBGetItem getItem = new XBGetItem(); getItem.SetModel(index, itemId, count); if (!xbResultDict.ContainsKey(i)) { xbResultDict.Add(i, getItem); } else { xbResultDict[i] = getItem; } } } } isXBCoolTime = false; if (RefreshXBResultAct != null) { RefreshXBResultAct(); } if (!UIManager.Instance.IsOpened()) { UIManager.Instance.OpenWindow(); } } public int GetCountInResult(int itemID) { int count = 0; if (xbResultDict != null && xbResultDict.Count > 0) { foreach (var item in xbResultDict) { if (item.Value.itemId == itemID) { count++; } } } return count; } public void ClearXBRusltData() { xbResultDict.Clear(); } public void GetServerXBInfo(HA351_tagMCTreasureInfo info) { for (int i = 0; i < info.InfoCount; i++) { if (!xbTypeInfoDict.ContainsKey(info.TreasuerInfoList[i].TreasureType)) { XBTypeInfo typeInfo = new XBTypeInfo(); typeInfo.xbType = info.TreasuerInfoList[i].TreasureType; typeInfo.luckValue = info.TreasuerInfoList[i].LuckValue; typeInfo.freeCountToday = info.TreasuerInfoList[i].FreeCountToday; typeInfo.treasureCount = (int)info.TreasuerInfoList[i].TreasureCount; typeInfo.treasureCountToday = (int)info.TreasuerInfoList[i].TreasureCountToday; typeInfo.treasureCntAward = (int)info.TreasuerInfoList[i].TreasureCntAward; if (typeInfo.gridLimitCntDict == null) typeInfo.gridLimitCntDict = new Dictionary(); for (int j = 0; j < info.TreasuerInfoList[i].GridLimitCntList.Length; j++) { int num = info.TreasuerInfoList[i].GridLimitCntList[j].GridNum; int cnt = info.TreasuerInfoList[i].GridLimitCntList[j].GridCnt; typeInfo.gridLimitCntDict[num] = cnt; } xbTypeInfoDict.Add(info.TreasuerInfoList[i].TreasureType, typeInfo); } else { xbTypeInfoDict[info.TreasuerInfoList[i].TreasureType].luckValue = info.TreasuerInfoList[i].LuckValue; xbTypeInfoDict[info.TreasuerInfoList[i].TreasureType].freeCountToday = info.TreasuerInfoList[i].FreeCountToday; xbTypeInfoDict[info.TreasuerInfoList[i].TreasureType].treasureCount = (int)info.TreasuerInfoList[i].TreasureCount; xbTypeInfoDict[info.TreasuerInfoList[i].TreasureType].treasureCountToday = (int)info.TreasuerInfoList[i].TreasureCountToday; xbTypeInfoDict[info.TreasuerInfoList[i].TreasureType].treasureCntAward = (int)info.TreasuerInfoList[i].TreasureCntAward; if (xbTypeInfoDict[info.TreasuerInfoList[i].TreasureType].gridLimitCntDict == null) xbTypeInfoDict[info.TreasuerInfoList[i].TreasureType].gridLimitCntDict = new Dictionary(); for (int j = 0; j < info.TreasuerInfoList[i].GridLimitCntList.Length; j++) { int num = info.TreasuerInfoList[i].GridLimitCntList[j].GridNum; int cnt = info.TreasuerInfoList[i].GridLimitCntList[j].GridCnt; xbTypeInfoDict[info.TreasuerInfoList[i].TreasureType].gridLimitCntDict[num] = cnt; } } } if (RefreshXBTypeInfoAct != null) { RefreshXBTypeInfoAct(); } HeroCallRedPoint(); } public XBTypeInfo GetXBInfoByType(int type) { XBTypeInfo typeInfo = null; xbTypeInfoDict.TryGetValue(type, out typeInfo); return typeInfo; } /// /// 请求寻宝 /// /// 寻宝类型 /// 0 单次寻宝 1 多次寻宝 /// 0-货币;1-免费次数;2-寻宝道具 public event Action StartXBEvent; public void SendXBQuest(int type, int index, int costType) { if (isXBCoolTime) return; isXBCoolTime = true; CA568_tagCMRequestTreasure treasure = new CA568_tagCMRequestTreasure(); treasure.TreasureType = (byte)type; treasure.TreasureIndex = (byte)index; treasure.CostType = (byte)costType; GameNetSystem.Instance.SendInfo(treasure); if (StartXBEvent != null) { StartXBEvent(index); } } public bool CheckIsEmptyGrid(PackType type, int needGrid = 1) { switch (type) { // case PackType.Treasure: // SinglePack singlePack = PackManager.Instance.GetSinglePack(type); // if (GeneralDefine.maxXBGridCount - singlePack.GetAllItems().Count < needGrid) // { // SysNotifyMgr.Instance.ShowTip("XBWarehouseFull"); // return false; // } // break; case PackType.Item: if (PackManager.Instance.GetEmptyGridCount(type) < needGrid) { SysNotifyMgr.Instance.ShowTip("BagFull"); return false; } break; case PackType.Hero: if (PackManager.Instance.GetEmptyGridCount(type) < needGrid) { SysNotifyMgr.Instance.ShowTip("HeroBagFull"); return false; } break; } return true; } public void SendOneXBQuest(int xbType) { var config = TreasureSetConfig.Get(xbType); if (GetXBInfoByType(xbType).treasureCountToday + config.TreasureCountList[0] > config.DailyMaxCount) { SysNotifyMgr.Instance.ShowTip("XBTodayMax"); return; } var funcSet = TreasureSetConfig.Get(xbType); if (CheckIsEmptyGrid((PackType)config.PackType)) { //道具寻宝 if (funcSet.CostItemID != 0 && IsHaveOneXBTool(xbType)) { SendXBQuest(xbType, 0, 2); return; } //货币寻宝 int moneyType = funcSet.CostMoneyType; int xbOneMoney = funcSet.CostMoneyList[0]; //暂定充值货币需要二次确认 if (moneyType == 1) { StoreModel.Instance.UseMoneyCheck(xbOneMoney, moneyType, () => { if (UIHelper.GetMoneyCnt(moneyType) >= xbOneMoney) { SendXBQuest(xbType, 0, 0); } else { ItemTipUtility.ShowMoneyTip(moneyType); } }, (int)BuyStoreItemCheckType.HeroCall, fullTip: Language.Get("CostMoneyForItem", funcSet.CostItemID, xbOneMoney, UIHelper.GetIconNameWithMoneyType(moneyType), funcSet.CostItemCountList[0])); } else { if (UIHelper.GetMoneyCnt(moneyType) >= xbOneMoney) { SendXBQuest(xbType, 0, 0); } else { ItemTipUtility.ShowMoneyTip(moneyType); } } } } public void SendXBManyQuest(int xbType) { var config = TreasureSetConfig.Get(xbType); if (GetXBInfoByType(xbType).treasureCountToday + config.TreasureCountList[1] > config.DailyMaxCount) { SysNotifyMgr.Instance.ShowTip("XBTodayMax"); return; } var funcSet = TreasureSetConfig.Get(xbType); if (CheckIsEmptyGrid((PackType)config.PackType, 10)) { int toolCnt = 0; int needToolCnt = 0; int needMoney = 0; if (IsHaveManyXBToolEx(xbType, out toolCnt, out needToolCnt, out needMoney)) { SendXBQuest(xbType, 1, 2); } //货币寻宝 int moneyType = funcSet.CostMoneyType; //暂定充值货币需要二次确认 if (moneyType == 1) { StoreModel.Instance.UseMoneyCheck(needMoney, moneyType, () => { //只要有道具就是道具寻宝,不足部分服务端扣货币 if (UIHelper.GetMoneyCnt(moneyType) >= needMoney) { SendXBQuest(xbType, 1, toolCnt > 0 ? 2 : 0); } else { ItemTipUtility.ShowMoneyTip(moneyType); } }, (int)BuyStoreItemCheckType.HeroCall, fullTip: Language.Get("CostMoneyForItem", funcSet.CostItemID, needMoney, UIHelper.GetIconNameWithMoneyType(moneyType), needToolCnt - toolCnt)); } else { if (UIHelper.GetMoneyCnt(moneyType) >= needMoney) { SendXBQuest(xbType, 1, toolCnt > 0 ? 2 : 0); } else { ItemTipUtility.ShowMoneyTip(moneyType); } } } } #endregion public bool IsHaveFreeXB(int type) { int freeCountToday = 0; XBTypeInfo typeInfo = GetXBInfoByType(type); if (typeInfo != null) { freeCountToday = typeInfo.freeCountToday; } //判断是否有免费次数,且免费次数是否用完 var funcSet = TreasureSetConfig.Get(type); return freeCountToday < funcSet.DailyFreeCount; } public int GetFreeCountToday(int type) { XBTypeInfo typeInfo = GetXBInfoByType(type); if (typeInfo != null) { return typeInfo.freeCountToday; } return 0; } public int GetDailyFreeCount(int type) { return TreasureSetConfig.Get(type).DailyFreeCount; } //获取还需多少次可得幸运奖励 public int GetNextXBCountForBigAward(int type, out List qualityList) { qualityList = new List(); XBTypeInfo typeInfo = GetXBInfoByType(type); if (typeInfo == null) { return 0; } var xbConfig = GetXBItemConfigByType(type); var luckList = xbConfig.LuckyItemRateInfo.Keys.ToList(); luckList.Sort(); //按阶梯显示 for (int i = 0; i < luckList.Count; i++) { if (typeInfo.luckValue < luckList[i]) { //把二维数组里的所有第二个元素组成新列表 qualityList = xbConfig.LuckyItemRateInfo[luckList[i]].Select(x => x[1]).ToList(); qualityList.Sort(); return luckList[i] - typeInfo.luckValue; } } return 0; } public bool CheckIsXBTool(int itemId, int type) { var funcSet = TreasureSetConfig.Get(type); if (funcSet == null) return false; if (funcSet.CostItemID == itemId) { return true; } return false; } public bool IsHaveOneXBTool(int type) { var funcSet = TreasureSetConfig.Get(type); if (funcSet == null) return false; int toolCnt = (int)PackManager.Instance.GetItemCountByID(PackType.Item, funcSet.CostItemID); if (toolCnt >= funcSet.CostItemCountList[0]) { return true; } return false; } //needToolCnt 为配表中需要的道具数量 // 可获得真正需要补足购买道具的金额 public bool IsHaveManyXBToolEx(int type, out int toolCnt, out int needToolCnt, out int needMoney) { toolCnt = 0; needToolCnt = 0; //配置中需要的道具数量 needMoney = 0; //真正需要补足购买道具的金额 var funcSet = TreasureSetConfig.Get(type); if (funcSet == null) return false; toolCnt = (int)PackManager.Instance.GetItemCountByID(PackType.Item, funcSet.CostItemID); needToolCnt = funcSet.CostItemCountList[1]; if (toolCnt >= needToolCnt) { //道具足够 return true; } if (funcSet.CostMoneyType != 0) { if (toolCnt != 0 && toolCnt < needToolCnt) { //部分不足的按单次价格算 needMoney = funcSet.CostMoneyList[0] * (needToolCnt - toolCnt); } else { //全部不足的按多次价格算 可能配置了折扣 needMoney = funcSet.CostMoneyList[1]; } } return false; } public int GetCostType(int type) { var funcSet = TreasureSetConfig.Get(type); if (funcSet == null) return 0; return funcSet.CostMoneyType; } public int GetCostItemID(int type) { var funcSet = TreasureSetConfig.Get(type); if (funcSet == null) return 0; return funcSet.CostItemID; } #region 红点逻辑 public const int HappyXB_RedKey = 203; public const int XBHeroCall1_RedKey = 20300; //武将免费召唤 public const int XBHeroCall10_RedKey = 20301; //武将10召唤 public const int XBHeroCallScore_RedKey = 20302; //武将积分召唤 public Redpoint happyXBRed = new Redpoint(MainRedDot.MainHerosRedpoint, HappyXB_RedKey); public Redpoint bestXBFreeRed = new Redpoint(HappyXB_RedKey, XBHeroCall1_RedKey); public Redpoint bestXB10Red = new Redpoint(HappyXB_RedKey, XBHeroCall10_RedKey); public Redpoint bestXBScoreRed = new Redpoint(HappyXB_RedKey, XBHeroCallScore_RedKey); private void UpdateFuncState(int funcId) { HeroCallRedPoint(); } private void RefreshXBTool(PackType type, int index, int id) { if (type != PackType.Item) return; if (!CheckIsXBTool(id, (int)HappXBTitle.HeroCallAdvanced)) return; HeroCallRedPoint(); } void OnDayEvent() { HeroCallRedPoint(); } //英雄招募 public void HeroCallRedPoint() { if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.HappyFindTreasure)) return; if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Hero)) return; // 免费 10连 积分 bestXB10Red.state = RedPointState.None; bestXBFreeRed.state = RedPointState.None; bestXBScoreRed.state = RedPointState.None; if (IsHaveFreeXB((int)HappXBTitle.HeroCallAdvanced)) { bestXBFreeRed.state = RedPointState.Simple; } if (IsHaveManyXBToolEx((int)HappXBTitle.HeroCallAdvanced, out int xbtoolCnt, out int needtoolCnt, out int needMoney)) { bestXB10Red.state = RedPointState.Simple; return; } //积分足够 if ((InvestModel.Instance.IsInvested(InvestModel.monthCardType) || GetXBInfoByType((int)HappXBTitle.HeroCallScore)?.treasureCount == 0) && UIHelper.GetMoneyCnt(51) >= TreasureSetConfig.Get((int)HappXBTitle.HeroCallScore).CostMoneyList[0]) { bestXBScoreRed.state = RedPointState.Simple; } } //按格子库配置的奖池 获得获取物品 public List GetAllGridLibItemIDByType(int type) { List itemIDListTemp = new List(); foreach (var kv in GetXBItemConfigByType(type).GridLibInfo) { itemIDListTemp.AddRange(TreasureItemLibConfig.GetItemIDList(kv.Value)); } return itemIDListTemp.Distinct().ToList(); } #endregion } public class XBTypeInfo { public int xbType; // 1 极品寻宝 2 符印寻宝 public int luckValue; public int freeCountToday; //今日已免费寻宝次数 public int treasureCount; //已寻宝总次数 public int treasureCountToday; //今日已寻宝总次数 public int treasureCntAward; //累计寻宝次数对应奖励领奖状态,按奖励记录索引二进制记录是否已领取 public Dictionary gridLimitCntDict; //<有限制抽取次数的格子编号,已抽到次数> 有限制抽取次数的格子次数信息 } public class XBGetItem { public int gridIndex; public int itemId; public int count; public DateTime createTime; public void SetModel(int index, int id, int count) { this.gridIndex = index; this.itemId = id; this.count = count; createTime = TimeUtility.ServerNow; } } public enum HappXBTitle { Best = 1, Rune = 2, //Store = 3, //Warehouse = 4, GatherSoul = 4, //聚魂寻宝 Gubao1 = 5, Gubao2 = 6, Gubao3 = 7, Gubao4 = 8, HeroCallNormal = 11, //11-普通招募 HeroCallAdvanced = 12, //12-高级招募 HeroCallScore = 13, //13-积分招募 YunShi1 = 105, YunShi2 = 106, YunShi3 = 107, YunShi4 = 108, }