Skip to content

Commit 09c76d2

Browse files
danfiremanclaude
andcommitted
Missile Silo UX: address review - reuse Attack AoE, use Vector.DistSq
Apply PR ZeroK-RTS#5771 review points to the missile silo launch UI: - Expose the Attack AoE falloff renderer as WG.DrawAoEPreview in gui_attack_aoe.lua and consume it, instead of duplicating the ring-drawing code. - Use Spring.Utilities.Vector.DistSq for squared distance rather than a hand-rolled helper. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 206552d commit 09c76d2

2 files changed

Lines changed: 43 additions & 42 deletions

File tree

LuaUI/Widgets/gui_attack_aoe.lua

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,41 @@ local function DrawAoE(tx, ty, tz, aoe, ee, alphaMult, offset, circleMode)
487487
glLineWidth(1)
488488
end
489489

490+
--------------------------------------------------------------------------------
491+
-- Shared blast-radius preview, exposed via WG so other widgets (e.g. the missile
492+
-- silo launch UI) draw their AoE footprint with THIS falloff code instead of
493+
-- duplicating it. Nested rings at (tx,ty,tz) whose alpha decays toward the edge by
494+
-- edgeEffectiveness `ee`. `color` (optional {r,g,b[,a]}) overrides the ring colour;
495+
-- `alphaMult` (optional) scales overall opacity. Line width is derived from the
496+
-- camera distance to the point, so callers need no per-frame setup of their own.
497+
--------------------------------------------------------------------------------
498+
local function DrawAoEPreview(tx, ty, tz, aoe, ee, color, alphaMult)
499+
if not aoe or aoe <= 0 then
500+
return
501+
end
502+
ee = ee or 1
503+
local cx, cy, cz = GetCameraPosition()
504+
local dx, dy, dz = cx - tx, cy - ty, cz - tz
505+
local camDist = sqrt(dx*dx + dy*dy + dz*dz)
506+
if camDist < 1 then
507+
camDist = 1
508+
end
509+
local r = (color and color[1]) or aoeColor[1]
510+
local g = (color and color[2]) or aoeColor[2]
511+
local b = (color and color[3]) or aoeColor[3]
512+
local baseAlpha = ((color and color[4]) or aoeColor[4]) * (alphaMult or 1)
513+
514+
glLineWidth(math.max(0.05, aoeLineWidthMult * aoe / camDist))
515+
for i = 1, numAoECircles do
516+
local proportion = i / (numAoECircles + 1)
517+
local alpha = baseAlpha * (1 - proportion) / (1 - proportion * ee)
518+
glColor(r, g, b, alpha)
519+
DrawCircle(tx, ty, tz, aoe * proportion)
520+
end
521+
glColor(1, 1, 1, 1)
522+
glLineWidth(1)
523+
end
524+
490525
--------------------------------------------------------------------------------
491526
--dgun/noexplode
492527
--------------------------------------------------------------------------------
@@ -1027,10 +1062,12 @@ function widget:Initialize()
10271062
aoeDefInfo[unitDefID], dgunInfo[unitDefID], extraDrawRangeDefInfo[unitDefID] = SetupUnit(unitDef)
10281063
end
10291064
SetupDisplayLists()
1065+
WG.DrawAoEPreview = DrawAoEPreview
10301066
end
10311067

10321068
function widget:Shutdown()
10331069
DeleteDisplayLists()
1070+
WG.DrawAoEPreview = nil
10341071
end
10351072

10361073
function widget:DrawWorld()

LuaUI/Widgets/gui_missile_silo_ux.lua

Lines changed: 6 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -115,26 +115,17 @@ local spTraceScreenRay = Spring.TraceScreenRay
115115
local spGetGroundHeight = Spring.GetGroundHeight
116116
local spGetUnitAllyTeam = Spring.GetUnitAllyTeam
117117
local spGetMyAllyTeamID = Spring.GetMyAllyTeamID
118-
local spGetCameraPosition = Spring.GetCameraPosition
119118

120119
local glColor = gl.Color
121120
local glLineWidth = gl.LineWidth
122121
local glLineStipple = gl.LineStipple
123122
local glDrawGroundCircle = gl.DrawGroundCircle
124123
local glDepthTest = gl.DepthTest
125124

