diff --git a/NEWS b/NEWS index f14bcb1b4..e12608d34 100644 --- a/NEWS +++ b/NEWS @@ -19,6 +19,7 @@ DFHack future - lua: lua interpreter front-end converted to a script from a native command. - dfusion: misc scripts with a text based menu. - embark: lets you embark anywhere. + - lever: list and pull fort levers from the dfhack console. New GUI scripts: - gui/guide-path: displays the cached path for minecart Guide orders. - gui/workshop-job: displays inputs of a workshop job and allows tweaking them. @@ -26,6 +27,14 @@ DFHack future - gui/assign-rack: works together with a binary patch to fix weapon racks. - gui/gm-editor: an universal editor for lots of dfhack things. - gui/companion-order: a adventure mode command interface for your companions. + New binary patches: + - armorstand-capacity + - custom-reagent-size + - deconstruct-heapfall + - deconstruct-teleport + - hospital-overstocking + - training-ammo + - weaponrack-unassign Workflow plugin: - properly considers minecarts assigned to routes busy. - code for deducing job outputs rewritten in lua for flexibility. diff --git a/scripts/lever.rb b/scripts/lever.rb new file mode 100644 index 000000000..2012f7297 --- /dev/null +++ b/scripts/lever.rb @@ -0,0 +1,109 @@ +# control your levers from the dfhack console + +def lever_pull_job(bld) + ref = DFHack::GeneralRefBuildingHolderst.cpp_new + ref.building_id = bld.id + + job = DFHack::Job.cpp_new + job.job_type = :PullLever + job.pos = [bld.centerx, bld.centery, bld.z] + job.general_refs << ref + bld.jobs << job + df.job_link job +end + +def lever_pull_cheat(bld) + bld.state = (bld.state == 0 ? 1 : 0) + + bld.linked_mechanisms.each { |i| + i.general_refs.grep(DFHack::GeneralRefBuildingHolderst).each { |r| + tg = r.building_tg + next if tg.gate_flags.closing or tg.gate_flags.opening + r.building_tg.setTriggerState(tg.gate_flags.closed ? 0 : 1) + } + } + + puts lever_descr(bld) +end + +def lever_descr(bld, idx=nil) + ret = [] + + # lever description + descr = '' + descr << "#{idx}: " if idx + descr << "lever ##{bld.id} @[#{bld.centerx}, #{bld.centery}, #{bld.z}] #{bld.state == 0 ? '\\' : '/'}" + + bld.linked_mechanisms.map { |i| + i.general_refs.grep(DFHack::GeneralRefBuildingHolderst) + }.flatten.each { |r| + # linked building description + tg = r.building_tg + state = tg.gate_flags.closed ? 'closed' : 'opened' + state << ', closing' if tg.gate_flags.closing + state << ', opening' if tg.gate_flags.opening + + ret << (descr + " linked to #{tg._rtti_classname} ##{tg.id} @[#{tg.centerx}, #{tg.centery}, #{tg.z}] #{state}") + + # indent other links + descr = descr.gsub(/./, ' ') + } + + ret << descr if ret.empty? + + ret +end + +def lever_list + @lever_list = [] + df.world.buildings.other[:TRAP].find_all { |bld| + bld.trap_type == :Lever + }.sort_by { |bld| bld.id }.each { |bld| + puts lever_descr(bld, @lever_list.length) + @lever_list << bld.id + } +end + +case $script_args[0] +when 'pull' + cheat = $script_args.delete('--cheat') || $script_args.delete('--now') + + id = $script_args[1].to_i + id = @lever_list[id] || id + bld = df.building_find(id) + raise 'invalid lever id' if not bld + + if cheat + lever_pull_cheat(bld) + else + lever_pull_job(bld) + end + +when 'list' + lever_list + +when /^\d+$/ + id = $script_args[0].to_i + id = @lever_list[id] || id + bld = df.building_find(id) + raise 'invalid lever id' if not bld + + puts lever_descr(bld) + +else + puts <