Custom buildings (tested)

develop
Petr Mrázek 2010-04-13 00:03:29 +02:00
parent da0602dbb1
commit 549b845738
6 changed files with 75 additions and 7 deletions

@ -393,6 +393,22 @@ bool memory_info::resolveClassnameToVPtr(const string classname, uint32_t & vptr
return false; 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) bool memory_info::resolveClassIDToClassname (const int32_t classID, string & classname)
{ {
if (classID >=0 && (uint32_t)classID < d->classnames.size()) if (classID >=0 && (uint32_t)classID < d->classnames.size())

@ -160,18 +160,15 @@ namespace DFHack
bool resolveObjectToClassID (const uint32_t address, int32_t & classID); 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) * Get a ClassID when you know the classname. can fail if the class is not in the cache
* can fail if the class is not in the cache
*/ */
bool resolveClassnameToClassID (const string classname, int32_t & classID); 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 * 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 * limited to normal classes, variable-dependent types will resolve to the base class
*/ */
bool resolveClassnameToVPtr ( const string classname, uint32_t & vptr ); 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) * Get a classname from a previous classID. Can fail if the type is not in the cache (you use bogus classID)

@ -32,9 +32,15 @@ namespace DFHack
Buildings(APIPrivate * d); Buildings(APIPrivate * d);
~Buildings(); ~Buildings();
bool Start(uint32_t & numBuildings); bool Start(uint32_t & numBuildings);
// read one building at offset
bool Read (const uint32_t index, t_building & building); bool Read (const uint32_t index, t_building & building);
bool Finish(); bool Finish();
// read a vector of names
bool ReadCustomWorkshopTypes(map <uint32_t, string> & btypes);
// returns -1 on error, >= 0 for real value
int32_t GetCustomWorkshopType(t_building & building);
private: private:
struct Private; struct Private;
Private *d; Private *d;

@ -52,9 +52,12 @@ struct t_building_df40d
struct Buildings::Private struct Buildings::Private
{ {
uint32_t buildings_vector; 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; DfVector * p_bld;
APIPrivate *d; APIPrivate *d;
bool Inited; bool Inited;
bool Started; bool Started;
@ -66,7 +69,12 @@ Buildings::Buildings(APIPrivate * d_)
d->d = d_; d->d = d_;
d->Inited = d->Started = false; d->Inited = d->Started = false;
memory_info * mem = d->d->offset_descriptor; 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"); d->buildings_vector = mem->getAddress ("buildings_vector");
mem->resolveClassnameToClassID("building_custom_workshop", d->custom_workshop_id);
d->Inited = true; d->Inited = true;
} }
@ -123,3 +131,32 @@ bool Buildings::Finish()
d->Started = false; d->Started = false;
return true; return true;
} }
bool Buildings::ReadCustomWorkshopTypes(map <uint32_t, string> & 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;
}

@ -44,7 +44,7 @@ int main (int argc,const char* argv[])
mode = 1; mode = 1;
} }
vector<DFHack::t_matgloss> creaturestypes; map <uint32_t, string> custom_workshop_types;
DFHack::API DF ("Memory.xml"); DFHack::API DF ("Memory.xml");
try try
@ -59,6 +59,7 @@ int main (int argc,const char* argv[])
#endif #endif
return 1; return 1;
} }
DFHack::memory_info * mem = DF.getMemoryInfo(); DFHack::memory_info * mem = DF.getMemoryInfo();
DFHack::Buildings * Bld = DF.getBuildings(); DFHack::Buildings * Bld = DF.getBuildings();
DFHack::Position * Pos = DF.getPosition(); DFHack::Position * Pos = DF.getPosition();
@ -66,6 +67,7 @@ int main (int argc,const char* argv[])
uint32_t numBuildings; uint32_t numBuildings;
if(Bld->Start(numBuildings)) if(Bld->Start(numBuildings))
{ {
Bld->ReadCustomWorkshopTypes(custom_workshop_types);
if(mode) if(mode)
{ {
cout << numBuildings << endl; cout << numBuildings << endl;
@ -110,6 +112,11 @@ int main (int argc,const char* argv[])
mem->resolveClassIDToClassname(temp.type, typestr); 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("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); 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); hexdump(DF,temp.origin,120);
} }
} }

@ -920,6 +920,7 @@ size=212
<class name="building_asheryst" type="0x14"/> <class name="building_asheryst" type="0x14"/>
<class name="building_dyers_shopst" type="0x15"/> <class name="building_dyers_shopst" type="0x15"/>
<class name="building_millstonest" type="0x16"/> <class name="building_millstonest" type="0x16"/>
<class name="building_custom_workshop" type="0x17" />
</multiclass> </multiclass>
<multiclass name="building_furnacest" typeoffset="0x152"> <multiclass name="building_furnacest" typeoffset="0x152">
<class name="building_wood_furnacest" type="0x0"/> <class name="building_wood_furnacest" type="0x0"/>
@ -1238,6 +1239,10 @@ map_data_1b60_offset 0x1B9c
Buildings Buildings
========= =========
<Address name="buildings_vector">0x0166f9a0</Address> <Address name="buildings_vector">0x0166f9a0</Address>
<Offset name="building_custom_workshop_type">0x164</Offset>
<Address name="custom_workshop_vector">0x016B8798</Address>
<Offset name="custom_workshop_name">0x4</Offset>
<Offset name="custom_workshop_type">0x20</Offset>
Effects Effects
======= =======