add scripts/stripcaged.rb and documentation

develop
jj 2012-11-22 16:56:22 +01:00
parent 139fd07df3
commit 8429f65176
3 changed files with 240 additions and 0 deletions

@ -21,6 +21,7 @@ DFHack future
- dfusion: misc scripts with a text based menu. - dfusion: misc scripts with a text based menu.
- embark: lets you embark anywhere. - embark: lets you embark anywhere.
- lever: list and pull fort levers from the dfhack console. - lever: list and pull fort levers from the dfhack console.
- stripcaged: mark items inside cages for dumping, eg caged goblin weapons.
New GUI scripts: New GUI scripts:
- gui/guide-path: displays the cached path for minecart Guide orders. - gui/guide-path: displays the cached path for minecart Guide orders.
- gui/workshop-job: displays inputs of a workshop job and allows tweaking them. - gui/workshop-job: displays inputs of a workshop job and allows tweaking them.

@ -144,6 +144,16 @@ system console:
The patches are expected to be encoded in text format used by IDA. The patches are expected to be encoded in text format used by IDA.
Live patching
-------------
As an alternative, you can use the ``binpatch`` dfhack command to apply/remove
patches live in memory during a DF session.
In this case, updating symbols.xml is not necessary.
============================= =============================
Something doesn't work, help! Something doesn't work, help!
============================= =============================
@ -1956,6 +1966,41 @@ embark
====== ======
Allows to embark anywhere. Currently windows only. Allows to embark anywhere. Currently windows only.
lever
=====
Allow manipulation of in-game levers from the dfhack console.
Can list levers, including state and links, with::
lever list
To queue a job so that a dwarf will pull the lever 42, use ``lever pull 42``.
This is the same as 'q'uerying the building and queue a 'P'ull request.
To magically toggle the lever immediately, use::
lever pull 42 --now
stripcaged
==========
For dumping items inside cages. Will mark selected items for dumping, then
a dwarf may come and actually dump it. See also ``autodump``.
With the ``items`` argument, only dumps items laying in the cage, excluding
stuff worn by caged creatures. ``weapons`` will dump worn weapons, ``armor``
will dump everything worn by caged creatures (including armor and clothing),
and ``all`` will dump everything, on a creature or not.
``stripcaged list`` will display on the dfhack console the list of all cages
and their item content.
Without further arguments, all commands work on all cages and animal traps on
the map. With the ``here`` argument, considers only the in-game selected cage
(or the cage under the game cursor). To target only specific cages, you can
alternatively pass cage IDs as arguments::
stripcaged weapons 25321 34228
======================= =======================
In-game interface tools In-game interface tools
======================= =======================

