From d5aa1488a600389b48c6b703893cb5f44536b2cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Tue, 6 Apr 2010 13:05:54 +0200 Subject: [PATCH 1/8] Magma create works --- dfhack/include/DFTypes.h | 178 +------------------------------- dfhack/include/modules/Maps.h | 188 +++++++++++++++++++++++++++++++++- examples/veccheck.cpp | 49 ++++++++- output/Memory.xml | 5 + tools/CMakeLists.txt | 4 +- tools/magma_create.cpp | 54 +++++----- 6 files changed, 270 insertions(+), 208 deletions(-) diff --git a/dfhack/include/DFTypes.h b/dfhack/include/DFTypes.h index f9ba70cd5..902684947 100644 --- a/dfhack/include/DFTypes.h +++ b/dfhack/include/DFTypes.h @@ -64,20 +64,7 @@ struct t_vein uint32_t address_of; // this is NOT part of the DF vein, but an address of the vein as seen by DFhack. }; */ -struct t_vein -{ - uint32_t vtable; - int32_t type; - int16_t assignment[16]; - uint32_t flags; - uint32_t address_of; // this is NOT part of the DF vein, but an address of the vein as seen by DFhack. -}; -// stores what tiles should appear when the ice melts -struct t_frozenliquidvein -{ - uint32_t vtable; - int16_t tiles[16][16]; -}; + struct t_matglossPair { @@ -121,10 +108,12 @@ struct t_construction_df40d { int16_t x; int16_t y; + // 4 int16_t z; int16_t unk1; + // 8 int16_t unk2; - t_matglossPair material; // 4B + t_matglossPair material; // C points to the index part // int16_t mat_type; // int16_t mat_idx; }; @@ -695,165 +684,6 @@ struct t_itemType char name[128]; }; - -enum e_traffic -{ - traffic_normal, - traffic_low, - traffic_high, - traffic_restricted -}; - -enum e_designation -{ - designation_no, - designation_default, // dig walls, remove stairs and ramps, gather plants, fell trees - designation_ud_stair, // dig up/down stairs - designation_channel, // dig a channel - designation_ramp, // dig ramp out of a wall - designation_d_stair, // dig a stair down - designation_u_stair, // dig a stair up - designation_7 // whatever -}; - -enum e_liquidtype -{ - liquid_water, - liquid_magma -}; - -struct naked_designation -{ - unsigned int flow_size : 3; // how much liquid is here? - unsigned int pile : 1; // stockpile? - /* - * All the different dig designations... needs more info, probably an enum - */ - e_designation dig : 3; - unsigned int smooth : 2; - unsigned int hidden : 1; - - /* - * This one is rather involved, but necessary to retrieve the base layer matgloss index - * see http://www.bay12games.com/forum/index.php?topic=608.msg253284#msg253284 for details - */ - unsigned int geolayer_index :4; - unsigned int light : 1; - unsigned int subterranean : 1; // never seen the light of day? - unsigned int skyview : 1; // sky is visible now, it rains in here when it rains - - /* - * Probably similar to the geolayer_index. Only with a different set of offsets and different data. - * we don't use this yet - */ - unsigned int biome : 4; - /* - * 0 = water - * 1 = magma - */ - e_liquidtype liquid_type : 1; - unsigned int water_table : 1; // srsly. wtf? - unsigned int rained : 1; // does this mean actual rain (as in the blue blocks) or a wet tile? - e_traffic traffic : 2; // needs enum - unsigned int flow_forbid : 1; // what? - unsigned int liquid_static : 1; - unsigned int moss : 1;// I LOVE MOSS - unsigned int feature_present : 1; // another wtf... is this required for magma pipes to work? - unsigned int liquid_character : 2; // those ripples on streams? -}; - -union t_designation -{ - uint32_t whole; - naked_designation bits; -}; - -// occupancy flags (rat,dwarf,horse,built wall,not build wall,etc) -struct naked_occupancy -{ - unsigned int building : 3;// building type... should be an enum? - // 7 = door - unsigned int unit : 1; - unsigned int unit_grounded : 1; - unsigned int item : 1; - // splatter. everyone loves splatter. - unsigned int mud : 1; - unsigned int vomit :1; - unsigned int broken_arrows_color :4; - unsigned int blood_g : 1; - unsigned int blood_g2 : 1; - unsigned int blood_b : 1; - unsigned int blood_b2 : 1; - unsigned int blood_y : 1; - unsigned int blood_y2 : 1; - unsigned int blood_m : 1; - unsigned int blood_m2 : 1; - unsigned int blood_c : 1; - unsigned int blood_c2 : 1; - unsigned int blood_w : 1; - unsigned int blood_w2 : 1; - unsigned int blood_o : 1; - unsigned int blood_o2 : 1; - unsigned int slime : 1; - unsigned int slime2 : 1; - unsigned int blood : 1; - unsigned int blood2 : 1; - unsigned int broken_arrows_variant : 1; - unsigned int snow : 1; -}; - -struct naked_occupancy_grouped -{ - unsigned int building : 3;// building type... should be an enum? - // 7 = door - unsigned int unit : 1; - unsigned int unit_grounded : 1; - unsigned int item : 1; - // splatter. everyone loves splatter. - unsigned int splatter : 26; -}; - -union t_occupancy -{ - uint32_t whole; - naked_occupancy bits; - naked_occupancy_grouped unibits; -}; - -// map block flags -struct naked_blockflags -{ - unsigned int designated : 1;// designated for jobs (digging and stuff like that) - unsigned int unk_1 : 1; // possibly related to the designated flag - // two flags required for liquid flow. no idea why - unsigned int liquid_1 : 1; - unsigned int liquid_2 : 1; - unsigned int unk_2: 28; // rest of the flags is completely unknown - // there's a possibility that this flags field is shorter than 32 bits -}; - -union t_blockflags -{ - uint32_t whole; - naked_blockflags bits; -}; - -typedef int16_t tiletypes40d [16][16]; -typedef DFHack::t_designation designations40d [16][16]; -typedef DFHack::t_occupancy occupancies40d [16][16]; -typedef uint8_t biome_indices40d [16]; - -typedef struct -{ - tiletypes40d tiletypes; - designations40d designation; - occupancies40d occupancy; - // really a '7', but I use 8 to make it neater :) - biome_indices40d biome_indices; - uint32_t origin; // the address where it came from - t_blockflags blockflags; -} mapblock40d; - struct t_viewscreen { int32_t type; diff --git a/dfhack/include/modules/Maps.h b/dfhack/include/modules/Maps.h index eb4856d32..7e4274cc4 100644 --- a/dfhack/include/modules/Maps.h +++ b/dfhack/include/modules/Maps.h @@ -1,12 +1,194 @@ +/******************************************************************************* + M A P S + Read and write DF's map +*******************************************************************************/ #ifndef CL_MOD_MAPS #define CL_MOD_MAPS #include "Export.h" -/* -* Maps: Read and write DF's map -*/ namespace DFHack { + /*************************************************************************** + T Y P E S + ***************************************************************************/ + + struct t_vein + { + uint32_t vtable; + int32_t type; + int16_t assignment[16]; + uint32_t flags; + uint32_t address_of; // this is NOT part of the DF vein, but an address of the vein as seen by DFhack. + }; + // stores what tiles should appear when the ice melts + struct t_frozenliquidvein + { + uint32_t vtable; + int16_t tiles[16][16]; + }; + + enum e_traffic + { + traffic_normal, + traffic_low, + traffic_high, + traffic_restricted + }; + + enum e_designation + { + designation_no, + designation_default, // dig walls, remove stairs and ramps, gather plants, fell trees + designation_ud_stair, // dig up/down stairs + designation_channel, // dig a channel + designation_ramp, // dig ramp out of a wall + designation_d_stair, // dig a stair down + designation_u_stair, // dig a stair up + designation_7 // whatever + }; + + enum e_liquidtype + { + liquid_water, + liquid_magma + }; + + struct naked_designation + { + unsigned int flow_size : 3; // how much liquid is here? + unsigned int pile : 1; // stockpile? + /* + * All the different dig designations... needs more info, probably an enum + */ + e_designation dig : 3; + unsigned int smooth : 2; + unsigned int hidden : 1; + + /* + * This one is rather involved, but necessary to retrieve the base layer matgloss index + * see http://www.bay12games.com/forum/index.php?topic=608.msg253284#msg253284 for details + */ + unsigned int geolayer_index :4; + unsigned int light : 1; + unsigned int subterranean : 1; // never seen the light of day? + unsigned int skyview : 1; // sky is visible now, it rains in here when it rains + + /* + * Probably similar to the geolayer_index. Only with a different set of offsets and different data. + * we don't use this yet + */ + unsigned int biome : 4; + /* + * 0 = water + * 1 = magma + */ + e_liquidtype liquid_type : 1; + unsigned int water_table : 1; // srsly. wtf? + unsigned int rained : 1; // does this mean actual rain (as in the blue blocks) or a wet tile? + e_traffic traffic : 2; // needs enum + unsigned int flow_forbid : 1; // what? + unsigned int liquid_static : 1; + unsigned int moss : 1;// I LOVE MOSS + unsigned int feature_present : 1; // another wtf... is this required for magma pipes to work? + unsigned int liquid_character : 2; // those ripples on streams? + }; + + union t_designation + { + uint32_t whole; + naked_designation bits; + }; + + // occupancy flags (rat,dwarf,horse,built wall,not build wall,etc) + struct naked_occupancy + { + unsigned int building : 3;// building type... should be an enum? + // 7 = door + unsigned int unit : 1; + unsigned int unit_grounded : 1; + unsigned int item : 1; + // splatter. everyone loves splatter. + unsigned int mud : 1; + unsigned int vomit :1; + unsigned int broken_arrows_color :4; + unsigned int blood_g : 1; + unsigned int blood_g2 : 1; + unsigned int blood_b : 1; + unsigned int blood_b2 : 1; + unsigned int blood_y : 1; + unsigned int blood_y2 : 1; + unsigned int blood_m : 1; + unsigned int blood_m2 : 1; + unsigned int blood_c : 1; + unsigned int blood_c2 : 1; + unsigned int blood_w : 1; + unsigned int blood_w2 : 1; + unsigned int blood_o : 1; + unsigned int blood_o2 : 1; + unsigned int slime : 1; + unsigned int slime2 : 1; + unsigned int blood : 1; + unsigned int blood2 : 1; + unsigned int broken_arrows_variant : 1; + unsigned int snow : 1; + }; + + struct naked_occupancy_grouped + { + unsigned int building : 3;// building type... should be an enum? + // 7 = door + unsigned int unit : 1; + unsigned int unit_grounded : 1; + unsigned int item : 1; + // splatter. everyone loves splatter. + unsigned int splatter : 26; + }; + + union t_occupancy + { + uint32_t whole; + naked_occupancy bits; + naked_occupancy_grouped unibits; + }; + + // map block flags + struct naked_blockflags + { + unsigned int designated : 1;// designated for jobs (digging and stuff like that) + unsigned int unk_1 : 1; // possibly related to the designated flag + // two flags required for liquid flow. no idea why + unsigned int liquid_1 : 1; + unsigned int liquid_2 : 1; + unsigned int unk_2: 28; // rest of the flags is completely unknown + // there's a possibility that this flags field is shorter than 32 bits + }; + + union t_blockflags + { + uint32_t whole; + naked_blockflags bits; + }; + + typedef int16_t tiletypes40d [16][16]; + typedef DFHack::t_designation designations40d [16][16]; + typedef DFHack::t_occupancy occupancies40d [16][16]; + typedef uint8_t biome_indices40d [16]; + + typedef struct + { + tiletypes40d tiletypes; + designations40d designation; + occupancies40d occupancy; + // really a '7', but I use 8 to make it neater :) + biome_indices40d biome_indices; + uint32_t origin; // the address where it came from + t_blockflags blockflags; + } mapblock40d; + + /*************************************************************************** + C L I E N T M O D U L E + ***************************************************************************/ + class APIPrivate; struct t_viewscreen; class DFHACK_EXPORT Maps diff --git a/examples/veccheck.cpp b/examples/veccheck.cpp index ba82b2f87..e8cfbe086 100644 --- a/examples/veccheck.cpp +++ b/examples/veccheck.cpp @@ -6,6 +6,7 @@ #include #include #include +#include using namespace std; #include @@ -13,6 +14,7 @@ using namespace std; #include #include #include +#include void DumpObjStr0Vector (const char * name, DFHack::Process *p, uint32_t addr) { @@ -25,7 +27,18 @@ void DumpObjStr0Vector (const char * name, DFHack::Process *p, uint32_t addr) } cout << endl; } - +void DumpObjVtables (const char * name, DFHack::Process *p, uint32_t addr) +{ + cout << "----==== " << name << " ====----" << endl; + DFHack::DfVector vect(p,addr,4); + for(int i = 0; i < vect.getSize();i++) + { + uint32_t addr = *(uint32_t *) vect[i]; + uint32_t vptr = p->readDWord(addr); + cout << p->readClassName(vptr) << endl; + } + cout << endl; +} void DumpDWordVector (const char * name, DFHack::Process *p, uint32_t addr) { cout << "----==== " << name << " ====----" << endl; @@ -63,11 +76,41 @@ int main (int numargs, const char ** args) DFHack::Process* p = DF.getProcess(); DFHack::memory_info* mem = DF.getMemoryInfo(); //const vector * names = mem->getClassIDMapping(); +/* + string name="Stuff"; + cout << "----==== " << name << " ====----" << endl; + DFHack::DfVector vect(p,0x165b290,4); + for(int i = 0; i < vect.getSize();i++) + { + uint32_t addr = *(uint32_t *) vect[i]; + DFHack::t_construction_df40d constr; + DF.ReadRaw(addr, sizeof(constr), (uint8_t *) &constr); + printf("0x%x %dX %dY %dZ: %d:%d\n", addr, constr.x, constr.y, constr.z, + constr.material.type,constr.material.index); + } - DumpObjStr0Vector("Material templates",p, mem->getAddress("mat_templates")); + cout << endl; + */ + /* + DumpObjVtables("Constructions?",p,0x165b278); + DumpObjVtables("Constructions?",p,0x166edb8); + */ + /* + DumpObjStr0Vector("Material templates",p, mem->getAddress("mat_templates")); + */ DumpObjStr0Vector("Inorganics",p, mem->getAddress("mat_inorganics")); + cout << "----==== Inorganics ====----" << endl; + DFHack::DfVector vect(p,addr,4); + for(int i = 0; i < vect.getSize();i++) + { + uint32_t addr = *(uint32_t *) vect[i]; + cout << p->readSTLString(addr) << endl; + } + cout << endl; + + /* DumpObjStr0Vector("Organics - all",p, mem->getAddress("mat_organics_all")); DumpObjStr0Vector("Organics - plants",p, mem->getAddress("mat_organics_plants")); @@ -89,7 +132,7 @@ int main (int numargs, const char ** args) DumpObjStr0Vector("Creature variations",p, mem->getAddress("mat_creature_variations")); DumpObjStr0Vector("Creature types",p, mem->getAddress("mat_creature_types")); - + */ #ifndef LINUX_BUILD cout << "Done. Press any key to continue" << endl; diff --git a/output/Memory.xml b/output/Memory.xml index f4d5a751d..8630545e3 100644 --- a/output/Memory.xml +++ b/output/Memory.xml @@ -3012,6 +3012,11 @@ map_data_1b60_offset 0x1B9c
0x016AFE58
+ + +
0x165b290
+ 0x14 + +
0x01470fbc
DWORD, OK + This seems to be wrong: + creature_vector = 0x0166ed2c Materials ========= @@ -3017,6 +3022,12 @@ map_data_1b60_offset 0x1B9c
0x165b290
0x14 + Translations + ============ +
0x016B0008
+
0x016AFFD8
+ 0x58 +
0x01470fbc
DWORD, OK @@ -3018,15 +3020,32 @@ map_data_1b60_offset 0x1B9c - + Constructions + =============
0x165b290
0x14 Translations ============ -
0x016B0008
-
0x016AFFD8
- 0x58 +
0x016AFFD8
+
0x016B0008
+ 0x4C + + Vegetation + ========== + + :( + + Buildings + ========= + + :( + + Effects + ======= + + :( +
0x01470fbc
DWORD, OK From 01383fd8b78a04e3f3875d1c6ae6061554589eb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Wed, 7 Apr 2010 03:38:22 +0200 Subject: [PATCH 6/8] Dwarf labors work, added to creaturedump --- dfhack/include/DFTypes.h | 315 ----------------------------- dfhack/include/modules/Creatures.h | 311 +++++++++++++++++++++++++++- dfhack/modules/Creatures.cpp | 38 ++-- examples/creaturedump.cpp | 19 ++ output/Memory.xml | 2 + 5 files changed, 345 insertions(+), 340 deletions(-) diff --git a/dfhack/include/DFTypes.h b/dfhack/include/DFTypes.h index 902684947..c47932911 100644 --- a/dfhack/include/DFTypes.h +++ b/dfhack/include/DFTypes.h @@ -262,257 +262,6 @@ enum BiomeOffset eSouthEast, eBiomeCount }; -/* -bits: - -0 Can the dwarf move or are they waiting for their movement timer -1 Dead (might also be set for incoming/leaving critters that are alive) -2 Currently in mood -3 Had a mood -4 "marauder" -- wide class of invader/inside creature attackers -5 Drowning -6 Active merchant -7 "forest" (used for units no longer linked to merchant/diplomacy, they just try to leave mostly) -8 Left (left the map) -9 Rider -10 Incoming -11 Diplomat -12 Zombie -13 Skeleton -14 Can swap tiles during movement (prevents multiple swaps) -15 On the ground (can be conscious) -16 Projectile -17 Active invader (for organized ones) -18 Hidden in ambush -19 Invader origin (could be inactive and fleeing) -20 Will flee if invasion turns around -21 Active marauder/invader moving inward -22 Marauder resident/invader moving in all the way -23 Check against flows next time you get a chance -24 Ridden -25 Caged -26 Tame -27 Chained -28 Royal guard -29 Fortress guard -30 Suppress wield for beatings/etc -31 Is an important historical figure -*/ - -struct naked_creaturflags1 -{ - unsigned int move_state : 1; // Can the dwarf move or are they waiting for their movement timer - unsigned int dead : 1; // might also be set for incoming/leaving critters that are alive - unsigned int has_mood : 1; // Currently in mood - unsigned int had_mood : 1; // Had a mood - - unsigned int marauder : 1; // wide class of invader/inside creature attackers - unsigned int drowning : 1; - unsigned int merchant : 1; // active merchant - unsigned int forest : 1; // used for units no longer linked to merchant/diplomacy, they just try to leave mostly - - unsigned int left : 1; // left the map - unsigned int rider : 1; - unsigned int incoming : 1; - unsigned int diplomat : 1; - - unsigned int zombie : 1; - unsigned int skeleton : 1; - unsigned int can_swap : 1; // Can swap tiles during movement (prevents multiple swaps) - unsigned int on_ground : 1; // can be conscious - - unsigned int projectile : 1; - unsigned int active_invader : 1; // for organized ones - unsigned int hidden_in_ambush : 1; - unsigned int invader_origin : 1; // could be inactive and fleeing - - unsigned int coward : 1; // Will flee if invasion turns around - unsigned int hidden_ambusher : 1; // maybe - unsigned int invades : 1; // Active marauder/invader moving inward - unsigned int check_flows : 1; // Check against flows next time you get a chance - - // 0100 0000 - 8000 0000 - unsigned int ridden : 1; - unsigned int caged : 1; - unsigned int tame : 1; - unsigned int chained : 1; - - unsigned int royal_guard : 1; - unsigned int fortress_guard : 1; - unsigned int suppress_wield : 1; // Suppress wield for beatings/etc - unsigned int important_historical_figure : 1; // Is an important historical figure -}; - -union t_creaturflags1 -{ - uint32_t whole; - naked_creaturflags1 bits; -}; - -/* -bits: - -0 Swimming -1 Play combat for sparring -2 Do not notify about level gains (for embark etc) -3 Unused - -4 Nerves calculated -5 Body part info calculated -6 Is important historical figure (slight variation) -7 Has been killed by kill function (slightly different from dead, not necessarily violent death) - -8 Must be forgotten by forget function (just cleanup) -9 Must be deleted (cleanup) -10 Recently forgotten (cleanup) -11 Offered for trade - -12 Trade resolved -13 Has breaks -14 Gutted -15 Circulatory spray - -16 Locked in for trading (it's a projectile on the other set of flags, might be what the flying was) -17 Marked for slaughter -18 Underworld creature -19 Current resident - -20 Marked for special cleanup as unused load from unit block on disk -21 Insulation from clothing calculated -22 Uninvited guest -23 Visitor - -24 Inventory order calculated -25 Vision -- have good part -26 Vision -- have damaged part -27 Vision -- have missing part - -28 Breathing -- have good part -29 Breathing -- having a problem -30 Roaming wilderness population source -31 Roaming wilderness population source -- not a map feature -*/ -struct naked_creaturflags2 -{ - unsigned int swimming : 1; - unsigned int sparring : 1; - unsigned int no_notify : 1; // Do not notify about level gains (for embark etc) - unsigned int unused : 1; - - unsigned int calculated_nerves : 1; - unsigned int calculated_bodyparts : 1; - unsigned int important_historical_figure : 1; // slight variation - unsigned int killed : 1; // killed by kill() function - - unsigned int cleanup_1 : 1; // Must be forgotten by forget function (just cleanup) - unsigned int cleanup_2 : 1; // Must be deleted (cleanup) - unsigned int cleanup_3 : 1; // Recently forgotten (cleanup) - unsigned int for_trade : 1; // Offered for trade - - unsigned int trade_resolved : 1; - unsigned int has_breaks : 1; - unsigned int gutted : 1; - unsigned int circulatory_spray : 1; - - unsigned int locked_in_for_trading : 1; - unsigned int slaughter : 1; // marked for slaughter - unsigned int underworld : 1; // Underworld creature - unsigned int resident : 1; // Current resident - - unsigned int cleanup_4 : 1; // Marked for special cleanup as unused load from unit block on disk - unsigned int calculated_insulation : 1; // Insulation from clothing calculated - unsigned int visitor_uninvited : 1; // Uninvited guest - unsigned int visitor : 1; // visitor - - unsigned int calculated_inventory : 1; // Inventory order calculated - unsigned int vision_good : 1; // Vision -- have good part - unsigned int vision_damaged : 1; // Vision -- have damaged part - unsigned int vision_missing : 1; // Vision -- have missing part - - unsigned int breathing_good : 1; // Breathing -- have good part - unsigned int breathing_problem : 1; // Breathing -- having a problem - unsigned int roaming_wilderness_population_source : 1; - unsigned int roaming_wilderness_population_source_not_a_map_feature : 1; - -}; -union t_creaturflags2 -{ - uint32_t whole; - naked_creaturflags2 bits; -}; - -/* -struct t_labor -{ - string name; - uint8_t value; - t_labor() { - value =0; - } - t_labor(const t_labor & b){ - name=b.name; - value=b.value; - } - t_labor & operator=(const t_labor &b){ - name=b.name; - value=b.value; - return *this; - } -}; -struct t_skill -{ - string name; - uint16_t id; - uint32_t experience; - uint16_t rating; - t_skill(){ - id=rating=0; - experience=0; - } - t_skill(const t_skill & b) - { - name=b.name; - id=b.id; - experience=b.experience; - rating=b.rating; - } - t_skill & operator=(const t_skill &b) - { - name=b.name; - id=b.id; - experience=b.experience; - rating=b.rating; - return *this; - } -}; - -struct t_trait -{ - uint16_t value; - string displayTxt; - string name; - t_trait(){ - value=0; - } - t_trait(const t_trait &b) - { - name=b.name; - displayTxt=b.displayTxt; - value=b.value; - } - t_trait & operator=(const t_trait &b) - { - name=b.name; - displayTxt=b.displayTxt; - value=b.value; - return *this; - } -}; -*/ - -/* -CREATURE -*/ //#pragma pack(push,4) struct t_name @@ -525,70 +274,6 @@ struct t_name bool has_name; }; -struct t_skill -{ - uint16_t id; - uint32_t experience; - uint16_t rating; -}; -struct t_job -{ - bool active; - uint8_t jobId; -}; -struct t_like -{ - int16_t type; - int16_t itemClass; - int16_t itemIndex; - t_matglossPair material; - bool active; -}; -//#pragma pack(pop) - -#define NUM_CREATURE_TRAITS 30 -#define NUM_CREATURE_LABORS 102 -struct t_creature -{ - uint32_t origin; - uint16_t x; - uint16_t y; - uint16_t z; - uint32_t type; - t_creaturflags1 flags1; - t_creaturflags2 flags2; - t_name name; - t_name squad_name; - t_name artifact_name; - uint8_t profession; - char custom_profession[128]; - // enabled labors - uint8_t labors[NUM_CREATURE_LABORS]; - // personality traits - uint16_t traits[NUM_CREATURE_TRAITS]; - uint8_t numSkills; - t_skill skills[256]; - /* - //string last_name; - string current_job; - */ - uint8_t numLikes; - t_like likes[32]; - t_job current_job; - int16_t mood; - uint32_t happiness; - uint32_t id; - uint32_t agility; - uint32_t strength; - uint32_t toughness; - uint32_t money; - int32_t squad_leader_id; - uint8_t sex; - uint32_t pregnancy_timer; //Countdown timer to giving birth - int32_t blood_max; - int32_t blood_current; - uint32_t bleed_rate; -}; //raw struct t_item_df40d { diff --git a/dfhack/include/modules/Creatures.h b/dfhack/include/modules/Creatures.h index a701eaef7..3d02e7773 100644 --- a/dfhack/include/modules/Creatures.h +++ b/dfhack/include/modules/Creatures.h @@ -6,6 +6,315 @@ #include "Export.h" namespace DFHack { + /* + bits: + + 0 Can the dwarf move or are they waiting for their movement timer + 1 Dead (might also be set for incoming/leaving critters that are alive) + 2 Currently in mood + 3 Had a mood + 4 "marauder" -- wide class of invader/inside creature attackers + 5 Drowning + 6 Active merchant + 7 "forest" (used for units no longer linked to merchant/diplomacy, they just try to leave mostly) + 8 Left (left the map) + 9 Rider + 10 Incoming + 11 Diplomat + 12 Zombie + 13 Skeleton + 14 Can swap tiles during movement (prevents multiple swaps) + 15 On the ground (can be conscious) + 16 Projectile + 17 Active invader (for organized ones) + 18 Hidden in ambush + 19 Invader origin (could be inactive and fleeing) + 20 Will flee if invasion turns around + 21 Active marauder/invader moving inward + 22 Marauder resident/invader moving in all the way + 23 Check against flows next time you get a chance + 24 Ridden + 25 Caged + 26 Tame + 27 Chained + 28 Royal guard + 29 Fortress guard + 30 Suppress wield for beatings/etc + 31 Is an important historical figure + */ + + struct naked_creaturflags1 + { + unsigned int move_state : 1; // Can the dwarf move or are they waiting for their movement timer + unsigned int dead : 1; // might also be set for incoming/leaving critters that are alive + unsigned int has_mood : 1; // Currently in mood + unsigned int had_mood : 1; // Had a mood + + unsigned int marauder : 1; // wide class of invader/inside creature attackers + unsigned int drowning : 1; + unsigned int merchant : 1; // active merchant + unsigned int forest : 1; // used for units no longer linked to merchant/diplomacy, they just try to leave mostly + + unsigned int left : 1; // left the map + unsigned int rider : 1; + unsigned int incoming : 1; + unsigned int diplomat : 1; + + unsigned int zombie : 1; + unsigned int skeleton : 1; + unsigned int can_swap : 1; // Can swap tiles during movement (prevents multiple swaps) + unsigned int on_ground : 1; // can be conscious + + unsigned int projectile : 1; + unsigned int active_invader : 1; // for organized ones + unsigned int hidden_in_ambush : 1; + unsigned int invader_origin : 1; // could be inactive and fleeing + + unsigned int coward : 1; // Will flee if invasion turns around + unsigned int hidden_ambusher : 1; // maybe + unsigned int invades : 1; // Active marauder/invader moving inward + unsigned int check_flows : 1; // Check against flows next time you get a chance + + // 0100 0000 - 8000 0000 + unsigned int ridden : 1; + unsigned int caged : 1; + unsigned int tame : 1; + unsigned int chained : 1; + + unsigned int royal_guard : 1; + unsigned int fortress_guard : 1; + unsigned int suppress_wield : 1; // Suppress wield for beatings/etc + unsigned int important_historical_figure : 1; // Is an important historical figure + }; + + union t_creaturflags1 + { + uint32_t whole; + naked_creaturflags1 bits; + }; + + /* + bits: + + 0 Swimming + 1 Play combat for sparring + 2 Do not notify about level gains (for embark etc) + 3 Unused + + 4 Nerves calculated + 5 Body part info calculated + 6 Is important historical figure (slight variation) + 7 Has been killed by kill function (slightly different from dead, not necessarily violent death) + + 8 Must be forgotten by forget function (just cleanup) + 9 Must be deleted (cleanup) + 10 Recently forgotten (cleanup) + 11 Offered for trade + + 12 Trade resolved + 13 Has breaks + 14 Gutted + 15 Circulatory spray + + 16 Locked in for trading (it's a projectile on the other set of flags, might be what the flying was) + 17 Marked for slaughter + 18 Underworld creature + 19 Current resident + + 20 Marked for special cleanup as unused load from unit block on disk + 21 Insulation from clothing calculated + 22 Uninvited guest + 23 Visitor + + 24 Inventory order calculated + 25 Vision -- have good part + 26 Vision -- have damaged part + 27 Vision -- have missing part + + 28 Breathing -- have good part + 29 Breathing -- having a problem + 30 Roaming wilderness population source + 31 Roaming wilderness population source -- not a map feature + */ + struct naked_creaturflags2 + { + unsigned int swimming : 1; + unsigned int sparring : 1; + unsigned int no_notify : 1; // Do not notify about level gains (for embark etc) + unsigned int unused : 1; + + unsigned int calculated_nerves : 1; + unsigned int calculated_bodyparts : 1; + unsigned int important_historical_figure : 1; // slight variation + unsigned int killed : 1; // killed by kill() function + + unsigned int cleanup_1 : 1; // Must be forgotten by forget function (just cleanup) + unsigned int cleanup_2 : 1; // Must be deleted (cleanup) + unsigned int cleanup_3 : 1; // Recently forgotten (cleanup) + unsigned int for_trade : 1; // Offered for trade + + unsigned int trade_resolved : 1; + unsigned int has_breaks : 1; + unsigned int gutted : 1; + unsigned int circulatory_spray : 1; + + unsigned int locked_in_for_trading : 1; + unsigned int slaughter : 1; // marked for slaughter + unsigned int underworld : 1; // Underworld creature + unsigned int resident : 1; // Current resident + + unsigned int cleanup_4 : 1; // Marked for special cleanup as unused load from unit block on disk + unsigned int calculated_insulation : 1; // Insulation from clothing calculated + unsigned int visitor_uninvited : 1; // Uninvited guest + unsigned int visitor : 1; // visitor + + unsigned int calculated_inventory : 1; // Inventory order calculated + unsigned int vision_good : 1; // Vision -- have good part + unsigned int vision_damaged : 1; // Vision -- have damaged part + unsigned int vision_missing : 1; // Vision -- have missing part + + unsigned int breathing_good : 1; // Breathing -- have good part + unsigned int breathing_problem : 1; // Breathing -- having a problem + unsigned int roaming_wilderness_population_source : 1; + unsigned int roaming_wilderness_population_source_not_a_map_feature : 1; + }; + + union t_creaturflags2 + { + uint32_t whole; + naked_creaturflags2 bits; + }; + + /* + struct t_labor + { + string name; + uint8_t value; + t_labor() { + value =0; + } + t_labor(const t_labor & b){ + name=b.name; + value=b.value; + } + t_labor & operator=(const t_labor &b){ + name=b.name; + value=b.value; + return *this; + } + }; + struct t_skill + { + string name; + uint16_t id; + uint32_t experience; + uint16_t rating; + t_skill(){ + id=rating=0; + experience=0; + } + t_skill(const t_skill & b) + { + name=b.name; + id=b.id; + experience=b.experience; + rating=b.rating; + } + t_skill & operator=(const t_skill &b) + { + name=b.name; + id=b.id; + experience=b.experience; + rating=b.rating; + return *this; + } + }; + + struct t_trait + { + uint16_t value; + string displayTxt; + string name; + t_trait(){ + value=0; + } + t_trait(const t_trait &b) + { + name=b.name; + displayTxt=b.displayTxt; + value=b.value; + } + t_trait & operator=(const t_trait &b) + { + name=b.name; + displayTxt=b.displayTxt; + value=b.value; + return *this; + } + }; + */ + + struct t_skill + { + uint16_t id; + uint32_t experience; + uint16_t rating; + }; + struct t_job + { + bool active; + uint8_t jobId; + }; + struct t_like + { + int16_t type; + int16_t itemClass; + int16_t itemIndex; + t_matglossPair material; + bool active; + }; + + // FIXME: define in Memory.xml instead? + #define NUM_CREATURE_TRAITS 30 + #define NUM_CREATURE_LABORS 102 + struct t_creature + { + uint32_t origin; + uint16_t x; + uint16_t y; + uint16_t z; + uint32_t type; + t_creaturflags1 flags1; + t_creaturflags2 flags2; + t_name name; + t_name squad_name; + t_name artifact_name; + uint8_t profession; + char custom_profession[128]; + // enabled labors + uint8_t labors[NUM_CREATURE_LABORS]; + // personality traits + uint16_t traits[NUM_CREATURE_TRAITS]; + uint8_t numSkills; + t_skill skills[256]; + uint8_t numLikes; + t_like likes[32]; + t_job current_job; + int16_t mood; + uint32_t happiness; + uint32_t id; + uint32_t agility; + uint32_t strength; + uint32_t toughness; + uint32_t money; + int32_t squad_leader_id; + uint8_t sex; + uint32_t pregnancy_timer; //Countdown timer to giving birth + int32_t blood_max; + int32_t blood_current; + uint32_t bleed_rate; + }; + class APIPrivate; struct t_creature; class DFHACK_EXPORT Creatures @@ -23,7 +332,7 @@ namespace DFHack const uint16_t x2, const uint16_t y2,const uint16_t z2); bool ReadCreature(const int32_t index, t_creature & furball); /// write labors of a creature (for Dwarf Therapist) - //bool WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]); + bool WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]); private: struct Private; diff --git a/dfhack/modules/Creatures.cpp b/dfhack/modules/Creatures.cpp index ea0fd615f..d1913e638 100644 --- a/dfhack/modules/Creatures.cpp +++ b/dfhack/modules/Creatures.cpp @@ -25,17 +25,19 @@ distribution. #include "DFCommonInternal.h" #include "../private/APIPrivate.h" -// we connect to those -#include -#include -#include -#include "modules/Creatures.h" #include "DFVector.h" #include "DFMemInfo.h" #include "DFProcess.h" #include "DFError.h" #include "DFTypes.h" +// we connect to those +#include +#include +#include +#include "modules/Creatures.h" + + #define SHMCREATURESHDR ((Creatures2010::shm_creature_hdr *)d->d->shm_start) #define SHMCMD(num) ((shm_cmd *)d->d->shm_start)[num]->pingpong #define SHMHDR ((shm_core_hdr *)d->d->shm_start) @@ -162,22 +164,10 @@ bool Creatures::ReadCreature (const int32_t index, t_creature & furball) // labors g_pProcess->read (temp + offs.creature_labors_offset, NUM_CREATURE_LABORS, furball.labors); + // traits //g_pProcess->read (temp + offs.creature_traits_offset, sizeof (uint16_t) * NUM_CREATURE_TRAITS, (uint8_t *) &furball.traits); - // learned skills - /* - DfVector skills (d->p, temp + offs.creature_skills_offset, 4 ); - furball.numSkills = skills.getSize(); - for (uint32_t i = 0; i < furball.numSkills;i++) - { - uint32_t temp2 = * (uint32_t *) skills[i]; - //skills.read(i, (uint8_t *) &temp2); - // a byte: this gives us 256 skills maximum. - furball.skills[i].id = g_pProcess->readByte (temp2); - furball.skills[i].rating = g_pProcess->readByte (temp2 + 4); - furball.skills[i].experience = g_pProcess->readWord (temp2 + 8); - } - */ + // profession furball.profession = g_pProcess->readByte (temp + offs.creature_profession_offset); // current job HACK: the job object isn't cleanly represented here @@ -290,14 +280,14 @@ int32_t Creatures::ReadCreatureInBox (int32_t index, t_creature & furball, } -/* -bool API::WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]) + +bool Creatures::WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]) { - if(!d->creaturesInited) return false; + if(!d->Started) return false; uint32_t temp = * (uint32_t *) d->p_cre->at (index); - WriteRaw(temp + d->creatures.creature_labors_offset, NUM_CREATURE_LABORS, labors); + g_pProcess->write(temp + d->creatures.creature_labors_offset, NUM_CREATURE_LABORS, labors); } -*/ + /* bool API::getCurrentCursorCreature(uint32_t & creature_index) { diff --git a/examples/creaturedump.cpp b/examples/creaturedump.cpp index e8c09f361..27c0ca8a2 100644 --- a/examples/creaturedump.cpp +++ b/examples/creaturedump.cpp @@ -234,6 +234,7 @@ void printCreature(DFHack::API & DF, const DFHack::t_creature & creature) //skills + cout << "Skills" << endl; for(unsigned int i = 0; i < creature.numSkills;i++) { if(i > 0) @@ -244,6 +245,24 @@ void printCreature(DFHack::API & DF, const DFHack::t_creature & creature) } cout << endl; + // labors + cout << "Labors" << endl; + for(unsigned int i = 0; i < NUM_CREATURE_LABORS;i++) + { + if(!creature.labors[i]) + continue; + string laborname; + try + { + laborname = mem->getLabor(i); + } + catch(exception &) + { + break; + } + cout << laborname << ", "; + } + cout << endl; /* * FLAGS 1 */ diff --git a/output/Memory.xml b/output/Memory.xml index 7690f4145..60f548fc4 100644 --- a/output/Memory.xml +++ b/output/Memory.xml @@ -2800,6 +2800,7 @@ 64 65 + ==================================================================== V -- T A B L E S (for stonesense) From 839e255d178b7ec09355806ac42e85005595af6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Wed, 7 Apr 2010 12:49:37 +0200 Subject: [PATCH 7/8] Vegetation reading --- dfhack/APIPrivate.cpp | 3 + dfhack/CMakeLists.txt | 1 + dfhack/DFHackAPI.cpp | 53 +++------------- dfhack/include/DFHackAPI.h | 2 + dfhack/include/DFTypes.h | 8 --- dfhack/include/modules/Vegetation.h | 45 ++++++++++++++ dfhack/modules/Vegetation.cpp | 96 +++++++++++++++++++++++++++++ dfhack/private/APIPrivate.h | 2 + examples/veccheck.cpp | 91 ++++++++++++++++++++++++++- output/Memory.xml | 5 +- 10 files changed, 249 insertions(+), 57 deletions(-) create mode 100644 dfhack/include/modules/Vegetation.h create mode 100644 dfhack/modules/Vegetation.cpp diff --git a/dfhack/APIPrivate.cpp b/dfhack/APIPrivate.cpp index 2f132b8cc..453cbac7e 100644 --- a/dfhack/APIPrivate.cpp +++ b/dfhack/APIPrivate.cpp @@ -12,6 +12,7 @@ #include "modules/Materials.h" #include "modules/Position.h" #include "modules/Translation.h" +#include "modules/Vegetation.h" #include "modules/Gui.h" using namespace DFHack; @@ -25,6 +26,7 @@ APIPrivate::APIPrivate() gui = 0; materials = 0; translation = 0; + vegetation = 0; } APIPrivate::~APIPrivate() @@ -35,6 +37,7 @@ APIPrivate::~APIPrivate() if(gui) delete gui; if(materials) delete materials; if(translation) delete translation; + if(vegetation) delete vegetation; } bool APIPrivate::InitReadNames() diff --git a/dfhack/CMakeLists.txt b/dfhack/CMakeLists.txt index b15aa71b4..5f5df470d 100644 --- a/dfhack/CMakeLists.txt +++ b/dfhack/CMakeLists.txt @@ -38,6 +38,7 @@ modules/Maps.cpp modules/Materials.cpp modules/Position.cpp modules/Translation.cpp +modules/Vegetation.cpp ) SET(PROJECT_HDRS_LINUX diff --git a/dfhack/DFHackAPI.cpp b/dfhack/DFHackAPI.cpp index d47189f6b..6b65cf811 100644 --- a/dfhack/DFHackAPI.cpp +++ b/dfhack/DFHackAPI.cpp @@ -41,6 +41,7 @@ distribution. #include "modules/Gui.h" #include "modules/Creatures.h" #include "modules/Translation.h" +#include "modules/Vegetation.h" using namespace DFHack; @@ -209,6 +210,13 @@ Translation * API::getTranslation() return d->translation; } +Vegetation * API::getVegetation() +{ + if(!d->vegetation) + d->vegetation = new Vegetation(d); + return d->vegetation; +} + /* // returns number of buildings, expects v_buildingtypes that will later map t_building.type to its name bool API::InitReadBuildings ( uint32_t& numbuildings ) @@ -379,51 +387,6 @@ void API::FinishReadConstructions() d->constructionsInited = false; } - -bool API::InitReadVegetation(uint32_t & numplants) -{ - try - { - int vegetation = d->offset_descriptor->getAddress ("vegetation"); - d->tree_offset = d->offset_descriptor->getOffset ("tree_desc_offset"); - - d->vegetationInited = true; - d->p_veg = new DfVector (d->p, vegetation, 4); - numplants = d->p_veg->getSize(); - return true; - } - catch (Error::MissingMemoryDefinition&) - { - d->vegetationInited = false; - numplants = 0; - throw; - } -} - - -bool API::ReadVegetation (const int32_t index, t_tree_desc & shrubbery) -{ - if(!d->vegetationInited) - return false; - // read pointer from vector at position - uint32_t temp = * (uint32_t *) d->p_veg->at (index); - //read construction from memory - g_pProcess->read (temp + d->tree_offset, sizeof (t_tree_desc), (uint8_t *) &shrubbery); - // FIXME: this is completely wrong. type isn't just tree/shrub but also different kinds of trees. stuff that grows around ponds has its own type ID - if (shrubbery.material.type == 3) shrubbery.material.type = 2; - return true; -} - - -void API::FinishReadVegetation() -{ - if(d->p_veg) - { - delete d->p_veg; - d->p_veg = 0; - } - d->vegetationInited = false; -} */ /* bool API::InitReadNotes( uint32_t &numnotes ) diff --git a/dfhack/include/DFHackAPI.h b/dfhack/include/DFHackAPI.h index 352caeb1b..5a6ee82f8 100644 --- a/dfhack/include/DFHackAPI.h +++ b/dfhack/include/DFHackAPI.h @@ -49,6 +49,7 @@ namespace DFHack class Gui; class Materials; class Translation; + class Vegetation; class DFHACK_EXPORT API { @@ -92,6 +93,7 @@ namespace DFHack Position * getPosition(); Materials * getMaterials(); Translation * getTranslation(); + Vegetation * getVegetation(); /* * Constructions (costructed walls, floors, ramps, etc...) diff --git a/dfhack/include/DFTypes.h b/dfhack/include/DFTypes.h index c47932911..f9d19c0dc 100644 --- a/dfhack/include/DFTypes.h +++ b/dfhack/include/DFTypes.h @@ -180,14 +180,6 @@ struct t_building // FIXME: not complete, we need building presence bitmaps for stuff like farm plots and stockpiles, orientation (N,E,S,W) and state (open/closed) }; -struct t_tree_desc -{ - t_matglossPair material; - uint16_t x; - uint16_t y; - uint16_t z; -}; - /* case 10: ret += "leather"; diff --git a/dfhack/include/modules/Vegetation.h b/dfhack/include/modules/Vegetation.h new file mode 100644 index 000000000..f5c21a564 --- /dev/null +++ b/dfhack/include/modules/Vegetation.h @@ -0,0 +1,45 @@ +#ifndef CL_MOD_VEGETATION +#define CL_MOD_VEGETATION +/* +* DF vegetation - stuff that grows and gets cut down or trampled by dwarves +*/ +#include "Export.h" +namespace DFHack +{ + /* + types + 0: sapling?, dead sapling?, grown maple tree + 1: willow sapling? + 2: shrub + 3: shrub near water! + */ + struct t_tree + { + uint16_t type; // +0x6C + uint16_t material; // +0x6E + uint16_t x; // +0x70 + uint16_t y; // +0x72 + uint16_t z; // +0x74 + /* + junk_fill<0xA> junk; + uint32_t flags; // +0x80 maybe? + */ + uint32_t address; + }; + + struct APIPrivate; + class DFHACK_EXPORT Vegetation + { + public: + Vegetation(APIPrivate * d); + ~Vegetation(); + bool Start(uint32_t & numTrees); + bool Read (const uint32_t index, t_tree & shrubbery); + bool Finish(); + + private: + struct Private; + Private *d; + }; +} +#endif diff --git a/dfhack/modules/Vegetation.cpp b/dfhack/modules/Vegetation.cpp new file mode 100644 index 000000000..721f6af1e --- /dev/null +++ b/dfhack/modules/Vegetation.cpp @@ -0,0 +1,96 @@ +/* +www.sourceforge.net/projects/dfhack +Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#include "DFCommonInternal.h" +#include "../private/APIPrivate.h" +#include "modules/Translation.h" +#include "DFMemInfo.h" +#include "DFProcess.h" +#include "DFVector.h" +#include "DFTypes.h" +#include "modules/Vegetation.h" + +using namespace DFHack; + +struct Vegetation::Private +{ + uint32_t vegetation_vector; + uint32_t tree_desc_offset; + // translation + DfVector * p_veg; + + APIPrivate *d; + bool Inited; + bool Started; +}; + +Vegetation::Vegetation(APIPrivate * d_) +{ + d = new Private; + d->d = d_; + d->Inited = d->Started = false; + memory_info * mem = d->d->offset_descriptor; + d->vegetation_vector = mem->getAddress ("vegetation_vector"); + d->tree_desc_offset = mem->getOffset ("tree_desc_offset"); + d->Inited = true; +} + +Vegetation::~Vegetation() +{ + if(d->Started) + Finish(); + delete d; +} + +bool Vegetation::Start(uint32_t & numplants) +{ + d->p_veg = new DfVector (g_pProcess, d->vegetation_vector, 4); + numplants = d->p_veg->getSize(); + d->Started = true; + return true; +} + + +bool Vegetation::Read (const uint32_t index, t_tree & shrubbery) +{ + if(!d->Started) + return false; + // read pointer from vector at position + uint32_t temp = * (uint32_t *) d->p_veg->at (index); + // read from memory + g_pProcess->read (temp + d->tree_desc_offset, sizeof (t_tree), (uint8_t *) &shrubbery); + shrubbery.address = temp; + return true; +} + +bool Vegetation::Finish() +{ + if(d->p_veg) + { + delete d->p_veg; + d->p_veg = 0; + } + d->Started = false; + return true; +} \ No newline at end of file diff --git a/dfhack/private/APIPrivate.h b/dfhack/private/APIPrivate.h index 85fce5f26..1131df91b 100644 --- a/dfhack/private/APIPrivate.h +++ b/dfhack/private/APIPrivate.h @@ -39,6 +39,7 @@ namespace DFHack class Translation; class ProcessEnumerator; class Process; + class Vegetation; class memory_info; struct t_name; class APIPrivate @@ -69,6 +70,7 @@ namespace DFHack Gui * gui; Materials * materials; Translation * translation; + Vegetation * vegetation; /* uint32_t item_material_offset; diff --git a/examples/veccheck.cpp b/examples/veccheck.cpp index e8cfbe086..74a746a8e 100644 --- a/examples/veccheck.cpp +++ b/examples/veccheck.cpp @@ -1,6 +1,7 @@ // Just show some position data #include +#include #include #include #include @@ -15,6 +16,9 @@ using namespace std; #include #include #include +#include +#include +#include void DumpObjStr0Vector (const char * name, DFHack::Process *p, uint32_t addr) { @@ -51,6 +55,37 @@ void DumpDWordVector (const char * name, DFHack::Process *p, uint32_t addr) cout << endl; } +/* +address = absolute address of dump start +length = length in lines. 1 line = 16 bytes +*/ +void hexdump (DFHack::API& DF, uint32_t address, uint32_t length) +{ + char *buf = new char[length * 16]; + + DF.ReadRaw(address, length * 16, (uint8_t *) buf); + for (int i = 0; i < length; i++) + { + // leading offset + cout << "0x" << hex << setw(4) << i*16 << " "; + // groups + for(int j = 0; j < 4; j++) + { + // bytes + for(int k = 0; k < 4; k++) + { + int idx = i * 16 + j * 4 + k; + + cout << hex << setw(2) << int(static_cast(buf[idx])) << " "; + } + cout << " "; + } + cout << endl; + } + delete buf; +} + + int main (int numargs, const char ** args) { uint32_t addr; @@ -99,6 +134,7 @@ int main (int numargs, const char ** args) /* DumpObjStr0Vector("Material templates",p, mem->getAddress("mat_templates")); */ + /* DumpObjStr0Vector("Inorganics",p, mem->getAddress("mat_inorganics")); cout << "----==== Inorganics ====----" << endl; @@ -109,7 +145,7 @@ int main (int numargs, const char ** args) cout << p->readSTLString(addr) << endl; } cout << endl; - + */ /* DumpObjStr0Vector("Organics - all",p, mem->getAddress("mat_organics_all")); @@ -133,6 +169,59 @@ int main (int numargs, const char ** args) DumpObjStr0Vector("Creature types",p, mem->getAddress("mat_creature_types")); */ + DFHack::Position * pos = DF.getPosition(); + DFHack::Vegetation * v = DF.getVegetation(); + DFHack::Materials * mat = DF.getMaterials(); + vector organics; + mat->ReadOrganicMaterials(organics); + + int32_t x,y,z; + pos->getCursorCoords(x,y,z); + + + uint32_t numVegs = 0; + v->Start(numVegs); + if(x == -30000) + { + cout << "----==== Trees ====----" << endl; + for(uint32_t i =0; i < numVegs; i++) + { + DFHack::t_tree tree; + v->Read(i,tree); + printf("%d/%d/%d, %d:%d\n",tree.x,tree.y,tree.z,tree.type,tree.material); + } + } + else + { + cout << "----==== Tree at "<< x << "/" << y << "/" << z << " ====----" << endl; + for(uint32_t i =0; i < numVegs; i++) + { + DFHack::t_tree tree; + v->Read(i,tree); + if(tree.x == x && tree.y == y && tree.z == z) + { + printf("%d:%d = ",tree.type,tree.material); + if(tree.type == 1 || tree.type == 3) + { + cout << "near-water "; + } + cout << organics[tree.material].id << " "; + if(tree.type == 0 || tree.type == 1) + { + cout << "tree"; + } + if(tree.type == 2 || tree.type == 3) + { + cout << "shrub"; + } + cout << endl; + printf("Address: 0x%x\n", tree.address); + hexdump(DF,tree.address,13); + break; + } + } + } + v->Finish(); #ifndef LINUX_BUILD cout << "Done. Press any key to continue" << endl; diff --git a/output/Memory.xml b/output/Memory.xml index 60f548fc4..d80209eab 100644 --- a/output/Memory.xml +++ b/output/Memory.xml @@ -3037,8 +3037,8 @@ map_data_1b60_offset 0x1B9c Vegetation ========== - - :( +
0x0167030C
belal: 0x017f6d98 ... what? + 0x6C Buildings ========= @@ -3073,7 +3073,6 @@ map_data_1b60_offset 0x1B9c settlement_current 0xffffffff settlements 0x016af4a4 translation_vector 0x016b0010 - vegetation 0x017f6da0 view_screen 0xffffffff window_dims 0x017f5abc window_x 0x00e32798 From 9589617d9838d8da1db927211c8bbcbb7d40b38f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Wed, 7 Apr 2010 16:45:38 +0200 Subject: [PATCH 8/8] Moved some common bits of the examples to a header file treedump utility --- examples/CMakeLists.txt | 4 + examples/buildingsdump.cpp | 91 +----------------- examples/materialtest.cpp | 51 ---------- examples/renamer.cpp | 15 +-- examples/treedump.cpp | 107 +++++++++++++++++++++ examples/veccheck.cpp | 184 +------------------------------------ output/Memory.xml | 10 +- 7 files changed, 125 insertions(+), 337 deletions(-) create mode 100644 examples/treedump.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index e430b94b0..7ec11cc62 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -57,6 +57,10 @@ TARGET_LINK_LIBRARIES(dfsuspend dfhack) ADD_EXECUTABLE(dfvecc veccheck.cpp) TARGET_LINK_LIBRARIES(dfvecc dfhack) +# treedump - dump them trees! +ADD_EXECUTABLE(dftreedump treedump.cpp) +TARGET_LINK_LIBRARIES(dftreedump dfhack) + # catsplosion - Makes every cat pregnant, and almost due... # Author: Zhentar # ADD_EXECUTABLE(dfcatsplosion catsplosion.cpp) diff --git a/examples/buildingsdump.cpp b/examples/buildingsdump.cpp index 7b87b734b..dee75ceb4 100644 --- a/examples/buildingsdump.cpp +++ b/examples/buildingsdump.cpp @@ -12,96 +12,7 @@ using namespace std; #include #include #include - -/* -address = absolute address of dump start -length = length in lines. 1 line = 16 bytes -*/ -void hexdump (DFHack::API& DF, uint32_t address, uint32_t length) -{ - char *buf = new char[length * 16]; - - DF.ReadRaw(address, length * 16, (uint8_t *) buf); - for (int i = 0; i < length; i++) - { - // leading offset - cout << "0x" << hex << setw(4) << i*16 << " "; - // groups - for(int j = 0; j < 4; j++) - { - // bytes - for(int k = 0; k < 4; k++) - { - int idx = i * 16 + j * 4 + k; - - cout << hex << setw(2) << int(static_cast(buf[idx])) << " "; - } - cout << " "; - } - cout << endl; - } - delete buf; -} - -void interleave_hex (DFHack::API& DF, vector < uint32_t > & addresses, uint32_t length) -{ - vector bufs; - - for(int counter = 0; counter < addresses.size(); counter ++) - { - char * buf = new char[length * 16]; - DF.ReadRaw(addresses[counter], length * 16, (uint8_t *) buf); - bufs.push_back(buf); - } - cout << setfill('0'); - - // output a header - cout << "line offset "; - for (int obj = 0; obj < addresses.size(); obj++) - { - cout << "0x" << hex << setw(9) << addresses[obj] << " "; - } - cout << endl; - - for(int offs = 0 ; offs < length * 16; offs += 4) - { - if((!(offs % 16)) && offs != 0) - { - cout << endl; - } - cout << setfill(' '); - cout << dec << setw(4) << offs/4 << " "; - cout << setfill('0'); - cout << "0x" << hex << setw(4) << offs << " "; - for (int object = 0; object < bufs.size(); object++) - { - // bytes - for(int k = 0; k < 4; k++) - { - uint8_t data = bufs[object][offs + k]; - cout << hex << setw(2) << int(static_cast(data)) << " "; - } - cout << " "; - } - cout << endl; - } - for(int counter = 0; counter < addresses.size(); counter ++) - { - delete bufs[counter]; - } -} - -template -void print_bits ( T val, std::ostream& out ) -{ - T n_bits = sizeof ( val ) * CHAR_BIT; - - for ( unsigned i = 0; i < n_bits; ++i ) { - out<< !!( val & 1 ) << " "; - val >>= 1; - } -} - +#include "miscutils.h" int main (int argc,const char* argv[]) { diff --git a/examples/materialtest.cpp b/examples/materialtest.cpp index 5f5acdda3..815a0c510 100644 --- a/examples/materialtest.cpp +++ b/examples/materialtest.cpp @@ -15,30 +15,6 @@ using namespace std; #include #include -void DumpObjStr0Vector (const char * name, DFHack::Process *p, uint32_t addr) -{ - cout << "----==== " << name << " ====----" << endl; - DFHack::DfVector vect(p,addr,4); - for(int i = 0; i < vect.getSize();i++) - { - uint32_t addr = *(uint32_t *) vect[i]; - cout << p->readSTLString(addr) << endl; - } - cout << endl; -} - -void DumpDWordVector (const char * name, DFHack::Process *p, uint32_t addr) -{ - cout << "----==== " << name << " ====----" << endl; - DFHack::DfVector vect(p,addr,4); - for(int i = 0; i < vect.getSize();i++) - { - uint32_t number = *(uint32_t *) vect[i]; - cout << number << endl; - } - cout << endl; -} - int main (int numargs, const char ** args) { uint32_t addr; @@ -65,33 +41,6 @@ int main (int numargs, const char ** args) DFHack::memory_info* mem = DF.getMemoryInfo(); DFHack::Materials *Materials = DF.getMaterials(); - //const vector * names = mem->getClassIDMapping(); - /* - DumpObjStr0Vector("Material templates",p, mem->getAddress("mat_templates")); - - DumpObjStr0Vector("Inorganics",p, mem->getAddress("mat_inorganics")); - - DumpObjStr0Vector("Organics - all",p, mem->getAddress("mat_organics_all")); - - DumpObjStr0Vector("Organics - plants",p, mem->getAddress("mat_organics_plants")); - - DumpDWordVector("Maybe map between all organics and plants",p, mem->getAddress("mat_unk1_numbers")); - - DumpObjStr0Vector("Trees/wood",p, mem->getAddress("mat_organics_trees")); - - DumpDWordVector("Maybe map between all organics and trees",p, mem->getAddress("mat_unk2_numbers")); - - DumpObjStr0Vector("Body material templates",p, mem->getAddress("mat_body_material_templates")); - - DumpObjStr0Vector("Body detail plans",p, mem->getAddress("mat_body_detail_plans")); - - DumpObjStr0Vector("Bodies",p, mem->getAddress("mat_bodies")); - - DumpObjStr0Vector("Bodygloss",p, mem->getAddress("mat_bodygloss")); - - DumpObjStr0Vector("Creature variations",p, mem->getAddress("mat_creature_variations")); - */ - cout << "----==== Inorganic ====----" << endl; vector matgloss; Materials->ReadInorganicMaterials (matgloss); diff --git a/examples/renamer.cpp b/examples/renamer.cpp index 953ff2591..927c620c7 100644 --- a/examples/renamer.cpp +++ b/examples/renamer.cpp @@ -14,19 +14,8 @@ using namespace std; #include #include #include -#include - -template -void print_bits ( T val, std::ostream& out ) -{ - T n_bits = sizeof ( val ) * CHAR_BIT; - - for ( unsigned i = 0; i < n_bits; ++i ) - { - out<< !!( val & 1 ) << " "; - val >>= 1; - } -} +#include +#include "miscutils.h" vector< vector > englishWords; vector< vector > foreignWords; diff --git a/examples/treedump.cpp b/examples/treedump.cpp new file mode 100644 index 000000000..463bbb8c3 --- /dev/null +++ b/examples/treedump.cpp @@ -0,0 +1,107 @@ +// Just show some position data + +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "miscutils.h" + +int main (int numargs, const char ** args) +{ + uint32_t addr; + if (numargs == 2) + { + istringstream input (args[1],istringstream::in); + input >> std::hex >> addr; + } + DFHack::API DF("Memory.xml"); + try + { + DF.Attach(); + } + catch (exception& e) + { + cerr << e.what() << endl; + #ifndef LINUX_BUILD + cin.ignore(); + #endif + return 1; + } + + DFHack::Process* p = DF.getProcess(); + DFHack::memory_info* mem = DF.getMemoryInfo(); + DFHack::Position * pos = DF.getPosition(); + DFHack::Vegetation * v = DF.getVegetation(); + DFHack::Materials * mat = DF.getMaterials(); + vector organics; + mat->ReadOrganicMaterials(organics); + + int32_t x,y,z; + pos->getCursorCoords(x,y,z); + + + uint32_t numVegs = 0; + v->Start(numVegs); + if(x == -30000) + { + cout << "----==== Trees ====----" << endl; + for(uint32_t i =0; i < numVegs; i++) + { + DFHack::t_tree tree; + v->Read(i,tree); + printf("%d/%d/%d, %d:%d\n",tree.x,tree.y,tree.z,tree.type,tree.material); + } + } + else + { + cout << "----==== Tree at "<< x << "/" << y << "/" << z << " ====----" << endl; + for(uint32_t i =0; i < numVegs; i++) + { + DFHack::t_tree tree; + v->Read(i,tree); + if(tree.x == x && tree.y == y && tree.z == z) + { + printf("%d:%d = ",tree.type,tree.material); + if(tree.type == 1 || tree.type == 3) + { + cout << "near-water "; + } + cout << organics[tree.material].id << " "; + if(tree.type == 0 || tree.type == 1) + { + cout << "tree"; + } + if(tree.type == 2 || tree.type == 3) + { + cout << "shrub"; + } + cout << endl; + printf("Address: 0x%x\n", tree.address); + hexdump(DF,tree.address,13); + break; + } + } + } + v->Finish(); + + #ifndef LINUX_BUILD + cout << "Done. Press any key to continue" << endl; + cin.ignore(); + #endif + return 0; +} diff --git a/examples/veccheck.cpp b/examples/veccheck.cpp index 74a746a8e..93452467f 100644 --- a/examples/veccheck.cpp +++ b/examples/veccheck.cpp @@ -19,72 +19,7 @@ using namespace std; #include #include #include - -void DumpObjStr0Vector (const char * name, DFHack::Process *p, uint32_t addr) -{ - cout << "----==== " << name << " ====----" << endl; - DFHack::DfVector vect(p,addr,4); - for(int i = 0; i < vect.getSize();i++) - { - uint32_t addr = *(uint32_t *) vect[i]; - cout << p->readSTLString(addr) << endl; - } - cout << endl; -} -void DumpObjVtables (const char * name, DFHack::Process *p, uint32_t addr) -{ - cout << "----==== " << name << " ====----" << endl; - DFHack::DfVector vect(p,addr,4); - for(int i = 0; i < vect.getSize();i++) - { - uint32_t addr = *(uint32_t *) vect[i]; - uint32_t vptr = p->readDWord(addr); - cout << p->readClassName(vptr) << endl; - } - cout << endl; -} -void DumpDWordVector (const char * name, DFHack::Process *p, uint32_t addr) -{ - cout << "----==== " << name << " ====----" << endl; - DFHack::DfVector vect(p,addr,4); - for(int i = 0; i < vect.getSize();i++) - { - uint32_t number = *(uint32_t *) vect[i]; - cout << number << endl; - } - cout << endl; -} - -/* -address = absolute address of dump start -length = length in lines. 1 line = 16 bytes -*/ -void hexdump (DFHack::API& DF, uint32_t address, uint32_t length) -{ - char *buf = new char[length * 16]; - - DF.ReadRaw(address, length * 16, (uint8_t *) buf); - for (int i = 0; i < length; i++) - { - // leading offset - cout << "0x" << hex << setw(4) << i*16 << " "; - // groups - for(int j = 0; j < 4; j++) - { - // bytes - for(int k = 0; k < 4; k++) - { - int idx = i * 16 + j * 4 + k; - - cout << hex << setw(2) << int(static_cast(buf[idx])) << " "; - } - cout << " "; - } - cout << endl; - } - delete buf; -} - +#include "miscutils.h" int main (int numargs, const char ** args) { @@ -107,122 +42,7 @@ int main (int numargs, const char ** args) #endif return 1; } - - DFHack::Process* p = DF.getProcess(); - DFHack::memory_info* mem = DF.getMemoryInfo(); - //const vector * names = mem->getClassIDMapping(); -/* - string name="Stuff"; - cout << "----==== " << name << " ====----" << endl; - DFHack::DfVector vect(p,0x165b290,4); - for(int i = 0; i < vect.getSize();i++) - { - uint32_t addr = *(uint32_t *) vect[i]; - DFHack::t_construction_df40d constr; - DF.ReadRaw(addr, sizeof(constr), (uint8_t *) &constr); - printf("0x%x %dX %dY %dZ: %d:%d\n", addr, constr.x, constr.y, constr.z, - constr.material.type,constr.material.index); - } - - - cout << endl; - */ - /* - DumpObjVtables("Constructions?",p,0x165b278); - DumpObjVtables("Constructions?",p,0x166edb8); - */ - /* - DumpObjStr0Vector("Material templates",p, mem->getAddress("mat_templates")); - */ - /* - DumpObjStr0Vector("Inorganics",p, mem->getAddress("mat_inorganics")); - - cout << "----==== Inorganics ====----" << endl; - DFHack::DfVector vect(p,addr,4); - for(int i = 0; i < vect.getSize();i++) - { - uint32_t addr = *(uint32_t *) vect[i]; - cout << p->readSTLString(addr) << endl; - } - cout << endl; - */ - /* - DumpObjStr0Vector("Organics - all",p, mem->getAddress("mat_organics_all")); - - DumpObjStr0Vector("Organics - plants",p, mem->getAddress("mat_organics_plants")); - - DumpDWordVector("Maybe map between all organics and plants",p, mem->getAddress("mat_unk1_numbers")); - - DumpObjStr0Vector("Trees/wood",p, mem->getAddress("mat_organics_trees")); - - DumpDWordVector("Maybe map between all organics and trees",p, mem->getAddress("mat_unk2_numbers")); - - DumpObjStr0Vector("Body material templates",p, mem->getAddress("mat_body_material_templates")); - - DumpObjStr0Vector("Body detail plans",p, mem->getAddress("mat_body_detail_plans")); - - DumpObjStr0Vector("Bodies",p, mem->getAddress("mat_bodies")); - - DumpObjStr0Vector("Bodygloss",p, mem->getAddress("mat_bodygloss")); - - DumpObjStr0Vector("Creature variations",p, mem->getAddress("mat_creature_variations")); - - DumpObjStr0Vector("Creature types",p, mem->getAddress("mat_creature_types")); - */ - DFHack::Position * pos = DF.getPosition(); - DFHack::Vegetation * v = DF.getVegetation(); - DFHack::Materials * mat = DF.getMaterials(); - vector organics; - mat->ReadOrganicMaterials(organics); - - int32_t x,y,z; - pos->getCursorCoords(x,y,z); - - - uint32_t numVegs = 0; - v->Start(numVegs); - if(x == -30000) - { - cout << "----==== Trees ====----" << endl; - for(uint32_t i =0; i < numVegs; i++) - { - DFHack::t_tree tree; - v->Read(i,tree); - printf("%d/%d/%d, %d:%d\n",tree.x,tree.y,tree.z,tree.type,tree.material); - } - } - else - { - cout << "----==== Tree at "<< x << "/" << y << "/" << z << " ====----" << endl; - for(uint32_t i =0; i < numVegs; i++) - { - DFHack::t_tree tree; - v->Read(i,tree); - if(tree.x == x && tree.y == y && tree.z == z) - { - printf("%d:%d = ",tree.type,tree.material); - if(tree.type == 1 || tree.type == 3) - { - cout << "near-water "; - } - cout << organics[tree.material].id << " "; - if(tree.type == 0 || tree.type == 1) - { - cout << "tree"; - } - if(tree.type == 2 || tree.type == 3) - { - cout << "shrub"; - } - cout << endl; - printf("Address: 0x%x\n", tree.address); - hexdump(DF,tree.address,13); - break; - } - } - } - v->Finish(); - + #ifndef LINUX_BUILD cout << "Done. Press any key to continue" << endl; cin.ignore(); diff --git a/output/Memory.xml b/output/Memory.xml index d80209eab..9eac342f3 100644 --- a/output/Memory.xml +++ b/output/Memory.xml @@ -2859,7 +2859,7 @@ 0x18 0xC Vector layout in MSVC 9: - DWORD Allocator + DWORD Allocator? DWORD ? DWORD ? DWORD Start @@ -2867,6 +2867,9 @@ DWORD AllocationEnd 0x1C + +
0x0165B188
Position and window dimensions ============================== @@ -3050,6 +3053,11 @@ map_data_1b60_offset 0x1B9c :( + Settlements + =========== + + :( +