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

2092 lines
63 KiB
Lua

local uiCtrl = require_ex('UI/Panels/Base/UICtrl')
local PANEL_ID = PanelId.MainHud
local TopBtnPosType = {
AlwaysOutside = 1,
TopViewInside = 2,
AlwaysInside = 3,
}
local ControllerTopBtnPosTypes = {
Fixed = 1,
Dynamic = 2,
}
local ControllerDynamicTopBtnBaseOrderWhitRedDot = 1000
local ControllerDynamicTopBtnBaseOrder = 100000
MainHudCtrl = HL.Class('MainHudCtrl', uiCtrl.UICtrl)
local PhaseForbidStyle = CS.Beyond.Gameplay.PhaseForbidStyle
local DisableSwitchModeForbidStyle = CS.Beyond.Gameplay.DisableSwitchModeForbidParams.ForbidStyle
MainHudCtrl.s_messages = HL.StaticField(HL.Table) << {
[MessageConst.ON_SQUAD_INFIGHT_CHANGED] = 'OnSquadInfightChanged',
[MessageConst.ON_SET_IN_SAFE_ZONE] = 'OnSetInSafeZone',
[MessageConst.ON_IN_FAC_MAIN_REGION_CHANGE] = 'OnInFacMainRegionChange',
[MessageConst.ON_FAC_MODE_CHANGE] = 'OnFacModeChange',
[MessageConst.ON_FAC_TOP_VIEW_HIDE_UI_MODE_CHANGE] = 'OnFacTopViewHideUIModeChange',
[MessageConst.FAC_ON_PLAYER_POS_INFO_CHANGED] = 'OnFacPlayerPosInfoChanged',
[MessageConst.FAC_SET_ENABLE_EXIT_FACTORY_MODE] = 'SetEnableExitFactoryMode',
[MessageConst.ON_SYSTEM_UNLOCK_CHANGED] = 'OnSystemUnlock',
[MessageConst.GAME_MODE_ENABLE] = 'OnGameModeChange',
[MessageConst.ON_CHANGE_THROW_MODE] = 'OnThrowModeChange',
[MessageConst.FAC_TOGGLE_TOP_VIEW] = 'FacToggleTopView',
[MessageConst.ON_TOGGLE_FAC_TOP_VIEW] = 'OnToggleFacTopView',
[MessageConst.ON_EXIT_FACTORY_MODE] = 'OnExitFactoryMode',
[MessageConst.ON_TOGGLE_SPRINT] = 'OnToggleSprint',
[MessageConst.ON_APPLICATION_FOCUS] = 'OnApplicationFocus',
[MessageConst.ON_DOMAIN_DEVELOPMENT_UNLOCK] = 'OnDomainDevelopmentUnlock',
[MessageConst.ON_SUB_GAME_STAGE_CHANGE] = "OnSubGameStageChange",
[MessageConst.ON_ENTER_TOWER_DEFENSE_DEFENDING_PHASE] = 'OnEnterTowerDefenseDefendingPhase',
[MessageConst.ON_TOWER_DEFENSE_LEVEL_REWARDS_FINISHED] = 'OnTowerDefenseDefendingRewardsFinished',
[MessageConst.ON_BUILD_MODE_CHANGE] = 'OnBuildModeChange',
[MessageConst.BEFORE_ENTER_BUILD_MODE] = 'BeforeEnterBuildMode',
[MessageConst.ON_FAC_DESTROY_MODE_CHANGE] = 'OnFacDestroyModeChange',
[MessageConst.BEFORE_ENTER_DESTROY_MODE] = 'BeforeEnterDestroyMode',
[MessageConst.ON_GET_NEW_MAILS] = 'OnGetNewMails',
[MessageConst.ON_GET_LOST_AND_FOUND] = 'OnLostAndFoundRefresh',
[MessageConst.ON_ADD_LOST_AND_FOUND] = 'OnLostAndFoundRefresh',
[MessageConst.OVERRIDE_JUMP_ACTION] = 'OverrideJump',
[MessageConst.FAC_ON_FLUID_IN_BUILDING_REMOVED] = 'OnFluidInBuildingRemoved',
[MessageConst.SET_MAIN_HUD_CAN_AUTO_STOP_EXPAND] = 'OnSetMainHudCanAutoStopExpand',
[MessageConst.FORBID_SYSTEM_CHANGED] = 'TryUpdateAllTopBtnsVisible',
[MessageConst.ON_TOGGLE_PHASE_FORBID] = 'TryUpdateAllTopBtnsVisible',
[MessageConst.ON_LIMITED_GUIDE_WIKI_ENTRY_READ_STATE_CHANGE] = 'TryUpdateAllTopBtnsVisible',
[MessageConst.ON_TOGGLE_UI_ACTION] = 'OnToggleUiAction',
[MessageConst.BLOCK_LUA_UI_INPUT] = 'OnBlockUIInput',
[MessageConst.ON_QUEST_OBJECTIVE_UPDATE] = '_OnQuestObjectiveUpdate',
[MessageConst.TOGGLE_FORBID_CHAR_FOOT_BAR] = 'ForbidCharFootBar',
[MessageConst.TRY_SWITCH_FAC_MODE] = 'TrySwitchMode',
}
MainHudCtrl.s_clearScreenId = HL.StaticField(HL.Number) << 0
MainHudCtrl.s_clearScreenIdExceptSomePanel = HL.StaticField(HL.Number) << 0
MainHudCtrl.m_indicatorControllerGroupId = HL.Field(HL.Number) << 1
MainHudCtrl.m_characterFootBar = HL.Field(HL.Table)
MainHudCtrl.m_quickMenuBindingId = HL.Field(HL.Number) << -1
MainHudCtrl.OnCreate = HL.Override(HL.Any) << function(self, arg)
self.m_hideJumpKeys = {}
self:_InitOneTopNodeExpand(self.view.topRightBtns)
self:_InitOneTopNodeExpand(self.view.topLeftBtns)
self:_InitTopBtns()
self:_InitMainHudBinding()
self:_UpdateInventoryState(true)
self:_UpdateSwitchModeState()
self:_InitDebugAction()
self.view.attackButton:InitAttackButton()
self.m_characterFootBar = Utils.wrapLuaNode(CSUtils.CreateObject(self.view.config.CHARACTER_FOOT_BAR, UIManager.worldObjectRoot))
if Utils.isSwitchModeDisabled() then
self:BindInputPlayerAction("common_disable_switch_mode", function()
if Utils.isInBlackbox() then
Notify(MessageConst.SHOW_TOAST, Language.LUA_BLACK_BOX_SWITCH_MODE_DISABLED)
elseif Utils.isInSpaceShip() then
Notify(MessageConst.SHOW_TOAST, Language.LUA_SPASCESHIP_SWITCH_MODE_DISABLED)
end
end)
end
end
MainHudCtrl.OnShow = HL.Override() << function(self)
self.m_forceBtnOutside = Utils.isInDungeon()
self.view.topRightBtns.controllerBtnList.gameObject:SetActive(DeviceInfo.usingController)
self:UpdateAllTopBtnsVisible()
RedDotManager:TriggerUpdate("Mail")
self:_CheckShowMailBtnBubble()
if Utils.isInFactoryMode() then
self.view.topLeftBtns.animationWrapper:SampleToInAnimationEnd()
else
self.view.topLeftBtns.animationWrapper:SampleToOutAnimationEnd()
end
if not Utils.isInFactoryMode() and InputManagerInst:GetControllerIndicatorState() then
self:_ToggleControllerIndicator(true)
end
self.view.attackButton:OnShow()
self:_InitActivityBubbles()
self.m_characterFootBar.mainCharFootBar:SetUIDisable("MainHudActive", false)
self:OnToggleSprint({ GameInstance.playerController.isMainCharacterSprinting })
end
MainHudCtrl.OnHide = HL.Override() << function(self)
self:_ToggleControllerIndicator(false)
self.view.topLeftBtns.expandNode:SetExpanded(false, true)
self.view.topRightBtns.expandNode:SetExpanded(false, true)
self.view.attackButton:OnHide()
if self.m_mailBubbleShowingState ~= 0 then
self.m_mailBubbleShowingState = 0
self.m_mainBubbleCor = self:_ClearCoroutine(self.m_mainBubbleCor)
self.view.topLeftBtns.mailBubbleImg.gameObject:SetActive(false)
end
self.m_characterFootBar.mainCharFootBar:SetUIDisable("MainHudActive", true)
end
MainHudCtrl.OnClose = HL.Override() << function(self)
if self.m_characterFootBar then
GameObject.Destroy(self.m_characterFootBar.gameObject)
end
self.m_characterFootBar = nil
end
MainHudCtrl.m_topBtnDataMap = HL.Field(HL.Table)
MainHudCtrl.m_topBtnDataList = HL.Field(HL.Table)
MainHudCtrl._BuildTopBtnData = HL.Method() << function(self)
self.m_topBtnDataMap = {
top = {
viewNode = self.view.topNode,
checkVisible = function()
if Utils.isForbidden(ForbidType.ForbidMainHudTopBtns) then
return false
end
if GameWorld.worldInfo.curLevelId == Tables.spaceshipConst.visitSceneName then
return false
end
if FactoryUtils.isInBuildMode() then
return false
end
if LuaSystemManager.factory.inDestroyMode then
return false
end
return true
end,
canStayInTowerDefenseDefending = true,
canStayInFocusMode = true,
},
bottomRight = {
viewNode = self.view.bottomRightNode,
checkVisible = function()
if LuaSystemManager.factory.inTopView then
return false
end
return true
end,
canStayInTowerDefenseDefending = true,
canStayInFocusMode = true,
},
exitDungeon = {
button = self.view.topLeftBtns.exitDungeonBtn,
checkVisible = function()
return Utils.isInDungeon() and not Utils.isInDungeonFactory()
end,
onClick = function()
if WeeklyRaidUtils.IsInWeeklyRaid() then
local dungeonId = GameInstance.dungeonManager.curDungeonId
if string.isEmpty(dungeonId) then
return
end
Notify(MessageConst.SHOW_WEEK_RAID_LEAVE_CONFIRM)
else
if LuaSystemManager.commonTaskTrackSystem:HasRequest() then
return
end
DungeonUtils.onClickExitDungeonBtn()
end
end
},
exitFocusMode = {
button = self.view.topLeftBtns.exitFocusModeBtn,
checkVisible = function()
return FocusModeUtils.isInFocusMode
end,
onClick = function()
Notify(MessageConst.SHOW_POP_UP, {
content = Language.LUA_EXIT_FOCUS_MODE_POP_UP,
freezeWorld = true,
onConfirm = function()
if PhaseManager:IsOpen(PhaseId.CharInfo) then
PhaseManager:ExitPhaseFast(PhaseId.CharInfo)
end
CS.Beyond.Gameplay.FocusModeUtils.OnBtnLeaveFocusMode()
end
})
end,
canStayInFocusMode = true,
},
switchMode = {
viewNode = self.view.topLeftBtns.switchModeNode,
toggle = self.view.topLeftBtns.switchModeNode.toggle,
checkVisible = function()
if not Utils.isSystemUnlocked(GEnums.UnlockSystemType.FacMode) then
return false
end
local isForbid, forbidParams = Utils.isForbiddenWithReason(ForbidType.DisableSwitchMode)
if isForbid and forbidParams and forbidParams.forbidStyle ~= DisableSwitchModeForbidStyle.ShowInvalidIcon then
return false
end
if not Utils.isCurrentMapHasFactoryGrid() then
return false
end
return true
end,
checkIsValueValid = function(isOn)
local valid, toast = self:_CheckSwitchModeValueValid(isOn)
if not valid then
Notify(MessageConst.SHOW_TOAST, toast)
AudioAdapter.PostEvent("au_ui_fac_mode_fail")
end
return valid
end,
onValueChanged = function(isOn)
self:_SwitchMode(isOn)
end,
getCurValue = function()
return Utils.isInFactoryMode()
end,
},
emptySwitch = {
viewNode = self.view.topLeftBtns.emptySwitchNode,
checkVisible = function()
local isForbid, forbidParams = Utils.isForbiddenWithReason(ForbidType.DisableSwitchMode)
if isForbid and forbidParams and forbidParams.forbidStyle == DisableSwitchModeForbidStyle.ShowEmptyBtn then
return true
end
return false
end,
},
techTree = {
button = self.view.topLeftBtns.techTreeBtn,
redDotView = self.view.topLeftBtns.techTreeRedDot,
phaseId = PhaseId.FacTechTree,
checkVisible = function()
return not Utils.isInDungeon()
end,
posType = TopBtnPosType.AlwaysOutside,
controllerPosType = ControllerTopBtnPosTypes.Dynamic,
controllerPosOrder = 4,
},
dungeonInfo = {
button = self.view.topLeftBtns.dungeonInfoBtn,
checkVisible = function()
return DungeonUtils.checkVisibilityDungeonInfoBtn()
end,
onClick = function()
DungeonUtils.onClickDungeonInfoBtn()
end,
controllerPosType = ControllerTopBtnPosTypes.Fixed,
controllerPosOrder = 1,
},
domain = {
button = self.view.topLeftBtns.domainBtn,
redDotView = self.view.topLeftBtns.domainRedDot,
phaseId = PhaseId.DomainMain,
checkVisible = function()
if Utils.isInDungeon() then
return
end
local isUnlock = Utils.isSystemUnlocked(GEnums.UnlockSystemType.DomainDevelopment) and GameInstance.player.domainDevelopmentSystem.domainDevDataDic.Count > 0
return isUnlock
end,
posType = TopBtnPosType.AlwaysOutside,
controllerPosType = ControllerTopBtnPosTypes.Dynamic,
controllerPosOrder = 3,
},
hub = {
button = self.view.topLeftBtns.hubBtn,
checkVisible = function()
return Utils.isInDungeonFactory()
end,
onClick = function()
Notify(MessageConst.FAC_OPEN_NEAREST_BUILDING_PANEL, { FacConst.HUB_DATA_ID, true })
end,
posType = TopBtnPosType.AlwaysOutside,
controllerPosType = ControllerTopBtnPosTypes.Fixed,
controllerPosOrder = 5,
},
controlCenter = {
button = self.view.topLeftBtns.controlCenterBtn,
checkVisible = function()
return Utils.isInSpaceShip()
end,
phaseId = PhaseId.SpaceshipControlCenter,
phaseArgs = { fromMainHud = true },
posType = TopBtnPosType.AlwaysOutside,
controllerPosType = ControllerTopBtnPosTypes.Fixed,
controllerPosOrder = 4,
},
watch = {
button = self.view.topRightBtns.watchBtn,
redDotView = self.view.topRightBtns.watchRedDot,
redDotName = "WatchBtn",
phaseId = PhaseId.Watch,
onClick = function()
PhaseManager:OpenPhase(PhaseId.Watch)
end,
},
simpleMenu = {
button = self.view.topRightBtns.simpleMenuBtn,
phaseId = PhaseId.SimpleSystem,
checkVisible = function()
return not Utils.isSystemUnlocked(GEnums.UnlockSystemType.Watch)
end,
},
inventory = {
button = self.view.topRightBtns.inventoryBtn,
redDotView = self.view.topRightBtns.inventoryRedDot,
phaseId = PhaseId.Inventory,
posType = TopBtnPosType.AlwaysOutside,
getControllerPosInfo = function()
if Utils.isInBlackbox() then
return ControllerTopBtnPosTypes.Fixed, 4
else
return ControllerTopBtnPosTypes.Dynamic, 6
end
end,
icon = self.view.topRightBtns.inventoryBtnNormalIcon,
iconSpriteGetter = function()
if WeeklyRaidUtils.IsInWeeklyRaid() or WeeklyRaidUtils.IsInWeeklyRaidIntro() then
return "btn_week_raid_backpack"
end
return "btn_backpack"
end
},
valuableDepot = {
button = self.view.topRightBtns.valuableDepotBtn,
redDotName = "ValuableDepotInMainHud",
redDotView = self.view.topRightBtns.valuableDepotRedDot,
phaseId = PhaseId.ValuableDepot,
posType = TopBtnPosType.AlwaysInside,
controllerPosType = ControllerTopBtnPosTypes.Dynamic,
controllerPosOrder = 8,
},
character = {
button = self.view.topRightBtns.characterBtn,
phaseId = PhaseId.CharInfo,
canStayInFocusMode = true,
redDotView = self.view.topRightBtns.charRedDot,
posType = TopBtnPosType.TopViewInside,
controllerPosType = ControllerTopBtnPosTypes.Dynamic,
controllerPosOrder = 2,
},
formation = {
button = self.view.topRightBtns.formationBtn,
phaseId = PhaseId.CharFormation,
posType = TopBtnPosType.AlwaysInside,
controllerPosType = ControllerTopBtnPosTypes.Dynamic,
controllerPosOrder = 10,
},
mail = {
button = self.view.topLeftBtns.mailBtn,
redDotView = self.view.topLeftBtns.mailRedDot,
phaseId = PhaseId.Mail,
checkVisible = function()
return RedDotManager:GetRedDotState("Mail") and not Utils.isInDungeon()
end,
posType = TopBtnPosType.AlwaysOutside,
controllerPosType = ControllerTopBtnPosTypes.Dynamic,
controllerPosOrder = 0,
},
adventureBook = {
button = self.view.topRightBtns.adventureBookBtn,
phaseId = PhaseId.AdventureBook,
redDotView = self.view.topRightBtns.adventureBookRedDot,
checkVisible = function()
return not Utils.isInDungeon()
end,
posType = TopBtnPosType.AlwaysOutside,
controllerPosType = ControllerTopBtnPosTypes.Fixed,
controllerPosOrder = 1,
},
gacha = {
button = self.view.topRightBtns.gachaBtn,
phaseId = PhaseId.GachaPool,
redDotView = self.view.topRightBtns.gachaRedDot,
posType = TopBtnPosType.TopViewInside,
controllerPosType = ControllerTopBtnPosTypes.Dynamic,
controllerPosOrder = 1,
checkVisible = function()
return not (WeeklyRaidUtils.IsInWeeklyRaid() or WeeklyRaidUtils.IsInWeeklyRaidIntro())
end,
},
weekRaid = {
button = self.view.topLeftBtns.weekRaidBtn,
checkVisible = function()
return WeeklyRaidUtils.IsInWeeklyRaid()
end,
onClick = function()
PhaseManager:OpenPhase(PhaseId.DungeonWeeklyRaid,{strPanelId = "DungeonWeeklyRaid" , isPreview = true})
end,
posType = TopBtnPosType.AlwaysOutside,
controllerPosType = ControllerTopBtnPosTypes.Dynamic,
controllerPosOrder = 4,
},
weekRaidTipInfo = {
button = self.view.topLeftBtns.weekRaidInfoBtn,
checkVisible = function()
return WeeklyRaidUtils.IsInWeeklyRaid() or WeeklyRaidUtils.IsInWeeklyRaidIntro()
end,
onClick = function()
Notify(MessageConst.SHOW_INTRO, "week_raid")
end,
posType = TopBtnPosType.AlwaysOutside,
controllerPosType = ControllerTopBtnPosTypes.Dynamic,
controllerPosOrder = 3,
},
controllerMission = {
button = self.view.topRightBtns.controllerBtnList.controllerMissionBtn,
phaseId = PhaseId.Mission,
redDotView = self.view.topRightBtns.controllerBtnList.controllerMissionRedDot,
checkVisible = function()
if Utils.isForbidden(ForbidType.ForbidMissionHudShowNonTracking) then
return false
end
if Utils.isForbidden(ForbidType.ForbidJumpToMissionPanelFromHud) then
return false
end
return DeviceInfo.usingController
end,
controllerPosType = ControllerTopBtnPosTypes.Dynamic,
controllerPosOrder = 9,
},
controllerSNS = {
button = self.view.topRightBtns.controllerBtnList.controllerSNSBtn,
phaseId = PhaseId.SNS,
redDotView = self.view.topRightBtns.controllerBtnList.controllerSNSRedDot,
checkVisible = function()
return DeviceInfo.usingController and not GameInstance.mode.hideSNSHud
end,
controllerPosType = ControllerTopBtnPosTypes.Dynamic,
controllerPosOrder = 7,
},
activityCenter = {
button = self.view.topRightBtns.activityBtn,
phaseId = PhaseId.ActivityCenter,
phaseArgs = {
openFrom = "MainHud"
},
redDotView = self.view.topRightBtns.activityRedDot,
posType = TopBtnPosType.TopViewInside,
controllerPosType = ControllerTopBtnPosTypes.Fixed,
controllerPosOrder = 2,
checkVisible = function()
return Utils.isSystemUnlocked(GEnums.UnlockSystemType.Activity)
end,
},
wikiGuide = {
button = self.view.topLeftBtns.wikiGuideBtn,
redDotName = "WikiLimitedGuide",
redDotView = self.view.topLeftBtns.wikiGuideRedDot,
posType = TopBtnPosType.AlwaysOutside,
controllerPosType = ControllerTopBtnPosTypes.Dynamic,
controllerPosOrder = 10,
checkVisible = function()
local guideLimitedCtrl = require_ex('UI/Panels/GuideLimited/GuideLimitedCtrl')
local isDefaultGameMode = GameInstance.mode.modeType == GEnums.GameModeType.Default
return isDefaultGameMode and not string.isEmpty(guideLimitedCtrl.GuideLimitedCtrl.s_waitReadGuideWikiEntry)
end,
onClick = function()
local guideLimitedCtrl = require_ex('UI/Panels/GuideLimited/GuideLimitedCtrl')
Notify(MessageConst.SHOW_WIKI_ENTRY, {
wikiEntryId = guideLimitedCtrl.GuideLimitedCtrl.s_waitReadGuideWikiEntry,
})
end
},
battlePass = {
button = self.view.topRightBtns.battlePassBtn,
phaseId = PhaseId.BattlePass,
redDotView = self.view.topRightBtns.battlePassRedDot,
posType = TopBtnPosType.AlwaysInside,
controllerPosType = ControllerTopBtnPosTypes.Fixed,
controllerPosOrder = 3,
},
cashShop = {
button = self.view.topRightBtns.cashShopBtn,
phaseId = PhaseId.CashShop,
redDotView = self.view.topRightBtns.cashShopBtnRedDot,
posType = TopBtnPosType.AlwaysInside,
controllerPosType = ControllerTopBtnPosTypes.Dynamic,
controllerPosOrder = 3.1,
},
}
end
MainHudCtrl._InitTopBtns = HL.Method() << function(self)
self:_BuildTopBtnData()
self.m_topBtnDataList = {}
for k, info in pairs(self.m_topBtnDataMap) do
info.id = k
self:_InitSingleTopBtn(info)
table.insert(self.m_topBtnDataList, info)
end
table.sort(self.m_topBtnDataList, Utils.genSortFunction({ "sortId" }, true))
self:UpdateAllTopBtnsIcon()
end
MainHudCtrl._InitSingleTopBtn = HL.Method(HL.Table) << function(self, info)
if not info.viewNode then
info.viewNode = info.button or info.toggle
end
if info.phaseId then
if not info.redDotName then
info.redDotName = PhaseManager:GetPhaseRedDotName(info.phaseId)
end
end
local hasPosType = info.posType or info.controllerPosType or info.getControllerPosInfo
if info.redDotView then
if hasPosType then
local isInit = true
info.redDotView:InitRedDot(info.redDotName, nil, function(redDot, active, rdType)
if not isInit then
self:_OnAfterApplyRedDotSate(info, active)
end
end)
isInit = false
else
info.redDotView:InitRedDot(info.redDotName)
end
end
if info.button then
info.button.onClick:RemoveAllListeners()
info.button.onClick:AddListener(function()
self:OnMainHudBtnClick(info)
end)
end
if info.toggle then
info.toggle.onValueChanged:RemoveAllListeners()
info.toggle.isOn = info.getCurValue()
info.toggle.onValueChanged:AddListener(function(isOn)
info.onValueChanged(isOn)
end)
if info.checkIsValueValid then
info.toggle.checkIsValueValid = function(isOn)
return info.checkIsValueValid(isOn)
end
end
end
if hasPosType then
info.oriParentTrans = info.viewNode.transform.parent
if info.posType then
if info.viewNode.transform:IsChildOf(self.view.topLeftBtns.transform) then
info.belongNode = self.view.topLeftBtns
elseif info.viewNode.transform:IsChildOf(self.view.topRightBtns.transform) then
info.belongNode = self.view.topRightBtns
else
logger.error("No Valid Belong Node", info.viewNode.transform:PathFromRoot())
end
info.sortId = info.viewNode.transform:GetSiblingIndex()
end
end
end
MainHudCtrl.OnMainHudBtnClick = HL.Method(HL.Table) << function(self, info)
if info.onClick then
info.onClick()
else
PhaseManager:OpenPhase(info.phaseId, info.phaseArgs)
end
end
MainHudCtrl.GetMainHudBtnInfo = HL.Method(HL.String).Return(HL.Table) << function(self, infoId)
return self.m_topBtnDataMap[infoId]
end
MainHudCtrl.IsMainHudBtnVisible = HL.Method(HL.Table).Return(HL.Boolean) << function(self, info)
return self:_GetSingleTopBtnVisible(info)
end
MainHudCtrl.m_updateTimerId = HL.Field(HL.Number) << -1
MainHudCtrl.TryUpdateAllTopBtnsVisible = HL.Method(HL.Opt(HL.Any)) << function(self, _)
if self.m_updateTimerId > 0 then
return
end
self.m_updateTimerId = self:_StartTimer(0, function()
if IsNull(self.view.gameObject) then
return
end
self.m_updateTimerId = -1
self:UpdateAllTopBtnsVisible()
self:OnForbidSystemChanged()
end)
end
MainHudCtrl.OnForbidSystemChanged = HL.Method() << function(self)
if Utils.isForbidden(ForbidType.ForbidMove) then
GameInstance.playerController:UpdateMoveCommand(Vector2.zero)
end
if Utils.isForbidden(ForbidType.ForbidSprint) then
self.view.sprintBtn.gameObject:SetActive(false)
self:_OnReleaseSprint()
else
self.view.sprintBtn.gameObject:SetActive(true)
self:_UpdateSprintInfo(self.view.inputGroup.groupEnabled)
end
local forbidJump = Utils.isForbidden(ForbidType.ForbidJump)
self:TogglePlayerJump({"ForbidSystem", forbidJump})
end
MainHudCtrl.UpdateAllTopBtnsVisible = HL.Method() << function(self)
if DeviceInfo.usingController then
self:_UpdateAllTopBtnsVisibleInController()
else
self:_ResetTopNodePosInfo(self.view.topLeftBtns)
self:_ResetTopNodePosInfo(self.view.topRightBtns)
for _, info in ipairs(self.m_topBtnDataList) do
self:_UpdateSingleTopBtnVisible(info)
end
self:_UpdateTopNodeExpandState(self.view.topLeftBtns)
self:_UpdateTopNodeExpandState(self.view.topRightBtns)
end
end
MainHudCtrl._UpdateSingleTopBtnVisible = HL.Method(HL.Table, HL.Opt(HL.Boolean, HL.Boolean)) << function(self, info, playAnimation, visible)
if visible == nil then
visible = self:_GetSingleTopBtnVisible(info)
end
if info.viewNode then
if playAnimation then
UIUtils.PlayAnimationAndToggleActive(info.viewNode, visible)
else
info.viewNode.gameObject:SetActive(visible)
end
else
logger.error("No viewNode on", info)
end
if visible then
self:_UpdateBtnPos(info)
end
end
MainHudCtrl._UpdateBtnPos = HL.Method(HL.Table) << function(self, info)
if not info.posType then
return
end
local isOutside
if self.m_forceBtnOutside then
isOutside = true
elseif self.m_forceBtnInside then
isOutside = false
elseif info.posType == TopBtnPosType.AlwaysOutside then
isOutside = true
else
if info.posType == TopBtnPosType.TopViewInside then
isOutside = not LuaSystemManager.factory.inTopView
elseif info.posType == TopBtnPosType.AlwaysInside then
isOutside = false
end
if not isOutside and not LuaSystemManager.factory.inTopView then
if info.redDotView and info.redDotView.curIsActive then
if not info.belongNode.m_flexibleOutsideBtnInfo then
info.belongNode.m_flexibleOutsideBtnInfo = info
isOutside = true
else
info.belongNode.expandRedDot:ApplyState(true)
end
end
end
end
info.isOutside = isOutside
if isOutside then
info.viewNode.transform:SetParent(info.oriParentTrans)
else
info.viewNode.transform:SetParent(info.belongNode.expandNode.transform)
if info.belongNode.m_curInsideBtnCount then
info.belongNode.m_curInsideBtnCount = info.belongNode.m_curInsideBtnCount + 1
end
end
info.viewNode.transform.localScale = Vector3.one
info.viewNode.transform:SetAsLastSibling()
end
MainHudCtrl.UpdateAllTopBtnsIcon = HL.Method() << function(self)
for _, info in ipairs(self.m_topBtnDataList) do
if info.icon and info.iconSpriteGetter then
local spriteName = info.iconSpriteGetter()
if info.icon.sprite.name ~= spriteName then
info.icon:LoadSprite(UIConst.UI_SPRITE_MAIN_HUD, spriteName)
end
end
end
end
MainHudCtrl._GetSingleTopBtnVisible = HL.Method(HL.Table).Return(HL.Boolean) << function(self, info)
if Utils.isInSettlementDefenseDefending() then
if not info.canStayInTowerDefenseDefending then
return false
end
end
if FocusModeUtils.isInFocusMode then
if not info.canStayInFocusMode then
return false
end
end
if info.onlyInFacMode then
if not Utils.isInFactoryMode() then
return false
end
end
if info.hideInFacMode then
if Utils.isInFactoryMode() then
return false
end
end
if info.phaseId then
if not PhaseManager:IsPhaseUnlocked(info.phaseId) then
return false
end
local isPhaseForbidden, forbidStyle = PhaseManager:IsPhaseForbidden(info.phaseId)
if isPhaseForbidden and forbidStyle == PhaseForbidStyle.HideEntrance then
return false
end
end
if info.checkVisible then
local rst = info.checkVisible()
return rst == true
end
return true
end
MainHudCtrl._InitMainHudBinding = HL.Method() << function(self)
self.view.sprintBtn.onPressStart:AddListener(function()
self:_OnPressSprint()
end)
self.view.sprintBtn.onPressEnd:AddListener(function()
self:_OnReleaseSprint()
end)
self.view.jumpBtn.onPressStart:AddListener(function()
self:_OnPressJump()
end)
self.view.sprintBtnDragHandler.onDrag:AddListener(function(eventData)
self:_OnDragSprint(eventData)
end)
self.view.attackButtonDragHandler.onDrag:AddListener(function(eventData)
self:_OnDragAttack(eventData)
end)
self.view.jumpBtnDragHandler.onDrag:AddListener(function(eventData)
self:_OnDragJump(eventData)
end)
self.m_quickMenuBindingId = self:BindInputPlayerAction("common_open_quick_menu_start", function()
UIManager:Open(PanelId.QuickMenu)
end, self.view.topNodeInputGroup.groupId)
self.m_indicatorControllerGroupId = InputManagerInst:CreateGroup(self.view.inputGroup.groupId)
UIUtils.bindInputPlayerAction("common_indicator_start", function()
self:_ToggleControllerIndicator(true)
end, self.m_indicatorControllerGroupId)
UIUtils.bindInputPlayerAction("common_indicator_end", function()
self:_ToggleControllerIndicator(false)
end, self.m_indicatorControllerGroupId)
if not UNITY_EDITOR and DeviceInfo.isAndroid then
self:BindInputPlayerAction("common_quit_game", function()
self:Notify(MessageConst.SHOW_POP_UP, {
content = Language.LUA_QUIT_GAME_CONFIRM,
hideBlur = true,
onConfirm = function()
logger.info("[MainHud] QuitGame triggered")
CSUtils.QuitGame(0)
end,
})
end)
end
GameInstance.player.forbidSystem:SetForbid(ForbidType.ForbidSprint, "Unlock", not Utils.isSystemUnlocked(GEnums.UnlockSystemType.Dash));
if not Utils.isSystemUnlocked(GEnums.UnlockSystemType.Jump) then
self:TogglePlayerJump({"system_unlock", true})
end
end
MainHudCtrl.OnBlockUIInput = HL.Method(HL.Table) << function(self, arg)
local active = InputManagerInst:IsGroupEnabled(self.view.inputGroup.groupId)
self:_OnPanelInputBlocked(active)
end
MainHudCtrl._OnPanelInputBlocked = HL.Override(HL.Boolean) << function(self, active)
self:_UpdateSprintInfo(active)
if not active then
self.view.attackButton:ToggleControllerIndicator(false)
Notify(MessageConst.TOGGLE_HIDE_INTERACT_OPTION_LIST, { "CONTROLLER_INDICATOR", false })
end
self:CheckNormalAttackBtn(active)
end
MainHudCtrl.OnToggleUiAction = HL.Method(HL.Table) << function(self, arg)
self:_OnPanelInputBlocked(self.view.inputGroup.groupEnabled)
local isShow, isUltimate = unpack(arg)
if not isUltimate then
return
end
if isShow then
InputManagerInst:ChangeParent(true, self.view.attackButton.view.button.groupId, self.view.inputGroup.groupId)
else
InputManagerInst:ChangeParent(true, self.view.attackButton.view.button.groupId, InputManagerInst.rootGroupId)
end
end
MainHudCtrl.CheckNormalAttackBtn = HL.Method(HL.Boolean) << function(self, active)
if active then
if DeviceInfo.isPCorConsole and ((InputManagerInst:GetKey(CS.Beyond.Input.KeyboardKeyCode.Mouse0) and not InputManagerInst:GetKeyUp(CS.Beyond.Input.KeyboardKeyCode.Mouse0))
or (InputManagerInst:GetKey(CS.Beyond.Input.GamepadKeyCode.X)
and not InputManagerInst:GetKeyUp(CS.Beyond.Input.GamepadKeyCode.X)
and not InputManagerInst:GetControllerIndicatorState())) then
self.view.attackButton:StartPressAttackBtn()
end
else
self.view.attackButton:ReleaseNormalAttackBtn()
end
end
MainHudCtrl._InitDebugAction = HL.Method() << function(self)
if not BEYOND_DEBUG_COMMAND then
return
end
self:BindInputPlayerAction("battle_debug_flying_mode", function()
CS.Beyond.Gameplay.Core.PlayerController.ToggleFlyingMode()
end)
self:BindInputPlayerAction("battle_debug_get_debug_info", function()
CS.Beyond.Gameplay.Core.PlayerController.GetDebugInfo()
end)
self:BindInputEvent(CS.Beyond.Input.KeyboardKeyCode.Minus, function()
Notify(MessageConst.ON_SHOW_SNAPSHOT)
end)
end
MainHudCtrl.OnExitFactoryMode = HL.Method() << function(self)
end
MainHudCtrl._OnQuestObjectiveUpdate = HL.Method(HL.Any) << function(self, arg)
local questId = unpack(arg)
if not WeeklyRaidUtils.IsInWeeklyRaid() then
self.view.topLeftBtns.weekRaidBubbleImg.gameObject:SetActiveIfNecessary(false)
return
end
local missionId = GameInstance.player.mission:GetMissionIdByQuestId(questId)
local completed = GameInstance.player.weekRaidSystem:IsMissionCompleted(missionId)
if not completed then
return
end
for i = 0, GameInstance.player.weekRaidSystem.scheduledMission.Count - 1 do
local delegateId = GameInstance.player.weekRaidSystem.scheduledMission[i]
local _, delegateCfg = Tables.weekRaidDelegateTable:TryGetValue(delegateId)
if delegateCfg then
local displayQuestIds = GameInstance.player.mission:GetDisplayQuestIdsByMissionId(delegateCfg.missionId)
if displayQuestIds ~= nil and displayQuestIds.Count ~= 0 then
if questId == displayQuestIds[0] then
if not GameInstance.player.weekRaidSystem.weekRaidGame.ShowToastDelegates:Contains(delegateId) then
GameInstance.player.weekRaidSystem.weekRaidGame.ShowToastDelegates:Add(delegateId)
self.view.topLeftBtns.weekRaidBubbleImg.gameObject:SetActiveIfNecessary(true)
self.view.topLeftBtns.weekRaidBubbleImg:SetState(delegateCfg.weekRaidMissionType == GEnums.WeekRaidMissionType.MainMission and "MainMission" or "Normal")
self.view.topLeftBtns.weekRaidBubbleTxt.text = WeeklyRaidUtils.GetWeeklyRaidMissionText(missionId).name
coroutine.start(function()
coroutine.wait(4)
self.view.topLeftBtns.weekRaidBubbleImg.gameObject:SetActiveIfNecessary(false)
end)
end
return
end
end
end
end
end
MainHudCtrl._OnClearScreenOn = HL.StaticMethod() << function()
if MainHudCtrl.s_clearScreenId > 0 then
print("MainHudCtrl._OnClearScreenOn : s_clearScreenId > 0")
return
end
MainHudCtrl.s_clearScreenId = UIManager:ClearScreen()
Notify(MessageConst.ON_CLEAR_SCREEN_STATE_CHANGED, true)
end
MainHudCtrl._OnClearScreenOff = HL.StaticMethod() << function()
UIManager:RecoverScreen(MainHudCtrl.s_clearScreenId)
MainHudCtrl.s_clearScreenId = 0
Notify(MessageConst.ON_CLEAR_SCREEN_STATE_CHANGED, false)
end
MainHudCtrl._OnClearScreenOnExceptSomePanel = HL.StaticMethod(HL.Table) << function(arg)
if MainHudCtrl.s_clearScreenIdExceptSomePanel > 0 then
print("MainHudCtrl._OnClearScreenOnExceptSomePanel : s_clearScreenIdExceptSomePanel > 0")
return
end
local panels = unpack(arg)
local panelIds = {}
for _, panelId in pairs(panels) do
table.insert(panelIds, PanelId[panelId])
end
MainHudCtrl.s_clearScreenIdExceptSomePanel = UIManager:ClearScreen(panelIds)
Notify(MessageConst.ON_CLEAR_SCREEN_STATE_CHANGED, true)
end
MainHudCtrl._OnClearScreenOffExceptSomePanel = HL.StaticMethod() << function()
UIManager:RecoverScreen(MainHudCtrl.s_clearScreenIdExceptSomePanel)
MainHudCtrl.s_clearScreenIdExceptSomePanel = 0
Notify(MessageConst.ON_CLEAR_SCREEN_STATE_CHANGED, false)
end
MainHudCtrl.OnSquadInfightChanged = HL.Method(HL.Opt(HL.Any)) << function(self, args)
local inFight = unpack(args)
self:_UpdateSwitchModeState()
self:_UpdateInventoryState(false)
self.m_forceBtnInside = inFight
self:TryUpdateAllTopBtnsVisible()
end
MainHudCtrl.OnSetInSafeZone = HL.Method(HL.Opt(HL.Any)) << function(self, args)
self:_UpdateInventoryState(false)
end
MainHudCtrl.OnInFacMainRegionChange = HL.Method(HL.Boolean) << function(self, inFacMain)
self:TryUpdateAllTopBtnsVisible()
self:_UpdateInventoryState(false)
end
MainHudCtrl.OnFacPlayerPosInfoChanged = HL.Method() << function(self)
self:_UpdateSwitchModeState()
end
MainHudCtrl.m_inFacModeTagHandle = HL.Field(HL.Userdata)
MainHudCtrl.OnFacModeChange = HL.Method(HL.Boolean) << function(self, inFacMode)
self:TryUpdateAllTopBtnsVisible()
self:_UpdateSwitchModeState()
if inFacMode then
if not self.m_inFacModeTagHandle then
self.m_inFacModeTagHandle = GameInstance.player.globalTagsSystem:AddGlobalTag(
CS.Beyond.Gameplay.Core.GameplayTag(CS.Beyond.GlobalTagConsts.TAG_FAC_MODE))
end
self.view.topLeftBtns.animationWrapper:PlayInAnimation()
else
if self.m_inFacModeTagHandle then
self.m_inFacModeTagHandle:RemoveTag()
self.m_inFacModeTagHandle = nil
end
self.view.topLeftBtns.animationWrapper:PlayOutAnimation()
end
InputManagerInst:ToggleGroup(self.m_indicatorControllerGroupId, not inFacMode)
end
MainHudCtrl.OnFacTopViewHideUIModeChange = HL.Method(HL.Boolean) << function(self, isTopViewHideUIMode)
self:TryUpdateAllTopBtnsVisible()
end
MainHudCtrl.OnToggleFacTopView = HL.Method(HL.Boolean) << function(self, active)
self:TryUpdateAllTopBtnsVisible()
self:_UpdateSwitchModeState()
self.m_characterFootBar.mainCharFootBar:SetUIDisable("facTopView", active)
end
MainHudCtrl.FacToggleTopView = HL.Method(HL.Any) << function(self, arg)
local active = false
local fastMode
if type(arg) == "table" then
active, fastMode = unpack(arg)
else
active = arg
end
if active then
self.m_characterFootBar.mainCharFootBar:SetUIDisable("facTopView", active)
end
end
MainHudCtrl.ForbidCharFootBar = HL.Method(HL.Any) << function(self, arg)
local key, isForbid = unpack(arg)
self.m_characterFootBar.mainCharFootBar:SetUIDisable(key, isForbid)
end
MainHudCtrl.OnSystemUnlock = HL.Method(HL.Table) << function(self, arg)
self:TryUpdateAllTopBtnsVisible()
local system = unpack(arg)
system = GEnums.UnlockSystemType.__CastFrom(system)
if system == GEnums.UnlockSystemType.FacMode then
self:_UpdateSwitchModeState()
elseif system == GEnums.UnlockSystemType.Dash then
GameInstance.player.forbidSystem:SetForbid(ForbidType.ForbidSprint, "Unlock", false);
elseif system == GEnums.UnlockSystemType.Jump then
self:TogglePlayerJump({"system_unlock", false})
end
end
MainHudCtrl.OnGameModeChange = HL.Method(HL.Table) << function(self, mode)
self:TryUpdateAllTopBtnsVisible()
self:_UpdateSwitchModeState()
end
MainHudCtrl.OnDomainDevelopmentUnlock = HL.Method(HL.Opt(HL.Any)) << function(self)
self:TryUpdateAllTopBtnsVisible()
end
MainHudCtrl.OnSubGameStageChange = HL.Method() << function(self)
self:TryUpdateAllTopBtnsVisible()
end
MainHudCtrl.BeforeEnterBuildMode = HL.Method(HL.Boolean) << function(self, skipMainHudAnim)
self:_UpdateSingleTopBtnVisible(self.m_topBtnDataMap.top, not skipMainHudAnim, false)
end
MainHudCtrl.OnBuildModeChange = HL.Method(HL.Number) << function(self, mode)
local isNormal = mode == FacConst.FAC_BUILD_MODE.Normal
self:_UpdateSingleTopBtnVisible(self.m_topBtnDataMap.top, true)
if isNormal or LuaSystemManager.factory.inTopView then
self.view.disabledFakeAttackButton.gameObject:SetActive(false)
else
self.view.disabledFakeAttackButton.gameObject:SetActive(true)
end
end
MainHudCtrl.BeforeEnterDestroyMode = HL.Method() << function(self)
self:_UpdateSingleTopBtnVisible(self.m_topBtnDataMap.top, true, false)
end
MainHudCtrl.OnFacDestroyModeChange = HL.Method(HL.Boolean) << function(self, inDestroyMode)
self:_UpdateSingleTopBtnVisible(self.m_topBtnDataMap.top, true)
self.view.disabledFakeAttackButton.gameObject:SetActive(inDestroyMode and not LuaSystemManager.factory.inTopView)
end
MainHudCtrl._UpdateSwitchModeState = HL.Method() << function(self)
local node = self.view.topLeftBtns.switchModeNode
local inFacMode = Utils.isInFactoryMode()
node.toggle:SetIsOnWithoutNotify(inFacMode)
local inFight = Utils.isInFight()
local isOutOfRangeManual = FactoryUtils.isPlayerOutOfRangeManual()
node.invalidIcon.gameObject:SetActiveIfNecessary(inFight or isOutOfRangeManual)
local forbidParams = Utils.getForbiddenReason(ForbidType.DisableSwitchMode)
node.invalidIconRight.gameObject:SetActiveIfNecessary(forbidParams and forbidParams.forbidStyle == DisableSwitchModeForbidStyle.ShowInvalidIcon)
end
MainHudCtrl._CheckSwitchModeValueValid = HL.Method(HL.Boolean).Return(HL.Boolean, HL.Opt(HL.String)) << function(self, inFacMode)
if Utils.isForbidden(ForbidType.DisableSwitchMode) then
return false, Language.LUA_SWITCH_MODE_FAIL_WHEN_DISABLED
end
if inFacMode then
if Utils.isInFight() then
return false, Language.LUA_SWITCH_MODE_FAIL_WHEN_FIGHT
end
if FactoryUtils.isPlayerOutOfRangeManual() then
return false, Language.LUA_SWITCH_MODE_FAIL_WHEN_OUT_OF_RANGE_MANUAL
end
if Utils.isForbidden(ForbidType.ForbidFactoryMode) then
return false, Language.LUA_GAME_MODE_FORBID_FACTORY_BUILD
end
if Utils.isInThrowMode() then
return false, Language.LUA_SWITCH_MODE_FAIL_WHEN_THROW
end
end
return true
end
MainHudCtrl._SwitchMode = HL.Method(HL.Boolean) << function(self, toFactory)
if toFactory then
LuaSystemManager.factory:ClearAndSetFactoryMode(true)
else
if self.m_enableExitFactoryMode then
LuaSystemManager.factory:ClearAndSetFactoryMode(false)
end
end
end
MainHudCtrl.m_enableExitFactoryMode = HL.Field(HL.Boolean) << true
MainHudCtrl.SetEnableExitFactoryMode = HL.Method(HL.Table) << function(self, args)
local enable = unpack(args)
self.m_enableExitFactoryMode = enable
end
MainHudCtrl.TrySwitchMode = HL.Method(HL.Boolean) << function(self, isFacMode)
if not self.m_topBtnDataMap.switchMode.checkVisible() or
not self:_CheckSwitchModeValueValid(isFacMode) or
isFacMode == self.m_topBtnDataMap.switchMode.getCurValue() then
return
end
self:_SwitchMode(isFacMode)
end
MainHudCtrl.m_lastIsInSafeZone = HL.Field(HL.Boolean) << false
MainHudCtrl._UpdateInventoryState = HL.Method(HL.Boolean) << function(self, skipAnim)
local inSafeZone = Utils.isInSafeZone()
local wrapper = self.view.topRightBtns.inventoryBtnAnimationWrapper
if skipAnim then
if inSafeZone then
wrapper:SampleToInAnimationEnd()
else
wrapper:SampleToOutAnimationEnd()
end
else
if inSafeZone ~= self.m_lastIsInSafeZone then
if inSafeZone then
wrapper:PlayInAnimation()
else
wrapper:PlayOutAnimation()
end
end
end
self.m_lastIsInSafeZone = inSafeZone
end
MainHudCtrl.m_onPressJumpOverride = HL.Field(HL.Any)
MainHudCtrl.OverrideJump = HL.Method(HL.Any) << function(self, arg)
if arg then
self.m_onPressJumpOverride = arg[1]
else
self.m_onPressJumpOverride = nil
end
end
MainHudCtrl.OnFluidInBuildingRemoved = HL.Method(HL.Any) << function(self, arg)
local nodeList = unpack(arg)
for i = 0, nodeList.Count - 1 do
local node = nodeList[i]
local buildingData = GameInstance.remoteFactoryManager.staticData:QueryBuildingData(node.templateId)
if buildingData then
local toastContent = string.format(Language.LUA_FACTORY_FLUID_IN_NODE_REMOVED, buildingData.name)
Notify(MessageConst.SHOW_TOAST, toastContent)
end
end
end
MainHudCtrl._OnPressJump = HL.Method() << function(self)
InputManagerInst:TryClickSkillButtonWhenControllerIndicatorJustRelease(3)
self.view.jumpAnimNode:PlayWithTween("mobile_mainhud_jumpbtn_pressedring")
if self.m_onPressJumpOverride then
self.m_onPressJumpOverride()
else
GameInstance.playerController:Jump()
end
end
MainHudCtrl.m_startPressSprintTime = HL.Field(HL.Number) << 0
MainHudCtrl._OnPressSprint = HL.Method() << function(self)
if BEYOND_DEBUG and UNITY_EDITOR then
if InputManagerInst:GetKey(CS.Beyond.Input.KeyboardKeyCode.Mouse1) then
if CS.Beyond.DebugDefines.disableRightClickSprintEvenNoCursor then
return
end
if CS.Beyond.DebugDefines.disableRightClickSprint and InputManager.cursorVisible then
return
end
end
end
InputManagerInst:TryClickSkillButtonWhenControllerIndicatorJustRelease(2)
if Utils.isForbidden(ForbidType.ForbidMove) then
return
end
if GameInstance.playerController:OnSprintPressed() then
self.view.sprintLightSuccess:PlayWithTween("mobile_mainhud_jumpbtn_release_success")
end
self.view.sprintAnimNode:PlayWithTween("mobile_mainhud_jumpbtn_pressedring")
self.m_startPressSprintTime = Time.unscaledTime
end
MainHudCtrl._OnReleaseSprint = HL.Method() << function(self)
GameInstance.playerController:OnSprintReleased()
end
MainHudCtrl._OnDragSprint = HL.Method(HL.Userdata) << function(self, eventData)
if Time.unscaledTime - self.m_startPressSprintTime >= self.view.config.SPRINT_BTN_DRAG_DELAY then
Notify(MessageConst.ON_DRAG_SPRINT_BTN, eventData.delta)
end
end
MainHudCtrl._OnDragAttack = HL.Method(HL.Userdata) << function(self, eventData)
Notify(MessageConst.ON_DRAG_SPRINT_BTN, eventData.delta)
end
MainHudCtrl._OnDragJump = HL.Method(HL.Userdata) << function(self, eventData)
Notify(MessageConst.MOVE_LEVEL_CAMERA, eventData.delta)
end
MainHudCtrl._UpdateSprintInfo = HL.Method(HL.Boolean) << function(self, inputEnabled)
if inputEnabled then
if self.view.sprintBtn.groupEnabled then
if InputManagerInst:GetKey(CS.Beyond.Input.KeyboardKeyCode.LeftShift) then
self:_OnPressSprint()
end
end
else
self:_OnReleaseSprint()
end
end
MainHudCtrl._ToggleControllerIndicator = HL.Method(HL.Boolean) << function(self, active)
Notify(MessageConst.ON_CONTROLLER_INDICATOR_CHANGE, active)
Notify(MessageConst.TOGGLE_HIDE_INTERACT_OPTION_LIST, { "CONTROLLER_INDICATOR", active })
self.view.attackButton:ToggleControllerIndicator(active)
self:CheckNormalAttackBtn(not active)
if active then
UIManager:HideWithKey(PanelId.GeneralAbility, "CONTROLLER_INDICATOR")
else
UIManager:ShowWithKey(PanelId.GeneralAbility, "CONTROLLER_INDICATOR")
end
end
MainHudCtrl.m_hideJumpKeys = HL.Field(HL.Table)
MainHudCtrl.OnToggleSprint = HL.Method(HL.Table) << function(self, args)
local active = unpack(args)
self.view.sprintTypeNode.gameObject:SetActive(active)
self.view.sprintNormalNode.gameObject:SetActive(not active)
end
MainHudCtrl.TogglePlayerJump = HL.Method(HL.Table) << function(self, args)
local reason, forbid = unpack(args)
if forbid then
self.m_hideJumpKeys[reason] = true
else
self.m_hideJumpKeys[reason] = nil
end
if next(self.m_hideJumpKeys) then
self.view.jumpBtn.gameObject:SetActive(false)
else
self.view.jumpBtn.gameObject:SetActive(true)
end
end
MainHudCtrl.OnApplicationFocus = HL.Method(HL.Table) << function(self, arg)
if DeviceInfo.usingKeyboard and not InputManagerInst:GetKey(CS.Beyond.Input.KeyboardKeyCode.LeftShift) then
GameInstance.playerController:OnSprintReleased()
end
end
MainHudCtrl.OnEnterTowerDefenseDefendingPhase = HL.Method() << function(self)
LuaSystemManager.factory:AddFactoryModeRequest({ false, "TowerDefense" })
LuaSystemManager.factory:RemoveFactoryModeRequest("TowerDefensePrepare")
self:TryUpdateAllTopBtnsVisible()
end
MainHudCtrl.OnTowerDefenseDefendingRewardsFinished = HL.Method() << function(self)
LuaSystemManager.factory:RemoveFactoryModeRequest("TowerDefense")
self:_UpdateSwitchModeState()
end
MainHudCtrl.m_canAutoStopExpand = HL.Field(HL.Boolean) << true
MainHudCtrl.m_forceBtnOutside = HL.Field(HL.Boolean) << false
MainHudCtrl.m_forceBtnInside = HL.Field(HL.Boolean) << false
MainHudCtrl._InitOneTopNodeExpand = HL.Method(HL.Table) << function(self, node)
node.expandBtn.onClick:AddListener(function(eventData)
local expandAll = DeviceInfo.usingKeyboard
if expandAll then
self:_OnClickExpand(self.view.topLeftBtns)
self:_OnClickExpand(self.view.topRightBtns)
else
self:_OnClickExpand(node)
end
end)
node.expandNode:InitMainHudExpandNode(node)
node.expandNode.view.closeExpandBtn.onClick:AddListener(function(eventData)
local expandAll = DeviceInfo.usingKeyboard
if expandAll then
self.view.topLeftBtns.expandNode:SetExpanded(false)
self.view.topRightBtns.expandNode:SetExpanded(false)
else
node.expandNode:SetExpanded(false)
end
end)
node.expandRedDot:InitRedDot("")
end
MainHudCtrl._OnClickExpand = HL.Method(HL.Table) << function(self, node)
node.expandNode:SetExpanded(true)
if self.m_canAutoStopExpand then
node.expandNode:StartAutoCloseTimer()
end
end
MainHudCtrl.OnSetMainHudCanAutoStopExpand = HL.Method(HL.Any) << function(self, args)
self.m_canAutoStopExpand = unpack(args)
end
MainHudCtrl._ResetTopNodePosInfo = HL.Method(HL.Table) << function(self, node)
node.m_flexibleOutsideBtnInfo = nil
node.m_curInsideBtnCount = 0
node.expandRedDot:ApplyState(false)
end
MainHudCtrl._UpdateTopNodeExpandState = HL.Method(HL.Table) << function(self, node)
if node.m_curInsideBtnCount and node.m_curInsideBtnCount > 0 then
node.expandBtn.gameObject:SetActive(not node.expandNode.m_isExpanded)
for k = 1, 4 do
local img = node.expandDotNode["dot" .. k]
if node.m_curInsideBtnCount >= k then
UIUtils.changeAlpha(img, 1)
else
UIUtils.changeAlpha(img, 0.3)
end
end
else
node.expandNode:SetExpanded(false, true)
end
node.expandNode.view.closeExpandBtn.transform:SetAsLastSibling()
node.expandBtn.transform:SetAsLastSibling()
end
MainHudCtrl._OnAfterApplyRedDotSate = HL.Method(HL.Table, HL.Boolean) << function(self, info, active)
if self.m_updateTimerId > 0 then
return
end
if DeviceInfo.usingController then
self:_OnOneTopBtnRedDotChangedInController(info, active)
return
end
if self.m_forceBtnInside or self.m_forceBtnOutside then
return
end
local canBeFlexibleOutside = info.posType == TopBtnPosType.AlwaysInside or (info.posType == TopBtnPosType.TopViewInside and LuaSystemManager.factory.inTopView)
if not canBeFlexibleOutside then
return
end
local shouldUpdate
local belongNode = info.belongNode
if info.isOutside then
if not active then
shouldUpdate = true
end
else
if active then
if not belongNode.m_flexibleOutsideBtnInfo or info.sortId < belongNode.m_flexibleOutsideBtnInfo.sortId then
shouldUpdate = true
end
end
end
if shouldUpdate then
self:_ResetTopNodePosInfo(belongNode)
for _, otherInfo in ipairs(self.m_topBtnDataList) do
if otherInfo.belongNode == belongNode and otherInfo.viewNode.gameObject.activeSelf then
self:_UpdateBtnPos(otherInfo)
end
end
self:_UpdateTopNodeExpandState(belongNode)
end
end
local MAIL_BUBBLE_STATE_NONE = 0
local MAIL_BUBBLE_STATE_LOST_AND_FOUND = 1
local MAIL_BUBBLE_STATE_QUESTIONNAIRE = 2
MainHudCtrl.m_mailBubbleCacheState = HL.Field(HL.Number) << 0
MainHudCtrl.m_mailBubbleShowingState = HL.Field(HL.Number) << 0
MainHudCtrl.m_mainBubbleCor = HL.Field(HL.Thread)
MainHudCtrl.OnGetNewMails = HL.Method() << function(self)
self:_UpdateSingleTopBtnVisible(self.m_topBtnDataMap.mail)
self:_CheckShowMailBtnBubble()
end
MainHudCtrl.OnLostAndFoundRefresh = HL.Method(HL.Opt(HL.Table)) << function(self, args)
self:_UpdateSingleTopBtnVisible(self.m_topBtnDataMap.mail)
self:_CheckShowMailBtnBubble()
end
MainHudCtrl._CheckShowMailBtnBubble = HL.Method() << function(self)
self.m_mailBubbleCacheState = MAIL_BUBBLE_STATE_NONE
if GameInstance.player.mail.needShowNewQuestionnaire then
self.m_mailBubbleCacheState = MAIL_BUBBLE_STATE_QUESTIONNAIRE
elseif GameInstance.player.inventory.lostAndFoundHasNew and not GameInstance.player.inventory.lostAndFound:IsEmpty() then
self.m_mailBubbleCacheState = MAIL_BUBBLE_STATE_LOST_AND_FOUND
end
if self:IsShow() then
self:_ShowMainBtnBubble()
end
end
MainHudCtrl._ShowMainBtnBubble = HL.Method() << function(self)
if self.m_mailBubbleShowingState >= self.m_mailBubbleCacheState then
return
end
if self.m_mainBubbleCor then
self.m_mainBubbleCor = self:_ClearCoroutine(self.m_mainBubbleCor)
end
self.m_mainBubbleCor = self:_StartCoroutine(function()
self.view.topLeftBtns.mailBubbleImg.gameObject:SetActive(true)
self.m_mailBubbleShowingState = self.m_mailBubbleCacheState
self.m_mailBubbleCacheState = MAIL_BUBBLE_STATE_NONE
if self.m_mailBubbleShowingState == MAIL_BUBBLE_STATE_QUESTIONNAIRE then
GameInstance.player.mail.needShowNewQuestionnaire = false
GameInstance.player.inventory.lostAndFoundHasNew = false
self.view.topLeftBtns.mailBubbleTxt.text = Language.LUA_MAIL_HUD_BUBBLE_QUESTIONNAIRE
elseif self.m_mailBubbleShowingState == MAIL_BUBBLE_STATE_LOST_AND_FOUND then
GameInstance.player.inventory.lostAndFoundHasNew = false
self.view.topLeftBtns.mailBubbleTxt.text = Language.LUA_MAIL_HUD_BUBBLE_LOST_AND_FOUND
end
coroutine.wait(self.view.config.MAIL_BUBBLE_STAY_TIME)
self.view.topLeftBtns.mailBubbleImg.gameObject:SetActive(false)
self.m_mailBubbleShowingState = MAIL_BUBBLE_STATE_NONE
end)
end
MainHudCtrl.OnThrowModeChange = HL.Method(HL.Any) << function(self, args)
local inThrowMode = GameWorld.battle.inThrowMode
self:TogglePlayerJump({"throw_mode", inThrowMode})
if inThrowMode then
self.view.attackButton:ReleaseNormalAttackBtn()
end
end
MainHudCtrl.m_curControllerVisibleTopBtns = HL.Field(HL.Table)
MainHudCtrl._UpdateAllTopBtnsVisibleInController = HL.Method() << function(self)
local visibleBtnInfos = {}
for _, info in ipairs(self.m_topBtnDataList) do
local visible = self:_GetSingleTopBtnVisible(info)
if visible then
local controllerPosType, controllerPosOrder
if info.getControllerPosInfo then
controllerPosType, controllerPosOrder = info.getControllerPosInfo()
else
controllerPosType, controllerPosOrder = info.controllerPosType, info.controllerPosOrder
end
if controllerPosType then
if controllerPosType == ControllerTopBtnPosTypes.Fixed then
info.curControllerPosSortId = controllerPosOrder
else
if info.redDotView and info.redDotView.curIsActive then
info.curControllerPosSortId = ControllerDynamicTopBtnBaseOrderWhitRedDot + controllerPosOrder
else
info.curControllerPosSortId = ControllerDynamicTopBtnBaseOrder + controllerPosOrder
end
end
table.insert(visibleBtnInfos, info)
else
info.viewNode.gameObject:SetActive(true)
end
else
info.viewNode.gameObject:SetActive(false)
end
end
table.sort(visibleBtnInfos, Utils.genSortFunction({ "curControllerPosSortId" }, true))
self.m_curControllerVisibleTopBtns = visibleBtnInfos
self:_ChooseShowingTopBtnsInController()
self:_RefreshQuickMenuWithTopBtnsVisibleStateInController()
end
MainHudCtrl._ChooseShowingTopBtnsInController = HL.Method() << function(self)
local maxShowCount = self.view.config.CONTROLLER_TOP_BTN_MAX_SHOW_COUNT
local listNode = self.view.topRightBtns.controllerBtnList
if #self.m_curControllerVisibleTopBtns == 0 then
listNode.gameObject:SetActive(false)
return
end
for k, info in ipairs(self.m_curControllerVisibleTopBtns) do
if k <= maxShowCount then
if info.viewNode.transform.parent ~= listNode.transform then
info.viewNode.transform:SetParent(listNode.transform)
info.viewNode.transform.localScale = Vector3.one
end
info.viewNode.transform:SetAsLastSibling()
info.viewNode.gameObject:SetActive(true)
else
info.viewNode.gameObject:SetActive(false)
end
end
if #self.m_curControllerVisibleTopBtns > maxShowCount then
listNode.moreDeco.gameObject:SetActive(true)
listNode.moreDeco.transform:SetAsLastSibling()
else
listNode.moreDeco.gameObject:SetActive(false)
end
listNode.gameObject:SetActive(true)
end
MainHudCtrl._OnOneTopBtnRedDotChangedInController = HL.Method(HL.Table, HL.Boolean) << function(self, changedInfo, active)
local controllerPosType, controllerPosOrder
if changedInfo.getControllerPosInfo then
controllerPosType, controllerPosOrder = changedInfo.getControllerPosInfo()
else
controllerPosType, controllerPosOrder = changedInfo.controllerPosType, changedInfo.controllerPosOrder
end
if controllerPosType == ControllerTopBtnPosTypes.Fixed then
return
end
local newSortId
if active then
newSortId = ControllerDynamicTopBtnBaseOrderWhitRedDot + controllerPosOrder
else
newSortId = ControllerDynamicTopBtnBaseOrder + controllerPosOrder
end
changedInfo.curControllerPosSortId = newSortId
local maxShowCount = self.view.config.CONTROLLER_TOP_BTN_MAX_SHOW_COUNT
local count = #self.m_curControllerVisibleTopBtns
local needRefresh
if count > maxShowCount then
local lastShowingBtnInfo = self.m_curControllerVisibleTopBtns[maxShowCount]
needRefresh = newSortId > lastShowingBtnInfo.curControllerPosSortId
else
needRefresh = true
end
if needRefresh then
table.sort(self.m_curControllerVisibleTopBtns, Utils.genSortFunction({ "curControllerPosSortId" }, true))
self:_ChooseShowingTopBtnsInController()
end
end
MainHudCtrl._RefreshQuickMenuWithTopBtnsVisibleStateInController = HL.Method() << function(self)
InputManagerInst:ToggleBinding(self.m_quickMenuBindingId, #self.m_curControllerVisibleTopBtns > 0)
end
MainHudCtrl.m_activityBubbleIndex = HL.Field(HL.Number) << -1
MainHudCtrl._InitActivityBubbles = HL.Method() << function(self)
if not Utils.isSystemUnlocked(GEnums.UnlockSystemType.Activity) then
return
end
local activities = GameInstance.player.activitySystem:GetAllActivities()
local allActivities = {}
for _, activity in cs_pairs(activities) do
local _, activityData = Tables.activityTable:TryGetValue(activity.id)
if not activityData or not activityData.bubbleSortId then
return
end
if activityData then
table.insert(allActivities, {
id = activity.id,
completed = activity.isCompleted and 1 or 0,
bubbleSortId = -activityData.bubbleSortId,
bubbleText = activityData.bubbleText,
isUnlocked = activity.isUnlocked,
})
end
end
table.sort(allActivities, Utils.genSortFunction({"completed","bubbleSortId", "id"}, true))
for index = 1,#allActivities do
if ActivityUtils.isNewActivityBubble(allActivities[index].id) and allActivities[index].isUnlocked and not string.isEmpty(allActivities[index].bubbleText) then
self.m_activityBubbleIndex = index
self.view.topRightBtns.activityStartReminderNode.gameObject:SetActive(true)
self.view.topRightBtns.reminderContentTxt.text = allActivities[index].bubbleText
self:_StartCoroutine(function()
coroutine.wait(self.view.config.ACTIVITY_BUBBLE_DISAPPEAR_TIME)
ActivityUtils.setFalseNewActivityBubble(allActivities[index].id)
if self.m_activityBubbleIndex == index then
self.view.topRightBtns.activityStartReminderNode.gameObject:SetActive(false)
end
end)
return
elseif self.m_activityBubbleIndex == index then
self.view.topRightBtns.activityStartReminderNode.gameObject:SetActive(false)
end
end
self.view.topRightBtns.activityStartReminderNode.gameObject:SetActive(false)
end
HL.Commit(MainHudCtrl)