Files
Endfield-Data/LuaScripts/Phase/GenderSelect/PhaseGenderSelect.lua
2025-12-02 20:37:18 +07:00

480 lines
14 KiB
Lua

local phaseBase = require_ex('Phase/Core/PhaseBase')
local PHASE_ID = PhaseId.GenderSelect
PhaseGenderSelect = HL.Class('PhaseGenderSelect', phaseBase.PhaseBase)
local PHASE_GENDER_SELECT_OBJECT = "GameplayGenderSelect"
local EnterCutsceneId = "Cutscene_e0m0_1"
local DECO_NORMAL_LOOP_ANIM = "gender_deco_normal_loop"
local AVAILABLE_SELECTION = {
None = "none",
Male = "male",
Female = "female",
}
local GENDER_HOVER_FIRST_DELAY = 1.2
local GENDER_HOVER_LOOP_ANIM = "gender_deco_hover_loop"
local TITLE_TEXT_MAT_PATH = "Assets/Beyond/DynamicAssets/Gameplay/Prefabs/GenderSelect/Materials/M_ui_cutscene_e0m0_1_tittletext_01.mat"
PhaseGenderSelect.s_messages = HL.StaticField(HL.Table) << {
[MessageConst.GENDER_SELECT_START] = { 'OnGenderSelectStart', false },
[MessageConst.ON_CONFIRM_GENDER] = { 'OnConfirmGender', true },
[MessageConst.ON_GENDER_HOVER_CHANGE] = { 'OnGenderHoverChange', true },
[MessageConst.ON_GENDER_HOVER_ANIM] = { 'GenderHoverPlayAnim', true },
}
PhaseGenderSelect.m_sceneObject = HL.Field(HL.Forward("PhaseGameObjectItem"))
PhaseGenderSelect.m_genderSelectPanel = HL.Field(HL.Forward("PhasePanelItem"))
PhaseGenderSelect.m_genderConfirmPanel = HL.Field(HL.Forward("PhasePanelItem"))
PhaseGenderSelect.m_firstActive = HL.Field(HL.Boolean) << true
PhaseGenderSelect.m_curSelection = HL.Field(HL.String) << AVAILABLE_SELECTION.None
PhaseGenderSelect.m_onFinishGenderSelect = HL.Field(HL.Any)
PhaseGenderSelect.m_effectCor = HL.Field(HL.Thread)
PhaseGenderSelect.m_genderHoverTimerId = HL.Field(HL.Number) << 0
PhaseGenderSelect.m_hadSelected = HL.Field(HL.Boolean) << false
PhaseGenderSelect.m_genderConfirmCheckUpdateKey = HL.Field(HL.Number) << -1
PhaseGenderSelect.m_timelineHandle = HL.Field(HL.Any)
PhaseGenderSelect.OnGenderSelectStart = HL.StaticMethod(HL.Any) << function(onFinishGenderSelect)
logger.info(ELogChannel.GamePlay, "PhaseGenderSelect.OnGenderSelectStart")
PhaseManager:OpenPhaseFast(PhaseId.GenderSelect, onFinishGenderSelect)
end
PhaseGenderSelect._OnInit = HL.Override() << function(self)
PhaseGenderSelect.Super._OnInit(self)
self.m_sceneObject = nil
end
PhaseGenderSelect._OnActivated = HL.Override() << function(self)
UIManager:Hide(PanelId.Touch)
logger.info(ELogChannel.GamePlay, "PhaseGenderSelect OnActivated")
local arg = self.arg or {}
if self.m_firstActive then
self.m_onFinishGenderSelect = unpack(arg)
self:_InitSceneObject()
self.m_curSelection = AVAILABLE_SELECTION.None
GameWorld.playerCenterUpdater:SetProxyRef(self.m_sceneObject.view.actor)
logger.info(ELogChannel.GamePlay, "PhaseGenderSelect PlayEnterCutscene")
self.m_timelineHandle = GameAction.PlayCutsceneAndGetHandle(EnterCutsceneId, function()
self:OnNotificationActive()
end)
end
self.m_firstActive = false
end
PhaseGenderSelect._InitSceneObject = HL.Method() << function(self)
self.m_sceneObject = self:CreatePhaseGOItem(PHASE_GENDER_SELECT_OBJECT, PhaseManager.m_cacheRoot)
local sceneObject = self.m_sceneObject
local view = sceneObject.view
self:_ToggleGenderSelectGameplay(false)
local titleMaterial = self.m_resourceLoader:LoadI18NAsset(TITLE_TEXT_MAT_PATH, typeof(CS.UnityEngine.Material))
view.titleTextRender.sharedMaterial = titleMaterial
view.canvasMale.worldCamera = CameraManager.mainCamera
view.canvasFemale.worldCamera = CameraManager.mainCamera
view.hoverImageMale.gameObject:SetActive(false)
view.hoverImageFemale.gameObject:SetActive(false)
end
PhaseGenderSelect.OnNotificationActive = HL.Method() << function(self)
logger.info(ELogChannel.GamePlay, "PhaseGenderSelect OnNotificationActive")
local sceneObject = self.m_sceneObject
if not sceneObject then
return
end
if not sceneObject.view then
return
end
if not sceneObject.view.actor then
return
end
AudioManager.PostEvent(AudioDataContainer.audioGlobalConfig.specialGameplayGenderSelectIn)
AudioManager.PostEvent("au_music_lv000_elevator")
self:_ToggleGenderSelectGameplay(true)
self.m_genderSelectPanel = self:CreatePhasePanelItem(PanelId.GenderSelectController,{
phase = self
})
self.m_genderConfirmPanel = self:CreatePhasePanelItem(PanelId.GenderSelectConfirmHolder,{
phase = self
})
self.m_genderConfirmPanel.uiCtrl:Hide()
end
PhaseGenderSelect._ToggleGenderSelectGameplay = HL.Method(HL.Boolean) << function(self, isOn)
local sceneObject = self.m_sceneObject
if not sceneObject then
return
end
if not sceneObject.view then
return
end
sceneObject.view.actor.gameObject:SetActive(isOn)
sceneObject.view.camera.gameObject:SetActive(isOn)
sceneObject.view.others.gameObject:SetActive(isOn)
sceneObject.view.light.gameObject:SetActive(isOn)
end
PhaseGenderSelect.ChooseFemale = HL.Method() << function(self)
logger.info(ELogChannel.GamePlay, "PhaseGenderSelect ChooseFemale")
AudioAdapter.PostEvent("Au_UI_Button_Player_Girl")
self:_InnerChooseGender(AVAILABLE_SELECTION.Female)
end
PhaseGenderSelect.ChooseMale = HL.Method() << function(self)
logger.info(ELogChannel.GamePlay, "PhaseGenderSelect ChooseMale")
AudioAdapter.PostEvent("Au_UI_Button_Player_Boy")
self:_InnerChooseGender(AVAILABLE_SELECTION.Male)
end
PhaseGenderSelect.ChooseNone = HL.Method() << function(self)
logger.info(ELogChannel.GamePlay, "PhaseGenderSelect ChooseNone")
self:_InnerChooseGender(AVAILABLE_SELECTION.None)
end
PhaseGenderSelect.OnGenderHoverChange = HL.Method(HL.Table) << function(self, arg)
local view = self.m_sceneObject.view
local isMale, isHover = unpack(arg)
local wrapper = isMale and view.hoverImageMale or view.hoverImageFemale
local wrapperStateController = isMale and view.hoverImageMaleStateController or view.hoverImageFemaleStateController
if wrapperStateController == nil then
return
end
if isHover then
AudioAdapter.PostEvent("Au_UI_Hover_CharSelect")
wrapperStateController:SetState("Choose")
if wrapper:GetClipLength(GENDER_HOVER_LOOP_ANIM) > 0 then
wrapper:PlayWithTween(GENDER_HOVER_LOOP_ANIM)
end
else
wrapperStateController:SetState("NoChoose")
if wrapper.curState ~= CS.Beyond.UI.UIConst.AnimationState.Out then
wrapper:PlayWithTween(DECO_NORMAL_LOOP_ANIM)
end
end
end
PhaseGenderSelect._ClearGenderHoverTimer = HL.Method() << function(self)
if self.m_genderHoverTimerId > 0 then
TimerManager:ClearTimer(self.m_genderHoverTimerId)
end
self.m_genderHoverTimerId = 0
end
PhaseGenderSelect.GenderHoverPlayAnim = HL.Method(HL.Table) << function(self, arg)
local isIn, delay = unpack(arg)
local view = self.m_sceneObject.view
local maleWrapper = view.hoverImageMale
local femaleWrapper = view.hoverImageFemale
local maleWrapperStateController = view.hoverImageMaleStateController
local femaleWrapperStateController = view.hoverImageFemaleStateController
maleWrapperStateController:SetState("NoChoose")
femaleWrapperStateController:SetState("NoChoose")
self:_ClearGenderHoverTimer()
if isIn then
if delay then
self.m_genderHoverTimerId = TimerManager:StartTimer(GENDER_HOVER_FIRST_DELAY, function()
maleWrapper.gameObject:SetActive(true)
femaleWrapper.gameObject:SetActive(true)
maleWrapper:PlayInAnimation(function()
maleWrapper:PlayWithTween(DECO_NORMAL_LOOP_ANIM)
end)
femaleWrapper:PlayInAnimation(function()
femaleWrapper:PlayWithTween(DECO_NORMAL_LOOP_ANIM)
end)
self:_ClearGenderHoverTimer()
end)
else
maleWrapper.gameObject:SetActive(true)
femaleWrapper.gameObject:SetActive(true)
maleWrapper:PlayInAnimation(function()
maleWrapper:PlayWithTween(DECO_NORMAL_LOOP_ANIM)
end)
femaleWrapper:PlayInAnimation(function()
femaleWrapper:PlayWithTween(DECO_NORMAL_LOOP_ANIM)
end)
end
maleWrapperStateController:SetState("NoChoose")
else
if delay then
self.m_genderHoverTimerId = TimerManager:StartTimer(GENDER_HOVER_FIRST_DELAY, function()
maleWrapper:PlayOutAnimation(function()
maleWrapper:PlayWithTween(DECO_NORMAL_LOOP_ANIM)
end)
femaleWrapper:PlayOutAnimation(function()
femaleWrapper:PlayWithTween(DECO_NORMAL_LOOP_ANIM)
end)
self:_ClearGenderHoverTimer()
end)
else
maleWrapper:PlayOutAnimation(function()
maleWrapper:PlayWithTween(DECO_NORMAL_LOOP_ANIM)
end)
femaleWrapper:PlayOutAnimation(function()
femaleWrapper:PlayWithTween(DECO_NORMAL_LOOP_ANIM)
end)
end
end
end
PhaseGenderSelect.ConfirmSelection = HL.Method() << function(self)
if self.m_hadSelected then
return
end
self.m_hadSelected = true
local playerInfoSystem = GameInstance.player.playerInfoSystem
local sceneObject = self.m_sceneObject
local serverGender = CS.Proto.GENDER.GenFemale
if self.m_curSelection == AVAILABLE_SELECTION.Female then
sceneObject.view.ac_endminm.gameObject:SetActive(false)
serverGender = CS.Proto.GENDER.GenFemale
AudioManager.PostEvent("au_sfx_levelscript_elevatorfoley_f")
elseif self.m_curSelection == AVAILABLE_SELECTION.Male then
sceneObject.view.ac_endminf.gameObject:SetActive(false)
serverGender = CS.Proto.GENDER.GenMale
AudioManager.PostEvent("au_sfx_levelscript_elevatorfoley_m")
end
UIManager:Hide(PanelId.GenderSelectConfirmHolder)
sceneObject.view.ac_camera:SetTrigger(string.format("CONFIRM_%s", self.m_curSelection))
sceneObject.view.ac_endminf:SetTrigger(string.format("CONFIRM_%s", self.m_curSelection))
sceneObject.view.ac_endminm:SetTrigger(string.format("CONFIRM_%s", self.m_curSelection))
sceneObject.view.ac_camera:Update(0)
sceneObject.view.ac_endminf:Update(0)
sceneObject.view.ac_endminm:Update(0)
sceneObject.view.hoverImageMale.gameObject:SetActive(false)
sceneObject.view.hoverImageFemale.gameObject:SetActive(false)
playerInfoSystem:SetGender(serverGender, true)
end
PhaseGenderSelect._InnerChooseGender = HL.Method(HL.String, HL.Opt(HL.Boolean)) << function(self, gender, isInit)
local sceneObject = self.m_sceneObject
sceneObject.view.ac_camera:SetTrigger(string.format("IN_%s", gender))
sceneObject.view.ac_camera:Update(0)
local realConfirmPanelView = self.m_genderConfirmPanel.uiCtrl:GetRealPanelView()
if gender == AVAILABLE_SELECTION.Female then
realConfirmPanelView.transform:SetParent(sceneObject.view.femaleConfirmPopupPos)
elseif gender == AVAILABLE_SELECTION.Male then
realConfirmPanelView.transform:SetParent(sceneObject.view.maleConfirmPopupPos)
end
realConfirmPanelView.transform:Reset()
self.m_curSelection = gender
self.m_effectCor = PhaseManager:_StartCoroutine(function()
if gender == AVAILABLE_SELECTION.None then
self.m_genderConfirmPanel.uiCtrl:Hide()
coroutine.wait(sceneObject.view.config.SHOW_CONTROLLER_PANEL_DURATION)
UIUtils.PlayAnimationAndToggleActive(sceneObject.view.hoverImageFemale, true)
UIUtils.PlayAnimationAndToggleActive(sceneObject.view.hoverImageMale, true)
self.m_genderSelectPanel.uiCtrl:Show()
else
self.m_genderSelectPanel.uiCtrl:PlayAnimationOutAndHide()
UIUtils.PlayAnimationAndToggleActive(sceneObject.view.hoverImageFemale, false)
UIUtils.PlayAnimationAndToggleActive(sceneObject.view.hoverImageMale, false)
coroutine.wait(sceneObject.view.config.SHOW_CONFIRM_PANEL_DURATION)
self.m_genderConfirmPanel.uiCtrl:Show()
end
end)
end
PhaseGenderSelect.OnConfirmGender = HL.Method() << function(self)
logger.info(ELogChannel.GamePlay, "PhaseGenderSelect on gender confirm, start check loop")
local checkLoopTime = 0
self.m_genderConfirmCheckUpdateKey = LuaUpdate:Add("Tick", function(deltaTime)
checkLoopTime = checkLoopTime + deltaTime
if checkLoopTime > 15 then
logger.error(ELogChannel.GamePlay, "PhaseGenderSelect check loop timeout")
self:LeaveGenderSelect()
return
end
local csLeaderIndex = GameInstance.player.squadManager.curSquad.leaderIndex
local squadSlots = GameInstance.player.squadManager.curSquad.slots
local leaderSlot = squadSlots[csLeaderIndex]
if leaderSlot == nil then
return
end
local camCanExit = false
local sceneObject = self.m_sceneObject
local ac_camera = sceneObject.view.ac_camera
local curStateInfo = ac_camera:GetCurrentAnimatorStateInfo(0)
if curStateInfo:IsName(string.format("CONFIRM_STATE_%s", self.m_curSelection)) and curStateInfo.normalizedTime > 0.95 then
camCanExit = true
end
local leader = leaderSlot.character
if leader.modelCom and leader.modelCom.isModelLoaded and camCanExit then
logger.info(ELogChannel.GamePlay, "PhaseGenderSelect all model loaded, leave")
self:LeaveGenderSelect()
end
end)
end
PhaseGenderSelect.LeaveGenderSelect = HL.Method() << function(self)
AudioManager.PostEvent(AudioDataContainer.audioGlobalConfig.specialGameplayGenderSelectOut)
LuaUpdate:Remove(self.m_genderConfirmCheckUpdateKey)
local mainCharRoot = GameInstance.playerController.mainCharacter.rootCom
if mainCharRoot then
GameWorld.playerCenterUpdater:SetProxyRef(mainCharRoot.transform);
end
PhaseManager:ExitPhaseFast(PHASE_ID)
if self.m_onFinishGenderSelect then
self.m_onFinishGenderSelect()
end
end
PhaseGenderSelect._OnDestroy = HL.Override() << function(self)
PhaseGenderSelect.Super._OnDestroy(self)
if self.m_timelineHandle then
self.m_timelineHandle.afterFinish = nil
end
LuaUpdate:Remove(self.m_genderConfirmCheckUpdateKey)
UIManager:Show(PanelId.Touch)
end
HL.Commit(PhaseGenderSelect)