Code for getting the current and all settlements in the world, currently has offsets for the settlement location, name, and area size. Right now the current settlement causes msvc to claim the heap is corrupted, I think due to the fact that the current_settlement vector only has 1 item in it. I think it may be a bug in the vector code, as my code is basically identical between the current settlement and the other settlements.

Signed-off-by: belal <jimbelal@gmail.com>
develop
belal 2010-02-22 21:25:57 -05:00 committed by Petr Mrázek
parent bdc22b4052
commit a5d42e4051
7 changed files with 183 additions and 4 deletions

@ -47,6 +47,11 @@ TARGET_LINK_LIBRARIES(dfhotkeynotedump dfhack)
ADD_EXECUTABLE(dffindnameindexes findnameindexes.cpp) ADD_EXECUTABLE(dffindnameindexes findnameindexes.cpp)
TARGET_LINK_LIBRARIES(dffindnameindexes dfhack) TARGET_LINK_LIBRARIES(dffindnameindexes dfhack)
# settlementdump - dumps the settlements on the loaded map
# Author: belal
ADD_EXECUTABLE(dfsettlementdump settlementdump.cpp)
TARGET_LINK_LIBRARIES(dfsettlementdump dfhack)
IF(UNIX) IF(UNIX)
# veinlook - look at the map... sort of # veinlook - look at the map... sort of
ADD_EXECUTABLE(dfveinlook veinlook.cpp) ADD_EXECUTABLE(dfveinlook veinlook.cpp)

