1111 lines
35 KiB
Lua
1111 lines
35 KiB
Lua
local UIWidgetBase = require_ex('Common/Core/UIWidgetBase')
|
|
local LuaNodeCache = require_ex('Common/Utils/LuaNodeCache')
|
|
local CommonCache = require_ex('Common/Utils/CommonCache')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BlueprintPreview = HL.Class('BlueprintPreview', UIWidgetBase)
|
|
|
|
|
|
local uiSizePerUnit = 128
|
|
|
|
|
|
|
|
BlueprintPreview.m_csBP = HL.Field(CS.Beyond.Gameplay.RemoteFactory.RemoteFactoryBlueprint)
|
|
|
|
|
|
BlueprintPreview.m_nodeCellCache = HL.Field(LuaNodeCache)
|
|
|
|
|
|
BlueprintPreview.m_conveyorCellCache = HL.Field(LuaNodeCache)
|
|
|
|
|
|
BlueprintPreview.m_showingCellDic = HL.Field(HL.Table)
|
|
|
|
|
|
BlueprintPreview.m_previewHelper = HL.Field(CS.Beyond.UI.BlueprintPreviewHelper)
|
|
|
|
|
|
BlueprintPreview.m_canEdit = HL.Field(HL.Boolean) << false
|
|
|
|
|
|
BlueprintPreview.m_updateId = HL.Field(HL.Number) << -1
|
|
|
|
|
|
BlueprintPreview.m_nextTargetId = HL.Field(HL.Number) << 1
|
|
|
|
|
|
BlueprintPreview.m_id2Cell = HL.Field(HL.Table)
|
|
|
|
|
|
BlueprintPreview.m_bpAbnormalIconHelper = HL.Field(HL.Table)
|
|
|
|
|
|
BlueprintPreview.mouseShow = HL.Field(HL.Boolean) << true
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local NodeType = {
|
|
Building = 1,
|
|
Logistic = 2,
|
|
Belt = 3,
|
|
Pipe = 4,
|
|
}
|
|
local Face2Vector2 = {
|
|
[0] = Vector2(0, 1),
|
|
[1] = Vector2(1, 0),
|
|
[2] = Vector2(0, -1),
|
|
[3] = Vector2(-1, 0),
|
|
}
|
|
local Face2RotZForConveyor = {
|
|
[0] = 90,
|
|
[1] = 0,
|
|
[2] = -90,
|
|
[3] = 180,
|
|
}
|
|
local Face2RotZForBuilding = {
|
|
[0] = 360,
|
|
[1] = 270,
|
|
[2] = 180,
|
|
[3] = 90,
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BlueprintPreview._OnFirstTimeInit = HL.Override() << function(self)
|
|
self.m_nodeCellCache = LuaNodeCache(self.view.nodeCell, self.view.content)
|
|
self.m_conveyorCellCache = LuaNodeCache(self.view.conveyorCell, self.view.content)
|
|
self.m_previewHelper = CS.Beyond.UI.BlueprintPreviewHelper()
|
|
self.view.maskBtn.onClick:AddListener(function()
|
|
self:_OnClick()
|
|
end)
|
|
self:_InitChangeIconNode()
|
|
|
|
|
|
local secondCellObj = CSUtils.CreateObject(self.view.hoverTipsCell.gameObject, self.view.hoverTipsNode)
|
|
secondCellObj.name = "HoverTipsCell2"
|
|
secondCellObj.transform:SetAsLastSibling()
|
|
self.view.hoverTipsCell2 = Utils.wrapLuaNode(secondCellObj)
|
|
end
|
|
|
|
|
|
BlueprintPreview.m_widthScale = HL.Field(HL.Number) << 1
|
|
|
|
|
|
BlueprintPreview.m_heightScale = HL.Field(HL.Number) << 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BlueprintPreview.InitBlueprintPreview = HL.Method(CS.Beyond.Gameplay.RemoteFactory.RemoteFactoryBlueprint, HL.Boolean, HL.Opt(HL.Table)) << function(self, csBP, canEdit, bpAbnormalIconHelper)
|
|
self:_FirstTimeInit()
|
|
|
|
self:_HideChangeIconNode(true)
|
|
if self.m_showingCellDic then
|
|
for cell, info in pairs(self.m_showingCellDic) do
|
|
if info.type == NodeType.Building or info.type == NodeType.Logistic then
|
|
self.m_nodeCellCache:Cache(cell)
|
|
elseif info.type == NodeType.Belt or info.type == NodeType.Pipe then
|
|
self.m_conveyorCellCache:Cache(cell)
|
|
end
|
|
end
|
|
end
|
|
|
|
self.m_csBP = csBP
|
|
self.m_showingCellDic = {}
|
|
self.m_changedIcons = {}
|
|
self.m_canEdit = canEdit
|
|
self.m_bpAbnormalIconHelper = bpAbnormalIconHelper
|
|
self:_CancelHover()
|
|
|
|
|
|
local range = self.m_csBP.sourceRect
|
|
local bpUISize = Vector2(range.width, range.height) * uiSizePerUnit
|
|
self.view.content.transform.sizeDelta = bpUISize
|
|
local viewSize = self.view.scrollRect.transform.rect.size - Vector2(100, 100)
|
|
local widthRatio = viewSize.x / bpUISize.x
|
|
local heightRatio = viewSize.y / bpUISize.y
|
|
local scaleValue = math.min(widthRatio, heightRatio, 1)
|
|
scaleValue = math.max(scaleValue, self.view.config.MIN_SCALE)
|
|
|
|
self.m_widthScale = scaleValue/widthRatio - 1
|
|
self.m_heightScale = scaleValue/heightRatio - 1
|
|
|
|
self.view.content.transform.localScale = Vector3(scaleValue, scaleValue, 1)
|
|
|
|
|
|
local curMaxShowingCount = self.view.scrollRect.transform.rect.size / (uiSizePerUnit * scaleValue)
|
|
local bgWidth, bgHeight
|
|
if curMaxShowingCount.x > range.width then
|
|
bgWidth = math.ceil(curMaxShowingCount.x)
|
|
|
|
bgWidth = bgWidth + (bgWidth + range.width) % 2
|
|
else
|
|
bgWidth = range.width + 2
|
|
end
|
|
if curMaxShowingCount.y > range.height then
|
|
bgHeight = math.ceil(curMaxShowingCount.y)
|
|
|
|
bgHeight = bgHeight + (bgHeight + range.height) % 2
|
|
else
|
|
bgHeight = range.height + 2
|
|
end
|
|
self.view.gridImg.transform.sizeDelta = Vector2(bgWidth, bgHeight) * uiSizePerUnit
|
|
self.view.gridImg.transform:SetAsFirstSibling()
|
|
|
|
self.m_previewHelper:SetSize(range.width, range.height)
|
|
self.m_nextTargetId = 1
|
|
self.m_id2Cell = {}
|
|
|
|
|
|
for _, entry in pairs(self.m_csBP.buildingNodes) do
|
|
self:_GenPreviewBuilding(entry)
|
|
end
|
|
|
|
|
|
for _, entry in pairs(self.m_csBP.conveyorNodes) do
|
|
self:_GenPreviewConveyor(entry)
|
|
end
|
|
|
|
self.view.hoverHint.transform:SetAsLastSibling()
|
|
if DeviceInfo.usingController then
|
|
self.view.controllerMouse.gameObject:SetActive(true)
|
|
else
|
|
self.view.controllerMouse.gameObject:SetActive(false)
|
|
end
|
|
|
|
if DeviceInfo.usingController then
|
|
InputManagerInst:SetCustomControllerMouse(self.view.controllerMouse.transform, self:GetUICtrl().uiCamera)
|
|
self.view.changeIconNode.selectableNaviGroup.onIsFocusedChange:AddListener(function(isTarget)
|
|
if not isTarget then
|
|
self:_HideChangeIconNode()
|
|
end
|
|
end)
|
|
self.view.controllerMouse.anchoredPosition = Vector2(self.view.scrollRectRectTransform.rect.size.x * 1/2, self.view.scrollRectRectTransform.rect.size.y * 1/2)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BlueprintPreview._GenPreviewBuilding = HL.Method(CS.Beyond.Gameplay.RemoteFactory.BlueprintBuildingEntry) << function(self, entry)
|
|
local cell = self.m_nodeCellCache:Get()
|
|
local info = {
|
|
id = self:_GetNextTargetId(),
|
|
entry = entry,
|
|
}
|
|
self.m_showingCellDic[cell] = info
|
|
self.m_id2Cell[info.id] = cell
|
|
|
|
local templateId = entry.templateId
|
|
local isBuilding, bData = Tables.factoryBuildingTable:TryGetValue(templateId)
|
|
info.type = isBuilding and NodeType.Building or NodeType.Logistic
|
|
|
|
if self.m_canEdit then
|
|
local _, iconData = Tables.factoryBlueprintMachineIconTable:TryGetValue(templateId)
|
|
if iconData then
|
|
info.canChangeIcon = iconData.canModify
|
|
else
|
|
info.canChangeIcon = false
|
|
end
|
|
else
|
|
info.canChangeIcon = false
|
|
end
|
|
cell.selectedNode.gameObject:SetActive(false)
|
|
|
|
local spatial = entry.spatial
|
|
local gridSize = Vector2(isBuilding and bData.range.width or 1, isBuilding and bData.range.depth or 1)
|
|
local swapSize = spatial.face == 1 or spatial.face == 3
|
|
local swappedGridSize = swapSize and Vector2(gridSize.y, gridSize.x) or gridSize
|
|
local nodeUISize = gridSize * uiSizePerUnit
|
|
cell.transform.sizeDelta = swappedGridSize * uiSizePerUnit
|
|
local pos = entry.worldSpatial.worldPosition
|
|
cell.transform.anchoredPosition = Vector2(pos.x, pos.z) * uiSizePerUnit
|
|
cell.bg.transform.sizeDelta = nodeUISize
|
|
cell.bg.transform.localEulerAngles = Vector3(0, 0, Face2RotZForBuilding[spatial.face])
|
|
|
|
local minX = lume.round(pos.x - swappedGridSize.x / 2)
|
|
local minY = lume.round(pos.z - swappedGridSize.y / 2)
|
|
self.m_previewHelper:BatchAddGridValue(minX, minY, swappedGridSize.x, swappedGridSize.y, info.id)
|
|
|
|
local bgPath, isDefaultBuilding
|
|
if isBuilding then
|
|
local spBGInfo = FacConst.BLUEPRINT_PREVIEW_SP_BUILDING_BG[bData.type]
|
|
isDefaultBuilding = spBGInfo == nil
|
|
bgPath = spBGInfo and spBGInfo[1] or FacConst.BLUEPRINT_PREVIEW_BUILDING_DEFAULT_BG
|
|
else
|
|
bgPath = string.format(FacConst.BLUEPRINT_PREVIEW_LOGISTIC_BG, templateId)
|
|
end
|
|
cell.bg:LoadSpriteWithOutFormat(bgPath)
|
|
|
|
self:_PrepareCellImgCache(cell)
|
|
|
|
if isDefaultBuilding then
|
|
self:_GenDefaultBuildingBG(entry, cell, bData)
|
|
else
|
|
cell.waistDeco.gameObject:SetActive(false)
|
|
cell.machineBG.gameObject:SetActive(false)
|
|
end
|
|
|
|
if not isBuilding then
|
|
local _, isLiquid = FactoryUtils.getLogisticData(templateId)
|
|
if isLiquid then
|
|
info.isHighLayer = true
|
|
else
|
|
|
|
cell.transform:SetAsFirstSibling()
|
|
end
|
|
end
|
|
|
|
self:_UpdateTargetIcon(info.id)
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BlueprintPreview._SetEdgeImgs = HL.Method(HL.Table, HL.Table, HL.String, HL.String) << function(self, edgeImgs, info, format, formatAlter)
|
|
local count = info.count
|
|
if count > 0 then
|
|
local size = info.size
|
|
if count == size then
|
|
edgeImgs[info.edgeFace] = string.format(format, count)
|
|
else
|
|
edgeImgs[info.edgeFace] = string.format(formatAlter, size, count)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BlueprintPreview._GenDefaultBuildingBG = HL.Method(CS.Beyond.Gameplay.RemoteFactory.BlueprintBuildingEntry, HL.Table, HL.Any) << function(self, entry, cell, bData)
|
|
local isBigBuilding = bData.range.width >= 3 and bData.range.depth >= 3 and (bData.range.width * bData.range.depth >= 9)
|
|
|
|
local edgeImgs = {}
|
|
|
|
|
|
local inPorts = self:_GenDefaultBuildingPort(bData.inputPorts, true, bData.range.width, bData.range.depth)
|
|
local outPorts = self:_GenDefaultBuildingPort(bData.outputPorts, false, bData.range.width, bData.range.depth)
|
|
|
|
|
|
self:_SetEdgeImgs(edgeImgs, inPorts.belt, FacConst.BLUEPRINT_PREVIEW_BELT_PORT_IN, FacConst.BLUEPRINT_PREVIEW_BELT_PORT_IN_ALTER)
|
|
self:_SetEdgeImgs(edgeImgs, outPorts.belt, FacConst.BLUEPRINT_PREVIEW_BELT_PORT_OUT, FacConst.BLUEPRINT_PREVIEW_BELT_PORT_OUT_ALTER)
|
|
|
|
|
|
local formulaMode = entry:GetFormulaMode()
|
|
if not formulaMode or formulaMode == FacConst.FAC_FORMULA_MODE_MAP.LIQUID then
|
|
self:_SetEdgeImgs(edgeImgs, inPorts.pipe, FacConst.BLUEPRINT_PREVIEW_PIPE_PORT_IN, FacConst.BLUEPRINT_PREVIEW_PIPE_PORT_IN_ALTER)
|
|
self:_SetEdgeImgs(edgeImgs, outPorts.pipe, FacConst.BLUEPRINT_PREVIEW_PIPE_PORT_OUT, FacConst.BLUEPRINT_PREVIEW_PIPE_PORT_OUT_ALTER)
|
|
end
|
|
|
|
local needWaist = true
|
|
for face = 0, 3 do
|
|
local imgPath = edgeImgs[face]
|
|
local img
|
|
if not imgPath then
|
|
if face == 0 or face == 2 then
|
|
|
|
img = cell.m_imgCache:Get()
|
|
img:LoadSpriteWithOutFormat(isBigBuilding and FacConst.BLUEPRINT_PREVIEW_BUILDING_DEFAULT_EDGE_BIG or FacConst.BLUEPRINT_PREVIEW_BUILDING_DEFAULT_EDGE_SMALL)
|
|
img.transform.sizeDelta = Vector2(bData.range.width * uiSizePerUnit, isBigBuilding and 140 or 40)
|
|
img.type = CS.UnityEngine.UI.Image.Type.Sliced
|
|
end
|
|
else
|
|
img = cell.m_imgCache:Get()
|
|
img:LoadSpriteWithOutFormat(imgPath)
|
|
img:SetNativeSizeIgnoreRefScale()
|
|
img.type = CS.UnityEngine.UI.Image.Type.Simple
|
|
end
|
|
if img then
|
|
|
|
if face == 0 then
|
|
img.transform.anchoredPosition = Vector2(bData.range.width / 2, bData.range.depth) * uiSizePerUnit
|
|
img.transform.localEulerAngles = Vector3(0, 0, 0)
|
|
elseif face == 1 then
|
|
img.transform.anchoredPosition = Vector2(bData.range.width, bData.range.depth / 2) * uiSizePerUnit
|
|
img.transform.localEulerAngles = Vector3(0, 0, 270)
|
|
needWaist = false
|
|
elseif face == 2 then
|
|
img.transform.anchoredPosition = Vector2(bData.range.width / 2, 0) * uiSizePerUnit
|
|
img.transform.localEulerAngles = Vector3(0, 0, 180)
|
|
elseif face == 3 then
|
|
img.transform.anchoredPosition = Vector2(0, bData.range.depth / 2) * uiSizePerUnit
|
|
img.transform.localEulerAngles = Vector3(0, 0, 90)
|
|
needWaist = false
|
|
end
|
|
table.insert(cell.m_showingImgs, img)
|
|
end
|
|
end
|
|
cell.waistDeco.gameObject:SetActive(needWaist)
|
|
if isBigBuilding then
|
|
cell.machineBG:LoadSprite(UIConst.UI_SPRITE_FAC_BUILDING_PANEL_ICON_BIG, bData.iconOnPanel)
|
|
cell.machineBG.transform.localEulerAngles = Vector3(0, 0, -cell.bg.transform.localEulerAngles.z)
|
|
cell.machineBG.gameObject:SetActive(true)
|
|
else
|
|
cell.machineBG.gameObject:SetActive(false)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BlueprintPreview._GenDefaultBuildingPort = HL.Method(HL.Any, HL.Boolean, HL.Number, HL.Number).Return(HL.Table) << function(self, portsData, isInput, width, depth)
|
|
local ports = {
|
|
belt = { count = 0, edgeFace = -1, minPos = math.maxinteger, maxPos = math.mininteger },
|
|
pipe = { count = 0, edgeFace = -1, minPos = math.maxinteger, maxPos = math.mininteger },
|
|
}
|
|
for _, v in pairs(portsData) do
|
|
local info = v.isPipe and ports.pipe or ports.belt
|
|
info.count = info.count + 1
|
|
local portPosIsOnX = (v.trans.rotation.y / 90) % 2 == 0
|
|
local portPos = portPosIsOnX and v.trans.position.x or v.trans.position.z
|
|
info.minPos = math.min(portPos, info.minPos)
|
|
info.maxPos = math.max(portPos, info.maxPos)
|
|
info.edgeFace = (v.trans.rotation.y / 90 + (isInput and 2 or 0)) % 4
|
|
end
|
|
for _, info in pairs(ports) do
|
|
if info.count > 0 then
|
|
info.size = info.maxPos - info.minPos + 1
|
|
|
|
local buildingSize = info.edgeFace % 2 == 0 and width or depth
|
|
if (buildingSize - info.size) % 2 == 1 then
|
|
info.size = info.size + 1
|
|
end
|
|
end
|
|
end
|
|
return ports
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BlueprintPreview._GenPreviewConveyor = HL.Method(CS.Beyond.Gameplay.RemoteFactory.BlueprintConveyorEntry) << function(self, entry)
|
|
|
|
|
|
local cell = self.m_conveyorCellCache:Get()
|
|
local info = {
|
|
id = self:_GetNextTargetId(),
|
|
entry = entry,
|
|
canChangeIcon = false,
|
|
}
|
|
self.m_showingCellDic[cell] = info
|
|
self.m_id2Cell[info.id] = cell
|
|
|
|
local templateId = entry.templateId
|
|
local isBelt = templateId == FacConst.BELT_ID
|
|
info.type = isBelt and NodeType.Belt or NodeType.Pipe
|
|
info.segInfos = self:_GetConveyorSegmentInfos(entry)
|
|
info.isHighLayer = not isBelt
|
|
|
|
if isBelt then
|
|
|
|
cell.transform:SetAsFirstSibling()
|
|
end
|
|
|
|
local imgs = isBelt and FacConst.BLUEPRINT_PREVIEW_BELT_IMGS or FacConst.BLUEPRINT_PREVIEW_PIPE_IMGS
|
|
self:_PrepareCellImgCache(cell)
|
|
for k, v in ipairs(info.segInfos) do
|
|
|
|
local img = cell.m_imgCache:Get()
|
|
if UNITY_EDITOR then
|
|
img.gameObject.name = "Seg_" .. k
|
|
end
|
|
table.insert(cell.m_showingImgs, img)
|
|
if v.length then
|
|
|
|
img:LoadSpriteWithOutFormat(imgs.normal)
|
|
local centerGridPos = v.startPoint + Vector2(0.5, 0.5) + (v.length - 1) / 2 * Face2Vector2[v.startFace]
|
|
img.transform.anchoredPosition = centerGridPos * uiSizePerUnit
|
|
img.transform.sizeDelta = Vector2(v.length, 1) * uiSizePerUnit
|
|
img.transform.localEulerAngles = Vector3(0, 0, Face2RotZForConveyor[v.startFace])
|
|
|
|
local endPoint = v.startPoint + (v.length - 1) * Face2Vector2[v.startFace]
|
|
local minX = math.min(v.startPoint.x, endPoint.x)
|
|
local minY = math.min(v.startPoint.y, endPoint.y)
|
|
local sizeX = math.abs(v.startPoint.x - endPoint.x) + 1
|
|
local sizeY = math.abs(v.startPoint.y - endPoint.y) + 1
|
|
self.m_previewHelper:BatchAddGridValue(minX, minY, sizeX, sizeY, info.id)
|
|
else
|
|
|
|
local imgInfo = FacConst.BLUEPRINT_PREVIEW_CORNER_DIC[v.startFace][v.endFace]
|
|
img:LoadSpriteWithOutFormat(imgInfo[1] and imgs.corner1 or imgs.corner2)
|
|
local centerGridPos = v.startPoint + Vector2(0.5, 0.5)
|
|
img.transform.anchoredPosition = centerGridPos * uiSizePerUnit
|
|
img.transform.sizeDelta = Vector2(uiSizePerUnit, uiSizePerUnit)
|
|
img.transform.localEulerAngles = Vector3(0, 0, imgInfo[2])
|
|
|
|
self.m_previewHelper:AddGridValue(v.startPoint.x, v.startPoint.y, info.id)
|
|
end
|
|
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
BlueprintPreview._GetConveyorSegmentInfos = HL.Method(CS.Beyond.Gameplay.RemoteFactory.BlueprintConveyorEntry).Return(HL.Table) << function(self, entry)
|
|
|
|
local spatialInfo = entry.spatial
|
|
local gridPath = spatialInfo.gridPath
|
|
local segInfos = {}
|
|
local curStartPoint = Vector2(gridPath.startPoint.x, gridPath.startPoint.y)
|
|
local curStartFace = spatialInfo.startFace
|
|
for _, vector in pairs(gridPath.segments) do
|
|
local length = vector.length
|
|
if vector.face ~= curStartFace then
|
|
|
|
local cornerInfo = {
|
|
startPoint = curStartPoint,
|
|
startFace = curStartFace,
|
|
endFace = vector.face,
|
|
}
|
|
curStartFace = cornerInfo.endFace
|
|
curStartPoint = curStartPoint + Face2Vector2[cornerInfo.endFace]
|
|
table.insert(segInfos, cornerInfo)
|
|
length = length - 1
|
|
end
|
|
|
|
if length > 0 then
|
|
|
|
local straightInfo = {
|
|
startPoint = curStartPoint,
|
|
startFace = curStartFace,
|
|
length = length,
|
|
}
|
|
table.insert(segInfos, straightInfo)
|
|
curStartPoint = curStartPoint + straightInfo.length * Face2Vector2[curStartFace]
|
|
end
|
|
end
|
|
return segInfos
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BlueprintPreview.m_iconCells = HL.Field(HL.Forward('UIListCache'))
|
|
|
|
|
|
BlueprintPreview.m_changedIcons = HL.Field(HL.Table)
|
|
|
|
|
|
BlueprintPreview.m_curIconIndex = HL.Field(HL.Number) << -1
|
|
|
|
|
|
BlueprintPreview.m_iconInfos = HL.Field(HL.Table)
|
|
|
|
|
|
BlueprintPreview.m_curChangeIconTargetId = HL.Field(HL.Number) << -1
|
|
|
|
|
|
|
|
|
|
BlueprintPreview._InitChangeIconNode = HL.Method() << function(self)
|
|
local node = self.view.changeIconNode
|
|
self.m_iconCells = UIUtils.genCellCache(node.iconCell)
|
|
node.autoCloseArea.onTriggerAutoClose:AddListener(function()
|
|
self:_HideChangeIconNode()
|
|
end)
|
|
end
|
|
|
|
|
|
|
|
|
|
BlueprintPreview._ShowChangeIconNode = HL.Method(HL.Number) << function(self, targetId)
|
|
if self.m_curChangeIconTargetId == targetId then
|
|
self:_HideChangeIconNode()
|
|
return
|
|
end
|
|
|
|
local node = self.view.changeIconNode
|
|
node.gameObject:SetActive(true)
|
|
node.animationWrapper:ClearTween(false)
|
|
node.animationWrapper:PlayInAnimation()
|
|
|
|
self.m_curChangeIconTargetId = targetId
|
|
|
|
local cell = self.m_id2Cell[targetId]
|
|
local info = self.m_showingCellDic[cell]
|
|
local templateId = info.entry.templateId
|
|
local bData = Tables.factoryBuildingTable[templateId]
|
|
node.titleTxt.text = string.format(Language.LUA_FAC_BLUEPRINT_CHANGE_MACHINE_ICON_TITLE, bData.name)
|
|
|
|
|
|
local iconMap = {
|
|
[""] = {
|
|
itemId = "",
|
|
icon = bData.iconOnPanel,
|
|
sortId1 = math.maxinteger,
|
|
},
|
|
}
|
|
local _, curItemId = self:_GetTargetIconInfo(targetId)
|
|
if not string.isEmpty(curItemId) then
|
|
|
|
local itemData = Tables.itemTable[curItemId]
|
|
iconMap[curItemId] = {
|
|
itemId = curItemId,
|
|
icon = itemData.iconId,
|
|
sortId1 = itemData.sortId1,
|
|
sortId2 = itemData.sortId2,
|
|
rarity = itemData.rarity,
|
|
}
|
|
end
|
|
local _, formulaCpt = info.entry.info:TryGetValue(GEnums.FCComponentPos.FormulaMan)
|
|
local currentMode
|
|
if formulaCpt and not string.isEmpty(formulaCpt.currentMode) then
|
|
currentMode = formulaCpt.currentMode
|
|
end
|
|
local craftInfos = FactoryUtils.getBuildingCrafts(templateId, nil, nil, currentMode)
|
|
for _, cInfo in ipairs(craftInfos) do
|
|
if cInfo.outcomes then
|
|
for _, v in ipairs(cInfo.outcomes) do
|
|
local itemId = v.id
|
|
if not iconMap[itemId] then
|
|
local itemData = Tables.itemTable[itemId]
|
|
iconMap[itemId] = {
|
|
itemId = itemId,
|
|
icon = itemData.iconId,
|
|
sortId1 = itemData.sortId1,
|
|
sortId2 = itemData.sortId2,
|
|
rarity = itemData.rarity,
|
|
}
|
|
end
|
|
end
|
|
end
|
|
end
|
|
self.m_iconInfos = {}
|
|
for _, v in pairs(iconMap) do
|
|
table.insert(self.m_iconInfos, v)
|
|
end
|
|
table.sort(self.m_iconInfos, Utils.genSortFunction({ "sortId1", "sortId2", "itemId" }))
|
|
|
|
local selectedCell = nil
|
|
|
|
self.m_iconCells:Refresh(#self.m_iconInfos, function(iconCell, index)
|
|
local iconInfo = self.m_iconInfos[index]
|
|
if string.isEmpty(iconInfo.itemId) then
|
|
|
|
|
|
iconCell.icon:InitItemIcon("item_gold")
|
|
iconCell.icon.view.icon:LoadSprite(UIConst.UI_SPRITE_FAC_BUILDING_PANEL_ICON, iconInfo.icon)
|
|
iconCell.rarityLine.gameObject:SetActive(false)
|
|
iconCell.rarityLight.gameObject:SetActive(false)
|
|
else
|
|
iconCell.icon:InitItemIcon(iconInfo.itemId)
|
|
iconCell.rarityLine.gameObject:SetActive(true)
|
|
iconCell.rarityLight.gameObject:SetActive(true)
|
|
local color = UIUtils.getItemRarityColor(iconInfo.rarity)
|
|
iconCell.rarityLine.color = color
|
|
iconCell.rarityLight.color = color
|
|
end
|
|
iconCell.button.onClick:RemoveAllListeners()
|
|
iconCell.button.onClick:AddListener(function()
|
|
self:_OnClickIcon(index)
|
|
end)
|
|
local isSelected = iconInfo.itemId == curItemId
|
|
if isSelected then
|
|
self.m_curIconIndex = index
|
|
selectedCell = iconCell
|
|
end
|
|
iconCell.stateController:SetState(isSelected and "Selected" or "Normal")
|
|
end)
|
|
cell.selectedNode.gameObject:SetActive(true)
|
|
|
|
local panelCtrl = self:GetUICtrl()
|
|
UIUtils.updateTipsPosition(self.view.changeIconNode.transform, cell.transform, panelCtrl.view.transform, panelCtrl.uiCamera,
|
|
UIConst.UI_TIPS_POS_TYPE.RightTop, {
|
|
top = self.view.config.CHANGE_ICON_NODE_PADDING_VER.x,
|
|
bottom = self.view.config.CHANGE_ICON_NODE_PADDING_VER.y,
|
|
left = self.view.config.CHANGE_ICON_NODE_PADDING_HOR.x,
|
|
right = self.view.config.CHANGE_ICON_NODE_PADDING_HOR.y,
|
|
})
|
|
node.autoCloseArea.tmpSafeArea = cell.transform
|
|
|
|
|
|
if DeviceInfo.usingController then
|
|
node.selectableNaviGroup:ManuallyFocus()
|
|
if selectedCell then
|
|
self.mouseShow = false
|
|
self.view.leftBottomNode.gameObject:SetActive(false)
|
|
self:_CancelHover()
|
|
UIUtils.setAsNaviTarget(selectedCell.button)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
BlueprintPreview._OnClickIcon = HL.Method(HL.Number) << function(self, index)
|
|
if index == self.m_curIconIndex then
|
|
return
|
|
end
|
|
|
|
local oldCell = self.m_iconCells:Get(self.m_curIconIndex)
|
|
oldCell.stateController:SetState("Normal")
|
|
self.m_curIconIndex = index
|
|
local newCell = self.m_iconCells:Get(self.m_curIconIndex)
|
|
newCell.stateController:SetState("Selected")
|
|
|
|
self.m_changedIcons[self.m_curChangeIconTargetId] = self.m_iconInfos[index].itemId
|
|
self:_UpdateTargetIcon(self.m_curChangeIconTargetId)
|
|
end
|
|
|
|
|
|
|
|
|
|
BlueprintPreview._HideChangeIconNode = HL.Method(HL.Opt(HL.Boolean)) << function(self, skipAni)
|
|
local node = self.view.changeIconNode
|
|
if not skipAni then
|
|
if node.animationWrapper.curState == CS.Beyond.UI.UIConst.AnimationState.Out then
|
|
|
|
return
|
|
end
|
|
end
|
|
|
|
if skipAni then
|
|
node.animationWrapper:ClearTween(false)
|
|
node.gameObject:SetActive(false)
|
|
else
|
|
UIUtils.PlayAnimationAndToggleActive(node.animationWrapper, false)
|
|
end
|
|
self.mouseShow = true
|
|
self.view.leftBottomNode.gameObject:SetActive(true)
|
|
if self.m_curChangeIconTargetId > 0 then
|
|
local cell = self.m_id2Cell[self.m_curChangeIconTargetId]
|
|
self.m_curChangeIconTargetId = -1
|
|
cell.selectedNode.gameObject:SetActive(false)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
BlueprintPreview._GetTargetIconInfo = HL.Method(HL.Number).Return(HL.Opt(HL.String, HL.String, HL.Number)) << function(self, targetId)
|
|
local itemId = self.m_changedIcons[targetId]
|
|
local cell = self.m_id2Cell[targetId]
|
|
local info = self.m_showingCellDic[cell]
|
|
if not itemId then
|
|
itemId = info.entry.productIcon
|
|
end
|
|
if string.isEmpty(itemId) then
|
|
|
|
if info.type == NodeType.Building then
|
|
local data = Tables.factoryBuildingTable[info.entry.templateId]
|
|
return data.iconOnPanel, ""
|
|
end
|
|
return
|
|
end
|
|
local itemData = Tables.itemTable[itemId]
|
|
return itemData.iconId, itemId, itemData.rarity
|
|
end
|
|
|
|
|
|
|
|
|
|
BlueprintPreview._UpdateTargetIcon = HL.Method(HL.Number) << function(self, targetId)
|
|
local cell = self.m_id2Cell[targetId]
|
|
local info = self.m_showingCellDic[cell]
|
|
local icon, itemId, rarity = self:_GetTargetIconInfo(targetId)
|
|
local node = cell.iconNode
|
|
node.machineIcon.gameObject:SetActive(false)
|
|
node.emptyNode.gameObject:SetActive(false)
|
|
node.itemNode.gameObject:SetActive(false)
|
|
if icon == nil then
|
|
node.emptyNode.gameObject:SetActive(true)
|
|
elseif string.isEmpty(itemId) then
|
|
node.machineIcon.gameObject:SetActive(true)
|
|
node.machineIcon:LoadSprite(UIConst.UI_SPRITE_FAC_BUILDING_PANEL_ICON, icon)
|
|
else
|
|
node.itemNode.gameObject:SetActive(true)
|
|
node.itemIcon:InitItemIcon(itemId)
|
|
local color = UIUtils.getItemRarityColor(rarity)
|
|
node.rarityIcon.color = color
|
|
local isAbnormal
|
|
if Utils.isInBlackbox() then
|
|
isAbnormal = false
|
|
else
|
|
isAbnormal = self.m_bpAbnormalIconHelper and self.m_bpAbnormalIconHelper.IsAbnormal(info.entry.templateId, itemId)
|
|
end
|
|
node.abnormalNode.gameObject:SetActive(isAbnormal)
|
|
end
|
|
node.changeHint.gameObject:SetActive(info.canChangeIcon)
|
|
end
|
|
|
|
|
|
|
|
BlueprintPreview.ApplyIconChanges = HL.Method() << function(self)
|
|
for targetId, itemId in pairs(self.m_changedIcons) do
|
|
local cell = self.m_id2Cell[targetId]
|
|
local info = self.m_showingCellDic[cell]
|
|
info.entry.productIcon = itemId
|
|
end
|
|
end
|
|
|
|
|
|
|
|
BlueprintPreview.GetChangedIcons = HL.Method().Return(HL.Opt(HL.Table)) << function(self)
|
|
if not self:HasIconChanged() then
|
|
return
|
|
end
|
|
local dic = {}
|
|
for targetId, newIcon in pairs(self.m_changedIcons) do
|
|
local cell = self.m_id2Cell[targetId]
|
|
local info = self.m_showingCellDic[cell]
|
|
dic[info.entry.nodeId] = newIcon
|
|
end
|
|
return dic
|
|
end
|
|
|
|
|
|
|
|
BlueprintPreview.HasIconChanged = HL.Method().Return(HL.Boolean) << function(self)
|
|
return next(self.m_changedIcons) ~= nil
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BlueprintPreview.m_curHoverTargetId = HL.Field(HL.Any)
|
|
|
|
|
|
BlueprintPreview.m_curHoverTargetId2 = HL.Field(HL.Any)
|
|
|
|
|
|
|
|
|
|
BlueprintPreview._UpdateHoverPos = HL.Method() << function(self)
|
|
if not DeviceInfo.usingController and not self.view.maskBtnArea.pointerInArea then
|
|
|
|
if self.m_curHoverTargetId then
|
|
self:_CancelHover()
|
|
end
|
|
return
|
|
end
|
|
if DeviceInfo.usingController then
|
|
if not self.mouseShow then
|
|
self.view.controllerMouse.gameObject:SetActive(false)
|
|
return
|
|
end
|
|
self.view.controllerMouse.gameObject:SetActive(true)
|
|
local stickValue = InputManagerInst:GetGamepadStickValue(true)
|
|
local moveDelta = stickValue * self.view.config.CONTROLLER_MOVE_SPEED * Time.deltaTime
|
|
local targetPosition = self.view.controllerMouse.anchoredPosition + moveDelta
|
|
local targetNormalizedPosition = self.view.scrollRect.normalizedPosition
|
|
if targetPosition.x <= self.view.config.CONTROLLER_PADDING and self.m_widthScale > 0 then
|
|
targetNormalizedPosition.x = lume.clamp(self.view.scrollRect.normalizedPosition.x - self.view.config.CONTROLLER_ROLL_SPEED * Time.deltaTime / self.m_widthScale,0,1)
|
|
elseif targetPosition.x >= self.view.scrollRectRectTransform.rect.size.x - self.view.config.CONTROLLER_PADDING and self.m_widthScale > 0 then
|
|
targetNormalizedPosition.x = lume.clamp(self.view.scrollRect.normalizedPosition.x + self.view.config.CONTROLLER_ROLL_SPEED * Time.deltaTime / self.m_widthScale,0,1)
|
|
end
|
|
if targetPosition.y <= self.view.config.CONTROLLER_PADDING and self.m_heightScale > 0 then
|
|
targetNormalizedPosition.y = lume.clamp(self.view.scrollRect.normalizedPosition.y - self.view.config.CONTROLLER_ROLL_SPEED * Time.deltaTime / self.m_heightScale,0,1)
|
|
elseif targetPosition.y >= self.view.scrollRectRectTransform.rect.size.y - self.view.config.CONTROLLER_PADDING and self.m_heightScale > 0 then
|
|
targetNormalizedPosition.y = lume.clamp(self.view.scrollRect.normalizedPosition.y + self.view.config.CONTROLLER_ROLL_SPEED * Time.deltaTime / self.m_heightScale,0,1)
|
|
end
|
|
self.view.scrollRect.normalizedPosition = targetNormalizedPosition
|
|
|
|
if stickValue ~= Vector2.zero then
|
|
targetPosition.x = lume.clamp(targetPosition.x,self.view.config.CONTROLLER_PADDING,self.view.scrollRectRectTransform.rect.size.x - self.view.config.CONTROLLER_PADDING)
|
|
targetPosition.y = lume.clamp(targetPosition.y,self.view.config.CONTROLLER_PADDING,self.view.scrollRectRectTransform.rect.size.y - self.view.config.CONTROLLER_PADDING)
|
|
self.view.controllerMouse.anchoredPosition = targetPosition
|
|
end
|
|
end
|
|
|
|
|
|
local mousePos = InputManager.mousePosition:XY()
|
|
local rect = CSUtils.RectTransformToScreenRect(self.view.content.transform, self:GetUICtrl().uiCamera)
|
|
local relativePos = mousePos - rect.min
|
|
local gridScreenSize = rect.width / self.m_csBP.sourceRect.width
|
|
local gridPos = relativePos / gridScreenSize
|
|
gridPos = Vector2(math.floor(gridPos.x), math.floor(gridPos.y))
|
|
local id1, id2 = self.m_previewHelper:GetGridValue(gridPos.x, gridPos.y)
|
|
if id1 == 0 then
|
|
|
|
if self.m_curHoverTargetId then
|
|
self:_CancelHover()
|
|
end
|
|
self.view.controllerEditBtn.interactable = false
|
|
return
|
|
end
|
|
|
|
|
|
local cell1 = self.m_id2Cell[id1]
|
|
local info1 = self.m_showingCellDic[cell1]
|
|
local isConveyor = info1.type == NodeType.Belt or info1.type == NodeType.Pipe
|
|
if not isConveyor and id1 == self.m_curHoverTargetId and id2 == self.m_curHoverTargetId2 then
|
|
|
|
return
|
|
end
|
|
|
|
self.view.controllerEditBtn.interactable = info1.canChangeIcon
|
|
|
|
self.m_curHoverTargetId = id1
|
|
if id2 == 0 then
|
|
self.m_curHoverTargetId2 = nil
|
|
else
|
|
local cell2 = self.m_id2Cell[id2]
|
|
local info2 = self.m_showingCellDic[cell2]
|
|
if info2.isHighLayer then
|
|
self.m_curHoverTargetId = id2
|
|
self.m_curHoverTargetId2 = id1
|
|
isConveyor = info2.type == NodeType.Belt or info2.type == NodeType.Pipe
|
|
cell1, info1 = cell2, info2
|
|
else
|
|
self.m_curHoverTargetId2 = id2
|
|
end
|
|
end
|
|
self:_UpdateHoverTips()
|
|
|
|
self.view.hoverHint.gameObject:SetActive(true)
|
|
self.view.hoverTipsNode.gameObject:SetActive(true)
|
|
|
|
if isConveyor then
|
|
self.view.hoverHint.transform.sizeDelta = Vector2(uiSizePerUnit, uiSizePerUnit)
|
|
self.view.hoverHint.transform.anchoredPosition = Vector2(math.floor(gridPos.x) + 0.5, math.floor(gridPos.y) + 0.5) * uiSizePerUnit
|
|
else
|
|
self.view.hoverHint.transform.sizeDelta = cell1.transform.sizeDelta
|
|
self.view.hoverHint.transform.anchoredPosition = cell1.transform.anchoredPosition
|
|
end
|
|
end
|
|
|
|
|
|
|
|
BlueprintPreview._CancelHover = HL.Method() << function(self)
|
|
self.m_curHoverTargetId = nil
|
|
self.m_curHoverTargetId2 = nil
|
|
self.view.hoverHint.gameObject:SetActive(false)
|
|
self.view.hoverTipsNode.gameObject:SetActive(false)
|
|
end
|
|
|
|
|
|
|
|
BlueprintPreview._OnClick = HL.Method() << function(self)
|
|
if not self.m_canEdit then
|
|
return
|
|
end
|
|
|
|
self:_UpdateHoverPos()
|
|
|
|
if self.m_curHoverTargetId then
|
|
local info = self.m_showingCellDic[self.m_id2Cell[self.m_curHoverTargetId]]
|
|
if not info.canChangeIcon then
|
|
return
|
|
end
|
|
self:_ShowChangeIconNode(self.m_curHoverTargetId)
|
|
|
|
end
|
|
if self.m_curHoverTargetId2 then
|
|
|
|
end
|
|
end
|
|
|
|
|
|
|
|
BlueprintPreview._UpdateHoverTips = HL.Method() << function(self)
|
|
self:_UpdateSingleHoverTips(self.view.hoverTipsCell, self.m_curHoverTargetId)
|
|
self:_UpdateSingleHoverTips(self.view.hoverTipsCell2, self.m_curHoverTargetId2)
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
BlueprintPreview._UpdateSingleHoverTips = HL.Method(HL.Table, HL.Any) << function(self, cell, targetId)
|
|
if not targetId then
|
|
cell.m_curTargetId = nil
|
|
cell.gameObject.gameObject:SetActive(false)
|
|
return
|
|
end
|
|
local oriActive = cell.gameObject.activeInHierarchy
|
|
cell.gameObject.gameObject:SetActive(true)
|
|
if cell.m_curTargetId == targetId then
|
|
if not oriActive then
|
|
AudioAdapter.PostEvent("Au_UI_Popup_CommonHoverTipPanel_Open")
|
|
end
|
|
return
|
|
end
|
|
cell.m_curTargetId = targetId
|
|
AudioAdapter.PostEvent("Au_UI_Popup_CommonHoverTipPanel_Open")
|
|
|
|
local nodeCell = self.m_id2Cell[targetId]
|
|
local info = self.m_showingCellDic[nodeCell]
|
|
local templateId = info.entry.templateId
|
|
local icon, name, itemId
|
|
if info.type == NodeType.Building then
|
|
local data = Tables.factoryBuildingTable[templateId]
|
|
icon = data.iconOnPanel
|
|
name = data.name
|
|
itemId = FactoryUtils.getBuildingItemId(templateId)
|
|
elseif info.type == NodeType.Logistic then
|
|
local data = FactoryUtils.getLogisticData(templateId)
|
|
icon = data.iconOnPanel
|
|
name = data.name
|
|
itemId = data.itemId
|
|
elseif info.type == NodeType.Belt then
|
|
local data = Tables.factoryGridBeltTable[templateId]
|
|
icon = data.beltData.iconOnPanel
|
|
name = data.beltData.name
|
|
itemId = data.beltData.itemId
|
|
elseif info.type == NodeType.Pipe then
|
|
local data = Tables.factoryLiquidPipeTable[templateId]
|
|
icon = data.pipeData.iconOnPanel
|
|
name = data.pipeData.name
|
|
itemId = data.pipeData.itemId
|
|
end
|
|
|
|
cell.icon:LoadSprite(UIConst.UI_SPRITE_FAC_BUILDING_PANEL_ICON, icon)
|
|
cell.nameTxt.text = name
|
|
local itemData = Tables.itemTable[itemId]
|
|
cell.rarityLine.color = UIUtils.getItemRarityColor(itemData.rarity)
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BlueprintPreview._OnEnable = HL.Override() << function(self)
|
|
if self.m_updateId < 0 then
|
|
self.m_updateId = LuaUpdate:Add("TailTick", function()
|
|
self:_UpdateHoverPos()
|
|
end)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
BlueprintPreview._OnDisable = HL.Override() << function(self)
|
|
if self.m_updateId then
|
|
self.m_updateId = LuaUpdate:Remove(self.m_updateId)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
BlueprintPreview._OnDestroy = HL.Override() << function(self)
|
|
if self.m_updateId then
|
|
self.m_updateId = LuaUpdate:Remove(self.m_updateId)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
BlueprintPreview._GetNextTargetId = HL.Method().Return(HL.Number) << function(self)
|
|
local id = self.m_nextTargetId
|
|
self.m_nextTargetId = self.m_nextTargetId + 1
|
|
return id
|
|
end
|
|
|
|
|
|
|
|
|
|
BlueprintPreview._PrepareCellImgCache = HL.Method(HL.Any) << function(self, cell)
|
|
if not cell.m_imgCache then
|
|
cell.m_imgCache = CommonCache(function()
|
|
local obj = CSUtils.CreateObject(cell.image.gameObject, cell.image.transform.parent)
|
|
return obj.gameObject:GetComponent("UIImage")
|
|
end, function(img)
|
|
img.gameObject:SetActive(true)
|
|
end, function(img)
|
|
img.gameObject:SetActive(false)
|
|
end)
|
|
cell.m_imgCache:Cache(cell.image)
|
|
cell.m_showingImgs = {}
|
|
else
|
|
for _, img in ipairs(cell.m_showingImgs) do
|
|
cell.m_imgCache:Cache(img)
|
|
end
|
|
cell.m_showingImgs = {}
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
HL.Commit(BlueprintPreview)
|
|
return BlueprintPreview
|