From 9dceca3ec72af2a5475639d60b2eb6c5977cdcac Mon Sep 17 00:00:00 2001 From: speed2CZ Date: Tue, 1 Sep 2026 23:48:50 +0200 Subject: [PATCH 1/2] Improve wreckage extraction for map preview Instead of the shallow lookup for `WRECKAGE` group, so a full sweep of all groups and get positions from any group that contains `wreck`. `WRECKAGE` group is a naming convention for a group that is automatically spawned on game start, but there might be more wreck groups spawned later by map script. --- lua/ui/controls/resmappreview.lua | 35 +++++++------------- lua/ui/maputil.lua | 54 +++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 23 deletions(-) diff --git a/lua/ui/controls/resmappreview.lua b/lua/ui/controls/resmappreview.lua index c2394610f1..9106de289c 100644 --- a/lua/ui/controls/resmappreview.lua +++ b/lua/ui/controls/resmappreview.lua @@ -155,30 +155,19 @@ ResourceMapPreview = ClassUI(Group) { -- Add the wreckage, if activated. (done first so the important things appear on top) local wreckagemarkers = {} if enableWreckage then - local armies = mapdata.Scenario.Armies - - for _, army in armies do - -- This is so spectacularly brittle it's magnificent. - if army.Units and army.Units.Units and army.Units.Units.WRECKAGE and army.Units.Units.WRECKAGE.Units then - for k, v in army.Units.Units.WRECKAGE.Units do - -- Some maps have extra entities in the Units list, representing groups. - -- Very annoying, so let's check for the fields we care about. - if v.Position then - local marker = self.wreckageIconPool:Get() - table.insert(wreckagemarkers, marker) - if scenarioInfo.hidePreviewMarkers then - marker:Hide() - else - marker:Show() - end - - -- Yes, these ones have a capital Position, but the others have a lowercase. - LayoutHelpers.AtLeftTopIn(marker, self.mapPreview, - xOffset + (v.Position[1] / mWidth) * (self.size - 2) * xFactor, - yOffset + (v.Position[3] / mHeight) * (self.size - 2) * yFactor) - end - end + for _, pos in MapUtil.GetWreckagePositions(mapdata.Scenario) do + local marker = self.wreckageIconPool:Get() + table.insert(wreckagemarkers, marker) + if scenarioInfo.hidePreviewMarkers then + marker:Hide() + else + marker:Show() end + + -- Yes, these ones have a capital Position, but the others have a lowercase. + LayoutHelpers.AtLeftTopIn(marker, self.mapPreview, + xOffset + (pos[1] / mWidth) * (self.size - 2) * xFactor, + yOffset + (pos[3] / mHeight) * (self.size - 2) * yFactor) end end self.wreckagemarkers = wreckagemarkers diff --git a/lua/ui/maputil.lua b/lua/ui/maputil.lua index 7a37f1a756..a44b4abe0c 100644 --- a/lua/ui/maputil.lua +++ b/lua/ui/maputil.lua @@ -586,4 +586,58 @@ function GetStartPositionsFromScenario(scenarioInfo, scenarioSave) return output end +---Returns all units' (leaf nodes) positions under the specified group. +---@param tblNode? table +---@param positions? Vector[] +---@return Vector[] +local function extractUnitPositions(tblNode, positions) + positions = positions or {} + if not tblNode then return positions end + + for strName, tblData in pairs(tblNode.Units) do + if tblData.type == 'GROUP' then + positions = extractUnitPositions(tblData, positions) + else + table.insert(positions, tblData.Position) + end + end + + return positions +end + +---Extracts wreckage positions from all groups that contain `"wreck"` in their name. +---@param tblNode? table +---@param positions? Vector[] +---@return Vector[] +local function extractPositionsFromWreckageGroups(tblNode, positions) + positions = positions or {} + if not tblNode then return positions end + + for strName, tblData in pairs(tblNode.Units) do + if tblData.type == 'GROUP' then + if string.find(string.lower(strName), "wreck") then + positions = extractUnitPositions(tblData, positions) + else + positions = extractPositionsFromWreckageGroups(tblData, positions) + end + end + end + + return positions +end + +---Returns all unit wreckage positions. Extracted from army groups that contain `"wreck"` in their name. +---@param scenario UIScenarioSaveFile +---@return Vector[] +function GetWreckagePositions(scenario) + ---@type Vector[] + local positions = {} + + for _, army in pairs(scenario.Armies) do + positions = extractPositionsFromWreckageGroups(army.Units, positions) + end + + return positions +end + --#endregion From aa9335afddd873eac5f360121b56980ea0e7c0b7 Mon Sep 17 00:00:00 2001 From: speed2CZ Date: Wed, 2 Sep 2026 00:02:26 +0200 Subject: [PATCH 2/2] Create features.7269.md --- changelog/features.7269.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/features.7269.md diff --git a/changelog/features.7269.md b/changelog/features.7269.md new file mode 100644 index 0000000000..772fd471c5 --- /dev/null +++ b/changelog/features.7269.md @@ -0,0 +1 @@ +- Improved wreckae detection for lobby map preview. (#7269) \ No newline at end of file