Petr Mrázek 2012-08-24 22:30:39 +02:00
commit 21904fd607
6 changed files with 94 additions and 34 deletions

@ -213,8 +213,7 @@ Find the raws name of the plant under cursor
p df.world.raws.plants.all[plant.mat_index].id p df.world.raws.plants.all[plant.mat_index].id
Dig a channel under the cursor Dig a channel under the cursor
df.map_designation_at(df.cursor).dig = :Channel df.map_tile_at(df.cursor).dig(:Channel)
df.map_block_at(df.cursor).flags.designated = true
Spawn 2/7 magma on the tile of the dwarf nicknamed 'hotfeet' Spawn 2/7 magma on the tile of the dwarf nicknamed 'hotfeet'
hot = df.unit_citizens.find { |u| u.name.nickname == 'hotfeet' } hot = df.unit_citizens.find { |u| u.name.nickname == 'hotfeet' }

@ -279,9 +279,9 @@ module DFHack
job = Job.cpp_new job = Job.cpp_new
refbuildingholder = GeneralRefBuildingHolderst.cpp_new refbuildingholder = GeneralRefBuildingHolderst.cpp_new
job.job_type = :DestroyBuilding job.job_type = :DestroyBuilding
refbuildingholder.building_id = building.id refbuildingholder.building_id = bld.id
job.references << refbuildingholder job.references << refbuildingholder
building.jobs << job bld.jobs << job
job_link job job_link job
job job
end end

@ -188,6 +188,11 @@ module DFHack
"#<MapTile pos=[#@x, #@y, #@z] shape=#{shape} tilemat=#{tilemat} material=#{mat_info.token}>" "#<MapTile pos=[#@x, #@y, #@z] shape=#{shape} tilemat=#{tilemat} material=#{mat_info.token}>"
end end
def dig(mode=:Default)
designation.dig = mode
mapblock.flags.designated = true
end
def spawn_liquid(quantity, is_magma=false, flowing=true) def spawn_liquid(quantity, is_magma=false, flowing=true)
designation.flow_size = quantity designation.flow_size = quantity
designation.liquid_type = (is_magma ? :Magma : :Water) designation.liquid_type = (is_magma ? :Magma : :Water)

@ -666,9 +666,9 @@ module DFHack
@_tg = tg @_tg = tg
end end
field(:_ptr, 0) { number 32, false } field(:_ptr, 0) { pointer }
field(:_prev, 4) { number 32, false } field(:_prev, 4) { pointer }
field(:_next, 8) { number 32, false } field(:_next, 8) { pointer }
def item def item
# With the current xml structure, currently _tg designate # With the current xml structure, currently _tg designate
@ -682,22 +682,24 @@ module DFHack
def item=(v) def item=(v)
#addr = _ptr #addr = _ptr
#raise 'null pointer' if addr == 0 #raise 'null pointer' if not addr
#@_tg.at(addr)._set(v) #@_tg.at(addr)._set(v)
raise 'null pointer' raise 'null pointer'
end end
def prev def prev
addr = _prev addr = _prev
return if addr == 0 return if not addr
@_tg._at(addr)._get @_tg._at(addr)._get
end end
def next def next
addr = _next addr = _next
return if addr == 0 return if not addr
@_tg._at(addr)._get @_tg._at(addr)._get
end end
alias next= _next=
alias prev= _prev=
include Enumerable include Enumerable
def each def each

