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

3006 lines
104 KiB
Lua

local uiCtrl = require_ex('UI/Panels/Base/UICtrl')
local PANEL_ID = PanelId.FacBuildMode
FacBuildModeCtrl = HL.Class('FacBuildModeCtrl', uiCtrl.UICtrl)
FacBuildModeCtrl.s_messages = HL.StaticField(HL.Table) << {
[MessageConst.ON_INTERACT_CONVEYOR_LOCAL_CHECKING_FAILED] = 'OnInteractConveyorLocalCheckingFailed',
[MessageConst.FAC_BUILD_EXIT_CUR_MODE] = 'ExitCurMode',
[MessageConst.ON_SQUAD_INFIGHT_CHANGED] = 'OnSquadInfightChanged',
[MessageConst.ON_PREPARE_NARRATIVE] = 'ExitCurModeForCS',
[MessageConst.ON_SCENE_LOAD_START] = 'ExitCurModeForCS',
[MessageConst.ALL_CHARACTER_DEAD] = 'ExitCurModeForCS',
[MessageConst.ON_TELEPORT_SQUAD] = 'ExitCurModeForCS',
[MessageConst.PLAY_CG] = 'ExitCurModeForCS',
[MessageConst.ON_PLAY_CUTSCENE] = 'ExitCurModeForCS',
[MessageConst.ON_DIALOG_START] = 'ExitCurModeForCS',
[MessageConst.ALL_CHARACTER_DEAD] = 'ExitCurModeForCS',
[MessageConst.ON_REPATRIATE] = 'ExitCurModeForCS',
[MessageConst.ON_IN_FAC_MAIN_REGION_CHANGE] = 'OnInFacMainRegionChange',
[MessageConst.FAC_LOCK_BUILD_POS] = 'FacLockBuildPos',
[MessageConst.FAC_ON_BUILDING_BATCH_MOVED] = 'FacOnBuildingBatchMoved',
}
FacBuildModeCtrl.s_enableContinueBuild = HL.StaticField(HL.Boolean) << false
FacBuildModeCtrl.m_onClickScreen = HL.Field(HL.Function)
FacBuildModeCtrl.m_onPressScreen = HL.Field(HL.Function)
FacBuildModeCtrl.m_onReleaseScreen = HL.Field(HL.Function)
FacBuildModeCtrl.m_mode = HL.Field(HL.Number) << FacConst.FAC_BUILD_MODE.Normal
FacBuildModeCtrl.m_buildArgs = HL.Field(HL.Table)
FacBuildModeCtrl.m_itemData = HL.Field(HL.Userdata)
FacBuildModeCtrl.m_buildingNodeId = HL.Field(HL.Any)
FacBuildModeCtrl.m_buildingId = HL.Field(HL.String) << ""
FacBuildModeCtrl.m_beltId = HL.Field(HL.String) << ""
FacBuildModeCtrl.m_lastMouseWorldPos = HL.Field(HL.Userdata)
FacBuildModeCtrl.m_tickCor = HL.Field(HL.Thread)
FacBuildModeCtrl.m_sizeIndicator = HL.Field(HL.Table)
FacBuildModeCtrl.m_beltStartPreviewMark = HL.Field(HL.Table)
FacBuildModeCtrl.m_pipePreviewMark = HL.Field(HL.Table)
FacBuildModeCtrl.m_hideKey = HL.Field(HL.Number) << -1
FacBuildModeCtrl.m_powerPoleRange = HL.Field(HL.Table)
FacBuildModeCtrl.m_fluidSprayRange = HL.Field(HL.Table)
FacBuildModeCtrl.m_battleRange = HL.Field(HL.Table)
FacBuildModeCtrl.m_isDragging = HL.Field(HL.Boolean) << false
FacBuildModeCtrl.m_draggingOffset = HL.Field(Vector3)
FacBuildModeCtrl.m_camState = HL.Field(HL.Any)
FacBuildModeCtrl.m_signResetBindingId = HL.Field(HL.Number) << -1
FacBuildModeCtrl.m_rpgBuildBindingGroupId = HL.Field(HL.Number) << -1
FacBuildModeCtrl.m_topViewBuildBindingGroupId = HL.Field(HL.Number) << -1
FacBuildModeCtrl.OnCreate = HL.Override(HL.Any) << function(self, arg)
for _, node in ipairs({ self.view.actionButtonsAsIcon, self.view.actionButtonsAsOption }) do
node.exitButton.onClick:AddListener(function()
self:_OnClickExitIcon()
end)
node.confirmButton.onClick:AddListener(function()
self:_OnClickConfirm()
end)
node.rotateButton.onClick:AddListener(function()
self:_RotateUnit()
end)
node.delButton.onClick:AddListener(function()
self:_DelBuilding()
end)
if node.signResetButton ~= nil then
node.signResetButton.onClick:AddListener(function()
self:_OpenSignSettingPanel(true)
end)
node.signResetButton.gameObject:SetActiveIfNecessary(false)
end
end
self.view.exitBeltModeButton.onClick:AddListener(function()
self:_ExitCurMode(true)
end)
self.m_onClickScreen = function()
self:_OnClickScreen()
end
self.m_onPressScreen = function()
self:_OnPressScreen()
end
self.m_onReleaseScreen = function()
self:_OnReleaseScreen()
end
self.m_onPlaceFinish = function()
self:_OnPlaceFinish()
end
self.m_rpgBuildBindingGroupId = InputManagerInst:CreateGroup(self.view.inputGroup.groupId)
self:BindInputPlayerAction("fac_build_confirm", function()
if DeviceInfo.usingController then
self:_OnClickConfirm()
end
end, self.m_rpgBuildBindingGroupId)
self:BindInputPlayerAction("fac_build_cancel_alter", function()
self:_ExitCurMode(true)
end, self.m_rpgBuildBindingGroupId)
self.m_topViewBuildBindingGroupId = InputManagerInst:CreateGroup(self.view.inputGroup.groupId)
self:BindInputPlayerAction("fac_build_confirm_in_top_view", function()
if DeviceInfo.usingController then
self:_OnClickConfirm()
end
end, self.m_topViewBuildBindingGroupId)
self:BindInputPlayerAction("fac_build_continuous_confirm", function()
if DeviceInfo.usingController then
self:_OnClickConfirm()
end
end, self.m_topViewBuildBindingGroupId)
self:BindInputPlayerAction("fac_build_cancel", function()
self:_ExitCurMode(true)
end, self.m_topViewBuildBindingGroupId)
self:BindInputPlayerAction("fac_disable_mouse1_sprint", function()
end)
self:BindInputPlayerAction("fac_rotate_device", function()
self:_RotateUnit()
end)
self:BindInputPlayerAction("fac_build_mode_delete", function()
self:_DelBuilding()
end)
self.m_signResetBindingId = self:BindInputPlayerAction("fac_build_sign_reset", function()
self:_OpenSignSettingPanel(true)
end)
InputManagerInst:ToggleBinding(self.m_signResetBindingId, false)
self.view.moveBuildingHint.gameObject:SetActive(false)
do
local prefab = self.loader:LoadGameObject(FacConst.BUILDING_SIZE_INDICATOR_PATH)
local obj = self:_CreateWorldGameObject(prefab)
self.m_sizeIndicator = Utils.wrapLuaNode(obj)
obj.gameObject:SetActive(false)
end
do
local prefab = self.loader:LoadGameObject(FacConst.BELT_START_PREVIEW_MARK_PREFAB_PATH)
local obj = self:_CreateWorldGameObject(prefab)
local mark = Utils.wrapLuaNode(obj)
mark.gameObject:SetActive(false)
mark.mesh.sharedMaterial = mark.mesh:GetInstantiatedMaterial()
local cornerMeshMat = mark.cornerMesh1:GetInstantiatedMaterial()
mark.cornerMesh1.sharedMaterial = cornerMeshMat
mark.cornerMesh2.sharedMaterial = cornerMeshMat
mark.cornerMesh3.sharedMaterial = cornerMeshMat
mark.cornerMesh4.sharedMaterial = cornerMeshMat
mark.mats = { mark.mesh.sharedMaterial, cornerMeshMat }
self.m_beltStartPreviewMark = mark
end
do
local prefab = self.loader:LoadGameObject(FacConst.PIPE_PREVIEW_MARK_PREFAB_PATH)
local obj = self:_CreateWorldGameObject(prefab)
local mark = Utils.wrapLuaNode(obj)
mark.gameObject:SetActive(false)
mark.mesh1.sharedMaterial = mark.mesh1:GetInstantiatedMaterial()
mark.mesh2.sharedMaterial = mark.mesh2:GetInstantiatedMaterial()
mark.mesh3.sharedMaterial = mark.mesh3:GetInstantiatedMaterial()
local cornerMeshMat = mark.cornerMesh1:GetInstantiatedMaterial()
mark.cornerMesh1.sharedMaterial = cornerMeshMat
mark.cornerMesh2.sharedMaterial = cornerMeshMat
mark.cornerMesh3.sharedMaterial = cornerMeshMat
mark.cornerMesh4.sharedMaterial = cornerMeshMat
mark.mats = { mark.mesh1.sharedMaterial, mark.mesh2.sharedMaterial, mark.mesh3.sharedMaterial, cornerMeshMat }
self.m_pipePreviewMark = mark
end
do
local prefab = self.loader:LoadGameObject(FacConst.FLUID_SPRAY_RANGE_EFFECT)
local obj = self:_CreateWorldGameObject(prefab)
self.m_fluidSprayRange = Utils.wrapLuaNode(obj)
obj.gameObject:SetActive(false)
end
do
local prefab = self.loader:LoadGameObject(FacConst.BATTLE_BUILDING_RANGE_EFFECT)
local obj = self:_CreateWorldGameObject(prefab)
self.m_battleRange = Utils.wrapLuaNode(obj)
obj.gameObject:SetActive(false)
end
self.view.hideToggle.toggle.onValueChanged:AddListener(function(isOn)
self:_OnChangeHideToggle(isOn)
end)
self.view.continueBuildToggle.isOn = false
self.view.continueBuildToggle.onValueChanged:AddListener(function(isOn)
self:_OnChangeContinueToggle(isOn)
end)
self:_InitKeyHint()
if BEYOND_DEBUG_COMMAND then
UIUtils.bindInputEvent(CS.Beyond.Input.KeyboardKeyCode.C, function()
self:DebugOutputPrepareBuildingPosInfo()
end, nil, nil, self.view.inputGroup.groupId)
end
end
FacBuildModeCtrl._Tick = HL.Method() << function(self)
if self.m_mode == FacConst.FAC_BUILD_MODE.Normal then
return
end
local isBelt = self.m_mode == FacConst.FAC_BUILD_MODE.Belt
local isBuilding = self.m_mode == FacConst.FAC_BUILD_MODE.Building
local isLogistic = self.m_mode == FacConst.FAC_BUILD_MODE.Logistic
local isBlueprint = self.m_mode == FacConst.FAC_BUILD_MODE.Blueprint
if self.m_lockBuildPos then
if isBelt then
self:_UpdateBPStartPreviewMarkColor()
end
return
end
local curMousePos = self:_GetCurPointerPressPos()
local camRay = CameraManager.mainCamera:ScreenPointToRay(curMousePos)
local _, curMouseWorldPos = CSFactoryUtil.SampleLevelRegionPointWithRay(camRay)
local customGridCenter = curMouseWorldPos
local usingDrag = self:_InDragMode()
if self.m_isDragging then
curMousePos = curMousePos + self.m_draggingOffset
end
local curMode, posChanged
if isBuilding or isLogistic then
curMode = GameInstance.remoteFactoryManager.interact.currentBuildingMode
if not usingDrag or self.m_isDragging then
GameInstance.remoteFactoryManager:GridPositionTriggered(curMousePos, 4)
posChanged = true
elseif usingDrag then
local buildingCenterPos = GameInstance.remoteFactoryManager.interact.currentBuildingMode:GetPreviewRenderInfo()
local buildingScreenPos = CameraManager.mainCamera:WorldToScreenPoint(buildingCenterPos)
buildingScreenPos.z = 0
local newScreenPos = Vector3.zero
newScreenPos.x = lume.clamp(buildingScreenPos.x, self.view.config.DRAG_MODE_BUILDING_PADDING_X.x, Screen.width - self.view.config.DRAG_MODE_BUILDING_PADDING_X.y)
newScreenPos.y = lume.clamp(buildingScreenPos.y, self.view.config.DRAG_MODE_BUILDING_PADDING_Y.x, Screen.height - self.view.config.DRAG_MODE_BUILDING_PADDING_Y.y)
if newScreenPos ~= buildingScreenPos then
GameInstance.remoteFactoryManager:GridPositionTriggered(newScreenPos, 4)
buildingCenterPos = GameInstance.remoteFactoryManager.interact.currentBuildingMode:GetPreviewRenderInfo()
posChanged = true
end
customGridCenter = buildingCenterPos
end
if not self.m_buildingNodeId and DeviceInfo.usingKeyboard then
Notify(MessageConst.CHANGE_MOUSE_ICON_HINT, {
name = "FacBuildModeCtrl-ContinuousBuild",
type = self:_EnableContinueBuild() and UIConst.MOUSE_ICON_HINT.ContinuousBuild or UIConst.MOUSE_ICON_HINT.Default,
})
end
elseif isBelt then
curMode = GameInstance.remoteFactoryManager.interact.currentConveyorMode
if usingDrag then
if self.m_isDragging then
GameInstance.remoteFactoryManager:GridPositionTriggered(curMousePos, 2)
posChanged = true
end
else
GameInstance.remoteFactoryManager:GridPositionTriggered(curMousePos, 4)
posChanged = true
end
local hasStart = curMode.hasStart
if hasStart ~= self.m_beltHasStartLastTick then
self:_UpdateOnBeltHasStartChanged()
if usingDrag then
local mark = self:_IsPipe() and self.m_pipePreviewMark or self.m_beltStartPreviewMark
mark.gameObject.gameObject:SetActive(hasStart)
end
end
if hasStart and usingDrag then
local beltEndWorldPos = curMode:GetDragHandlingPoint(Vector3.zero) + Vector3(0.5, 0, 0.5)
beltEndWorldPos.y = curMouseWorldPos.y
if not self.m_isDragging then
customGridCenter = beltEndWorldPos
end
self:_UpdateBPStartPreviewMarkWithWorldPos(beltEndWorldPos)
end
if not usingDrag then
self:_UpdateBPStartPreviewMarkWithWorldPos(curMouseWorldPos)
end
elseif isBlueprint then
curMode = GameInstance.remoteFactoryManager.interact.currentBlueprintMode
if not usingDrag or self.m_isDragging then
GameInstance.remoteFactoryManager:GridPositionTriggered(curMousePos, 4)
posChanged = true
local gridPos = Unity.Vector2Int(curMode.preparedPosition.x, curMode.preparedPosition.z)
if gridPos ~= self.m_lastBPGridPos then
self:_SetBluePrintSelectGrids(gridPos)
end
elseif usingDrag then
if not self.m_lastBPGridPos then
posChanged = true
self:_SetBluePrintSelectGrids(Unity.Vector2Int(curMode.preparedPosition.x, curMode.preparedPosition.z))
else
local buildingCenterPos = Vector3(curMode.preparedPosition.x + 0.5, curMode.preparedPosition.y, curMode.preparedPosition.z + 0.5)
local buildingScreenPos = CameraManager.mainCamera:WorldToScreenPoint(buildingCenterPos)
buildingScreenPos.z = 0
local newScreenPos = Vector3.zero
newScreenPos.x = lume.clamp(buildingScreenPos.x, self.view.config.DRAG_MODE_BUILDING_PADDING_X.x, Screen.width - self.view.config.DRAG_MODE_BUILDING_PADDING_X.y)
newScreenPos.y = lume.clamp(buildingScreenPos.y, self.view.config.DRAG_MODE_BUILDING_PADDING_Y.x, Screen.height - self.view.config.DRAG_MODE_BUILDING_PADDING_Y.y)
if newScreenPos ~= buildingScreenPos then
GameInstance.remoteFactoryManager:GridPositionTriggered(newScreenPos, 4)
posChanged = true
self:_SetBluePrintSelectGrids(Unity.Vector2Int(curMode.preparedPosition.x, curMode.preparedPosition.z))
end
end
end
customGridCenter = Unity.Vector3(curMode.preparedPosition.x, curMode.preparedPosition.y, curMode.preparedPosition.z)
end
if curMode then
curMode.useCustomGridCenter = LuaSystemManager.factory.inTopView
if curMode.useCustomGridCenter and posChanged then
curMode.customGridCenter = customGridCenter
end
end
self.m_lastMouseWorldPos = curMouseWorldPos
self:_UpdateValidResult()
self:_UpdateAutoConnectExtraHint()
self:_NotifyPowerPoleTravelHint()
if usingDrag then
local targetWorldPos, targetSize
if isBelt then
targetWorldPos = customGridCenter
targetSize = Vector3.zero
elseif isBlueprint then
targetWorldPos = Vector3(curMode.preparedPosition.x, curMode.preparedPosition.y, curMode.preparedPosition.z)
targetSize = Vector3.zero
local range = self.m_buildArgs.range
local needReverse = curMode.preparedDirection % 2 == 1
targetSize.x = needReverse and range.height or range.width
targetSize.z = needReverse and range.width or range.height
else
local pos, rot = GameInstance.remoteFactoryManager.interact.currentBuildingMode:GetPreviewRenderInfo()
targetWorldPos = pos
if isBuilding then
local data = Tables.factoryBuildingTable:GetValue(self.m_buildingId)
targetSize = (rot.y % 180 == 0) and Vector3(data.range.width, 0, data.range.depth) or Vector3(data.range.depth, 0, data.range.width)
else
targetSize = Vector3.one
end
end
local min = CameraManager.mainCamera:WorldToScreenPoint(targetWorldPos + targetSize / 2)
local max = CameraManager.mainCamera:WorldToScreenPoint(targetWorldPos - targetSize / 2)
local size = max - min
size.x = math.abs(size.x)
size.y = math.abs(size.y)
min.x = math.min(min.x, max.x)
min.y = math.min(min.y, max.y)
max = min + size
local targetScreenRect = Unity.Rect(min.x, Screen.height - (min.y + size.y), size.x, size.y)
UIUtils.updateTipsPositionWithScreenRect(self.view.actionButtonsAsIcon.transform, targetScreenRect, self.view.transform,
self.uiCamera, UIConst.UI_TIPS_POS_TYPE.FacTopViewBuildActionIcons, {
top = self.view.config.DRAG_MODE_BUILDING_PADDING_Y.x,
left = self.view.config.DRAG_MODE_BUILDING_PADDING_X.x,
right = self.view.config.DRAG_MODE_BUILDING_PADDING_X.y,
top = self.view.config.DRAG_MODE_BUILDING_PADDING_Y.x,
bottom = self.view.config.DRAG_MODE_BUILDING_PADDING_Y.y,
})
if isBelt then
local dir = self.view.joystick.jsValue
local needSwitch = LuaSystemManager.factory.canMoveCamTarget == false
if needSwitch then
LuaSystemManager.factory.canMoveCamTarget = true
end
LuaSystemManager.factory:MoveTopViewCamTarget(dir * 15 * Time.deltaTime)
if needSwitch then
LuaSystemManager.factory.canMoveCamTarget = false
end
end
end
end
FacBuildModeCtrl.OnShow = HL.Override() << function(self)
self:_AddRegister()
CS.HG.Rendering.ScriptBridge.TAAUControlBridge.taauFastConverge = true
Notify(MessageConst.TOGGLE_FORBID_ATTACK, { "FacBuildModeCtrl", true })
self:FacLockBuildPos({ false })
self.view.continueBuildToggle.isOn = FacBuildModeCtrl.s_enableContinueBuild
self.view.actionButtonsAsOption.signResetButton.gameObject:SetActiveIfNecessary(false)
end
FacBuildModeCtrl.OnHide = HL.Override() << function(self)
self:FacLockBuildPos({ false })
self:_OnReleaseScreen()
self:_ClearRegister()
CS.HG.Rendering.ScriptBridge.TAAUControlBridge.taauFastConverge = true
Notify(MessageConst.TOGGLE_FORBID_ATTACK, { "FacBuildModeCtrl", false })
Notify(MessageConst.CHANGE_MOUSE_ICON_HINT, {
name = "FacBuildModeCtrl-ContinuousBuild",
type = UIConst.MOUSE_ICON_HINT.Default,
})
end
FacBuildModeCtrl.OnClose = HL.Override() << function(self)
self:_ExitCurMode(false, true, true)
self:_ClearRegister()
Notify(MessageConst.TOGGLE_FORBID_ATTACK, { "FacBuildModeCtrl", false })
self.m_hideKey = UIManager:RecoverScreen(self.m_hideKey)
GameInstance.remoteFactoryManager.inBuildMode = false
Notify(MessageConst.CHANGE_MOUSE_ICON_HINT, {
name = "FacBuildModeCtrl-ContinuousBuild",
type = UIConst.MOUSE_ICON_HINT.Default,
})
end
FacBuildModeCtrl.EnterBlueprintMode = HL.StaticMethod(HL.Table) << function(args)
FacBuildModeCtrl._EnterMode(args, FacConst.FAC_BUILD_MODE.Blueprint)
end
FacBuildModeCtrl.s_isEntering = HL.StaticField(HL.Boolean) << false
FacBuildModeCtrl._EnterMode = HL.StaticMethod(HL.Table, HL.Number) << function(args, mode)
if Utils.isCurSquadAllDead() then
return
end
local facDestroyModeCtrlClass = require_ex("UI/Panels/FacDestroyMode/FacDestroyModeCtrl").FacDestroyModeCtrl
if facDestroyModeCtrlClass.s_isEntering then
return false
end
if PhaseManager:CheckIsInTransition() then
return
end
if FacBuildModeCtrl.s_isEntering then
return
end
if FacBuildModeCtrl._CheckBanAndToastSignInTopView(args.itemId) then
return
end
local isOpen, ctrl = UIManager:IsOpen(PANEL_ID)
if isOpen then
if ctrl.m_mode ~= FacConst.FAC_BUILD_MODE.Normal then
return
end
end
if not FacBuildModeCtrl.CheckCanEnterAndShowToast() then
return
end
if mode == FacConst.FAC_BUILD_MODE.Logistic then
local itemId = args.itemId
local logisticId = Tables.factoryItem2LogisticIdTable[itemId].logisticId
local logisticData, isLiquid = FactoryUtils.getLogisticData(logisticId)
if isLiquid and not FactoryUtils.isDomainSupportPipe() then
Notify(MessageConst.SHOW_TOAST, Language.LUA_FAC_DOMAIN_NOT_SUPPORT_PIPE)
return
end
end
FacBuildModeCtrl.s_isEntering = true
Notify(MessageConst.TOGGLE_IN_MAIN_HUD_STATE, { key = "facBuildMode", isInMainHud = false })
FacBuildModeCtrl._BeforeEnterBuildMode(args.skipMainHudAnim or false)
local onClearScreenFinishAct = function(key)
local self = FacBuildModeCtrl.AutoOpen(PANEL_ID, nil, true)
self.m_hideKey = key
if mode == FacConst.FAC_BUILD_MODE.Building then
self:_EnterBuildingMode(args)
elseif mode == FacConst.FAC_BUILD_MODE.Logistic then
self:_EnterLogisticMode(args)
elseif mode == FacConst.FAC_BUILD_MODE.Belt then
if lume.isarray(args) then
args = { beltId = args[1] }
end
self:_EnterBeltMode(args)
elseif mode == FacConst.FAC_BUILD_MODE.Blueprint then
self:_EnterBlueprintMode(args)
end
if args.triggerPressScreen then
self:_StartCoroutine(function()
coroutine.step()
if self:IsShow() then
self:_OnPressScreen()
end
end)
end
FacBuildModeCtrl.s_isEntering = false
if DeviceInfo.usingKeyboard then
self:_UpdateAutoMoveTopViewCamState()
end
end
if args.fastEnter then
local key = UIManager:ClearScreen(Const.RESERVE_PANEL_IDS_FOR_FAC_BUILD_MODE)
onClearScreenFinishAct(key)
else
UIManager:ClearScreenWithOutAnimation(function(key)
onClearScreenFinishAct(key)
end, Const.RESERVE_PANEL_IDS_FOR_FAC_BUILD_MODE)
end
GameInstance.remoteFactoryManager.inBuildMode = true
end
FacBuildModeCtrl.EnterBuildingMode = HL.StaticMethod(HL.Table) << function(args)
FacBuildModeCtrl._EnterMode(args, FacConst.FAC_BUILD_MODE.Building)
end
FacBuildModeCtrl.EnterLogisticMode = HL.StaticMethod(HL.Table) << function(args)
FacBuildModeCtrl._EnterMode(args, FacConst.FAC_BUILD_MODE.Logistic)
end
FacBuildModeCtrl.EnterBeltMode = HL.StaticMethod(HL.Table) << function(args)
FacBuildModeCtrl._EnterMode(args, FacConst.FAC_BUILD_MODE.Belt)
end
FacBuildModeCtrl._BeforeEnterBuildMode = HL.StaticMethod(HL.Boolean) << function(skipMainHudAnim)
Notify(MessageConst.HIDE_ITEM_TIPS)
PhaseManager:ExitPhaseFastTo(PhaseId.Level, true)
Notify(MessageConst.BEFORE_ENTER_BUILD_MODE, skipMainHudAnim)
end
FacBuildModeCtrl.OnSquadInfightChanged = HL.Method(HL.Opt(HL.Any)) << function(self)
local inFight = Utils.isInFight()
if inFight then
self:_ExitCurMode(false, true)
end
end
FacBuildModeCtrl.CheckCanEnterAndShowToast = HL.StaticMethod().Return(HL.Boolean)<< function()
local level = PhaseManager.m_openedPhaseSet[PhaseId.Level]
if not level then
return false
end
local csCheckResult = GameInstance.remoteFactoryManager:CheckEnterInteractMode()
if csCheckResult == CS.Beyond.Gameplay.RemoteFactory.EnterInteractModeCheckResult.InvalidLevel then
Notify(MessageConst.SHOW_TOAST, Language.LUA_CANT_ENTER_BUILD_MODE_WHEN_NO_FAC_REGION)
return false
end
if level.isPlayerOutOfRangeManual then
Notify(MessageConst.SHOW_TOAST, Language.LUA_CANT_ENTER_BUILD_MODE_WHEN_OUT_OF_RANGE_MANUAL)
return false
end
if GameWorld.battle.isSquadInFight and not Utils.isInSettlementDefenseDefending() then
Notify(MessageConst.SHOW_TOAST, Language.LUA_CANT_ENTER_BUILD_MODE_WHEN_FIGHT)
return false
end
return true
end
FacBuildModeCtrl.m_needCloseMiniPower = HL.Field(HL.Boolean) << false
FacBuildModeCtrl._AddRegister = HL.Method() << function(self)
if not DeviceInfo.usingController then
local touchPanel = UIManager.commonTouchPanel
touchPanel.onClick:AddListener(self.m_onClickScreen)
touchPanel.onPress:AddListener(self.m_onPressScreen)
touchPanel.onRelease:AddListener(self.m_onReleaseScreen)
end
self:_Tick()
self.m_tickCor = self:_StartCoroutine(function()
while true do
coroutine.step()
self:_Tick()
end
end)
end
FacBuildModeCtrl._ClearRegister = HL.Method() << function(self)
self.m_tickCor = self:_ClearCoroutine(self.m_tickCor)
local touchPanel = UIManager.commonTouchPanel
touchPanel.onClick:RemoveListener(self.m_onClickScreen)
touchPanel.onPress:RemoveListener(self.m_onPressScreen)
touchPanel.onRelease:RemoveListener(self.m_onReleaseScreen)
end
FacBuildModeCtrl._OnClickScreen = HL.Method() << function(self)
if not DeviceInfo.usingTouch then
self:_OnClickConfirm()
elseif LuaSystemManager.factory.inTopView and self.m_mode == FacConst.FAC_BUILD_MODE.Belt and not GameInstance.remoteFactoryManager.interact.currentConveyorMode.hasStart and self.view.actionHint.gameObject.activeInHierarchy then
self.view.actionHint:Play("facbuildmodeerrorhint_blink")
end
end
FacBuildModeCtrl._OnClickConfirm = HL.Method() << function(self)
if not FacBuildModeCtrl.s_enableConfirmBuild then
return
end
if self.m_mode == FacConst.FAC_BUILD_MODE.Building then
self:_ConfirmBuilding()
elseif self.m_mode == FacConst.FAC_BUILD_MODE.Logistic then
self:_ConfirmLogistic()
elseif self.m_mode == FacConst.FAC_BUILD_MODE.Belt then
if self.m_curBuildIsValid then
if self.m_lockBuildPos then
local isPipe = self:_IsPipe()
local mark = isPipe and self.m_pipePreviewMark or self.m_beltStartPreviewMark
local worldPos = mark.transform.position
local voxelPos = GameInstance.remoteFactoryManager.visual:WorldToVoxel(worldPos)
local gridPos = Unity.Vector2Int(math.floor(voxelPos.x), math.floor(voxelPos.z))
GameInstance.remoteFactoryManager:GridPositionTriggered(gridPos, Vector2.zero, voxelPos.y, 0)
else
GameInstance.remoteFactoryManager:GridPositionTriggered(self:_GetCurPointerPressPos(), 0)
end
AudioAdapter.PostEvent("au_ui_fac_btn_belt_build_click")
else
AudioAdapter.PostEvent("au_ui_fac_unbuildable")
end
local hasStart = GameInstance.remoteFactoryManager.interact.currentConveyorMode.hasStart
if not hasStart then
Notify(MessageConst.SHOW_TOAST, self:_IsPipe() and Language.LUA_FAC_BUILD_PIPE_START_CLICK_ERROR or Language.LUA_FAC_BUILD_BELT_START_CLICK_ERROR)
if self.view.errorHint.gameObject.activeInHierarchy then
self.view.errorHint:Play("facbuildmodeerrorhint_blink")
end
end
elseif self.m_mode == FacConst.FAC_BUILD_MODE.Blueprint then
self:_ConfirmBlueprint()
end
end
FacBuildModeCtrl._OnPressScreen = HL.Method() << function(self)
self.m_mobileDragBeltChecker = self:_ClearCoroutine(self.m_mobileDragBeltChecker)
if self.m_mode == FacConst.FAC_BUILD_MODE.Normal then
return
end
if not LuaSystemManager.factory.inTopView or not DeviceInfo.usingTouch then
return
end
if Input.touchCount > 1 then
return
end
local isBuilding = self.m_mode == FacConst.FAC_BUILD_MODE.Building
local isBelt = self.m_mode == FacConst.FAC_BUILD_MODE.Belt
local isLogistic = self.m_mode == FacConst.FAC_BUILD_MODE.Logistic
local isBlueprint = self.m_mode == FacConst.FAC_BUILD_MODE.Blueprint
local curMousePos = self:_GetCurPointerPressPos()
local camRay = CameraManager.mainCamera:ScreenPointToRay(curMousePos)
local _, worldPos = CSFactoryUtil.SampleLevelRegionPointWithRay(camRay)
local dragTargetCenterPos, renderExist
if isBuilding or isLogistic then
dragTargetCenterPos, _, _, renderExist = GameInstance.remoteFactoryManager.interact.currentBuildingMode:GetPreviewRenderInfo()
elseif isBelt then
renderExist = true
dragTargetCenterPos = GameInstance.remoteFactoryManager.interact.currentConveyorMode:GetDragHandlingPoint(worldPos) + Vector3(0.5, 0, 0.5)
elseif isBlueprint then
renderExist = true
local mode = GameInstance.remoteFactoryManager.interact.currentBlueprintMode
dragTargetCenterPos = Vector3(mode.preparedPosition.x, mode.preparedPosition.y, mode.preparedPosition.z)
end
if not renderExist then
return
end
local dragTargetCenterScreenPos = CameraManager.mainCamera:WorldToScreenPoint(dragTargetCenterPos)
local halfMinSizeInScreen = self.view.config.MOBILE_MIN_DRAG_SIZE / 2 / self.view.transform.rect.width * Screen.width
if math.abs(curMousePos.x - dragTargetCenterScreenPos.x) > halfMinSizeInScreen or math.abs(curMousePos.y - dragTargetCenterScreenPos.y) > halfMinSizeInScreen then
local targetWorldRect, direction
targetWorldRect = Unity.Rect()
if isBuilding then
local buildingData = Tables.factoryBuildingTable:GetValue(self.m_buildingId)
local width = buildingData.range.width
local depth = buildingData.range.depth
targetWorldRect.size = Vector2(width, depth)
direction = GameInstance.remoteFactoryManager.interact.currentBuildingMode.finalBuildingDirection
elseif isBlueprint then
local range = self.m_buildArgs.range
targetWorldRect.size = Vector2(range.width, range.height)
direction = GameInstance.remoteFactoryManager.interact.currentBlueprintMode.preparedDirection
else
targetWorldRect.size = Vector2.one
direction = 0
end
if direction % 2 == 1 then
targetWorldRect.size = Vector2(targetWorldRect.size.y, targetWorldRect.size.x)
end
local rectCenter = Vector2(dragTargetCenterPos.x, dragTargetCenterPos.z)
if isBlueprint then
if targetWorldRect.width % 2 == 1 then
rectCenter.x = rectCenter.x + 0.5
end
if targetWorldRect.height % 2 == 1 then
rectCenter.y = rectCenter.y + 0.5
end
end
targetWorldRect.center = rectCenter
if not targetWorldRect:Contains(worldPos:XZ()) then
return
end
end
local autoMoveCamExtraPadding
if isBelt then
if GameInstance.remoteFactoryManager:CheckValidConveyorStartByScreenPos(curMousePos, 1) then
LuaSystemManager.factory.canMoveCamTarget = false
self.m_mobileDragBeltChecker = self:_StartCoroutine(function()
while true do
coroutine.step()
if Input.touchCount > 1 then
LuaSystemManager.factory.canMoveCamTarget = true
self.m_mobileDragBeltChecker = nil
return
end
if (self:_GetCurPointerPressPos() - curMousePos).sqrMagnitude > 100 then
self.m_isDragging = true
UIManager.commonTouchPanel.enableZoom = false
self.m_draggingOffset = Vector3.zero
GameInstance.remoteFactoryManager:GridPositionTriggered(curMousePos, 1)
self:_UpdateAutoMoveTopViewCamState()
self.m_mobileDragBeltChecker = nil
return
end
end
end)
end
else
self.m_isDragging = true
UIManager.commonTouchPanel.enableZoom = false
local targetCenterScreenPos
if isBlueprint then
targetCenterScreenPos = CameraManager.mainCamera:WorldToScreenPoint(dragTargetCenterPos + Vector3(0.5, 0, 0.5))
else
targetCenterScreenPos = CameraManager.mainCamera:WorldToScreenPoint(dragTargetCenterPos)
end
targetCenterScreenPos.z = 0
self.m_draggingOffset = targetCenterScreenPos - curMousePos
autoMoveCamExtraPadding = Unity.Vector4()
if self.m_draggingOffset.x >= 0 then
autoMoveCamExtraPadding.z = self.m_draggingOffset.x
else
autoMoveCamExtraPadding.y = -self.m_draggingOffset.x
end
if self.m_draggingOffset.y >= 0 then
autoMoveCamExtraPadding.x = self.m_draggingOffset.y
else
autoMoveCamExtraPadding.w = -self.m_draggingOffset.y
end
end
if self.m_isDragging then
LuaSystemManager.factory.canMoveCamTarget = false
self:_UpdateAutoMoveTopViewCamState(autoMoveCamExtraPadding)
end
end
FacBuildModeCtrl.m_mobileDragBeltChecker = HL.Field(HL.Any)
FacBuildModeCtrl._OnReleaseScreen = HL.Method() << function(self)
local curMousePos = self:_GetCurPointerPressPos()
if self.m_isDragging then
GameInstance.remoteFactoryManager:GridPositionTriggered(curMousePos, 3)
self.m_isDragging = false
UIManager.commonTouchPanel.enableZoom = true
self.m_draggingOffset = nil
LuaSystemManager.factory:ToggleAutoMoveTopViewCam()
elseif self.m_mobileDragBeltChecker then
self.m_mobileDragBeltChecker = self:_ClearCoroutine(self.m_mobileDragBeltChecker)
if Input.touchCount <= 1 then
GameInstance.remoteFactoryManager:GridPositionTriggered(curMousePos, 1)
self:_StartTimer(0, function()
GameInstance.remoteFactoryManager:GridPositionTriggered(curMousePos, 3)
end)
end
end
LuaSystemManager.factory.canMoveCamTarget = true
end
FacBuildModeCtrl.OnInFacMainRegionChange = HL.Method(HL.Boolean) << function(self, inMainRegion)
if inMainRegion then
return
end
if self.m_mode == FacConst.FAC_BUILD_MODE.Building then
if FactoryUtils.canPlaceBuildingOnCurRegion(self.m_buildingId) then
return
end
elseif self.m_mode == FacConst.FAC_BUILD_MODE.Logistic then
local logisticData, isLiquid = FactoryUtils.getLogisticData(self.m_buildingId)
if isLiquid then
return
end
elseif self.m_mode == FacConst.FAC_BUILD_MODE.Belt then
if self:_IsPipe() then
return
end
end
self:_ExitCurMode(false, true)
end
FacBuildModeCtrl._SetCamState = HL.Method(HL.Opt(HL.String)) << function(self, camStateName)
if LuaSystemManager.factory.inTopView then
return
end
if not camStateName then
if self.m_camState then
self.m_camState = FactoryUtils.exitFacCamera(self.m_camState)
end
return
end
if self.m_camState then
logger.error("self.m_camState Not Null", self.m_camState)
return
end
self.m_camState = FactoryUtils.enterFacCamera(camStateName)
end
FacBuildModeCtrl._OnChangeHideToggle = HL.Method(HL.Boolean) << function(self, isOn)
if isOn then
if self:_IsPipe() then
FactoryUtils.startBeltFigureRenderer()
else
FactoryUtils.startPipeFigureRenderer()
end
else
FactoryUtils.stopLogisticFigureRenderer()
end
end
FacBuildModeCtrl.ExitCurModeForCS = HL.Method(HL.Opt(HL.Any)) << function(self)
self:_ExitCurMode(false, true, true)
end
FacBuildModeCtrl._OnClickExitIcon = HL.Method() << function(self)
if self.m_mode == FacConst.FAC_BUILD_MODE.Belt and self:_InDragMode() then
local conveyorMode = GameInstance.remoteFactoryManager.interact.currentConveyorMode
if conveyorMode then
conveyorMode:TriggerConveyorKeyReset()
end
else
self:_ExitCurMode(true)
end
end
FacBuildModeCtrl.ExitCurMode = HL.Method(HL.Opt(HL.Boolean)) << function(self, skipAnim)
self:_ExitCurMode(false, skipAnim, true)
end
FacBuildModeCtrl._ExitCurMode = HL.Method(HL.Opt(HL.Boolean, HL.Boolean, HL.Boolean)) << function(self, fromClick, skipAnim, forceExit)
if not FacBuildModeCtrl.s_enableExitBuildMode and not forceExit then
return
end
if self.m_mode == FacConst.FAC_BUILD_MODE.Normal then
return
end
if self.m_mode == FacConst.FAC_BUILD_MODE.Building then
self:_CancelBuilding(skipAnim)
elseif self.m_mode == FacConst.FAC_BUILD_MODE.Logistic then
self:_CancelLogistic(skipAnim)
elseif self.m_mode == FacConst.FAC_BUILD_MODE.Belt then
self:_ExitBeltMode(skipAnim)
elseif self.m_mode == FacConst.FAC_BUILD_MODE.Blueprint then
local targets = self.m_buildArgs.batchSelectTargets
local showCreateHint = self.m_buildArgs.showCreateHint
if fromClick and targets then
self:_ExitBlueprintMode(true)
Notify(MessageConst.FAC_ENTER_DESTROY_MODE, {
fastEnter = true,
batchSelectTargets = targets,
showCreateHint = showCreateHint,
})
return
end
local csBPInst = self.m_buildArgs.csBPInst
local bpSearchInfos = self.m_buildArgs.searchInfos
if fromClick and csBPInst then
local clearScreenKey = UIManager:ClearScreen({ PANEL_ID })
self:_ExitBlueprintMode(true)
PhaseManager:OpenPhaseFast(PhaseId.FacBlueprint, { csBPInst = csBPInst, bpSearchInfos = bpSearchInfos })
UIManager:RecoverScreen(clearScreenKey)
return
end
self:_ExitBlueprintMode(skipAnim)
end
AudioAdapter.PostEvent("au_sfx_ui_fac_buiding_off")
end
FacBuildModeCtrl._ClearArgs = HL.Method() << function(self)
self.m_buildArgs = nil
self.m_itemData = nil
self.m_buildingNodeId = nil
self.m_buildingId = ""
self.m_beltId = ""
self.m_lastMouseWorldPos = nil
self:_SetCamState()
end
FacBuildModeCtrl._ExitMode = HL.Method(HL.Opt(HL.Boolean)) << function(self, skipAnim)
local oldMode = self.m_mode
if oldMode == FacConst.FAC_BUILD_MODE.Blueprint then
local mode = GameInstance.remoteFactoryManager.interact.currentBlueprintMode
mode.onPlaceBlueprint = mode.onPlaceBlueprint - self.m_onPlaceFinish
elseif oldMode == FacConst.FAC_BUILD_MODE.Building or oldMode == FacConst.FAC_BUILD_MODE.Logistic then
local mode = GameInstance.remoteFactoryManager.interact.buildingMode
mode.onPlaceBuilding = mode.onPlaceBuilding - self.m_onPlaceFinish
end
self.m_mode = FacConst.FAC_BUILD_MODE.Normal
self.view.errorHint.gameObject:SetActiveIfNecessary(false)
local onExit = self.m_buildArgs.onExit
self:_ClearArgs()
GameInstance.remoteFactoryManager.interact:ExitCurrentMode()
LuaSystemManager.factory:ToggleAutoMoveTopViewCam()
local exitAct = function()
self:Hide()
self.m_hideKey = UIManager:RecoverScreen(self.m_hideKey)
Notify(MessageConst.TOGGLE_IN_MAIN_HUD_STATE, { key = "facBuildMode", isInMainHud = true })
if onExit then
onExit()
end
if oldMode == FacConst.FAC_BUILD_MODE.Building then
Notify(MessageConst.ON_EXIT_BUILDING_MODE)
elseif oldMode == FacConst.FAC_BUILD_MODE.Logistic then
Notify(MessageConst.ON_EXIT_LOGISTIC_MODE)
elseif oldMode == FacConst.FAC_BUILD_MODE.Belt then
Notify(MessageConst.ON_EXIT_BELT_MODE)
elseif oldMode == FacConst.FAC_BUILD_MODE.Blueprint then
end
Notify(MessageConst.ON_BUILD_MODE_CHANGE, self.m_mode)
GameInstance.remoteFactoryManager.inBuildMode = false
end
if not skipAnim then
self:PlayAnimationOutWithCallback(exitAct)
else
exitAct()
end
end
FacBuildModeCtrl._UpdateCommonNodesOnEnterMode = HL.Method() << function(self)
local isBuilding = self.m_mode == FacConst.FAC_BUILD_MODE.Building
local isBelt = self.m_mode == FacConst.FAC_BUILD_MODE.Belt
local isLogistic = self.m_mode == FacConst.FAC_BUILD_MODE.Logistic
local isBlueprint = self.m_mode == FacConst.FAC_BUILD_MODE.Blueprint
local isPipe = self:_IsPipe()
local usingDrag = self:_InDragMode()
local inTopView = LuaSystemManager.factory.inTopView
if isBelt and usingDrag then
self.view.actionHint.gameObject:SetActive(true)
self:_UpdateOnBeltHasStartChanged()
else
self.view.actionHint.gameObject:SetActive(false)
end
local node = (inTopView and self.view.actionButtonsAsIcon or self.view.actionButtonsAsOption)
node.confirmButton.gameObject:SetActive(true)
node.rotateButton.gameObject:SetActive(not isBelt and self:_CanRotate())
node.rotateButton.text = isBelt and Language["ui_fac_common_logistic_rotate_mobile"] or Language["ui_fac_common_rotate_mobile"]
node.delButton.gameObject:SetActive(self:_CanDelBuilding())
if not inTopView then
node.confirmText.text = isBelt and Language.LUA_FAC_BUILD_MODE_CONFIRM_BELT_START or Language.LUA_FAC_BUILD_CONFIRM_NORMAL
end
local showHideToggle = inTopView and isBelt and FactoryUtils.canShowPipe()
self.view.hideToggle.gameObject:SetActive(showHideToggle)
self.view.hideToggle.toggle:SetIsOnWithoutNotify(showHideToggle)
self:_OnChangeHideToggle(showHideToggle)
self.view.hideToggle.beltIcon.gameObject:SetActive(isPipe)
self.view.hideToggle.pipeIcon.gameObject:SetActive(not isPipe)
local showContinueBuild = inTopView and (isBuilding or isLogistic) and DeviceInfo.usingTouch and self.m_buildingNodeId == nil
self.view.continueBuildToggle.gameObject:SetActive(showContinueBuild)
self.view.actionButtonsAsIcon.continueBuildHint.gameObject:SetActive(showContinueBuild and self.view.continueBuildToggle.isOn)
self.view.actionButtonsAsIcon.gameObject:SetActive(inTopView)
self.view.actionButtonsAsOption.gameObject:SetActive(not inTopView)
self.view.joystick.gameObject:SetActive(false)
if not isBuilding and not isBlueprint then
self.view.moveBuildingHint.gameObject:SetActive(false)
end
self.view.exitBeltModeButton.gameObject:SetActive(isBelt and usingDrag)
if isBlueprint then
if self.m_buildArgs.isMove then
self.view.modeName.text = Language.LUA_FAC_BUILD_MODE_TITLE_BATCH_MOVE
elseif self.m_buildArgs.csBPInst then
self.view.modeName.text = Language.LUA_FAC_BUILD_MODE_TITLE_BLUEPRINT
else
self.view.modeName.text = Language.LUA_FAC_BUILD_MODE_TITLE_BATCH_COPY
end
else
self.view.modeName.text = Language.LUA_FAC_BUILD_MODE_TITLE_NORMAL
end
self:_UpdatePendingHint()
self.view.normalHint.gameObject:SetActive(false)
self.view.warningHint.gameObject:SetActive(false)
if inTopView then
GameInstance.mobileMotionManager:PostEventCommonShort()
end
InputManagerInst:ToggleGroup(self.m_topViewBuildBindingGroupId, inTopView)
InputManagerInst:ToggleGroup(self.m_rpgBuildBindingGroupId, not inTopView)
end
FacBuildModeCtrl._UpdatePendingHint = HL.Method() << function(self)
local isBlueprint = self.m_mode == FacConst.FAC_BUILD_MODE.Blueprint
local isPending = false
if isBlueprint and not self.m_buildArgs.isMove then
local bp = self.m_buildArgs.blueprint or self.m_buildArgs.csBPInst.info.bp or self.m_buildArgs[1]
local needItems = {}
for _, entry in pairs(bp.buildingNodes) do
local itemId = FactoryUtils.getBuildingItemId(entry.templateId)
if itemId then
if needItems[itemId] then
needItems[itemId] = needItems[itemId] + 1
else
needItems[itemId] = 1
end
end
end
for itemId, count in pairs(needItems) do
if Utils.getItemCount(itemId, true, true) < count then
isPending = true
break
end
end
end
self.view.pendingHint.gameObject:SetActive(isPending)
end
local KeyHints = {
newBuilding = {
"fac_rotate_device",
"fac_build_confirm",
"fac_build_cancel_alter",
},
newBuildingInTopView = {
"fac_rotate_device",
"fac_build_confirm",
"fac_build_continuous_confirm",
"fac_build_cancel_alter",
},
oldBuilding = {
"fac_build_mode_delete",
"fac_rotate_device",
"fac_build_confirm",
"fac_build_cancel_alter",
},
blueprint = {
"fac_rotate_device",
"fac_build_confirm",
"fac_build_cancel",
},
logistic = {
"fac_rotate_device",
"fac_build_confirm",
"fac_build_cancel_alter",
},
logisticInTopView = {
"fac_rotate_device",
"fac_build_confirm",
"fac_build_continuous_confirm",
"fac_build_cancel_alter",
},
beltStart = {
"fac_build_confirm_belt_start",
"fac_build_rotate_belt",
"fac_build_cancel_alter",
},
beltEnd = {
"fac_build_confirm_belt_end",
"fac_build_rotate_belt",
"fac_build_cancel_alter",
},
pipeStart = {
"fac_build_confirm_belt_start",
"fac_build_rotate_pipe",
"fac_build_cancel_alter",
},
pipeEnd = {
"fac_build_confirm_belt_end",
"fac_build_rotate_pipe",
"fac_build_cancel_alter",
},
signBuilding = {
"fac_rotate_device",
"fac_build_confirm",
"fac_build_sign_reset",
"fac_build_cancel_alter",
},
}
FacBuildModeCtrl.m_keyHintCells = HL.Field(HL.Forward('UIListCache'))
FacBuildModeCtrl._InitKeyHint = HL.Method() << function(self)
self.m_keyHintCells = UIUtils.genCellCache(self.view.keyHintCell)
end
FacBuildModeCtrl._RefreshKeyHint = HL.Method(HL.Opt(HL.Table)) << function(self, keyHint)
if not keyHint then
self.m_keyHintCells:Refresh(0)
return
end
if DeviceInfo.usingController and LuaSystemManager.factory.inTopView then
keyHint = {}
end
local count = #keyHint
local preActionIds, preActionIdCount
if LuaSystemManager.factory.inTopView then
preActionIds = DeviceInfo.usingController and FacConst.FAC_TOP_VIEW_BASIC_ACTION_IDS_FOR_CONTROLLER or FacConst.FAC_TOP_VIEW_BASIC_ACTION_IDS
preActionIdCount = #preActionIds
count = count + preActionIdCount
else
preActionIds = { "cam_zoom_in_ct", }
preActionIdCount = #preActionIds
count = count + preActionIdCount
end
self.m_keyHintCells:Refresh(count, function(cell, index)
local actionId
if preActionIds then
actionId = preActionIds[index] or keyHint[index - preActionIdCount]
else
actionId = keyHint[index]
end
if LuaSystemManager.factory.inTopView then
if actionId == "fac_build_confirm" then
actionId = "fac_build_confirm_in_top_view"
elseif actionId == "fac_build_confirm_belt_start" then
actionId = "fac_build_confirm_belt_start_in_top_view"
end
end
cell.actionKeyHint:SetActionId(actionId)
cell.gameObject.name = "KeyHint-" .. actionId
end)
end
FacBuildModeCtrl.m_curBuildIsValid = HL.Field(HL.Boolean) << true
FacBuildModeCtrl._GetBuildingCheckResultHint = HL.Method(HL.Userdata).Return(HL.Boolean, HL.Opt(HL.String)) << function(self, checkResult)
local valid, hint = checkResult.success, nil
if not valid then
if checkResult.busLimited then
hint = Language.LUA_FAC_BUILD_MODE_ROAD_ATTACH
elseif checkResult.buildableInChapterLimit then
local hintSet = false
if self.m_buildingId and not self.m_buildingId:isEmpty() then
local limitChapters = CSFactoryUtil.GetLimitedChapterNames(self.m_buildingId)
local nameCount = limitChapters.Count
if nameCount == 1 then
hint = string.format(Language.LUA_FAC_BUILD_MODE_CHAPTER_BUILDABLE_LIMIT_FORMAT_1, limitChapters[0])
hintSet = true
elseif nameCount == 2 then
hint = string.format(Language.LUA_FAC_BUILD_MODE_CHAPTER_BUILDABLE_LIMIT_FORMAT_2, limitChapters[0], limitChapters[1])
hintSet = true
elseif nameCount >= 3 then
hint = string.format(Language.LUA_FAC_BUILD_MODE_CHAPTER_BUILDABLE_LIMIT_FORMAT_3, limitChapters[0], limitChapters[1])
hintSet = true
end
end
if not hintSet then
hint = Language.LUA_FAC_BUILD_MODE_CHAPTER_BUILDABLE_LIMIT_DEFAULT
end
elseif checkResult.totalCountInChapterLimit then
if self.m_buildingId and not self.m_buildingId:isEmpty() then
local buildingData = Tables.factoryBuildingTable:GetValue(self.m_buildingId)
local buildingName = buildingData and buildingData.name or ""
hint = string.format(Language.LUA_FAC_BUILD_MODE_CHAPTER_BUILDING_COUNT_LIMIT_FORMAT, buildingName)
else
hint = Language.LUA_FAC_BUILD_MODE_CHAPTER_BUILDING_COUNT_LIMIT_DEFAULT
end
elseif checkResult.bandwidthLimited then
hint = Language.LUA_FAC_BUILD_MODE_ON_BANDWIDTH_MAX
elseif checkResult.mainRegionLimited then
if GameInstance.remoteFactoryManager.interact.isInBlueprintMode then
hint = Language.LUA_FAC_BUILD_MODE_MAIN_REGION_LIMITED_BLUEPRINT
else
hint = Language.LUA_FAC_BUILD_MODE_MAIN_REGION_LIMITED
end
elseif checkResult.freeBusCountLimit then
if self.m_buildingId and not self.m_buildingId:isEmpty() then
local buildingData = Tables.factoryBuildingTable:GetValue(self.m_buildingId)
local buildingName = buildingData and buildingData.name or ""
hint = string.format(Language.LUA_FAC_BUILD_MODE_FREE_BUS_COUNT_OVER_LIMIT, buildingName)
else
hint = Language.LUA_FAC_BUILD_MODE_FREE_BUS_COUNT_OVER_LIMIT_DEFAULT
end
elseif checkResult.cropAreaLimited then
hint = Language.LUA_FAC_BUILD_MODE_ON_CROP_AREA_ONLY
elseif checkResult.cropCntLimited then
hint = Language.LUA_FAC_BUILD_MODE_ON_CROP_COUNT_LIMITED
elseif checkResult.travelPoleCountLimited then
hint = Language.LUA_FAC_BUILD_MODE_ON_TRAVEL_POLE_COUNT_MAX
elseif checkResult.battleCountLimited then
hint = Language.LUA_FAC_BUILD_MODE_ON_BATTLE_COUNT_MAX
elseif checkResult.mineLimited then
hint = Language.LUA_FAC_BUILD_MODE_ON_MINE_ONLY
elseif checkResult.mineTypeLimited then
hint = Language.LUA_FAC_BUILD_MODE_ON_WRONG_MINE_TYPE
elseif checkResult.mineLevelLimited then
hint = Language.LUA_FAC_BUILD_MODE_MINE_LEVEL_LIMITED
elseif checkResult.buildableWaterLimited then
hint = Language.LUA_FAC_BUILD_MODE_IN_WATER_LIMITED
elseif checkResult.buildableLimited then
hint = Language.LUA_FAC_BUILD_MODE_IN_BUILDABLE_RANGE_BUT_HAS_INVALID_GRID
elseif checkResult.occludedByArea then
hint = Language.LUA_FAC_BUILD_MODE_OCCLUDED_BY_AREA
elseif checkResult.crossDivisionBoundary then
hint = Language.LUA_FAC_BUILD_MODE_CROSS_DIVISION_BOUNDARY
elseif checkResult.overlayWithBlueprintNode
or (checkResult.overlayNodes and checkResult.overlayNodes.Count > 0)
or (checkResult.overlayPendingNodes and checkResult.overlayPendingNodes.Count > 0) then
hint = Language.LUA_FAC_BUILD_MODE_BUILDING_OVERLAP
elseif checkResult.outRanged then
hint = Language.LUA_FAC_BUILD_MODE_OUT_OF_RANGE
elseif checkResult.outOfHeight then
hint = Language.LUA_FAC_BUILD_MODE_HEIGHT_OVER_TOOMUCH
elseif checkResult.groundTooUneven then
hint = Language.LUA_FAC_BUILD_MODE_GROUND_TOO_UNEVEN
elseif checkResult.collideWithMap then
hint = Language.LUA_FAC_BUILD_MODE_SPACE_HEIGHT_NOT_ENOUGH
elseif checkResult.blockedByInter then
hint = Language.LUA_FAC_BUILD_MODE_BLOCK_BY_DYNAMIC_ENTITY
elseif checkResult.blockedByErosion then
hint = Language.LUA_FAC_BUILD_MODE_BLOCK_WITH_EROSION
elseif checkResult.pumpReachLiquidLimited then
hint = Language.LUA_FAC_BUILD_MODE_PUMP_MUST_REACH_LIQUID
elseif checkResult.dumpReachLiquidLimited then
hint = Language.LUA_FAC_BUILD_MODE_DUMP_MUST_REACH_LIQUID
elseif checkResult.noSoilForWaterSpray then
hint = Language.LUA_FAC_BUILD_MODE_NO_SOIL_IN_SPRAY
elseif checkResult.moveAcrossScene then
hint = Language.LUA_FAC_BUILD_MODE_MOVE_ACROSS_SCENE
elseif checkResult.notAlongLogistic then
hint = Language.LUA_FAC_BUILD_MODE_NOT_ALONG_LOGISTIC_DIRECTION
elseif checkResult.notPutOnConveyor then
if self.m_buildingId and not self.m_buildingId:isEmpty() then
if Tables.factoryFluidValveTable:ContainsKey(self.m_buildingId) then
hint = Language.LUA_FAC_BUILD_MODE_VALVE_NOT_ON_CONVEYOR_FLUID
end
end
if not hint then
hint = Language.LUA_FAC_BUILD_MODE_VALVE_NOT_ON_CONVEYOR_BOX
end
elseif checkResult.minDistanceLimitNodes and checkResult.minDistanceLimitNodes.Count > 0 then
hint = Language.LUA_FAC_BUILD_MODE_MIN_DISTANCE_LIMIT
elseif checkResult.medicRangeOverlap then
hint = Language.LUA_FAC_BUILD_MODE_MEDIC_RANGE_OVERLAP
elseif checkResult.overlayMineIndex and checkResult.overlayMineIndex.Count > 0 then
hint = Language.LUA_FAC_BUILD_MODE_MINE_OVERLAP
elseif checkResult.domainModeLimited then
if self.m_buildingId and not self.m_buildingId:isEmpty() then
local buildingData = Tables.factoryBuildingTable:GetValue(self.m_buildingId)
local buildingName = buildingData and buildingData.name or ""
hint = string.format(
Language.LUA_FAC_BUILD_MODE_CHAPTER_MODE_LIMIT_FORMAT,
GameInstance.remoteFactoryManager.currentChapterInfo.data.name, buildingName
)
else
hint = Language.LUA_FAC_BUILD_MODE_OTHERS
end
elseif checkResult.freeBusNoConnectSource then
hint = Language.LUA_FAC_BUILD_MODE_FREE_BUS_NO_CONNECTION_TO_START
else
hint = Language.LUA_FAC_BUILD_MODE_OTHERS
end
end
return valid, hint
end
FacBuildModeCtrl._GetConveyorCheckResultHint = HL.Method(HL.Userdata, HL.Boolean).Return(HL.Boolean, HL.Opt(HL.String)) << function(self, checkResult, isPipe)
local valid, hint = checkResult.success, nil
if not valid then
if checkResult.mainRegionLimited then
if GameInstance.remoteFactoryManager.interact.isInBlueprintMode then
hint = Language.LUA_FAC_BUILD_MODE_MAIN_REGION_LIMITED_BLUEPRINT
else
hint = Language.LUA_FAC_BUILD_MODE_MAIN_REGION_LIMITED
end
elseif checkResult.buildableLimited then
hint = Language.LUA_FAC_BUILD_MODE_IN_BUILDABLE_RANGE_BUT_HAS_INVALID_GRID
elseif checkResult.occludedByArea then
hint = Language.LUA_FAC_BUILD_MODE_OCCLUDED_BY_AREA
elseif checkResult.hasSelfOverlay then
hint = isPipe and Language.LUA_FAC_BUILD_MODE_PIPE_SELF_OVERLAP or Language.LUA_FAC_BUILD_MODE_BELT_SELF_OVERLAP
elseif checkResult.pipeAngleLimited then
hint = Language.LUA_FAC_BUILD_MODE_PIPE_ANGLE_LIMITED
elseif (checkResult.overlayNodes and checkResult.overlayNodes.Count > 0)
or (checkResult.overlayPendingNodes and checkResult.overlayPendingNodes.Count > 0) then
hint = Language.LUA_FAC_BUILD_MODE_BUILDING_OVERLAP
elseif checkResult.directionConflictLogisticUnits and checkResult.directionConflictLogisticUnits.Count > 0 then
hint = isPipe and Language.LUA_FAC_BUILD_MODE_DIRECTION_CONFLICT_LOGISTIC_UNIT_PIPE or Language.LUA_FAC_BUILD_MODE_DIRECTION_CONFLICT_LOGISTIC_UNIT_BELT
elseif checkResult.overLengthLimit then
hint = isPipe and Language.LUA_FAC_BUILD_MODE_PIPE_OVER_LENGTH_LIMIT or Language.LUA_FAC_BUILD_MODE_BELT_OVER_LENGTH_LIMIT
elseif checkResult.shapeInvalid then
hint = isPipe and Language.LUA_FAC_BUILD_MODE_PIPE_SHAPE_INVALID or Language.LUA_FAC_BUILD_MODE_BELT_SHAPE_INVALID
elseif checkResult.pipeStartModeLimited then
hint = Language.LUA_FAC_BUILD_MODE_START_NODE_PIPE_MODE_LIMITED
elseif checkResult.pipeEndModeLimited then
hint = Language.LUA_FAC_BUILD_MODE_END_NODE_PIPE_MODE_LIMITED
elseif checkResult.pipeStartPortLimited then
hint = Language.LUA_FAC_BUILD_MODE_START_NODE_PIPE_PORT_LIMITED
elseif checkResult.pipeEndPortLimited then
hint = Language.LUA_FAC_BUILD_MODE_END_NODE_PIPE_PORT_LIMITED
elseif checkResult.overlayMineIndex and checkResult.overlayMineIndex.Count > 0 then
hint = Language.LUA_FAC_BUILD_MODE_MINE_OVERLAP
elseif checkResult.domainModeLimited then
local pipeData = Tables.factoryLiquidPipeTable:GetValue("log_pipe_01")
local buildingName = pipeData and pipeData.pipeData.name or ""
hint = string.format(
Language.LUA_FAC_BUILD_MODE_CHAPTER_MODE_LIMIT_FORMAT,
GameInstance.remoteFactoryManager.currentChapterInfo.data.name, buildingName
)
else
hint = Language.LUA_FAC_BUILD_MODE_OTHERS
end
end
return valid, hint
end
FacBuildModeCtrl._UpdateValidResult = HL.Method() << function(self)
if self.m_mode == FacConst.FAC_BUILD_MODE.Normal then
return
end
local inDragMode = self:_InDragMode()
local valid, errorHint, moving = false, nil, false
local actionHint, warningHint, normalHint
if self.m_mode == FacConst.FAC_BUILD_MODE.Building or self.m_mode == FacConst.FAC_BUILD_MODE.Logistic then
local rst = GameInstance.remoteFactoryManager.interact.currentBuildingMode.addBuildingCheckResult
valid, errorHint = self:_GetBuildingCheckResultHint(rst)
if valid then
local pos, rot = GameInstance.remoteFactoryManager.interact.currentBuildingMode:GetPreviewRenderInfo()
CS.Beyond.Gameplay.Conditions.OnFacPrepareBuildingEnterArea.Trigger(self.m_buildingId, pos, rot.y)
local buildingMode = GameInstance.remoteFactoryManager.interact.currentBuildingMode
local autoConnect = buildingMode.autoConnectCandidateList
local inFac = buildingMode.inMainRegion or false
if autoConnect ~= nil and autoConnect.Count > 0 then
actionHint = inFac and Language.LUA_POWER_AUTOCONNECT_INFAC_HINT or Language.LUA_POWER_AUTOCONNECT_BUILD_MODE_HINT
elseif FacConst.POLE_RANGE_EFFECT_MAP[self.m_buildingId] and inFac then
actionHint = Language.LUA_POWER_AUTOCONNECT_INFAC_HINT
end
if not self:_CheckSignCanBuild() then
actionHint = Language.LUA_MARKER_BUILD_COUNT_MAX
end
end
moving = GameInstance.remoteFactoryManager.interact.currentBuildingMode.isMoving
elseif self.m_mode == FacConst.FAC_BUILD_MODE.Belt then
local conveyorMode = GameInstance.remoteFactoryManager.interact.currentConveyorMode
local rst = conveyorMode.checkResult
local isPipe = self:_IsPipe()
valid = conveyorMode.hasStart or conveyorMode.hasPrecalculatedPort
if not valid then
if not inDragMode then
if conveyorMode.usePipePreview then
errorHint = Language.LUA_FAC_BUILD_MODE_PIPE_CANNOT_FROM_EMPTY
else
errorHint = Language.LUA_FAC_BUILD_MODE_CONVEYOR_CANNOT_FROM_EMPTY
end
end
end
if valid then
valid, errorHint = self:_GetConveyorCheckResultHint(rst, isPipe)
end
if valid then
valid, errorHint = self:_GetBuildingCheckResultHint(GameInstance.remoteFactoryManager.interact.currentConveyorMode.additionalBuildingCheckResult)
end
if valid then
local hasEnd, endPos
if conveyorMode.hasStart then
hasEnd, endPos = conveyorMode:GetEndPosVector3()
end
if hasEnd then
endPos = endPos + Vector3(0.5, 0, 0.5)
local endPos2 = (isPipe and self.m_pipePreviewMark or self.m_beltStartPreviewMark).transform.position
if (endPos - endPos2):XZ().sqrMagnitude <= 0.1 then
CS.Beyond.Gameplay.Conditions.OnFacPrepareBuildingEnterArea.Trigger(self.m_beltId, endPos, 0)
end
else
local mark = isPipe and self.m_pipePreviewMark or self.m_beltStartPreviewMark
endPos = mark.transform.position
CS.Beyond.Gameplay.Conditions.OnFacPrepareBuildingEnterArea.Trigger(self.m_beltId, endPos, 0)
end
end
if valid and errorHint == nil then
if conveyorMode:HasMismatchedEndPort() then
if conveyorMode.usePipePreview then
warningHint = Language.LUA_FAC_BUILD_MODE_PIPE_END_PORT_REVERSE
else
warningHint = Language.LUA_FAC_BUILD_MODE_CONVEYOR_END_PORT_REVERSE
end
elseif conveyorMode.hasStart then
if not conveyorMode.endNodeHandler and not conveyorMode:HasEndJointNode() then
normalHint = isPipe and Language.LUA_FAC_BUILD_MODE_PIPE_END_IS_EMPTY or Language.LUA_FAC_BUILD_MODE_BELT_END_IS_EMPTY
end
end
end
elseif self.m_mode == FacConst.FAC_BUILD_MODE.Blueprint then
local curMode = GameInstance.remoteFactoryManager.interact.currentBlueprintMode
local buildingRst = curMode.addBuildingCheckResult
valid, errorHint = self:_GetBuildingCheckResultHint(buildingRst)
if valid then
local conveyorRst = curMode.addConveyorCheckResult
valid, errorHint = self:_GetConveyorCheckResultHint(conveyorRst, false)
end
if valid then
local pipeRst = curMode.addPipeCheckResult
valid, errorHint = self:_GetConveyorCheckResultHint(pipeRst, true)
end
moving = curMode.isMoving
if valid and self.m_buildArgs.isSystemBP then
local dir = curMode.preparedDirection * 90
local pos = Vector3(curMode.preparedPosition.x, curMode.preparedPosition.y, curMode.preparedPosition.z)
CS.Beyond.Gameplay.Conditions.OnFacPrepareBuildingEnterArea.Trigger(self.m_buildArgs.sysBpKey, pos, dir)
end
end
if errorHint then
if not self.view.errorHint.gameObject.activeInHierarchy then
UIUtils.PlayAnimationAndToggleActive(self.view.errorHint, true)
end
self.view.errorHintText:SetAndResolveTextStyle(errorHint)
else
if self.view.errorHint.gameObject.activeInHierarchy and self.view.errorHint.curState ~= UIConst.UI_ANIMATION_WRAPPER_STATE.Out then
UIUtils.PlayAnimationAndToggleActive(self.view.errorHint, false)
end
end
if inDragMode and self.m_mode == FacConst.FAC_BUILD_MODE.Belt then
self.view.actionHint.gameObject:SetActive(errorHint == nil)
else
if actionHint then
if not self.view.actionHint.gameObject.activeInHierarchy then
UIUtils.PlayAnimationAndToggleActive(self.view.actionHint, true)
end
self.view.actionHintTxt:SetAndResolveTextStyle(actionHint)
else
if self.view.actionHint.gameObject.activeInHierarchy and self.view.actionHint.curState ~= UIConst.UI_ANIMATION_WRAPPER_STATE.Out then
UIUtils.PlayAnimationAndToggleActive(self.view.actionHint, false)
end
end
end
if warningHint then
if not self.view.warningHint.gameObject.activeInHierarchy then
UIUtils.PlayAnimationAndToggleActive(self.view.warningHint, true)
end
self.view.warningHintTxt:SetAndResolveTextStyle(warningHint)
else
if self.view.warningHint.gameObject.activeInHierarchy and self.view.warningHint.curState ~= UIConst.UI_ANIMATION_WRAPPER_STATE.Out then
UIUtils.PlayAnimationAndToggleActive(self.view.warningHint, false)
end
end
if normalHint then
if not self.view.normalHint.gameObject.activeInHierarchy then
UIUtils.PlayAnimationAndToggleActive(self.view.normalHint, true)
end
self.view.normalHintTxt:SetAndResolveTextStyle(normalHint)
else
if self.view.normalHint.gameObject.activeInHierarchy and self.view.normalHint.curState ~= UIConst.UI_ANIMATION_WRAPPER_STATE.Out then
UIUtils.PlayAnimationAndToggleActive(self.view.normalHint, false)
end
end
self.m_curBuildIsValid = valid
GameInstance.remoteFactoryManager:SetPreviewUnitState(valid, moving)
end
FacBuildModeCtrl._UpdateAutoConnectExtraHint = HL.Method() << function(self)
local buildingMode = GameInstance.remoteFactoryManager.interact.currentBuildingMode
if not buildingMode then
return
end
local autoConnect = buildingMode.autoConnectCandidateList
if not autoConnect then
return
end
local status = CS.Beyond.Gameplay.Factory.PowerAutoConnectStatus
local notInPower, noPower = true, false
for i = 0, autoConnect.Count - 1 do
local info = autoConnect[i]
if info.Item5 == status.Outage then
noPower = true
notInPower = false
break
elseif info.Item5 ~= status.LocalLink and info.Item5 ~= status.DistLimit then
notInPower = false
end
end
local moving = GameInstance.remoteFactoryManager.interact.currentBuildingMode.isMoving
self.view.moveBuildingHint.gameObject:SetActiveIfNecessary(moving or notInPower or noPower)
self.view.rebuildInfoTxt.gameObject:SetActiveIfNecessary(moving)
self.view.noPowerTxt.gameObject:SetActiveIfNecessary(notInPower)
self.view.noElectricity.gameObject:SetActiveIfNecessary(noPower)
end
FacBuildModeCtrl._EnterBuildingMode = HL.Method(HL.Table) << function(self, args)
if self.m_mode == FacConst.FAC_BUILD_MODE.Building then
if self.m_buildArgs.onExit then
self.m_buildArgs.onExit()
end
self:_SetCamState()
elseif self.m_mode == FacConst.FAC_BUILD_MODE.Logistic then
self:_ExitLogisticMode()
elseif self.m_mode == FacConst.FAC_BUILD_MODE.Belt then
self:_ExitBeltMode()
elseif self.m_mode == FacConst.FAC_BUILD_MODE.Blueprint then
self:_ExitBlueprintMode()
end
self.m_isDragging = false
UIManager.commonTouchPanel.enableZoom = true
self.m_buildArgs = args
local buildingId, itemData
local nodeId = args.nodeId
local mousePos
if args.initMousePos then
mousePos = Vector3(args.initMousePos.x, args.initMousePos.y, 0)
else
mousePos = self:_InDragMode() and Vector3(Screen.width / 2, Screen.height / 2, 0) or self:_GetCurPointerPressPos()
end
local camRay = CameraManager.mainCamera:ScreenPointToRay(mousePos)
local _, initWorldPos = CSFactoryUtil.SampleLevelRegionPointWithRay(camRay)
local initGridPos = GameInstance.remoteFactoryManager.visual:WorldToVoxel(initWorldPos)
initGridPos = Unity.Vector3Int(math.floor(initGridPos.x), math.floor(initGridPos.y), math.floor(initGridPos.z))
if nodeId then
self.m_buildingNodeId = nodeId
local node = FactoryUtils.getBuildingNodeHandler(nodeId)
buildingId = node.templateId
itemData = FactoryUtils.getBuildingItemData(buildingId)
self:_RefreshKeyHint(KeyHints.oldBuilding)
local face = lume.round(node.transform.direction.y / 90)
if not args.initMousePos and DeviceInfo.usingTouch and LuaSystemManager.factory.inTopView then
local bData = Tables.factoryBuildingTable[buildingId]
local rectInt = CS.UnityEngine.RectInt(bData.range.x, bData.range.z, bData.range.width, bData.range.depth)
local offset = CS.Beyond.Gameplay.RemoteFactory.GridMath.CenterMatchOffset(rectInt, face)
initGridPos = node.transform.position - Unity.Vector3Int(offset.x, 0, offset.y)
end
GameInstance.remoteFactoryManager.interact:SwitchToBuildingModeAsMove(nodeId, initGridPos, face)
self.view.moveBuildingHint.gameObject:SetActive(true)
else
self.m_buildingNodeId = nil
local itemId = args.itemId
itemData = Tables.itemTable[itemId]
local buildingItemData = Tables.factoryBuildingItemTable[itemId]
buildingId = buildingItemData.buildingId
self:_RefreshKeyHint(LuaSystemManager.factory.inTopView and KeyHints.newBuildingInTopView or KeyHints.newBuilding)
local initDir = math.floor(((CameraManager.mainCamera.transform.eulerAngles.y + 45) % 360) / 90) % 4
if FacConst.SIGN_BUILDING_EXTRA_SETTING_PANEL[buildingId] then
initDir = (initDir + 1) % 4
end
GameInstance.remoteFactoryManager.interact:SwitchToBuildingMode(buildingId, initGridPos, initDir)
self.view.moveBuildingHint.gameObject:SetActive(false)
local mode = GameInstance.remoteFactoryManager.interact.buildingMode
mode.onPlaceBuilding = mode.onPlaceBuilding - self.m_onPlaceFinish
mode.onPlaceBuilding = mode.onPlaceBuilding + self.m_onPlaceFinish
end
self.m_buildingId = buildingId
self.m_itemData = itemData
self:_UpdateValidResult()
self:_UpdateAutoConnectExtraHint()
self.m_mode = FacConst.FAC_BUILD_MODE.Building
do
if self.m_powerPoleRange then
if self.m_powerPoleRange.gameObject then
GameObject.Destroy(self.m_powerPoleRange.gameObject)
end
self.m_powerPoleRange = nil
end
local effectPath = FacConst.POLE_RANGE_EFFECT_MAP[self.m_buildingId]
if effectPath then
local prefab = self.loader:LoadGameObject(effectPath)
local obj = self:_CreateWorldGameObject(prefab)
self.m_powerPoleRange = Utils.wrapLuaNode(obj)
obj.gameObject:SetActive(false)
end
end
self:_UpdateBuildingFollowerState(true)
local bData = Tables.factoryBuildingTable[self.m_buildingId]
self:_SetCamState(bData.buildCamState)
Notify(MessageConst.ON_BUILD_MODE_CHANGE, self.m_mode)
Notify(MessageConst.ON_ENTER_BUILDING_MODE, itemData.id)
self:_NotifyPowerPoleTravelHint()
self:_UpdateCommonNodesOnEnterMode()
if not self:_InDragMode() then
self:_Tick()
end
self:_ProcessSignBuildSetting()
end
FacBuildModeCtrl._ExitBuildingMode = HL.Method(HL.Opt(HL.Boolean)) << function(self, skipAnim)
if self.m_mode ~= FacConst.FAC_BUILD_MODE.Building then
return
end
self.m_sizeIndicator.gameObject:SetActiveIfNecessary(false)
if self.m_powerPoleRange then
if self.m_powerPoleRange.gameObject then
GameObject.Destroy(self.m_powerPoleRange.gameObject)
end
self.m_powerPoleRange = nil
end
self.m_fluidSprayRange.gameObject:SetActive(false)
self.m_battleRange.gameObject:SetActive(false)
self:_ResetMoveBuildingHintState()
self:_ExitMode(skipAnim)
end
FacBuildModeCtrl._ResetMoveBuildingHintState = HL.Method() << function(self)
self.view.moveBuildingHint.gameObject:SetActiveIfNecessary(false)
self.view.rebuildInfoTxt.gameObject:SetActive(true)
self.view.noPowerTxt.gameObject:SetActive(false)
self.view.noElectricity.gameObject:SetActive(false)
end
FacBuildModeCtrl._NotifyPowerPoleTravelHint = HL.Method() << function(self)
if self.m_mode ~= FacConst.FAC_BUILD_MODE.Building then
return
end
local pos, rot = GameInstance.remoteFactoryManager.interact.currentBuildingMode:GetPreviewRenderInfo()
if not self.m_buildingNodeId then
Notify(MessageConst.ON_BUILD_POWER_POLE_TRAVEL_HINT, {
buildingTypeId = self.m_buildingId,
position = pos
})
else
Notify(MessageConst.ON_MOVE_POWER_POLE_TRAVEL_HINT, {
buildingTypeId = self.m_buildingId,
position = pos,
nodeId = self.m_buildingNodeId,
})
end
end
FacBuildModeCtrl._ConfirmBuilding = HL.Method() << function(self)
if not self:_CheckSignCanBuild() then
self.m_lockBuildPos = true
UIManager:AutoOpen(PanelId.FacMarkerManagePopup, {
onClose = function()
self.m_lockBuildPos = false
end
})
return
end
self:_Tick()
if not self.m_curBuildIsValid then
Notify(MessageConst.SHOW_TOAST, self.view.errorHintText.text)
AudioAdapter.PostEvent("au_ui_fac_unbuildable")
return
end
local buildingItemId = self.m_itemData.id
local mousePos = self:_GetCurPointerPressPos()
GameInstance.remoteFactoryManager:GridPositionTriggered(mousePos, 0)
local isNewBuilding = self.m_buildingNodeId == nil
if isNewBuilding then
if self:_EnableContinueBuild() then
local count = Utils.getItemCount(buildingItemId)
if count <= 1 then
self:_ExitBuildingMode()
Notify(MessageConst.SHOW_TOAST, Language.LUA_FAC_BUILD_CONTINUOUS_STOPPED)
end
else
self:_ExitBuildingMode()
end
else
self:_ExitBuildingMode()
AudioAdapter.PostEvent("au_ui_fac_building_move_set")
end
end
FacBuildModeCtrl._CancelBuilding = HL.Method(HL.Opt(HL.Boolean)) << function(self, skipAnim)
local onCancel = self.m_buildArgs.onCancel
if onCancel then
onCancel()
end
self:_ExitBuildingMode(skipAnim)
end
FacBuildModeCtrl._DelBuilding = HL.Method() << function(self)
if not self:_CanDelBuilding() then
return
end
GameInstance.player.remoteFactory.core:Message_OpDismantle(Utils.getCurrentChapterId(), self.m_buildingNodeId, function()
self:_ExitBuildingMode()
end)
end
FacBuildModeCtrl._CanDelBuilding = HL.Method().Return(HL.Boolean) << function(self)
if self.m_mode ~= FacConst.FAC_BUILD_MODE.Building then
return false
end
local nodeId = self.m_buildingNodeId
if not nodeId then
return false
end
return FactoryUtils.canDelBuilding(self.m_buildingNodeId)
end
FacBuildModeCtrl._RotateUnit = HL.Method() << function(self)
if not self:_CanRotate() then
return
end
GameInstance.remoteFactoryManager.interact:InputKeyRotation(true)
self:_UpdateBuildingFollowerState(false)
if DeviceInfo.usingKeyboard then
self:_UpdateAutoMoveTopViewCamState()
end
AudioAdapter.PostEvent("au_ui_building_turn")
if self.m_mode == FacConst.FAC_BUILD_MODE.Blueprint then
self:_SetBluePrintSelectGrids(self.m_lastBPGridPos)
end
end
FacBuildModeCtrl._CanRotate = HL.Method().Return(HL.Boolean) << function(self)
if self.m_mode == FacConst.FAC_BUILD_MODE.Normal then
return false
elseif self.m_mode == FacConst.FAC_BUILD_MODE.Logistic then
if FacConst.FAC_VALVE_NODE_IDS[self.m_buildingId] then
return false
end
end
return true
end
FacBuildModeCtrl._UpdateAutoMoveTopViewCamState = HL.Method(HL.Opt(HL.Any)) << function(self, extraPadding)
if not LuaSystemManager.factory.inTopView then
return
end
local size
if self.m_mode == FacConst.FAC_BUILD_MODE.Building then
size = Vector2.one
elseif self.m_mode == FacConst.FAC_BUILD_MODE.Logistic then
size = Vector2.one
elseif self.m_mode == FacConst.FAC_BUILD_MODE.Belt then
size = Vector2.one
elseif self.m_mode == FacConst.FAC_BUILD_MODE.Blueprint then
size = Vector2.one
end
LuaSystemManager.factory:ToggleAutoMoveTopViewCam(size, extraPadding)
end
FacBuildModeCtrl._UpdateBuildingFollowerState = HL.Method(HL.Boolean) << function(self, isInit)
if self.m_mode ~= FacConst.FAC_BUILD_MODE.Building then
return
end
local data = Tables.factoryBuildingTable:GetValue(self.m_buildingId)
self.m_sizeIndicator.gameObject:SetActiveIfNecessary(true)
self.m_sizeIndicator.followerObject.getTargetPosInfo = function(pos, rot)
pos, rot = GameInstance.remoteFactoryManager.interact.currentBuildingMode:GetPreviewRenderInfo()
return pos, rot
end
local scale = Vector3(data.range.width, data.modelHeight, data.range.depth)
local reverseScale = Vector3(1 / scale.x, 1 / scale.y, 1 / scale.z)
self.m_sizeIndicator.transform.localScale = scale
self.m_sizeIndicator.transform:DoActionOnChildren(function(childTrans)
childTrans.localScale = reverseScale
end)
if isInit then
if self.m_powerPoleRange then
local powerPoleData = GameInstance.remoteFactoryManager.staticData:QueryPowerPoleData(self.m_buildingId)
if powerPoleData and GameInstance.remoteFactoryManager.powerPoleConditionQuery:QueryDiffuserEnabled(powerPoleData) then
local poleData = Tables.factoryPowerPoleTable[self.m_buildingId]
local extSizeW = poleData.rangeExtend.x
local extSizeH = poleData.rangeExtend.z
if extSizeW > 0 or extSizeH > 0 then
self.m_powerPoleRange.gameObject:SetActive(true)
self.m_powerPoleRange.followerObject.getTargetPosInfo = function(pos, rot)
pos, rot = GameInstance.remoteFactoryManager.interact.currentBuildingMode:GetPreviewRenderInfo()
return pos, rot
end
end
end
end
end
if isInit and data.type == GEnums.FacBuildingType.FluidSpray then
local fluidSprayData = Tables.factoryFluidSprayTable[self.m_buildingId]
local localCenterPosX = fluidSprayData.squirterOffset.x + fluidSprayData.squirterRange.x * 0.5 - data.range.width * 0.5
local localCenterPosY = fluidSprayData.squirterOffset.y
local localCenterPosZ = fluidSprayData.squirterOffset.z + fluidSprayData.squirterRange.z * 0.5 - data.range.depth * 0.5
self.m_fluidSprayRange.gameObject:SetActive(true)
self.m_fluidSprayRange.followerObject.getTargetPosInfo = function(pos, rot)
pos, rot = GameInstance.remoteFactoryManager.interact.currentBuildingMode:GetPreviewRenderInfo()
local q = Quaternion.Euler(rot.x, rot.y, rot.z)
local m = Unity.Matrix4x4.TRS(pos, q, Vector3.one)
pos = m:MultiplyPoint3x4(Vector3(localCenterPosX, localCenterPosY, localCenterPosZ))
return pos, rot
end
end
if isInit and data.type == GEnums.FacBuildingType.Battle then
local battleData = Tables.factoryBattleTable[self.m_buildingId]
local range = battleData.attackRange
if range > 0 then
self.m_battleRange.gameObject:SetActive(true)
self.m_battleRange.transform.localScale = Vector3(range / 8, 1, range / 8)
self.m_battleRange.followerObject.getTargetPosInfo = function(pos, rot)
pos, rot = GameInstance.remoteFactoryManager.interact.currentBuildingMode:GetPreviewRenderInfo()
return pos, rot
end
end
end
end
FacBuildModeCtrl._ProcessSignBuildSetting = HL.Method() << function(self)
local isSign = FacConst.SIGN_BUILDING_EXTRA_SETTING_PANEL[self.m_buildingId] or false
local isMoving = self.m_buildingNodeId ~= nil
self.view.actionButtonsAsOption.signResetButton.gameObject:SetActiveIfNecessary(isSign and not isMoving)
InputManagerInst:ToggleBinding(self.m_signResetBindingId, isSign and not isMoving)
if isSign then
if isMoving then
local icons = GameInstance.remoteFactoryManager:GetSignBuildingIcons(self.m_buildingNodeId)
GameInstance.remoteFactoryManager:SetPreviewSignBuildingIcon(icons[0], icons[1], icons[2])
else
self:_RefreshKeyHint(KeyHints.signBuilding)
self:_OpenSignSettingPanel(false)
end
end
end
FacBuildModeCtrl._OpenSignSettingPanel = HL.Method(HL.Boolean) << function(self, reset)
self.m_lockBuildPos = true
self.view.actionButtonsAsOption.gameObject:SetActive(false)
self.view.errorHint.gameObject:SetActiveIfNecessary(false)
self.view.actionHint.gameObject:SetActiveIfNecessary(false)
if self.m_sizeIndicator then
self.m_sizeIndicator.gameObject:SetActive(false)
end
if reset then
UIManager:AutoOpen(PanelId.FacMarkerConfirm, {
reset = reset,
onConfirm = function()
self.m_lockBuildPos = false
self.view.actionButtonsAsOption.gameObject:SetActive(true)
if self.m_sizeIndicator then
self.m_sizeIndicator.gameObject:SetActive(true)
end
end,
onClose = function()
self.m_lockBuildPos = false
self.view.actionButtonsAsOption.gameObject:SetActive(true)
if self.m_sizeIndicator then
self.m_sizeIndicator.gameObject:SetActive(true)
end
end
})
else
UIManager:AutoOpen(PanelId.FacMarkerConfirm, {
reset = reset,
onConfirm = function()
self.m_lockBuildPos = false
self.view.actionButtonsAsOption.gameObject:SetActive(true)
if self.m_sizeIndicator then
self.m_sizeIndicator.gameObject:SetActive(true)
end
end,
onClose = function()
self:_ExitCurMode(true)
end
})
end
end
FacBuildModeCtrl._CheckSignCanBuild = HL.Method().Return(HL.Boolean) << function(self)
local isSign = FacConst.SIGN_BUILDING_EXTRA_SETTING_PANEL[self.m_buildingId]
if isSign then
local curNum = #FactoryUtils.getPlayerAllMarkerBuildingNodeInfo()
local maxNum = Tables.factoryConst.signNodeCountLimit
local detla = self.m_buildingNodeId == nil and 1 or 0
return curNum + detla <= maxNum
end
return true
end
FacBuildModeCtrl._CheckBanAndToastSignInTopView = HL.StaticMethod().Return(HL.Boolean) << function(itemId)
local ban = false
if FacConst.SIGN_BUILDING_BAN_IN_TOPVIEW[itemId] then
if GameInstance.player.gameSettingSystem.forbiddenFactorySign then
Notify(MessageConst.SHOW_TOAST, Language.LUA_FAC_BAN_SIGN_SDK_FORBIDDEN)
ban = true
elseif LuaSystemManager.factory.inTopView then
Notify(MessageConst.SHOW_TOAST, Language.LUA_FAC_BAN_SIGN_IN_TOP_VIEW)
ban = true
end
end
return ban
end
FacBuildModeCtrl._EnterBlueprintMode = HL.Method(HL.Table) << function(self, args)
if self.m_mode == FacConst.FAC_BUILD_MODE.Building then
if self.m_buildArgs.onExit then
self.m_buildArgs.onExit()
end
elseif self.m_mode == FacConst.FAC_BUILD_MODE.Logistic then
self:_ExitLogisticMode()
elseif self.m_mode == FacConst.FAC_BUILD_MODE.Belt then
self:_ExitBeltMode()
elseif self.m_mode == FacConst.FAC_BUILD_MODE.Blueprint then
self:_ExitBlueprintMode()
end
self.m_isDragging = false
UIManager.commonTouchPanel.enableZoom = true
self.m_buildArgs = args
self.m_lastBPGridPos = nil
local initGridPos
if args.initGridPos then
initGridPos = args.initGridPos
else
local mousePos
if args.initMousePos then
mousePos = Vector3(args.initMousePos.x, args.initMousePos.y, 0)
else
mousePos = self:_InDragMode() and Vector3(Screen.width / 2, Screen.height / 2, 0) or self:_GetCurPointerPressPos()
end
local camRay = CameraManager.mainCamera:ScreenPointToRay(mousePos)
local _, initWorldPos = CSFactoryUtil.SampleLevelRegionPointWithRay(camRay)
initGridPos = GameInstance.remoteFactoryManager.visual:WorldToVoxel(initWorldPos)
end
initGridPos = Unity.Vector3Int(math.floor(initGridPos.x), math.floor(initGridPos.y), math.floor(initGridPos.z))
self:_RefreshKeyHint(KeyHints.blueprint)
local interact = GameInstance.remoteFactoryManager.interact
if args.blueprint then
interact:SwitchToBlueprintMode(args.blueprint, initGridPos, 0, args.isMove)
Notify(MessageConst.FAC_TOP_VIEW_SET_BLUEPRINT_ICONS, args.blueprint)
elseif args.csBPInst then
interact:SwitchToBlueprintModeWidthServerBlueprint(args.csBPInst, initGridPos, 0)
if args.csBPInst.sourceType == CS.Beyond.Gameplay.RemoteFactory.RemoteFactoryBlueprintSourceType.Sys then
self.m_buildArgs.isSystemBP = true
self.m_buildArgs.sysBpKey = args.csBPInst.param.sysBpKey
elseif args.csBPInst.sourceType == CS.Beyond.Gameplay.RemoteFactory.RemoteFactoryBlueprintSourceType.Preset then
self.m_buildArgs.isSystemBP = true
self.m_buildArgs.sysBpKey = args.csBPInst.param.presetBpKey
end
Notify(MessageConst.FAC_TOP_VIEW_SET_BLUEPRINT_ICONS, args.csBPInst.info.bp)
elseif args[1] then
interact:SwitchToBlueprintModeWidthServerBlueprint(args[1], initGridPos, 0)
end
local mode = interact.currentBlueprintMode
if mode.onPlaceBlueprint then
mode.onPlaceBlueprint = mode.onPlaceBlueprint - self.m_onPlaceFinish
mode.onPlaceBlueprint = mode.onPlaceBlueprint + self.m_onPlaceFinish
else
mode.onPlaceBlueprint = self.m_onPlaceFinish
end
self.view.moveBuildingHint.gameObject:SetActive(args.isMove == true)
self:_AdjustCameraForBlueprint(true)
self.m_mode = FacConst.FAC_BUILD_MODE.Blueprint
Notify(MessageConst.ON_BUILD_MODE_CHANGE, self.m_mode)
Notify(MessageConst.ON_ENTER_BLUEPRINT_MODE)
self:_NotifyPowerPoleTravelHint()
self:_UpdateCommonNodesOnEnterMode()
if not self:_InDragMode() then
self:_Tick()
end
end
FacBuildModeCtrl._AdjustCameraForBlueprint = HL.Method(HL.Boolean) << function(self, isEnterBlueprint)
local camCtrl = LuaSystemManager.factory.m_topViewCamCtrl
if not isEnterBlueprint then
camCtrl:ResetCameraAdjustForRange()
return
end
local range = self.m_buildArgs.range
if not range then
return
end
local needReverse = lume.round(LuaSystemManager.factory.topViewCamTarget.eulerAngles.y) % 180 ~= 0
camCtrl:AdjustCameraForRange(needReverse and range.height or range.width, needReverse and range.width or range.height, function(pos)
return FactoryUtils.clampTopViewCamTargetPosition(pos)
end)
end
FacBuildModeCtrl._ExitBlueprintMode = HL.Method(HL.Opt(HL.Boolean)) << function(self, skipAnim)
Notify(MessageConst.FAC_TOP_VIEW_SET_BLUEPRINT_ICONS)
self:_ExitMode(skipAnim)
self:_AdjustCameraForBlueprint(false)
end
FacBuildModeCtrl.FacOnBuildingBatchMoved = HL.Method() << function(self)
if not self.m_buildArgs then
return
end
local targets = self.m_buildArgs.batchSelectTargets
self:_ExitCurMode(true)
if targets then
Notify(MessageConst.FAC_UPDATE_TOP_VIEW_BUILDING_INFOS, targets)
end
end
FacBuildModeCtrl._ConfirmBlueprint = HL.Method() << function(self)
self:_Tick()
if not self.m_curBuildIsValid then
Notify(MessageConst.SHOW_TOAST, self.view.errorHintText.text)
AudioAdapter.PostEvent("au_ui_fac_unbuildable")
return
end
local mousePos = self:_GetCurPointerPressPos()
GameInstance.remoteFactoryManager:GridPositionTriggered(mousePos, 0)
end
FacBuildModeCtrl.m_lastBPGridPos = HL.Field(HL.Any)
FacBuildModeCtrl._SetBluePrintSelectGrids = HL.Method(CS.UnityEngine.Vector2Int) << function(self, gridPos)
self.m_lastBPGridPos = gridPos
local range = self.m_buildArgs.range
local curMode = GameInstance.remoteFactoryManager.interact.currentBlueprintMode
local dir = curMode.preparedDirection
local needReverse = dir % 2 == 1
local width = needReverse and range.height or range.width
local height = needReverse and range.width or range.height
local rectInt = CS.UnityEngine.RectInt(gridPos.x - math.floor(width / 2), gridPos.y - math.floor(height / 2), width, height)
CSFactoryUtil.SetSelectGrids(rectInt, CS.Beyond.Gameplay.Factory.GlobalSharedData.MapGridRendererData.MapGridInfo.SelectType.BLUEPRINT)
local bpOriWorldPos = Vector3(rectInt.center.x, curMode.preparedPosition.y, rectInt.center.y)
if dir == 0 then
bpOriWorldPos = bpOriWorldPos - Vector3(width / 2, 0, height / 2)
elseif dir == 1 then
bpOriWorldPos = bpOriWorldPos - Vector3(width / 2, 0, -height / 2)
elseif dir == 2 then
bpOriWorldPos = bpOriWorldPos + Vector3(width / 2, 0, height / 2)
elseif dir == 3 then
bpOriWorldPos = bpOriWorldPos + Vector3(width / 2, 0, -height / 2)
end
Notify(MessageConst.FAC_TOP_VIEW_SET_BLUEPRINT_ICON_POS, { bpOriWorldPos, dir })
end
FacBuildModeCtrl._EnterLogisticMode = HL.Method(HL.Table) << function(self, args)
if self.m_mode == FacConst.FAC_BUILD_MODE.Building then
self:_ExitBuildingMode()
elseif self.m_mode == FacConst.FAC_BUILD_MODE.Logistic then
if self.m_buildArgs.onExit then
self.m_buildArgs.onExit()
end
self:_SetCamState()
elseif self.m_mode == FacConst.FAC_BUILD_MODE.Belt then
self:_ExitBeltMode()
elseif self.m_mode == FacConst.FAC_BUILD_MODE.Blueprint then
self:_ExitBlueprintMode()
end
self.m_isDragging = false
UIManager.commonTouchPanel.enableZoom = true
self.m_buildArgs = args
local itemId = args.itemId
local itemData = Tables.itemTable[itemId]
local logisticId = Tables.factoryItem2LogisticIdTable[itemId].logisticId
local mousePos
if args.initMousePos then
mousePos = Vector3(args.initMousePos.x, args.initMousePos.y, 0)
else
mousePos = self:_InDragMode() and Vector3(Screen.width / 2, Screen.height / 2, 0) or self:_GetCurPointerPressPos()
end
local camRay = CameraManager.mainCamera:ScreenPointToRay(mousePos)
local _, initWorldPos = CSFactoryUtil.SampleLevelRegionPointWithRay(camRay)
local initGridPos = GameInstance.remoteFactoryManager.visual:WorldToVoxel(initWorldPos)
initGridPos = Unity.Vector3Int(lume.round(initGridPos.x), lume.round(initGridPos.y), lume.round(initGridPos.z))
GameInstance.remoteFactoryManager.interact:SwitchToBuildingMode(logisticId, initGridPos, 0)
local mode = GameInstance.remoteFactoryManager.interact.buildingMode
mode.onPlaceBuilding = mode.onPlaceBuilding - self.m_onPlaceFinish
mode.onPlaceBuilding = mode.onPlaceBuilding + self.m_onPlaceFinish
self.m_buildingId = logisticId
self.m_itemData = itemData
self.m_mode = FacConst.FAC_BUILD_MODE.Logistic
local keyHint = LuaSystemManager.factory.inTopView and KeyHints.logisticInTopView or KeyHints.logistic
if not self:_CanRotate() then
local tmp = {}
for _, v in ipairs(keyHint) do
if v ~= "fac_rotate_device" then
table.insert(tmp, v)
end
end
keyHint = tmp
end
self:_RefreshKeyHint(keyHint)
self:_UpdateValidResult()
local logisticData = FactoryUtils.getLogisticData(logisticId)
self:_SetCamState(logisticData.buildCamState)
Notify(MessageConst.ON_BUILD_MODE_CHANGE, self.m_mode)
Notify(MessageConst.ON_ENTER_LOGISTIC_MODE, itemData.id)
self:_UpdateCommonNodesOnEnterMode()
end
FacBuildModeCtrl._ExitLogisticMode = HL.Method(HL.Opt(HL.Boolean)) << function(self, skipAnim)
self:_ExitMode(skipAnim)
end
FacBuildModeCtrl._ConfirmLogistic = HL.Method() << function(self)
self:_Tick()
if not self.m_curBuildIsValid then
Notify(MessageConst.SHOW_TOAST, self.view.errorHintText.text)
AudioAdapter.PostEvent("au_ui_fac_unbuildable")
return
end
local mousePos = self:_GetCurPointerPressPos()
GameInstance.remoteFactoryManager:GridPositionTriggered(mousePos, 0)
if not self:_EnableContinueBuild() then
self:_ExitLogisticMode()
end
end
FacBuildModeCtrl._CancelLogistic = HL.Method(HL.Opt(HL.Boolean)) << function(self, skipAnim)
local onCancel = self.m_buildArgs.onCancel
if onCancel then
onCancel()
end
self:_ExitLogisticMode(skipAnim)
end
FacBuildModeCtrl._EnterBeltMode = HL.Method(HL.Table) << function(self, args)
if self.m_mode == FacConst.FAC_BUILD_MODE.Belt then
if self.m_buildArgs.onExit then
self.m_buildArgs.onExit()
end
self:_SetCamState()
elseif self.m_mode == FacConst.FAC_BUILD_MODE.Logistic then
self:_ExitLogisticMode()
elseif self.m_mode == FacConst.FAC_BUILD_MODE.Building then
self:_ExitBuildingMode()
elseif self.m_mode == FacConst.FAC_BUILD_MODE.Blueprint then
self:_ExitBlueprintMode()
end
self.m_isDragging = false
UIManager.commonTouchPanel.enableZoom = true
self.m_beltHasStartLastTick = false
self.m_mode = FacConst.FAC_BUILD_MODE.Belt
self.m_buildArgs = args
self.m_beltId = args.beltId
local isPipe = self:_IsPipe()
local mark = isPipe and self.m_pipePreviewMark or self.m_beltStartPreviewMark
if self:_InDragMode() then
GameInstance.remoteFactoryManager:SetupConveyorInteractMode(CS.Beyond.Gameplay.RemoteFactory.ConveyorInteractMode.TraceDrag)
mark.gameObject:SetActive(false)
GameInstance.remoteFactoryManager.interact:SwitchToConveyorMode(self.m_beltId)
else
GameInstance.remoteFactoryManager:SetupConveyorInteractMode(CS.Beyond.Gameplay.RemoteFactory.ConveyorInteractMode.Precise)
mark.gameObject:SetActive(true)
GameInstance.remoteFactoryManager.interact:SwitchToConveyorMode(self.m_beltId)
self:_UpdateBPStartPreviewMark(self:_GetCurPointerPressPos(), true)
end
self:_RefreshKeyHint(isPipe and KeyHints.pipeStart or KeyHints.beltStart)
self:_UpdateValidResult()
Notify(MessageConst.ON_BUILD_MODE_CHANGE, self.m_mode)
Notify(MessageConst.ON_ENTER_BELT_MODE)
self:_UpdateCommonNodesOnEnterMode()
if isPipe then
local data = Tables.factoryLiquidPipeTable[self.m_beltId].pipeData
self:_SetCamState(data.buildCamState)
else
local data = Tables.factoryGridBeltTable[self.m_beltId].beltData
self:_SetCamState(data.buildCamState)
end
if DeviceInfo.usingTouch then
if LuaSystemManager.factory.inTopView then
self.view.actionButtonsAsIcon.gameObject:SetActive(false)
end
end
end
FacBuildModeCtrl._ExitBeltMode = HL.Method(HL.Opt(HL.Boolean)) << function(self, skipAnim)
local mark = self:_IsPipe() and self.m_pipePreviewMark or self.m_beltStartPreviewMark
mark.transform:DOKill()
mark.gameObject:SetActive(false)
FactoryUtils.stopLogisticFigureRenderer()
if DeviceInfo.usingTouch then
LuaSystemManager.factory.canMoveCamTarget = true
end
self:_ExitMode(skipAnim)
end
FacBuildModeCtrl.m_bpStartPreviewMarkLastPos = HL.Field(HL.Userdata)
FacBuildModeCtrl.m_bpStartPreviewMarkLastColor = HL.Field(Color)
FacBuildModeCtrl._UpdateBPStartPreviewMark = HL.Method(Vector3, HL.Opt(HL.Boolean)) << function(self, curMousePos, isInit)
local camRay = CameraManager.mainCamera:ScreenPointToRay(curMousePos)
local _, worldPos = CSFactoryUtil.SampleLevelRegionPointWithRay(camRay)
self:_UpdateBPStartPreviewMarkWithWorldPos(worldPos, isInit)
end
FacBuildModeCtrl._UpdateBPStartPreviewMarkWithWorldPos = HL.Method(Vector3, HL.Opt(HL.Boolean)) << function(self, worldPos, isInit)
local visual = GameInstance.remoteFactoryManager.visual
local beltPos = visual:WorldToBeltGrid(worldPos)
local roundedWorldPos = visual:BeltGridToWorld(Vector2(lume.round(beltPos.x), lume.round(beltPos.y)))
roundedWorldPos.y = worldPos.y
local isPipe = self:_IsPipe()
local mark = isPipe and self.m_pipePreviewMark or self.m_beltStartPreviewMark
local trans = mark.transform
if isInit then
trans.position = roundedWorldPos
self.m_bpStartPreviewMarkLastPos = nil
else
if not self.m_bpStartPreviewMarkLastPos or (roundedWorldPos - self.m_bpStartPreviewMarkLastPos).sqrMagnitude >= 0.01 then
trans.position = roundedWorldPos
self.m_bpStartPreviewMarkLastPos = roundedWorldPos
local needAudio
if DeviceInfo.usingTouch then
needAudio = not LuaSystemManager.factory.inTopView or self.m_isDragging
else
needAudio = true
end
if needAudio then
AudioAdapter.PostEvent("au_ui_belt_move")
end
end
end
self:_UpdateBPStartPreviewMarkColor(isInit)
end
FacBuildModeCtrl._UpdateBPStartPreviewMarkColor = HL.Method(HL.Opt(HL.Boolean)) << function(self, isInit)
local isPipe = self:_IsPipe()
local mark = isPipe and self.m_pipePreviewMark or self.m_beltStartPreviewMark
local color
if self.m_curBuildIsValid then
color = mark.config.NORMAL_COLOR
else
color = mark.config.INVALID_COLOR
end
if isInit or color ~= self.m_bpStartPreviewMarkLastColor then
self.m_bpStartPreviewMarkLastColor = color
for _, mat in ipairs(mark.mats) do
mat:SetColor("_TintColor", color)
end
end
end
FacBuildModeCtrl.OnInteractConveyorLocalCheckingFailed = HL.Method(HL.Table) << function(self, args)
self:_UpdateValidResult()
if not self.m_curBuildIsValid then
Notify(MessageConst.SHOW_TOAST, self.view.errorHintText.text)
end
end
FacBuildModeCtrl.m_beltHasStartLastTick = HL.Field(HL.Boolean) << false
FacBuildModeCtrl._UpdateOnBeltHasStartChanged = HL.Method() << function(self)
local hasStart = GameInstance.remoteFactoryManager.interact.currentConveyorMode.hasStart
self.m_beltHasStartLastTick = hasStart
local isPipe = self:_IsPipe()
local inTopView = LuaSystemManager.factory.inTopView
if inTopView then
if hasStart then
self.view.actionHintTxt:SetAndResolveTextStyle(isPipe and Language.LUA_FAC_BUILD_MODE_DRAW_PIPE_HINT_WITH_START or Language.LUA_FAC_BUILD_MODE_DRAW_BELT_HINT_WITH_START)
else
self.view.actionHintTxt:SetAndResolveTextStyle(isPipe and Language.LUA_FAC_BUILD_MODE_DRAW_PIPE_HINT or Language.LUA_FAC_BUILD_MODE_DRAW_BELT_HINT)
end
self.view.actionButtonsAsIcon.gameObject:SetActive(hasStart)
self.view.exitBeltModeButton.gameObject:SetActive(not hasStart)
else
self.view.actionButtonsAsOption.rotateButton.gameObject:SetActive(hasStart)
self.view.actionButtonsAsOption.confirmText.text = hasStart and Language.LUA_FAC_BUILD_MODE_CONFIRM_BELT_END or Language.LUA_FAC_BUILD_MODE_CONFIRM_BELT_START
end
if isPipe then
self:_RefreshKeyHint(hasStart and KeyHints.pipeEnd or KeyHints.pipeStart)
else
self:_RefreshKeyHint(hasStart and KeyHints.beltEnd or KeyHints.beltStart)
end
end
FacBuildModeCtrl._GetCurPointerPressPos = HL.Method().Return(Vector3) << function(self)
if self.m_lockBuildPos then
return CameraManager.mainCamera:WorldToScreenPoint(self.m_lastMouseWorldPos)
end
if LuaSystemManager.factory.inTopView then
if DeviceInfo.usingTouch then
return UIManager.commonTouchPanel.touchPos:XY()
else
return InputManager.mousePosition
end
else
if not InputManager.cursorVisible or DeviceInfo.usingTouch then
return Vector3(Screen.width / 2, Screen.height / 2, 0)
end
return InputManager.mousePosition
end
end
FacBuildModeCtrl._InDragMode = HL.Method().Return(HL.Boolean) << function(self)
return DeviceInfo.usingTouch and LuaSystemManager.factory.inTopView
end
FacBuildModeCtrl._IsPipe = HL.Method().Return(HL.Boolean) << function(self)
return self.m_beltId == FacConst.PIPE_ID
end
FacBuildModeCtrl.DebugOutputPrepareBuildingPosInfo = HL.Method() << function(self)
local id, pos, dir
if self.m_mode == FacConst.FAC_BUILD_MODE.Building or self.m_mode == FacConst.FAC_BUILD_MODE.Logistic then
local rot
pos, rot = GameInstance.remoteFactoryManager.interact.currentBuildingMode:GetPreviewRenderInfo()
id = self.m_buildingId
dir = rot.y
elseif self.m_mode == FacConst.FAC_BUILD_MODE.Belt then
local mark = isPipe and self.m_pipePreviewMark or self.m_beltStartPreviewMark
id = self.m_beltId
pos = mark.transform.position
dir = 0
elseif self.m_mode == FacConst.FAC_BUILD_MODE.Blueprint and self.m_buildArgs.isSystemBP then
local curMode = GameInstance.remoteFactoryManager.interact.currentBlueprintMode
id = self.m_buildArgs.sysBpKey
dir = curMode.preparedDirection * 90
pos = Vector3(curMode.preparedPosition.x, curMode.preparedPosition.y, curMode.preparedPosition.z)
else
return
end
local info = string.format("%s %s %d", id, pos:ToString(), dir)
Unity.GUIUtility.systemCopyBuffer = info
Notify(MessageConst.SHOW_TOAST, string.format("DEBUG: 已复制 %s", info))
logger.error("DebugOutputPrepareBuildingPosInfo", info)
end
FacBuildModeCtrl.s_enableConfirmBuild = HL.StaticField(HL.Boolean) << true
FacBuildModeCtrl.SetEnableConfirmBuild = HL.StaticMethod(HL.Table) << function(args)
local enable = unpack(args)
FacBuildModeCtrl.s_enableConfirmBuild = enable
end
FacBuildModeCtrl.s_enableExitBuildMode = HL.StaticField(HL.Boolean) << true
FacBuildModeCtrl.SetEnableExitBuildMode = HL.StaticMethod(HL.Table) << function(args)
local enable = unpack(args)
FacBuildModeCtrl.s_enableExitBuildMode = enable
end
FacBuildModeCtrl.m_lockBuildPos = HL.Field(HL.Boolean) << false
FacBuildModeCtrl.FacLockBuildPos = HL.Method(HL.Table) << function(self, arg)
local isLock = unpack(arg)
self.m_lockBuildPos = isLock
end
FacBuildModeCtrl._OnChangeContinueToggle = HL.Method(HL.Boolean) << function(self, isOn)
FacBuildModeCtrl.s_enableContinueBuild = isOn
UIUtils.PlayAnimationAndToggleActive(self.view.actionButtonsAsIcon.continueBuildHint, isOn)
end
FacBuildModeCtrl._EnableContinueBuild = HL.Method().Return(HL.Boolean) << function(self)
if not LuaSystemManager.factory.inTopView then
return false
end
if DeviceInfo.usingKeyboard then
return InputManagerInst:GetKey(CS.Beyond.Input.KeyboardKeyCode.LeftControl)
elseif DeviceInfo.usingController then
return InputManagerInst:GetKey(CS.Beyond.Input.GamepadKeyCode.LT)
end
return FacBuildModeCtrl.s_enableContinueBuild
end
FacBuildModeCtrl.m_onPlaceFinish = HL.Field(HL.Function)
FacBuildModeCtrl._OnPlaceFinish = HL.Method() << function(self)
Notify(MessageConst.SHOW_TOAST, Language.LUA_FAC_BUILD_CONTINUOUS_SUCCESS)
if DeviceInfo.usingTouch and LuaSystemManager.factory.inTopView and FacBuildModeCtrl.s_enableContinueBuild then
self:_StartCoroutine(function()
coroutine.step()
coroutine.step()
self:_AutoMoveOnContinueBuildSucc()
end)
end
self:_UpdatePendingHint()
end
FacBuildModeCtrl._AutoMoveOnContinueBuildSucc = HL.Method() << function(self)
if not DeviceInfo.usingTouch then
return
end
local worldPos = GameInstance.remoteFactoryManager.interact.currentBuildingMode:GetPreviewRenderInfo()
worldPos = worldPos + CameraManager.mainCamera.transform.right
local voxelPos = GameInstance.remoteFactoryManager.visual:WorldToVoxel(worldPos)
local gridPos = Unity.Vector2Int(math.floor(voxelPos.x), math.floor(voxelPos.z))
GameInstance.remoteFactoryManager:GridPositionTriggered(gridPos, Vector2.zero, voxelPos.y, 4)
end
HL.Commit(FacBuildModeCtrl)