From d1762e3cb8b16cc90760f8e56517292b7291c08f Mon Sep 17 00:00:00 2001 From: jj Date: Sun, 24 Jun 2012 21:41:43 +0200 Subject: [PATCH] ruby: add growcrops script, add doc for methods in README --- plugins/ruby/README | 62 +++++++++++++++++++++++++++++++++++++++++++ plugins/ruby/plant.rb | 47 -------------------------------- plugins/ruby/unit.rb | 2 +- scripts/growcrops.rb | 53 ++++++++++++++++++++++++++++++++++++ 4 files changed, 116 insertions(+), 48 deletions(-) create mode 100644 scripts/growcrops.rb diff --git a/plugins/ruby/README b/plugins/ruby/README index 619d85cf2..bda352e14 100644 --- a/plugins/ruby/README +++ b/plugins/ruby/README @@ -13,6 +13,10 @@ a map block, find an unit or an item, etc. Global dfhack objects are accessible through the 'df' accessor (eg 'df.world'). +DFHack structures are renamed in CamelCase in the ruby namespace. + +For a list of the structures and their methods, grep the ruby-autogen.rb file. + DFHack console -------------- @@ -47,6 +51,64 @@ The help string displayed in dfhack 'ls' command is the first line of the script, if it is a comment (starts with '# '). +Ruby helper functions +--------------------- + +This is an excerpt of the functions defined in dfhack/plugins/ruby/*.rb. Check +the files and the comments for a complete list. + + df.suspend { } +Ensures that the main game thread is paused while exec'ing the content of the +block. Similar to df.suspend() ; ; df.resume(). + + df.same_pos?(obj1, obj2) +Returns true if both objects are at the same game coordinates. +obj1 and 2 should respond to #pos and #x #y #z. + + df.map_block_at(pos) / map_block_at(x, y, z) +Returns the MapBlock for the coordinates or nil. + + df.each_map_block { |b| } + df.each_map_block_z(zlevel) { |b| } +Iterates over every map block (opt. on a single z-level). + + df.center_viewscreen(coords) +Centers the DF view on the given coordinates. Accepts x/y/z arguments, or a +single argument responding to pos/x/y/z, eg an Unit, Item, ... + + df.unit_find(arg) +Returns an Unit. +With no arg, returns the currently selected unit (through the (v) or (k) menus) +With a number, returns the unit with this ID +With something else, returns the first unit at the same game coordinates + + df.unit_workers +Returns a list of worker citizen: units of your race & civilization, adults, +not dead, crazy, ghosts or nobles exempted of work. + + df.unit_entitypositions(unit) +Returns the list of EntityPosition occupied by the unit. +Check the 'code' field for a readable name (MANAGER, CHIEF_MEDICAL_DWARF, ...) + + df.match_rawname(name, list) +String fuzzy matching. Returns the list entry most similar to 'name'. +First searches for an exact match, then for a case-insensitive match, and +finally for a case-insensitive substring. +Returns the element from list if there is only one match, or nil. +Most useful to allow the user to specify a raw-defined name, +eg 'gob' for 'GOBLIN' or 'coal' for 'COAL_BITUMINOUS', hence the name. + + df.building_alloc(type, subtype, customtype) + df.building_position(bld, pos, w, h) + df.building_construct(bld, item_list) +Allocates a new building in DF memory, define its position / dimensions, and +create a dwarf job to construct it from the given list of items. +See buildings.rb/buildbed for an exemple. + + df.each_tree(material) { |t| } +Iterates over every tree of the given material (eg 'maple'). + + DFHack callbacks ---------------- diff --git a/plugins/ruby/plant.rb b/plugins/ruby/plant.rb index 63195e6c2..db0f9a817 100644 --- a/plugins/ruby/plant.rb +++ b/plugins/ruby/plant.rb @@ -115,52 +115,5 @@ module DFHack puts "Grown #{cnt} saplings" end end - - def growcrops(material=nil, count_max=100) - @raws_plant_name ||= {} - @raws_plant_growdur ||= {} - if @raws_plant_name.empty? - df.world.raws.plants.all.each_with_index { |p, idx| - @raws_plant_name[idx] = p.id - @raws_plant_growdur[idx] = p.growdur - } - end - - if !material - cnt = Hash.new(0) - suspend { - world.items.other[:SEEDS].each { |seed| - next if not seed.flags.in_building - next if not seed.itemrefs.find { |ref| ref._rtti_classname == :general_ref_building_holderst } - next if seed.grow_counter >= @raws_plant_growdur[seed.mat_index] - cnt[seed.mat_index] += 1 - } - } - cnt.sort_by { |mat, c| c }.each { |mat, c| - name = world.raws.plants.all[mat].id - puts " #{name} #{c}" - } - else - if material != :any - mat = match_rawname(material, @raws_plant_name.values) - unless wantmat = @raws_plant_name.index(mat) - raise "invalid plant material #{material}" - end - end - - cnt = 0 - suspend { - world.items.other[:SEEDS].each { |seed| - next if wantmat and seed.mat_index != wantmat - next if not seed.flags.in_building - next if not seed.itemrefs.find { |ref| ref._rtti_classname == :general_ref_building_holderst } - next if seed.grow_counter >= @raws_plant_growdur[seed.mat_index] - seed.grow_counter = @raws_plant_growdur[seed.mat_index] - cnt += 1 - } - } - puts "Grown #{cnt} crops" - end - end end end diff --git a/plugins/ruby/unit.rb b/plugins/ruby/unit.rb index 41b7bf8a6..833cb4625 100644 --- a/plugins/ruby/unit.rb +++ b/plugins/ruby/unit.rb @@ -54,7 +54,7 @@ module DFHack def unit_idlers unit_workers.find_all { |u| # current_job includes eat/drink/sleep/pickupequip - !u.job.current_job._getv and + !u.job.current_job and # filter 'attend meeting' u.meetings.length == 0 and # filter soldiers (TODO check schedule) diff --git a/scripts/growcrops.rb b/scripts/growcrops.rb new file mode 100644 index 000000000..855600d7c --- /dev/null +++ b/scripts/growcrops.rb @@ -0,0 +1,53 @@ +# grow crops in farm plots. ex: growcrops helmet_plump 20 + +material = $script_args[0] +count_max = $script_args[1].to_i +count_max = 100 if count_max == 0 + +# cache information from the raws +@raws_plant_name ||= {} +@raws_plant_growdur ||= {} +if @raws_plant_name.empty? + df.world.raws.plants.all.each_with_index { |p, idx| + @raws_plant_name[idx] = p.id + @raws_plant_growdur[idx] = p.growdur + } +end + +if !material or material == 'help' or material == 'list' + # show a list of available crop types + cnt = Hash.new(0) + df.suspend { + df.world.items.other[:SEEDS].each { |seed| + next if not seed.flags.in_building + next if not seed.itemrefs.find { |ref| ref._rtti_classname == :general_ref_building_holderst } + next if seed.grow_counter >= @raws_plant_growdur[seed.mat_index] + cnt[seed.mat_index] += 1 + } + } + + cnt.sort_by { |mat, c| c }.each { |mat, c| + name = df.world.raws.plants.all[mat].id + puts " #{name} #{c}" + } + +else + + mat = df.match_rawname(material, @raws_plant_name.values) + unless wantmat = @raws_plant_name.index(mat) + raise "invalid plant material #{material}" + end + + cnt = 0 + df.suspend { + df.world.items.other[:SEEDS].each { |seed| + next if seed.mat_index != wantmat + next if not seed.flags.in_building + next if not seed.itemrefs.find { |ref| ref._rtti_classname == :general_ref_building_holderst } + next if seed.grow_counter >= @raws_plant_growdur[seed.mat_index] + seed.grow_counter = @raws_plant_growdur[seed.mat_index] + cnt += 1 + } + } + puts "Grown #{cnt} #{mat}" +end