@ -4,6 +4,7 @@
#include "Export.h" #include "Export.h"
#include "PluginManager.h" #include "PluginManager.h"
#include "VersionInfo.h" #include "VersionInfo.h"
#include "MemAccess.h"
#include "DataDefs.h" #include "DataDefs.h"
#include "df/global_objects.h" #include "df/global_objects.h"
@ -597,6 +598,45 @@ static VALUE rb_dfmemory_write_float(VALUE self, VALUE addr, VALUE val)
return Qtrue; return Qtrue;
} }
// return memory permissions at address (eg "rx", nil if unmapped)
static VALUE rb_dfmemory_check(VALUE self, VALUE addr)
{
void *ptr = (void*)rb_num2ulong(addr);
std::vector<t_memrange> ranges;
Core::getInstance().p->getMemRanges(ranges);
unsigned i = 0;
while (i < ranges.size() && ranges[i].end <= ptr)
i++;
if (i >= ranges.size() || ranges[i].start > ptr || !ranges[i].valid)
return Qnil;
std::string perm = "";
if (ranges[i].read)
perm += "r";
if (ranges[i].write)
perm += "w";
if (ranges[i].execute)
perm += "x";
if (ranges[i].shared)
perm += "s";
return rb_str_new(perm.c_str(), perm.length());
}
// memory write (tmp override page permissions, eg patch code)
static VALUE rb_dfmemory_patch(VALUE self, VALUE addr, VALUE raw)
{
int strlen = FIX2INT(rb_funcall(raw, rb_intern("length"), 0));
bool ret;
ret = Core::getInstance().p->patchMemory((void*)rb_num2ulong(addr),
rb_string_value_ptr(&raw), strlen);
return ret ? Qtrue : Qfalse;
}
// stl::string // stl::string
static VALUE rb_dfmemory_stlstring_new(VALUE self) static VALUE rb_dfmemory_stlstring_new(VALUE self)
@ -875,6 +915,8 @@ static void ruby_bind_dfhack(void) {
rb_define_singleton_method(rb_cDFHack, "memory_write_int16", RUBY_METHOD_FUNC(rb_dfmemory_write_int16), 2); rb_define_singleton_method(rb_cDFHack, "memory_write_int16", RUBY_METHOD_FUNC(rb_dfmemory_write_int16), 2);
rb_define_singleton_method(rb_cDFHack, "memory_write_int32", RUBY_METHOD_FUNC(rb_dfmemory_write_int32), 2); rb_define_singleton_method(rb_cDFHack, "memory_write_int32", RUBY_METHOD_FUNC(rb_dfmemory_write_int32), 2);
rb_define_singleton_method(rb_cDFHack, "memory_write_float", RUBY_METHOD_FUNC(rb_dfmemory_write_float), 2); rb_define_singleton_method(rb_cDFHack, "memory_write_float", RUBY_METHOD_FUNC(rb_dfmemory_write_float), 2);
rb_define_singleton_method(rb_cDFHack, "memory_check", RUBY_METHOD_FUNC(rb_dfmemory_check), 1);
rb_define_singleton_method(rb_cDFHack, "memory_patch", RUBY_METHOD_FUNC(rb_dfmemory_patch), 2);
rb_define_singleton_method(rb_cDFHack, "memory_stlstring_new", RUBY_METHOD_FUNC(rb_dfmemory_stlstring_new), 0); rb_define_singleton_method(rb_cDFHack, "memory_stlstring_new", RUBY_METHOD_FUNC(rb_dfmemory_stlstring_new), 0);
rb_define_singleton_method(rb_cDFHack, "memory_stlstring_delete", RUBY_METHOD_FUNC(rb_dfmemory_stlstring_delete), 1); rb_define_singleton_method(rb_cDFHack, "memory_stlstring_delete", RUBY_METHOD_FUNC(rb_dfmemory_stlstring_delete), 1);

@ -41,31 +41,44 @@ module DFHack
# returns an Array of all units that are current fort citizen (dwarves, on map, not hostile) # returns an Array of all units that are current fort citizen (dwarves, on map, not hostile)
def unit_citizens def unit_citizens
race = ui.race_id
civ = ui.civ_id
world.units.active.find_all { |u| world.units.active.find_all { |u|
u.race == race and u.civ_id == civ and !u.flags1.dead and !u.flags1.merchant and unit_iscitizen(u)
}
end
def unit_iscitizen(u)
u.race == ui.race_id and u.civ_id == ui.civ_id and !u.flags1.dead and !u.flags1.merchant and
!u.flags1.diplomat and !u.flags2.resident and !u.flags3.ghostly and !u.flags1.diplomat and !u.flags2.resident and !u.flags3.ghostly and
!u.curse.add_tags1.OPPOSED_TO_LIFE and !u.curse.add_tags1.CRAZED and !u.curse.add_tags1.OPPOSED_TO_LIFE and !u.curse.add_tags1.CRAZED and
u.mood != :Berserk u.mood != :Berserk
# TODO check curse ; currently this should keep vampires, but may include werebeasts # TODO check curse ; currently this should keep vampires, but may include werebeasts
}
end end
# list workers (citizen, not crazy / child / inmood / noble) # list workers (citizen, not crazy / child / inmood / noble)
def unit_workers def unit_workers
unit_citizens.find_all { |u| world.units.active.find_all { |u|
unit_isworker(u)
}
end
def unit_isworker(u)
unit_iscitizen(u) and
u.mood == :None and u.mood == :None and
u.profession != :CHILD and u.profession != :CHILD and
u.profession != :BABY and u.profession != :BABY and
# TODO MENIAL_WORK_EXEMPTION_SPOUSE # TODO MENIAL_WORK_EXEMPTION_SPOUSE
!unit_entitypositions(u).find { |pos| pos.flags[:MENIAL_WORK_EXEMPTION] } !unit_entitypositions(u).find { |pos| pos.flags[:MENIAL_WORK_EXEMPTION] }
}
end end
# list currently idle workers # list currently idle workers
def unit_idlers def unit_idlers
unit_workers.find_all { |u| world.units.active.find_all { |u|
unit_isidler(u)
}
end
def unit_isidler(u)
unit_isworker(u) and
# current_job includes eat/drink/sleep/pickupequip # current_job includes eat/drink/sleep/pickupequip
!u.job.current_job and !u.job.current_job and
# filter 'attend meeting' # filter 'attend meeting'
@ -74,15 +87,14 @@ module DFHack
u.military.squad_index == -1 and u.military.squad_index == -1 and
# filter 'on break' # filter 'on break'
not u.status.misc_traits.find { |t| t.id == :OnBreak } not u.status.misc_traits.find { |t| t.id == :OnBreak }
}
end end
def unit_entitypositions(unit) def unit_entitypositions(unit)
list = [] list = []
return list if not hf = world.history.figures.binsearch(unit.hist_figure_id) return list if not hf = unit.hist_figure_tg
hf.entity_links.each { |el| hf.entity_links.each { |el|
next if el._rtti_classname != :histfig_entity_link_positionst next if el._rtti_classname != :histfig_entity_link_positionst
next if not ent = world.entities.all.binsearch(el.entity_id) next if not ent = el.entity_tg
next if not pa = ent.positions.assignments.binsearch(el.assignment_id) next if not pa = ent.positions.assignments.binsearch(el.assignment_id)
next if not pos = ent.positions.own.binsearch(pa.position_id) next if not pos = ent.positions.own.binsearch(pa.position_id)
list << pos list << pos