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

350 lines
10 KiB
Lua

local uiCtrl = require_ex('UI/Panels/Base/UICtrl')
local ActionOnSetNaviTarget = CS.Beyond.Input.ActionOnSetNaviTarget
FacRouterCtrl = HL.Class('FacRouterCtrl', uiCtrl.UICtrl)
local MAX_ROUTER_PORT_COUNT = 4
local SINGLE_ROUTER_PORT_INDEX = 1
local NON_SINGLE_ROUTER_PORT_INDEX_OFFSET = -1
local SINGLE_ROUTER_ITEM_INDEX = 0
FacRouterCtrl.m_buildingInfo = HL.Field(HL.Userdata)
FacRouterCtrl.m_isSinglePortIn = HL.Field(HL.Boolean) << false
FacRouterCtrl.m_routerItems = HL.Field(HL.Table)
FacRouterCtrl.m_lastValidRouterItems = HL.Field(HL.Table)
FacRouterCtrl.m_updateThread = HL.Field(HL.Thread)
FacRouterCtrl.m_inBeltInfoList = HL.Field(HL.Table)
FacRouterCtrl.m_outBeltInfoList = HL.Field(HL.Table)
FacRouterCtrl.m_inBindingAnimMap = HL.Field(HL.Table)
FacRouterCtrl.m_outBindingAnimMap = HL.Field(HL.Table)
FacRouterCtrl.m_inItemAnimMap = HL.Field(HL.Table)
FacRouterCtrl.m_outItemAnimMap = HL.Field(HL.Table)
FacRouterCtrl.m_itemSpriteCache = HL.Field(HL.Table)
FacRouterCtrl.m_initialNaviTarget = HL.Field(HL.Forward("Item"))
FacRouterCtrl.OnCreate = HL.Override(HL.Any) << function(self, arg)
self.m_buildingInfo = arg.uiInfo
local logisticData = FactoryUtils.getLogisticData(self.m_buildingInfo.nodeHandler.templateId)
local buildingData = { nodeId = arg.uiInfo.nodeId }
setmetatable(buildingData, { __index = logisticData })
self.view.buildingCommon:InitBuildingCommon(nil, {
data = buildingData,
customRightButtonOnClicked = function()
self:_OnDeleteRouterButtonClicked()
end,
})
self.view.buildingCommon:ChangeBuildingStateDisplay(GEnums.FacBuildingState.Normal)
local speed = logisticData.msPerRound > 0 and 1000 / logisticData.msPerRound or 0
self.view.buildingCommon.view.speedText.text = string.format("%.1f", speed)
self.view.buildingCommon.view.stopLine.gameObject:SetActive(speed <= 0)
self.view.buildingCommon.view.normalLine.gameObject:SetActive(speed > 0)
self.m_routerItems = {}
self.m_lastValidRouterItems = {}
self.m_itemSpriteCache = {}
self:_InitConveyorEvent()
self:_InitRouterPortData()
self:_InitRouterUpdateThread()
self:_InitConveyorBindingAnim()
if DeviceInfo.usingController and self.m_initialNaviTarget ~= nil then
self.m_initialNaviTarget:SetAsNaviTarget()
end
end
FacRouterCtrl.OnClose = HL.Override() << function(self)
self:_ClearConveyorEvent()
self.m_updateThread = self:_ClearCoroutine(self.m_updateThread)
self.m_itemSpriteCache = nil
end
FacRouterCtrl._InitRouterPortData = HL.Virtual() << function(self)
end
FacRouterCtrl._InitConveyorEvent = HL.Method() << function(self)
self.m_inBeltInfoList, self.m_outBeltInfoList = FactoryUtils.getBuildingPortState(self.m_buildingInfo.nodeId, false)
if self.m_inBeltInfoList ~= nil then
for _, inBeltInfo in pairs(self.m_inBeltInfoList) do
if inBeltInfo.isBinding then
GameInstance.remoteFactoryManager:RegisterInterestedUnitId(inBeltInfo.touchNodeId)
end
end
end
if self.m_outBeltInfoList ~= nil then
for _, outBeltInfo in pairs(self.m_outBeltInfoList) do
if outBeltInfo.isBinding then
GameInstance.remoteFactoryManager:RegisterInterestedUnitId(outBeltInfo.touchNodeId)
end
end
end
MessageManager:Register(MessageConst.ON_CONVEYOR_CHANGE, function(args)
self:_OnConveyorChanged(args)
end, self)
end
FacRouterCtrl._ClearConveyorEvent = HL.Method() << function(self)
if self.m_inBeltInfoList ~= nil then
for _, inBeltInfo in pairs(self.m_inBeltInfoList) do
if inBeltInfo.isBinding then
GameInstance.remoteFactoryManager:UnregisterInterestedUnitId(inBeltInfo.touchNodeId)
end
end
end
if self.m_outBeltInfoList ~= nil then
for _, outBeltInfo in pairs(self.m_outBeltInfoList) do
if outBeltInfo.isBinding then
GameInstance.remoteFactoryManager:UnregisterInterestedUnitId(outBeltInfo.touchNodeId)
end
end
end
MessageManager:UnregisterAll(self)
end
FacRouterCtrl._InitRouterUpdateThread = HL.Method() << function(self)
self:_UpdateRouterItems()
self.m_updateThread = self:_StartCoroutine(function()
while true do
coroutine.wait(UIConst.FAC_COMMON_UI_UPDATE_INTERVAL)
self:_UpdateRouterItems()
end
end)
end
FacRouterCtrl._UpdateRouterItems = HL.Method() << function(self)
for index = SINGLE_ROUTER_PORT_INDEX, MAX_ROUTER_PORT_COUNT do
local isIn
if index == SINGLE_ROUTER_PORT_INDEX then
isIn = self.m_isSinglePortIn
else
isIn = not self.m_isSinglePortIn
end
local portIndex = index == SINGLE_ROUTER_PORT_INDEX and SINGLE_ROUTER_PORT_INDEX or index + NON_SINGLE_ROUTER_PORT_INDEX_OFFSET
local connectToMachine, fcType = CSFactoryUtil.GetPortConnectionNodeType(Utils.getCurrentChapterId(), self.m_buildingInfo.nodeId, isIn, CSIndex(portIndex))
local itemId = ""
if connectToMachine and fcType ~= GEnums.FCNodeType.BoxConveyor then
local router = self.m_buildingInfo.boxRouterM1
if router ~= nil then
local itemInfo = isIn and router.lastItemIn or router.lastItemOut
local succ, item = itemInfo:TryGetValue(CSIndex(portIndex))
if succ then
itemId = item
end
end
else
local success, itemList = CSFactoryUtil.GetLogisticInfo(Utils.getCurrentChapterId(), self.m_buildingInfo.nodeId, isIn, CSIndex(portIndex), false)
if success and itemList.Count > 0 then
local itemIndex = isIn and 0 or itemList.Count - 1
itemId = itemList[itemIndex]
end
end
self:_RefreshRouterItemState(index, itemId)
end
end
FacRouterCtrl._RefreshRouterItemState = HL.Method(HL.Number, HL.String) << function(self, index, itemId)
local viewItemName = string.format("itemLogistics%d", index)
local viewItem = self.view[viewItemName]
local lastItemId = self.m_routerItems[index]
if lastItemId == nil and string.isEmpty(itemId) then
viewItem:InitItem({
id = "",
count = 0,
})
viewItem.view.button:ChangeActionOnSetNaviTarget(ActionOnSetNaviTarget.None)
self.m_routerItems[index] = ""
return
end
local lastValidItemId = self.m_lastValidRouterItems[index]
local scope, domain = Utils.getCurrentScope(), Utils.getCurDomainId()
local count = string.isEmpty(itemId) and 0 or Utils.getDepotItemCount(itemId, scope, domain)
if string.isEmpty(itemId) and not string.isEmpty(lastValidItemId) then
count = Utils.getDepotItemCount(lastValidItemId, scope, domain)
end
if itemId ~= lastItemId then
if string.isEmpty(itemId) and not string.isEmpty(lastItemId) then
if not string.isEmpty(lastValidItemId) then
local lastValidCount = Utils.getDepotItemCount(lastValidItemId, scope, domain)
if lastValidCount > 0 then
viewItem.view.contentCanvasGroup.alpha = UIConst.ITEM_MISSING_TRANSPARENCY
end
end
else
viewItem:InitItem({
id = itemId,
count = count,
isInfinite = FactoryUtils.isItemInfiniteInFactoryDepot(itemId),
}, true)
viewItem.view.contentCanvasGroup.alpha = UIConst.ITEM_EXIST_TRANSPARENCY
self.m_lastValidRouterItems[index] = itemId
end
self.m_routerItems[index] = itemId
else
viewItem:UpdateCountSimple(count)
end
end
FacRouterCtrl._OnDeleteRouterButtonClicked = HL.Method() << function(self)
if not FactoryUtils.canDelBuilding(self.m_buildingInfo.nodeId, true) then
return
end
PhaseManager:ExitPhaseFast(PhaseId.FacMachine)
GameInstance.player.remoteFactory.core:Message_OpDismantle(Utils.getCurrentChapterId(), self.m_buildingInfo.nodeId)
end
FacRouterCtrl._GetRouterItemSprite = HL.Method(HL.String).Return(HL.Userdata) << function(self, itemId)
if self.m_itemSpriteCache[itemId] == nil then
local success, itemData = Tables.itemTable:TryGetValue(itemId)
if success then
self.m_itemSpriteCache[itemId] = self:LoadSprite(UIConst.UI_SPRITE_ITEM, itemData.iconId)
end
end
return self.m_itemSpriteCache[itemId]
end
FacRouterCtrl._InitConveyorBindingAnim = HL.Method() << function(self)
for inIndex, inBeltInfo in ipairs(self.m_inBeltInfoList) do
local animInfo = self.m_inBindingAnimMap[inIndex]
if animInfo ~= nil then
animInfo.decoAnimWrapper:PlayWithTween(animInfo.decoAnimName)
animInfo.conveyorAnimWrapper:PlayWithTween(animInfo.conveyorAnimName)
end
end
for outIndex, outBeltInfo in ipairs(self.m_outBeltInfoList) do
local animInfo = self.m_outBindingAnimMap[outIndex]
if animInfo ~= nil then
animInfo.decoAnimWrapper:PlayWithTween(animInfo.decoAnimName)
animInfo.conveyorAnimWrapper:PlayWithTween(animInfo.conveyorAnimName)
end
end
end
FacRouterCtrl._OnConveyorChanged = HL.Method(HL.Any) << function(self, args)
local bindingNodeId, componentId, isIn, itemList = unpack(args)
local infoList = isIn and self.m_outBeltInfoList or self.m_inBeltInfoList
local animMap = isIn and self.m_outItemAnimMap or self.m_inItemAnimMap
for index, info in ipairs(infoList) do
if info.touchNodeId == bindingNodeId then
local animInfo = animMap[index]
if animInfo ~= nil then
animInfo.animationNode.animationWrapper:ClearTween()
animInfo.animationNode.animationWrapper:PlayWithTween(animInfo.animationName)
local itemId = itemList[SINGLE_ROUTER_ITEM_INDEX]
animInfo.animationNode.image.sprite = self:_GetRouterItemSprite(itemId)
local fullSuccess, fullBottleData = Tables.fullBottleTable:TryGetValue(itemId)
if fullSuccess then
local liquidItemId = fullBottleData.liquidId
animInfo.animationNode.liquidIcon.sprite = self:_GetRouterItemSprite(liquidItemId)
animInfo.animationNode.liquidIcon.gameObject:SetActive(true)
else
animInfo.animationNode.liquidIcon.gameObject:SetActive(false)
end
end
end
end
end
HL.Commit(FacRouterCtrl)