# 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) empty_cages = 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 if count.empty? empty_cages += 1 else puts "#{type} ##{cage.id}: ", count.sort_by { |k, v| v }.map { |k, v| " #{v} #{k}" } end 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}" } puts "with #{plural(empty_cages, 'empty cage')}" 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 if list.empty? puts 'Please select a cage' throw :script_finished end 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 } if list.empty? puts 'Please use a valid cage id' throw :script_finished end else list = df.world.items.other[:ANY_CAGE_OR_TRAP] end # act case $script_args[0] when /^it/i cage_dump_items(list) when /^arm/i cage_dump_armor(list) when /^wea/i cage_dump_weapons(list) when 'all' cage_dump_all(list) when 'list' cage_dump_list(list) else puts <