Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
8e678d3
feat: Refactor /take command to Lua gadget with comprehensive fixes
keithharvey Jul 1, 2025
aab1004
add enum for TransferUnit
keithharvey Jul 2, 2025
c90f227
simplify AllowUnitTransfer
keithharvey Jul 3, 2025
6297948
cmd_take was missing a lot of security
keithharvey Jul 3, 2025
fe36d01
gotta catchem all
keithharvey Jul 3, 2025
70fa0e2
fix AllowUnitBuildStep team param
keithharvey Jul 4, 2025
da596c4
wip team_transfer_bar
Aug 7, 2025
03c8612
mas
keithharvey Aug 7, 2025
671a2e4
minor watchthefort feedback, start with gadgethandler stuff
keithharvey Aug 8, 2025
f93b2e0
wip: module
Aug 8, 2025
e33b682
wip: more module work, resources
Aug 8, 2025
59a9382
fix overflow
Aug 9, 2025
5c1f05b
wip: registration bs
Aug 11, 2025
33c3cad
wip minor cleanup
Aug 11, 2025
3b827c8
feat: Implement unit sharing modes and fix take issues
keithharvey Aug 11, 2025
8ef2f73
wip api
keithharvey Aug 11, 2025
f774d93
cleanup: remove auto-generated atlas files, sound lengths, and gadget…
devin-ai-integration[bot] Aug 12, 2025
942f0e1
Merge pull request #1 from keithharvey/move_take_cleaned
keithharvey Aug 13, 2025
4f8a641
feat: implement SYNCED_ACTION_FALLBACK for reclaim income taxation
devin-ai-integration[bot] Aug 13, 2025
7e250d8
refactor: remove AllowCommand functions from tax and construction mods
devin-ai-integration[bot] Aug 13, 2025
133f6db
update: sync recoil-lua-library submodule
devin-ai-integration[bot] Aug 13, 2025
0bfca3b
refactor: reorganize command restrictions according to gist functiona…
devin-ai-integration[bot] Aug 13, 2025
aba326d
refactor: migrate team transfer modules to use encapsulated mod optio…
devin-ai-integration[bot] Aug 13, 2025
812e771
feat: rename and expand mod_mex_upgrades to mod_structure_upgrades
devin-ai-integration[bot] Aug 13, 2025
b21fb83
feat: integrate blueprint substitution system for structure detection
devin-ai-integration[bot] Aug 13, 2025
210ecae
fix: replace WG table access with proper cross-environment communication
devin-ai-integration[bot] Aug 13, 2025
4fb964b
fix: simplify blueprint integration with direct VFS.Include access
devin-ai-integration[bot] Aug 13, 2025
9044a40
cleanup: remove deleted blueprint_category_bridge.lua file
devin-ai-integration[bot] Aug 13, 2025
d32b6f1
optimize: load blueprint logic once at initialization
devin-ai-integration[bot] Aug 13, 2025
b01c5fa
fix: use blueprint category enums and restrict to T1 upgrades only
devin-ai-integration[bot] Aug 13, 2025
bb98919
refactor: simplify blueprint category detection with getCategory helper
devin-ai-integration[bot] Aug 13, 2025
b44eb16
refactor: consolidate category detection into definitions.lua
devin-ai-integration[bot] Aug 13, 2025
a976b26
cleanup: remove categories.find() fallback detection logic
devin-ai-integration[bot] Aug 13, 2025
71c0ad6
Merge pull request #2 from keithharvey/taxable_income
keithharvey Aug 13, 2025
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
Binary file added bitmaps/.DS_Store
Binary file not shown.
3 changes: 2 additions & 1 deletion luarules/Utilities/damgam_lib/nearby_capture.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
-- To be done
local GaiaTeamID = Spring.GetGaiaTeamID()
local GaiaAllyTeamID = select(6, Spring.GetTeamInfo(GaiaTeamID))
local GG = gadgetHandler.GG

local function NearbyCapture(unitID, difficulty, range)
local difficulty = difficulty
Expand Down Expand Up @@ -41,7 +42,7 @@ local function NearbyCapture(unitID, difficulty, range)
local nearestAttacker = Spring.GetUnitNearestEnemy(unitID, range*2, false)
if nearestAttacker then
local attackerTeamID = Spring.GetUnitTeam(nearestAttacker)
Spring.TransferUnit(unitID, attackerTeamID, false)
GG.TeamTransfer.TransferUnit(unitID, attackerTeamID, GG.TeamTransfer.REASON.CAPTURED)
Spring.SetUnitHealth(unitID, {capture = 0.75})
SendToUnsynced("unitCaptureFrame", unitID, 0.75)
GG.addUnitToCaptureDecay(unitID)
Expand Down
79 changes: 56 additions & 23 deletions luarules/gadgets.lua
Original file line number Diff line number Diff line change
Expand Up @@ -332,8 +332,18 @@ function gadgetHandler:Initialize()
local syncedHandler = Script.GetSynced()

