Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
200 changes: 200 additions & 0 deletions LuaRules/Gadgets/unit_mobile_factory_helper.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
if not gadgetHandler:IsSyncedCode() then
return
end

function gadget:GetInfo()
return {
name = "Fake Factory Queue",
desc = "Creates fake units to store factory queues for mobile factories",
author = "Shaman",
date = "13 Jan 2024", --2013-09-05
license = "CC-0",
layer = -900,
enabled = true,
}
end

local fakeUnits = {} -- Attach the fake units to the real units. realUnitID -> fakeUnitID
local mobileFactories = {}
local needsCreation = {}
local usingQueueMode = {}
local blockAttackCommands = {}
local needsSupport = {}

local spSetUnitRulesParam = Spring.SetUnitRulesParam
local spCreateUnit = Spring.CreateUnit
local spGetUnitDefID = Spring.GetUnitDefID
local spDestroyUnit = Spring.DestroyUnit
local spGetUnitPosition = Spring.GetUnitPosition
local spUnitAttach = Spring.UnitAttach
local spSetUnitNoDraw = Spring.SetUnitNoDraw
local spSetUnitNoMinimap = Spring.SetUnitNoMinimap
local spSetUnitNoSelect = Spring.SetUnitNoSelect
local spSetUnitBlocking = Spring.SetUnitBlocking
local spGetUnitCommands = Spring.GetUnitCommands
local spInsertUnitCmdDesc = Spring.InsertUnitCmdDesc
local spGiveOrderArrayToUnit = Spring.GiveOrderArrayToUnit
local spGiveOrderToUnit = Spring.GiveOrderToUnit
local spEditUnitCmdDesc = Spring.EditUnitCmdDesc
local spFindUnitCmdDesc = Spring.FindUnitCmdDesc
local spSetUnitCloak = Spring.SetUnitCloak

local CMD_QUEUE_MODE = Spring.Utilities.CMD.QUEUE_MODE
local CMD_AREA_GUARD = Spring.Utilities.CMD.AREA_GUARD
local CMD_JUMP = Spring.Utilities.CMD.JUMP
local CMD_ORBIT = Spring.Utilities.CMD.ORBIT
local CMD_ORBIT_DRAW = Spring.Utilities.CMD.ORBIT_DRAW
local CMD_RAW_MOVE = Spring.Utilities.CMD.RAW_MOVE
local CMD_JUMP = Spring.Utilities.CMD.JUMP
-- command --

local CommandOrder = 123456
local CommandDesc = {
id = CMD_QUEUE_MODE,
type = CMDTYPE.ICON_MODE,
name = 'queuemode',
action = 'queuemode',
tooltip = 'Makes queue mode!',
params = { '0', 'off', 'on'},
}
local StateCount = #CommandDesc.params-1

local allowedCommandsForQueue = {
[CMD.STOP] = true,
[CMD.INSERT] = true,
[CMD.REMOVE] = true,
[CMD.WAITCODE_SQUAD] = true,
[CMD.WAITCODE_GATHER] = true,
[CMD.WAIT] = true,
[CMD.TIMEWAIT] = true,
[CMD.DEATHWAIT] = true,
[CMD.SQUADWAIT] = true,
[CMD.GATHERWAIT] = true,
[CMD.MOVE] = true,
[CMD.PATROL] = true,
[CMD.FIGHT] = true,
[CMD.ATTACK] = true,
[CMD.GUARD] = true,
--[CMD.REPAIR] = true,
--[CMD.RECLAIM] = true, -- Note: Fake factory cannot handle these! These would be "nice to have" though. FIXME for now.
[CMD_AREA_GUARD] = true,
[CMD_ORBIT] = true,
[CMD_ORBIT_DRAW] = true,
[CMD_RAW_MOVE] = true,
[CMD_JUMP] = true,
}


local ALLIEDONLY = {
allied = true,
}

for i = 1, #UnitDefs do
local ud = UnitDefs[i]
if ud.customParams.ismobilefac then
needsSupport[i] = tonumber(ud.customParams.mobilefactoryattachnum) or 1
if ud.customParams.cantreallyattack then
blockAttackCommands[i] = true
end
end
end

