Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
af51d1e
feat(camera): cycle camera on selected units (#7339)
Zaffer Aug 26, 2026
1a3bc21
types/luassert: assertions take a message, and assert is callable (#8…
keithharvey Aug 26, 2026
865d0a4
Warn when alt-click will cancel a factory's current build (#8889)
sparr Aug 26, 2026
c6c02fd
Set Target: match target tracking of builtin commands (#8777)
efrec Aug 26, 2026
18eb901
Fix Goblin backwards shots, twitchy aim and fire interruptions (#8901)
Egzothicki Aug 26, 2026
6448637
Fix loss of unit primitives after trying to draw >64 of them without …
sparr Aug 26, 2026
721399d
Fix Epic Grunt aiming and firing instantly in any direction (#8784)
Egzothicki Aug 26, 2026
6c847b2
Fix Grunt and Pawn sometimes firing sideways (#8764)
Egzothicki Aug 26, 2026
67d48ea
guard nuke_controller error after lua gracefully degrades tbl access …
efrec Aug 26, 2026
83238e3
Adding support for the Tab key to cycle through chat channels while t…
lawnchaiir Aug 26, 2026
99fd0d5
Annotate the GG APIs (#8853)
sparr Aug 26, 2026
b00b169
radar ranges preview: also display all allied radar coverage (#8927)
Ruwetuin Aug 26, 2026
b2970ae
Move chat autocomplete from Tab to the right arrow (#8926)
burnhamrobertp Aug 26, 2026
fc4519c
Sensor radar ranges preview lowered cubes per cell to prevent moire e…
Ruwetuin Aug 26, 2026
4f1b65d
legmex description (#8928)
Mitvit Aug 26, 2026
e77b0ed
sensor radar ranges preview: added background color and outline + def…
Ruwetuin Aug 26, 2026
39d04f8
Update Lua libary submodule
github-actions[bot] Aug 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion language/en/units.json
Original file line number Diff line number Diff line change
Expand Up @@ -1723,7 +1723,7 @@
"leglts": "Light Air Transport",
"leglupara": "Bomb-Resistant Medium-Range Anti-Air Flak Battery",
"legmed": "Heavy Long-Range Salvo Rocket Tank",
"legmex": "Extracts Slightly Reduced Metal and Produces 7 Energy",
"legmex": "Extracts Metal from Metalspots",
"legmext15": "Extracts Extra Metal at a High Energy Cost",
"legmg": "Heavy Land/Air Gatling Gun Turret",
"legmh": "Hovercraft Rocket Launcher",
Expand Down
10 changes: 10 additions & 0 deletions luarules/gadgets/api_build_blocking.lua
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,11 @@ if gadgetHandler:IsSyncedCode() then
gadgetHandler:RemoveChatAction("buildunblock")
end

---Marks a unit definition as unbuildable by a team for the given reason.
---Reasons stack: the unit stays blocked until every reason is removed.
---@param unitDefID UnitDefID
---@param teamID TeamID
---@param reasonKey string Identifier for why the unit is blocked, e.g. "terrain_water".
function GG.BuildBlocking.AddBlockedUnit(unitDefID, teamID, reasonKey)
local blockedUnitDefs = teamBlockedUnitDefs[teamID]
if not blockedUnitDefs then
Expand All @@ -308,6 +313,11 @@ if gadgetHandler:IsSyncedCode() then
notifyUnitBlocked(unitDefID, teamID, unitReasons)
end

---Removes one block reason from a unit definition for a team.
---@param unitDefID UnitDefID
---@param teamID TeamID
---@param reasonKey string Identifier previously passed to `AddBlockedUnit`.
---@return boolean removed `true` if that reason was set and has been cleared.
function GG.BuildBlocking.RemoveBlockedUnit(unitDefID, teamID, reasonKey)
local blockedUnitDefs = teamBlockedUnitDefs[teamID]
if not blockedUnitDefs then
Expand Down
4 changes: 4 additions & 0 deletions luarules/gadgets/api_pbr_enabler.lua
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,14 @@ if not gadgetHandler:IsSyncedCode() then --unsynced gadget

local ENVLUT_SAMPLES -- number of cubemap samples

---Returns the name of the generated BRDF lookup texture.
---@return string? texName `nil` if the lookup table failed to generate.
local function GetBrdfTexture()
return brdfLut:GetTexture()
end

---Returns the name of the generated IBL environment lookup texture.
---@return string? texName `nil` if the lookup table failed to generate.
local function GetEnvTexture()
return envLut:GetTexture()
end
Expand Down
20 changes: 19 additions & 1 deletion luarules/gadgets/cus_gl4.lua
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,10 @@ local objectDefToUniformBin = {} -- maps unitDefID/featuredefID to a uniform bin
-- objectDefs are negative for features
-- objectIDs are negative for features too

---Maps an object definition to the uniform bin its draw call belongs to.
---@param objectDefID (UnitDefID|-FeatureDefID)? Positive for unitDefIDs, negative for featureDefIDs.
---@param reason string? Label used in debug output when no bin is found.
---@return string uniformBinID Falls back to `'otherunit'` for unmapped definitions.
local function GetUniformBinID(objectDefID, reason)
if objectDefID and objectDefToUniformBin[objectDefID] then
return objectDefToUniformBin[objectDefID]
Expand Down Expand Up @@ -478,7 +482,9 @@ local unitDrawBins = nil -- this also controls whether cusgl4 is on at all!

local objectIDtoDefID = {}

local shaders = {} -- double nested table of {drawflag : {"units":shaderID}}
---Compiled shaders, keyed by draw flag and then by material name.
---@type table<integer, table<string, LuaShader>>
local shaders = {}

local modelsVertexVBO = nil
local modelsIndexVBO = nil
Expand Down Expand Up @@ -550,6 +556,10 @@ end
local featuresDefsWithAlpha = {}
local unitDefsUseSkinning = {}

---Returns the compiled shader used to draw an object in a given draw pass.
---@param drawPass integer Draw flag of the current pass.
---@param objectDefID (UnitDefID|-FeatureDefID)? Positive for unitDefIDs, negative for featureDefIDs.
---@return LuaShader|false shader `false` when `objectDefID` is `nil`.
local function GetShader(drawPass, objectDefID)
if objectDefID == nil then
return false
Expand All @@ -569,6 +579,10 @@ local function GetShader(drawPass, objectDefID)
end
end

---Returns the name of the shader used to draw an object in a given draw pass.
---@param drawPass integer Draw flag of the current pass.
---@param objectDefID (UnitDefID|-FeatureDefID)? Positive for unitDefIDs, negative for featureDefIDs.
---@return "unit"|"unitskinning"|"tree"|"feature"|false shaderName `false` when `objectDefID` is `nil`.
local function GetShaderName(drawPass, objectDefID)
-- this function does 2 table lookups, could get away with just one.
if objectDefID == nil then
Expand Down Expand Up @@ -603,6 +617,10 @@ local function SetFixedStatePost(drawPass, shaderID)
end
end

---Uploads the draw pass, clip plane, and uniform bin values to the active shader.
---@param drawPass integer Draw flag of the current pass.
---@param shaderID integer GL program id of the currently bound shader.
---@param uniformBinID string Key into `uniformBins`, as returned by `GetUniformBinID`.
local function SetShaderUniforms(drawPass, shaderID, uniformBinID)
-- Cache uniform locations per-shader to avoid repeated gl.GetUniformLocation calls every frame
local locCache = uniformLocCache[shaderID]
Expand Down
2 changes: 2 additions & 0 deletions luarules/gadgets/game_apm_broadcast.lua
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ if gadgetHandler:IsSyncedCode() then
end
end

---Excludes the unit's next order from the team's APM count for one game frame.
---@param unitID UnitID
local function addSkipOrder(unitID)
ignoreUnits[unitID] = gameFrame + 1
end
Expand Down
3 changes: 3 additions & 0 deletions luarules/gadgets/game_quick_start.lua
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ local buildsInProgress = {}

GG.quick_start = {}

---Moves tracked state from one commander unit to another.
---@param oldUnitID UnitID?
---@param newUnitID UnitID?
function GG.quick_start.transferCommanderData(oldUnitID, newUnitID)
if oldUnitID and newUnitID and spValidUnitID(oldUnitID) and spValidUnitID(newUnitID) then
buildsInProgress[newUnitID] = buildsInProgress[oldUnitID]
Expand Down
17 changes: 17 additions & 0 deletions luarules/gadgets/game_startbox_config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ function gadget:Initialize()
GG.startBoxConfig = startBoxConfig
GG.startBoxConfigSource = configSource

---Tests a map position against an allyteam's polygonal start box.
---@param x number
---@param z number
---@param allyTeamID AllyTeamID
---@return boolean? inside `nil` when no polygon config exists; the caller should
---fall back to the engine's axis-aligned start box.
GG.IsInsideStartbox = function(x, z, allyTeamID)
if not isExplicitConfig then
return nil -- caller should fall back to engine AABB
Expand All @@ -64,6 +70,13 @@ function gadget:Initialize()
return PolygonLib.PointInStartbox(x, z, entry)
end

---Returns the axis-aligned bounding box of an allyteam's start box polygons.
---@param allyTeamID AllyTeamID
---@return number? xmin `nil` when no polygon config exists; the caller should
---fall back to the engine's axis-aligned start box.
---@return number? zmin
---@return number? xmax
---@return number? zmax
GG.GetStartboxBounds = function(allyTeamID)
if not isExplicitConfig then
return nil -- caller should fall back to engine AABB
Expand All @@ -77,6 +90,10 @@ function gadget:Initialize()
return PolygonLib.GetStartboxBounds(entry)
end

---Returns the raw start box polygons configured for an allyteam.
---@param allyTeamID AllyTeamID
---@return Position2D[][]? boxes Array of polygons, each an array of `{x, z}` vertex
---pairs. `nil` when no polygon config exists.
GG.GetStartboxPolygons = function(allyTeamID)
if not isExplicitConfig then
return nil
Expand Down
12 changes: 12 additions & 0 deletions luarules/gadgets/game_team_death_effect.lua
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ local function getSqrDistance(x1, z1, x2, z2)
return (dx * dx) + (dz * dz)
end

---Neutralizes a team's units and queues them to explode
---@param teamID TeamID
---@param originX number? Wave epicentre; when omitted the death frames are randomized.
---@param originZ number? Wave epicentre; when omitted the death frames are randomized.
---@param attackerUnitID UnitID? Credited as the killer of the destroyed units.
---@param periodMult number? Scales how long the wave takes. Defaults to `1`.
local function wipeoutTeam(teamID, originX, originZ, attackerUnitID, periodMult) -- only teamID is required
wipedoutTeams[teamID] = Spring.GetGameFrame()
periodMult = periodMult or 1
Expand Down Expand Up @@ -101,6 +107,12 @@ local function wipeoutTeam(teamID, originX, originZ, attackerUnitID, periodMult)
GG.maxDeathFrame = GG.maxDeathFrame and math.max(GG.maxDeathFrame, maxDeathFrame) or maxDeathFrame -- storing frame of total unit wipeout
end

---Wipes out every team in an allyteam, shortening the wave when few units remain.
---@param allyTeamID AllyTeamID
---@param attackerUnitID UnitID? Credited as the killer of the destroyed units.
---@param originX number? Wave epicentre; when omitted the death frames are randomized.
---@param originZ number? Wave epicentre; when omitted the death frames are randomized.
---@param periodMult number? Scales how long the wave takes. Defaults to `1`.
local function wipeoutAllyTeam(allyTeamID, attackerUnitID, originX, originZ, periodMult) -- only allyTeamID is required
-- xmas gadget uses this (to prevent creating xmasballs)
if not _G.destroyingTeam then
Expand Down
Loading
Loading