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

221 lines
6.7 KiB
Lua

local uiCtrl = require_ex('UI/Panels/Base/UICtrl')
local PANEL_ID = PanelId.SettlementDefenseTracker
local LuaNodeCache = require_ex('Common/Utils/LuaNodeCache')
local STANDARD_HORIZONTAL_RESOLUTION = CS.Beyond.UI.UIConst.CUR_STANDARD_HORIZONTAL_RESOLUTION
local STANDARD_VERTICAL_RESOLUTION = CS.Beyond.UI.UIConst.CUR_STANDARD_VERTICAL_RESOLUTION
SettlementDefenseTrackerCtrl = HL.Class('SettlementDefenseTrackerCtrl', uiCtrl.UICtrl)
local TRACKER_CORE_ATTACKED_IN_ANIMATION_NAME = "defense_tracker_core_attacked_in"
SettlementDefenseTrackerCtrl.m_towerDefenseGame = HL.Field(HL.Userdata)
SettlementDefenseTrackerCtrl.m_spawnerTrackerCache = HL.Field(LuaNodeCache)
SettlementDefenseTrackerCtrl.m_coreTrackerCache = HL.Field(LuaNodeCache)
SettlementDefenseTrackerCtrl.m_spawnerTrackerDataList = HL.Field(HL.Table)
SettlementDefenseTrackerCtrl.m_coreTrackerDataList = HL.Field(HL.Table)
SettlementDefenseTrackerCtrl.m_xEdgeRadius = HL.Field(HL.Number) << -1
SettlementDefenseTrackerCtrl.m_yEdgeRadius = HL.Field(HL.Number) << -1
SettlementDefenseTrackerCtrl.m_updateThread = HL.Field(HL.Thread)
SettlementDefenseTrackerCtrl.m_hpChangeCallbackList = HL.Field(HL.Table)
SettlementDefenseTrackerCtrl.s_messages = HL.StaticField(HL.Table) << {
}
SettlementDefenseTrackerCtrl.OnCreate = HL.Override(HL.Any) << function(self, arg)
self.m_towerDefenseGame = GameInstance.player.towerDefenseSystem.towerDefenseGame
self.m_spawnerTrackerCache = LuaNodeCache(self.view.spawnerTracker, self.view.spawnerTrackersRoot)
self.m_coreTrackerCache = LuaNodeCache(self.view.coreTracker, self.view.coreTrackersRoot)
self.m_spawnerTrackerDataList = {}
self.m_coreTrackerDataList = {}
self.m_hpChangeCallbackList = {}
self.m_xEdgeRadius = self.view.config.TRACKER_EDGE_RADIUS_X * (
self.view.main.rect.width / STANDARD_HORIZONTAL_RESOLUTION
)
self.m_yEdgeRadius = self.view.config.TRACKER_EDGE_RADIUS_Y * (
self.view.main.rect.height / STANDARD_VERTICAL_RESOLUTION
)
self:_InitTrackerTargets()
end
SettlementDefenseTrackerCtrl.OnClose = HL.Override() << function(self)
self.m_updateThread = self:_ClearCoroutine(self.m_updateThread)
if self.m_towerDefenseGame ~= nil then
local coreAbilitySystems = self.m_towerDefenseGame.tdCoreAbilitySystems
for coreAbilityIndex = 0, coreAbilitySystems.Count - 1 do
local coreAbilitySystem = coreAbilitySystems[coreAbilityIndex]
coreAbilitySystem.onHpChange:Remove(self.m_hpChangeCallbackList[coreAbilityIndex])
end
end
end
SettlementDefenseTrackerCtrl._BuildTrackerData = HL.Method(Vector3, HL.Any).Return(HL.Table) << function(self, worldPos, tracker)
return {
worldPos = worldPos,
tracker = tracker,
isInBound = false,
visible = true,
}
end
SettlementDefenseTrackerCtrl._InitTrackerTargets = HL.Method() << function(self)
local towerDefenseGame = GameInstance.player.towerDefenseSystem.towerDefenseGame
local coreAbilitySystems = towerDefenseGame.tdCoreAbilitySystems
local corePositions = towerDefenseGame.tdCorePositions
local spawners = towerDefenseGame.gameData.portalEffectPosRot
if coreAbilitySystems.Count > 0 then
for coreAbilityIndex = 0, coreAbilitySystems.Count - 1 do
local coreAbilitySystem = coreAbilitySystems[coreAbilityIndex]
local coreWorldPos = coreAbilitySystem.entity.position + self.view.config.CORE_TRACKER_OFFSET
local coreTracker = self.m_coreTrackerCache:Get()
table.insert(self.m_coreTrackerDataList, self:_BuildTrackerData(coreWorldPos, coreTracker))
local callback = function(entity, changedHp)
if changedHp < 0 then
coreTracker.animationWrapper:ClearTween()
coreTracker.animationWrapper:PlayWithTween(TRACKER_CORE_ATTACKED_IN_ANIMATION_NAME)
end
end
self.m_hpChangeCallbackList[coreAbilityIndex] = callback
coreAbilitySystem.onHpChange:Add(callback)
end
else
for coreIndex = 0, corePositions.Count - 1 do
local coreWorldPos = corePositions[coreIndex] + self.view.config.CORE_TRACKER_OFFSET
local coreTracker = self.m_coreTrackerCache:Get()
table.insert(self.m_coreTrackerDataList, self:_BuildTrackerData(coreWorldPos, coreTracker))
end
end
local spawnerCount = spawners ~= nil and spawners.Count or 0
if spawnerCount == 0 then
logger.error("【据点防守】出怪点特效位置 配置数量为0")
end
for spawnerIndex = 0, spawnerCount - 1 do
local spawnerWorldPos = spawners[spawnerIndex].position + self.view.config.SPAWNER_TRACKER_OFFSET
local spawnerTracker = self.m_spawnerTrackerCache:Get()
table.insert(self.m_spawnerTrackerDataList, self:_BuildTrackerData(spawnerWorldPos, spawnerTracker))
end
self:_UpdateTrackersThread()
self.m_updateThread = self:_StartCoroutine(function()
while true do
self:_UpdateTrackersThread()
coroutine.step()
end
end)
end
SettlementDefenseTrackerCtrl._UpdateTrackersThread = HL.Method() << function(self)
for _, coreData in ipairs(self.m_coreTrackerDataList) do
self:_UpdateTrackerScreenPosition(coreData)
self:_RefreshTrackerState(coreData)
end
for _, spawnerData in ipairs(self.m_spawnerTrackerDataList) do
self:_UpdateTrackerScreenPosition(spawnerData)
self:_RefreshTrackerState(spawnerData)
end
end
SettlementDefenseTrackerCtrl._UpdateTrackerScreenPosition = HL.Method(HL.Table) << function(self, data)
if data == nil or data.worldPos == nil then
return
end
local screenPos = CameraManager.mainCamera:WorldToScreenPoint(data.worldPos)
if screenPos.z < 0 then
screenPos.x = Screen.width-screenPos.x
screenPos.y = -screenPos.y
end
local screenPos = UIUtils.screenPointToUI(Vector2(screenPos.x, screenPos.y), self.uiCamera)
local uiPos, uiAngle, isOutBound = UIUtils.mapScreenPosToEllipseEdge(screenPos, self.m_xEdgeRadius / 2.0, self.m_yEdgeRadius / 2.0)
data.position = uiPos
data.angle = uiAngle
data.isInBound = not isOutBound
end
SettlementDefenseTrackerCtrl._RefreshTrackerState = HL.Method(HL.Table) << function(self, data)
if not data.visible then
data.tracker.gameObject:SetActiveIfNecessary(false)
return
end
local tracker = data.tracker
tracker.rectTransform.anchoredPosition = data.position
tracker.arrowRotator.localRotation = Quaternion.Euler(0, 0, data.angle);
tracker.arrowRotator.gameObject:SetActiveIfNecessary(not data.isInBound)
tracker.gameObject:SetActiveIfNecessary(true)
end
HL.Commit(SettlementDefenseTrackerCtrl)