local function AddFakeFactory(unitID)
local x, y, z = spGetUnitPosition(unitID)
local unitTeam = Spring.GetUnitTeam(unitID)
local unitDefID = Spring.GetUnitDefID(unitID)
local fakeUnitID = spCreateUnit("factoryfake", x, y, z, 1, unitTeam)
if fakeUnitID then
spUnitAttach(unitID, fakeUnitID, needsSupport[unitDefID])
spSetUnitNoDraw(fakeUnitID, true)
spSetUnitNoMinimap(fakeUnitID, true)
spSetUnitNoSelect(fakeUnitID, true)
spSetUnitCloak(fakeUnitID, 4)
spSetUnitBlocking(fakeUnitID, false, false, false, false, false, false, false)
fakeUnits[unitID] = fakeUnitID
spSetUnitRulesParam(unitID, "queueunit", fakeUnitID, ALLIEDONLY)
needsCreation[unitID] = nil
else
needsCreation[unitID] = true
end
end

local function ToggleCommand(unitID, cmdParams)
local state = cmdParams[1]
local cmdDescID = spFindUnitCmdDesc(unitID, CMD_QUEUE_MODE)
if needsCreation[unitID] then
AddFakeFactory(unitID)
return
end
if (cmdDescID) and not needsCreation[unitID] then
CommandDesc.params[1] = state
spEditUnitCmdDesc(unitID, cmdDescID, { params = CommandDesc.params})
end
if state == 1 then
usingQueueMode[unitID] = true
else
usingQueueMode[unitID] = nil
end
end

function gadget:UnitDestroyed(unitID)
mobileFactories[unitID] = nil
needsCreation[unitID] = nil
if fakeUnits[unitID] then
spDestroyUnit(fakeUnits[unitID], false, true)
end
end

function gadget:UnitFinished(unitID, unitDefID, unitTeam)
local factoryUnit = mobileFactories[unitID]
if factoryUnit then
local rallyUnit = fakeUnits[factoryUnit]
local rallyCommandList = spGetUnitCommands(rallyUnit, 300) -- put a sane limit on this so potatos can work.
if rallyCommandList and #rallyCommandList > 0 then
for i = 1, #rallyCommandList do
local cmd = rallyCommandList[i]
cmd.cmdOpts = cmd.cmdOpts or {}
spGiveOrderToUnit(unitID, cmd.id, cmd.params, cmd.options)
end
end
mobileFactories[unitID] = nil
end
end

function gadget:UnitCreated(unitID, unitDefID, unitTeam, builderID)
if builderID and not UnitDefs[unitDefID].isImmobile then
local builderDef = spGetUnitDefID(builderID)
if needsSupport[builderDef] then
mobileFactories[unitID] = builderID
end
end
if needsSupport[unitDefID] then
AddFakeFactory(unitID)
spInsertUnitCmdDesc(unitID, CommandDesc)
if UnitDefs[unitDefID].customParams.wantsqueuemode then
ToggleCommand(unitID, {1})
end
end
end

function gadget:AllowCommand(unitID, unitDefID, unitTeam, cmdID, cmdParams, cmdOptions, cmdTag, synced)
if not needsSupport[unitDefID] then
return true
end
if cmdID == CMD.ATTACK and blockAttackCommands[unitDefID] and not usingQueueMode[unitID] then
return false
end
if cmdID == CMD_QUEUE_MODE then
ToggleCommand(unitID, cmdParams)
return false
end
if usingQueueMode[unitID] and allowedCommandsForQueue[cmdID] and not (cmdOptions.internal and cmdID == CMD.PATROL) then
if needsCreation[unitID] then
AddFakeFactory(unitID)
end
local fakeUnit = fakeUnits[unitID]
spGiveOrderToUnit(fakeUnit, cmdID, cmdParams, cmdOptions)
return false
end
return true
end
88 changes: 88 additions & 0 deletions LuaUI/Widgets/unit_drawfactoryrally.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
function widget:GetInfo()
return {
name = "Mobile Factory Helper",
desc = "Displays queues of the fake units.",
author = "Shaman",
date = "12 January 2024",
license = "CC-0",
layer = 2500,
enabled = true,
alwaysStart = true,
}
end

local drawCount = 0
local wantDraw = false
local drawThese = {}
local wantedUnits = {}
local watchUnitsForUnselection = {}
local CMD_QUEUE_MODE = 34225