@ -0,0 +1,194 @@
# mark stuff inside of cages for dumping.
def plural(nr, name)
# '1 cage' / '4 cages'
"#{nr} #{name}#{'s' if nr > 1}"
end
def cage_dump_items(list)
count = 0
count_cage = 0
list.each { |cage|
pre_count = count
cage.general_refs.each { |ref|
next unless ref.kind_of?(DFHack::GeneralRefContainsItemst)
next if ref.item_tg.flags.dump
count += 1
ref.item_tg.flags.dump = true
}
count_cage += 1 if pre_count != count
}
puts "Dumped #{plural(count, 'item')} in #{plural(count_cage, 'cage')}"
end
def cage_dump_armor(list)
count = 0
count_cage = 0
list.each { |cage|
pre_count = count
cage.general_refs.each { |ref|
next unless ref.kind_of?(DFHack::GeneralRefContainsUnitst)
ref.unit_tg.inventory.each { |it|
next if it.mode != :Worn
next if it.item.flags.dump
count += 1
it.item.flags.dump = true
}
}
count_cage += 1 if pre_count != count
}
puts "Dumped #{plural(count, 'armor piece')} in #{plural(count_cage, 'cage')}"
end
def cage_dump_weapons(list)
count = 0
count_cage = 0
list.each { |cage|
pre_count = count
cage.general_refs.each { |ref|
next unless ref.kind_of?(DFHack::GeneralRefContainsUnitst)
ref.unit_tg.inventory.each { |it|
next if it.mode != :Weapon
next if it.item.flags.dump
count += 1
it.item.flags.dump = true
}
}
count_cage += 1 if pre_count != count
}
puts "Dumped #{plural(count, 'weapon')} in #{plural(count_cage, 'cage')}"
end
def cage_dump_all(list)
count = 0
count_cage = 0
list.each { |cage|
pre_count = count
cage.general_refs.each { |ref|
case ref
when DFHack::GeneralRefContainsItemst
next if ref.item_tg.flags.dump
count += 1
ref.item_tg.flags.dump = true
when DFHack::GeneralRefContainsUnitst
ref.unit_tg.inventory.each { |it|
next if it.item.flags.dump
count += 1
it.item.flags.dump = true
}
end
}
count_cage += 1 if pre_count != count
}
puts "Dumped #{plural(count, 'item')} in #{plural(count_cage, 'cage')}"
end
def cage_dump_list(list)
count_total = Hash.new(0)
list.each { |cage|
count = Hash.new(0)
cage.general_refs.each { |ref|
case ref
when DFHack::GeneralRefContainsItemst
count[ref.item_tg._rtti_classname] += 1
when DFHack::GeneralRefContainsUnitst
ref.unit_tg.inventory.each { |it|
count[it.item._rtti_classname] += 1
}
# TODO vermin ?
else
puts "unhandled ref #{ref.inspect}" if $DEBUG
end
}
type = case cage
when DFHack::ItemCagest; 'Cage'
when DFHack::ItemAnimaltrapst; 'Animal trap'
else cage._rtti_classname
end
puts "#{type} ##{cage.id}: ", count.sort_by { |k, v| v }.map { |k, v| " #{v} #{k}" }
count.each { |k, v| count_total[k] += v }
}
if list.length > 2
puts '', "Total: ", count_total.sort_by { |k, v| v }.map { |k, v| " #{v} #{k}" }
end
end
# handle magic script arguments
here_only = $script_args.delete 'here'
if here_only
it = df.item_find
list = [it]
if not it.kind_of?(DFHack::ItemCagest) and not it.kind_of?(DFHack::ItemAnimaltrapst)
list = df.world.items.other[:ANY_CAGE_OR_TRAP].find_all { |i| df.at_cursor?(i) }
end
puts 'Please select a cage' if list.empty?
elsif ids = $script_args.find_all { |arg| arg =~ /^\d+$/ } and ids.first
list = []
ids.each { |id|
$script_args.delete id
if not it = df.item_find(id.to_i)
puts "Invalid item id #{id}"
elsif not it.kind_of?(DFHack::ItemCagest) and not it.kind_of?(DFHack::ItemAnimaltrapst)
puts "Item ##{id} is not a cage"
list << it
else
list << it
end
}
puts 'Please use a valid cage id' if list.empty?
else
list = df.world.items.other[:ANY_CAGE_OR_TRAP]
end
# act
case $script_args[0]
when 'items'
cage_dump_items(list) if not list.empty?
when 'armor'
cage_dump_armor(list) if not list.empty?
when 'weapons'
cage_dump_weapons(list) if not list.empty?
when 'all'
cage_dump_all(list) if not list.empty?
when 'list'
cage_dump_list(list) if not list.empty?
else
puts <<EOS
Marks items inside all cages for dumping.
Add 'here' to dump stuff only for selected cage.
Add a cage id to dump stuff for this cage only.
See 'autodump' to actually dump stuff.
Usage:
stripcaged items
dump items directly in cages (eg seeds after training)
stripcaged [armor|weapons] here
dump armor or weapons of caged creatures in selected cage
stripcaged all 28 29
dump every item in cage id 28 and 29, along with every item worn by creatures in there too
stripcaged list
show content of the cages
EOS
end