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

357 lines
9.0 KiB
Lua

local uiCtrl = require_ex('UI/Panels/Base/UICtrl')
local PANEL_ID = PanelId.DungeonCharTutorialStepHud
local StepNodeState = {
Normal = "Normal",
Succ = "Succ",
Fail = "Fail",
}
local StepState = {
Fail = 0,
Succ = 1,
}
local Phase = {
Normal = 1,
Fail = 2,
CompleteMainGoal = 3,
CompleteAllGoal = 4,
}
local StepNodeAnim = {
Cur = "actionstepnormal_loop",
Succ = "actionstepnormal_succ",
Fail = "actionstepnormal_fail",
}
DungeonCharTutorialStepHudCtrl = HL.Class('DungeonCharTutorialStepHudCtrl', uiCtrl.UICtrl)
DungeonCharTutorialStepHudCtrl.m_dungeonId = HL.Field(HL.String) << ""
DungeonCharTutorialStepHudCtrl.m_curStage = HL.Field(HL.Number) << 0
DungeonCharTutorialStepHudCtrl.m_curStep = HL.Field(HL.Number) << 0
DungeonCharTutorialStepHudCtrl.m_curStepIds = HL.Field(HL.Any)
DungeonCharTutorialStepHudCtrl.m_actionStepCellCached = HL.Field(HL.Forward("UIListCache"))
DungeonCharTutorialStepHudCtrl.m_failResetCor = HL.Field(HL.Thread)
DungeonCharTutorialStepHudCtrl.m_inFailCor = HL.Field(HL.Boolean) << false
DungeonCharTutorialStepHudCtrl.m_succScrollCor = HL.Field(HL.Thread)
DungeonCharTutorialStepHudCtrl.OnDungeonGameStart = HL.StaticMethod(HL.Table) << function(args)
local dungeonId = unpack(args)
if not DungeonUtils.isDungeonCharTutorial(dungeonId) then
return
end
UIManager:Open(PANEL_ID, dungeonId)
end
DungeonCharTutorialStepHudCtrl.OpenCharTutorialStepHud = HL.StaticMethod(HL.Table) << function(args)
local dungeonId = unpack(args)
if string.isEmpty(dungeonId) then
dungeonId = GameInstance.dungeonManager.curDungeonId
end
if not Tables.dungeonCharTutorialTable:ContainsKey(dungeonId) then
return
end
UIManager:Open(PANEL_ID, dungeonId)
end
DungeonCharTutorialStepHudCtrl.s_messages = HL.StaticField(HL.Table) << {
[MessageConst.ON_CHAR_TUTORIAL_STEP_STATE_CHANGE] = 'OnTutorialStepStateChangeV2',
[MessageConst.ON_SUB_GAME_FINISH_STATE_CHANGE] = "OnSubGameFinishStateChange",
[MessageConst.ON_SUB_GAME_STAGE_CHANGE] = "OnSubGameStageChange",
[MessageConst.ON_SUB_GAME_STAGE_CHANGE_FINISH] = "OnSubGameStageChangeFinish",
[MessageConst.LEVEL_SCRIPT_PUSH_STAGE] = "OnLevelScriptPushStage",
[MessageConst.TOGGLE_CHAR_TUTORIAL_STEP_HUD] = "ToggleCharTutorialStepHUD",
[MessageConst.ON_SUB_GAME_RESET] = "OnSubGameReset",
}
DungeonCharTutorialStepHudCtrl.OnCreate = HL.Override(HL.Any) << function(self, arg)
self.m_actionStepCellCached = UIUtils.genCellCache(self.view.actionStepCell)
self.m_dungeonId = arg
self:_RefreshStage()
end
DungeonCharTutorialStepHudCtrl.OnTutorialStepStateChangeV2 = HL.Method(HL.Any) << function(self, arg)
local step, state, needResetStep = unpack(arg)
logger.warn("[char tutorial] step:", step, "state:", state, "needResetStep:", needResetStep)
if state == StepState.Fail then
local curStepCell = self.m_actionStepCellCached:Get(self.m_curStep)
curStepCell.animationWrapper:Play(StepNodeAnim.Fail)
AudioAdapter.PostEvent("Au_UI_Mission_TrainError")
if needResetStep then
local waitTime = curStepCell.animationWrapper:GetClipLength(StepNodeAnim.Fail)
self.m_curStep = 1
self.m_inFailCor = true
self.m_failResetCor = self:_StartCoroutine( function()
coroutine.wait(waitTime)
self:_RefreshStage()
self.m_inFailCor = false
end)
else
self:_StartTimer(self.view.config.SHOW_RESET_HINT_TIME_DELAY,function()
self:_ToggleResetHintNode(true)
end)
end
else
local totalSteps = self.m_curStepIds.Count
for i = 1, totalSteps do
local stepCell = self.m_actionStepCellCached:Get(i)
local percent
if i < step then
percent = 1
elseif i > step then
percent = 0
end
stepCell.animationWrapper:SampleClipAtPercent(StepNodeAnim.Succ, percent)
stepCell.imageSelect.gameObject:SetActive(false)
end
local curStepCell = self.m_actionStepCellCached:Get(step)
curStepCell.animationWrapper:SampleClipAtPercent(StepNodeAnim.Cur, 0)
curStepCell.animationWrapper:Play(StepNodeAnim.Succ)
self.view.actionStepScrollView:AutoScrollToRectTransform(curStepCell.transform, true)
AudioAdapter.PostEvent("Au_UI_Mission_TrainStep_Complete")
if step < totalSteps then
local nextStep = step + 1
local nextCell = self.m_actionStepCellCached:Get(nextStep)
nextCell.animationWrapper:Play(StepNodeAnim.Cur)
nextCell.imageSelect.gameObject:SetActive(true)
local succTime = curStepCell and curStepCell.animationWrapper:GetClipLength(StepNodeAnim.Succ) or 0.1
self.m_curStep = nextStep
self.view.actionStepScrollView:AutoScrollToRectTransform(nextCell.transform)
end
end
self:_UpdateStepDesc()
end
DungeonCharTutorialStepHudCtrl.OnSubGameFinishStateChange = HL.Method(HL.Any) << function(self, args)
local _, phase = unpack(args)
self.view.finishNode.gameObject:SetActive(phase == Phase.CompleteAllGoal or phase == Phase.CompleteMainGoal)
self.view.stepDescNode.gameObject:SetActive(phase == Phase.Normal or phase == Phase.Fail)
end
DungeonCharTutorialStepHudCtrl.OnSubGameStageChange = HL.Method() << function(self)
self.view.finishNode.gameObject:SetActive(true)
self.view.stepDescNode.gameObject:SetActive(false)
end
DungeonCharTutorialStepHudCtrl.OnSubGameStageChangeFinish = HL.Method() << function(self)
end
DungeonCharTutorialStepHudCtrl.OnLevelScriptPushStage = HL.Method(HL.Table) << function(self, args)
local pushStage = unpack(args)
self:_RefreshStage(pushStage)
end
DungeonCharTutorialStepHudCtrl.OnSubGameReset = HL.Method() << function(self)
if self.m_failResetCor then
self.m_failResetCor = self:_ClearCoroutine(self.m_failResetCor)
self.m_inFailCor = false
end
if self.m_succScrollCor then
self.m_succScrollCor = self:_ClearCoroutine(self.m_succScrollCor)
end
self:_RefreshStage()
end
DungeonCharTutorialStepHudCtrl.ToggleCharTutorialStepHUD = HL.Method(HL.Table) << function(self, args)
local isOn, closeHUD = unpack(args)
if isOn then
self:Show()
elseif not closeHUD then
self:Hide()
else
self:Close()
end
end
DungeonCharTutorialStepHudCtrl._RefreshStage = HL.Method(HL.Opt(HL.Number)) << function(self, pushStage)
local charTutorialCfg = Tables.dungeonCharTutorialTable[self.m_dungeonId]
local game = GameWorld.worldInfo.subGame
local stage = game.stage
if pushStage ~= nil then
stage = pushStage
end
local tutorialStageCfg = charTutorialCfg.tutorialStageData[CSIndex(stage)]
local stepIds = tutorialStageCfg.stepIds
self.m_curStepIds = stepIds
self.m_curStage = stage
self.m_curStep = 1
self.m_actionStepCellCached:Refresh(stepIds.Count, function(cell, luaIndex)
local csIndex = CSIndex(luaIndex)
local stepId = self.m_curStepIds[csIndex]
local stepCfg = Tables.dungeonCharTutorialStepTable[stepId]
local curLuaIndex = LuaIndex(csIndex)
cell.skillIcon:LoadSprite(UIConst.UI_SPRITE_SKILL_ICON, stepCfg.stepIcon)
cell.skillDesc.text = stepCfg.iconDesc
cell.animationWrapper:SampleClipAtPercent(StepNodeAnim.Succ, curLuaIndex < self.m_curStep and 1 or 0)
cell.imageSelect.gameObject:SetActive(self.m_curStep == LuaIndex(csIndex))
cell.gameObject.name = stepId
if curLuaIndex == self.m_curStep then
cell.animationWrapper:Play(StepNodeAnim.Cur)
end
end)
self.view.actionStepScrollView:AutoScrollToRectTransform(self.m_actionStepCellCached:Get(self.m_curStep).transform)
self:_ToggleResetHintNode(false)
self:_UpdateStepDesc()
self:_ResetSubGameStageState()
end
DungeonCharTutorialStepHudCtrl._UpdateStepDesc = HL.Method() << function(self)
local curStepId = self.m_curStepIds[CSIndex(self.m_curStep)]
local curStepCfg = Tables.dungeonCharTutorialStepTable[curStepId]
self.view.stepDescTxt.text = curStepCfg.stepDesc
end
DungeonCharTutorialStepHudCtrl._ResetSubGameStageState = HL.Method() << function(self)
self:OnSubGameFinishStateChange({self.m_dungeonId, Phase.Normal})
end
DungeonCharTutorialStepHudCtrl._ToggleResetHintNode = HL.Method(HL.Boolean) << function(self, isOn)
self.view.resetHintNode.gameObject:SetActive(isOn)
local succ, ctrl = UIManager:IsOpen(PanelId.CommonTaskTrackHud)
if not succ then
return
end
local rect = ctrl:GetResetBtnFollowerRect()
ctrl:ToggleResetBtnLoopHint(isOn)
self.view.resetHintNode.position = rect.position
end
HL.Commit(DungeonCharTutorialStepHudCtrl)