local Bag_Controller = {} local private = {} local EventSystem = require('Event/EventSystem') --当前道具类型 local _currentShowItemType = 1; --快捷使用弹窗数据key:CfgId Value:{win, Count} local _quickUseItemWinArr; --道具过期销毁检测timer local _expireTimeHandler; --自选金色物品礼包 local SelectGoldenGiftType = { HeroAppearance = 1, -- 武将皮肤 WeaponAppearance = 2, -- 神兵皮肤 Hero = 3, -- 武将 HeroFragment = 4, -- 武将碎片 WeaponAppearanceFragment = 5, -- 神兵碎片、神兵铸图 HorseFragment = 6, -- 坐骑碎片 TearsureFragment = 7, -- 宝物碎片 } function Bag_Controller.OnStartup() EventSystem.Regist(EventID.BagItem_Update, Bag_Controller.RefreshBagRedPoint); EventSystem.Regist(EventID.UI_ActiveTreasureSuccess, Bag_Controller.RefreshBagRedPoint); EventSystem.Regist(EventID.UI_ActiveHorseSuccess, Bag_Controller.RefreshBagRedPoint); _quickUseItemWinArr = {}; private.delayFastApplyPanel = false --道具第一类型事件存储 private.itemFirstTypeEvents = {} private.itemFirstTypeEventsParams = {} --道具第二类型事件存储 private.itemSecondTypeEvents = {} private.itemSecondTypeEventsParams = {} --道具id事件存储 private.itemIdEvents = {} private.itemIdEventsParams = {} private.StartExpireTimer() end function Bag_Controller.OnShutdown() _quickUseItemWinArr = nil; if _expireTimeHandler then TimerUtil.Remove(_expireTimeHandler); _expireTimeHandler = nil; end end --region -- **************** 背包处理相关 ******************* -- function Bag_Controller.OpenUIBagPanel() UIManager.OpenView(Const_UI_Lua.UIEnum.UIBagMain) end function Bag_Controller.SetCurrentShowItemType(type) _currentShowItemType = type; end function Bag_Controller.GetCurrentShowItemType() return _currentShowItemType end function Bag_Controller.GetBagData() return MDL.Bag.GetBagDisplayDataByType(_currentShowItemType) end function private.StartExpireTimer() _expireTimeHandler = TimerUtil.Interval( function() MDL.Bag.CheckExpireItems(); private.StartExcuteExpireItems(); end, 1, 0); end function private.StartExcuteExpireItems() local expireItems = MDL.Bag.GetExpireItems(); if next(expireItems) ~= nil then --请求删除过期道具 MDL.Bag.DiscardOverdueItemReq(); if UIManager.IsViewOpened(Const_UI_Lua.UIEnum.UIBagMain) then Bag_Controller.ShowExpireItemDeleteTips(); end end end function Bag_Controller.ShowExpireItemDeleteTips() local expireItems = MDL.Bag.GetExpireItems(); local deleteItemData; for __, expireItem in pairs(expireItems) do if not deleteItemData then deleteItemData = {} end if not deleteItemData[expireItem.cfgId] then deleteItemData[expireItem.cfgId] = expireItem.count; else deleteItemData[expireItem.cfgId] = deleteItemData[expireItem.cfgId] + expireItem.count; end end if deleteItemData then for cfgId, count in pairs(deleteItemData) do local itemCfgData = DataSheetManager.ItemData:GetDataByID(cfgId); local itemNameAndDesc = UTL.Item.GetItemDataSpliceByType(cfgId); local colorName = UTL.Color.FormatQualityText(itemNameAndDesc.Name, itemCfgData.Color) CTL.Tips.AddTipsMsg(Const_IDS["IDS_Bag_Tips_Overdue"], colorName, count); end MDL.Bag.ClearExpireItems(); end end ---------------------------------快速使用逻辑------------------------------ function Bag_Controller.SetDelayFastApplyPanel(isDelay) private.delayFastApplyPanel = isDelay if private.delayFastApplyPanel then -- 关闭全部快速使用弹窗 UIManager.CloseView(Const_UI_Lua.UIEnum.UIBagItemFastApplyPanel) else -- 遍历显示快捷使用 if _quickUseItemWinArr then for _, v in pairs (_quickUseItemWinArr) do if v.isDelayShow then private.AddQuickUseItem(v.itemCfgId, v.isUse) v.isDelayShow = false end end end end end function Bag_Controller.ShowGainItem(itemId) local isDisplay = CTL.DrawCard.IsDisplayIDSTips(itemId) if not isDisplay then return end if not BattleDataGetter.IsTownLevel() then return end local itemData = DataSheetManager.ItemData:GetDataByID(itemId) if itemData.IsShow and CTL.ItemUse.CanUseItem(nil, itemId, false) then private.AddQuickUseItem(itemId); end end ---isUse----倒计时完后是否自动使用 function private.AddQuickUseItem(itemId, isUse) local itemCount = MDL.Bag.GetItemCount(itemId) if itemCount == 0 then return end if _quickUseItemWinArr[itemId] then _quickUseItemWinArr[itemId].count = itemCount; else _quickUseItemWinArr[itemId] = {itemCfgId = itemId, count = itemCount, isUse = isUse, isDelayShow = false}; end -- 延迟显示快捷使用道具弹窗 if private.delayFastApplyPanel then _quickUseItemWinArr[itemId].isDelayShow = true return end if not _quickUseItemWinArr[itemId].Win then if not UIManager.IsViewOpened(Const_UI_Lua.UIEnum.UIBagItemFastApplyPanel) then UIManager.OpenView(Const_UI_Lua.UIEnum.UIBagItemFastApplyPanel) end EventSystem.Dispatch(EventID.Bag_ItemFastApply, {data = _quickUseItemWinArr[itemId], isUse = isUse}); _quickUseItemWinArr[itemId].Win = true; else EventSystem.Dispatch(EventID.Bag_UpdateQuickUse, _quickUseItemWinArr[itemId]); end end ---isUse----倒计时完后是否自动使用 function Bag_Controller.ShowQuickUseItem(itemId, isUse) if not BattleDataGetter.IsTownLevel() then CTL.HomeMain.AddTownHomeDelayFunc(private.AddQuickUseItem, itemId, isUse) else private.AddQuickUseItem(itemId, isUse) end end function Bag_Controller.DeleteQuickUseItem(itemCfgId) _quickUseItemWinArr[itemCfgId] = nil; end function Bag_Controller.HasQuickUseItem(itemCfgId) return _quickUseItemWinArr[itemCfgId] end function Bag_Controller.CloseAllQuickUseWin() EventSystem.Dispatch(EventID.Bag_UpdateQuickUse, nil); end --------------------------红点相关逻辑------------------------ function Bag_Controller.IsBagFull() for index, tabData in ipairs(MDL.Bag.BagTypeTabData) do if Bag_Controller.IsBagPageMaxNum(tabData.pageType) then return true; end end return false; end function Bag_Controller.IsBagPageMaxNum(pageType) local pageTypeDatas = MDL.Bag.GetItemDataByPageType(pageType); local maxNum = DataSheetManager.ConstData:GetDataByID("BagMaxNum").IntValue; return pageTypeDatas[maxNum] ~= nil; end function Bag_Controller.RefreshBagRedPoint() for index, tabData in ipairs(MDL.Bag.BagTypeTabData) do if Bag_Controller.IsPageHasRedpoint(tabData.pageType) then CTL.RedPoint.AddRedPoint(CTL.RedPoint.RedPointKey.Bag); return; end end CTL.RedPoint.RemoveRedPoint(CTL.RedPoint.RedPointKey.Bag); end --背包分类页签是否有红点 function Bag_Controller.IsPageHasRedpoint(pageType) local pageTypeDatas = MDL.Bag.GetItemDataByPageType(pageType); for __, itemData in ipairs(pageTypeDatas) do if Bag_Controller.IsItemHasRedpoint(itemData) then return true; end end return false; end --背包道具是否有红点 function Bag_Controller.IsItemHasRedpoint(itemData) local itemCfgData= DataSheetManager.ItemData:GetDataByID(itemData.CfgId); if itemCfgData.FirstType == LuaConst.ItemType.GiftBag then return CTL.ItemUse.CanUseItem(itemData) elseif itemCfgData.FirstType == LuaConst.ItemType.HeroFragment then local heroCfgId = Bag_Controller.GetHeroCfgIdByItemId(itemData.CfgId); if heroCfgId > 0 then return MDL.HeroSelect.IsHeroCanActive(heroCfgId); end elseif itemCfgData.FirstType == LuaConst.ItemType.Horse then if not MDL.Unlock.IsUnlock(MDL.Unlock.FunctionType.WarHorse) then return false; end local warHorseId = Bag_Controller.GetWarHorseCfgIdByItemId(itemData.CfgId); if warHorseId > 0 then local warHorseCfgData = DataSheetManager.HorseData:GetDataByHorseID(warHorseId); return CTL.WarHorse.CheckHorseIfEnableActive(warHorseCfgData); end elseif itemCfgData.FirstType == LuaConst.ItemType.Treasure then if not MDL.Unlock.IsUnlock(MDL.Unlock.FunctionType.Treasure) then return false; end local treasureCfgId = Bag_Controller.GetTreasureCfgIdByItemId(itemData.CfgId); if treasureCfgId > 0 then return CTL.Treasure.IfTreasureCanActive(treasureCfgId); end elseif itemCfgData.FirstType == LuaConst.ItemType.Title then return MDL.Unlock.IsUnlock(MDL.Unlock.FunctionType.Title) and itemCfgData.SecondType ==1 elseif itemCfgData.FirstType == LuaConst.ItemType.Portrait then return MDL.Character.IsPortraitHasRedInBag(itemData.CfgId) elseif itemCfgData.FirstType == LuaConst.ItemType.Frame then return MDL.Character.IsFrameHasRedInBag(itemData.CfgId) elseif itemCfgData.FirstType == LuaConst.ItemType.Stratagem then return CTL.Stratagem.FrameIsActiveByItemId(itemData.CfgId) elseif itemCfgData.FirstType == LuaConst.ItemType.Appearance then if itemCfgData.SecondType == MDL.Appearance.AppearanceType.Horse then return CTL.WarHorse.ItemAppearanceInBagHasRed(itemData.CfgId) end elseif itemCfgData.FirstType == LuaConst.ItemType.RechargeGiftBag then return itemCfgData.LimitRequireRechargeScore <= MDL.Currency.GetTotalRechargeCredit() else return Bag_Controller.IsBatchItemById(MDL.Bag.GetBatchItemId(itemData.CfgId)) end return false; end function Bag_Controller.IsBatchItemById(id) local compose = id and DataSheetManager.ItemCompose:GetDataByID(id) or nil if compose then for _, item in ipairs(compose.Item_Table) do local returnCount = MDL.Bag.GetItemCount(item.ItemID) if returnCount < item.ItemNum then return false end end return true end return false end --物品Id反推拿到需要该物品的武将id function Bag_Controller.GetHeroCfgIdByItemId(itemCfgId) local itemCfgData = DataSheetManager.ItemData:GetDataByID(itemCfgId); return itemCfgData.BelongerID or 0; end --itemCfgId拿到装备Id function Bag_Controller.GetEquipCfgIdByItemId(itemCfgId) local itemCfgData = DataSheetManager.ItemData:GetDataByID(itemCfgId); return itemCfgData.BelongerID or 0; end --itemCfgId拿到神兵Id function Bag_Controller.GetMagicWeaponCfgIdByItemId(itemCfgId) local itemCfgData = DataSheetManager.ItemData:GetDataByID(itemCfgId); return itemCfgData.BelongerID or 0; end --itemCfgId拿到战骑Id function Bag_Controller.GetWarHorseCfgIdByItemId(itemCfgId) local itemCfgData = DataSheetManager.ItemData:GetDataByID(itemCfgId); return itemCfgData.BelongerID or 0; end --itemCfgId拿到宝物Id function Bag_Controller.GetTreasureCfgIdByItemId(itemCfgId) local itemCfgData = DataSheetManager.ItemData:GetDataByID(itemCfgId); return itemCfgData.BelongerID or 0; end --道具id得到各个系统的拥有的数量,比如拥有的武器数量,宝石数量等,需要从其他背包获取 function Bag_Controller.GetHasCountByItemCfgID(itemCfgId) local itemCfgData = DataSheetManager.ItemData:GetDataByID(itemCfgId); local returnCount = 0; if itemCfgData.FirstType == LuaConst.ItemType.Gem then local allGems = MDL.GemCompose.GetGemBagDatas(); for __, gemData in pairs(allGems) do if gemData.ItemData.ID == itemCfgData.ID then returnCount = returnCount + gemData.Count; end end elseif itemCfgData.FirstType == LuaConst.ItemType.Equip then local allEquips = MDL.Equipment.GetEquipmentInfoDic(); if allEquips then for __, equipData in pairs(allEquips) do if equipData.EquipData.ID == itemCfgData.ID then returnCount = returnCount + 1; end end end elseif itemCfgData.FirstType == LuaConst.ItemType.EquipDebris then local allEquipDebris = MDL.Equipment.GetDebrisInfoDic(); if allEquipDebris then for __, equipDebris in pairs(allEquipDebris) do if equipDebris.ItemData.ID == itemCfgData.ID then returnCount = returnCount + equipDebris.Num; end end end elseif itemCfgData.FirstType == LuaConst.ItemType.Materials then if itemCfgData.SecondType == LuaConst.ItemMaterialsType.AdvanceMaterials then returnCount = MDL.Currency.GetMoneyCount(itemCfgData.ID); elseif itemCfgData.SecondType == LuaConst.ItemMaterialsType.DragonJade then returnCount = MDL.Currency.GetMoneyCount(itemCfgData.ID); else returnCount = MDL.Bag.GetItemCount(itemCfgData.ID); end elseif itemCfgData.FirstType == LuaConst.ItemType.TeamExp then if itemCfgData.SecondType == LuaConst.ItemTeam.Exp then returnCount = MDL.Player.GetRoleLevelExp(); elseif itemCfgData.SecondType == LuaConst.ItemTeam.Energy then returnCount = MDL.Player.GetEnergyValue(); else returnCount = MDL.Bag.GetItemCount(itemCfgData.ID); end elseif itemCfgData.FirstType == LuaConst.ItemType.Guild then if MDL.Guild.IsHasGuild() then local myGuildInfo = MDL.Guild.GetMyGuildInfo(); if itemCfgData.SecondType == LuaConst.ItemGuildType.Reputation then for i=1, myGuildInfo.listInfo.fameLevel do returnCount = returnCount + DataSheetManager.GuildReputation:GetDataByID(i).Value end returnCount = returnCount + myGuildInfo.listInfo.fameValue; elseif itemCfgData.SecondType == LuaConst.ItemGuildType.Gold then returnCount = myGuildInfo.fund; elseif itemCfgData.SecondType == LuaConst.ItemGuildType.Ingot then returnCount = myGuildInfo.goldIngot; else returnCount = MDL.Bag.GetItemCount(itemCfgData.ID); end end elseif itemCfgData.FirstType == LuaConst.ItemType.SlgGvEMaterial then returnCount = MDL.SlgGvE.GetMaterialNum(itemCfgId) else returnCount = MDL.Bag.GetItemCount(itemCfgData.ID); end return returnCount; end -- 屏蔽自选礼包中未运营的金色品质物品 function Bag_Controller.GetGiftBagItemData(giftBagData) local giftBagItemIdData = {} if giftBagData.Iscover == SelectGoldenGiftType.HeroAppearance then -- 武将皮肤 for _, itemId in ipairs(giftBagData.GiftBagItemID) do local appearanceCfgId = MDL.Appearance.GetAppearanceCfgIdByItemId(itemId) local heroId = DataSheetManager.HeroAppearance:GetDataByID(appearanceCfgId).HeroID if MDL.HideGolden.IsShowGoldenByID(LuaConst.ShowGoldenType.Hero, heroId) then table.insert(giftBagItemIdData, itemId) end end elseif giftBagData.Iscover == SelectGoldenGiftType.WeaponAppearance then -- 神兵皮肤 for _, itemId in ipairs(giftBagData.GiftBagItemID) do local appearanceCfgId = MDL.Appearance.GetAppearanceCfgIdByItemId(itemId) local heroId = DataSheetManager.WeaponAppearance:GetDataByID(appearanceCfgId).HeroID if MDL.HideGolden.IsShowGoldenByID(LuaConst.ShowGoldenType.Hero, heroId) then table.insert(giftBagItemIdData, itemId) end end elseif giftBagData.Iscover == SelectGoldenGiftType.Hero or giftBagData.Iscover == SelectGoldenGiftType.HeroFragment then -- 武将(碎片) for _, itemId in ipairs(giftBagData.GiftBagItemID) do local heroId = Bag_Controller.GetHeroCfgIdByItemId(itemId) if MDL.HideGolden.IsShowGoldenByID(LuaConst.ShowGoldenType.Hero, heroId) then table.insert(giftBagItemIdData, itemId) end end elseif giftBagData.Iscover == SelectGoldenGiftType.WeaponAppearanceFragment then -- 神兵碎片、神兵铸图 for _, itemId in ipairs(giftBagData.GiftBagItemID) do local weaponId = Bag_Controller.GetMagicWeaponCfgIdByItemId(itemId) if MDL.HideGolden.IsShowGoldenByID(LuaConst.ShowGoldenType.Hero, weaponId) then table.insert(giftBagItemIdData, itemId) end end elseif giftBagData.Iscover == SelectGoldenGiftType.HorseFragment then -- 坐骑碎片 for _, itemId in ipairs(giftBagData.GiftBagItemID) do local horseId = Bag_Controller.GetWarHorseCfgIdByItemId(itemId) if MDL.HideGolden.IsShowGoldenByID(LuaConst.ShowGoldenType.Horse, horseId) then table.insert(giftBagItemIdData, itemId) end end elseif giftBagData.Iscover == SelectGoldenGiftType.TearsureFragment then -- 宝物碎片 for _, itemId in ipairs(giftBagData.GiftBagItemID) do local treasureId = Bag_Controller.GetTreasureCfgIdByItemId(itemId) if MDL.HideGolden.IsShowGoldenByID(LuaConst.ShowGoldenType.Treasure, treasureId) then table.insert(giftBagItemIdData, itemId) end end else giftBagItemIdData = giftBagData.GiftBagItemID end return giftBagItemIdData end function private.DispatchItemEventErrorMsg(msg) logging.error(LTAG.ERROR, "DispatchItemEventErrorMsg执行失败", msg) end function Bag_Controller.TryTranslateItem(itemCfgId, giftBagData) if giftBagData.UseableType == LuaConst.ItemGiftBagSelectType.HeroFilter then local isTranslate = true for _, itemId in ipairs(giftBagData.GiftBagItemID) do local itemCfgData = DataSheetManager.ItemData:GetDataByID(itemId); local heroId = itemCfgData.BelongToHero if MDL.HideGolden.IsShowGoldenByID(LuaConst.ShowGoldenType.Hero, heroId) then if not MDL.HeroSelect.IsHasHero(heroId) then isTranslate = false break end end end if isTranslate then MDL.Bag.UseItemByCfgIdReq(itemCfgId, 1, { [1] = { place = 0, count = 1 } }); return true end end return false end --一个占位符,保证Events和EventsParams 数组长度相等 local EmptyTable = {} --根据道具类型注册监听事件,道具第二类型可选 --listener 如果是面板监听self,如果是controller或者model,空 function Bag_Controller.RegisteEventByItemType(itemFirstType, listenCallback, listener, itemSecondType) --用-1表示一个占位符,保证currencyTypeEvents和currencyTypeParams 数组长度相等 if itemSecondType then if not private.itemSecondTypeEvents[itemSecondType] then private.itemSecondTypeEvents[itemSecondType] = {} private.itemSecondTypeEventsParams[itemSecondType] = {} end if not private.itemSecondTypeEvents[itemSecondType][itemFirstType] then private.itemSecondTypeEvents[itemSecondType][itemFirstType] = {} private.itemSecondTypeEventsParams[itemSecondType][itemFirstType] = {} end local secondTypeEventLen = #private.itemSecondTypeEvents[itemSecondType][itemFirstType] private.itemSecondTypeEvents[itemSecondType][itemFirstType][secondTypeEventLen+1] = listenCallback private.itemSecondTypeEventsParams[itemSecondType][itemFirstType][secondTypeEventLen+1] = listener or EmptyTable else if not private.itemFirstTypeEvents[itemFirstType] then private.itemFirstTypeEvents[itemFirstType] = {} private.itemFirstTypeEventsParams[itemFirstType] = {} end local firstTypeEventLen = #private.itemFirstTypeEvents[itemFirstType] private.itemFirstTypeEvents[itemFirstType][firstTypeEventLen+1] = listenCallback private.itemFirstTypeEventsParams[itemFirstType][firstTypeEventLen+1] = listener or EmptyTable end end function private.RemoveEventAndEventParams(eventTable, eventParamTable, index, listener) if listener then if eventParamTable[index] == listener then table.remove(eventTable, index) table.remove(eventParamTable, index) return true end return false elseif eventParamTable[index] == EmptyTable then table.remove(eventTable, index) table.remove(eventParamTable, index) return true end return false end function Bag_Controller.UnRegisteEventByItemType(itemFirstType, listenCallback, listener, itemSecondType) if itemSecondType then if private.itemSecondTypeEvents[itemSecondType] then local secondTypeEventTable = private.itemSecondTypeEvents[itemSecondType][itemFirstType] if secondTypeEventTable then for index, func in ipairs(secondTypeEventTable) do if func == listenCallback then if private.RemoveEventAndEventParams(secondTypeEventTable, private.itemSecondTypeEventsParams[itemSecondType][itemFirstType], index, listener) then break end end end end end elseif private.itemFirstTypeEvents[itemFirstType] then for index, func in ipairs(private.itemFirstTypeEvents[itemFirstType]) do if func == listenCallback then if private.RemoveEventAndEventParams(private.itemFirstTypeEvents[itemFirstType], private.itemFirstTypeEventsParams[itemFirstType], index, listener) then break end end end end end --根据道具id监听道具变化事件 function Bag_Controller.RegisteEventByItemId(itemCfgId, listenCallback, listener) if not private.itemIdEvents[itemCfgId] then private.itemIdEvents[itemCfgId] = {} private.itemIdEventsParams[itemCfgId] = {} end local idEventLen = #private.itemIdEvents[itemCfgId] private.itemIdEvents[itemCfgId][idEventLen+1] = listenCallback private.itemIdEventsParams[itemCfgId][idEventLen+1] = listener or EmptyTable end function Bag_Controller.UnRegisteEventByItemId(itemCfgId, listenCallback, listener) if private.itemIdEvents[itemCfgId] then for index, func in ipairs(private.itemIdEvents[itemCfgId]) do if func == listenCallback then if private.RemoveEventAndEventParams(private.itemIdEvents[itemCfgId], private.itemIdEventsParams[itemCfgId], index, listener) then break end end end end end function Bag_Controller.CheckAndDispatchItemEvent(msgId, itemList) for i = 1, #itemList do local itemCfgId = itemList[i] if private.itemIdEvents[itemCfgId] then for index, func in ipairs(private.itemIdEvents[itemCfgId]) do local itemIdEventListener = private.itemIdEventsParams[itemCfgId][index] if itemIdEventListener ~= EmptyTable then xpcall(func, private.DispatchItemEventErrorMsg, itemIdEventListener, msgId, itemCfgId) else xpcall(func, private.DispatchItemEventErrorMsg, msgId, itemCfgId) end end end local itemCfgData = DataSheetManager.ItemData:GetDataByID(itemCfgId) if private.itemSecondTypeEvents[itemCfgData.SecondType] and private.itemSecondTypeEvents[itemCfgData.SecondType][itemCfgData.FirstType] then for index, func in ipairs(private.itemSecondTypeEvents[itemCfgData.SecondType][itemCfgData.FirstType]) do local itemSecondTypeEventListener = private.itemSecondTypeEventsParams[itemCfgData.SecondType][itemCfgData.FirstType][index] if itemSecondTypeEventListener ~= EmptyTable then xpcall(func, private.DispatchItemEventErrorMsg, itemSecondTypeEventListener, msgId, itemCfgData.FirstType, itemCfgData.SecondType) else xpcall(func, private.DispatchItemEventErrorMsg, msgId, itemCfgData.FirstType, itemCfgData.SecondType) end end end if private.itemFirstTypeEvents[itemCfgData.FirstType] then for index, func in ipairs(private.itemFirstTypeEvents[itemCfgData.FirstType]) do local itemFirstTypeEventListener = private.itemFirstTypeEventsParams[itemCfgData.FirstType][index] if itemFirstTypeEventListener ~= EmptyTable then xpcall(func, private.DispatchItemEventErrorMsg, itemFirstTypeEventListener, msgId, itemCfgData.FirstType) else xpcall(func, private.DispatchItemEventErrorMsg, msgId, itemCfgData.FirstType) end end end end end return Bag_Controller