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

702 lines
18 KiB
Lua
Raw Permalink 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 uiCtrl = require_ex('UI/Panels/Base/UICtrl')
local PANEL_ID = PanelId.GachaWeapon
local GachaStage = {
UIStar = 1,
CloseUp = 2,
Reveal = 3,
}
local StarAnimations = {
[4] = "gacha_char_start_4",
[5] = "gacha_char_start_5",
[6] = "gacha_char_start_6",
}
local StarAudios = {
[4] = "Au_UI_Gacha_Star4_weapon",
[5] = "Au_UI_Gacha_Star5_weapon",
[6] = "Au_UI_Gacha_Star6_weapon",
}
local UIRarityColorConfigName = {
[4] = "RARITY_COLOR_4",
[5] = "RARITY_COLOR_5",
[6] = "RARITY_COLOR_6",
}
local LoopAudios = {
[4] = "Au_UI_Gacha_Weaponshow4",
[5] = "Au_UI_Gacha_Weaponshow5",
[6] = "Au_UI_Gacha_Weaponshow6",
}
local WeaponRootName = {
[GEnums.WeaponType.Sword] = "swordRoot",
[GEnums.WeaponType.Wand] = "wandRoot",
[GEnums.WeaponType.Claymores] = "claymoresRoot",
[GEnums.WeaponType.Lance] = "lanceRoot",
[GEnums.WeaponType.Pistol] = "pistolRoot",
}
GachaWeaponCtrl = HL.Class('GachaWeaponCtrl', uiCtrl.UICtrl)
GachaWeaponCtrl.m_args = HL.Field(HL.Table)
GachaWeaponCtrl.m_curInfo = HL.Field(HL.Table)
GachaWeaponCtrl.m_curIndex = HL.Field(HL.Number) << -1
GachaWeaponCtrl.m_rarityEffect = HL.Field(HL.Table)
GachaWeaponCtrl.m_rarityEffectRoot = HL.Field(Transform)
GachaWeaponCtrl.m_isSkipped = HL.Field(HL.Boolean) << false
GachaWeaponCtrl.m_lastSkipTime = HL.Field(HL.Number) << 0
GachaWeaponCtrl.m_stage = HL.Field(HL.Number) << -1
GachaWeaponCtrl.m_weaponCount = HL.Field(HL.Number) << -1
GachaWeaponCtrl.m_curWeaponType = HL.Field(GEnums.WeaponType)
GachaWeaponCtrl.m_weaponRootCache = HL.Field(HL.Table)
GachaWeaponCtrl.m_curWeaponObjList = HL.Field(HL.Table)
GachaWeaponCtrl.m_modelRequestList = HL.Field(HL.Table)
GachaWeaponCtrl.m_startTimelineCor = HL.Field(HL.Thread)
GachaWeaponCtrl.m_weaponTlInfos = HL.Field(HL.Table)
GachaWeaponCtrl.m_curPlayTlInfo = HL.Field(HL.Table)
GachaWeaponCtrl.m_isInLoopTrack = HL.Field(HL.Boolean) << false
GachaWeaponCtrl.m_updateCheckTlKey = HL.Field(HL.Number) << -1
GachaWeaponCtrl.s_messages = HL.StaticField(HL.Table) << {
}
GachaWeaponCtrl.OnCreate = HL.Override(HL.Any) << function(self, args)
self.view.fullScreenBtn.onClick:AddListener(function()
self:_OnClickScreen()
end)
self.view.skipBtn.onClick:AddListener(function()
self:_Skip()
end)
self.view.transitions.gameObject:SetActive(true)
self.m_args = args
self.m_weaponCount = #self.m_args.weapons
self.m_modelRequestList = {}
self.m_curWeaponObjList = {}
self.view.controllerHintPlaceholder:InitControllerHintPlaceholder({ self.view.inputGroup.groupId })
end
GachaWeaponCtrl._PlayWeaponAt = HL.Method(HL.Number) << function(self, index)
self.m_curIndex = index
self.m_curInfo = self.m_args.weapons[index]
self.m_lastSkipTime = 0
logger.info("GachaWeaponCtrl._PlayWeaponAt", index, self.m_curInfo)
self:_PlayStarAnimationStage()
end
GachaWeaponCtrl._PlayStarAnimationStage = HL.Method() << function(self)
logger.info("GachaWeaponCtrl._PlayStarAnimationStage")
self.m_stage = GachaStage.UIStar
self.view.contentNode.gameObject:SetActive(false)
self.view.starNode.gameObject:SetActive(true)
self.m_phase.m_displayObjItem.view.charInfo3DUI.gameObject:SetActive(false)
self:_HideAllRarityEffect()
local info = self.m_curInfo
local weaponId = info.weaponId
local weaponCfg = Utils.tryGetTableCfg(Tables.weaponBasicTable, weaponId)
local weaponType = weaponCfg.weaponType
self.m_curWeaponType = weaponType
self:_LoadWeaponModelAsset(weaponId, weaponType)
self:_LoadWeaponTimeline()
local rarity = self.m_curInfo.rarity
local ani = StarAnimations[rarity]
self.view.transitions:ResetVideo()
self.view.starNode:Play(ani)
local delayTime = rarity >= 6 and self.view.config["TIMELINE_DELAY_TIME_" .. rarity] or self.view.config["UI_DELAY_TIME_" .. rarity]
local tween = self.view.starNode.curTween
local clipLength = self.view.starNode:GetClipLength(ani)
self.m_startTimelineCor = self:_ClearCoroutine(self.m_startTimelineCor)
self.m_startTimelineCor = self:_StartCoroutine(function()
if rarity < 6 then
local time = self.m_curPlayTlInfo.loopStartTime
self:_SetTimeline(time, false)
end
while true do
coroutine.step()
local tweenProgress = tween:GetValue()
if tweenProgress >= 1 or tweenProgress * clipLength >= delayTime then
if PhaseManager:IsOpen(PhaseId.GachaWeapon) then
if rarity >= 6 then
self:_PlayWeaponCloseUpStage()
else
local time = self.m_curPlayTlInfo.loopStartTime
self:_SetTimeline(time, true)
self:_PlayRevealStage()
end
end
return
end
end
end)
AudioManager.PostEvent(StarAudios[info.rarity])
end
GachaWeaponCtrl._PlayWeaponCloseUpStage = HL.Method() << function(self)
logger.info("GachaWeaponCtrl._PlayWeaponCloseUpStage")
self.m_stage = GachaStage.CloseUp
self.m_startTimelineCor = self:_ClearCoroutine(self.m_startTimelineCor)
self:_SetTimeline(0, true)
self.m_updateCheckTlKey = LuaUpdate:Add("TailTick", function(deltaTime)
self:_TailTickCheckTimelineStartLoop(function()
self:_PlayRevealStage()
end)
end)
end
GachaWeaponCtrl._PlayRevealStage = HL.Method() << function(self)
logger.info("GachaWeaponCtrl._PlayRevealStage")
self.m_stage = GachaStage.Reveal
self.m_startTimelineCor = self:_ClearCoroutine(self.m_startTimelineCor)
local info = self.m_curInfo
local weaponId = info.weaponId
local weaponCfg = Utils.tryGetTableCfg(Tables.weaponBasicTable, weaponId)
local weaponName = UIUtils.getItemName(weaponId)
local weaponTypeName = UIUtils.getItemTypeName(weaponId)
local weaponEngName = weaponCfg.engName
local weaponType = weaponCfg.weaponType
self.view.nameTxt.text = weaponName
self.view.nameShadowTxt.text = weaponName
self.view.professionIcon:LoadSprite(UIConst.UI_SPRITE_WEAPON_EXHIBIT, UIConst.WEAPON_EXHIBIT_WEAPON_TYPE_ICON_PREFIX .. weaponType:ToInt())
self.view.elementTxt.text = weaponTypeName
self.view.newHintNode.gameObject:SetActive(info.isNew)
self.view.starGroup:InitStarGroup(info.rarity)
local extraRewardNode = self.view.extraRewardNode
if info.items and next(info.items) then
local extraCount = #info.items
extraRewardNode.gameObject:SetActive(true)
if not extraRewardNode.m_extraItemCells then
extraRewardNode.m_extraItemCells = UIUtils.genCellCache(extraRewardNode.extraItemCell)
end
extraRewardNode.m_extraItemCells:Refresh(extraCount, function(cell, index)
local bundle = info.items[index]
self:_UpdateItemCell(cell, bundle.id, bundle.count)
end)
else
extraRewardNode.gameObject:SetActive(false)
end
self.view.contentNode.gameObject:SetActive(true)
local ui3d = self.m_phase.m_displayObjItem.view.charInfo3DUI
if ui3d then
ui3d.nameTxt.text = weaponEngName
ui3d.gameObject:SetActive(true)
end
AudioManager.PostEvent(LoopAudios[info.rarity])
local colorName = UIRarityColorConfigName[info.rarity]
self.view.lightImg.color = self.view.config[colorName]
self:_ShowRarityEffect(info.rarity)
if not self.m_isSkipped then
self.view.skipBtn.gameObject:SetActive(self.m_curIndex < self.m_weaponCount)
end
end
GachaWeaponCtrl._JumpToRevealStage = HL.Method() << function(self)
self.m_updateCheckTlKey = LuaUpdate:Remove(self.m_updateCheckTlKey)
local time = self.m_curPlayTlInfo.loopStartTime
self:_SetTimeline(time, true)
self:_PlayRevealStage()
end
GachaWeaponCtrl._SetTimeline = HL.Method(HL.Number, HL.Boolean) << function(self, time, isPlay)
local tlInfo = self.m_curPlayTlInfo
local dir = tlInfo.mainDir
dir.time = time
if isPlay then
dir:Play()
else
dir:Evaluate()
end
end
GachaWeaponCtrl._ShowRarityEffect = HL.Method(HL.Number) << function(self, rarity)
if self.m_rarityEffect == nil then
self:_LoadRarityEffect()
end
for key, obj in pairs(self.m_rarityEffect) do
if key == rarity then
obj:SetActive(true)
else
obj:SetActive(false)
end
end
end
GachaWeaponCtrl._HideAllRarityEffect = HL.Method() << function(self)
if self.m_rarityEffect == nil then
self:_LoadRarityEffect()
end
for _, obj in pairs(self.m_rarityEffect) do
obj:SetActive(false)
end
end
GachaWeaponCtrl._UpdateItemCell = HL.Method(HL.Table, HL.String, HL.Number) << function(self, cell, itemId, count)
local itemData = Tables.itemTable[itemId]
cell.itemIcon:LoadSprite(UIConst.UI_SPRITE_ITEM, itemData.iconId)
cell.countTxt.text = string.format("×%d", count)
cell.rarityImg.color = UIUtils.getItemRarityColor(itemData.rarity)
end
GachaWeaponCtrl._Exit = HL.Method() << function(self)
logger.info("GachaWeaponCtrl._Exit")
local onComplete = self.m_args.onComplete
PhaseManager:ExitPhaseFast(PhaseId.GachaWeapon)
if onComplete then
onComplete()
end
end
GachaWeaponCtrl._InitAllWeaponRoot = HL.Method() << function(self)
self.m_weaponRootCache = {}
for weaponType, rootName in pairs(WeaponRootName) do
local root = self.m_phase.m_displayObjItem.view.weaponRoot[rootName]
if root then
local rootList = self.m_weaponRootCache[weaponType]
if not rootList then
rootList = {}
self.m_weaponRootCache[weaponType] = rootList
end
local subRootCount = root.childCount
if subRootCount <= 0 then
subRootCount = 1
table.insert(rootList, root)
else
for i = 0, subRootCount - 1 do
local child = root:GetChild(i)
table.insert(rootList, child)
end
end
else
logger.error("Not found weapon root, name" .. rootName)
end
end
end
GachaWeaponCtrl._InitAllTimeline = HL.Method() << function(self)
self.m_weaponTlInfos = {}
for weaponType, rootName in pairs(WeaponRootName) do
local cutscene = self.m_phase.m_displayObjItem.view.timelineRoot[rootName]
if cutscene then
local dirInfo = {
tlCutscene = cutscene,
camRoot = nil,
mainDir = nil,
dirList = {},
actorDir = nil,
loopStartTime = 0,
loopEndTime = 0,
}
cutscene.gameObject:SetActive(false)
local rootTrans = cutscene.transform
dirInfo.mainDir = cutscene.director
table.insert(dirInfo.dirList, dirInfo.mainDir)
dirInfo.camRoot = rootTrans:Find("ExternalCamera")
if not dirInfo.camRoot then
logger.error("【武器抽卡】没找到timeline对应相机", dirInfo.actorDir.transform:PathFromRoot())
end
for k = 0, rootTrans.childCount - 1 do
local child = rootTrans:GetChild(k)
if child.name == "Actor" then
local suc, actorDir = child:TryGetComponent(typeof(CS.UnityEngine.Playables.PlayableDirector))
if suc then
dirInfo.actorDir = actorDir
table.insert(dirInfo.dirList, actorDir)
break
else
logger.error("【武器抽卡】没有找到Actor Playable Director武器类型", weaponType)
end
end
end
local suc, timeInfo = CS.Beyond.Gameplay.Core.TimelineUtils.GetClipTimeInfo(dirInfo.actorDir, "Loop Track", "LoopPlayableClip")
if suc then
dirInfo.loopStartTime = timeInfo.x
dirInfo.loopEndTime = timeInfo.y
else
logger.error("【武器抽卡】没找到LoopTrack", dirInfo.actorDir.transform:PathFromRoot())
end
self.m_weaponTlInfos[weaponType] = dirInfo
else
logger.error("Not found weapon timeline root, name" .. rootName)
end
end
end
GachaWeaponCtrl._LoadWeaponModelAsset = HL.Method(HL.String, GEnums.WeaponType) << function(self, weaponId, weaponType)
logger.info("GachaWeaponCtrl._LoadWeaponModelAsset")
local hasValue, modelPath = CS.Beyond.Gameplay.WeaponUtil.TryGetWeaponModelByTemplateId(weaponId, false)
if not hasValue then
logger.error("[武器抽卡] 没找到武器模型路径, id" .. weaponId)
return
end
if self.m_weaponRootCache == nil then
self:_InitAllWeaponRoot()
end
local subRootList = self.m_weaponRootCache[weaponType]
if subRootList == nil then
logger.error("[武器抽卡] subRootList == nil, weaponType:" .. weaponType)
return
end
local subRootCount = #subRootList
for i = 1, subRootCount do
local subRoot = subRootList[i]
self:_LoadModelAsync(i, modelPath, function(modelGo)
table.insert(self.m_curWeaponObjList, modelGo)
modelGo:SetLayerRecursive(UIConst.GACHA_LAYER)
local success, animator = modelGo:TryGetComponent(typeof(CS.UnityEngine.Animator))
if success then
animator.enabled = false
end
local transform = modelGo.transform
transform:SetParent(subRoot)
transform.localPosition = Vector3.zero
transform.localEulerAngles = Vector3.zero
transform.localScale = Vector3.one
end)
end
end
GachaWeaponCtrl._LoadModelAsync = HL.Method(HL.Number, HL.String, HL.Function) << function(self, loadKey, modelPath, callback)
local modelManager = GameInstance.modelManager
local hash = __beyond_calculate_ab_path_hash(modelPath)
local pathHash = CS.Beyond.Resource.StringPathHash(hash)
self.m_modelRequestList[loadKey] = modelManager:LoadAsync(pathHash, function(requestId, path, activeModelGo)
self.m_modelRequestList[loadKey] = nil
if activeModelGo and callback then
callback(activeModelGo)
end
end)
end
GachaWeaponCtrl._LoadWeaponTimeline = HL.Method() << function(self)
if self.m_weaponTlInfos == nil then
self:_InitAllTimeline()
end
if self.m_curPlayTlInfo then
self.m_curPlayTlInfo.tlCutscene.gameObject:SetActive(false)
self.m_curPlayTlInfo = nil
end
local weaponType = self.m_curWeaponType
local tlInfo = self.m_weaponTlInfos[weaponType]
tlInfo.tlCutscene.gameObject:SetActive(true)
self.m_curPlayTlInfo = tlInfo
local transform = self.m_rarityEffectRoot
transform:SetParent(tlInfo.camRoot)
transform.localPosition = Vector3.zero
transform.localEulerAngles = Vector3.zero
transform.localScale = Vector3.one
self:_SetTimeline(0, false)
end
GachaWeaponCtrl._LoadRarityEffect = HL.Method() << function(self)
local displayView = self.m_phase.m_displayObjItem.view
self.m_rarityEffectRoot = displayView.rarityEffectRoot
self.m_rarityEffect = {
[4] = displayView.rarityEffect4.gameObject,
[5] = displayView.rarityEffect5.gameObject,
[6] = displayView.rarityEffect6.gameObject,
}
end
GachaWeaponCtrl._ClearCurAsset = HL.Method() << function(self)
local modelManager = GameInstance.modelManager
for key, obj in pairs(self.m_curWeaponObjList) do
modelManager:Unload(obj)
self.m_curWeaponObjList[key] = nil
end
for key, requestId in pairs(self.m_modelRequestList) do
modelManager:Cancel(requestId)
self.m_modelRequestList[key] = nil
end
end
GachaWeaponCtrl._GoToNext = HL.Method() << function(self)
logger.info("GachaWeaponCtrl._GoToNext")
self:_ClearCurAsset()
local newIndex
for k = self.m_curIndex + 1, self.m_weaponCount do
local info = self.m_args.weapons[k]
if not self.m_isSkipped or info.isNew or info.rarity == UIConst.WEAPON_MAX_RARITY then
newIndex = k
break
end
end
if newIndex then
self:_PlayWeaponAt(newIndex)
else
self:_Exit()
end
end
GachaWeaponCtrl._Skip = HL.Method() << function(self)
logger.info("GachaWeaponCtrl._Skip")
self.m_isSkipped = true
self.view.skipBtn.gameObject:SetActive(false)
if self.m_curInfo.isNew or self.m_curInfo.rarity == UIConst.WEAPON_MAX_RARITY then
self:_OnClickScreen()
else
self:_GoToNext()
end
end
GachaWeaponCtrl._OnClickScreen = HL.Method() << function(self)
if Time.unscaledTime < self.m_lastSkipTime + self.view.config.SKIP_CD then
return
end
logger.info("GachaWeaponCtrl._OnClickScreen", self.m_stage)
if self.m_stage == GachaStage.UIStar then
self.m_lastSkipTime = Time.unscaledTime
self.view.starNode:ClearTween(false)
self.view.starNode.gameObject:SetActive(false)
self:_JumpToRevealStage()
elseif self.m_stage == GachaStage.CloseUp then
self.m_lastSkipTime = Time.unscaledTime
self:_JumpToRevealStage()
elseif self.m_stage == GachaStage.Reveal then
self.m_lastSkipTime = Time.unscaledTime
self:_GoToNext()
end
end
GachaWeaponCtrl._TailTickCheckTimelineStartLoop = HL.Method(HL.Function) << function(self, onBecomeLoop)
if self.m_isInLoopTrack then
return
end
local tlInfo = self.m_curPlayTlInfo
if tlInfo.actorDir.time >= tlInfo.loopStartTime then
onBecomeLoop()
self.m_updateCheckTlKey = LuaUpdate:Remove(self.m_updateCheckTlKey)
end
end
HL.Commit(GachaWeaponCtrl)