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

774 lines
22 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
local MAX_SHOW_CHAR_INFO_COUNT = 5
local uiCtrl = require_ex('UI/Panels/Base/UICtrl')
local PANEL_ID = PanelId.GachaPool
GachaPoolCtrl = HL.Class('GachaPoolCtrl', uiCtrl.UICtrl)
GachaPoolCtrl.s_messages = HL.StaticField(HL.Table) << {
[MessageConst.ON_GACHA_SUCC] = 'OnGachaSucc',
[MessageConst.ON_GACHA_POOL_INFO_CHANGED] = 'OnGachaPoolInfoChanged',
[MessageConst.ON_GACHA_POOL_ROLE_DATA_CHANGED] = 'OnGachaPoolRoleDataChanged',
[MessageConst.ON_WALLET_CHANGED] = 'OnWalletChanged',
[MessageConst.ON_ITEM_COUNT_CHANGED] = 'OnItemChanged',
[MessageConst.GACHA_POOL_ADD_SHOW_REWARD] = 'AddQueueReward',
[MessageConst.ON_ONE_GACHA_POOL_REWARD_FINISHED] = 'OnOneQueueRewardFinished',
[MessageConst.ON_SYSTEM_DISPLAY_SIZE_CHANGED] = '_OnDisplaySizeChanged',
}
GachaPoolCtrl.m_getCell = HL.Field(HL.Function)
GachaPoolCtrl.m_curPoolId = HL.Field(HL.String) << ''
GachaPoolCtrl.m_pools = HL.Field(HL.Table)
GachaPoolCtrl.m_curIndex = HL.Field(HL.Number) << 1
GachaPoolCtrl.m_poolTabCache = HL.Field(HL.Forward('UIListCache'))
GachaPoolCtrl.m_showRewardFuncQueue = HL.Field(HL.Forward("Queue"))
GachaPoolCtrl.m_queueRewardConfigs = HL.Field(HL.Table)
GachaPoolCtrl.m_curIsShowReward = HL.Field(HL.Boolean) << false
GachaPoolCtrl.OnCreate = HL.Override(HL.Any) << function(self, arg)
self.m_phase = arg and arg.phase or nil
self:_InitUI()
self:_InitData(arg.poolId)
self:_StartCoroutine(function()
while true do
coroutine.wait(UIConst.COMMON_UI_TIME_UPDATE_INTERVAL)
local cell = self.m_getCell(self.m_curIndex)
if cell then
self:_UpdateRemainingTime(cell.node, self.m_curIndex)
end
end
end)
end
GachaPoolCtrl.OnShow = HL.Override() << function(self)
local time = Time.unscaledTime
self.loader:LoadGameObjectAsync("Assets/Beyond/DynamicAssets/Gameplay/Prefabs/Gacha/GachaOutside.prefab", function()
logger.info("GachaOutside 预载完成", Time.unscaledTime - time)
end)
self.loader:LoadGameObjectAsync("Assets/Beyond/DynamicAssets/Gameplay/Prefabs/Gacha/GachaRoom.prefab", function()
logger.info("GachaRoom 预载完成", Time.unscaledTime - time)
end)
logger.info("GachaPoolCtrl.OnShow")
self:_OnTestimonialConvert()
local count = self.view.poolList.count
for i = 1, count do
local cell = self.m_getCell(i)
if cell then
InputManagerInst:ToggleGroup(cell.node.inputGroup.groupId, self.m_curIndex == i)
end
end
self:_TryShowQueueReward()
local cell = self.m_poolTabCache:Get(self.m_curIndex)
if cell then
UIUtils.setAsNaviTargetInSilentModeIfNecessary(self.view.poolTabNodeNaviGroup, cell.toggle)
end
local poolCell = self.m_getCell(self.m_curIndex)
if poolCell then
poolCell.cellWidget:PlayGachaScrollInAni()
end
self:OnItemChanged()
end
GachaPoolCtrl.OnHide = HL.Override() << function(self)
self.view.moneyNode.naviGroup:ManuallyStopFocus()
end
GachaPoolCtrl.OnClose = HL.Override() << function(self)
GameInstance.player.charBag:ClearAllClientCharAndItemData()
end
GachaPoolCtrl._OnPlayAnimationOut = HL.Override() << function(self)
GachaPoolCtrl.Super._OnPlayAnimationOut(self)
LuaSystemManager.gachaSystem:UpdateGachaSettingState()
local cell = self.m_getCell(self.m_curIndex)
if cell then
cell.cellWidget:PlayGachaOutAni()
end
end
GachaPoolCtrl._InitData = HL.Method(HL.Opt(HL.String)) << function(self, poolId)
self.m_curIndex = 1
local targetIndex = 1
self.m_pools = {}
local csGacha = GameInstance.player.gacha
for id, csInfo in pairs(csGacha.poolInfos) do
if csInfo.isChar and csInfo.isOpenValid then
local info = {
id = id,
csInfo = csInfo,
data = csInfo.data,
sortId = csInfo.data.sortId,
}
table.insert(self.m_pools, info)
end
end
table.sort(self.m_pools, Utils.genSortFunction({ "sortId" }, true))
local count = #self.m_pools
self.m_poolTabCache:Refresh(count, function(cell, index)
if poolId and self.m_pools[index].id == poolId then
targetIndex = index
end
self:_UpdateTabCell(cell, index)
end)
self.view.poolList:UpdateCount(count)
self.view.poolList:ScrollToIndex(CSIndex(targetIndex), true)
self:_InitRewardQueueConfigs()
end
GachaPoolCtrl._InitUI = HL.Method() << function(self)
self.view.closeBtn.onClick:AddListener(function()
PhaseManager:PopPhase(PhaseId.GachaPool)
end)
self:BindInputPlayerAction("common_open_gacha", function()
PhaseManager:PopPhase(PhaseId.GachaPool)
end, self.view.closeBtn.groupId)
self.view.weaponShopBtn.onClick:AddListener(function()
Utils.jumpToSystem("jump_payshop_weapon")
end)
self.m_poolTabCache = UIUtils.genCellCache(self.view.poolTabCell)
self.m_getCell = UIUtils.genCachedCellFunction(self.view.poolList)
self.view.poolList.onUpdateCell:AddListener(function(obj, csIndex)
self:_OnUpdateCell(self.m_getCell(obj), LuaIndex(csIndex))
end)
self.view.poolList.onCenterIndexChanged:AddListener(function(oldIndex, newIndex)
self:_OnCenterIndexChanged(LuaIndex(newIndex))
end)
self.view.controllerHintPlaceholder:InitControllerHintPlaceholder({ self.view.inputGroup.groupId })
self:_InitMoneyNode()
self.m_showRewardFuncQueue = require_ex("Common/Utils/DataStructure/Queue")()
self.view.moneyNode.naviGroup.getDefaultSelectableFunc = function()
local cell = self.view.moneyNode.diamond
return cell.view.button
end
end
GachaPoolCtrl._UpdateTabCell = HL.Method(HL.Table, HL.Number) << function(self, cell, index)
local info = self.m_pools[index]
local poolTypeData = Tables.gachaCharPoolTypeTable[info.data.type]
cell.nameTxt.text = poolTypeData.tagName
cell.nameTxt.color = UIUtils.getColorByString(info.data.textColor)
cell.nameBG.color = UIUtils.getColorByString(info.data.color)
cell.shadowImg.color = UIUtils.getColorByString(info.data.tabGradientColor, cell.shadowImg.color.a * 255)
cell.selectDeco.color = UIUtils.getColorByString(info.data.tabGradientColor)
cell.bannerImg:LoadSprite(UIConst.UI_SPRITE_GACHA_POOL, info.data.tabImage)
cell.selectStateCtrl:SetState("Unselect")
cell.toggle.onValueChanged:RemoveAllListeners()
cell.toggle.onValueChanged:AddListener(function(isOn)
if self.m_curIndex == index then
return
end
if isOn then
self.view.poolList:ScrollToIndex(CSIndex(index), true)
local poolNodeCell = self.m_getCell(index)
if poolNodeCell then
poolNodeCell.cellWidget:PlayGachaChangeTabInAni()
end
end
end)
cell.gameObject.name = info.data.type:ToString()
cell.redDot:InitRedDot("GachaSinglePool", info.id)
end
GachaPoolCtrl._OnCenterIndexChanged = HL.Method(HL.Number) << function(self, index)
logger.info("GachaPoolCtrl._OnCenterIndexChanged", index)
local info = self.m_pools[index]
local preIndex = self.m_curIndex
self.m_curIndex = index
self.m_curPoolId = info.id
local preTabCell = self.m_poolTabCache:Get(preIndex)
local nowTabCell = self.m_poolTabCache:Get(index)
if preTabCell then
preTabCell.selectStateCtrl:SetState("Unselect")
end
if nowTabCell then
nowTabCell.selectStateCtrl:SetState("Select")
nowTabCell.toggle:SetIsOnWithoutNotify(true)
end
local prePoolCell = self.m_getCell(preIndex)
if prePoolCell then
InputManagerInst:ToggleGroup(prePoolCell.node.inputGroup.groupId, false)
prePoolCell.cellWidget:PlayGachaScrollOutAni()
end
local cell = self.m_getCell(self.m_curIndex)
if cell then
self:_OnUpdateCell(cell, self.m_curIndex)
cell.cellWidget:UpdateMoneyNode(self.view.moneyNode)
RedDotUtils.setGachaSinglePoolRead(self.m_curPoolId)
cell.cellWidget:PlayGachaScrollInAni()
InputManagerInst:ToggleGroup(cell.node.inputGroup.groupId, true)
end
if self.view.poolList.centerIndex ~= CSIndex(index) then
self.view.poolList:ScrollToIndex(CSIndex(index))
end
end
GachaPoolCtrl._OnUpdateCell = HL.Method(HL.Table, HL.Number) << function(self, cell, index)
if cell.m_lastUpdateFrame and cell.m_lastUpdateFrame == Time.frameCount then
return
end
cell.m_lastUpdateFrame = Time.frameCount
logger.info("GachaPoolCtrl._OnUpdateCell", index)
local poolInfo = self.m_pools[index]
local poolData = Tables.gachaCharPoolTable[poolInfo.id]
local uiPrefabName = poolData.uiPrefab
if cell.uiPrefabName ~= uiPrefabName then
if cell.node then
GameObject.Destroy(cell.node.gameObject)
end
local path = string.format("Assets/Beyond/DynamicAssets/Gameplay/UI/Prefabs/Gacha/Widgets/%s.prefab", uiPrefabName)
local prefab = self.m_phase.m_resourceLoader:LoadGameObject(path)
local obj = CSUtils.CreateObject(prefab, cell.transform)
obj.name = poolData.type:ToString()
cell.uiPrefabName = uiPrefabName
local poolCellWidget = Utils.wrapLuaNode(obj)
poolCellWidget:InitGachaPoolCell(poolInfo.id)
cell.cellWidget = poolCellWidget
cell.node = poolCellWidget.view
InputManagerInst:ToggleGroup(cell.node.inputGroup.groupId, false)
end
local node = cell.node
cell.cellWidget:UpdateGachaPoolCell()
if self.m_curIndex == index then
cell.cellWidget:CheckAndShowSpecialRewardPopup()
end
if node.nameMainImg then
node.nameMainImg:LoadSprite(UIConst.UI_SPRITE_GACHA_POOL, poolData.nameImage)
end
node.detailNode.gameObject:SetActive(not GameInstance.player.gameSettingSystem.forbiddenWebView)
node.detailBtn.onClick:RemoveAllListeners()
node.detailBtn.onClick:AddListener(function()
self:_ShowDetailPanel()
end)
local endTime = poolInfo.csInfo.closeTime
if node.endTimeTxt then
node.endTimeTxt.text = Utils.appendUTC(Utils.timestampToDateMDHM(endTime))
end
self:_UpdateRemainingTime(node, index)
local upCharIdsCS = poolData.upCharIds
for k = 1, MAX_SHOW_CHAR_INFO_COUNT do
local btnNode = node["showCharInfoBtn" .. k]
if btnNode then
if btnNode.config then
self:_UpdateShowCharInfoBtn(btnNode, btnNode.config.CHAR_ID)
else
self:_UpdateShowCharInfoBtn(btnNode, upCharIdsCS[CSIndex(k)])
end
end
end
if node.previewRoleBtn then
node.previewRoleBtn.onClick:RemoveAllListeners()
node.previewRoleBtn.onClick:AddListener(function()
self:_ShowUpCharInfo()
end)
end
end
GachaPoolCtrl._UpdateRemainingTime = HL.Method(HL.Table, HL.Number) << function(self, node, index)
if node.remainingTimeTxt then
local poolInfo = self.m_pools[index]
local endTime = poolInfo.csInfo.closeTime
local curServerTime = DateTimeUtils.GetCurrentTimestampBySeconds()
local diffTime = math.max(0, endTime - curServerTime)
node.remainingTimeTxt.text = string.format(Language.LUA_GACHA_REMAINING_TIME, UIUtils.getShortLeftTime(diffTime))
end
end
GachaPoolCtrl._UpdateShowCharInfoBtn = HL.Method(HL.Table, HL.String) << function(self, node, charId)
if node.button then
node.button.onClick:RemoveAllListeners()
node.button.onClick:AddListener(function()
self:_ShowUpCharInfo(charId)
end)
end
local charCfg = Tables.characterTable[charId]
if node.nameTxt then
node.nameTxt.text = charCfg.name
end
if node.professionIcon then
node.professionIcon:LoadSprite(UIConst.UI_SPRITE_CHAR_PROFESSION, CharInfoUtils.getCharProfessionIconName(charCfg.profession))
end
if node.starGroup then
node.starGroup:InitStarGroup(charCfg.rarity)
end
if node.headIcon then
node.headIcon:LoadSprite(UIConst.UI_SPRITE_ROUND_CHAR_HEAD, UIConst.UI_ROUND_CHAR_HEAD_PREFIX .. charCfg.charId)
end
end
GachaPoolCtrl._ShowUpCharInfo = HL.Method(HL.Opt(HL.String)) << function(self, charId)
if PhaseManager:IsOpen(PhaseId.CharInfo) then
Notify(MessageConst.SHOW_TOAST, Language.LUA_GACHA_RESULT_OPEN_CHAR_INFO_FAIL)
return
end
local poolData = Tables.gachaCharPoolTable[self.m_curPoolId]
local idsCS = poolData.upCharIds
local ids = {}
if idsCS.Count == 0 then
local contentData = Tables.gachaCharPoolContentTable[self.m_curPoolId]
for _, v in pairs(contentData.list) do
local id = v.charId
local charData = Tables.characterTable[id]
if charData.rarity == UIConst.CHAR_MAX_RARITY then
table.insert(ids, id)
end
end
table.sort(ids)
else
for _, v in pairs(idsCS) do
table.insert(ids, v)
end
end
if string.isEmpty(charId) then
charId = ids[1]
end
local curCharInfo
local charInstIdList = {}
for _, id in ipairs(ids) do
local info = GameInstance.player.charBag:CreateClientInitialGachaPoolChar(id)
if id == charId then
curCharInfo = info
end
table.insert(charInstIdList, info.instId)
end
if not curCharInfo then
return
end
logger.info("charInstIdList", charInstIdList)
local curMaxCharInfo
local maxCharInstIdList = {}
for _, id in ipairs(ids) do
local info = GameInstance.player.charBag:CreateClientPerfectGachaPoolCharInfo(id)
if id == charId then
curMaxCharInfo = info
end
table.insert(maxCharInstIdList, info.instId)
end
if not curMaxCharInfo then
return
end
PhaseManager:OpenPhase(PhaseId.CharInfo, {
initCharInfo = {
instId = curCharInfo.instId,
templateId = charId,
charInstIdList = charInstIdList,
maxCharInstIdList = maxCharInstIdList,
isShowPreview = true,
},
})
end
GachaPoolCtrl._InitMoneyNode = HL.Method() << function(self)
local moneyNode = self.view.moneyNode
local originiumItemCfg = Tables.itemTable:GetValue(Tables.globalConst.originiumItemId)
local diamondItemCfg = Tables.itemTable:GetValue(Tables.globalConst.diamondItemId)
moneyNode.diamond:InitMoneyCell(Tables.globalConst.diamondItemId)
moneyNode.diamond.view.addBtn.onClick:AddListener(function()
moneyNode.naviGroup:ManuallyStopFocus()
end)
moneyNode.originiumConvertedDiamond.icon:LoadSprite(UIConst.UI_SPRITE_WALLET, originiumItemCfg.iconId)
moneyNode.originiumConvertedDiamond.icon2:LoadSprite(UIConst.UI_SPRITE_WALLET, diamondItemCfg.iconId)
moneyNode.originiumConvertedDiamond.button.onClick:AddListener(function()
local curIsShow = moneyNode.originiumConvertedDiamond.selected.gameObject.activeSelf
if curIsShow then
moneyNode.originiumConvertedDiamond.selected.gameObject:SetActive(false)
Notify(MessageConst.HIDE_ITEM_TIPS)
return
end
moneyNode.originiumConvertedDiamond.selected.gameObject:SetActive(true)
Notify(MessageConst.SHOW_ITEM_TIPS, {
transform = moneyNode.originiumConvertedDiamond.transform,
posType = UIConst.UI_TIPS_POS_TYPE.MidBottom,
itemId = Tables.globalConst.originiumItemId,
isSideTips = true,
padding = { top = 100 },
onClose = function()
if not moneyNode or not moneyNode.originiumConvertedDiamond then
return
end
moneyNode.originiumConvertedDiamond.selected.gameObject:SetActive(false)
end
})
end)
end
GachaPoolCtrl.OnWalletChanged = HL.Method(HL.Opt(HL.Any)) << function(self, _)
local cell = self.m_getCell(self.m_curIndex)
if not cell or string.isEmpty(self.m_curPoolId) then
return
end
cell.cellWidget:UpdateMoneyNodeOnlyMoney(self.view.moneyNode)
cell.cellWidget:UpdateGachaBtnCost()
end
GachaPoolCtrl.OnItemChanged = HL.Method(HL.Opt(HL.Any)) << function(self, _)
local cell = self.m_getCell(self.m_curIndex)
if not cell or string.isEmpty(self.m_curPoolId) then
return
end
cell.cellWidget:UpdateMoneyNodeOnlyGachaTicket(self.view.moneyNode)
cell.cellWidget:UpdateGachaBtnCost()
end
GachaPoolCtrl.OnGachaPoolInfoChanged = HL.Method() << function(self)
end
GachaPoolCtrl.OnGachaPoolRoleDataChanged = HL.Method() << function(self)
end
GachaPoolCtrl._ShowDetailPanel = HL.Method() << function(self)
CS.Beyond.SDK.SDKUtils.OpenHGWebPortalSDK("gacha_char", string.format("{\"pool_id\":\"%s\"}",self.m_curPoolId), nil)
end
GachaPoolCtrl._OnTestimonialConvert = HL.Method() << function(self)
local csGachaSystem = GameInstance.player.gacha
local count = csGachaSystem.testimonialConvertNtfs.Count
if count > 0 then
local ntf = csGachaSystem.testimonialConvertNtfs[0]
local name1 = Tables.itemTable[ntf.TestimonialItemId].name
local name2 = Tables.itemTable[ntf.ConvertToItemId].name
local tips = string.format(Language.LUA_GACHA_ITEM_CONVERT_TIP, name1, name2)
local arg = {
queueRewardType = "TestimonialConvert",
showRewardFunc = function()
UIManager:Open(PanelId.GachaItemConvert, {
title = Language.LUA_GACHA_ITEM_CONVERT_TITLE_TESTIMONIAL,
tipsText = tips,
originalItemId = ntf.TestimonialItemId,
convertItemId= ntf.ConvertToItemId,
onComplete = function()
csGachaSystem:SetTestimonialConvertNtfIsCheck(0)
Notify(MessageConst.ON_ONE_GACHA_POOL_REWARD_FINISHED)
end
})
end
}
Notify(MessageConst.GACHA_POOL_ADD_SHOW_REWARD, arg)
end
end
GachaPoolCtrl.OnGachaSucc = HL.Method(HL.Table) << function(self, arg)
local msg = unpack(arg)
if msg.GachaPoolId ~= self.m_curPoolId then
return
end
local chars = {}
for k = 0, msg.FinalResults.Count - 1 do
local v = msg.FinalResults[k]
local charId = msg.OriResultIds[k]
local isNew = not string.isEmpty(v.ItemId)
local items = {}
for kk = 0, v.RewardIds.Count - 1 do
local rewardId = v.RewardIds[kk]
UIUtils.getRewardItems(rewardId, items)
end
if not string.isEmpty(v.RewardItemId) then
table.insert(items, 2, { id = v.RewardItemId, count = 1 })
end
table.insert(chars, {
charId = charId,
isNew = isNew,
items = items,
rarity = Tables.characterTable[charId].rarity,
})
end
logger.info("OnGachaSucc", chars)
LuaSystemManager.gachaSystem:UpdateGachaSettingState()
local isOpen = PhaseManager:OpenPhaseFast(PhaseId.GachaDropBin, {
chars = chars,
onComplete = function()
PhaseManager:OpenPhaseFast(PhaseId.GachaChar, {
fromGacha = true,
chars = chars,
onComplete = function()
if self.m_pools[self.m_curIndex].csInfo.isClosed then
self:_InitData()
else
if not IsNull(self.view.poolList) then
local cell = self.m_getCell(self.m_curIndex)
if cell then
self:_OnUpdateCell(cell, self.m_curIndex)
end
end
end
end
})
end
})
if isOpen then
Notify(MessageConst.ON_DISABLE_ACHIEVEMENT_TOAST, UIConst.ACHIEVEMENT_TOAST_DISABLE_KEY.GachaChar)
end
end
GachaPoolCtrl._InitRewardQueueConfigs = HL.Method() << function(self)
self.m_queueRewardConfigs = {
GachaResultReward = {
order = -100,
},
PotentialReward = {
order = 0,
},
TestimonialReward = {
order = 10,
},
TestimonialConvert = {
order = 11,
},
}
end
GachaPoolCtrl.AddQueueReward = HL.Method(HL.Table) << function(self, arg)
logger.info("GachaPoolCtrl.AddQueueReward" .. arg.queueRewardType)
self.m_showRewardFuncQueue:Push({
order = self.m_queueRewardConfigs[arg.queueRewardType].order,
showRewardFunc = arg.showRewardFunc
})
self.m_showRewardFuncQueue:Sort(function(x, y)
return x.order < y.order
end)
end
GachaPoolCtrl._TryShowQueueReward = HL.Method() << function(self)
if self.m_showRewardFuncQueue:Count() > 0 and not self.m_curIsShowReward then
self.m_curIsShowReward = true
local queueData = self.m_showRewardFuncQueue:Pop()
queueData.showRewardFunc()
end
end
GachaPoolCtrl.OnOneQueueRewardFinished = HL.Method() << function(self)
self.m_curIsShowReward = false
self:_TryShowQueueReward()
end
GachaPoolCtrl._OnDisplaySizeChanged = HL.Method() << function(self)
self:_StartCoroutine(function()
coroutine.waitForRenderDone()
coroutine.step()
coroutine.step()
self.view.poolList:TryRecalculateSize()
self.view.poolList:ScrollToIndex(CSIndex(self.m_curIndex), true)
end)
end
GachaPoolCtrl.OnPhaseRefresh = HL.Override(HL.Any) << function(self, arg)
if not arg or not arg.poolId then
return
end
local count = #self.m_pools
for index = 1, count do
if self.m_pools[index].id == arg.poolId then
self.view.poolList:ScrollToIndex(CSIndex(index), true)
return
end
end
end
HL.Commit(GachaPoolCtrl)