Skip to content

Commit cf6fec1

Browse files
authored
Update instruments.lua
This update enhances the instruments script by adding support for ordering all known instruments in a single command. Users can now run instruments order all to queue one of each discovered instrument, or optionally specify a quantity and filter by instrument type (e.g. instruments order all 3 handheld). The script accepts flexible argument order and ensures compatibility with UTF-8 input by relying on normalized string comparisons. instruments order all -- Order 1 of every instrument instruments order all 5 -- Order 5 of every instrument instruments order all handheld -- Order 1 of every handheld instrument instruments order all building -- Order 1 of every building instrument instruments order all 3 handheld -- Order 3 of every handheld instrument instruments order all handheld 3 -- Order 3 of every handheld instrument instruments order all building 2 -- Order 2 of every building instrument instruments order all 2 building -- Order 2 of every building instrument
1 parent 10a04ab commit cf6fec1

1 file changed

Lines changed: 94 additions & 7 deletions

File tree

instruments.lua

Lines changed: 94 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,65 @@ function describeReaction(reaction)
4444
return skill .. ": " .. table.concat(reagents, ", ")
4545
end
4646

47+
function collect_unique_instrument_names()
48+
local civ_id = df.global.plotinfo.civ_id
49+
local instruments = {}
50+
local seen = {}
51+
52+
for _, instr in ipairs(df.global.world.raws.itemdefs.instruments) do
53+
if instr.source_enid == civ_id then
54+
local name = instr.name
55+
local normalized = dfhack.toSearchNormalized(name)
56+
if not seen[normalized] then
57+
seen[normalized] = true
58+
local type = instr.flags.PLACED_AS_BUILDING and "building" or "handheld"
59+
table.insert(instruments, { name = name, type = type })
60+
end
61+
end
62+
end
63+
64+
return instruments
65+
end
66+
67+
function place_instrument_work_orders(count, quiet, type_filter)
68+
local instruments = collect_unique_instrument_names()
69+
local counts = { building = 0, handheld = 0, total = 0 }
70+
71+
for _, instrument in ipairs(instruments) do
72+
local name = instrument.name
73+
local type = instrument.type
74+
75+
if type_filter and type ~= type_filter then goto continue end
76+
77+
if not quiet then
78+
print("------------------------------")
79+
print("Placing order for: " .. name .. " (x" .. count .. ") [" .. type .. "]")
80+
print("------------------------------")
81+
end
82+
83+
local success, err = pcall(function()
84+
order_instrument(name, count, quiet)
85+
end)
86+
87+
if not success then
88+
dfhack.printerr("Failed to place order for '" .. name .. "': " .. tostring(err))
89+
else
90+
counts[type] = counts[type] + count
91+
counts.total = counts.total + count
92+
end
93+
94+
::continue::
95+
end
96+
97+
if not quiet then
98+
print("\n==== Instrument Order Summary ====")
99+
print("Total instruments ordered: " .. counts.total)
100+
print(" Handheld: " .. counts.handheld)
101+
print(" Building: " .. counts.building)
102+
print("==================================\n")
103+
end
104+
end
105+
47106
local function print_list()
48107
-- gather instrument piece reactions and index them by the instrument they are part of
49108
local instruments = {}
@@ -75,12 +134,16 @@ local function print_list()
75134
end
76135
end
77136

78-
local function order_instrument(name, amount, quiet)
137+
function order_instrument(name, amount, quiet)
79138
local instrument = nil
139+
local civ_id = df.global.plotinfo.civ_id
140+
local normalized_input = dfhack.toSearchNormalized(name)
80141

81142
for _, instr in ipairs(raws.itemdefs.instruments) do
82-
if dfhack.toSearchNormalized(instr.name) == name and instr.source_enid == civ_id then
143+
if instr.source_enid == civ_id and
144+
dfhack.toSearchNormalized(instr.name) == normalized_input then
83145
instrument = instr
146+
break
84147
end
85148
end
86149

@@ -107,6 +170,9 @@ local function order_instrument(name, amount, quiet)
107170
end
108171

109172
local assembly_reaction = getAssemblyReaction(instrument.id)
173+
if not assembly_reaction then
174+
qerror("No assembly reaction found for instrument '" .. name .. "'")
175+
end
110176

111177
local assembly_order = {
112178
id=-1,
@@ -152,11 +218,32 @@ end
152218
if #positionals == 0 or positionals[1] == "list" then
153219
print_list()
154220
elseif positionals[1] == "order" then
155-
local instrument_name = positionals[2]
156-
if not instrument_name then
157-
qerror("Usage: instruments order <instrument_name> [<amount>]")
221+
local target = positionals[2]
222+
if not target then
223+
qerror("Usage: instruments order <instrument_name|all> [<amount>] [handheld|building]")
224+
end
225+
226+
local amount = 1
227+
local type_filter = nil
228+
229+
for i = 3, #positionals do
230+
local arg = positionals[i]:lower()
231+
if tonumber(arg) then
232+
amount = tonumber(arg)
233+
elseif arg == "handheld" or arg == "building" then
234+
type_filter = arg
235+
else
236+
qerror("Invalid argument: " .. positionals[i])
237+
end
158238
end
159239

160-
local amount = positionals[3] or 1
161-
order_instrument(instrument_name, amount, quiet)
240+
if amount < 1 then
241+
qerror("Amount must be a positive number")
242+
end
243+
244+
if target == "all" then
245+
place_instrument_work_orders(amount, quiet, type_filter)
246+
else
247+
order_instrument(target, amount, quiet)
248+
end
162249
end

0 commit comments

Comments
 (0)