From c7c446a33ad2ce2e15f6f65cdeb3dae09352cb44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Fri, 1 Jan 2010 02:14:41 +0000 Subject: [PATCH] merged previous patch from belal (things intended for Dwarf Therapist) --- library/DFHackAPI.cpp | 140 ++++++++++++++++++++++++++++++++++++++- library/DFHackAPI.h | 8 ++- library/DFTypes.h | 34 +++++++++- output/Memory.xml | 21 ++++++ tools/creaturedump.cpp | 146 ++++++++++++++++++++++++++++++++++++++++- 5 files changed, 342 insertions(+), 7 deletions(-) diff --git a/library/DFHackAPI.cpp b/library/DFHackAPI.cpp index ba081f208..ab0498b82 100644 --- a/library/DFHackAPI.cpp +++ b/library/DFHackAPI.cpp @@ -78,6 +78,7 @@ public: uint32_t creature_labors_offset; uint32_t creature_happiness_offset; uint32_t creature_traits_offset; + uint32_t creature_likes_offset; uint32_t item_material_offset; @@ -358,7 +359,9 @@ void API::getSize (uint32_t& x, uint32_t& y, uint32_t& z) bool API::ReadWoodMatgloss (vector & woods) { + int matgloss_address = d->offset_descriptor->getAddress ("matgloss"); + int matgloss_wood_name_offset = d->offset_descriptor->getOffset("matgloss_wood_name"); // TODO: find flag for autumnal coloring? DfVector p_matgloss = d->dm->readVector (matgloss_address, 4); @@ -379,6 +382,7 @@ bool API::ReadWoodMatgloss (vector & woods) fill_char_buf(mat.id, d->dm->readSTLString(temp)); // reads a C string given an address */ d->dm->readSTLString (temp, mat.id, 128); + d->dm->readSTLString (temp+matgloss_wood_name_offset, mat.name, 128); woods.push_back (mat); } return true; @@ -390,6 +394,8 @@ bool API::ReadStoneMatgloss (vector & stones) int matgloss_address = minfo->getAddress ("matgloss"); int matgloss_offset = minfo->getHexValue ("matgloss_skip"); int matgloss_colors = minfo->getOffset ("matgloss_stone_color"); + int matgloss_stone_name_offset = minfo->getOffset("matgloss_stone_name"); + DfVector p_matgloss = d->dm->readVector (matgloss_address + matgloss_offset, 4); uint32_t size = p_matgloss.getSize(); @@ -403,6 +409,7 @@ bool API::ReadStoneMatgloss (vector & stones) t_matgloss mat; //fill_char_buf(mat.id, d->dm->readSTLString(temp)); // reads a C string given an address d->dm->readSTLString (temp, mat.id, 128); + d->dm->readSTLString (temp+matgloss_stone_name_offset, mat.name, 128); mat.fore = (uint8_t) g_pProcess->readWord (temp + matgloss_colors); mat.back = (uint8_t) g_pProcess->readWord (temp + matgloss_colors + 2); mat.bright = (uint8_t) g_pProcess->readWord (temp + matgloss_colors + 4); @@ -418,6 +425,7 @@ bool API::ReadMetalMatgloss (vector & metals) int matgloss_address = minfo->getAddress ("matgloss"); int matgloss_offset = minfo->getHexValue ("matgloss_skip"); int matgloss_colors = minfo->getOffset ("matgloss_metal_color"); + int matgloss_metal_name_offset = minfo->getOffset("matgloss_metal_name"); DfVector p_matgloss = d->dm->readVector (matgloss_address + matgloss_offset * 3, 4); metals.clear(); @@ -430,6 +438,7 @@ bool API::ReadMetalMatgloss (vector & metals) t_matgloss mat; //fill_char_buf(mat.id, d->dm->readSTLString(temp)); // reads a C string given an address d->dm->readSTLString (temp, mat.id, 128); + d->dm->readSTLString (temp+matgloss_metal_name_offset, mat.name, 128); mat.fore = (uint8_t) g_pProcess->readWord (temp + matgloss_colors); mat.back = (uint8_t) g_pProcess->readWord (temp + matgloss_colors + 2); mat.bright = (uint8_t) g_pProcess->readWord (temp + matgloss_colors + 4); @@ -443,6 +452,7 @@ bool API::ReadPlantMatgloss (vector & plants) memory_info * minfo = d->offset_descriptor; int matgloss_address = minfo->getAddress ("matgloss"); int matgloss_offset = minfo->getHexValue ("matgloss_skip"); + int matgloss_plant_name_offset = minfo->getOffset("matgloss_plant_name"); DfVector p_matgloss = d->dm->readVector (matgloss_address + matgloss_offset * 2, 4); plants.clear(); @@ -459,6 +469,43 @@ bool API::ReadPlantMatgloss (vector & plants) // read the string pointed at by //fill_char_buf(mat.id, d->dm->readSTLString(temp)); // reads a C string given an address d->dm->readSTLString (temp, mat.id, 128); + d->dm->readSTLString (temp+matgloss_plant_name_offset, mat.name, 128); + plants.push_back (mat); + } + return true; +} + +bool API::ReadPlantMatgloss (vector & plants) +{ + memory_info * minfo = d->offset_descriptor; + int matgloss_address = minfo->getAddress ("matgloss"); + int matgloss_offset = minfo->getHexValue ("matgloss_skip"); + int matgloss_plant_name_offset = minfo->getOffset("matgloss_plant_name"); + int matgloss_plant_drink_offset = minfo->getOffset("matgloss_plant_drink"); + int matgloss_plant_food_offset = minfo->getOffset("matgloss_plant_food"); + int matgloss_plant_extract_offset = minfo->getOffset("matgloss_plant_extract"); + DfVector p_matgloss = d->dm->readVector (matgloss_address + matgloss_offset * 2, 4); + + plants.clear(); + + // TODO: use green? + t_matglossPlant mat; + mat.fore = 7; + mat.back = 0; + mat.bright = 0; + for (uint32_t i = 0; i < p_matgloss.getSize();i++) + { + // read the matgloss pointer from the vector into temp + uint32_t temp = * (uint32_t *) p_matgloss[i]; + // read the string pointed at by + //fill_char_buf(mat.id, d->dm->readSTLString(temp)); // reads a C string given an address + d->dm->readSTLString (temp, mat.id, 128); + d->dm->readSTLString (temp+matgloss_plant_name_offset, mat.name, 128); + d->dm->readSTLString (temp+matgloss_plant_drink_offset, mat.drink_name, 128); + d->dm->readSTLString (temp+matgloss_plant_food_offset, mat.food_name, 128); + d->dm->readSTLString (temp+matgloss_plant_extract_offset, mat.extract_name, 128); + + //d->dm->readSTLString (temp plants.push_back (mat); } return true; @@ -469,6 +516,7 @@ bool API::ReadCreatureMatgloss (vector & creatures) memory_info * minfo = d->offset_descriptor; int matgloss_address = minfo->getAddress ("matgloss"); int matgloss_offset = minfo->getHexValue ("matgloss_skip"); + int matgloss_creature_name_offset = minfo->getOffset("matgloss_creature_name"); DfVector p_matgloss = d->dm->readVector (matgloss_address + matgloss_offset * 6, 4); creatures.clear(); @@ -485,6 +533,7 @@ bool API::ReadCreatureMatgloss (vector & creatures) // read the string pointed at by //fill_char_buf(mat.id, d->dm->readSTLString(temp)); // reads a C string given an address d->dm->readSTLString (temp, mat.id, 128); + d->dm->readSTLString (temp+matgloss_creature_name_offset, mat.name, 128); creatures.push_back (mat); } return true; @@ -741,6 +790,7 @@ uint32_t API::InitReadCreatures() d->creature_labors_offset = minfo->getOffset ("creature_labors"); d->creature_happiness_offset = minfo->getOffset ("creature_happiness"); d->creature_traits_offset = minfo->getOffset ("creature_traits"); + d->creature_likes_offset = minfo->getOffset("creature_likes"); if (creatures && d->creature_pos_offset && d->creature_type_offset @@ -762,6 +812,7 @@ uint32_t API::InitReadCreatures() && d->creature_labors_offset && d->creature_happiness_offset && d->creature_traits_offset + // && d->creature_likes_offset ) { d->p_cre = new DfVector (d->dm->readVector (creatures, 4)); @@ -889,7 +940,16 @@ bool API::ReadCreature (const int32_t &index, t_creature & furball) { furball.current_job.jobId = g_pProcess->readByte (jobIdAddr + d->creature_current_job_id_offset); } - + + //likes + DfVector likes(d->dm->readVector(temp+d->creature_likes_offset,4)); + furball.numLikes = likes.getSize(); + for(uint32_t i = 0;ireadDWord (temp + d->creature_happiness_offset, furball.happiness); g_pProcess->readDWord (temp + d->creature_id_offset, furball.id); g_pProcess->readDWord (temp + d->creature_agility_offset, furball.agility); @@ -901,6 +961,12 @@ bool API::ReadCreature (const int32_t &index, t_creature & furball) return true; } +void API::WriteLabors(const uint32_t &index, uint8_t labors[NUM_CREATURE_LABORS]) +{ + uint32_t temp = * (uint32_t *) d->p_cre->at (index); + WriteRaw(temp + d->creature_labors_offset, NUM_CREATURE_LABORS, labors); +} + void API::InitReadNameTables (map< string, vector > & nameTable) { int genericAddress = d->offset_descriptor->getAddress ("language_vector"); @@ -1243,3 +1309,75 @@ bool API::ReadViewScreen (t_viewscreen &screen) } return d->offset_descriptor->resolveClassId (last, screen.type); } +bool API::ReadItemTypes(vector< vector< t_itemType > > & itemTypes) +{ + memory_info * minfo = d->offset_descriptor; + int matgloss_address = minfo->getAddress("matgloss"); + int matgloss_skip = minfo->getHexValue("matgloss_skip"); + int item_type_name_offset = minfo->getOffset("item_type_name"); + for(int i = 8;i<20;i++){ + DfVector p_temp = d->dm->readVector(matgloss_address + i*matgloss_skip,4); + vector< t_itemType > typesForVec; + for(uint32_t j =0; jdm->readSTLString(temp+4,currType.id,128); + d->dm->readSTLString(temp+item_type_name_offset,currType.name,128); + //stringsForVec.push_back(string(name)); + typesForVec.push_back(currType); + } + itemTypes.push_back(typesForVec); + } + return true; +} +bool API::ReadAllMatgloss(vector< vector< string > > & all) +{ + memory_info * minfo = d->offset_descriptor; + int matgloss_address = minfo->getAddress("matgloss"); + int matgloss_skip = minfo->getHexValue("matgloss_skip"); + for(int i = 0;i<7;i++){ + DfVector p_temp = d->dm->readVector(matgloss_address + i*matgloss_skip,4); + vector< string > stringsForVec; + for(uint32_t j =0; jdm->readSTLString(temp); + stringsForVec.push_back(tempStr); + } + all.push_back(stringsForVec); + } + for(int i = 7;i<22;i++){ + DfVector p_temp = d->dm->readVector(matgloss_address + i*matgloss_skip,4); + vector< string > stringsForVec; + for(uint32_t j =0; jdm->readSTLString(temp+4); + stringsForVec.push_back(tempStr); + } + all.push_back(stringsForVec); + } + for(int i = 22;i<25;i++){ + DfVector p_temp = d->dm->readVector(matgloss_address + i*matgloss_skip,4); + vector< string > stringsForVec; + for(uint32_t j =0; jdm->readSTLString(temp); + stringsForVec.push_back(tempStr); + } + all.push_back(stringsForVec); + } + DfVector p_temp = d->dm->readVector(0x01604104,4); + vector< string > stringsForVec; + for(uint32_t j =0; jdm->readSTLString(temp); + stringsForVec.push_back(tempStr); + } + all.push_back(stringsForVec); + return true; +} diff --git a/library/DFHackAPI.h b/library/DFHackAPI.h index ac59095bd..02a446caf 100644 --- a/library/DFHackAPI.h +++ b/library/DFHackAPI.h @@ -74,6 +74,7 @@ namespace DFHack bool ReadWoodMatgloss (vector & output); bool ReadMetalMatgloss(vector & output); bool ReadPlantMatgloss(vector & output); + bool ReadPlantMatgloss (vector & plants); bool ReadCreatureMatgloss(vector & output); // read region surroundings, get their vectors of geolayers so we can do translation (or just hand the translation table to the client) @@ -198,7 +199,9 @@ namespace DFHack string TranslateName(const t_lastname & last, const map< string, vector< string > > &nameTable,const string & language="GENERIC"); string TranslateName(const t_squadname & squad, const map< string, vector< string > > &nameTable,const string & language="GENERIC"); - + + void WriteLabors(const uint32_t &index, uint8_t labors[NUM_CREATURE_LABORS]); + uint32_t InitReadItems(); bool ReadItem(const uint32_t &index, t_item & item); void FinishReadItems(); @@ -206,6 +209,9 @@ namespace DFHack memory_info getMemoryInfo(); Process * getProcess(); DFWindow * getWindow(); + + bool ReadAllMatgloss(vector< vector< string > > & all); + bool ReadItemTypes(vector< vector< t_itemType > > & itemTypes); }; } // namespace DFHack #endif // SIMPLEAPI_H_INCLUDED diff --git a/library/DFTypes.h b/library/DFTypes.h index cfb2de2c3..60a5d5335 100644 --- a/library/DFTypes.h +++ b/library/DFTypes.h @@ -32,11 +32,25 @@ namespace DFHack struct t_matgloss { - char id[128]; + char id[128]; //the id in the raws uint8_t fore; // Annoyingly the offset for this differs between types uint8_t back; uint8_t bright; + char name[128]; //this is the name displayed ingame }; + +struct t_matglossPlant +{ + char id[128]; //the id in the raws + uint8_t fore; // Annoyingly the offset for this differs between types + uint8_t back; + uint8_t bright; + char name[128]; //this is the name displayed ingame + char drink_name[128]; //the name this item becomes a drink + char food_name[128]; + char extract_name[128]; +}; + struct t_vein { uint32_t vtable; @@ -476,7 +490,14 @@ 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; +}; #define NUM_CREATURE_TRAITS 30 #define NUM_CREATURE_LABORS 102 struct t_creature @@ -504,6 +525,8 @@ struct t_creature //string last_name; string current_job; */ + uint8_t numLikes; + t_like likes[32]; t_job current_job; uint32_t happiness; uint32_t id; @@ -552,6 +575,13 @@ struct t_item // FIXME: not complete, we need building presence bitmaps for stuff like farm plots and stockpiles, orientation (N,E,S,W) and state (open/closed) }; +// can add more here later, but this is fine for now +struct t_itemType +{ + char id[128]; + char name[128]; +}; + // TODO: research this further? consult DF hacker wizards? union t_designation { diff --git a/output/Memory.xml b/output/Memory.xml index a6e8207ad..c59fd88d0 100644 --- a/output/Memory.xml +++ b/output/Memory.xml @@ -1090,6 +1090,17 @@ + + 0x24 + 0x1C + 0x28 + 0x24 + 0x24 + 0x24 + 0x5C + 0x94 + 0xB0 + .-"""-. @@ -1162,6 +1173,7 @@ 0x0338 0x033C 0x0340 + 0x034C 0x0364 0x0400 0x0490 @@ -1538,6 +1550,15 @@ + 0xC + 0x4 + 0x10 + 0xC + 0xC + 0xC + 0x14 + 0x1C + 0x20 diff --git a/tools/creaturedump.cpp b/tools/creaturedump.cpp index b72a6f721..255c11fb9 100644 --- a/tools/creaturedump.cpp +++ b/tools/creaturedump.cpp @@ -20,19 +20,150 @@ void print_bits ( T val, std::ostream& out ) val >>= 1; } } +struct matGlosses +{ + vector plantMat; + vector woodMat; + vector stoneMat; + vector metalMat; + vector creatureMat; +}; +enum likeType +{ + FAIL = 0, + MATERIAL = 1, + ITEM = 2, + FOOD = 3 +}; + +likeType printLike(DFHack::t_like like, const matGlosses & mat,const vector< vector > & itemTypes) +{ // The function in DF which prints out the likes is a monster, it is a huge switch statement with tons of options and calls a ton of other functions as well, + //so I am not going to try and put all the possibilites here, only the low hanging fruit, with stones and metals, as well as items, + //you can easily find good canidates for military duty for instance + //The ideal thing to do would be to call the df function directly with the desired likes, the df function modifies a string, so it should be possible to do... + if(like.active){ + if(like.type ==0){ + switch (like.material.type) + { + case 0: + cout << mat.woodMat[like.material.index].name; + return(MATERIAL); + case 1: + cout << mat.stoneMat[like.material.index].name; + return(MATERIAL); + case 2: + cout << mat.metalMat[like.material.index].name; + return(MATERIAL); + case 12: // don't ask me why this has such a large jump, maybe this is not actually the matType for plants, but they all have this set to 12 + cout << mat.plantMat[like.material.index].name; + return(MATERIAL); + case 32: + cout << mat.plantMat[like.material.index].name; + return(MATERIAL); + case 121: + cout << mat.creatureMat[like.material.index].name; + return(MATERIAL); + default: + return(FAIL); + } + } + else if(like.type == 4 && like.itemIndex != -1){ + switch(like.itemClass) + { + case 24: + cout << itemTypes[0][like.itemIndex].name; + return(ITEM); + case 25: + cout << itemTypes[4][like.itemIndex].name; + return(ITEM); + case 26: + cout << itemTypes[8][like.itemIndex].name; + return(ITEM); + case 27: + cout << itemTypes[9][like.itemIndex].name; + return(ITEM); + case 28: + cout << itemTypes[10][like.itemIndex].name; + return(ITEM); + case 29: + cout << itemTypes[7][like.itemIndex].name; + return(ITEM); + case 38: + cout << itemTypes[5][like.itemIndex].name; + return(ITEM); + case 63: + cout << itemTypes[11][like.itemIndex].name; + return(ITEM); + case 68: + case 69: + cout << itemTypes[6][like.itemIndex].name; + return(ITEM); + case 70: + cout << itemTypes[1][like.itemIndex].name; + return(ITEM); + default: + // cout << like.itemClass << ":" << like.itemIndex; + return(FAIL); + } + } + else if(like.material.type != -1){// && like.material.index == -1){ + if(like.type == 2){ + switch(like.itemClass) + { + case 52: + case 53: + case 58: + cout << mat.plantMat[like.material.type].name; + return(FOOD); + case 72: + if(like.material.type =! 10){ // 10 is for milk stuff, which I don't know how to do + cout << mat.plantMat[like.material.index].extract_name; + return(FOOD); + } + return(FAIL); + case 74: + cout << mat.plantMat[like.material.index].drink_name; + return(FOOD); + case 75: + cout << mat.plantMat[like.material.index].food_name; + return(FOOD); + case 47: + case 48: + cout << mat.creatureMat[like.material.type].name; + return(FOOD); + default: + return(FAIL); + } + } + } + } + return(FAIL); +} int main (void) { vector creaturestypes; - +// t_matglossPlant test; DFHack::API DF("Memory.xml"); if(!DF.Attach()) { cerr << "DF not found" << endl; return 1; } - + vector buildingtypes; + uint32_t numBuildings = DF.InitReadBuildings(buildingtypes); + //vector< vector > all; + vector< vector > itemTypes; + DF.ReadItemTypes(itemTypes); + //DF.ReadAllMatgloss(all); + matGlosses mat; + DF.ReadPlantMatgloss(mat.plantMat); + DF.ReadWoodMatgloss(mat.woodMat); + DF.ReadStoneMatgloss(mat.stoneMat); + DF.ReadMetalMatgloss(mat.metalMat); + DF.ReadCreatureMatgloss(mat.creatureMat); + DFHack::memory_info mem = DF.getMemoryInfo(); // get stone matgloss mapping if(!DF.ReadCreatureMatgloss(creaturestypes)) @@ -46,8 +177,11 @@ int main (void) uint32_t numCreatures = DF.InitReadCreatures(); for(uint32_t i = 0; i < numCreatures; i++) { + DF.Suspend(); DFHack::t_creature temp; DF.ReadCreature(i, temp); + DF.ForceResume(); + if(string(creaturestypes[temp.type].id) == "DWARF"){ cout << "address: " << temp.origin << " creature type: " << creaturestypes[temp.type].id << ", position: " << temp.x << "x " << temp.y << "y "<< temp.z << "z" << endl; bool addendl = false; if(temp.first_name[0]) @@ -76,6 +210,11 @@ int main (void) addendl=true; } */ + cout << ", likes: "; + for(uint32_t i = 0;i