Skip to content

Commit 4f6626a

Browse files
committed
Rewrite lever.rb in Lua
1 parent fed70e3 commit 4f6626a

3 files changed

Lines changed: 241 additions & 171 deletions

File tree

docs/lever.rst

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,26 @@ Usage
99
-----
1010

1111
``lever list``
12-
Print out a list of your fort's levers, including their name, activation
12+
Print out a list of your fort's levers, including their ID, name, activation
1313
state, and what they are linked to (if anything).
14-
``lever pull <id> [<options>]``
14+
``lever pull --id <id> [<options>]``
1515
Queue a job so a dwarf will pull the specified lever. This is the same as
1616
:kbd:`q` querying the building and queueing a :kbd:`P` pull job.
17-
18-
If your levers aren't named, you can find out a lever's ID with the
19-
`bprobe <probe>` command.
17+
``lever show --id <id>``
18+
Center the display on the specified lever and print information about it.
2019

2120
Examples
2221
--------
2322

24-
``lever pull 42 --priority``
23+
``lever pull --id 42 --priority``
2524
Queue a job to pull lever 42 at high priority.
26-
``lever pull 42 --now``
25+
``lever pull --id 42 --cheat``
2726
Skip the job and pull the lever with the hand of Armok!
2827

2928
Options
3029
-------
3130

3231
``--priority``
3332
Queue a job at high priority.
34-
``--now``
33+
``--cheat``
3534
Magically toggle the lever immediately.