local unsortedGadgets = {}
-- get the gadget names
-- get the gadget names - both direct .lua files and gadget.lua in subdirectories
local gadgetFiles = VFS.DirList(GADGETS_DIR, "*.lua", VFSMODE)

-- discover gadget packages: look for subdirs with gadget.lua
local subdirs = VFS.SubDirs(GADGETS_DIR, "*", VFSMODE)
for _, subdir in ipairs(subdirs) do
local packageGadgetFile = subdir .. "gadget.lua"
if VFS.FileExists(packageGadgetFile, VFSMODE) then
table.insert(gadgetFiles, packageGadgetFile)
end
end

-- table.sort(gadgetFiles)

-- for k,gf in ipairs(gadgetFiles) do
Expand Down Expand Up @@ -439,6 +449,25 @@ function gadgetHandler:LoadGadget(filename, overridevfsmode)
return nil
end

-- Centralized registration: prefer gadget manager; fall back to GetSyncedActions via manager
if gadget.CreateGadgetManager then
gadget._gadgetManager = gadget:CreateGadgetManager():Register()
elseif gadget.GetSyncedActions then
local GadgetManager = VFS.Include('luarules/modules/gadget_manager.lua', nil, VFSMODE)
local builder = GadgetManager.CreateGadget(gadget.ghInfo.name)
local handlers = gadget:GetSyncedActions()
for name, func in pairs(handlers) do
if not func then
error("Missing handler for SyncedActionFallback '" .. name .. "' in gadget " .. gadget.ghInfo.name)
end
if type(func) ~= "function" then
error("Handler for SyncedActionFallback '" .. name .. "' must be a function, got " .. type(func))
end
builder:WithSyncedAction(name, func)
end
gadget._gadgetManager = builder:Register()
end

local knownInfo = self.knownGadgets[name]
if knownInfo then
if knownInfo.active then
Expand Down Expand Up @@ -787,10 +816,22 @@ function gadgetHandler:RemoveGadgetRaw(gadget)

local name = gadget.ghInfo.name
self.knownGadgets[name].active = false

-- Auto-unregister gadget managers (preferred path)
if gadget._gadgetManager then
gadget._gadgetManager:Unregister()
elseif gadget.GetSyncedActions then
-- Legacy/manual path for old-style gadgets not using the manager
for name, _ in pairs(gadget:GetSyncedActions()) do
Script.RemoveSyncedActionFallback(name)
end
end

if gadget.Shutdown then
gadget:Shutdown()
end

