From 549b845738c97e212cf60d6e47d2f6f9373e006b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Tue, 13 Apr 2010 00:03:29 +0200 Subject: [PATCH] Custom buildings (tested) --- dfhack/DFMemInfo.cpp | 16 ++++++++++++ dfhack/include/DFMemInfo.h | 5 +--- dfhack/include/modules/Buildings.h | 6 +++++ dfhack/modules/Buildings.cpp | 41 ++++++++++++++++++++++++++++-- examples/buildingsdump.cpp | 9 ++++++- output/Memory.xml | 5 ++++ 6 files changed, 75 insertions(+), 7 deletions(-) diff --git a/dfhack/DFMemInfo.cpp b/dfhack/DFMemInfo.cpp index af8aa875e..621ac56c2 100644 --- a/dfhack/DFMemInfo.cpp +++ b/dfhack/DFMemInfo.cpp @@ -393,6 +393,22 @@ bool memory_info::resolveClassnameToVPtr(const string classname, uint32_t & vptr return false; } +bool memory_info::resolveClassnameToClassID (const string classname, int32_t & classID) +{ + // FIXME: another stupid search. + classID = -1; + for(uint32_t i = 0;i< d->classnames.size();i++) + { + if(d->classnames[i] == classname) + { + classID = i; + return true; + } + } + // we failed to find anything that would match + return false; +} + bool memory_info::resolveClassIDToClassname (const int32_t classID, string & classname) { if (classID >=0 && (uint32_t)classID < d->classnames.size()) diff --git a/dfhack/include/DFMemInfo.h b/dfhack/include/DFMemInfo.h index 3712031d1..7b4be6cf8 100644 --- a/dfhack/include/DFMemInfo.h +++ b/dfhack/include/DFMemInfo.h @@ -160,18 +160,15 @@ namespace DFHack bool resolveObjectToClassID (const uint32_t address, int32_t & classID); /* - * Get a classID from an address. The address has to point to the start of a virtual object (one with a virtual base class) - * can fail if the class is not in the cache + * Get a ClassID when you know the classname. can fail if the class is not in the cache */ bool resolveClassnameToClassID (const string classname, int32_t & classID); - //bool resolveClassnameToClassID (const char * classname, int32_t & classID); /* * Get a vptr from a classname. Can fail if the type is not in the cache * limited to normal classes, variable-dependent types will resolve to the base class */ bool resolveClassnameToVPtr ( const string classname, uint32_t & vptr ); - //bool resolveClassnameToVPtr ( const char * classname, uint32_t & vptr ); /* * Get a classname from a previous classID. Can fail if the type is not in the cache (you use bogus classID) diff --git a/dfhack/include/modules/Buildings.h b/dfhack/include/modules/Buildings.h index fd3589bee..1d27a6f41 100644 --- a/dfhack/include/modules/Buildings.h +++ b/dfhack/include/modules/Buildings.h @@ -32,9 +32,15 @@ namespace DFHack Buildings(APIPrivate * d); ~Buildings(); bool Start(uint32_t & numBuildings); + // read one building at offset bool Read (const uint32_t index, t_building & building); bool Finish(); + // read a vector of names + bool ReadCustomWorkshopTypes(map & btypes); + // returns -1 on error, >= 0 for real value + int32_t GetCustomWorkshopType(t_building & building); + private: struct Private; Private *d; diff --git a/dfhack/modules/Buildings.cpp b/dfhack/modules/Buildings.cpp index 8e8c4de31..580ec5c5f 100644 --- a/dfhack/modules/Buildings.cpp +++ b/dfhack/modules/Buildings.cpp @@ -52,9 +52,12 @@ struct t_building_df40d struct Buildings::Private { uint32_t buildings_vector; - // translation + uint32_t custom_workshop_vector; + uint32_t building_custom_workshop_type; + uint32_t custom_workshop_type; + uint32_t custom_workshop_name; + int32_t custom_workshop_id; DfVector * p_bld; - APIPrivate *d; bool Inited; bool Started; @@ -66,7 +69,12 @@ Buildings::Buildings(APIPrivate * d_) d->d = d_; d->Inited = d->Started = false; memory_info * mem = d->d->offset_descriptor; + d->custom_workshop_vector = mem->getAddress("custom_workshop_vector"); + d->building_custom_workshop_type = mem->getOffset("building_custom_workshop_type"); + d->custom_workshop_type = mem->getOffset("custom_workshop_type"); + d->custom_workshop_name = mem->getOffset("custom_workshop_name"); d->buildings_vector = mem->getAddress ("buildings_vector"); + mem->resolveClassnameToClassID("building_custom_workshop", d->custom_workshop_id); d->Inited = true; } @@ -122,4 +130,33 @@ bool Buildings::Finish() } d->Started = false; return true; +} + +bool Buildings::ReadCustomWorkshopTypes(map & btypes) +{ + DfVector p_matgloss (g_pProcess, d->custom_workshop_vector, 4); + uint32_t size = p_matgloss.getSize(); + btypes.clear(); + for (uint32_t i = 0; i < size;i++) + { + string out = g_pProcess->readSTLString (*(uint32_t *) p_matgloss[i] + d->custom_workshop_name); + uint32_t type = g_pProcess->readDWord (*(uint32_t *) p_matgloss[i] + d->custom_workshop_type); + #ifdef DEBUG + cout << out << ": " << type << endl; + #endif + btypes[type] = out; + } + return true; +} + +int32_t Buildings::GetCustomWorkshopType(t_building & building) +{ + int32_t type = (int32_t)building.type; + int32_t ret = -1; + if(type != -1 && type == d->custom_workshop_id) + { + // read the custom workshop subtype + ret = (int32_t) g_pProcess->readDWord(building.origin + d->building_custom_workshop_type); + } + return ret; } \ No newline at end of file diff --git a/examples/buildingsdump.cpp b/examples/buildingsdump.cpp index ba6d77cc4..d4cccb440 100644 --- a/examples/buildingsdump.cpp +++ b/examples/buildingsdump.cpp @@ -44,7 +44,7 @@ int main (int argc,const char* argv[]) mode = 1; } - vector creaturestypes; + map custom_workshop_types; DFHack::API DF ("Memory.xml"); try @@ -59,6 +59,7 @@ int main (int argc,const char* argv[]) #endif return 1; } + DFHack::memory_info * mem = DF.getMemoryInfo(); DFHack::Buildings * Bld = DF.getBuildings(); DFHack::Position * Pos = DF.getPosition(); @@ -66,6 +67,7 @@ int main (int argc,const char* argv[]) uint32_t numBuildings; if(Bld->Start(numBuildings)) { + Bld->ReadCustomWorkshopTypes(custom_workshop_types); if(mode) { cout << numBuildings << endl; @@ -110,6 +112,11 @@ int main (int argc,const char* argv[]) mem->resolveClassIDToClassname(temp.type, typestr); printf("Address 0x%x, type %d (%s), %d/%d/%d\n",temp.origin, temp.type, typestr.c_str(), temp.x1,temp.y1,temp.z); printf("Material %d %d\n", temp.material.type, temp.material.index); + int32_t custom; + if((custom = Bld->GetCustomWorkshopType(temp)) != -1) + { + printf("Custom workshop type %s (%d)\n",custom_workshop_types[custom].c_str(),custom); + } hexdump(DF,temp.origin,120); } } diff --git a/output/Memory.xml b/output/Memory.xml index 93aa8a3a9..89aa73886 100644 --- a/output/Memory.xml +++ b/output/Memory.xml @@ -920,6 +920,7 @@ size=212 + @@ -1238,6 +1239,10 @@ map_data_1b60_offset 0x1B9c Buildings =========
0x0166f9a0
+ 0x164 +
0x016B8798
+ 0x4 + 0x20 Effects =======