From 51a1ec5c1e96bf950532246d785c73b0fe18880e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sun, 4 Apr 2010 12:29:56 +0200 Subject: [PATCH] Very basic creature reading --- dfhack/DFHackAPI.cpp | 11 ----- dfhack/modules/Creatures-data.h | 2 +- dfhack/modules/Creatures-proc.h | 5 +- dfhack/modules/Creatures.cpp | 83 +++++++++++++++---------------- dfhack/modules/Materials.cpp | 9 +++- dfhack/private/APIPrivate.h | 3 +- dfhack/shm/mod-creature2010.h | 87 +++++++++++++++++++++++++++++++++ examples/CMakeLists.txt | 4 +- examples/creaturedump.cpp | 46 ++++++++++------- output/Memory.xml | 6 ++- 10 files changed, 176 insertions(+), 80 deletions(-) create mode 100644 dfhack/shm/mod-creature2010.h diff --git a/dfhack/DFHackAPI.cpp b/dfhack/DFHackAPI.cpp index bcdee6efc..3655cb9bb 100644 --- a/dfhack/DFHackAPI.cpp +++ b/dfhack/DFHackAPI.cpp @@ -707,17 +707,6 @@ void API::FinishReadNameTables() d->nameTablesInited = false; } -void API::FinishReadCreatures() -{ - if(d->p_cre) - { - delete d->p_cre; - d->p_cre = 0; - } - d->creaturesInited = false; - //FinishReadNameTables(); -} - void API::FinishReadNotes() { if(d->p_notes) diff --git a/dfhack/modules/Creatures-data.h b/dfhack/modules/Creatures-data.h index 0a11df357..f8630ceb4 100644 --- a/dfhack/modules/Creatures-data.h +++ b/dfhack/modules/Creatures-data.h @@ -1,4 +1,4 @@ bool creaturesInited; -Creatures::creature_offsets creatures; +Creatures2010::creature_offsets creatures; uint32_t creature_module; DfVector *p_cre; \ No newline at end of file diff --git a/dfhack/modules/Creatures-proc.h b/dfhack/modules/Creatures-proc.h index 9b980903b..6e9c3cfce 100644 --- a/dfhack/modules/Creatures-proc.h +++ b/dfhack/modules/Creatures-proc.h @@ -9,6 +9,7 @@ int32_t ReadCreatureInBox(const int32_t index, t_creature & furball, const uint16_t x1, const uint16_t y1,const uint16_t z1, const uint16_t x2, const uint16_t y2,const uint16_t z2); bool ReadCreature(const int32_t index, t_creature & furball); -void FinishReadCreatures(); /// write labors of a creature (for Dwarf Therapist) -bool WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]); \ No newline at end of file +//bool WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]); + +void FinishReadCreatures(); \ No newline at end of file diff --git a/dfhack/modules/Creatures.cpp b/dfhack/modules/Creatures.cpp index b16c7b2ad..c8280543b 100644 --- a/dfhack/modules/Creatures.cpp +++ b/dfhack/modules/Creatures.cpp @@ -25,68 +25,47 @@ distribution. #include "DFCommonInternal.h" #include "../private/APIPrivate.h" -#define SHMCREATURESHDR ((Creatures::shm_creature_hdr *)d->shm_start) +#define SHMCREATURESHDR ((Creatures2010::shm_creature_hdr *)d->shm_start) using namespace DFHack; -/* + bool API::InitReadCreatures( uint32_t &numcreatures ) { if(!d->InitReadNames()) return false; try { memory_info * minfo = d->offset_descriptor; - Creatures::creature_offsets & off = d->creatures; - off.creature_vector = minfo->getAddress ("creatures"); + Creatures2010::creature_offsets & off = d->creatures; + off.creature_vector = minfo->getAddress ("creature_vector"); off.creature_pos_offset = minfo->getOffset ("creature_position"); - off.creature_type_offset = minfo->getOffset ("creature_race"); + off.creature_profession_offset = minfo->getOffset ("creature_profession"); + off.creature_race_offset = minfo->getOffset ("creature_race"); off.creature_flags1_offset = minfo->getOffset ("creature_flags1"); off.creature_flags2_offset = minfo->getOffset ("creature_flags2"); off.creature_name_offset = minfo->getOffset ("creature_name"); - off.creature_custom_profession_offset = minfo->getOffset ("creature_custom_profession"); - off.creature_profession_offset = minfo->getOffset ("creature_profession"); off.creature_sex_offset = minfo->getOffset ("creature_sex"); off.creature_id_offset = minfo->getOffset ("creature_id"); - off.creature_squad_name_offset = minfo->getOffset ("creature_squad_name"); - off.creature_squad_leader_id_offset = minfo->getOffset ("creature_squad_leader_id"); - off.creature_money_offset = minfo->getOffset ("creature_money"); - off.creature_current_job_offset = minfo->getOffset ("creature_current_job"); - off.creature_current_job_id_offset = minfo->getOffset ("current_job_id"); - off.creature_strength_offset = minfo->getOffset ("creature_strength"); - off.creature_agility_offset = minfo->getOffset ("creature_agility"); - off.creature_toughness_offset = minfo->getOffset ("creature_toughness"); - off.creature_skills_offset = minfo->getOffset ("creature_skills"); off.creature_labors_offset = minfo->getOffset ("creature_labors"); off.creature_happiness_offset = minfo->getOffset ("creature_happiness"); - off.creature_traits_offset = minfo->getOffset ("creature_traits"); - off.creature_likes_offset = minfo->getOffset("creature_likes"); off.creature_artifact_name_offset = minfo->getOffset("creature_artifact_name"); - off.creature_mood_offset = minfo->getOffset("creature_mood"); - - off.creature_pregnancy_offset = minfo->getOffset("creature_pregnancy"); - off.creature_blood_max_offset = minfo->getOffset("creature_blood_max"); - off.creature_blood_current_offset = minfo->getOffset("creature_blood_current"); - off.creature_bleed_offset = minfo->getOffset("creature_bleed"); // name offsets for the creature module off.name_firstname_offset = minfo->getOffset("name_firstname"); off.name_nickname_offset = minfo->getOffset("name_nickname"); off.name_words_offset = minfo->getOffset("name_words"); - // HACK: vector correction. No longer relevant. - off.vector_correct = 0; - d->p_cre = new DfVector (d->p, off.creature_vector, 4); d->creaturesInited = true; numcreatures = d->p_cre->getSize(); // --> SHM initialization (if possible) <-- - g_pProcess->getModuleIndex("Creatures40d",1,d->creature_module); + g_pProcess->getModuleIndex("Creatures2010",1,d->creature_module); if(d->creature_module) { // supply the module with offsets so it can work with them - memcpy(SHMDATA(Creatures::creature_offsets),&d->creatures,sizeof(Creatures::creature_offsets)); - const uint32_t cmd = Creatures::CREATURE_INIT + (d->creature_module << 16); + memcpy(SHMDATA(Creatures2010::creature_offsets),&d->creatures,sizeof(Creatures2010::creature_offsets)); + const uint32_t cmd = Creatures2010::CREATURE_INIT + (d->creature_module << 16); g_pProcess->SetAndWait(cmd); } return true; @@ -106,7 +85,7 @@ bool API::ReadCreature (const int32_t index, t_creature & furball) { // supply the module with offsets so it can work with them SHMCREATURESHDR->index = index; - const uint32_t cmd = Creatures::CREATURE_AT_INDEX + (d->creature_module << 16); + const uint32_t cmd = Creatures2010::CREATURE_AT_INDEX + (d->creature_module << 16); g_pProcess->SetAndWait(cmd); memcpy(&furball,SHMDATA(t_creature),sizeof(t_creature)); // cerr << "creature read from SHM!" << endl; @@ -115,24 +94,25 @@ bool API::ReadCreature (const int32_t index, t_creature & furball) // read pointer from vector at position uint32_t temp = * (uint32_t *) d->p_cre->at (index); furball.origin = temp; - Creatures::creature_offsets &offs = d->creatures; + Creatures2010::creature_offsets &offs = d->creatures; //read creature from memory g_pProcess->read (temp + offs.creature_pos_offset, 3 * sizeof (uint16_t), (uint8_t *) & (furball.x)); // xyz really - g_pProcess->readDWord (temp + offs.creature_type_offset, furball.type); + g_pProcess->readDWord (temp + offs.creature_race_offset, furball.type); g_pProcess->readDWord (temp + offs.creature_flags1_offset, furball.flags1.whole); g_pProcess->readDWord (temp + offs.creature_flags2_offset, furball.flags2.whole); // names d->readName(furball.name,temp + offs.creature_name_offset); - d->readName(furball.squad_name, temp + offs.creature_squad_name_offset); + //d->readName(furball.squad_name, temp + offs.creature_squad_name_offset); 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, d->p->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); + //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++) @@ -144,9 +124,11 @@ bool API::ReadCreature (const int32_t index, t_creature & furball) 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 + /* uint32_t jobIdAddr = g_pProcess->readDWord (temp + offs.creature_current_job_offset); if (jobIdAddr) @@ -158,8 +140,9 @@ bool API::ReadCreature (const int32_t index, t_creature & furball) { furball.current_job.active = false; } - +*/ //likes + /* DfVector likes(d->p, temp + offs.creature_likes_offset, 4); furball.numLikes = likes.getSize(); for(uint32_t i = 0;ireadWord (temp + offs.creature_mood_offset); - +*/ g_pProcess->readDWord (temp + offs.creature_happiness_offset, furball.happiness); g_pProcess->readDWord (temp + offs.creature_id_offset, furball.id); + /* g_pProcess->readDWord (temp + offs.creature_agility_offset, furball.agility); g_pProcess->readDWord (temp + offs.creature_strength_offset, furball.strength); g_pProcess->readDWord (temp + offs.creature_toughness_offset, furball.toughness); g_pProcess->readDWord (temp + offs.creature_money_offset, furball.money); furball.squad_leader_id = (int32_t) g_pProcess->readDWord (temp + offs.creature_squad_leader_id_offset); + */ g_pProcess->readByte (temp + offs.creature_sex_offset, furball.sex); - +/* g_pProcess->readDWord(temp + offs.creature_pregnancy_offset, furball.pregnancy_timer); furball.blood_max = (int32_t) g_pProcess->readDWord(temp + offs.creature_blood_max_offset); furball.blood_current = (int32_t) g_pProcess->readDWord(temp + offs.creature_blood_current_offset); g_pProcess->readDWord(temp + offs.creature_bleed_offset, furball.bleed_rate); - +*/ return true; } - +/* bool API::WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]) { if(!d->creaturesInited) return false; uint32_t temp = * (uint32_t *) d->p_cre->at (index); WriteRaw(temp + d->creatures.creature_labors_offset, NUM_CREATURE_LABORS, labors); } - - +*/ +/* bool API::getCurrentCursorCreature(uint32_t & creature_index) { if(!d->cursorWindowInited) return false; creature_index = g_pProcess->readDWord(d->current_cursor_creature_offset); return true; } -*/ \ No newline at end of file +*/ +void API::FinishReadCreatures() +{ + if(d->p_cre) + { + delete d->p_cre; + d->p_cre = 0; + } + d->creaturesInited = false; + //FinishReadNameTables(); +} \ No newline at end of file diff --git a/dfhack/modules/Materials.cpp b/dfhack/modules/Materials.cpp index bdd1ba2d9..b3ee08f2a 100644 --- a/dfhack/modules/Materials.cpp +++ b/dfhack/modules/Materials.cpp @@ -188,9 +188,16 @@ bool API::ReadPlantMaterials (vector & plants) { return ReadNamesOnly(d->p, d->offset_descriptor->getAddress ("mat_organics_plants"), plants ); } - +/* +Gives bad results combined with the creature race field! bool API::ReadCreatureTypes (vector & creatures) { return ReadNamesOnly(d->p, d->offset_descriptor->getAddress ("mat_creature_types"), creatures ); return true; } +*/ +bool API::ReadCreatureTypes (vector & creatures) +{ + return ReadNamesOnly(d->p, d->offset_descriptor->getAddress ("creature_type_vector"), creatures ); + return true; +} diff --git a/dfhack/private/APIPrivate.h b/dfhack/private/APIPrivate.h index 6c3752a7f..930691ad0 100644 --- a/dfhack/private/APIPrivate.h +++ b/dfhack/private/APIPrivate.h @@ -33,7 +33,8 @@ distribution. #include #include #include -#include +// #include +#include #define SHMCMD(num) ((shm_cmd *)d->shm_start)[num]->pingpong #define SHMHDR ((shm_core_hdr *)d->shm_start) diff --git a/dfhack/shm/mod-creature2010.h b/dfhack/shm/mod-creature2010.h new file mode 100644 index 000000000..620d21f9d --- /dev/null +++ b/dfhack/shm/mod-creature2010.h @@ -0,0 +1,87 @@ +/* +www.sourceforge.net/projects/dfhack +Copyright (c) 2009 Petr Mrázek (peterix) + +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. +*/ + +#ifndef MOD_CREATURES2010_H +#define MOD_CREATURES2010_H + +namespace DFHack +{ + namespace Creatures2010 + { + +#define CREATURES2010_VERSION 1 +typedef struct +{ + // creature offsets + uint32_t creature_vector; + uint32_t creature_pos_offset; + uint32_t creature_profession_offset; + uint32_t creature_race_offset; + uint32_t creature_flags1_offset; + uint32_t creature_flags2_offset; + uint32_t creature_name_offset; + uint32_t creature_sex_offset; + uint32_t creature_id_offset; + uint32_t creature_labors_offset; + uint32_t creature_happiness_offset; + uint32_t creature_artifact_name_offset; + // name offsets (needed for reading creature names) + uint32_t name_firstname_offset; + uint32_t name_nickname_offset; + uint32_t name_words_offset; +} creature_offsets; + +typedef struct +{ + bool inited; + creature_offsets offsets; +} creature_modulestate; + +typedef struct +{ + shm_cmd cmd[SHM_MAX_CLIENTS]; // MANDATORY! + // box + uint32_t x; + uint32_t y; + uint32_t z; + uint32_t x2; + uint32_t y2; + uint32_t z2; + // starting index + int32_t index; +} shm_creature_hdr; + +enum CREATURE_COMMAND +{ + CREATURE_INIT = 0, // initialization + CREATURE_FIND_IN_BOX, + CREATURE_AT_INDEX, + NUM_CREATURE_CMDS, +}; +DFPP_module Init(void); + + } +} + +#endif \ No newline at end of file diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 4569dd33f..e430b94b0 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -18,8 +18,8 @@ ADD_EXECUTABLE(dfexpbench expbench.cpp) TARGET_LINK_LIBRARIES(dfexpbench dfhack) # creaturedump - basic creature dump - a test of the creature related exports -# ADD_EXECUTABLE(dfcreaturedump creaturedump.cpp) -# TARGET_LINK_LIBRARIES(dfcreaturedump dfhack) +ADD_EXECUTABLE(dfcreaturedump creaturedump.cpp) +TARGET_LINK_LIBRARIES(dfcreaturedump dfhack) # materialtest - just list the first material of each type ADD_EXECUTABLE(dfmaterialtest materialtest.cpp) diff --git a/examples/creaturedump.cpp b/examples/creaturedump.cpp index 125f802dc..73d9afdcc 100644 --- a/examples/creaturedump.cpp +++ b/examples/creaturedump.cpp @@ -43,8 +43,8 @@ vector< vector > itemTypes; DFHack::memory_info *mem; vector< vector > englishWords; vector< vector > foreignWords; - -likeType printLike(DFHack::t_like like, const matGlosses & mat,const vector< vector > & itemTypes) +/* +likeType printLike40d(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 @@ -147,7 +147,7 @@ likeType printLike(DFHack::t_like like, const matGlosses & mat,const vector< vec } return(FAIL); } - +*/ void printCreature(DFHack::API & DF, const DFHack::t_creature & creature) { @@ -163,13 +163,15 @@ 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); if(!transName.empty()) { cout << ", trans name: " << transName; addendl=true; } - +*/ + /* cout << ", likes: "; for(uint32_t i = 0;igetProfession(creature.profession) << "(" << (int) creature.profession << ")"; + cout << "profession: " /*<< mem->getProfession(creature.profession) <<*/ "(" << (int) creature.profession << ")"; + /* if(creature.custom_profession[0]) { cout << ", custom profession: " << creature.custom_profession; @@ -192,16 +196,18 @@ void printCreature(DFHack::API & DF, const DFHack::t_creature & creature) { cout << ", current job: " << mem->getJob(creature.current_job.jobId); } + */ cout << endl; - cout << "happiness: " << creature.happiness << ", strength: " << creature.strength << ", agility: " - << creature.agility << ", toughness: " << creature.toughness << ", money: " << creature.money << ", id: " << creature.id; + cout << "happiness: " << creature.happiness /*<< ", strength: " << creature.strength << ", agility: " + << creature.agility << ", toughness: " << creature.toughness << ", money: " << creature.money*/ << ", id: " << creature.id; + /* if(creature.squad_leader_id != -1) { cout << ", squad_leader_id: " << creature.squad_leader_id; } if(creature.mood != -1){ cout << ", mood: " << creature.mood << " "; - } + }*/ cout << ", sex: "; if(creature.sex == 0) { @@ -212,10 +218,11 @@ void printCreature(DFHack::API & DF, const DFHack::t_creature & creature) cout <<"Male"; } cout << endl; - + /* if(creature.pregnancy_timer > 0) cout << "gives birth in " << creature.pregnancy_timer/1200 << " days. "; cout << "Blood: " << creature.blood_current << "/" << creature.blood_max << " bleeding: " << creature.bleed_rate; + */ cout << endl; /* @@ -288,10 +295,12 @@ void printCreature(DFHack::API & DF, const DFHack::t_creature & creature) cout << "from the underworld, "; } cout << endl; - if(creature.flags1.bits.had_mood && (creature.mood == -1 || creature.mood == 8 ) ){ + /* + if(creature.flags1.bits.had_mood && (creature.mood == -1 || creature.mood == 8 ) ) + { string artifact_name = DF.TranslateName(creature.artifact_name,englishWords,foreignWords,false); cout << "artifact: " << artifact_name << endl; - } + }*/ cout << endl; } @@ -329,28 +338,29 @@ int main (void) #endif return 1; } - + /* DF.ReadItemTypes(itemTypes); DF.ReadPlantMatgloss(mat.plantMat); DF.ReadWoodMatgloss(mat.woodMat); DF.ReadStoneMatgloss(mat.stoneMat); DF.ReadMetalMatgloss(mat.metalMat); DF.ReadCreatureMatgloss(mat.creatureMat); - + */ mem = DF.getMemoryInfo(); // get stone matgloss mapping - if(!DF.ReadCreatureMatgloss(creaturestypes)) + if(!DF.ReadCreatureTypes(creaturestypes)) { cerr << "Can't get the creature types." << endl; return 1; } - + /* if(!DF.InitReadNameTables(englishWords,foreignWords)) { cerr << "Can't get name tables" << endl; return 1; } - DF.InitViewAndCursor(); + */ + //DF.InitViewAndCursor(); for(uint32_t i = 0; i < numCreatures; i++) { DFHack::t_creature temp; @@ -361,6 +371,7 @@ int main (void) printCreature(DF,temp); } } + /* uint32_t currentIdx; DFHack::t_creature currentCreature; DF.getCurrentCursorCreature(currentIdx); @@ -368,6 +379,7 @@ int main (void) DF.ReadCreature(currentIdx, currentCreature); printCreature(DF,currentCreature); + */ DF.FinishReadCreatures(); DF.Detach(); #ifndef LINUX_BUILD diff --git a/output/Memory.xml b/output/Memory.xml index 933a4a8a1..227c66a0e 100644 --- a/output/Memory.xml +++ b/output/Memory.xml @@ -3132,6 +3132,8 @@ =========
0x0166ecc4
0x0 + 0x88 + 0x8C 0x90 0xF8 0xFC @@ -3174,8 +3176,10 @@
0x16AFDDC
0x16AFDF4
- +
0x16AFE0C
+ +
0x016AFE58