126-
-- AoE-preview look, mirrored from the stock "Attack AoE" widget (gui_attack_aoe.lua):
127-
-- concentric rings whose alpha decays toward the edge by edgeEffectiveness, so the
128-
-- preview conveys how the blast's strength falls off with distance from the epicentre.
129-
local NUM_AOE_CIRCLES = 9
130-
local AOE_LINE_WIDTH_MULT = 64 -- ring width scales with aoe/cameraDistance (screen-space)
131-
132125
local CMD_ATTACK = CMD.ATTACK
133126
local CMD_OPT_RIGHT = CMD.OPT_RIGHT
134127

135128
local floor = math.floor
136-
local sqrt = math.sqrt
137-
local max = math.max
138129
local schar = string.char
139130

140131
-- Chili colour escape for a caption ("\255rgb").
@@ -275,10 +266,8 @@ end
275266
-- Targeting helpers
276267
--------------------------------------------------------------------------------
277268

278-
local function Dist2(ax, az, bx, bz)
279-
local dx, dz = ax - bx, az - bz
280-
return dx * dx + dz * dz
281-
end
269+
-- Squared XZ distance -- shared engine utility (Spring.Utilities.Vector), not hand-rolled.
270+
local Dist2 = Spring.Utilities.Vector.DistSq
282271

283272
-- Fire one ready missile of `t` from the nearest in-range silo to (tx,tz).
284273
local function FireType(t, tx, tz, targetUnitID)
@@ -528,33 +517,6 @@ end
528517
-- World-space range/AoE preview (immediate-mode; Chili can't draw on the map)
529518
--------------------------------------------------------------------------------
530519

531-
-- Draw the blast footprint at (cx,cz) as nested rings whose alpha falls off toward
532-
-- the edge, exactly like the stock force-fire AoE indicator (gui_attack_aoe.lua):
533-
-- alpha(r) = baseAlpha * (1 - p) / (1 - p*ee), p = ring proportion of the radius.
534-
-- ee == 1 (e.g. EMP) => flat alpha (uniform damage to the edge); ee < 1 => brighter
535-
-- centre fading out, conveying reduced damage with distance from the epicentre.
536-
local function DrawAoEFalloff(cx, cz, t)
537-
local aoe = t.aoe
538-
if not aoe or aoe <= 0 then return end
539-
local ee = t.ee or 1
540-
541-
-- Match native screen-space ring thickness: scale by aoe / cameraDistance.
542-
local camx, camy, camz = spGetCameraPosition()
543-
local cy = spGetGroundHeight(cx, cz) or 0
544-
local dx, dy, dz = camx - cx, camy - cy, camz - cz
545-
local camDist = sqrt(dx * dx + dy * dy + dz * dz)
546-
if camDist < 1 then camDist = 1 end
547-
glLineWidth(max(0.5, AOE_LINE_WIDTH_MULT * aoe / camDist))
548-
549-
local r, g, b = t.color[1], t.color[2], t.color[3]
550-
for i = 1, NUM_AOE_CIRCLES do
551-
local p = i / (NUM_AOE_CIRCLES + 1)
552-
local alpha = 0.9 * (1 - p) / (1 - p * ee)
553-
glColor(r, g, b, alpha)
554-
glDrawGroundCircle(cx, 0, cz, aoe * p, 48)
555-
end
556-
end
557-
558520
function widget:DrawWorld()
559521
if not haveSilos or not uiBuilt then return end
560522

@@ -593,11 +555,13 @@ function widget:DrawWorld()
593555
-- AoE preview at the cursor while armed. Zeno is homing but still lays down a slow
594556
-- FIELD, so it has a real AoE too -- show it exactly like force-firing via selection
595557
-- (gui_attack_aoe draws Zeno's gui_aoe at the target). Gated only on aoe > 0.
596-
if activeT == t and t.aoe and t.aoe > 0 then
558+
-- Reuse the stock Attack AoE falloff renderer (exposed via WG) rather than
559+
-- duplicating it; the missile's colour makes the preview read as its type.
560+
if activeT == t and t.aoe and t.aoe > 0 and WG.DrawAoEPreview then
597561
local mx, my = spGetMouseState()
598562
local _, coords = spTraceScreenRay(mx, my, true)
599563
if coords then
600-
DrawAoEFalloff(coords[1], coords[3], t)
564+
WG.DrawAoEPreview(coords[1], coords[2], coords[3], t.aoe, t.ee, t.color)
601565
end
602566
end
603567

0 commit comments

Comments
 (0)