1+ -- ******************************************************************************************************
2+ -- ** Copyright (c) 2025 Willem 'Jip' Wijnia
3+ -- **
4+ -- ** Permission is hereby granted, free of charge, to any person obtaining a copy
5+ -- ** of this software and associated documentation files (the "Software"), to deal
6+ -- ** in the Software without restriction, including without limitation the rights
7+ -- ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ -- ** copies of the Software, and to permit persons to whom the Software is
9+ -- ** furnished to do so, subject to the following conditions:
10+ -- **
11+ -- ** The above copyright notice and this permission notice shall be included in all
12+ -- ** copies or substantial portions of the Software.
13+ -- **
14+ -- ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ -- ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ -- ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ -- ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ -- ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ -- ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+ -- ** SOFTWARE.
21+ -- ******************************************************************************************************
22+
23+ local TableGetn = table .getn
24+ local TableEmpty = table .empty
25+ local TableInsert = table.insert
26+
27+ local MathFloor = math.floor
28+ local MathMin = math.min
29+ local MathMax = math.max
130
231local UserDecal = import (" /lua/user/userdecal.lua" ).UserDecal
332local CreateChunkTemplate = import (" /lua/shared/aichunktemplates.lua" ).CreateChunkTemplate
433local VerifyChunkTemplate = import (" /lua/shared/aichunktemplates.lua" ).VerifyChunkTemplate
534local StringifyChunkTemplate = import (" /lua/shared/aichunktemplates.lua" ).StringifyChunkTemplate
635
36+ --- Adds the given units to the given template.
37+ --- @param template AIChunkTemplate
38+ --- @param units UserUnit[]
739--- @param size number
8- function PopulateChunkTemplate (size )
9- -- sanity check
10- local template = CreateChunkTemplate (size , ' UEF' )
11- if not template then
12- return
13- end
14-
15- -- sanity check
16- local selection = GetSelectedUnits ()
17- if not selection or table .empty (selection ) then
18- return
19- end
20-
40+ --- @return boolean
41+ function AddToChunkTemplate (template , units , size )
2142 local buildAreas = template .BuildAreas
2243
23- -- for debugging
24- local decals = { }
25- ForkThread (
26- function ()
27- WaitSeconds (10 )
28- for k , v in decals do
29- v :Destroy ()
30- end
31- end
32- )
33-
34- local c = table .getn (selection )
44+ -- compute the center
45+ local c = TableGetn (units )
3546 local cx , cz = 0 , 0
3647 for k = 1 , c do
3748 -- compute center
38- local unit = selection [k ]
49+ local unit = units [k ]
3950 local position = unit :GetPosition ()
4051 cx = cx + position [1 ]
4152 cz = cz + position [3 ]
@@ -46,18 +57,18 @@ function PopulateChunkTemplate (size)
4657 --- @type string | number
4758 -- local id = "Walls"
4859 -- if not EntityCategoryContains(categories.WALL, unit) then
49- id = math.min ( math.max (blueprint .Physics .SkirtSizeX , blueprint .Physics .SkirtSizeZ ), 16 )
60+ id = MathMin ( MathMax (blueprint .Physics .SkirtSizeX , blueprint .Physics .SkirtSizeZ ), 16 )
5061 -- end
5162
52- table.insert (buildAreas [id ], unit )
63+ TableInsert (buildAreas [id ], unit )
5364 end
5465
55- cx = math.floor ((cx / c ) / size ) * size + 0.5 * size
56- cz = math.floor ((cz / c ) / size ) * size + 0.5 * size
66+ cx = MathFloor ((cx / c ) / size ) * size + 0.5 * size
67+ cz = MathFloor ((cz / c ) / size ) * size + 0.5 * size
5768
58- for k = 1 , table . getn (buildAreas ) do
69+ for k = 1 , TableGetn (buildAreas ) do
5970 local buildOffsets = buildAreas [k ]
60- for u = 1 , table . getn (buildOffsets ) do
71+ for u = 1 , TableGetn (buildOffsets ) do
6172 local unit = buildOffsets [u ] --[[ @as UserUnit]]
6273 local position = unit :GetPosition ()
6374 buildOffsets [u ] = {
@@ -69,29 +80,73 @@ function PopulateChunkTemplate (size)
6980
7081 -- #region debugging
7182
83+ -- add a decal underneath each unit that we processed
84+
85+ local decals = {}
86+ ForkThread (
87+ function ()
88+ WaitSeconds (10 )
89+ for k , v in decals do
90+ v :Destroy ()
91+ end
92+ end
93+ )
94+
7295 local decal = UserDecal ()
7396 decal :SetTexture (" /textures/ui/common/game/AreaTargetDecal/nuke_icon_inner.dds" )
7497 decal :SetScale ({ 20 , 1 , 20 })
75- decal :SetPosition ({cx , 0 , cz })
76- table.insert (decals , decal )
98+ decal :SetPosition ({ cx , 0 , cz })
99+ TableInsert (decals , decal )
77100
78- for k = 1 , table . getn (buildAreas ) do
101+ for k = 1 , TableGetn (buildAreas ) do
79102 local buildOffsets = buildAreas [k ]
80- for u = 1 , table . getn (buildOffsets ) do
103+ for u = 1 , TableGetn (buildOffsets ) do
81104 local offset = buildOffsets [u ]
82105
83106 local decal = UserDecal ()
84107 decal :SetTexture (" /textures/ui/common/game/AreaTargetDecal/nuke_icon_inner.dds" )
85108 decal :SetScale ({ 1 , 1 , 1 })
86109 decal :SetPosition ({ cx + offset [1 ], 0 , cz + offset [2 ] })
87- table.insert (decals , decal )
110+ TableInsert (decals , decal )
88111 end
89112 end
90113
91114 -- #endregion
92115
93- LOG (StringifyChunkTemplate (template ))
94- VerifyChunkTemplate (template )
116+ if not VerifyChunkTemplate (template ) then
117+ print (" Unable to create a valid chunk template" )
118+ return false
119+ end
120+
121+ return true
122+ end
123+
124+ --- Creates a new chunk template and populates it with the unit selection.
125+ --- @param size number
126+ --- @return AIChunkTemplate ?
127+ function AddUnitSelectionToEmptyChunkTemplate (size )
128+ -- sanity check
129+ local template = CreateChunkTemplate (size , ' UEF' )
130+ if not template then
131+ print (" Unable to create a new chunk template" )
132+ return
133+ end
134+
135+ -- sanity check
136+ local selection = GetSelectedUnits ()
137+ if not selection or TableEmpty (selection ) then
138+ print (" Unable to populate a new chunk template with no unit selection" )
139+ return
140+ end
141+
142+ -- populate the template
143+ local ok = AddToChunkTemplate (template , selection , size )
144+ if not ok then
145+ print (" Unable to populate a new chunk template with the given unit selection" )
146+ return
147+ end
95148
96- return template
97- end
149+ -- copy the template to the clipboard
150+ CopyToClipboard (StringifyChunkTemplate (template ))
151+ print (" Template copied to clipboard" )
152+ end
0 commit comments