-- Essential gadget system cleanup - DO NOT REMOVE
ArrayRemove(self.gadgets, gadget)
Comment thread
keithharvey marked this conversation as resolved.
self:RemoveGadgetGlobals(gadget)
actionHandler.RemoveGadgetActions(gadget)
Expand Down Expand Up @@ -1542,18 +1583,16 @@ function gadgetHandler:AllowUnitTransportUnload(transporterID, transporterUnitDe
return true
end

function gadgetHandler:AllowUnitTransfer(unitID, unitDefID,
oldTeam, newTeam, capture)
function gadgetHandler:AllowUnitTransfer(unitID, unitDefID, oldTeam, newTeam, reason)
for _, g in ipairs(self.AllowUnitTransferList) do
if not g:AllowUnitTransfer(unitID, unitDefID, oldTeam, newTeam, capture) then
if not g:AllowUnitTransfer(unitID, unitDefID, oldTeam, newTeam, reason) then
return false
end
end
return true
end

function gadgetHandler:AllowUnitBuildStep(builderID, builderTeam,
unitID, unitDefID, part)
function gadgetHandler:AllowUnitBuildStep(builderID, builderTeam, unitID, unitDefID, part)

tracy.ZoneBeginN("G:AllowUnitBuildStep")
for _, g in ipairs(self.AllowUnitBuildStepList) do
Expand Down Expand Up @@ -1594,8 +1633,7 @@ function gadgetHandler:AllowUnitDecloak(unitID, objectID, weaponID)
return true
end

function gadgetHandler:AllowFeatureBuildStep(builderID, builderTeam,
featureID, featureDefID, part)
function gadgetHandler:AllowFeatureBuildStep(builderID, builderTeam, featureID, featureDefID, part)
for _, g in ipairs(self.AllowFeatureBuildStepList) do
if not g:AllowFeatureBuildStep(builderID, builderTeam, featureID, featureDefID, part) then
return false
Expand Down Expand Up @@ -1631,8 +1669,7 @@ function gadgetHandler:AllowResourceTransfer(oldTeamID, newTeamID, res, amount)
return true
end

function gadgetHandler:AllowDirectUnitControl(unitID, unitDefID, unitTeam,
playerID)
function gadgetHandler:AllowDirectUnitControl(unitID, unitDefID, unitTeam, playerID)
for _, g in ipairs(self.AllowDirectUnitControlList) do
if not g:AllowDirectUnitControl(unitID, unitDefID, unitTeam, playerID) then
return false
Expand Down Expand Up @@ -1660,8 +1697,7 @@ function gadgetHandler:MoveCtrlNotify(unitID, unitDefID, unitTeam, data)
return state
end

function gadgetHandler:TerraformComplete(unitID, unitDefID, unitTeam,
buildUnitID, buildUnitDefID, buildUnitTeam)
function gadgetHandler:TerraformComplete(unitID, unitDefID, unitTeam, buildUnitID, buildUnitDefID, buildUnitTeam)
for _, g in ipairs(self.TerraformCompleteList) do
local stop = g:TerraformComplete(unitID, unitDefID, unitTeam, buildUnitID, buildUnitDefID, buildUnitTeam)
if stop then
Expand Down Expand Up @@ -1742,8 +1778,7 @@ function gadgetHandler:UnitFinished(unitID, unitDefID, unitTeam)
return
end

function gadgetHandler:UnitFromFactory(unitID, unitDefID, unitTeam,
factID, factDefID, userOrders)
function gadgetHandler:UnitFromFactory(unitID, unitDefID, unitTeam, factID, factDefID, userOrders)
for _, g in ipairs(self.UnitFromFactoryList) do
g:UnitFromFactory(unitID, unitDefID, unitTeam, factID, factDefID, userOrders)
end
Expand Down Expand Up @@ -1782,8 +1817,7 @@ function gadgetHandler:RenderUnitDestroyed(unitID, unitDefID, unitTeam)
return
end

function gadgetHandler:UnitExperience(unitID, unitDefID, unitTeam,
experience, oldExperience)
function gadgetHandler:UnitExperience(unitID, unitDefID, unitTeam, experience, oldExperience)
for _, g in ipairs(self.UnitExperienceList) do
g:UnitExperience(unitID, unitDefID, unitTeam, experience, oldExperience)
end
Expand Down Expand Up @@ -1846,20 +1880,19 @@ end

function gadgetHandler:UnitTaken(unitID, unitDefID, unitTeam, newTeam)
gadgetHandler:MetaUnitRemoved(unitID, unitDefID, unitTeam)
Comment thread
keithharvey marked this conversation as resolved.

for _, g in ipairs(self.UnitTakenList) do
g:UnitTaken(unitID, unitDefID, unitTeam, newTeam)
end
return
end

function gadgetHandler:UnitGiven(unitID, unitDefID, unitTeam, oldTeam)
gadgetHandler:MetaUnitAdded(unitID, unitDefID, unitTeam)

function gadgetHandler:UnitGiven(unitID, unitDefID, oldTeam, newTeam)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the order of the last two parameters being reversed? This is not semantically correct, it should be newTeam, oldTeam, not oldTeam, newTeam.

gadgetHandler:MetaUnitAdded(unitID, unitDefID, newTeam)
for _, g in ipairs(self.UnitGivenList) do
g:UnitGiven(unitID, unitDefID, unitTeam, oldTeam)
g:UnitGiven(unitID, unitDefID, oldTeam, newTeam)
end
return

end

function gadgetHandler:UnitCommand(unitID, unitDefID, unitTeam, cmdId, cmdParams, cmdOpts, cmdTag, playerID, fromSynced, fromLua)
Expand Down
3 changes: 2 additions & 1 deletion luarules/gadgets/cmd_dev_helpers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ local PACKET_HEADER_LENGTH = string.len(PACKET_HEADER)

if gadgetHandler:IsSyncedCode() then
startPlayers = {}
local GG = gadgetHandler.GG
end

function isAuthorized(playerID)
Expand Down Expand Up @@ -781,7 +782,7 @@ if gadgetHandler:IsSyncedCode() then
Spring.DestroyUnit(unitID, false, true)
elseif action == 'transfer' then
if type(tonumber(params)) == 'number' then
Spring.TransferUnit(unitID, tonumber(params), true)
GG.TeamTransfer.TransferUnit(unitID, tonumber(params), GG.TeamTransfer.REASON.DEV_TRANSFER)
end
elseif action == 'reclaim' then
local teamID = Spring.GetUnitTeam(unitID)
Expand Down
147 changes: 0 additions & 147 deletions luarules/gadgets/cmd_give.lua

This file was deleted.

Loading