Merge remote branch 'upstream/master'

develop
Raoul XQ 2011-04-23 03:18:38 +02:00
commit d53cd6163c
44 changed files with 1785 additions and 1330 deletions

12
.gitignore vendored

@ -17,6 +17,16 @@ build*/
#except for the real one
!build/
# in-place build
build/Makefile
build/CMakeCache.txt
build/cmake_install.cmake
build/CMakeFiles
build/doc
build/bin
build/library
build/tools
#ignore Kdevelop stuff
.kdev4
@ -30,4 +40,4 @@ dfhack/python/PyDFHack.egg-info
dfhack/python/build
dfhack/python/dist
/cmakeall.bat
/cmakeall.bat

@ -29,6 +29,9 @@
<Offset name="first" description="Lowercase stl string with the first name. For ex. 'urist'" />
<Offset name="nick" description="Stl string with the nickname. Set by the player." />
<Offset name="second_words" description="Array of 7 indexes into the language vectors."/>
<Offset name="parts_of_speech" description="Array of 7 16-bit indexes into the language vectors."/>
<Offset name="language" description="Language of the name."/>
<Offset name="has_name" description="Boolean flag."/>
</Group>
</Offsets>
</Base>
@ -784,6 +787,9 @@
<Offset name="first" description="Lowercase stl string with the first name. For ex. 'urist'" />
<Offset name="nick" description="Stl string with the nickname. Set by the player." />
<Offset name="second_words" description="Array of 7 indexes into the language vectors."/>
<Offset name="parts_of_speech" description="Array of 7 16-bit indexes into the language vectors."/>
<Offset name="language" description="Language of the name."/>
<Offset name="has_name" description="Boolean flag."/>
</Group>
<Group name="Position" description="Offsets used by the Position module.">
<Address name="window_x" description="X coordinate of the current view (DWORD)" />
@ -819,6 +825,8 @@
<Group name="block" description="The map block structure.">
<Offset name="vein_vector" description="Mineral veins, objects holding tile types under ice, etc..."/>
<Offset name="vegetation_vector" description="All the plants in this block, including farm plats."/>
<Offset name="effect_vector" description="Effect objects present in the block."/>
<Offset name="item_idx_vector" description="Indexes of item objects present in the block."/>
<Offset name="type" description="16x16 x 2B tile type values"/>
<Offset name="designation" description="16x16 * 4B designation fields"/>
<Offset name="occupancy" description="16x16 * 4B occupancy fields" />
@ -870,6 +878,7 @@
<Offset name="position" description="X,Y,Z." />
<Offset name="flags1" description="First set of flags" />
<Offset name="flags2" description="Second set of flags" />
<Offset name="flags3" description="Third set of flags" />
<Offset name="caste" description="Caste of the creature. Same as sex most of the time." />
<Offset name="sex" description="Sex of the creature." />
<Offset name="id" description="Unique ID of the creature, seems to be used for binary search in the creature vector." />
@ -891,6 +900,7 @@
<Offset name="current_soul" description="Currently active soul?" />
<Offset name="labors" description="Array of labors. Used by DT to enable/disable them." />
<Offset name="happiness" description="Number that says how happy the creature is." />
<Offset name="hist_figure_id" description="For a creature matching a historical figure, it's ID"/>
</Group>
</Group>
@ -993,10 +1003,12 @@
<Offset name="item_subindex_accessor" />
<Offset name="item_index_accessor" />
<Offset name="item_quality_accessor" />
<!--
<Offset name="item_improvement_vector" />
<Offset name="item_improvement_subindex" />
<Offset name="item_improvement_index" />
<Offset name="item_improvement_quality" />
-->
<Offset name="item_wear_accessor" />
<Offset name="item_ref_vector" description="Contains the owner among other things"/>
<Offset name="owner_ref_id_field" description="Creature ID offset in general_ref_unit_itemownerst"/>
@ -1009,6 +1021,39 @@
<Address name="control_mode" description="Current control mode" />
<!--<Address name="control_mode_copy" description="Copy of the control mode in DF memory" />-->
</Group>
<Group name="Legends">
<Group name="figures">
<Address name="vector"/>
<Offset name="profession" description="Figure's profession"/>
<Offset name="race" description="Figure's race"/>
<Offset name="caste" description="Figure's caste; mostly equal to sex"/>
<Offset name="sex" description="Figure's sex (or maybe the other way round)"/>
<Offset name="appeared_year"/>
<Offset name="born_year"/>
<Offset name="born_seconds"/>
<Offset name="died_year"/>
<Offset name="died_seconds"/>
<Offset name="name" description="A standard name record"/>
<Offset name="unit_id" description="ID of the creature matching the figure, or -1"/>
<Offset name="figure_id" description="ID of the figure, ordered"/>
<Offset name="entity_link_vector"/>
<Offset name="histfig_link_vector"/>
</Group>
<Group name="events">
<Address name="vector"/>
<Offset name="year"/>
<Offset name="seconds"/>
<Offset name="event_id"/>
<Group name="hist_figure_died">
<Offset name="figure_id"/>
<Offset name="slayer_id"/>
<Offset name="slayer_race"/>
<Offset name="slayer_caste"/>
<Offset name="slayer_item_id"/>
<Offset name="region_id"/>
</Group>
</Group>
</Group>
</Offsets>
</Base>
@ -1070,6 +1115,9 @@
<Offset name="first" value="0x0" />
<Offset name="nick" value="0x1C" />
<Offset name="second_words" value="0x38" />
<Offset name="parts_of_speech" value="0x54" />
<Offset name="language" value="0x64" />
<Offset name="has_name" value="0x68" />
</Group>
<Group name="Position">
<Address name="window_x" value="0xe32798" />
@ -1383,12 +1431,15 @@
<Offset name="item_subtype_accessor" value="0x4" />
<Offset name="item_subindex_accessor" value="0x8" />
<Offset name="item_index_accessor" value="0xC" />
<Offset name="item_type_accessor" value="0x14" /> ... seriously, WHAT?
<Offset name="item_quality_accessor" value="0x238" />
<!--
<Offset name="item_improvement_vector" value="0xA0" />
<Offset name="item_improvement_subindex" value="0x4" />
<Offset name="item_improvement_index" value="0x8" />
<Offset name="item_improvement_quality" value="0x14" />
<Offset name="item_type_accessor" value="0x14" /> (in the vtable)
-->
</Group>
<Group name="World">
<Address name="current_tick" value="0x0e47e08" />
@ -1607,6 +1658,9 @@
<Offset name="first" value="0x0" />
<Offset name="nick" value="0x1C" />
<Offset name="second_words" value="0x38" />
<Offset name="parts_of_speech" value="0x54" />
<Offset name="language" value="0x64" />
<Offset name="has_name" value="0x68" />
</Group>
<Group name="Position">
<Address name="cursor_xyz" value="0xac77f0" />
@ -1863,7 +1917,9 @@
<Offset name="item_subindex_accessor" value="0x8" />
<Offset name="item_index_accessor" value="0xC" />
<Offset name="item_quality_accessor" value="0x238" />
<!--
<Offset name="item_improvement_vector" value="0x90" />
-->
</Group>
</Offsets>
</Version>
@ -2136,6 +2192,8 @@
<Group name="Maps">
<Group name="block">
<Offset name="mystery_offset" value="0x2C" />
<Offset name="item_idx_vector" value="0x3C" />
<Offset name="effect_vector" value="0x4C" />
<Offset name="vegetation_vector" value="0x64" />
<Offset name="type" value="0x7e" />
<Offset name="designation" value="0x280" />
@ -2175,6 +2233,25 @@
<Version name="v0.31.25 SDL" os="windows" base="v0.31.24 SDL">
<PETimeStamp value="0x4D90764F" />
<MD5 value="6ada05fc94785b53efe6aa5728b3756b" />
<Offsets>
<Group name="Items" valid="true">
<Address name="items_vector" value="0x16c4540"/>
<Offset name="item_ref_vector" value="0x28" />
<Offset name="owner_ref_id_field" value="0x4" />
<Offset name="item_wear_accessor" value="0xCC" />
<Offset name="item_quality_accessor" value="0x25C" />
</Group>
</Offsets>
cmake
item vector:
-- those two seem to have identical length
0x16c4540 -- maybe
0x16c4550 -- maybe
0x16c4d20 -- too small/bogus?
0x16c4660 -- too small again
0x185c104 -- no.
</Version>
.-"""-.
' \
@ -2219,6 +2296,9 @@
<Offset name="first" value="0x0" />
<Offset name="nick" value="0x4" />
<Offset name="second_words" value="0x8" />
<Offset name="parts_of_speech" value="0x24" />
<Offset name="language" value="0x34" />
<Offset name="has_name" value="0x3a" />
</Group>
<Group name="Position">
<Address name="window_x" value="0x8cc9b38" />
@ -2588,12 +2668,7 @@
</Group>
</Offsets>
</Version>
<Version name="faek" os="linux" base="v0.31.14 linux">
<Offsets>
<Group name="Position" valid="false" />
</Offsets>
</Version>
<Version name="v0.31.16 linux" os="linux" base="faek" rebase="0x1b40">
<Version name="v0.31.16 linux" os="linux" base="v0.31.14 linux" rebase="0x1b40">
<MD5 value="9cca2fa5da509e2f9a1042ddd1f9669c" />
<Offsets>
<Group name="Position">
@ -2604,45 +2679,87 @@
</Group>
</Offsets>
</Version>
<Version name="v0.31.18 linux" os="linux" base="faek">
<Version name="v0.31.18 linux" os="linux" base="v0.31.16 linux" rebase="0x81110">
<MD5 value="884f794d8e89e7d764057c15617c20b1" />
<Offsets valid="false">
<Group name="Maps" valid="true">
<Address name="map_data" value="0x93c0430" />
<Address name="region_x" value="0x93c045c" />
<Address name="region_y" value="0x93c0460" />
<Address name="region_z" value="0x93c0464" />
<Address name="x_count_block" value="0x93c0444" />
<Address name="y_count_block" value="0x93c0448" />
<Address name="z_count_block" value="0x93c044c" />
<Address name="x_count" value="0x93c0450" />
<Address name="y_count" value="0x93c0454" />
<Address name="z_count" value="0x93c0458" />
<Address name="world_size_x" value="0x93c1ab0" />
<Address name="world_size_y" value="0x93c1ab2" />
<Group name="block" valid="true" />
<Group name="features" valid="false" />
<Group name="geology" valid="false" />
<Offsets>
<Group name="Buildings">
<Address name="buildings_vector" value="0x9381814" />
<Address name="custom_workshop_vector" value="0x93c6938" />
</Group>
<Group name="Constructions">
<Address name="vector" value="0x936d824" />
</Group>
<Group name="Creatures">
<Address name="current_civ" value="0x9368bec" />
<Address name="current_race" value="0x9368bf8" />
<Address name="vector" value="0x938118c" />
</Group>
<Group name="GUI">
<Address name="pause_state" value="0x9366cb0"/>
</Group>
<Group name="string" valid="true" />
<Group name="vector" valid="true" />
<Group name="name" valid="true" />
<Group name="Maps">
<Group name="features">
<Group name="global">
<Address name="vector" value="0x93c2074" />
</Group>
<Group name="local">
<Address name="start_ptr" value="0x93c20ec" />
</Group>
</Group>
<Group name="geology">
<Address name="geoblock_vector" value="0x93c208c" />
<Address name="ptr2_region_array" value="0x93c20b0" />
</Group>
</Group>
<Group name="Materials">
<Address name="inorganics" value="0x93c25a8" />
<Address name="organics_all" value="0x93c25c0" />
<Address name="organics_plants" value="0x93c25cc" />
<Address name="organics_trees" value="0x93c25e4" />
<Address name="creature_type_vector" value="0x93c2660" />
<Group name="descriptors">
<Address name="colors_vector" value="0x93c6908" />
<Address name="all_colors_vector" value="0x93c6920" />
</Group>
</Group>
<Group name="Position">
<Address name="cursor_xyz" value="0x8bb4560" />
<Address name="window_x" value="0x8d7105c" />
<Address name="window_y" value="0x8d71058" />
<Address name="window_z" value="0x8d71060" />
</Group>
<Group name="Translations">
<Address name="language_vector" value="0x93c27a4" />
<Address name="translation_vector" value="0x93c27bc" />
</Group>
<Group name="World">
<Address name="current_weather" value="0x9366bd0" />
<Address name="current_tick" value="0x9366c0c" />
</Group>
</Offsets>
</Version>
<Version name="v0.31.19 linux" os="linux" base="v0.31.18 linux" rebase="0x77738">
<MD5 value="8fcb1f10af9cc2bda47d2acf42e1db54" />
<Offsets>
<Group name="Position" valid="true">
<Address name="cursor_xyz" value="0x8c2b560" />
<Address name="screen_tiles_pointer" valid="false" />
<Group name="Buildings">
<Address name="buildings_vector" value="0x93f8f18" />
<Address name="custom_workshop_vector" value="0x943e398" />
</Group>
<Group name="Constructions">
<Address name="vector" value="0x93e4f04" />
</Group>
<Group name="Creatures">
<Address name="current_civ" value="0x93e027c" />
<Address name="current_race" value="0x93e0288" />
<Address name="vector" value="0x93f886c" />
</Group>
<Group name="GUI">
<Address name="pause_state" value="0x93dddf0" />
</Group>
<Group name="Maps">
<Address name="world_size_x" value="0x94391f0" />
<Address name="world_size_y" value="0x94391f2" />
<Group name="features" valid="true">
<Group name="features">
<Group name="global">
<Address name="vector" value="0x94397cc" />
</Group>
@ -2650,84 +2767,162 @@
<Address name="start_ptr" value="0x9439844" />
</Group>
</Group>
<Group name="geology" valid="true">
<Group name="geology">
<Address name="geoblock_vector" value="0x94397e4" />
<Address name="ptr2_region_array" value="0x9439808" />
</Group>
</Group>
<Group name="GUI">
<Address name="pause_state" value="0x93dddf0" />
</Group>
<Group name="Materials">
<Address name="creature_type_vector" value="0x943a074" />
<Address name="inorganics" value="0x9439fc0" />
<Address name="organics_all" value="0x9439fd8" />
<Address name="organics_plants" value="0x9439fe4" />
<Address name="organics_trees" value="0x9439ffc" />
-------------------
!!LANGUAGE TABLES!!
-------------------
translation vector: 0x943a21c
lang vector: 0x943a204
word table offset: 0x1c
-------------
!!MATERIALS!!
-------------
inorganics:
0x9439fc0
organics:
0x9439fd8
organics 31.19:
trees:
0x9439ffc
plants:
0x9439fe4
color descriptors:
0x943e368
Amber color:0xa380190
all descriptors:
0x943e380
toad-first creature types:
0x943a074
all creature types:
0x943a068
0x943a074
Toad: 0xa441f10
Toad: rawname = 0x0
Toad: character (not reliable) = 0x20
Toad: caste vector = 0x60
Toad: extract? vector = 0x1f74
Toad: colors = 0x38
<Address name="creature_type_vector" value="0x943a074" />
<Group name="descriptors">
<Address name="colors_vector" value="0x943e368" />
<Address name="all_colors_vector" value="0x943e380" />
</Group>
</Group>
<Group name="Position">
<Address name="cursor_xyz" value="0x8c2b560" />
<Address name="window_x" value="0x8de819c" />
<Address name="window_y" value="0x8de8198" />
<Address name="window_z" value="0x8de81a0" />
</Group>
<Group name="Translations">
<Address name="language_vector" value="0x943a204" />
<Address name="translation_vector" value="0x943a21c" />
</Group>
<Group name="World">
<Address name="current_weather" value="0x93ddd10" />
<Address name="current_tick" value="0x93ddd4c" />
</Group>
</Offsets>
</Version>
<Version name="v0.31.22 linux" os="linux" base="v0.31.19 linux" rebase="0x12A80">
<Version name="v0.31.20 linux" os="linux" base="v0.31.19 linux" rebase="0xd540">
<MD5 value="6d33ec7332e59df9ea4cf7fae1e9836a" />
<Offsets>
<!-- Handling has changed for some offsets in 0.31.20, and they no longer
appear to be static - they're probably heap objects now or something.
Code no longer does 'mov <offset>, <register>', but now does something
more like 'mov <constant>, register; mov <offset>(<register>), <register>'
(indirect load).
Offsets affected in 0.31.20:
Maps.features.global.vector
Maps.features.local.start_ptr
Maps.geology.geoblock_vector
Maps.geology.ptr2_region_array
Maps.world_size_x
Maps.world_size_y
This breaks dfliquids, dfvdig (of the ones I care about anyway - probably more too)
-->
<Group name="Buildings">
<Address name="custom_workshop_vector" value="0x944b1b8" />
</Group>
<Group name="Materials">
<Address name="inorganics" value="0x9446de0" />
<Address name="organics_all" value="0x9446df8" />
<Address name="organics_plants" value="0x9446e04" />
<Address name="organics_trees" value="0x9446e1c" />
<Address name="creature_type_vector" value="0x9446e94" />
<Group name="descriptors">
<Address name="colors_vector" value="0x944b188" />
<Address name="all_colors_vector" value="0x944b1a0" />
</Group>
</Group>
<Group name="Position">
<Address name="cursor_xyz" value="0x8c38a90" />
<Address name="window_x" value="0x8df56d8" />
<Address name="window_y" value="0x8df56dc" />
</Group>
<Group name="Translations">
<Address name="language_vector" value="0x944703c" />
<Address name="translation_vector" value="0x9447024" />
</Group>
</Offsets>
</Version>
<Version name="v0.31.21 linux" os="linux" base="v0.31.20 linux" rebase="0x40">
<MD5 value="c3d2af104a00a3219fbbe89e671940fb" />
<Offsets>
<Group name="Position">
<Address name="cursor_xyz" value="0x8c38ae0" />
</Group>
<Group name="Translations">
<Address name="language_vector" value="0x9447064" />
<Address name="translation_vector" value="0x944707c" />
</Group>
</Offsets>
</Version>
<Version name="v0.31.22 linux" os="linux" base="v0.31.21 linux" rebase="0x5500">
<MD5 value="c7319be110759209bd736071fb367960" />
<Offsets>
<Group name="Buildings" valid="true">
<Address name="buildings_vector" value="0x940b998" />
One of the two, really:
0x940b998
0x940b9a4
<Address name="custom_workshop_vector" value="0x94506f8" />
<Group name="Creatures">
<Address name="current_civ" value="0x93f2cdc" />
<Address name="current_race" value="0x93f2ce8" />
<Group name="creature">
<Group name="advanced">
<Offset name="pregnancy" value="0x190" />
<Offset name="pregnancy_ptr" value="0x194" />
<Offset name="birth_year" value="0x1A0" />
<Offset name="birth_time" value="0x1A4" />
<Offset name="inventory_vector" value="0x204" />
<Offset name="current_job" value="0x25C" />
<Offset name="current_job_skill" value="0x260" />
<Offset name="physical" value="0x310" />
<Offset name="appearance_vector" value="0x450" />
<Offset name="artifact_name" value="0x4f4" />
<Offset name="soul_vector" value="0x530" />
<Offset name="current_soul" value="0x53C" />
<Offset name="labors" value="0x54C" />
<Offset name="happiness" value="0x05dc" />
</Group>
<Group name="Engravings">
<Address name="vector" value="0x93F7918 0x93f77b8"/>
there are some possibly related vectors right next to it.
</Group>
<Group name="Constructions" valid="true">
<Address name="vector" value="0x93f7984" />
<Group name="job">
<Offset name="id" value="0x8" />
<!--<Offset name="materials_vector" />-->
<Offset name="type" value="0x40" /> MAYBE, DT SAYS SO
<!--
<Group name="material">
<Offset name="flags" /> NOT SET!
<Offset name="maintype" /> NOT SET!
<Offset name="sectype1" /> NOT SET!
<Offset name="sectype2" /> NOT SET!
<Offset name="sectype3" /> NOT SET!
</Group>
-->
</Group>
<Group name="soul">
<Offset name="name" value="0x4" />
<!--
<Offset name="mental" value="0x88" />
<Offset name="skills_vector" value="0x1c4" />
<Offset name="traits" value="0x1dc" />
-->
</Group>
</Group>
<Group name="GUI">
<Address name="pause_state" value="0x93f0850" />
</Group>
<Group name="Position">
<Address name="cursor_xyz" value="0x8c3dfc0" />
<Address name="window_dims" value="0x8c3e4c8" />
<Address name="window_x" value="0x8dfabf8" />
<Address name="window_y" value="0x8dfabfc" />
<Address name="window_z" value="0x8dfac00" />
<Address name="window_dims" value="0x8c3e4c8" />
</Group>
<Group name="World">
<Address name="current_weather" value="0x93f0770" />
<Address name="current_tick" value="0x93f07ac" />
<Address name="control_mode" value="0x8c3dff0" />
<Address name="game_mode" value="0x8c3e000" />
<Address name="current_year" value="0x93f0760" />
</Group>
<Group name="Engravings">
<Address name="vector" value="0x93F7918 0x93f77b8"/>
there are some possibly related vectors right next to it.
</Group>
<Group name="Maps">
<Address name="world_data" value="0x944bc14"/>
@ -2763,61 +2958,7 @@
<Offset name="ptr2_region_array_from_wdata" value="0x15C" />
</Group>
</Group>
<Group name="Creatures" valid="true">
<Address name="current_civ" value="0x093f2cb0" /> MAYBE
<Address name="current_race" value="0x093f2cbc" />
<Address name="vector" value="0x0940b310" /> POSSIBLY WRONG!
<Group name="creature">
<Group name="advanced">
<Offset name="pregnancy" value="0x190" />
<Offset name="pregnancy_ptr" value="0x194" />
<Offset name="birth_year" value="0x1A0" />
<Offset name="birth_time" value="0x1A4" />
<Offset name="inventory_vector" value="0x204" />
<Offset name="current_job" value="0x25C" />
<Offset name="current_job_skill" value="0x260" />
<Offset name="physical" value="0x310" />
<Offset name="appearance_vector" value="0x450" />
<Offset name="artifact_name" value="0x4f4" />
<Offset name="soul_vector" value="0x530" />
<Offset name="current_soul" value="0x53C" />
<Offset name="labors" value="0x54C" />
<Offset name="happiness" value="0x05dc" />
</Group>
</Group>
<Group name="job">
<Offset name="id" value="0x8" />
<!--<Offset name="materials_vector" />-->
<Offset name="type" value="0x40" /> MAYBE, DT SAYS SO
<!--
<Group name="material">
<Offset name="flags" /> NOT SET!
<Offset name="maintype" /> NOT SET!
<Offset name="sectype1" /> NOT SET!
<Offset name="sectype2" /> NOT SET!
<Offset name="sectype3" /> NOT SET!
</Group>
-->
</Group>
<Group name="soul">
<Offset name="name" value="0x4" />
<!--
<Offset name="mental" value="0x88" />
<Offset name="skills_vector" value="0x1c4" />
<Offset name="traits" value="0x1dc" />
-->
</Group>
</Group>
<Group name="Materials">
<Address name="inorganics" value="0x944c320" />
<Address name="organics_all" value="0x944c338" />
<Address name="organics_plants" value="0x944c344" />
<Address name="organics_trees" value="0x944c35c" />
<Address name="creature_type_vector" value="0x944c3d4" />
one of those:
0x944c3c8
0x944c3d4
<Address name="other" value="0x9450c54" />
<Group name="creature" valid="true">
<Offset name="tile_color" value="0x38" />
@ -2840,43 +2981,15 @@
<Offset name="startdate" value="0x34" />
</Group>
</Group>
<Group name="descriptors" valid="true">
<Address name="colors_vector" value="0x94506c8 0x93cdff4" />
<Address name="all_colors_vector" value="0x94506E0 0x93ce00c" />
</Group>
</Group>
<Group name="Translations" valid="true">
<!-- maybe swapped -->
<Address name="language_vector" value="0x944c564"/>
<Address name="translation_vector" value="0x944c57c"/>
</Group>
<Group name="Vegetation" valid="true">
<Address name="vector" value="0x940bed0" />
</Group>
<Group name="World">
<Address name="control_mode" value="0x8c3dff0" />
<Address name="game_mode" value="0x8c3e000" />
<Address name="current_weather" value="0x93f0744" />
<Address name="current_year" value="0x93f0760" />
<Address name="current_tick" value="0x93f0780" />
</Group>
</Offsets>
</Version>
<Version name="v0.31.23 linux" os="linux" base="v0.31.22 linux" rebase="-0x760">
<MD5 value="c8e82e6e7cc606bf4e8d2c91993b9c0d" />
<Offsets>
<Group name="Creatures">
<Address name="vector" value="0x0940ab74" /> VERIFY
</Group>
</Offsets>
</Version>
<Version name="v0.31.24 linux" os="linux" base="v0.31.23 linux" rebase="0x300">
<MD5 value="a47468cec4f4f0ff1fc03ac7d95c17ed" />
<Offsets>
<Group name="Creatures">
<Address name="vector" value="0x0940aeb0" /> VERIFY
</Group>
<Group name="Position">
<Address name="cursor_xyz" value="0x8c3db50" />
</Group>
@ -2890,7 +3003,12 @@
<MD5 value="fc15065c4d1977ca019c6dad220413d1" />
<Offsets>
<Group name="Creatures">
<Address name="vector" value="0x0940b174" /> VERIFY
<Group name="creature">
<Offset name="flags3" value="0x94"/>
<Group name="advanced">
<Offset name="hist_figure_id" value="0x640"/>
</Group>
</Group>
</Group>
<Group name="Position" valid="true">
<Address name="cursor_xyz" value="0x8c3de60"/>
@ -2910,6 +3028,39 @@
<Offset name="item_ref_vector" value="0x24" />
<Offset name="owner_ref_id_field" value="0x4" />
</Group>
<Group name="Legends">
<Group name="figures">
<Address name="vector" value="0x9451a18"/>
<Offset name="profession" value="0x00"/>
<Offset name="race" value="0x02"/>
<Offset name="caste" value="0x04"/>
<Offset name="sex" value="0x06"/>
<Offset name="appeared_year" value="0x08"/>
<Offset name="born_year" value="0x0C"/>
<Offset name="born_seconds" value="0x10"/>
<Offset name="died_year" value="0x1C"/>
<Offset name="died_seconds" value="0x20"/>
<Offset name="name" value="0x24"/>
<Offset name="unit_id" value="0x70"/>
<Offset name="figure_id" value="0x74"/>
<Offset name="entity_link_vector" value="0x7c"/>
<Offset name="histfig_link_vector" value="0x94"/>
</Group>
<Group name="events">
<Address name="vector" value="0x9451a00"/>
<Offset name="year" value="0x04"/>
<Offset name="seconds" value="0x08"/>
<Offset name="event_id" value="0x14"/>
<Group name="hist_figure_died">
<Offset name="figure_id" value="0x18"/>
<Offset name="slayer_id" value="0x1C"/>
<Offset name="slayer_race" value="0x20"/>
<Offset name="slayer_caste" value="0x24"/>
<Offset name="slayer_item_id" value="0x28"/>
<Offset name="region_id" value="0x48"/>
</Group>
</Group>
</Group>
</Offsets>
</Version>
</DFHack>

@ -133,9 +133,10 @@ Can be used to determine tile properties like temperature.
dfprospector
============
Lists all available minerals on the map and how much of them there is.
It has two parameters:
-a processes all tiles, even hidden ones.
-b includes layer rocks into the count.
It has one parameter:
* -a processes all tiles, even hidden ones.
On windows, it's possible to run dfprsopector-all.bat to process all the tiles without messing with terminal windows.
dfreveal
========

@ -474,9 +474,9 @@ You just lost a fortress and gained an adventurer.</p>
<div class="section" id="dfprospector">
<h2><a class="toc-backref" href="#id22">dfprospector</a></h2>
<p>Lists all available minerals on the map and how much of them there is.
It has two parameters:
-a processes all tiles, even hidden ones.
-b includes layer rocks into the count.</p>
It has one parameter:
* -a processes all tiles, even hidden ones.</p>
<p>On windows, it's possible to run dfprsopector-all.bat to process all the tiles without messing with terminal windows.</p>
</div>
<div class="section" id="dfreveal">
<h2><a class="toc-backref" href="#id23">dfreveal</a></h2>

@ -35,6 +35,9 @@ bool DFContextShared::InitReadNames()
name_firstname_offset = OG->getOffset("first");
name_nickname_offset = OG->getOffset("nick");
name_words_offset = OG->getOffset("second_words");
name_parts_offset = OG->getOffset("parts_of_speech");
name_language_offset = OG->getOffset("language");
name_set_offset = OG->getOffset("has_name");
return true;
}
@ -42,5 +45,25 @@ void DFContextShared::readName(t_name & name, uint32_t address)
{
p->readSTLString(address + name_firstname_offset , name.first_name, 128);
p->readSTLString(address + name_nickname_offset , name.nickname, 128);
p->read(address + name_words_offset ,28, (uint8_t *) name.words);
p->read(address + name_words_offset, 7*4, (uint8_t *)name.words);
p->read(address + name_parts_offset, 7*2, (uint8_t *)name.parts_of_speech);
name.language = p->readDWord(address + name_language_offset);
name.has_name = p->readByte(address + name_set_offset);
}
void DFContextShared::copyName(uint32_t address, uint32_t target)
{
uint8_t buf[28];
if (address == target)
return;
p->copySTLString(address + name_firstname_offset, target + name_firstname_offset);
p->copySTLString(address + name_nickname_offset, target + name_nickname_offset);
p->read(address + name_words_offset, 7*4, buf);
p->write(target + name_words_offset, 7*4, buf);
p->read(address + name_parts_offset, 7*2, buf);
p->write(target + name_parts_offset, 7*2, buf);
p->writeDWord(target + name_language_offset, p->readDWord(address + name_language_offset));
p->writeByte(target + name_set_offset, p->readByte(address + name_set_offset));
}

@ -476,7 +476,7 @@ size_t SHMProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapa
return fit;
}
void SHMProcess::writeSTLString(const uint32_t address, const std::string writeString)
size_t SHMProcess::writeSTLString(const uint32_t address, const std::string writeString)
{
if(!d->locked) throw Error::MemoryAccessDenied(address);
@ -484,4 +484,5 @@ void SHMProcess::writeSTLString(const uint32_t address, const std::string writeS
strncpy(D_SHMDATA(char),writeString.c_str(),writeString.length()+1); // length + 1 for the null terminator
full_barrier
d->SetAndWait(CORE_WRITE_STL_STRING);
return writeString.length();
}

@ -220,7 +220,7 @@ void LinuxProcessBase::writeByte (uint32_t offset, uint8_t data)
#endif
}
// blah. I hate the kernel devs for crippling /proc/PID/mem. THIS IS RIDICULOUS
// blah. THIS IS RIDICULOUS
void LinuxProcessBase::write (uint32_t offset, uint32_t size, uint8_t *source)
{
uint32_t indexptr = 0;

@ -71,7 +71,7 @@ namespace {
void readSTLVector(const uint32_t address, t_vecTriplet & triplet);
const std::string readSTLString (uint32_t offset);
size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity);
void writeSTLString(const uint32_t address, const std::string writeString){};
size_t writeSTLString(const uint32_t address, const std::string writeString);
// get class name of an object with rtti/type info
std::string readClassName(uint32_t vptr);
};
@ -157,6 +157,12 @@ size_t WineProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcap
return stl.readSTLString(offset, buffer, bufcapacity);
}
size_t WineProcess::writeSTLString(const uint32_t address, const std::string writeString)
{
return stl.writeSTLString(address,writeString);
}
const string WineProcess::readSTLString (uint32_t offset)
{
return stl.readSTLString(offset);

@ -65,7 +65,8 @@ namespace {
void readSTLVector(const uint32_t address, t_vecTriplet & triplet);
const std::string readSTLString (uint32_t offset);
size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity);
void writeSTLString(const uint32_t address, const std::string writeString){};
size_t writeSTLString(const uint32_t address, const std::string writeString);
size_t copySTLString(const uint32_t address, const uint32_t target);
// get class name of an object with rtti/type info
std::string readClassName(uint32_t vptr);
};
@ -125,9 +126,9 @@ NormalProcess::NormalProcess(uint32_t pid, VersionInfoFactory * known_versions)
struct _Rep_base
{
uint32_t _M_length;
uint32_t _M_capacity;
uint32_t _M_refcount;
uint32_t _M_length; // length of text stored, not including zero termination
uint32_t _M_capacity; // capacity, not including zero termination
uint32_t _M_refcount; // reference count (two STL strings can share a common buffer, copy on write rules apply)
};
size_t NormalProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity)
@ -141,6 +142,32 @@ size_t NormalProcess::readSTLString (uint32_t offset, char * buffer, size_t bufc
return read_real;
}
size_t NormalProcess::writeSTLString(const uint32_t address, const std::string writeString)
{
_Rep_base header;
// get buffer location
uint32_t start = Process::readDWord(address);
// read the header
read(start - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header);
// the buffer has actual size = 1. no space for storing anything more than a zero byte
if(header._M_capacity == 0)
return 0;
if(header._M_refcount != 0 && header._M_refcount != 0xFFFFFFFF ) // one ref or one non-shareable ref
return 0;
// get writeable length (lesser of our string length and capacity of the target)
uint32_t lstr = writeString.length();
uint32_t allowed_copy = min(lstr, header._M_capacity);
// write header with new length.
header._M_length = allowed_copy;
write(start - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header);
// write string, add a zero terminator, return bytes written
write(start, allowed_copy, (uint8_t *) writeString.c_str());
writeByte(start + allowed_copy, 0);
return allowed_copy;
}
void NormalProcess::readSTLVector(const uint32_t address, t_vecTriplet & triplet)
{
read(address + vector_start, sizeof(triplet), (uint8_t *) &triplet);
@ -161,6 +188,30 @@ const string NormalProcess::readSTLString (uint32_t offset)
return ret;
}
size_t NormalProcess::copySTLString (uint32_t offset, uint32_t target)
{
_Rep_base header;
offset = Process::readDWord(offset);
uint32_t old_target = Process::readDWord(target);
if (offset == old_target)
return 0;
read(offset - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header);
// destroying the leaked state
if (header._M_refcount == -1)
header._M_refcount = 1;
else
header._M_refcount++;
write(offset - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header);
writeDWord(target, offset);
return header._M_length;
}
string NormalProcess::readClassName (uint32_t vptr)
{
int typeinfo = Process::readDWord(vptr - 0x4);

@ -24,6 +24,8 @@ distribution.
#include "Internal.h"
#include "PlatformInternal.h"
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <string>
#include <map>

@ -24,6 +24,8 @@ distribution.
#include "Internal.h"
#include "PlatformInternal.h"
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <string>
#include <map>

@ -3,12 +3,644 @@
#include "dfhack/DFTileTypes.h"
#include "dfhack/DFExport.h"
namespace DFHack {
namespace DFHack
{
const TileRow tileTypeTable[TILE_TYPE_ARRAY_LENGTH] =
{
// 0
{"void",EMPTY, AIR, VAR_1},
{"ramp top",RAMP_TOP, AIR, VAR_1},
{"pool",FLOOR, SOIL, VAR_1, TILE_POOL},
{0, EMPTY, AIR, VAR_1},
{0, EMPTY, AIR, VAR_1},
{0, EMPTY, AIR, VAR_1},
{0, EMPTY, AIR, VAR_1},
{0, EMPTY, AIR, VAR_1},
{0, EMPTY, AIR, VAR_1},
{0, EMPTY, AIR, VAR_1},
// 10
{0, EMPTY, AIR, VAR_1},
{0, EMPTY, AIR, VAR_1},
{0, EMPTY, AIR, VAR_1},
{0, EMPTY, AIR, VAR_1},
{0, EMPTY, AIR, VAR_1},
{0, EMPTY, AIR, VAR_1},
{0, EMPTY, AIR, VAR_1},
{0, EMPTY, AIR, VAR_1},
{0, EMPTY, AIR, VAR_1},
{"driftwood stack",FLOOR, DRIFTWOOD, VAR_1},
// 20
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"tree",TREE_OK, SOIL, VAR_1},
{"ice stair up/down",STAIR_UPDOWN, ICE, VAR_1},
{"ice stair down",STAIR_DOWN, ICE, VAR_1},
{"ice stair up",STAIR_UP, ICE, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 30
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"empty space",EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"shrub",SHRUB_OK, SOIL, VAR_1},
{"chasm",FLOOR, AIR, VAR_1, TILE_ENDLESS },
{"obsidian stair up/down",STAIR_UPDOWN, OBSIDIAN, VAR_1},
{"obsidian stair down",STAIR_DOWN, OBSIDIAN, VAR_1},
{"obsidian stair up",STAIR_UP, OBSIDIAN, VAR_1},
{"soil stair up/down",STAIR_UPDOWN, SOIL, VAR_1},
// 40
{"soil stair down",STAIR_DOWN, SOIL, VAR_1},
{"soil stair up",STAIR_UP, SOIL, VAR_1},
{"eerie pit",FLOOR, HFS, VAR_1, TILE_ENDLESS},
{"smooth stone floor",FLOOR, STONE, VAR_1 , TILE_SMOOTH },
{"smooth obsidian floor",FLOOR, OBSIDIAN, VAR_1 , TILE_SMOOTH },
{"smooth featstone? floor",FLOOR, FEATSTONE, VAR_1 , TILE_SMOOTH },
{"smooth vein floor",FLOOR, VEIN, VAR_1 , TILE_SMOOTH },
{"smooth ice floor",FLOOR, ICE, VAR_1 , TILE_SMOOTH },
{0 ,EMPTY, AIR, VAR_1},
{"grass stair up/down",STAIR_UPDOWN, GRASS, VAR_1},
// 50
{"grass stair down",STAIR_DOWN, GRASS, VAR_1},
{"grass stair up",STAIR_UP, GRASS, VAR_1},
{"grass2 stair up/down",STAIR_UPDOWN, GRASS2, VAR_1},
{"grass2 stair down",STAIR_DOWN, GRASS2, VAR_1},
{"grass2 stair up",STAIR_UP, GRASS2, VAR_1},
{"stone stair up/down",STAIR_UPDOWN, STONE, VAR_1},
{"stone stair down",STAIR_DOWN, STONE, VAR_1},
{"stone stair up",STAIR_UP, STONE, VAR_1},
{"vein stair up/down",STAIR_UPDOWN, VEIN, VAR_1},
{"vein stair down",STAIR_DOWN, VEIN, VAR_1},
// 60
{"vein stair up",STAIR_UP, VEIN, VAR_1},
{"featstone? stair up/down",STAIR_UPDOWN, FEATSTONE, VAR_1},
{"featstone? stair down",STAIR_DOWN, FEATSTONE, VAR_1},
{"featstone? stair up",STAIR_UP, FEATSTONE, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"stone fortification",FORTIFICATION, STONE, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"campfire",FLOOR, CAMPFIRE, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 70
{"fire",FLOOR, FIRE, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"stone pillar",PILLAR, STONE, VAR_1},
//80
{"obsidian pillar",PILLAR, OBSIDIAN, VAR_1},
{"featstone? pillar",PILLAR, FEATSTONE, VAR_1},
{"vein pillar",PILLAR, VEIN, VAR_1},
{"ice pillar",PILLAR, ICE, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"waterfall landing",FLOOR, SOIL, VAR_1, TILE_WATERFALL }, // verify material
// 90
{"river source",FLOOR, SOIL, VAR_1, TILE_RIVER_SOURCE }, // verify material
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 100
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 110
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 120
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 130
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 140
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 150
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 160
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 170
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"cracked stone wall" ,WALL, STONE, VAR_1, TILE_CRACKED },
{"damaged stone wall" ,WALL, STONE, VAR_1, TILE_DAMAGED },
{"worn stone wall" ,WALL, STONE, VAR_1, TILE_WORN },
{0 ,EMPTY, AIR, VAR_1},
// 180
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 190
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 200
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 210
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"stone wall" ,WALL, STONE, VAR_1},
// 220
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 230
{0 ,EMPTY, AIR, VAR_1},
{"sapling" ,SAPLING_OK, SOIL, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"dry grass ramp" ,RAMP, GRASS_DRY, VAR_1},
{"dead grass ramp" ,RAMP, GRASS_DEAD, VAR_1},
{"grass ramp" ,RAMP, GRASS, VAR_1},
{"grass ramp" ,RAMP, GRASS2, VAR_1},
{"stone ramp" ,RAMP, STONE, VAR_1},
{"obsidian ramp" ,RAMP, OBSIDIAN, VAR_1},
{"featstone? ramp" ,RAMP, FEATSTONE, VAR_1},
// 240
{"vein ramp" ,RAMP, VEIN, VAR_1},
{"soil ramp" ,RAMP, SOIL, VAR_1},
{"ashes" ,FLOOR, ASHES, VAR_1},
{"ashes" ,FLOOR, ASHES, VAR_2},
{"ashes" ,FLOOR, ASHES, VAR_3},
{"ice ramp" ,RAMP, ICE, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 250
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"ice floor" ,FLOOR, ICE, VAR_2},
{"ice floor" ,FLOOR, ICE, VAR_3},
// 260
{"ice floor" ,FLOOR, ICE, VAR_4},
{"furrowed soil" ,FLOOR, SOIL, VAR_1},
{"ice floor" ,FLOOR, ICE, VAR_1},
{"semi-molten rock" ,WALL, MAGMA, VAR_1},// unminable magma wall
{"magma" ,FLOOR, MAGMA, VAR_1},
{"soil wall" ,WALL, SOIL, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"glowing floor" ,FLOOR, CYAN_GLOW, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"smooth obsidian wall RD2",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "--SS--E-" },
// 270
{"smooth obsidian wall R2D",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "--S---EE" },
{"smooth obsidian wall R2U",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "N-----EE" },
{"smooth obsidian wall RU2",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "NN----E-" },
{"smooth obsidian wall L2U",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "N---WW--" },
{"smooth obsidian wall LU2",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "NN--W---" },
{"smooth obsidian wall L2D",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "--S-WW--" },
{"smooth obsidian wall LD2",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "--SSW---" },
{"smooth obsidian wall LRUD",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH ,"N-S-W-E-" },
{"smooth obsidian wall RUD",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "N-S---E-" },
{"smooth obsidian wall LRD",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "--S-W-E-" },
// 280
{"smooth obsidian wall LRU",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "N---W-E-" },
{"smooth obsidian wall LUD",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "N-S-W---" },
{"smooth obsidian wall RD",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "--S---E-" },
{"smooth obsidian wall RU",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "N-----E-" },
{"smooth obsidian wall LU",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "N---W---" },
{"smooth obsidian wall LD",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "--S-W---" },
{"smooth obsidian wall UD",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "N-S-----" },
{"smooth obsidian wall LR",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "----W-E-" },
{"smooth featstone wall RD2",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "--SS--E-" },
{"smooth featstone wall R2D",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "--S---EE" },
// 290
{"smooth featstone wall R2U",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "N-----EE" },
{"smooth featstone wall RU2",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "NN----E-" },
{"smooth featstone wall L2U",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "N---WW--" },
{"smooth featstone wall LU2",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "NN--W---" },
{"smooth featstone wall L2D",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "--S-WW--" },
{"smooth featstone wall LD2",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "--SSW---" },
{"smooth featstone wall LRUD",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH ,"N-S-W-E-" },
{"smooth featstone wall RUD",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "N-S---E-" },
{"smooth featstone wall LRD",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "--S-W-E-" },
{"smooth featstone wall LRU",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "N---W-E-" },
//300
{"smooth featstone wall LUD",WALL,FEATSTONE,VAR_1, TILE_SMOOTH , "N-S-W---" },
{"smooth featstone wall RD",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "--S---E-" },
{"smooth featstone wall RU",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "N-----E-" },
{"smooth featstone wall LU",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "N---W---" },
{"smooth featstone wall LD",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "--S-W---" },
{"smooth featstone wall UD",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "N-S-----" },
{"smooth featstone wall LR",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "----W-E-" },
{"smooth stone wall RD2",WALL,STONE,VAR_1 , TILE_SMOOTH , "--SS--E-" },
{"smooth stone wall R2D",WALL,STONE,VAR_1 , TILE_SMOOTH , "--S---EE" },
{"smooth stone wall R2U",WALL,STONE,VAR_1 , TILE_SMOOTH , "N-----EE" },
//310
{"smooth stone wall RU2",WALL,STONE,VAR_1 , TILE_SMOOTH , "NN----E-" },
{"smooth stone wall L2U",WALL,STONE,VAR_1 , TILE_SMOOTH , "N---WW--" },
{"smooth stone wall LU2",WALL,STONE,VAR_1 , TILE_SMOOTH , "NN--W---" },
{"smooth stone wall L2D",WALL,STONE,VAR_1 , TILE_SMOOTH , "--S-WW--" },
{"smooth stone wall LD2",WALL,STONE,VAR_1 , TILE_SMOOTH , "--SSW---" },
{"smooth stone wall LRUD",WALL,STONE,VAR_1 , TILE_SMOOTH , "N-S-W-E-" },
{"smooth stone wall RUD",WALL,STONE,VAR_1 , TILE_SMOOTH , "N-S---E-" },
{"smooth stone wall LRD",WALL,STONE,VAR_1 , TILE_SMOOTH , "--S-W-E-" },
{"smooth stone wall LRU",WALL,STONE,VAR_1 , TILE_SMOOTH , "N---W-E-" },
{"smooth stone wall LUD",WALL,STONE,VAR_1 , TILE_SMOOTH , "N-S-W---" },
//320
{"smooth stone wall RD",WALL,STONE,VAR_1 , TILE_SMOOTH , "--S---E-" },
{"smooth stone wall RU",WALL,STONE,VAR_1 , TILE_SMOOTH , "N-----E-" },
{"smooth stone wall LU",WALL,STONE,VAR_1 , TILE_SMOOTH , "N---W---" },
{"smooth stone wall LD",WALL,STONE,VAR_1 , TILE_SMOOTH , "--S-W---" },
{"smooth stone wall UD",WALL,STONE,VAR_1 , TILE_SMOOTH , "N-S-----" },
{"smooth stone wall LR",WALL,STONE,VAR_1 , TILE_SMOOTH , "----W-E-" },
{"obsidian fortification",FORTIFICATION,OBSIDIAN,VAR_1},
{"featstone? fortification",FORTIFICATION,FEATSTONE,VAR_1},
{"cracked obsidian wall",WALL,OBSIDIAN,VAR_1, TILE_CRACKED },
{"damaged obsidian wall",WALL,OBSIDIAN,VAR_1, TILE_DAMAGED },
// 330
{"worn obsidian wall",WALL,OBSIDIAN,VAR_1},
{"obsidian wall",WALL,OBSIDIAN,VAR_1},
/*MAPTILE_FEATSTONE_WALL_WORN1,
MAPTILE_FEATSTONE_WALL_WORN2,
MAPTILE_FEATSTONE_WALL_WORN3,
MAPTILE_FEATSTONE_WALL,*/
{"cracked featstone wall",WALL,FEATSTONE,VAR_1, TILE_CRACKED },
{"damaged featstone wall",WALL,FEATSTONE,VAR_1, TILE_DAMAGED },
{"worn featstone wall",WALL,FEATSTONE,VAR_1, TILE_WORN },
{"featstone wall",WALL,FEATSTONE,VAR_1},
{"stone floor",FLOOR,STONE,VAR_1},
{"stone floor",FLOOR,STONE,VAR_2},
{"stone floor",FLOOR,STONE,VAR_3},
{"stone floor",FLOOR,STONE,VAR_4},
// 340
{"obsidian floor",FLOOR,OBSIDIAN,VAR_1},
{"obsidian floor",FLOOR,OBSIDIAN,VAR_2},
{"obsidian floor",FLOOR,OBSIDIAN,VAR_3},
{"obsidian floor",FLOOR,OBSIDIAN,VAR_4},
{"featstone floor 1",FLOOR,FEATSTONE,VAR_1},
{"featstone floor 2",FLOOR,FEATSTONE,VAR_2},
{"featstone floor 3",FLOOR,FEATSTONE,VAR_3},
{"featstone floor 4",FLOOR,FEATSTONE,VAR_4},
{"grass 1",FLOOR,GRASS,VAR_1},
{"grass 2",FLOOR,GRASS,VAR_2},
// 350
{"grass 3",FLOOR,GRASS,VAR_3},
{"grass 4",FLOOR,GRASS,VAR_4},
{"soil floor",FLOOR,SOIL,VAR_1},
{"soil floor",FLOOR,SOIL,VAR_2},
{"soil floor",FLOOR,SOIL,VAR_3},
{"soil floor",FLOOR,SOIL,VAR_4},
{"wet soil floor",FLOOR,SOIL,VAR_1},
{"wet soil floor",FLOOR,SOIL,VAR_2},
{"wet soil floor",FLOOR,SOIL,VAR_3},
{"wet soil floor",FLOOR,SOIL,VAR_4},
// 360
{"ice fortification",FORTIFICATION,ICE,VAR_1},
{"cracked ice wall",WALL,ICE,VAR_1, TILE_CRACKED},
{"damaged ice wall",WALL,ICE,VAR_1, TILE_DAMAGED},
{"worn ice wall",WALL,ICE,VAR_1, TILE_WORN },
{"ice wall",WALL,ICE,VAR_1},
{"river N",FLOOR,SOIL,VAR_1, TILE_RIVER , "N" },
{"river S",FLOOR,SOIL,VAR_1, TILE_RIVER , "S" },
{"river E",FLOOR,SOIL,VAR_1, TILE_RIVER , "E" },
{"river W",FLOOR,SOIL,VAR_1, TILE_RIVER , "W" },
{"river NW",FLOOR,SOIL,VAR_1, TILE_RIVER, "NW"},
//370
{"river NE",FLOOR,SOIL,VAR_1, TILE_RIVER , "NE" },
{"river SW",FLOOR,SOIL,VAR_1, TILE_RIVER , "SW" },
{"river SE",FLOOR,SOIL,VAR_1, TILE_RIVER , "SE" },
{"stream bed N",FLOOR,SOIL,VAR_1, TILE_STREAM , "N" },
{"stream bed S",FLOOR,SOIL,VAR_1, TILE_STREAM , "S" },
{"stream bed E",FLOOR,SOIL,VAR_1, TILE_STREAM , "E" },
{"stream bed W",FLOOR,SOIL,VAR_1, TILE_STREAM , "W" },
{"stream bed NW",FLOOR,SOIL,VAR_1, TILE_STREAM, "NW" },
{"stream bed NE",FLOOR,SOIL,VAR_1, TILE_STREAM, "NE" },
{"stream bed SW",FLOOR,SOIL,VAR_1, TILE_STREAM, "SW" },
// 380
{"stream bed SE",FLOOR,SOIL,VAR_1, TILE_STREAM, "SE" },
{"stream top",FLOOR,SOIL,VAR_1, TILE_STREAM_TOP },
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"dry grass 1",FLOOR,GRASS_DRY,VAR_1},
{"dry grass 2",FLOOR,GRASS_DRY,VAR_2},
{"dry grass 3",FLOOR,GRASS_DRY,VAR_3},
// 390
{"dry grass 4",FLOOR,GRASS_DRY,VAR_4},
{"dead tree",TREE_DEAD,SOIL,VAR_1},
{"dead sapling",SAPLING_DEAD,SOIL,VAR_1},
{"dead shrub",SHRUB_DEAD,SOIL,VAR_1},
{"dead grass 1",FLOOR,GRASS_DEAD,VAR_1},
{"dead grass 2",FLOOR,GRASS_DEAD,VAR_2},
{"dead grass 3",FLOOR,GRASS_DEAD,VAR_3},
{"dead grass 4",FLOOR,GRASS_DEAD,VAR_4},
{"grass B1",FLOOR,GRASS2,VAR_1},
{"grass B2",FLOOR,GRASS2,VAR_2},
// 400
{"grass B3",FLOOR,GRASS2,VAR_3},
{"grass B4",FLOOR,GRASS2,VAR_4},
{"boulder",BOULDER,STONE,VAR_1},
{"obsidian boulder",BOULDER,OBSIDIAN,VAR_1},
{"featstone? boulder",BOULDER,FEATSTONE,VAR_1},
{"pebbles 1",PEBBLES,STONE,VAR_1},
{"pebbles 2",PEBBLES,STONE,VAR_2},
{"pebbles 3",PEBBLES,STONE,VAR_3},
{"pebbles 4",PEBBLES,STONE,VAR_4},
{"obsidian shards",PEBBLES,OBSIDIAN,VAR_1},
// 410
{"obsidian shards",PEBBLES,OBSIDIAN,VAR_2},
{"obsidian shards",PEBBLES,OBSIDIAN,VAR_3},
{"obsidian shards",PEBBLES,OBSIDIAN,VAR_4},
{"featstone? pebbles",PEBBLES,FEATSTONE,VAR_1},
{"featstone? pebbles",PEBBLES,FEATSTONE,VAR_2},
{"featstone? pebbles",PEBBLES,FEATSTONE,VAR_3},
{"featstone? pebbles",PEBBLES,FEATSTONE,VAR_4},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "--SS--E-"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "--S---EE"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N-----EE" },
// 420
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "NN----E-"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N---WW--"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "NN--W---"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "--S-WW--" },
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "--SSW---"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N-S-W-E-"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N-S---E-"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "--S-W-E-"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N---W-E-"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N-S-W---"},
// 430
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "--S---E-"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N-----E-"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N---W---"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "--S-W---"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N-S-----"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "----W-E-"},
{"vein fortification",FORTIFICATION,VEIN,VAR_1},
{"cracked vein wall",WALL,VEIN,VAR_1, TILE_CRACKED },
{"damaged vein wall",WALL,VEIN,VAR_1, TILE_DAMAGED },
{"worn vein wall",WALL,VEIN,VAR_1 , TILE_WORN },
// 440
{"vein wall",WALL,VEIN,VAR_1},
{"vein floor",FLOOR,VEIN,VAR_1},
{"vein floor",FLOOR,VEIN,VAR_2},
{"vein floor",FLOOR,VEIN,VAR_3},
{"vein floor",FLOOR,VEIN,VAR_4},
{"vein boulder",BOULDER,VEIN,VAR_1},
{"vein pebbles",PEBBLES,VEIN,VAR_1},
{"vein pebbles",PEBBLES,VEIN,VAR_2},
{"vein pebbles",PEBBLES,VEIN,VAR_3},
{"vein pebbles",PEBBLES,VEIN,VAR_4},
// 450
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "--SS--E-"},
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "--S---EE" },
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N-----EE" },
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "NN----E-"},
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N---WW--" },
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "NN--W---" },
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "--S-WW--" },
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "--SSW---" },
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N-S-W-E-"},
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N-S---E-" },
// 460
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "--S-W-E-" },
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N---W-E-" },
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N-S-W---"},
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "--S---E-"},
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N-----E-" },
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N---W---" },
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "--S-W---" },
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N-S-----" },
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "----W-E-"},
{0 ,EMPTY, AIR, VAR_1},
// 470
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 480
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 490
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"constructed floor",FLOOR,CONSTRUCTED, VAR_1},
{"constructed fortification",FORTIFICATION,CONSTRUCTED, VAR_1},
{"constructed pillar",PILLAR,CONSTRUCTED, VAR_1},
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "--SS--E-" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "--S---EE" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N-----EE" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "NN----E-" },
// 500
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N---WW--" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "NN--W---" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "--S-WW--" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "--SSW---" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N-S-W-E-" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N-S---E-" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "--S-W-E-" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N---W-E-" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N-S-W---" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "--S---E-" },
// 510
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N-----E-" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N---W---" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "--S-W---" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N-S-----" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "----W-E-" },
{"constructed stair up/down",STAIR_UPDOWN,CONSTRUCTED, VAR_1},
{"constructed stair down",STAIR_DOWN,CONSTRUCTED, VAR_1},
{"constructed stair up",STAIR_UP,CONSTRUCTED, VAR_1},
{"constructed ramp",RAMP,CONSTRUCTED, VAR_1},
{0 ,EMPTY, AIR, VAR_1} // end
};
//set tile class string lookup table (e.g. for printing to user)
#define X(name,comment) #name,
const char * TileClassString[tileclass_count+1] = {
TILECLASS_MACRO
0
const char * TileShapeString[tileshape_count+1] = {
TILESHAPE_MACRO
0
};
#undef X
@ -16,7 +648,7 @@ namespace DFHack {
#define X(name,comment) #name,
const char * TileMaterialString[tilematerial_count+1] = {
TILEMATERIAL_MACRO
0
0
};
#undef X
@ -24,8 +656,46 @@ namespace DFHack {
#define X(name,comment) #name,
const char * TileSpecialString[tilespecial_count+1] = {
TILESPECIAL_MACRO
0
0
};
#undef X
int32_t findSimilarTileType( const int32_t sourceTileType, const TileShape tshape )
{
int32_t tt, maybe=0, match=0;
int value=0, matchv=0;
const TileRow *source = &tileTypeTable[sourceTileType];
#ifdef assert
assert( sourceTileType >=0 && sourceTileType < TILE_TYPE_ARRAY_LENGTH );
#endif
for(tt=0;tt<TILE_TYPE_ARRAY_LENGTH; ++tt)
{
if( tshape == tileTypeTable[tt].shape )
{
//shortcut null entries
if(!tileTypeTable[tt].name) continue;
//Special flag match is absolutely mandatory!
if( source->special != tileTypeTable[tt].special ) continue;
maybe=tt; value=0;
//Material is high-value match
if( tileTypeTable[tt].material == source->material ) value|=8;
//Direction is medium value match
if( tileTypeTable[tt].direction.whole == source->direction.whole ) value|=4;
//Variant is low-value match
if( tileTypeTable[tt].variant == source->variant ) value|=1;
//Check value against last match
if( value>matchv ){
match=tt;
matchv=value;
}
}
}
if( match ) return match;
return sourceTileType;
}
}

@ -53,7 +53,7 @@ int DFHack_isOpenTerrain(int in)
int DFHack_getVegetationType(int in)
{
return DFHack::getVegetationType(in);
return DFHack::tileShape(in);
}
int DFHack_getTileType(int index, TileRow* tPtr)

@ -100,3 +100,8 @@ string MicrosoftSTL::readClassName (uint32_t vptr)
raw.resize(raw.length() - 2);// trim @@ from end
return raw;
}
size_t MicrosoftSTL::writeSTLString(const uint32_t address, const std::string writeString)
{
return 0;
}

@ -161,8 +161,20 @@ namespace DFHack
virtual const std::string readSTLString (uint32_t offset) = 0;
/// read an STL string
virtual size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) = 0;
/// write an STL string
virtual void writeSTLString(const uint32_t address, const std::string writeString) = 0;
/**
* write an STL string
* @return length written
*/
virtual size_t writeSTLString(const uint32_t address, const std::string writeString) = 0;
/**
* attempt to copy a string from source address to target address. may truncate or leak, depending on platform
* @return length copied
*/
virtual size_t copySTLString(const uint32_t address, const uint32_t target)
{
return writeSTLString(target, readSTLString(address));
}
/// read a STL vector
virtual void readSTLVector(const uint32_t address, t_vecTriplet & triplet) = 0;
/// get class name of an object with rtti/type info

@ -35,7 +35,7 @@ namespace DFHack
// tile class -- determines the general shape of the tile
// enum and lookup table for string names created using X macros
#define TILECLASS_MACRO \
#define TILESHAPE_MACRO \
X(EMPTY, "") \
X(WALL, "") \
X(PILLAR, "") \
@ -54,18 +54,18 @@ namespace DFHack
X(SHRUB_OK, "") \
X(BOULDER, "") \
X(PEBBLES, "")
//end TILECLASS_MACRO
//end TILESHAPE_MACRO
//define tile class enum
#define X(name,comment) name,
enum TileClass {
tileclass_invalid=-1,
TILECLASS_MACRO
tileclass_count,
enum TileShape {
tileshape_invalid=-1,
TILESHAPE_MACRO
tileshape_count,
};
#undef X
DFHACK_EXPORT extern const char *TileClassString[];
DFHACK_EXPORT extern const char *TileShapeString[];
#define TILEMATERIAL_MACRO \
X(AIR, "empty" ) \
@ -243,650 +243,22 @@ namespace DFHack
struct TileRow
{
const char * name;
TileClass c;
TileMaterial m;
TileVariant v;
TileSpecial s;
TileDirection d;
TileShape shape;
TileMaterial material;
TileVariant variant;
TileSpecial special;
TileDirection direction;
};
#define TILE_TYPE_ARRAY_LENGTH 520
const TileRow tileTypeTable[TILE_TYPE_ARRAY_LENGTH] =
{
// 0
{"void",EMPTY, AIR, VAR_1},
{"ramp top",RAMP_TOP, AIR, VAR_1},
{"pool",FLOOR, SOIL, VAR_1, TILE_POOL},
{0, EMPTY, AIR, VAR_1},
{0, EMPTY, AIR, VAR_1},
{0, EMPTY, AIR, VAR_1},
{0, EMPTY, AIR, VAR_1},
{0, EMPTY, AIR, VAR_1},
{0, EMPTY, AIR, VAR_1},
{0, EMPTY, AIR, VAR_1},
// 10
{0, EMPTY, AIR, VAR_1},
{0, EMPTY, AIR, VAR_1},
{0, EMPTY, AIR, VAR_1},
{0, EMPTY, AIR, VAR_1},
{0, EMPTY, AIR, VAR_1},
{0, EMPTY, AIR, VAR_1},
{0, EMPTY, AIR, VAR_1},
{0, EMPTY, AIR, VAR_1},
{0, EMPTY, AIR, VAR_1},
{"driftwood stack",FLOOR, DRIFTWOOD, VAR_1},
// 20
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"tree",TREE_OK, SOIL, VAR_1},
{"ice stair up/down",STAIR_UPDOWN, ICE, VAR_1},
{"ice stair down",STAIR_DOWN, ICE, VAR_1},
{"ice stair up",STAIR_UP, ICE, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 30
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"empty space",EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"shrub",SHRUB_OK, SOIL, VAR_1},
{"chasm",FLOOR, AIR, VAR_1, TILE_ENDLESS },
{"obsidian stair up/down",STAIR_UPDOWN, OBSIDIAN, VAR_1},
{"obsidian stair down",STAIR_DOWN, OBSIDIAN, VAR_1},
{"obsidian stair up",STAIR_UP, OBSIDIAN, VAR_1},
{"soil stair up/down",STAIR_UPDOWN, SOIL, VAR_1},
// 40
{"soil stair down",STAIR_DOWN, SOIL, VAR_1},
{"soil stair up",STAIR_UP, SOIL, VAR_1},
{"eerie pit",FLOOR, HFS, VAR_1, TILE_ENDLESS},
{"smooth stone floor",FLOOR, STONE, VAR_1 , TILE_SMOOTH },
{"smooth obsidian floor",FLOOR, OBSIDIAN, VAR_1 , TILE_SMOOTH },
{"smooth featstone? floor",FLOOR, FEATSTONE, VAR_1 , TILE_SMOOTH },
{"smooth vein floor",FLOOR, VEIN, VAR_1 , TILE_SMOOTH },
{"smooth ice floor",FLOOR, ICE, VAR_1 , TILE_SMOOTH },
{0 ,EMPTY, AIR, VAR_1},
{"grass stair up/down",STAIR_UPDOWN, GRASS, VAR_1},
// 50
{"grass stair down",STAIR_DOWN, GRASS, VAR_1},
{"grass stair up",STAIR_UP, GRASS, VAR_1},
{"grass2 stair up/down",STAIR_UPDOWN, GRASS2, VAR_1},
{"grass2 stair down",STAIR_DOWN, GRASS2, VAR_1},
{"grass2 stair up",STAIR_UP, GRASS2, VAR_1},
{"stone stair up/down",STAIR_UPDOWN, STONE, VAR_1},
{"stone stair down",STAIR_DOWN, STONE, VAR_1},
{"stone stair up",STAIR_UP, STONE, VAR_1},
{"vein stair up/down",STAIR_UPDOWN, VEIN, VAR_1},
{"vein stair down",STAIR_DOWN, VEIN, VAR_1},
// 60
{"vein stair up",STAIR_UP, VEIN, VAR_1},
{"featstone? stair up/down",STAIR_UPDOWN, FEATSTONE, VAR_1},
{"featstone? stair down",STAIR_DOWN, FEATSTONE, VAR_1},
{"featstone? stair up",STAIR_UP, FEATSTONE, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"stone fortification",FORTIFICATION, STONE, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"campfire",FLOOR, CAMPFIRE, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 70
{"fire",FLOOR, FIRE, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"stone pillar",PILLAR, STONE, VAR_1},
//80
{"obsidian pillar",PILLAR, OBSIDIAN, VAR_1},
{"featstone? pillar",PILLAR, FEATSTONE, VAR_1},
{"vein pillar",PILLAR, VEIN, VAR_1},
{"ice pillar",PILLAR, ICE, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"waterfall landing",FLOOR, SOIL, VAR_1, TILE_WATERFALL }, // verify material
// 90
{"river source",FLOOR, SOIL, VAR_1, TILE_RIVER_SOURCE }, // verify material
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 100
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 110
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 120
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 130
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 140
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 150
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 160
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 170
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"cracked stone wall" ,WALL, STONE, VAR_1, TILE_CRACKED },
{"damaged stone wall" ,WALL, STONE, VAR_1, TILE_DAMAGED },
{"worn stone wall" ,WALL, STONE, VAR_1, TILE_WORN },
{0 ,EMPTY, AIR, VAR_1},
// 180
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 190
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 200
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 210
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"stone wall" ,WALL, STONE, VAR_1},
// 220
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 230
{0 ,EMPTY, AIR, VAR_1},
{"sapling" ,SAPLING_OK, SOIL, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"dry grass ramp" ,RAMP, GRASS_DRY, VAR_1},
{"dead grass ramp" ,RAMP, GRASS_DEAD, VAR_1},
{"grass ramp" ,RAMP, GRASS, VAR_1},
{"grass ramp" ,RAMP, GRASS2, VAR_1},
{"stone ramp" ,RAMP, STONE, VAR_1},
{"obsidian ramp" ,RAMP, OBSIDIAN, VAR_1},
{"featstone? ramp" ,RAMP, FEATSTONE, VAR_1},
// 240
{"vein ramp" ,RAMP, VEIN, VAR_1},
{"soil ramp" ,RAMP, SOIL, VAR_1},
{"ashes" ,FLOOR, ASHES, VAR_1},
{"ashes" ,FLOOR, ASHES, VAR_2},
{"ashes" ,FLOOR, ASHES, VAR_3},
{"ice ramp" ,RAMP, ICE, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 250
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"ice floor" ,FLOOR, ICE, VAR_2},
{"ice floor" ,FLOOR, ICE, VAR_3},
// 260
{"ice floor" ,FLOOR, ICE, VAR_4},
{"furrowed soil" ,FLOOR, SOIL, VAR_1},
{"ice floor" ,FLOOR, ICE, VAR_1},
{"semi-molten rock" ,WALL, MAGMA, VAR_1},// unminable magma wall
{"magma" ,FLOOR, MAGMA, VAR_1},
{"soil wall" ,WALL, SOIL, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"glowing floor" ,FLOOR, CYAN_GLOW, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"smooth obsidian wall RD2",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "--SS--E-" },
// 270
{"smooth obsidian wall R2D",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "--S---EE" },
{"smooth obsidian wall R2U",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "N-----EE" },
{"smooth obsidian wall RU2",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "NN----E-" },
{"smooth obsidian wall L2U",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "N---WW--" },
{"smooth obsidian wall LU2",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "NN--W---" },
{"smooth obsidian wall L2D",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "--S-WW--" },
{"smooth obsidian wall LD2",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "--SSW---" },
{"smooth obsidian wall LRUD",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH ,"N-S-W-E-" },
{"smooth obsidian wall RUD",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "N-S---E-" },
{"smooth obsidian wall LRD",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "--S-W-E-" },
// 280
{"smooth obsidian wall LRU",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "N---W-E-" },
{"smooth obsidian wall LUD",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "N-S-W---" },
{"smooth obsidian wall RD",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "--S---E-" },
{"smooth obsidian wall RU",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "N-----E-" },
{"smooth obsidian wall LU",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "N---W---" },
{"smooth obsidian wall LD",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "--S-W---" },
{"smooth obsidian wall UD",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "N-S-----" },
{"smooth obsidian wall LR",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "----W-E-" },
{"smooth featstone wall RD2",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "--SS--E-" },
{"smooth featstone wall R2D",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "--S---EE" },
// 290
{"smooth featstone wall R2U",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "N-----EE" },
{"smooth featstone wall RU2",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "NN----E-" },
{"smooth featstone wall L2U",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "N---WW--" },
{"smooth featstone wall LU2",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "NN--W---" },
{"smooth featstone wall L2D",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "--S-WW--" },
{"smooth featstone wall LD2",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "--SSW---" },
{"smooth featstone wall LRUD",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH ,"N-S-W-E-" },
{"smooth featstone wall RUD",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "N-S---E-" },
{"smooth featstone wall LRD",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "--S-W-E-" },
{"smooth featstone wall LRU",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "N---W-E-" },
//300
{"smooth featstone wall LUD",WALL,FEATSTONE,VAR_1, TILE_SMOOTH , "N-S-W---" },
{"smooth featstone wall RD",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "--S---E-" },
{"smooth featstone wall RU",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "N-----E-" },
{"smooth featstone wall LU",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "N---W---" },
{"smooth featstone wall LD",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "--S-W---" },
{"smooth featstone wall UD",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "N-S-----" },
{"smooth featstone wall LR",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "----W-E-" },
{"smooth stone wall RD2",WALL,STONE,VAR_1 , TILE_SMOOTH , "--SS--E-" },
{"smooth stone wall R2D",WALL,STONE,VAR_1 , TILE_SMOOTH , "--S---EE" },
{"smooth stone wall R2U",WALL,STONE,VAR_1 , TILE_SMOOTH , "N-----EE" },
//310
{"smooth stone wall RU2",WALL,STONE,VAR_1 , TILE_SMOOTH , "NN----E-" },
{"smooth stone wall L2U",WALL,STONE,VAR_1 , TILE_SMOOTH , "N---WW--" },
{"smooth stone wall LU2",WALL,STONE,VAR_1 , TILE_SMOOTH , "NN--W---" },
{"smooth stone wall L2D",WALL,STONE,VAR_1 , TILE_SMOOTH , "--S-WW--" },
{"smooth stone wall LD2",WALL,STONE,VAR_1 , TILE_SMOOTH , "--SSW---" },
{"smooth stone wall LRUD",WALL,STONE,VAR_1 , TILE_SMOOTH , "N-S-W-E-" },
{"smooth stone wall RUD",WALL,STONE,VAR_1 , TILE_SMOOTH , "N-S---E-" },
{"smooth stone wall LRD",WALL,STONE,VAR_1 , TILE_SMOOTH , "--S-W-E-" },
{"smooth stone wall LRU",WALL,STONE,VAR_1 , TILE_SMOOTH , "N---W-E-" },
{"smooth stone wall LUD",WALL,STONE,VAR_1 , TILE_SMOOTH , "N-S-W---" },
//320
{"smooth stone wall RD",WALL,STONE,VAR_1 , TILE_SMOOTH , "--S---E-" },
{"smooth stone wall RU",WALL,STONE,VAR_1 , TILE_SMOOTH , "N-----E-" },
{"smooth stone wall LU",WALL,STONE,VAR_1 , TILE_SMOOTH , "N---W---" },
{"smooth stone wall LD",WALL,STONE,VAR_1 , TILE_SMOOTH , "--S-W---" },
{"smooth stone wall UD",WALL,STONE,VAR_1 , TILE_SMOOTH , "N-S-----" },
{"smooth stone wall LR",WALL,STONE,VAR_1 , TILE_SMOOTH , "----W-E-" },
{"obsidian fortification",FORTIFICATION,OBSIDIAN,VAR_1},
{"featstone? fortification",FORTIFICATION,FEATSTONE,VAR_1},
{"cracked obsidian wall",WALL,OBSIDIAN,VAR_1, TILE_CRACKED },
{"damaged obsidian wall",WALL,OBSIDIAN,VAR_1, TILE_DAMAGED },
// 330
{"worn obsidian wall",WALL,OBSIDIAN,VAR_1},
{"obsidian wall",WALL,OBSIDIAN,VAR_1},
/*MAPTILE_FEATSTONE_WALL_WORN1,
MAPTILE_FEATSTONE_WALL_WORN2,
MAPTILE_FEATSTONE_WALL_WORN3,
MAPTILE_FEATSTONE_WALL,*/
{"cracked featstone wall",WALL,FEATSTONE,VAR_1, TILE_CRACKED },
{"damaged featstone wall",WALL,FEATSTONE,VAR_1, TILE_DAMAGED },
{"worn featstone wall",WALL,FEATSTONE,VAR_1, TILE_WORN },
{"featstone wall",WALL,FEATSTONE,VAR_1},
{"stone floor",FLOOR,STONE,VAR_1},
{"stone floor",FLOOR,STONE,VAR_2},
{"stone floor",FLOOR,STONE,VAR_3},
{"stone floor",FLOOR,STONE,VAR_4},
// 340
{"obsidian floor",FLOOR,OBSIDIAN,VAR_1},
{"obsidian floor",FLOOR,OBSIDIAN,VAR_2},
{"obsidian floor",FLOOR,OBSIDIAN,VAR_3},
{"obsidian floor",FLOOR,OBSIDIAN,VAR_4},
{"featstone floor 1",FLOOR,FEATSTONE,VAR_1},
{"featstone floor 2",FLOOR,FEATSTONE,VAR_2},
{"featstone floor 3",FLOOR,FEATSTONE,VAR_3},
{"featstone floor 4",FLOOR,FEATSTONE,VAR_4},
{"grass 1",FLOOR,GRASS,VAR_1},
{"grass 2",FLOOR,GRASS,VAR_2},
// 350
{"grass 3",FLOOR,GRASS,VAR_3},
{"grass 4",FLOOR,GRASS,VAR_4},
{"soil floor",FLOOR,SOIL,VAR_1},
{"soil floor",FLOOR,SOIL,VAR_2},
{"soil floor",FLOOR,SOIL,VAR_3},
{"soil floor",FLOOR,SOIL,VAR_4},
{"wet soil floor",FLOOR,SOIL,VAR_1},
{"wet soil floor",FLOOR,SOIL,VAR_2},
{"wet soil floor",FLOOR,SOIL,VAR_3},
{"wet soil floor",FLOOR,SOIL,VAR_4},
// 360
{"ice fortification",FORTIFICATION,ICE,VAR_1},
{"cracked ice wall",WALL,ICE,VAR_1, TILE_CRACKED},
{"damaged ice wall",WALL,ICE,VAR_1, TILE_DAMAGED},
{"worn ice wall",WALL,ICE,VAR_1, TILE_WORN },
{"ice wall",WALL,ICE,VAR_1},
{"river N",FLOOR,SOIL,VAR_1, TILE_RIVER , "N" },
{"river S",FLOOR,SOIL,VAR_1, TILE_RIVER , "S" },
{"river E",FLOOR,SOIL,VAR_1, TILE_RIVER , "E" },
{"river W",FLOOR,SOIL,VAR_1, TILE_RIVER , "W" },
{"river NW",FLOOR,SOIL,VAR_1, TILE_RIVER, "NW"},
//370
{"river NE",FLOOR,SOIL,VAR_1, TILE_RIVER , "NE" },
{"river SW",FLOOR,SOIL,VAR_1, TILE_RIVER , "SW" },
{"river SE",FLOOR,SOIL,VAR_1, TILE_RIVER , "SE" },
{"stream bed N",FLOOR,SOIL,VAR_1, TILE_STREAM , "N" },
{"stream bed S",FLOOR,SOIL,VAR_1, TILE_STREAM , "S" },
{"stream bed E",FLOOR,SOIL,VAR_1, TILE_STREAM , "E" },
{"stream bed W",FLOOR,SOIL,VAR_1, TILE_STREAM , "W" },
{"stream bed NW",FLOOR,SOIL,VAR_1, TILE_STREAM, "NW" },
{"stream bed NE",FLOOR,SOIL,VAR_1, TILE_STREAM, "NE" },
{"stream bed SW",FLOOR,SOIL,VAR_1, TILE_STREAM, "SW" },
// 380
{"stream bed SE",FLOOR,SOIL,VAR_1, TILE_STREAM, "SE" },
{"stream top",FLOOR,SOIL,VAR_1, TILE_STREAM_TOP },
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"dry grass 1",FLOOR,GRASS_DRY,VAR_1},
{"dry grass 2",FLOOR,GRASS_DRY,VAR_2},
{"dry grass 3",FLOOR,GRASS_DRY,VAR_3},
// 390
{"dry grass 4",FLOOR,GRASS_DRY,VAR_4},
{"dead tree",TREE_DEAD,SOIL,VAR_1},
{"dead sapling",SAPLING_DEAD,SOIL,VAR_1},
{"dead shrub",SHRUB_DEAD,SOIL,VAR_1},
{"dead grass 1",FLOOR,GRASS_DEAD,VAR_1},
{"dead grass 2",FLOOR,GRASS_DEAD,VAR_2},
{"dead grass 3",FLOOR,GRASS_DEAD,VAR_3},
{"dead grass 4",FLOOR,GRASS_DEAD,VAR_4},
{"grass B1",FLOOR,GRASS2,VAR_1},
{"grass B2",FLOOR,GRASS2,VAR_2},
// 400
{"grass B3",FLOOR,GRASS2,VAR_3},
{"grass B4",FLOOR,GRASS2,VAR_4},
{"boulder",BOULDER,STONE,VAR_1},
{"obsidian boulder",BOULDER,OBSIDIAN,VAR_1},
{"featstone? boulder",BOULDER,FEATSTONE,VAR_1},
{"pebbles 1",PEBBLES,STONE,VAR_1},
{"pebbles 2",PEBBLES,STONE,VAR_2},
{"pebbles 3",PEBBLES,STONE,VAR_3},
{"pebbles 4",PEBBLES,STONE,VAR_4},
{"obsidian shards",PEBBLES,OBSIDIAN,VAR_1},
// 410
{"obsidian shards",PEBBLES,OBSIDIAN,VAR_2},
{"obsidian shards",PEBBLES,OBSIDIAN,VAR_3},
{"obsidian shards",PEBBLES,OBSIDIAN,VAR_4},
{"featstone? pebbles",PEBBLES,FEATSTONE,VAR_1},
{"featstone? pebbles",PEBBLES,FEATSTONE,VAR_2},
{"featstone? pebbles",PEBBLES,FEATSTONE,VAR_3},
{"featstone? pebbles",PEBBLES,FEATSTONE,VAR_4},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "--SS--E-"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "--S---EE"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N-----EE" },
extern DFHACK_EXPORT const TileRow tileTypeTable[];
// 420
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "NN----E-"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N---WW--"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "NN--W---"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "--S-WW--" },
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "--SSW---"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N-S-W-E-"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N-S---E-"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "--S-W-E-"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N---W-E-"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N-S-W---"},
// 430
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "--S---E-"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N-----E-"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N---W---"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "--S-W---"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N-S-----"},
{"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "----W-E-"},
{"vein fortification",FORTIFICATION,VEIN,VAR_1},
{"cracked vein wall",WALL,VEIN,VAR_1, TILE_CRACKED },
{"damaged vein wall",WALL,VEIN,VAR_1, TILE_DAMAGED },
{"worn vein wall",WALL,VEIN,VAR_1 , TILE_WORN },
// 440
{"vein wall",WALL,VEIN,VAR_1},
{"vein floor",FLOOR,VEIN,VAR_1},
{"vein floor",FLOOR,VEIN,VAR_2},
{"vein floor",FLOOR,VEIN,VAR_3},
{"vein floor",FLOOR,VEIN,VAR_4},
{"vein boulder",BOULDER,VEIN,VAR_1},
{"vein pebbles",PEBBLES,VEIN,VAR_1},
{"vein pebbles",PEBBLES,VEIN,VAR_2},
{"vein pebbles",PEBBLES,VEIN,VAR_3},
{"vein pebbles",PEBBLES,VEIN,VAR_4},
// 450
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "--SS--E-"},
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "--S---EE" },
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N-----EE" },
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "NN----E-"},
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N---WW--" },
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "NN--W---" },
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "--S-WW--" },
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "--SSW---" },
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N-S-W-E-"},
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N-S---E-" },
// 460
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "--S-W-E-" },
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N---W-E-" },
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N-S-W---"},
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "--S---E-"},
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N-----E-" },
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N---W---" },
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "--S-W---" },
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N-S-----" },
{"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "----W-E-"},
{0 ,EMPTY, AIR, VAR_1},
// 470
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 480
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
// 490
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{0 ,EMPTY, AIR, VAR_1},
{"constructed floor",FLOOR,CONSTRUCTED, VAR_1},
{"constructed fortification",FORTIFICATION,CONSTRUCTED, VAR_1},
{"constructed pillar",PILLAR,CONSTRUCTED, VAR_1},
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "--SS--E-" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "--S---EE" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N-----EE" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "NN----E-" },
// 500
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N---WW--" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "NN--W---" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "--S-WW--" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "--SSW---" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N-S-W-E-" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N-S---E-" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "--S-W-E-" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N---W-E-" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N-S-W---" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "--S---E-" },
// 510
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N-----E-" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N---W---" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "--S-W---" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N-S-----" },
{"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "----W-E-" },
{"constructed stair up/down",STAIR_UPDOWN,CONSTRUCTED, VAR_1},
{"constructed stair down",STAIR_DOWN,CONSTRUCTED, VAR_1},
{"constructed stair up",STAIR_UP,CONSTRUCTED, VAR_1},
{"constructed ramp",RAMP,CONSTRUCTED, VAR_1},
{0 ,EMPTY, AIR, VAR_1} // end
};
// tile is missing a floor
inline
bool LowPassable(uint16_t tiletype)
{
switch(DFHack::tileTypeTable[tiletype].c)
switch(DFHack::tileTypeTable[tiletype].shape)
{
case DFHack::EMPTY:
case DFHack::STAIR_DOWN:
@ -902,7 +274,7 @@ namespace DFHack
inline
bool HighPassable(uint16_t tiletype)
{
switch(DFHack::tileTypeTable[tiletype].c)
switch(DFHack::tileTypeTable[tiletype].shape)
{
case DFHack::EMPTY:
case DFHack::STAIR_DOWN:
@ -926,128 +298,115 @@ namespace DFHack
inline
bool FlowPassable(uint16_t tiletype)
{
TileClass tc = tileTypeTable[tiletype].c;
TileShape tc = tileTypeTable[tiletype].shape;
return tc != WALL && tc != PILLAR && tc != TREE_DEAD && tc != TREE_OK;
};
inline
bool isWallTerrain(int in)
bool isWallTerrain(int tiletype)
{
return tileTypeTable[in].c >= WALL && tileTypeTable[in].c <= FORTIFICATION ;
return tileTypeTable[tiletype].shape >= WALL && tileTypeTable[tiletype].shape <= FORTIFICATION ;
}
inline
bool isFloorTerrain(int in)
bool isFloorTerrain(int tiletype)
{
return tileTypeTable[in].c >= FLOOR && tileTypeTable[in].c <= PEBBLES;
return tileTypeTable[tiletype].shape >= FLOOR && tileTypeTable[tiletype].shape <= PEBBLES;
}
inline
bool isRampTerrain(int in)
bool isRampTerrain(int tiletype)
{
return tileTypeTable[in].c == RAMP;
return tileTypeTable[tiletype].shape == RAMP;
}
inline
bool isStairTerrain(int in)
bool isStairTerrain(int tiletype)
{
return tileTypeTable[in].c >= STAIR_UP && tileTypeTable[in].c <= STAIR_UPDOWN;
return tileTypeTable[tiletype].shape >= STAIR_UP && tileTypeTable[tiletype].shape <= STAIR_UPDOWN;
}
inline
bool isOpenTerrain(int in)
bool isOpenTerrain(int tiletype)
{
return tileTypeTable[in].c == EMPTY;
return tileTypeTable[tiletype].shape == EMPTY;
}
inline
int getVegetationType(int in)
const char * tileName(int tiletype)
{
return tileTypeTable[in].c;
return tileTypeTable[tiletype].name;
}
//zilpin: for convenience, when you'll be using the tile information a lot.
inline const
TileRow * getTileTypeP(int in)
inline
TileShape tileShape(int tiletype)
{
if( in<0 || in>=TILE_TYPE_ARRAY_LENGTH ) return 0;
return ( const TileRow * ) &tileTypeTable[in];
return tileTypeTable[tiletype].shape;
}
//zilpin: Find the first tile entry which matches the given search criteria.
//All parameters are optional.
//To omit, use the 'invalid' enum for that type (e.g. tileclass_invalid, tilematerial_invalid, etc)
//For tile directions, pass NULL to omit.
//Returns matching index in tileTypeTable, or -1 if none found.
inline
int32_t findTileType( const TileClass tclass, const TileMaterial tmat, const TileVariant tvar, const TileSpecial tspecial, const TileDirection tdir )
TileSpecial tileSpecial(int tiletype)
{
int32_t tt;
for(tt=0;tt<TILE_TYPE_ARRAY_LENGTH; ++tt){
if( tclass>-1 ) if( tclass != tileTypeTable[tt].c ) continue;
if( tmat>-1 ) if( tmat != tileTypeTable[tt].m ) continue;
if( tvar>-1 ) if( tvar != tileTypeTable[tt].v ) continue;
if( tspecial>-1 ) if( tspecial != tileTypeTable[tt].s ) continue;
if( tdir.whole ) if( tdir.whole != tileTypeTable[tt].d.whole ) continue;
//Match!
return tt;
}
return -1;
return tileTypeTable[tiletype].special;
}
/*
//Convenience version of the above, to pass strings as the direction
inline
int32_t findTileType( const TileClass tclass, const TileMaterial tmat, const TileVariant tvar, const TileSpecial tspecial, const char *tdirStr )
TileVariant tileVariant(int tiletype)
{
if(tdirStr){
TileDirection tdir(tdirStr);
return findTileType(tclass,tmat,tvar,tspecial, tdir );
}else{
return findTileType(tclass,tmat,tvar,tspecial, 0 );
}
return tileTypeTable[tiletype].variant;
}
*/
//zilpin: Find a tile type similar to the one given, but with a different class.
//Useful for tile-editing operations.
//If no match found, returns the sourceType
//Definitely needs improvement for wall directions, etc.
inline
int32_t findSimilarTileType( const int32_t sourceTileType, const TileClass tclass ){
int32_t tt, maybe=0, match=0;
int value=0, matchv=0;
const TileRow *source = &tileTypeTable[sourceTileType];
#ifdef assert
assert( sourceTileType >=0 && sourceTileType < TILE_TYPE_ARRAY_LENGTH );
#endif
for(tt=0;tt<TILE_TYPE_ARRAY_LENGTH; ++tt){
if( tclass == tileTypeTable[tt].c ){
//shortcut null entries
if(!tileTypeTable[tt].name) continue;
TileMaterial tileMaterial(int tiletype)
{
return tileTypeTable[tiletype].material;
}
//Special flag match is absolutely mandatory!
if( source->s != tileTypeTable[tt].s ) continue;
inline
TileDirection tileDirection(int tiletype)
{
return tileTypeTable[tiletype].direction;
}
maybe=tt; value=0;
//Material is high-value match
if( tileTypeTable[tt].m == source->m ) value|=8;
//Direction is medium value match
if( tileTypeTable[tt].d.whole == source->d.whole ) value|=4;
//Variant is low-value match
if( tileTypeTable[tt].v == source->v ) value|=1;
/// Safely access the tile type array.
inline const
TileRow * getTileRow(int tiletype)
{
if( tiletype<0 || tiletype>=TILE_TYPE_ARRAY_LENGTH ) return 0;
return ( const TileRow * ) &tileTypeTable[tiletype];
}
//Check value against last match
if( value>matchv ){
match=tt;
matchv=value;
}
}
/**
* zilpin: Find the first tile entry which matches the given search criteria.
* All parameters are optional.
* To omit, use the 'invalid' enum for that type (e.g. tileclass_invalid, tilematerial_invalid, etc)
* For tile directions, pass NULL to omit.
* @return matching index in tileTypeTable, or -1 if none found.
*/
inline
int32_t findTileType( const TileShape tshape, const TileMaterial tmat, const TileVariant tvar, const TileSpecial tspecial, const TileDirection tdir )
{
int32_t tt;
for(tt=0;tt<TILE_TYPE_ARRAY_LENGTH; ++tt){
if( tshape>-1 ) if( tshape != tileTypeTable[tt].shape ) continue;
if( tmat>-1 ) if( tmat != tileTypeTable[tt].material ) continue;
if( tvar>-1 ) if( tvar != tileTypeTable[tt].variant ) continue;
if( tspecial>-1 ) if( tspecial != tileTypeTable[tt].special ) continue;
if( tdir.whole ) if( tdir.whole != tileTypeTable[tt].direction.whole ) continue;
//Match!
return tt;
}
if( match ) return match;
return sourceTileType;
return -1;
}
/**
* zilpin: Find a tile type similar to the one given, but with a different class.
* Useful for tile-editing operations.
* If no match found, returns the sourceType
*
* @todo Definitely needs improvement for wall directions, etc.
*/
DFHACK_EXPORT int32_t findSimilarTileType( const int32_t sourceTileType, const TileShape tshape );
}

@ -20,8 +20,7 @@ void SquashVeins (DFHack::Maps *m, DFHack::DFCoord bcoord, DFHack::mapblock40d &
for (uint32_t k = 0; k< 16;k++)
{
int16_t tt = mb.tiletypes[k][j];
DFHack::TileMaterial mat = DFHack::tileTypeTable[tt].m;
if(mat == DFHack::VEIN)
if(DFHack::tileMaterial(tt) == DFHack::VEIN)
{
for(int i = (int) veins.size() - 1; i >= 0;i--)
{

@ -341,6 +341,8 @@ namespace DFHack
bool WritePos(const uint32_t index, const t_creature &creature);
bool WriteCiv(const uint32_t index, const int32_t civ);
void CopyNameTo(t_creature &creature, uint32_t address);
private:
struct Private;
Private *d;

@ -119,6 +119,7 @@ public:
std::string getItemDescription(const dfh_item & item, Materials * Materials);
/// get a short name for an item
std::string getItemClass(int32_t index);
std::string getItemClass(const dfh_item & item);
/// read an item, including the extra attributes
bool readItem(uint32_t itemptr, dfh_item & item);
/// write item base (position and flags only = t_item part of dfh_item)

@ -686,3 +686,12 @@ bool Creatures::ReadInventoryPtr(const uint32_t temp, std::vector<uint32_t> & it
item[i] = p->readDWord(citem[i]);
return true;
}
void Creatures::CopyNameTo(t_creature &creature, uint32_t address)
{
Private::t_offsets &offs = d->creatures;
if(d->Ft_basic)
d->d->copyName(creature.origin + offs.name_offset, address);
}

@ -525,6 +525,11 @@ int32_t Items::getItemOwnerID(const DFHack::dfh_item &item)
return -1;
}
std::string Items::getItemClass(const dfh_item & item)
{
return getItemClass(item.matdesc.itemType);
}
std::string Items::getItemClass(int32_t index)
{
std::map<int32_t, ItemDesc *>::iterator it;
@ -584,8 +589,8 @@ std::string Items::getItemDescription(const dfh_item & item, Materials * Materia
/// dump offsets used by accessors of a valid item to a string
std::string Items::dumpAccessors(const dfh_item & item)
{
uint32_t vtable = item.base.vtable;
std::map< uint32_t, ItemDesc* >::const_iterator it = d->descVTable.find(vtable);
ItemDesc * desc = it->second;
return desc->dumpAccessors();
std::map< uint32_t, ItemDesc* >::const_iterator it = d->descVTable.find(item.base.vtable);
if(it != d->descVTable.end())
return it->second->dumpAccessors();
return "crud";
}

@ -25,7 +25,7 @@ distribution.
#include "Internal.h"
#include "PlatformInternal.h"
#include <vector>
#include <string>
using namespace std;
#include "ContextShared.h"
#include "dfhack/modules/WindowIO.h"

@ -56,11 +56,15 @@ namespace DFHack
// names, used by a few other modules.
void readName(t_name & name, uint32_t address);
void copyName(uint32_t address, uint32_t target);
// get the name offsets
bool InitReadNames();
uint32_t name_firstname_offset;
uint32_t name_nickname_offset;
uint32_t name_words_offset;
uint32_t name_parts_offset;
uint32_t name_language_offset;
uint32_t name_set_offset;
bool namesInited;
ProcessEnumerator* pm;

@ -39,7 +39,7 @@ namespace DFHack {
const std::string readSTLString (uint32_t offset);
size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity);
void writeSTLString(const uint32_t address, const std::string writeString){};
size_t writeSTLString(const uint32_t address, const std::string writeString);
// get class name of an object with rtti/type info
std::string readClassName(uint32_t vptr);
};

@ -70,7 +70,7 @@ namespace DFHack
const std::string readSTLString (uint32_t offset);
size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity);
void writeSTLString(const uint32_t address, const std::string writeString);
size_t writeSTLString(const uint32_t address, const std::string writeString);
void readSTLVector(const uint32_t address, t_vecTriplet & triplet);
// get class name of an object with rtti/type info

@ -35,8 +35,7 @@ DFHACK_TOOL(dfdigger2 digger2.cpp)
# itemdesignator - change some item designations (dump, forbid, on-fire) for all
# items of a given type and material
# Author: belal
# FIXME: turned off. there is no reliable Items module.
#DFHACK_TOOL(dfitemdesignator itemdesignator.cpp)
DFHACK_TOOL(dfitemdesignator itemdesignator.cpp)
# catsplosion - Accelerates pregnancy
# Author: Zhentar
@ -93,7 +92,7 @@ DFHACK_TOOL(dfcreaturemanager creaturemanager.cpp)
# Dig a specific pattern (in this case 3x3 bedrooms, modify as you like)
DFHACK_TOOL(dfdigpattern digpattern.cpp)
DFHACK_TOOL(dfcleanowned cleanowned.cpp)
DFHACK_TOOL(dffixbug-3708 fix-3708.cpp)
# this needs the C bindings
IF(BUILD_DFHACK_C_BINDINGS)

@ -38,7 +38,8 @@ void sort(int32_t &a,int32_t &b)
a = c;
}
}
void printVecOfVec(ostream &out, vector<vector<vector<string> > >vec,char sep){
void printVecOfVec(ostream &out, vector<vector<vector<string> > >vec,char sep)
{
for(int k=0;k<vec.size();k++){
for(int i =0;i<vec[k].size();i++){
for(int j=0;j<vec[k][i].size();j++){
@ -180,22 +181,24 @@ int main (int numargs, const char ** args)
while(1){
int32_t cx1,cy1,cz1;
cx1 = -30000;
while(cx1 == -30000){
while(cx1 == -30000)
{
DF->ForceResume();
cout << "Set cursor at first position, then press any key";
cin.ignore();
DF->Suspend();
Gui->getCursorCoords(cx1,cy1,cz1);
}
uint32_t tx1,ty1,tz1;
tx1 = cx1/16;
ty1 = cy1/16;
tz1 = cz1;
int32_t cx2,cy2,cz2;
cx2 = -30000;
while(cx2 == -30000){
while(cx2 == -30000)
{
DF->Resume();
cout << "Set cursor at second position, then press any key";
cin.ignore();
@ -254,12 +257,36 @@ int main (int numargs, const char ** args)
for(int xx = xstart; xx <= xend;xx++)
{
int xidx = xx+(16*(x-tx1)-(cx1%16));
if(DFHack::isOpenTerrain(block.tiletypes[xx][yy]) || DFHack::isFloorTerrain(block.tiletypes[xx][yy])) {dig[zidx][yidx][xidx] = "d";}
else if(DFHack::STAIR_DOWN == DFHack::tileTypeTable[block.tiletypes[xx][yy]].c){ dig [zidx][yidx][xidx] = "j"; build [zidx][yidx][xidx] = "Cd";}
else if(DFHack::STAIR_UP == DFHack::tileTypeTable[block.tiletypes[xx][yy]].c){ dig [zidx][yidx][xidx] = "u"; build [zidx][yidx][xidx] = "Cu";}
else if(DFHack::STAIR_UPDOWN == DFHack::tileTypeTable[block.tiletypes[xx][yy]].c){ dig [zidx][yidx][xidx] = "i"; build [zidx][yidx][xidx] = "Cx";}
else if(DFHack::isRampTerrain(block.tiletypes[xx][yy])){dig [zidx][yidx][xidx] = "r";build [zidx][yidx][xidx] = "Cr";}
else if(DFHack::isWallTerrain(block.tiletypes[xx][yy])){build [zidx][yidx][xidx] = "Cw";}
int16_t tt = block.tiletypes[xx][yy];
DFHack::TileShape ts = DFHack::tileShape(tt);
if(DFHack::isOpenTerrain(tt) || DFHack::isFloorTerrain(tt))
{
dig[zidx][yidx][xidx] = "d";
}
else if(DFHack::STAIR_DOWN == ts)
{
dig [zidx][yidx][xidx] = "j";
build [zidx][yidx][xidx] = "Cd";
}
else if(DFHack::STAIR_UP == ts)
{
dig [zidx][yidx][xidx] = "u";
build [zidx][yidx][xidx] = "Cu";
}
else if(DFHack::STAIR_UPDOWN == ts)
{
dig [zidx][yidx][xidx] = "i";
build [zidx][yidx][xidx] = "Cx";
}
else if(DFHack::isRampTerrain(tt))
{
dig [zidx][yidx][xidx] = "r";
build [zidx][yidx][xidx] = "Cr";
}
else if(DFHack::isWallTerrain(tt))
{
build [zidx][yidx][xidx] = "Cw";
}
}
yidx++;
}

@ -165,7 +165,7 @@ int dig(DFHack::Maps* Maps,
{
if (/*designations[lx][ly].bits.hidden == 0 && */
designations[lx][ly].bits.dig == 0 &&
vec_count(targets, DFHack::tileTypeTable[tiles[lx][ly]].c) > 0)
vec_count(targets, DFHack::tileShape(tiles[lx][ly])) > 0)
{
DigTarget dt(
x, y, z,

@ -26,7 +26,8 @@ using namespace std;
#define BLOCK_SIZE 16
void dig(DFHack::Maps* layers, DFHack::Gui* Gui, ::std::vector< ::std::string >& dig_map, bool verbose = false) {
void dig(DFHack::Maps* layers, DFHack::Gui* Gui, ::std::vector< ::std::string >& dig_map, bool verbose = false)
{
int32_t x_cent;
int32_t y_cent;
int32_t z_cent;
@ -63,7 +64,8 @@ void dig(DFHack::Maps* layers, DFHack::Gui* Gui, ::std::vector< ::std::string >&
int32_t x = 0;
::std::string::iterator chr_it;
for (chr_it = str_it->begin(); chr_it != str_it ->end(); ++chr_it) {
for (chr_it = str_it->begin(); chr_it != str_it ->end(); ++chr_it)
{
int32_t x_grid = (x_from + x) / BLOCK_SIZE;
int32_t y_grid = (y_from + y) / BLOCK_SIZE;
int32_t z_grid = z_from + z;
@ -71,41 +73,44 @@ void dig(DFHack::Maps* layers, DFHack::Gui* Gui, ::std::vector< ::std::string >&
int32_t y_locl = (y_from + y) - y_grid * BLOCK_SIZE;
int32_t z_locl = 0;
if (x_grid >= 0 && y_grid >= 0 && x_grid < x_max && y_grid < y_max) {
if (x_grid >= 0 && y_grid >= 0 && x_grid < x_max && y_grid < y_max)
{
// TODO this could probably be made much better, theres a big chance the trees are on the same grid
layers->ReadDesignations(x_grid, y_grid, z_grid, &designations);
layers->ReadTileTypes(x_grid, y_grid, z_grid, &tiles);
// ::std::cout << ::std::hex << "designations: " << designations[x_locl][y_locl].bits.dig << ::std::dec << ::std::endl;
if (designations[x_locl][y_locl].bits.dig == DFHack::designation_no && DFHack::tileTypeTable[tiles[x_locl][y_locl]].c == DFHack::WALL) {
DFHack::e_designation type = DFHack::designation_no;
switch ((char) *chr_it) {
DFHack::naked_designation & des = designations[x_locl][y_locl].bits;
if ( DFHack::tileShape(tiles[x_locl][y_locl]) == DFHack::WALL)
{
switch ((char) *chr_it)
{
case 'd':
designations[x_locl][y_locl].bits.dig = DFHack::designation_default;
des.dig = DFHack::designation_default;
break;
case 'u':
designations[x_locl][y_locl].bits.dig = DFHack::designation_u_stair;
des.dig = DFHack::designation_u_stair;
break;
case 'j':
designations[x_locl][y_locl].bits.dig = DFHack::designation_d_stair;
des.dig = DFHack::designation_d_stair;
break;
case 'i':
designations[x_locl][y_locl].bits.dig = DFHack::designation_ud_stair;
des.dig = DFHack::designation_ud_stair;
break;
case 'h':
designations[x_locl][y_locl].bits.dig = DFHack::designation_channel;
des.dig = DFHack::designation_channel;
break;
case 'r':
designations[x_locl][y_locl].bits.dig = DFHack::designation_ramp;
des.dig = DFHack::designation_ramp;
break;
case 'x':
designations[x_locl][y_locl].bits.dig = DFHack::designation_no;
des.dig = DFHack::designation_no;
break;
}
if (verbose) {
// ::std::cout << "designating " << (char) *chr_it << " at " << x_from + x << " " << y_from + y << " " << z_from + z << ::std::endl;
if (verbose)
{
::std::cout << "designating " << (char) *chr_it << " at " << x_from + x << " " << y_from + y << " " << z_from + z << ::std::endl;
}
layers->WriteDesignations(x_grid, y_grid, z_grid, &designations);

@ -0,0 +1,217 @@
/* Fixes bug 3708 (Ghosts that can't be engraved on a slab).
Cause of the bug:
In order to be engraved on a slab, the creature must be
a historical figure, i.e. be in the historical figure list
of the Legends mode. It seems that caravan guards are not
added to that list until they do something notable, e.g.
kill a goblin. Unfortunately, their own death doesn't
trigger this sometimes.
Solution:
Steal a historical figure entry from a dead goblin, by
replacing the IDs in the structures; also overwrite his
name, race and profession to make the menus make slightly
more sense.
Downsides:
- Obviously, this is an ugly hack.
- The Legends mode still lists the guard as belonging to
the goblin civilization, and killed by whoever killed the
original goblin. There might be other inconsistencies.
Positive sides:
- Avoids messing with tricky creature control code,
by allowing the ghost to be removed naturally.
*/
#include <iostream>
#include <climits>
#include <string.h>
#include <vector>
#include <list>
#include <stdio.h>
using namespace std;
#define DFHACK_WANT_MISCUTILS
#include <DFHack.h>
enum likeType
{
FAIL = 0,
MATERIAL = 1,
ITEM = 2,
FOOD = 3
};
DFHack::Materials * Materials;
DFHack::VersionInfo *mem;
DFHack::Creatures * Creatures = NULL;
void printCreature(DFHack::Context * DF, const DFHack::t_creature & creature)
{
cout << "Address: " << hex << creature.origin << dec << ", creature race: " << Materials->raceEx[creature.race].rawname
<< ", position: " << creature.x << "x " << creature.y << "y "<< creature.z << "z" << endl
<< "Name: " << creature.name.first_name;
if (creature.name.nickname[0])
cout << " `" << creature.name.nickname << "'";
DFHack::Translation * Tran = DF->getTranslation();
cout << " " << Tran->TranslateName(creature.name,false)
<< " (" << Tran->TranslateName(creature.name,true) << ")" << endl;
cout << "Profession: " << mem->getProfession(creature.profession);
if(creature.custom_profession[0])
cout << ", custom: " << creature.custom_profession;
uint32_t dayoflife = creature.birth_year*12*28 + creature.birth_time/1200;
cout << endl
<< "Born on the year " << creature.birth_year
<< ", month " << (creature.birth_time/1200/28)
<< ", day " << ((creature.birth_time/1200) % 28 + 1)
<< ", " << dayoflife << " days lived." << endl << endl;
}
int main (int numargs, char ** args)
{
DFHack::World * World;
DFHack::ContextManager DFMgr("Memory.xml");
DFHack::Context* DF;
try
{
DF = DFMgr.getSingleContext();
DF->Attach();
}
catch (exception& e)
{
cerr << e.what() << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
Creatures = DF->getCreatures();
Materials = DF->getMaterials();
World = DF->getWorld();
DFHack::Translation * Tran = DF->getTranslation();
uint32_t numCreatures;
if(!Creatures->Start(numCreatures))
{
cerr << "Can't get creatures" << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
Materials->ReadCreatureTypes();
Materials->ReadCreatureTypesEx();
mem = DF->getMemoryInfo();
DFHack::Process *p = DF->getProcess();
if(!Tran->Start())
{
cerr << "Can't get name tables" << endl;
return 1;
}
DFHack::OffsetGroup *ogc = mem->getGroup("Creatures")->getGroup("creature");
uint32_t o_flags3 = ogc->getOffset("flags3");
uint32_t o_c_hfid = ogc->getGroup("advanced")->getOffset("hist_figure_id");
std::list<uint32_t> goblins;
std::list<uint32_t> ghosts;
for(uint32_t i = 0; i < numCreatures; i++)
{
DFHack::t_creature temp;
Creatures->ReadCreature(i,temp);
int32_t hfid = p->readDWord(temp.origin + o_c_hfid);
if (hfid > 0) {
if (temp.flags1.bits.dead) {
std::string name = Materials->raceEx[temp.race].rawname;
if (name == "GOBLIN")
goblins.push_back(i);
}
} else {
uint32_t flags3 = p->readDWord(temp.origin + o_flags3);
if (!(flags3 & 0x1000))
continue;
ghosts.push_back(i);
}
}
if (goblins.size() >= ghosts.size() && ghosts.size() > 0)
{
DFHack::OffsetGroup *grp_figures = mem->getGroup("Legends")->getGroup("figures");
uint32_t f_vector = p->readDWord(grp_figures->getAddress("vector"));
uint32_t f_id = grp_figures->getOffset("figure_id");
uint32_t f_unit = grp_figures->getOffset("unit_id");
uint32_t f_name = grp_figures->getOffset("name");
uint32_t f_race = grp_figures->getOffset("race");
uint32_t f_profession = grp_figures->getOffset("profession");
for (std::list<uint32_t>::iterator it = ghosts.begin(); it != ghosts.end(); ++it)
{
int i = *it;
DFHack::t_creature ghost;
Creatures->ReadCreature(i,ghost);
printCreature(DF,ghost);
int igoblin = goblins.front();
goblins.pop_front();
DFHack::t_creature goblin;
Creatures->ReadCreature(igoblin,goblin);
printCreature(DF,goblin);
int32_t hfid = p->readDWord(goblin.origin + o_c_hfid);
uint32_t fptr = p->readDWord(f_vector + 4*hfid);
if (p->readDWord(fptr + f_id) != hfid ||
p->readDWord(fptr + f_unit) != goblin.id ||
p->readWord(fptr + f_race) != goblin.race)
{
cout << "Data structure inconsistency detected, aborting.";
break;
}
if (1) {
p->writeDWord(goblin.origin + o_c_hfid, -1);
p->writeDWord(ghost.origin + o_c_hfid, hfid);
p->writeDWord(fptr + f_unit, ghost.id);
p->writeWord(fptr + f_race, ghost.race);
p->writeWord(fptr + f_profession, ghost.profession);
Creatures->CopyNameTo(ghost, fptr + f_name);
cout << "Pair succesfully patched." << endl << endl;
}
}
}
else
{
cout << "No suitable ghosts, or not enough goblins." << endl;
}
Creatures->Finish();
DF->Detach();
#ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl;
cin.ignore();
#endif
return 0;
}

@ -716,10 +716,10 @@ int main (void)
{
if ( (pattern[x][y]>1) || (roof && pattern[x][y]) )
{
tp = getTileTypeP(block.tiletypes[x][y]);
tp = getTileRow(block.tiletypes[x][y]);
d = &block.designation[x][y];
//Only modify this level if it's 'empty'
if ( EMPTY != tp->c && RAMP_TOP != tp->c && STAIR_DOWN != tp->c && DFHack::TILE_STREAM_TOP != tp->s)
if ( EMPTY != tp->shape && RAMP_TOP != tp->shape && STAIR_DOWN != tp->shape && DFHack::TILE_STREAM_TOP != tp->special)
{
continue;
}
@ -782,12 +782,12 @@ int main (void)
for (int32_t y=0;y<16;++y)
{
t=0;
tp = getTileTypeP(block.tiletypes[x][y]);
tp = getTileRow(block.tiletypes[x][y]);
d = &block.designation[x][y];
tpat=pattern[x][y];
//Tile type material categories
switch ( tp->m )
switch ( tp->material )
{
case AIR:
++emptycount;
@ -804,7 +804,7 @@ int main (void)
//basicly, ignored.
break;
default:
if ( EMPTY == tp->c || RAMP_TOP == tp->c || STAIR_DOWN == tp->c )
if ( EMPTY == tp->shape || RAMP_TOP == tp->shape || STAIR_DOWN == tp->shape )
{
++emptycount;
}
@ -926,7 +926,7 @@ int main (void)
for (int32_t y=0;!done && y<16;++y)
{
t=0;
tp = getTileTypeP(block.tiletypes[x][y]);
tp = getTileRow(block.tiletypes[x][y]);
d = &block.designation[x][y];
tpat=pattern[x][y];
@ -949,7 +949,7 @@ int main (void)
if ( tpat && tpat!=3 && exposemagma )
{
//Leave certain tiles unchanged.
switch ( tp->m )
switch ( tp->material )
{
case HFS:
case FEATSTONE:
@ -1026,7 +1026,7 @@ int main (void)
case 2:
//Wall.
//First guess based on current material
switch ( tp->m )
switch ( tp->material )
{
case OBSIDIAN:
t=wmagma;
@ -1096,7 +1096,7 @@ int main (void)
if ( aquify )
{
//Only normal stone types can be aquified
if ( tp->m!=MAGMA && tp->m!=FEATSTONE && tp->m!=HFS )
if ( tp->material!=MAGMA && tp->material!=FEATSTONE && tp->material!=HFS )
{
//Only place next to the hole.
//If no hole, place in middle.
@ -1177,7 +1177,7 @@ int main (void)
{
t=floor;
v=floorvar;
tp = getTileTypeP(block.tiletypes[x][y]);
tp = getTileRow(block.tiletypes[x][y]);
d = &block.designation[x][y];
if ( exposehell )
@ -1221,7 +1221,7 @@ int main (void)
}
//Tile material check.
switch ( tp->m )
switch ( tp->material )
{
case OBSIDIAN:
t=340;

@ -1,202 +1,38 @@
// Item dump
// Item designator
#include <iostream>
#include <iomanip>
#include <sstream>
#include <climits>
#include <integers.h>
#include <vector>
using namespace std;
#include <DFTypes.h>
#include <DFHackAPI.h>
#include <DFMemInfo.h>
#include <DFHack.h>
#include <dfhack/DFVector.h>
using namespace DFHack;
struct matGlosses
{
vector<DFHack::t_matgloss> plantMat;
vector<DFHack::t_matgloss> woodMat;
vector<DFHack::t_matgloss> stoneMat;
vector<DFHack::t_matgloss> metalMat;
vector<DFHack::t_matgloss> creatureMat;
};
string getMaterialType(DFHack::t_item item, const string & itemtype,const matGlosses & mat)
{
// plant thread seeds
if(itemtype == "item_plant" || itemtype == "item_thread" || itemtype == "item_seeds" || itemtype == "item_leaves" )
{
if(item.material.type >= 0 && item.material.type < mat.plantMat.size())
{
return mat.plantMat[item.material.type].id;
}
else
{
return "some invalid plant material";
}
}
else if (itemtype == "item_drink") // drinks must have different offset for materials
{
return "Booze or something";
}
// item_skin_raw item_bones item_skull item_fish_raw item_pet item_skin_tanned item_shell
else if(itemtype == "item_skin_raw" ||
itemtype == "item_skin_tanned" ||
itemtype == "item_fish_raw" ||
itemtype == "item_pet" ||
itemtype == "item_shell" ||
itemtype == "item_horn"||
itemtype == "item_skull" ||
itemtype == "item_bones" ||
itemtype == "item_corpse" ||
itemtype == "item_meat"
)
{
if(item.material.type >= 0 && item.material.type < mat.creatureMat.size())
return mat.creatureMat[item.material.type].id;
return "bad material";
}
else if(itemtype == "item_wood")
{
if(item.material.type >= 0 && item.material.type < mat.woodMat.size())
return mat.woodMat[item.material.type].id;
return "bad material";
}
else if(itemtype == "item_bar")
{
if(item.material.type >= 0 && item.material.type < mat.metalMat.size())
return mat.metalMat[item.material.type].id;
return "bad material";
}
else
{
/*
Mat_Wood,
Mat_Stone,
Mat_Metal,
Mat_Plant,
Mat_Leather = 10,
Mat_SilkCloth = 11,
Mat_PlantCloth = 12,
Mat_GreenGlass = 13,
Mat_ClearGlass = 14,
Mat_CrystalGlass = 15,
Mat_Ice = 17,
Mat_Charcoal =18,
Mat_Potash = 19,
Mat_Ashes = 20,
Mat_PearlAsh = 21,
Mat_Soap = 24,
*/
switch (item.material.type)
{
case DFHack::Mat_Wood:
if(item.material.index >= 0 && item.material.index < mat.woodMat.size())
return mat.woodMat[item.material.index].id;
return "bad material";
case DFHack::Mat_Stone:
if(item.material.index >= 0 && item.material.index < mat.stoneMat.size())
return mat.stoneMat[item.material.index].id;
return "bad material";
case DFHack::Mat_Metal:
if(item.material.index >= 0 && item.material.index < mat.metalMat.size())
return mat.metalMat[item.material.index].id;
return "bad material";
//case DFHack::Mat_Plant:
case DFHack::Mat_PlantCloth:
//return mat.plantMat[item.material.index].id;
if(item.material.index >= 0 && item.material.index < mat.plantMat.size())
return string(mat.plantMat[item.material.index].id) + " plant";
return "bad material";
case 3: // bone
if(item.material.index >= 0 && item.material.index < mat.creatureMat.size())
return string(mat.creatureMat[item.material.index].id) + " bone";
return "bad material";
case 25: // fat
if(item.material.index >= 0 && item.material.index < mat.creatureMat.size())
return string(mat.creatureMat[item.material.index].id) + " fat";
return "bad material";
case 23: // tallow
if(item.material.index >= 0 && item.material.index < mat.creatureMat.size())
return string(mat.creatureMat[item.material.index].id) + " tallow";
return "bad material";
case 9: // shell
if(item.material.index >= 0 && item.material.index < mat.creatureMat.size())
return string(mat.creatureMat[item.material.index].id) + " shell";
return "bad material";
case DFHack::Mat_Leather: // really a generic creature material. meat for item_food, leather for item_box...
if(item.material.index >= 0 && item.material.index < mat.creatureMat.size())
return string(mat.creatureMat[item.material.index].id);
return "bad material";
case DFHack::Mat_SilkCloth:
if(item.material.index >= 0 && item.material.index < mat.creatureMat.size())
return string(mat.creatureMat[item.material.index].id) + " silk";
return "bad material";
case DFHack::Mat_Soap:
if(item.material.index >= 0 && item.material.index < mat.creatureMat.size())
return string(mat.creatureMat[item.material.index].id) + " soap";
return "bad material";
case DFHack::Mat_GreenGlass:
return "Green Glass";
case DFHack::Mat_ClearGlass:
return "Clear Glass";
case DFHack::Mat_CrystalGlass:
return "Crystal Glass";
case DFHack::Mat_Ice:
return "Ice";
case DFHack::Mat_Charcoal:
return "Charcoal";
/*case DFHack::Mat_Potash:
return "Potash";*/
case DFHack::Mat_Ashes:
return "Ashes";
case DFHack::Mat_PearlAsh:
return "Pearlash";
default:
cout << "unknown material hit: " << item.material.type << " " << item.material.index << " " << itemtype << endl;
return "Invalid";
}
}
return "Invalid";
}
void printItem(DFHack::t_item item, const string & typeString,const matGlosses & mat)
{
cout << dec << "Item at x:" << item.x << " y:" << item.y << " z:" << item.z << endl;
cout << "Type: " << (int) item.type << " " << typeString << " Address: " << hex << item.origin << endl;
cout << "Material: ";
string itemType = getMaterialType(item,typeString,mat);
cout << itemType << endl;
}
int main ()
{
DFHack::ContextManager DF ("Memory.xml");
DFHack::ContextManager CM ("Memory.xml");
DFHack::Context * DF;
DFHack::VersionInfo *mem;
DFHack::Gui * Gui;
DFHack::Materials * Mats;
DFHack::Items * Items;
cout << "This utility lets you mass-designate items by type and material." << endl
<< "Like set on fire all MICROCLINE item_stone..." << endl
<< "Some unusual combinations might be untested and cause the program to crash..."<< endl
<< "so, watch your step and backup your fort" << endl;
try
{
DF.Attach();
DF = CM.getSingleContext();
DF->Attach();
mem = DF->getMemoryInfo();
Gui = DF->getGui();
Mats = DF->getMaterials();
Mats->ReadAllMaterials();
Items = DF->getItems();
}
catch (exception& e)
{
@ -206,64 +42,27 @@ int main ()
#endif
return 1;
}
DFHack::memory_info *mem = DF.getMemoryInfo();
DF.Suspend();
DF.InitViewAndCursor();
matGlosses mat;
DF.ReadPlantMatgloss(mat.plantMat);
DF.ReadWoodMatgloss(mat.woodMat);
DF.ReadStoneMatgloss(mat.stoneMat);
DF.ReadMetalMatgloss(mat.metalMat);
DF.ReadCreatureMatgloss(mat.creatureMat);
DFHack::Process * p = DF->getProcess();
DFHack::OffsetGroup* itemGroup = mem->getGroup("Items");
unsigned vector_addr = itemGroup->getAddress("items_vector");
DFHack::DfVector <uint32_t> p_items (p, vector_addr);
uint32_t numItems = p_items.size();
// vector <string> objecttypes;
// DF.getClassIDMapping(objecttypes);
uint32_t numItems;
DF.InitReadItems(numItems);
map< string, map<string,vector<uint32_t> > > count;
map< string, map<string,vector< dfh_item > > > itemmap;
map< string, map< string, vector< dfh_item > > >::iterator it1;
int failedItems = 0;
map <string, int > bad_mat_items;
for(uint32_t i=0; i< numItems; i++)
{
DFHack::t_item temp;
DF.ReadItem(i,temp);
if(temp.type != -1) // this should be the case pretty much always
{
string typestr;
mem->resolveClassIDToClassname(temp.type,typestr);
string material = getMaterialType(temp,typestr,mat);
if (material != "Invalid")
{
count[typestr][material].push_back(i);
}
else
{
if(bad_mat_items.count(typestr))
{
int tmp = bad_mat_items[typestr];
tmp ++;
bad_mat_items[typestr] = tmp;
}
else
{
bad_mat_items[typestr] = 1;
}
}
}
}
map< string, int >::iterator it_bad;
if(! bad_mat_items.empty())
{
cout << "Items with badly assigned materials:" << endl;
for(it_bad = bad_mat_items.begin(); it_bad!=bad_mat_items.end();it_bad++)
{
cout << it_bad->first << " : " << it_bad->second << endl;
}
DFHack::dfh_item temp;
Items->readItem(p_items[i],temp);
string typestr = Items->getItemClass(temp);
string material = Mats->getDescription(temp.matdesc);
itemmap[typestr][material].push_back(temp);
}
map< string, map<string,vector<uint32_t> > >::iterator it1;
int i =0;
for(it1 = count.begin(); it1!=count.end();it1++)
for( it1 = itemmap.begin(); it1!=itemmap.end();it1++)
{
cout << i << ": " << it1->first << "\n";
i++;
@ -271,8 +70,7 @@ int main ()
if(i == 0)
{
cout << "No items found" << endl;
DF.FinishReadBuildings();
DF.Detach();
DF->Detach();
return 0;
}
cout << endl << "Select an item type from the list:";
@ -283,14 +81,14 @@ int main ()
ss.str(in);
ss >> number;
int j = 0;
it1 = count.begin();
while(j < number && it1!=count.end())
it1 = itemmap.begin();
while(j < number && it1!=itemmap.end())
{
it1++;
j++;
}
cout << it1->first << "\n";
map<string,vector<uint32_t> >::iterator it2;
map<string,vector<dfh_item> >::iterator it2;
i=0;
for(it2 = it1->second.begin();it2!=it1->second.end();it2++){
cout << i << ":\t" << it2->first << " [" << it2->second.size() << "]" << endl;
@ -302,7 +100,7 @@ int main ()
getline(cin, in);
ss.str(in);
ss >> number2;
decideAgain:
cout << "Select a designation - (d)ump, (f)orbid, (m)melt, set on fi(r)e :" << flush;
string designationType;
@ -310,19 +108,19 @@ int main ()
DFHack::t_itemflags changeFlag = {0};
if(designationType == "d" || designationType == "dump")
{
changeFlag.bits.dump = 1;
changeFlag.dump = 1;
}
else if(designationType == "f" || designationType == "forbid")
{
changeFlag.bits.forbid = 1;
changeFlag.forbid = 1;
}
else if(designationType == "m" || designationType == "melt")
{
changeFlag.bits.melt = 1;
changeFlag.melt = 1;
}
else if(designationType == "r" || designationType == "fire")
{
changeFlag.bits.on_fire = 1;
changeFlag.on_fire = 1;
}
else
{
@ -337,14 +135,11 @@ int main ()
}
for(uint32_t k = 0;k< it2->second.size();k++)
{
DFHack::t_item temp;
DF.ReadItem(it2->second[k],temp);
temp.flags.whole |= changeFlag.whole;
DF.WriteRaw(temp.origin+12,sizeof(uint32_t),(uint8_t *)&temp.flags.whole);
DFHack::dfh_item & t = it2->second[k];
t.base.flags.whole |= changeFlag.whole;
Items->writeItem(t);
}
DF.FinishReadItems();
DF.Detach();
DF->Detach();
#ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl;
cin.ignore();

@ -31,10 +31,10 @@ int main (int argc, char **argv)
//Classes
fprintf(f,"\nTile Type Classes:\n");
for(i=0;i<tileclass_count;++i)
for(i=0;i<tileshape_count;++i)
{
Size[1]=max<size_t>(Size[1],strlen(TileClassString[i]));
fprintf(f,"%4i ; %s\n", i, TileClassString[i] ,0 );
Size[1]=max<size_t>(Size[1],strlen(TileShapeString[i]));
fprintf(f,"%4i ; %s\n", i, TileShapeString[i] ,0 );
}
//Materials
@ -77,11 +77,11 @@ int main (int argc, char **argv)
{
fprintf(f," %*i ; %-*s ; %-*s ; %*c ; %-*s ; %-*s ; %s\n",
Size[0], i,
Size[1], ( tileTypeTable[i].name ? TileClassString[ tileTypeTable[i].c ] : "" ),
Size[2], ( tileTypeTable[i].name ? TileMaterialString[ tileTypeTable[i].m ] : "" ),
Size[3], ( tileTypeTable[i].v ? '0'+tileTypeTable[i].v : ' ' ),
Size[4], ( tileTypeTable[i].s ? TileSpecialString[ tileTypeTable[i].s ] : "" ),
Size[5], ( tileTypeTable[i].d.whole ? tileTypeTable[i].d.getStr() : "" ),
Size[1], ( tileTypeTable[i].name ? TileShapeString[ tileTypeTable[i].shape ] : "" ),
Size[2], ( tileTypeTable[i].name ? TileMaterialString[ tileTypeTable[i].material ] : "" ),
Size[3], ( tileTypeTable[i].variant ? '0'+tileTypeTable[i].variant : ' ' ),
Size[4], ( tileTypeTable[i].special ? TileSpecialString[ tileTypeTable[i].special ] : "" ),
Size[5], ( tileTypeTable[i].direction.whole ? tileTypeTable[i].direction.getStr() : "" ),
( tileTypeTable[i].name ? tileTypeTable[i].name : "" ),
0
);

@ -28,6 +28,9 @@ DFHACK_TOOL(dfpause forcepause.cpp)
# prospector - produces a list of available materials and their quantities
DFHACK_TOOL(dfprospector prospector.cpp)
IF(WIN32)
INSTALL(PROGRAMS dfprospector-all.bat DESTINATION ${DFHACK_BINARY_DESTINATION})
ENDIF()
# vdig - dig the vein under the cursor
DFHACK_TOOL(dfvdig vdig.cpp)
@ -38,6 +41,9 @@ ENDIF()
# cleanmap - removes mud, snow, blood and similar stuff from a map. farmers beware
DFHACK_TOOL(dfcleanmap cleanmap.cpp)
# cleanowned - confiscate items owned by dwarves so they can be atomsmashed/reused/etc.
DFHACK_TOOL(dfcleanowned cleanowned.cpp)
# unstuck - make DF run if something goes wrong with the 'normal' memory access method
DFHACK_TOOL(dfunstuck unstuck.cpp)
@ -63,7 +69,7 @@ DFHACK_TOOL(dfliquids liquids.cpp)
# Solves the problem of unusable items after reclaim by clearing the 'in_job' bit of all items.
# Original author: Quietust
#DFHACK_TOOL(dfcleartask cleartask.cpp)
DFHACK_TOOL(dfcleartask cleartask.cpp)
# position - check the DF window and cursor parameters
DFHACK_TOOL(dfposition position.cpp)

@ -529,7 +529,7 @@ bool findString (SegmentedFinder* s, uint32_t *addr, const char * compare )
bool findStrBuffer (SegmentedFinder* s, uint32_t *addr, const char * compare )
{
if(strcmp((const char *)addr, compare) == 0)
if(memcmp((const char *)addr, compare, strlen(compare)) == 0)
return true;
return false;
}

@ -94,6 +94,8 @@ int main (int argc, char *argv[])
if (!itm.base.flags.owned)
continue;
std::string name = Items->getItemClass(itm.matdesc.itemType);
bool confiscate = false;
bool dump = false;
@ -102,6 +104,12 @@ int main (int argc, char *argv[])
printf("Confiscating a rotten item: \t");
confiscate = true;
}
else if (itm.base.flags.on_ground &&
(name == "food" || name == "meat" || name == "plant"))
{
printf("Confiscating a dropped foodstuff: \t");
confiscate = true;
}
else if (itm.wear_level >= wear_dump_level)
{
printf("Confiscating and dumping a worn item: \t");

@ -55,9 +55,9 @@ int main ()
{
DFHack::t_itemflags flags;
flags.whole = p->readDWord(p_items[i] + 0x0C);
if (flags.bits.in_job)
if (flags.in_job)
{
flags.bits.in_job = 0;
flags.in_job = 0;
p->writeDWord(p_items[i] + 0x0C, flags.whole);
numtasked++;
}

@ -91,7 +91,7 @@ int main (void)
//Only the remove ramp designation (ignore channel designation, etc)
oldT = tiles[tx][ty];
if ( DFHack::designation_default == designations[tx][ty].bits.dig
&& DFHack::RAMP==DFHack::tileTypeTable[oldT].c)
&& DFHack::RAMP==DFHack::tileShape(oldT))
{
//Current tile is a ramp.
//Set current tile, as accurately as can be expected
@ -104,7 +104,7 @@ int main (void)
designations[tx][ty].bits.dig = DFHack::designation_no;
//Check the tile above this one, in case a downward slope needs to be removed.
if ( DFHack::RAMP_TOP == DFHack::tileTypeTable[tilesAbove[tx][ty]].c )
if ( DFHack::RAMP_TOP == DFHack::tileShape(tilesAbove[tx][ty]) )
{
tilesAbove[tx][ty] = 32;
}
@ -112,7 +112,7 @@ int main (void)
++count;
}
// ramp fixer
else if(DFHack::RAMP!=DFHack::tileTypeTable[oldT].c && DFHack::RAMP_TOP == DFHack::tileTypeTable[tilesAbove[tx][ty]].c)
else if(DFHack::RAMP!=DFHack::tileShape(oldT) && DFHack::RAMP_TOP == DFHack::tileShape(tilesAbove[tx][ty]))
{
tilesAbove[tx][ty] = 32;
countbad++;

@ -87,8 +87,7 @@ int main (void)
{
if(!designations[tx][ty].bits.feature_local) continue;
oldT = tiles[tx][ty];
DFHack::TileClass ttype = DFHack::tileTypeTable[oldT].c;
if ( ttype != DFHack::WALL )
if ( DFHack::tileShape(oldT) != DFHack::WALL )
{
//Current tile is not a wall.
//Set current tile, as accurately as can be expected

@ -108,15 +108,17 @@ int main (int numargs, const char ** args)
// tiletype
std::cout <<"tiletype: " << tiletype;
if(tileTypeTable[tiletype].name)
std::cout << " = " << tileTypeTable[tiletype].name << std::endl;
printf("%-10s: %4d %s\n","Class",tileTypeTable[tiletype].c,TileClassString[ tileTypeTable[tiletype].c ]);
printf("%-10s: %4d %s\n","Material",tileTypeTable[tiletype].c,TileMaterialString[ tileTypeTable[tiletype].m ]);
printf("%-10s: %4d %s\n","Special",tileTypeTable[tiletype].c,TileSpecialString[ tileTypeTable[tiletype].s ]);
printf("%-10s: %4d\n","Variant",tileTypeTable[tiletype].v);
printf("%-10s: %s\n","Direction",tileTypeTable[tiletype].d.getStr());
if(tileName(tiletype))
std::cout << " = " << tileName(tiletype) << std::endl;
DFHack::TileShape shape = tileShape(tiletype);
DFHack::TileMaterial material = tileMaterial(tiletype);
DFHack::TileSpecial special = tileSpecial(tiletype);
printf("%-10s: %4d %s\n","Class" ,shape, TileShapeString[ shape ]);
printf("%-10s: %4d %s\n","Material" ,material,TileMaterialString[ material ]);
printf("%-10s: %4d %s\n","Special" ,special, TileSpecialString[ special ]);
printf("%-10s: %4d\n" ,"Variant" ,tileVariant(tiletype));
printf("%-10s: %s\n" ,"Direction",tileDirection(tiletype).getStr());
std::cout << std::endl;
std::cout <<"temperature1: " << mc.temperature1At(cursor) << " U" << std::endl;

@ -19,7 +19,7 @@ using namespace std;
#include <DFHack.h>
#include <dfhack/DFTileTypes.h>
template<template <typename> class P = std::less >
template<template <typename> class P = std::greater >
struct compare_pair_first
{
template<class T1, class T2>
@ -29,7 +29,7 @@ struct compare_pair_first
}
};
template<template <typename> class P = std::less >
template<template <typename> class P = std::greater >
struct compare_pair_second
{
template<class T1, class T2>
@ -42,7 +42,6 @@ struct compare_pair_second
int main (int argc, const char* argv[])
{
bool showhidden = false;
bool showbaselayers = false;
for(int i = 1; i < argc; i++)
{
string test = argv[i];
@ -50,25 +49,21 @@ int main (int argc, const char* argv[])
{
showhidden = true;
}
else if(test == "-b")
else if(test == "--help")
{
showbaselayers = true;
}
else if(test == "-ab" || test == "-ba")
{
showhidden = true;
showbaselayers = true;
cout << "This is a prospector tool for the game Dwarf Fortress." << endl
<< "By default, only visible tiles are counted." << endl
<< "Use the parameter '-a' to scan all tiles." << endl;
return 0;
}
}
// let's be more useful when double-clicked on windows
#ifndef LINUX_BUILD
showhidden = true;
#endif
uint32_t x_max,y_max,z_max;
DFHack::mapblock40d Block;
map <int16_t, uint32_t> materials;
materials.clear();
map <int16_t, uint32_t> hardcoded_m;
map <int16_t, uint32_t> layer_m;
map <int16_t, uint32_t> vein_m;
vector<DFHack::t_feature> global_features;
std::map <DFHack::DFCoord, std::vector<DFHack::t_feature *> > local_features;
@ -133,7 +128,7 @@ int main (int argc, const char* argv[])
}
// get region geology
if(showbaselayers && !Maps->ReadGeology( layerassign ))
if(!Maps->ReadGeology( layerassign ))
{
cerr << "Can't get region geology." << endl;
#ifndef LINUX_BUILD
@ -158,36 +153,94 @@ int main (int argc, const char* argv[])
// read data
Maps->ReadBlock40d(x,y,z, &Block);
//Maps->ReadTileTypes(x,y,z, &tiletypes);
//Maps->ReadDesignations(x,y,z, &designations);
DFHack::tiletypes40d & tt = Block.tiletypes;
memset(tempvein, -1, sizeof(tempvein));
veins.clear();
Maps->ReadVeins(x,y,z,&veins);
// hardcoded materials
for(uint32_t xx = 0;xx<16;xx++)
{
for (uint32_t yy = 0; yy< 16;yy++)
{
DFHack::TileMaterial mat = DFHack::tileMaterial(tt[xx][yy]);
if(!DFHack::isWallTerrain(tt[xx][yy]))
continue;
if(Block.designation[xx][yy].bits.hidden && !showhidden)
continue;
if(hardcoded_m.count(mat))
{
hardcoded_m[mat] += 1;
}
else
{
hardcoded_m[mat] = 1;
}
}
}
if(showbaselayers)
// get the layer materials
for(uint32_t xx = 0;xx<16;xx++)
{
for (uint32_t yy = 0; yy< 16;yy++)
{
DFHack::TileMaterial mat = DFHack::tileMaterial(tt[xx][yy]);
DFHack::TileShape shape = DFHack::TileShape(tt[xx][yy]);
if(mat != DFHack::SOIL && mat != DFHack::STONE)
continue;
if(!DFHack::isWallTerrain(tt[xx][yy]))
continue;
if(Block.designation[xx][yy].bits.hidden && !showhidden)
continue;
uint8_t test = Block.designation[xx][yy].bits.biome;
if(test > maximum_regionoffset)
maximum_regionoffset = test;
if( test >= sizeof(Block.biome_indices))
{
num_overflows++;
continue;
}
uint16_t mat2 = layerassign [Block.biome_indices[test]] [Block.designation[xx][yy].bits.geolayer_index];
if(layer_m.count(mat2))
{
layer_m[mat2] += 1;
}
else
{
layer_m[mat2] = 1;
}
}
}
// global feature overrides
int16_t idx = Block.global_feature;
if( idx != -1 && uint16_t(idx) < global_features.size() && global_features[idx].type == DFHack::feature_Underworld)
{
// get the layer materials
for(uint32_t xx = 0;xx<16;xx++)
for(uint32_t xi = 0 ; xi< 16 ; xi++) for(uint32_t yi = 0 ; yi< 16 ; yi++)
{
for (uint32_t yy = 0; yy< 16;yy++)
if(!DFHack::isWallTerrain(tt[xi][yi]))
continue;
if(Block.designation[xi][yi].bits.hidden && !showhidden)
continue;
DFHack::TileMaterial mat = DFHack::tileMaterial(tt[xi][yi]);
if(Block.designation[xi][yi].bits.feature_global && mat == DFHack::FEATSTONE)
{
uint8_t test = Block.designation[xx][yy].bits.biome;
if(test > maximum_regionoffset)
maximum_regionoffset = test;
if( test >= sizeof(Block.biome_indices))
if(global_features[idx].main_material == 0) // stone
{
num_overflows++;
continue;
int32_t mat2 = global_features[idx].sub_material;
if(layer_m.count(mat2))
{
layer_m[mat2] += 1;
}
else
{
layer_m[mat2] = 1;
}
}
tempvein[xx][yy] =
layerassign
[Block.biome_indices[test]]
[Block.designation[xx][yy].bits.geolayer_index];
}
}
}
// vein stones
memset(tempvein, 0xff, sizeof(tempvein));
veins.clear();
Maps->ReadVeins(x,y,z,&veins);
// for each vein
for(int i = 0; i < (int)veins.size();i++)
{
@ -197,6 +250,9 @@ int main (int argc, const char* argv[])
//iterate through the bits
for (uint32_t k = 0; k< 16;k++)
{
DFHack::TileMaterial mat = DFHack::tileMaterial(tt[k][j]);
if(mat != DFHack::VEIN)
continue;
// and the bit array with a one-bit mask, check if the bit is set
bool set = !!(((1 << k) & veins[i].assignment[j]) >> k);
if(set)
@ -208,26 +264,6 @@ int main (int argc, const char* argv[])
}
}
// global feature overrides
int16_t idx = Block.global_feature;
if( idx != -1 && uint16_t(idx) < global_features.size() && global_features[idx].type == DFHack::feature_Underworld)
{
for(uint32_t xi = 0 ; xi< 16 ; xi++) for(uint32_t yi = 0 ; yi< 16 ; yi++)
{
if(Block.designation[xi][yi].bits.feature_global)
{
if(global_features[idx].main_material == 0) // stone
{
tempvein[xi][yi] = global_features[idx].sub_material;
}
else
{
tempvein[xi][yi] = -1;
}
}
}
}
idx = Block.local_feature;
if( idx != -1 )
{
@ -241,7 +277,8 @@ int main (int argc, const char* argv[])
{
for(uint32_t xi = 0 ; xi< 16 ; xi++) for(uint32_t yi = 0 ; yi< 16 ; yi++)
{
if(Block.designation[xi][yi].bits.feature_local && DFHack::isWallTerrain(Block.tiletypes[xi][yi]))
DFHack::TileMaterial mat = DFHack::tileMaterial(tt[xi][yi]);
if(Block.designation[xi][yi].bits.feature_local && mat == DFHack::FEATSTONE)
{
if(vectr[idx]->main_material == 0) // stone
{
@ -257,25 +294,28 @@ int main (int argc, const char* argv[])
}
}
// count the material types
// count the vein material types
for(uint32_t xi = 0 ; xi< 16 ; xi++)
{
for(uint32_t yi = 0 ; yi< 16 ; yi++)
{
// hidden tiles are ignored unless '-a' is provided on the command line
// non-wall tiles are ignored
if( (Block.designation[xi][yi].bits.hidden && !showhidden) || !DFHack::isWallTerrain(Block.tiletypes[xi][yi]))
if( (Block.designation[xi][yi].bits.hidden && !showhidden)
|| !DFHack::isWallTerrain(Block.tiletypes[xi][yi])
)
continue;
// ignore stuff that isn't a vein
if(tempvein[xi][yi] < 0)
continue;
if(materials.count(tempvein[xi][yi]))
if(vein_m.count(tempvein[xi][yi]))
{
materials[tempvein[xi][yi]] += 1;
vein_m[tempvein[xi][yi]] += 1;
}
else
{
materials[tempvein[xi][yi]] = 1;
vein_m[tempvein[xi][yi]] = 1;
}
}
}
@ -283,16 +323,35 @@ int main (int argc, const char* argv[])
}
}
// print report
cout << "Maximal regionoffset seen: " << maximum_regionoffset << ".";
// some layer/geology debug stuff
if(maximum_regionoffset >= sizeof(Block.biome_indices) )
{
cout << " This is above the regionoffsets array size!" << endl;
cout << "Number of overflows: " << num_overflows;
cerr << "Maximal regionoffset seen: " << maximum_regionoffset << ".";
cerr << " This is above the regionoffsets array size!" << endl;
cerr << "Number of overflows: " << num_overflows;
cerr << endl;
}
cout << endl;
vector <pair <int16_t, uint32_t> > matss;
vector <pair <int16_t, uint32_t> > veins_sort;
vector <pair <int16_t, uint32_t> > layers_sort;
vector <pair <int16_t, uint32_t> > hardcoded_sort;
map<int16_t, uint32_t>::iterator p;
for(p = materials.begin(); p != materials.end(); p++)
// HARDCODED
cout << endl << "Base materials:" << endl;
for(p = hardcoded_m.begin(); p != hardcoded_m.end(); p++)
{
hardcoded_sort.push_back( pair<int16_t,uint32_t>(p->first, p->second) );
}
std::sort(hardcoded_sort.begin(), hardcoded_sort.end(), compare_pair_second<>());
for(size_t i = 0; i < hardcoded_sort.size();i++)
{
cout << DFHack::TileMaterialString[hardcoded_sort[i].first] << " : " << hardcoded_sort[i].second << endl;
}
// LAYERS
cout << endl << "Layer materials:" << endl;
uint32_t layers_total = 0;
for(p = layer_m.begin(); p != layer_m.end(); p++)
{
if(p->first == -1)
{
@ -300,23 +359,54 @@ int main (int argc, const char* argv[])
}
else
{
matss.push_back( pair<int16_t,uint32_t>(p->first, p->second) );
layers_sort.push_back( pair<int16_t,uint32_t>(p->first, p->second) );
layers_total += p->second;
}
}
std::sort(matss.begin(), matss.end(), compare_pair_second<>());
for(size_t i = 0; i < matss.size();i++)
std::sort(layers_sort.begin(), layers_sort.end(), compare_pair_second<>());
for(size_t i = 0; i < layers_sort.size();i++)
{
if(matss[i].first >= Mats->inorganic.size())
if(layers_sort[i].first >= Mats->inorganic.size())
{
cerr << "Error, material out of bounds: " << matss[i].first << endl;
cerr << "Error, material out of bounds: " << layers_sort[i].first << endl;
continue;
}
cout << Mats->inorganic[matss[i].first].id << " : " << matss[i].second << endl;
cout << Mats->inorganic[layers_sort[i].first].id << " : " << layers_sort[i].second << endl;
}
cout << ">>> TOTAL = " << layers_total << endl;
// VEINS
uint32_t veins_total = 0;
cout << endl << "Vein materials:" << endl;
for(p = vein_m.begin(); p != vein_m.end(); p++)
{
if(p->first == -1)
{
cout << "Non-stone" << " : " << p->second << endl;
}
else
{
veins_sort.push_back( pair<int16_t,uint32_t>(p->first, p->second) );
veins_total += p->second;
}
}
std::sort(veins_sort.begin(), veins_sort.end(), compare_pair_second<>());
for(size_t i = 0; i < veins_sort.size();i++)
{
if(veins_sort[i].first >= Mats->inorganic.size())
{
cerr << "Error, material out of bounds: " << veins_sort[i].first << endl;
continue;
}
cout << Mats->inorganic[veins_sort[i].first].id << " : " << veins_sort[i].second << endl;
}
cout << ">>> TOTAL = " << veins_total << endl;
DF->Detach();
cout << endl << "Happy mining!";
#ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl;
cout << " Press any key to finish.";
cin.ignore();
#endif
cout << endl;
return 0;
}

@ -117,7 +117,7 @@ int main (int argc, char* argv[])
{
continue;
}
const TileRow * r = getTileTypeP(tt);
const TileRow * r = getTileRow(tt);
if(!r)
{
cerr << "unknown tiletype! " << dec << tt << endl;
@ -127,8 +127,8 @@ int main (int argc, char* argv[])
bool above = 0;
bool sides = 0;
bool unhide = 1;
// by tile class, determine behavior and action
switch (r->c)
// by tile shape, determine behavior and action
switch (r->shape)
{
// walls:
case WALL:

@ -93,7 +93,7 @@ void putwch(int x, int y, int znak, int color)
void puttile(int x, int y, int tiletype, int color)
{
unsigned int znak;
switch(tileTypeTable[tiletype].c)
switch(tileShape(tiletype))
{
case EMPTY:
znak = ' ';
@ -199,7 +199,7 @@ void clrscr()
*/
int pickColor(int tiletype)
{
switch(tileTypeTable[tiletype].m)
switch(tileMaterial(tiletype))
{
case AIR:
return COLOR_BLACK;
@ -792,8 +792,9 @@ int main(int argc, char *argv[])
{
for(int x = 0; x < 16; x++) for(int y = 0; y < 16; y++)
{
TileClass tc = tileTypeTable[Block->tiletypes[x][y]].c;
TileMaterial tm = tileTypeTable[Block->tiletypes[x][y]].m;
int16_t tiletype = Block->tiletypes[x][y];
TileShape tc = tileShape(tiletype);
TileMaterial tm = tileMaterial(tiletype);
if( tc == WALL && tm == VEIN || tc == TREE_OK || tc == TREE_DEAD)
{
Block->designation[x][y].bits.dig = designation_default;
@ -901,14 +902,6 @@ int main(int argc, char *argv[])
//iterate through the bits
for (uint32_t k = 0; k< 16;k++)
{
/*
if(tileTypeTable[blocks[1][1].tiletypes[k][j]].m != VEIN)
continue;
*/
/*
if(blocks[1][1].designation[k][j].bits.hidden)
continue;
*/
// and the bit array with a one-bit mask, check if the bit is set
bool set = !!(((1 << k) & veinVector[realvein].assignment[j]) >> k);
if(set)