for i = 1, #UnitDefs do
local ud = UnitDefs[i]
if ud.customParams.ismobilefac then
wantedUnits[i] = true
end
end

local spDrawUnitCommands = Spring.DrawUnitCommands
local spGetUnitDefID = Spring.GetUnitDefID
local spGetUnitRulesParam = Spring.GetUnitRulesParam

local watchDefs = {
[UnitDefNames["athena"].id] = true
}

local function CheckForAthenaUnselection(oldselect, newselect)
local notInTab2 = {}
for k, _ in pairs(oldselect) do
if newselect[k] == nil then
Spring.GiveOrderToUnit(k, CMD_QUEUE_MODE, {0}, 0) -- turn off queue mode.
watchUnitsForUnselection[k] = nil
end
end
watchUnitsForUnselection = newselect
end

function widget:UnitDestroyed(unitID)
watchUnitsForUnselection[unitID] = nil
end

function widget:SelectionChanged(selectedUnits)
if not (selectedUnits and selectedUnits[1]) then
CheckForAthenaUnselection(watchUnitsForUnselection, {})
wantDraw = false
return
end
drawCount = 0
local watchUnits = {}
for i = 1, #selectedUnits do
local unitID = selectedUnits[i]
local unitDef = spGetUnitDefID(unitID)
if wantedUnits[unitDef] then
if watchDefs[unitDef] then
watchUnits[unitID] = true
watchUnitsForUnselection[unitID] = true
end
local queueUnit = spGetUnitRulesParam(unitID, "queueunit")
if queueUnit then
drawCount = drawCount + 1
drawThese[drawCount] = spGetUnitRulesParam(unitID, "queueunit")
end
end
end
CheckForAthenaUnselection(watchUnitsForUnselection, watchUnits)
wantDraw = drawCount > 0
end

local function DoDraw()
if wantDraw and drawCount > 0 then
for i = 1, drawCount do
spDrawUnitCommands(drawThese[i])
end
end
end

function widget:DrawWorld()
DoDraw()
end
83 changes: 83 additions & 0 deletions units/factoryfake.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
return {
factoryfake = {
name = "Fake Factory",
description = "YOU SHOULD NOT SEE THIS OR THE GAME IS BROKEN.",
activateWhenBuilt = false,
builder = true,
buildDistance = 1,
buildPic = "levelterra.png",
buildOptions = {
"fakeunit",
},

canMove = true,
canPatrol = true,
canAttack = true,
category = "STUPIDTARGET",
customparams = {
completely_hidden = 1,
buggeroff_radius = 0, -- completely disable this because fake factories dont build anything
factorytab = 1,
nobuildpower = 1,
dontkill = 1,
massoverride = 0.01,
},
footprintX = 1,
footprintZ = 1,
health = 100000,
iconType = "none",
levelGround = false,
mass = 0.01,
maxSlope = 255,
maxWaterDepth = 99999,
metalCost = 0.01,
noAutoFire = false,
noChaseCategory = "FIXEDWING LAND SINK TURRET SHIP SATELLITE SWIM GUNSHIP FLOAT SUB HOVER",
objectName = "debris1x1b.s3o",
onoffable = false,
script = "nullfactoryscript.lua",
showNanoSpray = false,
selfDestructCountdown = 0,
sightDistance = 0.1,
useBuildingGroundDecal = false,
workerTime = 0.1,
yardMap = "c",
weapons = {
{
def = "AI_HAX",
onlyTargetCategory = "FIXEDWING LAND SINK TURRET SUB SHIP SWIM FLOAT GUNSHIP HOVER",
},
},
weaponDefs = {
AI_HAX = {
name = "Hackzy hax, you now can attack!",
accuracy = 0,
areaOfEffect = 32,
avoidFriendly = false,
avoidFeature = false,
avoidGround = true,
craterBoost = 0,
craterMult = 0,
customParams = {
restrict_in_widgets = 1,
bogus = 1,
},
damage = {
default = 0.0,
},
fireTolerance = 1820, -- 10 degrees
impulseBoost = 0,
impulseFactor = 0.2,
impactOnly = true,
interceptedByShieldType = 1,
noSelfDamage = true,
myGravity = 0.03,
range = 1,
reloadtime = 0.2,
turret = true,
weaponType = "Cannon",
weaponVelocity = 1600,
},
},
}
}