|
| 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