@ -63,7 +63,7 @@ int main (void)
while(input != "q"){ while(input != "q"){
for( map< string, vector<string> >::iterator it = names.begin();it != names.end(); it++){ for( map< string, vector<string> >::iterator it = names.begin();it != names.end(); it++){
for(uint32_t i = 0; i < it->second.size(); i++){ for(uint32_t i = 0; i < it->second.size(); i++){
uint32_t found = input.find(tolower(it->second[i])); uint32_t found = tolower(input).find(tolower(it->second[i]));
if(found != string::npos){ if(found != string::npos){
stringstream value; stringstream value;
value << setfill('0') << setw(8) << hex << endian_swap(i); value << setfill('0') << setw(8) << hex << endian_swap(i);

@ -0,0 +1,60 @@
#include <iostream>
#include <iomanip>
#include <sstream>
#include <climits>
#include <integers.h>
#include <vector>
using namespace std;
#include <DFTypes.h>
#include <DFHackAPI.h>
void printSettlement(DFHack::API & DF, const DFHack::t_settlement & settlement, const map<string, vector<string> > &names)
{
string genericName = DF.TranslateName(settlement.name,2,names,"GENERIC");
string dwarfName = DF.TranslateName(settlement.name,2,names,"DWARF");
cout << dwarfName << " " << genericName << " " << "world x: " << settlement.world_x << " world y: " << settlement.world_y
<< " local_x: " << settlement.local_x1 << " local_y: " << settlement.local_y1 << " size: " << settlement.local_x2 - settlement.local_x1 << " by " << settlement.local_y2 - settlement.local_y1 << "\n";
}
int main (int argc,const char* argv[])
{
DFHack::API DF ("Memory.xml");
if(!DF.Attach())
{
cerr << "DF not found" << endl;
return 1;
}
DFHack::t_settlement current;
uint32_t numSettlements;
if(!DF.InitReadSettlements(numSettlements))
{
cerr << "Could not read Settlements" << endl;
return 1;
}
map<string, vector<string> > names;
if(!DF.InitReadNameTables(names))
{
cerr << "Can't get name tables" << endl;
return 1;
}
cout << "Settlements\n";
for(uint32_t i =0;i<numSettlements;i++){
DFHack::t_settlement temp;
DF.ReadSettlement(i,temp);
printSettlement(DF,temp,names);
}
// MSVC claims this is causing the heap to be corrupted, I think it is because the currentSettlement vector only has 1 item in it
cout << "Current Settlement\n";
DF.ReadCurrentSettlement(0,current);
printSettlement(DF,current,names);
DF.FinishReadNameTables();
DF.FinishReadSettlements();
DF.Detach();
#ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl;
cin.ignore();
#endif
return 0;
}

@ -94,6 +94,10 @@ public:
uint32_t hotkey_mode_offset; uint32_t hotkey_mode_offset;
uint32_t hotkey_xyz_offset; uint32_t hotkey_xyz_offset;
uint32_t hotkey_size; uint32_t hotkey_size;
uint32_t settlement_name_offset;
uint32_t settlement_world_xy_offset;
uint32_t settlement_local_xy_offset;
uint32_t dwarf_lang_table_offset; uint32_t dwarf_lang_table_offset;
@ -112,6 +116,7 @@ public:
bool itemsInited; bool itemsInited;
bool notesInited; bool notesInited;
bool hotkeyInited; bool hotkeyInited;
bool settlementsInited;
bool nameTablesInited; bool nameTablesInited;
@ -122,6 +127,8 @@ public:
DfVector *p_veg; DfVector *p_veg;
DfVector *p_itm; DfVector *p_itm;
DfVector *p_notes; DfVector *p_notes;
DfVector *p_settlements;
DfVector *p_current_settlement;
}; };
API::API (const string path_to_xml) API::API (const string path_to_xml)
@ -139,6 +146,7 @@ API::API (const string path_to_xml)
d->itemsInited = false; d->itemsInited = false;
d->notesInited = false; d->notesInited = false;
d->hotkeyInited = false; d->hotkeyInited = false;
d->pm = NULL; d->pm = NULL;
} }
@ -944,7 +952,7 @@ bool API::InitReadCreatures( uint32_t &numcreatures )
bool API::InitReadNotes( uint32_t &numnotes ) bool API::InitReadNotes( uint32_t &numnotes )
{ {
memory_info * minfo = d->offset_descriptor; memory_info * minfo = d->offset_descriptor;
int notes = d->offset_descriptor->getAddress ("notes"); int notes = minfo->getAddress ("notes");
d->note_foreground_offset = minfo->getOffset ("note_foreground"); d->note_foreground_offset = minfo->getOffset ("note_foreground");
d->note_background_offset = minfo->getOffset ("note_background"); d->note_background_offset = minfo->getOffset ("note_background");
d->note_name_offset = minfo->getOffset ("note_name"); d->note_name_offset = minfo->getOffset ("note_name");
@ -958,7 +966,6 @@ bool API::InitReadNotes( uint32_t &numnotes )
) )
{ {
d->p_notes = new DfVector (d->p->readVector (notes, 4)); d->p_notes = new DfVector (d->p->readVector (notes, 4));
//InitReadNameTables();
d->notesInited = true; d->notesInited = true;
numnotes = d->p_notes->getSize(); numnotes = d->p_notes->getSize();
return true; return true;
@ -983,6 +990,68 @@ bool API::ReadNote (const int32_t &index, t_note & note)
g_pProcess->read (temp + d->note_xyz_offset, 3*sizeof (uint16_t), (uint8_t *) &note.x); g_pProcess->read (temp + d->note_xyz_offset, 3*sizeof (uint16_t), (uint8_t *) &note.x);
return true; return true;
} }
bool API::InitReadSettlements( uint32_t & numsettlements )
{
memory_info * minfo = d->offset_descriptor;
int allSettlements = minfo->getAddress ("settlements");
int currentSettlement = minfo->getAddress("settlement_current");
d->settlement_name_offset = minfo->getOffset ("settlement_name");
d->settlement_world_xy_offset = minfo->getOffset ("settlement_world_xy");
d->settlement_local_xy_offset = minfo->getOffset ("settlement_local_xy");
if (allSettlements && currentSettlement
&& d->settlement_name_offset
&& d->settlement_world_xy_offset
&& d->settlement_local_xy_offset
)
{
d->p_settlements = new DfVector (d->p->readVector (allSettlements, 4));
d->p_current_settlement = new DfVector(d->p->readVector(currentSettlement,4));
d->settlementsInited = true;
numsettlements = d->p_settlements->getSize();
return true;
}
else
{
d->settlementsInited = false;
numsettlements = 0;
return false;
}
}
bool API::ReadSettlement(const int32_t &index, t_settlement & settlement)
{
if(!d->settlementsInited)
return false;
// read pointer from vector at position
uint32_t temp = * (uint32_t *) d->p_settlements->at (index);
settlement.origin = temp;
g_pProcess->read(temp + d->settlement_name_offset, 2 * sizeof(int32_t), (uint8_t *) &settlement.name);
g_pProcess->read(temp + d->settlement_world_xy_offset, 2 * sizeof(int16_t), (uint8_t *) &settlement.world_x);
g_pProcess->read(temp + d->settlement_local_xy_offset, 4 * sizeof(int16_t), (uint8_t *) &settlement.local_x1);
return true;
}
bool API::ReadCurrentSettlement(t_settlement & settlement)
{
if(!d->settlementsInited)
return false;
uint32_t temp = * (uint32_t *) d->p_current_settlement->at(0);
settlement.origin = temp;
g_pProcess->read(temp + d->settlement_name_offset, 2 * sizeof(int32_t), (uint8_t *) &settlement.name);
g_pProcess->read(temp + d->settlement_world_xy_offset, 2 * sizeof(int32_t), (uint8_t *) &settlement.world_x);
g_pProcess->read(temp + d->settlement_local_xy_offset, 4 * sizeof(int32_t), (uint8_t *) &settlement.local_x1);
return true;
}
void API::FinishReadSettlements()
{
delete d->p_settlements;
delete d->p_current_settlement;
d->p_settlements = NULL;
d->p_current_settlement = NULL;
d->settlementsInited = false;
}
bool API::InitReadHotkeys( ) bool API::InitReadHotkeys( )
{ {
memory_info * minfo = d->offset_descriptor; memory_info * minfo = d->offset_descriptor;
@ -1195,6 +1264,26 @@ bool API::InitReadNameTables (map< string, vector<string> > & nameTable)
} }
} }
string API::TranslateName (const int names[], int size, const map<string, vector<string> > & nameTable, const string & language)
{
string trans;
assert (d->nameTablesInited);
map<string, vector<string> >::const_iterator it;
it = nameTable.find (language);
if (it != nameTable.end())
{
for (int i = 0;i < size;i++)
{
if (names[i] == -1)
{
break;
}
trans.append (it->second[names[i]]);
}
}
return (trans);
}
string API::TranslateName (const t_lastname & last, const map<string, vector<string> > & nameTable, const string & language) string API::TranslateName (const t_lastname & last, const map<string, vector<string> > & nameTable, const string & language)
{ {
string trans_last; string trans_last;
@ -1259,7 +1348,6 @@ void API::FinishReadNotes()
delete d->p_notes; delete d->p_notes;
d->p_notes = NULL; d->p_notes = NULL;
d->notesInited = false; d->notesInited = false;
//FinishReadNameTables();
} }
bool API::Attach() bool API::Attach()

@ -185,6 +185,11 @@ namespace DFHack
bool ReadNote(const int32_t &index, t_note & note); bool ReadNote(const int32_t &index, t_note & note);
void FinishReadNotes(); void FinishReadNotes();
bool InitReadSettlements( uint32_t & numsettlements );
bool ReadSettlement(const int32_t &index, t_settlement & settlement);
bool ReadCurrentSettlement(t_settlement & settlement);
void FinishReadSettlements();
bool InitReadHotkeys( ); bool InitReadHotkeys( );
bool ReadHotkeys(t_hotkey hotkeys[]); bool ReadHotkeys(t_hotkey hotkeys[]);
@ -219,6 +224,7 @@ namespace DFHack
string TranslateName(const t_lastname & last, const map< string, vector< string > > &nameTable,const string & language="GENERIC"); 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"); string TranslateName(const t_squadname & squad, const map< string, vector< string > > &nameTable,const string & language="GENERIC");
string TranslateName (const int names[], int size, const map<string, vector<string> > & nameTable, const string & language="GENERIC");
void WriteLabors(const uint32_t &index, uint8_t labors[NUM_CREATURE_LABORS]); void WriteLabors(const uint32_t &index, uint8_t labors[NUM_CREATURE_LABORS]);

@ -775,5 +775,18 @@ struct t_hotkey
int32_t z; int32_t z;
}; };
// local are numbered with top left as 0,0, name is indexes into the item vector
struct t_settlement
{
uint32_t origin;
int32_t name[2];
int16_t world_x;
int16_t world_y;
int16_t local_x1;
int16_t local_x2;
int16_t local_y1;
int16_t local_y2;
};
}// namespace DFHack }// namespace DFHack
#endif // TYPES_H_INCLUDED #endif // TYPES_H_INCLUDED

@ -1142,6 +1142,13 @@
<Address name="notes">0x014240A4</Address> <Address name="notes">0x014240A4</Address>
<Address name="hotkey_start">0x014240DC</Address> <Address name="hotkey_start">0x014240DC</Address>
<Address name="settlement_current">0x16385DC</Address>
<Address name="settlements">0x1638510</Address>
<Offset name="settlement_name">0x38</Offset>
<Offset name="settlement_world_xy">0x7a</Offset>
<Offset name="settlement_local_xy">0x100</Offset>
<VTable name="viewscreen_vtable"> <VTable name="viewscreen_vtable">
<class vtable="0x0092014C" name="viewscreen_conversation" /> <class vtable="0x0092014C" name="viewscreen_conversation" />
<class vtable="0x0092752C" name="viewscreen_option" /> <class vtable="0x0092752C" name="viewscreen_option" />