lever.lua

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
local help = [====[
2+
3+
lever
4+
=====
5+
Allow manipulation of in-game levers from the dfhack console.
6+
7+
Usage::
8+
9+
lever list|pull|show [-i|--id <id>] [--priority|--cheat]
10+
11+
To list availble levers, use::
12+
13+
lever list
14+
15+
To make a pull order for lever ID 123 with high priority, use::
16+
17+
lever pull --id 123 --priority
18+
19+
To magically toggle the lever immediately, use ``--cheat``::
20+
21+
lever pull --id 123 --cheat
22+
23+
To show a lever and on the screen and provide information about it, use::
24+
25+
lever show --id 123
26+
27+
]====]
28+
29+
world = df.global.world
30+
local argparse = require('argparse')
31+
local utils = require('utils')
32+
33+
function leverPullJob(lever, priority)
34+
local ref = df.general_ref_building_holderst:new()
35+
ref.building_id = lever.id
36+
37+
local job = df.job:new()
38+
job.job_type = df.job_type.PullLever
39+
job.pos = {
40+
x = lever.centerx,
41+
y = lever.centery,
42+
z = z
43+
}
44+
job.flags.do_now = priority
45+
job.general_refs:insert("#", ref)
46+
lever.jobs:insert("#", job)
47+
48+
dfhack.job.linkIntoWorld(job, true)
49+
dfhack.job.checkBuildingsNow()
50+
51+
print(leverDescribe(lever))
52+
end
53+
54+
function leverPullCheat(lever)
55+
for _, m in ipairs(lever.linked_mechanisms) do
56+
local tref = dfhack.items.getGeneralRef(m, df.general_ref_type.BUILDING_HOLDER)
57+
if tref then
58+
tref:getBuilding():setTriggerState(lever.state)
59+
end
60+
end
61+
62+
if lever.state == 1 then
63+
lever.state = 0
64+
else
65+
lever.state = 1
66+
end
67+
68+
print(leverDescribe(lever))
69+
end
70+
71+
function leverDescribe(lever)
72+
local lever_name = ''
73+
if string.len(lever.name) > 0 then
74+
lever_name = ' ' .. lever.name
75+
end
76+
77+
if lever.state == 0 then
78+
state_text = '\\'
79+
else
80+
state_text = '/'
81+
end
82+
83+
local t = ('lever #%d%s @[%d, %d, %d] %s'):format(lever.id, lever_name, lever.centerx, lever.centery, lever.z,
84+
state_text)
85+
86+
for _, j in ipairs(lever.jobs) do
87+
if j.job_type == df.job_type.PullLever then
88+
local r = ''
89+
if j.flags.do_now then
90+
r = r .. ', now'
91+
end
92+
if j.flags['repeat'] then
93+
r = r .. ', repeat'
94+
end
95+
if j.flags.suspend then
96+
r = r .. ', suspended'
97+
end
98+
99+
t = t .. (' (pull order%s)'):format(r)
100+
end
101+
end
102+
103+
for _, m in ipairs(lever.linked_mechanisms) do
104+
local tref = dfhack.items.getGeneralRef(m, df.general_ref_type.BUILDING_HOLDER)
105+
if tref then
106+
tg = tref:getBuilding()
107+
if pcall(function()
108+
return tg.gate_flags
109+
end) then
110+
if tg.gate_flags.closed then
111+
state = "closed"
112+
else
113+
state = "opened"
114+
end
115+
116+
if tg.gate_flags.closing then
117+
state = state .. (', closing (%d)'):format(tg.timer)
118+
end
119+
if tg.gate_flags.opening then
120+
state = state .. (', opening (%d)'):format(tg.timer)
121+
end
122+
123+
end
124+
125+
t = t ..
126+
("\n linked to %s %s #%d @[%d, %d, %d]"):format(state, df.building_type[tg:getType()], tg.id,
127+
tg.centerx, tg.centery, tg.z)
128+
end
129+
end
130+
131+
return t
132+
end
133+
134+
function ListLevers()
135+
for k, v in ipairs(world.buildings.other.TRAP) do -- hint:df.building_trapst
136+
if v.trap_type == df.trap_type.Lever then
137+
print(('#%d: %s'):format(k, leverDescribe(v)))
138+
end
139+
end
140+
end
141+
142+
function getLever(opts)
143+
local lever = utils.binsearch(world.buildings.all, opts.pullId, 'id')
144+
145+
if lever then
146+
if pcall(function()
147+
return lever.trap_type
148+
end) then
149+
if not lever.trap_type == df.trap_type.Lever then
150+
return nil
151+
end
152+
end
153+
return lever
154+
else
155+
return nil
156+
end
157+
end
158+
159+
function ShowLever(opts)
160+
local lever = getLever(opts)
161+
if lever == nil then
162+
print("Can't find lever with ID")
163+
return
164+
end
165+
166+
dfhack.gui.revealInDwarfmodeMap(lever.centerx, lever.centery, lever.z, true)
167+
print(leverDescribe(lever))
168+
end
169+
170+
function PullLever(opts)
171+
local lever = getLever(opts)
172+
if lever == nil then
173+
print("Can't find lever with ID")
174+
return
175+
end
176+
177+
if opts.cheat then
178+
leverPullNow(lever)
179+
else
180+
leverPullJob(lever, opts.priority)
181+
end
182+
end
183+
184+
local function parse_commandline(args)
185+
local opts = {}
186+
local commands = argparse.processArgsGetopt(args, {{
187+
'h',
188+
'help',
189+
handler = function()
190+
opts.help = true
191+
end
192+
}, {
193+
'i',
194+
'id',
195+
hasArg = true,
196+
handler = function(a)
197+
opts.pullId = tonumber(a)
198+
end
199+
}, {
200+
nil,
201+
'priority',
202+
handler = function()
203+
opts.priority = true
204+
end
205+
}, {
206+
nil,
207+
'cheat',
208+
handler = function()
209+
opts.cheat = true
210+
end
211+
}})
212+
213+
if commands[1] == "list" then
214+
opts.list = true
215+
elseif commands[1] == "show" then
216+
opts.show = true
217+
elseif commands[1] == "pull" then
218+
opts.pull = true
219+
elseif commands[1] == "help" then
220+
opts.help = true
221+
end
222+
return opts
223+
end
224+
225+
local opts = parse_commandline({...})
226+
if opts.help then
227+
print(help)
228+
elseif opts.list then
229+
ListLevers()
230+
elseif opts.show then
231+
ShowLever(opts)
232+
elseif opts.pull then
233+
PullLever(opts)
234+
end

0 commit comments

Comments
 (0)