diff --git a/dfhack/APIPrivate.cpp b/dfhack/APIPrivate.cpp index 37b2ce8da..453cbac7e 100644 --- a/dfhack/APIPrivate.cpp +++ b/dfhack/APIPrivate.cpp @@ -11,6 +11,8 @@ #include "modules/Maps.h" #include "modules/Materials.h" #include "modules/Position.h" +#include "modules/Translation.h" +#include "modules/Vegetation.h" #include "modules/Gui.h" using namespace DFHack; @@ -23,6 +25,8 @@ APIPrivate::APIPrivate() position = 0; gui = 0; materials = 0; + translation = 0; + vegetation = 0; } APIPrivate::~APIPrivate() @@ -32,6 +36,8 @@ APIPrivate::~APIPrivate() if(position) delete position; 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 ca851a01e..5f5df470d 100644 --- a/dfhack/CMakeLists.txt +++ b/dfhack/CMakeLists.txt @@ -37,6 +37,8 @@ modules/Gui.cpp 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 44879c0f4..6b65cf811 100644 --- a/dfhack/DFHackAPI.cpp +++ b/dfhack/DFHackAPI.cpp @@ -40,6 +40,8 @@ distribution. #include "modules/Position.h" #include "modules/Gui.h" #include "modules/Creatures.h" +#include "modules/Translation.h" +#include "modules/Vegetation.h" using namespace DFHack; @@ -201,6 +203,20 @@ Materials * API::getMaterials() return d->materials; } +Translation * API::getTranslation() +{ + if(!d->translation) + d->translation = new Translation(d); + 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 ) @@ -371,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 ) @@ -588,129 +559,6 @@ bool API::getItemIndexesInBox(vector &indexes, } */ /* -bool API::InitReadNameTables(vector > & translations , vector > & foreign_languages) //(map< string, vector > & nameTable) -{ - try - { - int genericAddress = d->offset_descriptor->getAddress ("language_vector"); - int transAddress = d->offset_descriptor->getAddress ("translation_vector"); - int word_table_offset = d->offset_descriptor->getOffset ("word_table"); - int sizeof_string = d->offset_descriptor->getHexValue ("sizeof_string"); - - DfVector genericVec (d->p, genericAddress, 4); - DfVector transVec (d->p, transAddress, 4); - - translations.resize(10); - for (uint32_t i = 0;i < genericVec.getSize();i++) - { - uint32_t genericNamePtr = * (uint32_t *) genericVec.at (i); - for(int i=0; i<10;i++) - { - string word = d->p->readSTLString (genericNamePtr + i * sizeof_string); - translations[i].push_back (word); - } - } - - foreign_languages.resize(transVec.getSize()); - for (uint32_t i = 0; i < transVec.getSize();i++) - { - uint32_t transPtr = * (uint32_t *) transVec.at (i); - //string transName = d->p->readSTLString (transPtr); - DfVector trans_names_vec (d->p, transPtr + word_table_offset, 4); - for (uint32_t j = 0;j < trans_names_vec.getSize();j++) - { - uint32_t transNamePtr = * (uint32_t *) trans_names_vec.at (j); - string name = d->p->readSTLString (transNamePtr); - foreign_languages[i].push_back (name); - } - } - d->nameTablesInited = true; - return true; - } - catch (Error::MissingMemoryDefinition&) - { - d->nameTablesInited = false; - throw; - } -} - -string API::TranslateName(const DFHack::t_name &name,const std::vector< std::vector > & translations ,const std::vector< std::vector > & foreign_languages, bool inEnglish) -{ - string out; - assert (d->nameTablesInited); - map >::const_iterator it; - - if(!inEnglish) - { - if(name.words[0] >=0 || name.words[1] >=0) - { - if(name.words[0]>=0) out.append(foreign_languages[name.language][name.words[0]]); - if(name.words[1]>=0) out.append(foreign_languages[name.language][name.words[1]]); - out[0] = toupper(out[0]); - } - if(name.words[5] >=0) - { - string word; - for(int i=2;i<=5;i++) - if(name.words[i]>=0) word.append(foreign_languages[name.language][name.words[i]]); - word[0] = toupper(word[0]); - if(out.length() > 0) out.append(" "); - out.append(word); - } - if(name.words[6] >=0) - { - string word; - word.append(foreign_languages[name.language][name.words[6]]); - word[0] = toupper(word[0]); - if(out.length() > 0) out.append(" "); - out.append(word); - } - } - else - { - if(name.words[0] >=0 || name.words[1] >=0) - { - if(name.words[0]>=0) out.append(translations[name.parts_of_speech[0]+1][name.words[0]]); - if(name.words[1]>=0) out.append(translations[name.parts_of_speech[1]+1][name.words[1]]); - out[0] = toupper(out[0]); - } - if(name.words[5] >=0) - { - if(out.length() > 0) - out.append(" the"); - else - out.append("The"); - string word; - for(int i=2;i<=5;i++) - { - if(name.words[i]>=0) - { - word = translations[name.parts_of_speech[i]+1][name.words[i]]; - word[0] = toupper(word[0]); - out.append(" " + word); - } - } - } - if(name.words[6] >=0) - { - if(out.length() > 0) - out.append(" of"); - else - out.append("Of"); - string word; - word.append(translations[name.parts_of_speech[6]+1][name.words[6]]); - word[0] = toupper(word[0]); - out.append(" " + word); - } - } - return out; -} - -void API::FinishReadNameTables() -{ - d->nameTablesInited = false; -} - void API::FinishReadNotes() { if(d->p_notes) diff --git a/dfhack/include/DFHackAPI.h b/dfhack/include/DFHackAPI.h index 6349f083d..5a6ee82f8 100644 --- a/dfhack/include/DFHackAPI.h +++ b/dfhack/include/DFHackAPI.h @@ -37,6 +37,7 @@ distribution. namespace DFHack { + class APIPrivate; class memory_info; class Process; @@ -47,6 +48,8 @@ namespace DFHack class Position; class Gui; class Materials; + class Translation; + class Vegetation; class DFHACK_EXPORT API { @@ -89,6 +92,8 @@ namespace DFHack Gui * getGui(); Position * getPosition(); Materials * getMaterials(); + Translation * getTranslation(); + Vegetation * getVegetation(); /* * Constructions (costructed walls, floors, ramps, etc...) @@ -154,14 +159,6 @@ namespace DFHack bool InitReadHotkeys( ); bool ReadHotkeys(t_hotkey hotkeys[]); */ - /* - * DF translation tables and name translation - */ - /* - bool InitReadNameTables (std::vector< std::vector > & translations , std::vector< std::vector > & foreign_languages); - void FinishReadNameTables(); - std::string TranslateName(const t_name & name,const std::vector< std::vector > & translations ,const std::vector< std::vector > & foreign_languages, bool inEnglish=true); - */ /* * Item reading diff --git a/dfhack/include/DFTypes.h b/dfhack/include/DFTypes.h index f9ba70cd5..f9d19c0dc 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; }; @@ -191,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"; @@ -273,257 +254,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 @@ -536,70 +266,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 { @@ -695,165 +361,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/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/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/dfhack/include/modules/Translation.h b/dfhack/include/modules/Translation.h new file mode 100644 index 000000000..e6b4d2237 --- /dev/null +++ b/dfhack/include/modules/Translation.h @@ -0,0 +1,35 @@ +#ifndef CL_MOD_TRANSLATION +#define CL_MOD_TRANSLATION +/* +* DF translation tables and name translation +*/ +#include "Export.h" +namespace DFHack +{ + struct APIPrivate; + typedef std::vector< std::vector > DFDict; + typedef struct + { + DFDict translations; + DFDict foreign_languages; + } Dicts; + + class DFHACK_EXPORT Translation + { + public: + Translation(APIPrivate * d); + ~Translation(); + bool Start(); + bool Finish(); + + // Get pointer to the two dictionary structures + Dicts * getDicts(); + // translate a name using the loaded dictionaries + std::string TranslateName(const DFHack::t_name& name, bool inEnglish = true); + + private: + struct Private; + Private *d; + }; +} +#endif 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/Creatures.cpp b/dfhack/modules/Creatures.cpp index 903de54c6..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) @@ -67,6 +69,7 @@ Creatures::Creatures(APIPrivate* _d) creatures.creature_vector = minfo->getAddress ("creature_vector"); creatures.creature_pos_offset = minfo->getOffset ("creature_position"); creatures.creature_profession_offset = minfo->getOffset ("creature_profession"); + creatures.creature_custom_profession_offset = minfo->getOffset ("creature_custom_profession"); creatures.creature_race_offset = minfo->getOffset ("creature_race"); creatures.creature_flags1_offset = minfo->getOffset ("creature_flags1"); creatures.creature_flags2_offset = minfo->getOffset ("creature_flags2"); @@ -76,6 +79,10 @@ Creatures::Creatures(APIPrivate* _d) creatures.creature_labors_offset = minfo->getOffset ("creature_labors"); creatures.creature_happiness_offset = minfo->getOffset ("creature_happiness"); creatures.creature_artifact_name_offset = minfo->getOffset("creature_artifact_name"); + creatures.creature_soul_vector_offset = minfo->getOffset("creature_soul_vector"); + + // soul offsets + creatures.soul_skills_vector_offset = minfo->getOffset("soul_skills_vector"); // name offsets for the creature module creatures.name_firstname_offset = minfo->getOffset("name_firstname"); @@ -153,26 +160,14 @@ bool Creatures::ReadCreature (const int32_t index, t_creature & furball) //d->readName(furball.squad_name, temp + offs.creature_squad_name_offset); d->d->readName(furball.artifact_name, temp + offs.creature_artifact_name_offset); // custom profession - //fill_char_buf (furball.custom_profession, d->p->readSTLString (temp + offs.creature_custom_profession_offset)); + fill_char_buf (furball.custom_profession, g_pProcess->readSTLString (temp + offs.creature_custom_profession_offset)); // 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 @@ -219,6 +214,20 @@ bool Creatures::ReadCreature (const int32_t index, t_creature & furball) g_pProcess->readDWord(temp + offs.creature_bleed_offset, furball.bleed_rate); */ + // enum soul pointer vector + DfVector souls(g_pProcess,temp + offs.creature_soul_vector_offset,4); + // get first soul's skills + DfVector skills(g_pProcess, *(uint32_t *)souls.at(0) + offs.soul_skills_vector_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); + } return true; } @@ -271,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/dfhack/modules/Maps.cpp b/dfhack/modules/Maps.cpp index af468510e..820cf9c6c 100644 --- a/dfhack/modules/Maps.cpp +++ b/dfhack/modules/Maps.cpp @@ -53,7 +53,6 @@ struct Maps::Private APIPrivate *d; bool Inited; bool Started; - //uint32_t biome_stuffs; vector v_geology[eBiomeCount]; }; diff --git a/dfhack/modules/Translation.cpp b/dfhack/modules/Translation.cpp new file mode 100644 index 000000000..ddec1c72e --- /dev/null +++ b/dfhack/modules/Translation.cpp @@ -0,0 +1,197 @@ +/* +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/Translation.h" + +using namespace DFHack; + +struct Translation::Private +{ + uint32_t genericAddress; + uint32_t transAddress; + uint32_t word_table_offset; + uint32_t sizeof_string; + + // translation + Dicts dicts; + + APIPrivate *d; + bool Inited; + bool Started; +}; + +Translation::Translation(APIPrivate * d_) +{ + d = new Private; + d->d = d_; + d->Inited = d->Started = false; + memory_info * mem = d->d->offset_descriptor; + d->genericAddress = mem->getAddress ("language_vector"); + d->transAddress = mem->getAddress ("translation_vector"); + d->word_table_offset = mem->getOffset ("word_table"); + d->sizeof_string = mem->getHexValue ("sizeof_string"); + d->Inited = true; +} + +Translation::~Translation() +{ + if(d->Started) + Finish(); + delete d; +} + +bool Translation::Start() +{ + if(!d->Inited) + return false; + Process * p = d->d->p; + DfVector genericVec (p, d->genericAddress, 4); + DfVector transVec (p, d->transAddress, 4); + DFDict & translations = d->dicts.translations; + DFDict & foreign_languages = d->dicts.foreign_languages; + + translations.resize(10); + for (uint32_t i = 0;i < genericVec.getSize();i++) + { + uint32_t genericNamePtr = * (uint32_t *) genericVec.at (i); + for(int i=0; i<10;i++) + { + string word = p->readSTLString (genericNamePtr + i * d->sizeof_string); + translations[i].push_back (word); + } + } + + foreign_languages.resize(transVec.getSize()); + for (uint32_t i = 0; i < transVec.getSize();i++) + { + uint32_t transPtr = * (uint32_t *) transVec.at (i); + //string transName = d->p->readSTLString (transPtr); + DfVector trans_names_vec (p, transPtr + d->word_table_offset, 4); + for (uint32_t j = 0;j < trans_names_vec.getSize();j++) + { + uint32_t transNamePtr = * (uint32_t *) trans_names_vec.at (j); + string name = p->readSTLString (transNamePtr); + foreign_languages[i].push_back (name); + } + } + d->Started = true; + return true; +} + +bool Translation::Finish() +{ + d->dicts.foreign_languages.clear(); + d->dicts.translations.clear(); + d->Started = false; + return true; +} + +Dicts * Translation::getDicts() +{ + assert(d->Started); + + if(d->Started) + return &d->dicts; + return 0; +} + +string Translation::TranslateName(const t_name &name, bool inEnglish) +{ + string out; + assert (d->Started); + + map >::const_iterator it; + + if(!inEnglish) + { + if(name.words[0] >=0 || name.words[1] >=0) + { + if(name.words[0]>=0) out.append(d->dicts.foreign_languages[name.language][name.words[0]]); + if(name.words[1]>=0) out.append(d->dicts.foreign_languages[name.language][name.words[1]]); + out[0] = toupper(out[0]); + } + if(name.words[5] >=0) + { + string word; + for(int i=2;i<=5;i++) + if(name.words[i]>=0) word.append(d->dicts.foreign_languages[name.language][name.words[i]]); + word[0] = toupper(word[0]); + if(out.length() > 0) out.append(" "); + out.append(word); + } + if(name.words[6] >=0) + { + string word; + word.append(d->dicts.foreign_languages[name.language][name.words[6]]); + word[0] = toupper(word[0]); + if(out.length() > 0) out.append(" "); + out.append(word); + } + } + else + { + if(name.words[0] >=0 || name.words[1] >=0) + { + if(name.words[0]>=0) out.append(d->dicts.translations[name.parts_of_speech[0]+1][name.words[0]]); + if(name.words[1]>=0) out.append(d->dicts.translations[name.parts_of_speech[1]+1][name.words[1]]); + out[0] = toupper(out[0]); + } + if(name.words[5] >=0) + { + if(out.length() > 0) + out.append(" the"); + else + out.append("The"); + string word; + for(int i=2;i<=5;i++) + { + if(name.words[i]>=0) + { + word = d->dicts.translations[name.parts_of_speech[i]+1][name.words[i]]; + word[0] = toupper(word[0]); + out.append(" " + word); + } + } + } + if(name.words[6] >=0) + { + if(out.length() > 0) + out.append(" of"); + else + out.append("Of"); + string word; + word.append(d->dicts.translations[name.parts_of_speech[6]+1][name.words[6]]); + word[0] = toupper(word[0]); + out.append(" " + word); + } + } + return out; +} \ No newline at end of file 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 07bd63adc..1131df91b 100644 --- a/dfhack/private/APIPrivate.h +++ b/dfhack/private/APIPrivate.h @@ -36,8 +36,10 @@ namespace DFHack class Position; class Maps; class Creatures; + class Translation; class ProcessEnumerator; class Process; + class Vegetation; class memory_info; struct t_name; class APIPrivate @@ -67,6 +69,8 @@ namespace DFHack Position * position; Gui * gui; Materials * materials; + Translation * translation; + Vegetation * vegetation; /* uint32_t item_material_offset; diff --git a/dfhack/shm/mod-creature2010.h b/dfhack/shm/mod-creature2010.h index 24795f889..32adb1300 100644 --- a/dfhack/shm/mod-creature2010.h +++ b/dfhack/shm/mod-creature2010.h @@ -37,6 +37,7 @@ typedef struct uint32_t creature_vector; uint32_t creature_pos_offset; uint32_t creature_profession_offset; + uint32_t creature_custom_profession_offset; uint32_t creature_race_offset; uint32_t creature_flags1_offset; uint32_t creature_flags2_offset; @@ -46,6 +47,9 @@ typedef struct uint32_t creature_labors_offset; uint32_t creature_happiness_offset; uint32_t creature_artifact_name_offset; + uint32_t creature_soul_vector_offset; + // soul offsets + uint32_t soul_skills_vector_offset; // name offsets (needed for reading creature names) uint32_t name_firstname_offset; uint32_t name_nickname_offset; 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/creaturedump.cpp b/examples/creaturedump.cpp index 60cb343be..27c0ca8a2 100644 --- a/examples/creaturedump.cpp +++ b/examples/creaturedump.cpp @@ -12,6 +12,7 @@ using namespace std; #include #include #include +#include template void print_bits ( T val, std::ostream& out ) @@ -165,14 +166,17 @@ void printCreature(DFHack::API & DF, const DFHack::t_creature & creature) cout << ", nick name: " << creature.name.nickname; addendl = true; } - /* - string transName = DF.TranslateName(creature.name,englishWords,foreignWords,false); + + DFHack::Translation *Tran = DF.getTranslation(); + DFHack::memory_info *mem = DF.getMemoryInfo(); + + string transName = Tran->TranslateName(creature.name,false); if(!transName.empty()) { cout << ", trans name: " << transName; addendl=true; } -*/ + /* cout << ", likes: "; for(uint32_t i = 0;igetProfession(creature.profession) << "(" << (int) creature.profession << ")"; - /* + if(creature.custom_profession[0]) { cout << ", custom profession: " << creature.custom_profession; } + /* if(creature.current_job.active) { cout << ", current job: " << mem->getJob(creature.current_job.jobId); @@ -227,15 +232,37 @@ void printCreature(DFHack::API & DF, const DFHack::t_creature & creature) */ cout << endl; - /* + //skills - for(unsigned int i = 0; i < creature.skills.size();i++){ - if(i > 0){ + cout << "Skills" << endl; + for(unsigned int i = 0; i < creature.numSkills;i++) + { + if(i > 0) + { cout << ", "; } - cout << creature.skills[i].name << ": " << creature.skills[i].rating; + cout << mem->getSkill(creature.skills[i].id) << ": " << creature.skills[i].rating; } - */ + 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 */ @@ -325,6 +352,7 @@ int main (void) DFHack::Creatures * Creatures = DF.getCreatures(); DFHack::Materials * Materials = DF.getMaterials(); + DFHack::Translation * Tran = DF.getTranslation(); uint32_t numCreatures; if(!Creatures->Start(numCreatures)) @@ -358,19 +386,19 @@ int main (void) cerr << "Can't get the creature types." << endl; return 1; } - /* - if(!DF.InitReadNameTables(englishWords,foreignWords)) + + if(!Tran->Start()) { cerr << "Can't get name tables" << endl; return 1; } - */ + //DF.InitViewAndCursor(); for(uint32_t i = 0; i < numCreatures; i++) { DFHack::t_creature temp; Creatures->ReadCreature(i,temp); - //if(string(creaturestypes[temp.type].id) == "DWARF") + if(string(creaturestypes[temp.type].id) == "DWARF") { cout << "index " << i << " "; printCreature(DF,temp); 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 d00993487..927c620c7 100644 --- a/examples/renamer.cpp +++ b/examples/renamer.cpp @@ -12,18 +12,10 @@ using namespace std; #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 +#include +#include "miscutils.h" vector< vector > englishWords; vector< vector > foreignWords; @@ -33,10 +25,11 @@ vector creaturestypes; void printDwarves(DFHack::API & DF) { int dwarfCounter = 0; + DFHack::Creatures * c = DF.getCreatures(); for (uint32_t i = 0; i < numCreatures; i++) { DFHack::t_creature temp; - DF.ReadCreature(i, temp); + c->ReadCreature(i, temp); string type = creaturestypes[temp.type].id; if (type == "DWARF" && !temp.flags1.bits.dead && !temp.flags2.bits.killed) { @@ -148,6 +141,7 @@ bool getDwarfSelection(DFHack::API & DF, DFHack::t_creature & toChange,string & changeString = lastText; return true; } + bool waitTillChanged(DFHack::API &DF, int creatureToCheck, string changeValue, bool isName) { DFHack::DFWindow * w = DF.getWindow(); @@ -313,9 +307,13 @@ bool setCursorToCreature(DFHack::API &DF) int main (void) { DFHack::API DF("Memory.xml"); + DFHack::Creatures *c; + DFHack::Materials *m; try { DF.Attach(); + c = DF.getCreatures(); + } catch (exception& e) { @@ -328,15 +326,16 @@ int main (void) DFHack::memory_info * mem = DF.getMemoryInfo(); - if (!DF.ReadCreatureMatgloss(creaturestypes)) + + if (!m->ReadCreatureTypes(creaturestypes)) { cerr << "Can't get the creature types." << endl; return 1; } DF.InitReadNameTables(englishWords,foreignWords); - DF.InitReadCreatures(numCreatures); - DF.InitViewAndCursor(); + c->Start(numCreatures); + // DF.InitViewAndCursor(); DFHack::Process * p = DF.getProcess(); DFHack::DFWindow * w = DF.getWindow(); 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 ba82b2f87..93452467f 100644 --- a/examples/veccheck.cpp +++ b/examples/veccheck.cpp @@ -1,11 +1,13 @@ // Just show some position data #include +#include #include #include #include #include #include +#include using namespace std; #include @@ -13,30 +15,11 @@ 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 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; -} +#include +#include +#include +#include +#include "miscutils.h" int main (int numargs, const char ** args) { @@ -59,38 +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(); - - 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")); - - DumpObjStr0Vector("Creature types",p, mem->getAddress("mat_creature_types")); - - + #ifndef LINUX_BUILD cout << "Done. Press any key to continue" << endl; cin.ignore(); diff --git a/output/Memory.xml b/output/Memory.xml index f4d5a751d..9eac342f3 100644 --- a/output/Memory.xml +++ b/output/Memory.xml @@ -2800,6 +2800,7 @@ 64 65 + ==================================================================== V -- T A B L E S (for stonesense) @@ -2857,7 +2859,7 @@ 0x18 0xC Vector layout in MSVC 9: - DWORD Allocator + DWORD Allocator? DWORD ? DWORD ? DWORD Start @@ -2865,6 +2867,9 @@ DWORD AllocationEnd 0x1C + +
0x0165B188
Position and window dimensions ============================== @@ -2962,6 +2967,7 @@ map_data_1b60_offset 0x1B9c =========
0x0166ecc4
0x0 + 0x6c 0x88 0x8C 0x90 @@ -2972,6 +2978,14 @@ map_data_1b60_offset 0x1B9c 0x6D0 0x770 0x830 + + 0x073C + 0x1F4 + + +
0x01470fbc
DWORD, OK + This seems to be wrong: + creature_vector = 0x0166ed2c Materials ========= @@ -3012,6 +3026,39 @@ map_data_1b60_offset 0x1B9c
0x016AFE58
+ + Constructions + ============= +
0x165b290
+ 0x14 + + Translations + ============ +
0x016AFFD8
+
0x016B0008
+ 0x4C + + Vegetation + ========== +
0x0167030C
belal: 0x017f6d98 ... what? + 0x6C + + Buildings + ========= + + :( + + Effects + ======= + + :( + + Settlements + =========== + + :( + +