Files
Endfield-Data/LuaScripts/UI/Panels/Shop/ShopCtrl.lua
2025-12-02 20:37:18 +07:00

609 lines
17 KiB
Lua

local uiCtrl = require_ex('UI/Panels/Base/UICtrl')
local PANEL_ID = PanelId.Shop
local PHASE_ID = PhaseId.Shop
local shopSystem = GameInstance.player.shopSystem
ShopCtrl = HL.Class('ShopCtrl', uiCtrl.UICtrl)
ShopCtrl.m_shopGroupId = HL.Field(HL.String) << ""
ShopCtrl.m_shopId = HL.Field(HL.String) << ""
ShopCtrl.m_goodsInfos = HL.Field(HL.Table)
ShopCtrl.m_goods = HL.Field(HL.Table)
ShopCtrl.m_soldOut = HL.Field(HL.Table)
ShopCtrl.m_needPlaySoldOut = HL.Field(HL.Table)
ShopCtrl.m_needPlayUnlock = HL.Field(HL.Table)
ShopCtrl.m_waitAnimation = HL.Field(HL.Boolean) << false
ShopCtrl.m_getCellFunc = HL.Field(HL.Function)
ShopCtrl.m_haveControllerTarget = HL.Field(HL.Boolean) << false
ShopCtrl.m_lastBuyGoods = HL.Field(HL.Table)
ShopCtrl.unlockedShopSheets = HL.Field(HL.Table)
ShopCtrl.index2TabCell = HL.Field(HL.Table)
ShopCtrl.m_tabCells = HL.Field(HL.Forward("UIListCache"))
ShopCtrl.m_moneyInfo = HL.Field(HL.Table)
local DEFAULT_DOMAIN = "domain_1"
ShopCtrl.s_messages = HL.StaticField(HL.Table) << {
[MessageConst.ON_SHOP_REFRESH] = '_OnShopRefresh',
[MessageConst.ON_SHOP_FREQUENCY_LIMIT_CHANGE] = 'OnLimitChange',
[MessageConst.ON_SHOP_GOODS_LOCK_CHANGE] = 'OnConditionChange',
[MessageConst.ON_BUY_ITEM_SUCC] = 'OnBuyItemSucc',
[MessageConst.AFTER_ON_BUY_ITEM_SUCC] = 'OnAfterBuyItemSucc',
[MessageConst.SHOP_WAIT_ANIMATION] = 'WaitAnimation',
[MessageConst.SHOW_SHOP_ITEM_POP_UP] = 'SetMoneyCell',
[MessageConst.ON_SHOP_GOODS_CONDITION_REFRESH] = '_OnShopRefresh',
[MessageConst.ON_SHOP_GOODS_MANUAL_REFRESH] = '_OnShopGoodsManualRefresh',
}
ShopCtrl._OnShopRefresh = HL.Virtual() << function(self)
if self.m_waitAnimation then
return
end
self.view.scrollList:SkipGraduallyShow()
self:_RefreshSheetTabs(self.m_shopId)
self.view.scrollList:SkipGraduallyShow()
end
ShopCtrl.OnCreate = HL.Override(HL.Any) << function(self, arg)
self.view.domainTopMoneyTitle.view.closeBtn.onClick:AddListener(function()
AudioAdapter.PostEvent("Au_UI_Menu_ShopPanel_Close")
local isOpen, phase = PhaseManager:IsOpen(PhaseId.Dialog)
if isOpen then
self:Notify(MessageConst.DIALOG_CLOSE_UI, { PANEL_ID, PHASE_ID, 0 })
else
PhaseManager:PopPhase(PHASE_ID)
end
end)
UIManager:ToggleBlockObtainWaysJump("common_shop", true)
self.m_needPlaySoldOut = {}
self.m_needPlayUnlock = {}
self.m_lastBuyGoods = {}
local shopGroupId, shopId
if type(arg) == "table" then
shopGroupId = arg.shopGroupId
shopId = arg.shopId
else
shopGroupId = arg
end
if shopGroupId == nil or type(shopGroupId) ~= "string" then
logger.error(ELogChannel.UI, "打开商店界面参数错误")
return
end
self.m_shopGroupId = shopGroupId
local shopGroupData = shopSystem:GetShopGroupData(self.m_shopGroupId)
local shopGroupTableData = Tables.shopGroupTable[self.m_shopGroupId]
self.m_shopId = shopId or shopGroupData.shopIdList[0]
self.view.domainTopMoneyTitle:SetTitleText(shopGroupTableData.shopGroupName)
local groupUnlock = shopSystem:CheckShopGroupUnlocked(shopGroupId)
local shopUnlock = shopSystem:CheckShopUnlocked(self.m_shopId)
self:_RefreshDomainTopMoneyTitle()
if not groupUnlock or not shopUnlock then
Notify(MessageConst.SHOW_POP_UP,{content = Language.LUA_SHOP_NOT_UNLOCK,hideCancel = true, onConfirm = function()
local isOpen, phase = PhaseManager:IsOpen(PhaseId.Dialog)
if isOpen then
self:Notify(MessageConst.DIALOG_CLOSE_UI, { PANEL_ID, PHASE_ID, 0 })
else
PhaseManager:PopPhase(PHASE_ID)
end
end})
return
end
self.m_getCellFunc = UIUtils.genCachedCellFunction(self.view.scrollList)
self.view.scrollList.onUpdateCell:AddListener(function(obj, index)
self:_RefreshContentCell(self.m_getCellFunc(obj), LuaIndex(index))
end)
local sortOptions = {
{
name = Language.LUA_SHOP_SORT_RARITY,
keys = { "rarity", "sortId", "id" }
},
{
name = Language.LUA_SHOP_SORT_PRICE,
keys = { "price", "sortId", "id" }
},
{
name = Language.LUA_SHOP_SORT_DEFAULT,
keys = { "sortId", "id" },
},
}
self.view.sortNode:InitSortNode(sortOptions, function(data, isIncremental)
self:_ApplySortOption(data, isIncremental)
end, #sortOptions - 1, false, true)
self:_RefreshSheetTabs(self.m_shopId)
self.view.controllerHintPlaceholder:InitControllerHintPlaceholder({self.view.inputGroup.groupId})
end
ShopCtrl.InitShopTabs = HL.Method(HL.String, HL.String) << function(self, shopGroupId, curShopId)
local shopGroupData = GameInstance.player.shopSystem:GetShopGroupData(shopGroupId)
self.unlockedShopSheets = {}
for i, shopId in pairs(shopGroupData.shopIdList) do
local isUnlocked = shopSystem:CheckShopUnlocked(shopId)
local shopTableData = Tables.shopTable[shopId]
if isUnlocked or shopTableData.isShowWhenLock then
table.insert(self.unlockedShopSheets, shopId)
end
end
if #self.unlockedShopSheets > 1 then
self.view.tabKeyHintPrev.gameObject:SetActive(true)
self.view.tabKeyHintPost.gameObject:SetActive(true)
else
self.view.tabKeyHintPrev.gameObject:SetActive(false)
self.view.tabKeyHintPost.gameObject:SetActive(false)
end
self.index2TabCell = {}
self.m_tabCells:Refresh(#self.unlockedShopSheets, function(cell, index)
local shopId = self.unlockedShopSheets[index]
cell.toggle.onValueChanged:RemoveAllListeners()
cell.toggle.onValueChanged:AddListener(function(isOn)
if isOn and curShopId ~= shopId then
AudioAdapter.PostEvent("Au_UI_Toggle_Tab_On")
shopSystem:SetGoodsIdSee()
self:_RefreshSheetTabs(shopId)
end
end)
self.index2TabCell[index] = cell
cell.toggle.isOn = shopId == curShopId
local shopData = Tables.shopTable[shopId]
cell.tabNameText.text = shopData.shopName
cell.tabNameDecoText.text = shopData.shopEnName
cell.tabIconImg:LoadSprite(UIConst.UI_SPRITE_INVENTORY,shopData.iconId)
cell.tabIconDecoImg:LoadSprite(UIConst.UI_SPRITE_INVENTORY,shopData.iconId)
cell.button.onClick:RemoveAllListeners()
cell.button.onClick:AddListener(function()
self:SelectTab(index)
end)
end)
end
ShopCtrl.SelectTab = HL.Method(HL.Number) << function(self, index)
for searchIndex, cell in ipairs(self.index2TabCell) do
cell.toggle.isOn = false
end
if self.index2TabCell[index] then
self.index2TabCell[index].toggle.isOn = true
end
end
ShopCtrl._RefreshDomainTopMoneyTitle = HL.Method() << function(self)
local success, levelBasicInfo = DataManager.levelBasicInfoTable:TryGetValue(GameWorld.worldInfo.curLevelId)
local dataSucc, domainDevData = GameInstance.player.domainDevelopmentSystem.domainDevDataDic:TryGetValue(levelBasicInfo.domainName)
if not dataSucc then
logger.error("DomainGradeCtrl._UpdateMoneyCell cant find domainDevData: ", levelBasicInfo.domainName)
return
end
local goldItemId = domainDevData.domainDataCfg.domainGoldItemId
local maxCount = domainDevData.curLevelData.moneyLimit
self.view.domainTopMoneyTitle.gameObject:SetActive(true)
self.view.domainTopMoneyTitle:InitDomainTopMoneyTitle(goldItemId, maxCount)
local moneyItemCfg = Utils.tryGetTableCfg(Tables.itemTable, goldItemId)
self.m_moneyInfo = {
moneyId = goldItemId,
moneyIcon = moneyItemCfg and moneyItemCfg.iconId or "",
}
end
ShopCtrl._RefreshSheetTabs = HL.Virtual(HL.String) << function(self, curShopId)
self.m_shopId = curShopId
self:_RefreshTimeCountDown()
self.m_tabCells = self.m_tabCells or UIUtils.genCellCache(self.view.marketTabLayout)
self:InitShopTabs(self.m_shopGroupId, self.m_shopId)
local shopTableData = Tables.shopTable[self.m_shopId]
local shopData = shopSystem:GetShopData(self.m_shopId)
self.m_goods = {}
self.m_soldOut = {}
for goodsId, goodsData in pairs(shopData.goodsDic) do
local isUnlocked = shopSystem:CheckGoodsUnlocked(goodsId)
local goodsTableData = Tables.shopGoodsTable[goodsData.goodsTemplateId]
if isUnlocked or goodsTableData.isShowWhenLock then
local itemBundle = UIUtils.getRewardFirstItem(goodsTableData.rewardId)
local itemTableData = Tables.itemTable[itemBundle.id]
local info = {
id = goodsId,
rarity = itemTableData.rarity,
price = goodsTableData.price * goodsData.discount,
sortId = goodsTableData.sortId,
}
if shopSystem:GetRemainCountByGoodsId(self.m_shopId, goodsId) > 0 then
table.insert(self.m_goods, info)
else
table.insert(self.m_soldOut, info)
end
end
end
self:_ApplySortOption()
end
ShopCtrl._ApplySortOption = HL.Method(HL.Opt(HL.Table, HL.Boolean)) << function(self, sortData, isIncremental)
sortData = sortData or self.view.sortNode:GetCurSortData()
if isIncremental == nil then
isIncremental = self.view.sortNode.isIncremental
end
table.sort(self.m_goods, Utils.genSortFunction(sortData.keys, isIncremental))
self.m_goodsInfos = {}
for i, v in ipairs(self.m_goods) do
table.insert(self.m_goodsInfos, v)
end
for i, v in ipairs(self.m_soldOut) do
table.insert(self.m_goodsInfos, v)
end
self:_RefreshContent()
end
ShopCtrl._RefreshContent = HL.Method() << function(self)
self.m_haveControllerTarget = false
self.view.scrollList:UpdateCount(#self.m_goodsInfos)
end
ShopCtrl._RefreshContentCell = HL.Virtual(HL.Any, HL.Number) << function(self, cell, luaIndex)
local goodsId = self.m_goodsInfos[luaIndex].id
local goodsData = shopSystem:GetShopGoodsData(self.m_shopId, goodsId)
local goodsTableData = Tables.shopGoodsTable[goodsData.goodsTemplateId]
local displayItem = UIUtils.getRewardFirstItem(goodsTableData.rewardId)
local remainCount = shopSystem:GetRemainCountByGoodsId(self.m_shopId, goodsId)
if luaIndex == #self.m_goodsInfos and not self.m_haveControllerTarget then
local firstCell = self.m_getCellFunc(1)
if firstCell then
local position = firstCell.gameObject.transform.anchoredPosition
self.view.sortNode.gameObject.transform.anchoredPosition = position
self.view.sortNode.gameObject:SetActive(true)
InputManagerInst.controllerNaviManager:SetTarget(firstCell.view.selectBtn)
self.m_haveControllerTarget = true
end
end
local goodsTplId = goodsData.goodsTemplateId
local _, goodsCfg = Tables.shopGoodsTable:TryGetValue(goodsTplId)
local discount = 1 - goodsData.discount
local discountedRatio = goodsData.discount
local remainLimitCount = shopSystem:GetRemainCountByGoodsId(self.m_shopId, goodsTplId)
local itemBundle = UIUtils.getRewardFirstItem(goodsCfg.rewardId)
local itemId = itemBundle.id
local hasCfg, itemCfg = Tables.itemTable:TryGetValue(itemId)
local goodsInfo = {
shopId = self.m_shopId,
goodsId = goodsId,
originPrice = goodsCfg.price,
discount = discount,
curPrice = lume.round(goodsCfg.price * discountedRatio, 1),
remainLimitCount = remainLimitCount,
refreshType = goodsCfg.limitCountRefreshType,
itemId = itemId,
itemName = itemCfg.name,
itemCount = Utils.getItemCount(itemId, true, true),
itemBundleCount = itemBundle.count,
itemIcon = itemCfg.iconId,
itemRarity = itemCfg.rarity,
moneyId = self.m_moneyInfo.moneyId,
moneyIcon = self.m_moneyInfo.moneyIcon,
remainLimitSort = remainLimitCount == 0 and 1 or 0,
raritySort = -itemCfg.rarity,
priceRatioSort = -discount,
sortId = goodsCfg.sortId,
isLocked = self:CheckGoodsUnlocked(goodsId),
}
cell:InitCommonShopGoodsCellCommonMode(goodsInfo)
end
ShopCtrl.CheckGoodsUnlocked = HL.Virtual(HL.String).Return(HL.Boolean) << function(self, goodsId)
return not shopSystem:CheckGoodsUnlocked(goodsId)
end
ShopCtrl._RefreshTimeCountDown = HL.Virtual() << function(self)
local shopTableData = Tables.shopTable[self.m_shopId]
if shopTableData.shopRefreshCycleType == GEnums.ShopRefreshCycleType.None then
self.view.timeNode.gameObject:SetActiveIfNecessary(false)
else
self.view.timeNode.gameObject:SetActiveIfNecessary(true)
self.view.countDownText:InitCountDownText(self:_CalculateTargetTime(shopTableData.shopRefreshCycleType), function()
self:_RefreshTimeCountDown()
end)
end
end
ShopCtrl._CalculateTargetTime = HL.Method(GEnums.ShopRefreshCycleType).Return(HL.Number) << function(self, refreshCycleType)
local time = self:_CalculateServerTargetTime(refreshCycleType)
return time
end
ShopCtrl._CalculateServerTargetTime = HL.Method(GEnums.ShopRefreshCycleType).Return(HL.Number) << function(self, refreshCycleType)
if refreshCycleType == GEnums.ShopRefreshCycleType.Daily then
return Utils.getNextCommonServerRefreshTime()
elseif refreshCycleType == GEnums.ShopRefreshCycleType.Weekly then
return Utils.getNextWeeklyServerRefreshTime()
elseif refreshCycleType == GEnums.ShopRefreshCycleType.Monthly then
return Utils.getNextMonthlyServerRefreshTime()
end
end
ShopCtrl.OnLimitChange = HL.Method(HL.Any) << function(self, data)
local goods, left
if type(data) == "table" then
goods,left = unpack(data)
end
for i, v in ipairs(self.m_goodsInfos) do
if v.id == goods then
if left == 0 then
table.insert(self.m_needPlaySoldOut, goods)
end
break
end
end
end
ShopCtrl.OnConditionChange = HL.Method(HL.Any) << function(self, data)
local goods, unlock
if type(data) == "table" then
goods,unlock = unpack(data)
end
for i, v in ipairs(self.m_goodsInfos) do
if v.id == goods then
if unlock then
table.insert(self.m_needPlayUnlock, goods)
end
break
end
end
end
ShopCtrl.OnBuyItemSucc = HL.Virtual(HL.Any) << function(self, arg)
local goodsId = arg[1].GoodsId
table.insert(self.m_lastBuyGoods, goodsId)
end
ShopCtrl.OnAfterBuyItemSucc = HL.Virtual() << function(self)
for i, v in ipairs(self.m_goodsInfos) do
for j, id in ipairs(self.m_needPlaySoldOut) do
if v.id == id then
local cell = self.m_getCellFunc(i)
if cell then
cell:PlaySoldOutAnimation()
end
break
end
end
for j, id in ipairs(self.m_needPlayUnlock) do
if v.id == id then
local cell = self.m_getCellFunc(i)
if cell then
cell:PlayUnlockAnimation()
end
end
break
end
end
for i, v in ipairs(self.m_needPlaySoldOut) do
for j, data in ipairs(self.m_goodsInfos) do
if v == data.id then
local cell = self.m_getCellFunc(j)
if cell then
self:_RefreshContentCell(cell, j)
end
end
end
end
for i, v in ipairs(self.m_needPlayUnlock) do
for j, data in ipairs(self.m_goodsInfos) do
if v == data.id then
local cell = self.m_getCellFunc(j)
if cell then
self:_RefreshContentCell(cell, j)
end
end
end
end
self.m_needPlaySoldOut = {}
self.m_needPlayUnlock = {}
for i, v in ipairs(self.m_lastBuyGoods) do
for j, data in ipairs(self.m_goodsInfos) do
if v == data.id then
local cell = self.m_getCellFunc(j)
if cell then
self:_RefreshContentCell(cell, j)
end
end
end
end
self.m_lastBuyGoods = {}
end
ShopCtrl.WaitAnimation = HL.Method(HL.Boolean) << function(self, state)
self.m_waitAnimation = state
end
ShopCtrl.SetMoneyCell = HL.Virtual(HL.Boolean) << function(self, arg)
end
ShopCtrl._OnShopGoodsManualRefresh = HL.Virtual() << function(self)
end
ShopCtrl.OnClose = HL.Override() << function(self)
LuaSystemManager.gachaSystem:UpdateGachaWeaponSettingState()
UIManager:ToggleBlockObtainWaysJump("common_shop", false)
shopSystem:SetGoodsIdSee()
end
HL.Commit(ShopCtrl)