Merge branch 'bartavelle' of git://bigbox.banquise.net/dfhack

develop
Petr Mrázek 2010-04-26 18:22:41 +02:00
commit f91720c97e
8 changed files with 286 additions and 11 deletions

@ -260,10 +260,20 @@ namespace DFHack
uint32_t experience; uint32_t experience;
uint16_t rating; uint16_t rating;
}; };
struct t_material
{
int16_t typeA;
int16_t typeB;
int16_t typeC;
int32_t typeD;
uint32_t flags;
};
struct t_job struct t_job
{ {
bool active; bool active;
uint8_t jobId; uint32_t jobId;
uint8_t jobType;
uint32_t occupationPtr;
}; };
struct t_like struct t_like
{ {
@ -284,6 +294,7 @@ namespace DFHack
uint32_t field_18; uint32_t field_18;
}; };
// FIXME: define in Memory.xml instead? // FIXME: define in Memory.xml instead?
#define NUM_CREATURE_TRAITS 30 #define NUM_CREATURE_TRAITS 30
#define NUM_CREATURE_LABORS 102 #define NUM_CREATURE_LABORS 102
@ -327,6 +338,7 @@ namespace DFHack
t_name name; t_name name;
int16_t mood; int16_t mood;
int16_t mood_skill;
t_name artifact_name; t_name artifact_name;
uint8_t profession; uint8_t profession;
@ -371,6 +383,7 @@ namespace DFHack
bool WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]); bool WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]);
uint32_t GetDwarfRaceIndex ( void ); uint32_t GetDwarfRaceIndex ( void );
int32_t GetDwarfCivId ( void ); int32_t GetDwarfCivId ( void );
bool ReadJob(const t_creature * furball, vector<t_material> & mat);
private: private:
struct Private; struct Private;
Private *d; Private *d;

@ -88,7 +88,9 @@ Creatures::Creatures(APIPrivate* _d)
creatures.default_soul_offset = minfo->getOffset("creature_default_soul"); creatures.default_soul_offset = minfo->getOffset("creature_default_soul");
creatures.physical_offset = minfo->getOffset("creature_physical"); creatures.physical_offset = minfo->getOffset("creature_physical");
creatures.mood_offset = minfo->getOffset("creature_mood"); creatures.mood_offset = minfo->getOffset("creature_mood");
creatures.mood_skill_offset = minfo->getOffset("creature_mood_skill");
creatures.pickup_equipment_bit = minfo->getOffset("creature_pickup_equipment_bit"); creatures.pickup_equipment_bit = minfo->getOffset("creature_pickup_equipment_bit");
creatures.current_job_offset = minfo->getOffset("creature_current_job");
// soul offsets // soul offsets
creatures.soul_skills_vector_offset = minfo->getOffset("soul_skills_vector"); creatures.soul_skills_vector_offset = minfo->getOffset("soul_skills_vector");
creatures.soul_mental_offset = minfo->getOffset("soul_mental"); creatures.soul_mental_offset = minfo->getOffset("soul_mental");
@ -157,6 +159,7 @@ bool Creatures::ReadCreature (const int32_t index, t_creature & furball)
} }
// non-SHM slow path // non-SHM slow path
memory_info * minfo = d->d->offset_descriptor;
// read pointer from vector at position // read pointer from vector at position
uint32_t temp = d->p_cre->at (index); uint32_t temp = d->p_cre->at (index);
@ -183,6 +186,7 @@ bool Creatures::ReadCreature (const int32_t index, t_creature & furball)
// mood stuff // mood stuff
furball.mood = (int16_t) p->readWord (temp + offs.mood_offset); furball.mood = (int16_t) p->readWord (temp + offs.mood_offset);
furball.mood_skill = p->readWord (temp + offs.mood_skill_offset);
d->d->readName(furball.artifact_name, temp + offs.artifact_name_offset); d->d->readName(furball.artifact_name, temp + offs.artifact_name_offset);
// custom profession // custom profession
@ -194,6 +198,19 @@ bool Creatures::ReadCreature (const int32_t index, t_creature & furball)
// profession // profession
furball.profession = p->readByte (temp + offs.profession_offset); furball.profession = p->readByte (temp + offs.profession_offset);
furball.current_job.occupationPtr = p->readDWord (temp + offs.current_job_offset);
if(furball.current_job.occupationPtr)
{
furball.current_job.active = true;
furball.current_job.jobType = p->readByte (furball.current_job.occupationPtr + minfo->getOffset("job_type") );
furball.current_job.jobId = p->readDWord (furball.current_job.occupationPtr + minfo->getOffset("job_id") );
}
else
{
furball.current_job.active = false;;
}
// current job HACK: the job object isn't cleanly represented here // current job HACK: the job object isn't cleanly represented here
/* /*
uint32_t jobIdAddr = p->readDWord (temp + offs.creature_current_job_offset); uint32_t jobIdAddr = p->readDWord (temp + offs.creature_current_job_offset);
@ -342,3 +359,24 @@ bool Creatures::getCurrentCursorCreature(uint32_t & creature_index)
return true; return true;
} }
*/ */
bool Creatures::ReadJob(const t_creature * furball, vector<t_material> & mat)
{
unsigned int i;
if(!d->Inited) return false;
if(!furball->current_job.active) return false;
Process * p = d->owner;
memory_info * minfo = d->d->offset_descriptor;
DfVector <uint32_t> cmats(p, furball->current_job.occupationPtr + minfo->getOffset("job_materials_vector"));
mat.resize(cmats.size());
for(i=0;i<cmats.size();i++)
{
mat[i].typeA = p->readWord(cmats[i] + minfo->getOffset("job_material_maintype"));
mat[i].typeB = p->readWord(cmats[i] + minfo->getOffset("job_material_sectype1"));
mat[i].typeC = p->readWord(cmats[i] + minfo->getOffset("job_material_sectype2"));
mat[i].typeD = p->readDWord(cmats[i] + minfo->getOffset("job_material_sectype3"));
mat[i].flags = p->readDWord(cmats[i] + minfo->getOffset("job_material_flags"));
}
return true;
}

@ -50,9 +50,11 @@ typedef struct
uint32_t artifact_name_offset; uint32_t artifact_name_offset;
uint32_t physical_offset; uint32_t physical_offset;
uint32_t mood_offset; uint32_t mood_offset;
uint32_t mood_skill_offset;
uint32_t pickup_equipment_bit; uint32_t pickup_equipment_bit;
uint32_t soul_vector_offset; uint32_t soul_vector_offset;
uint32_t default_soul_offset; uint32_t default_soul_offset;
uint32_t current_job_offset;
// soul offsets // soul offsets
uint32_t soul_skills_vector_offset; uint32_t soul_skills_vector_offset;
// name offsets (needed for reading creature names) // name offsets (needed for reading creature names)

@ -3,6 +3,7 @@
#include <iostream> #include <iostream>
#include <climits> #include <climits>
#include <integers.h> #include <integers.h>
#include <string.h>
#include <vector> #include <vector>
using namespace std; using namespace std;
@ -39,6 +40,7 @@ vector< vector <DFHack::t_itemType> > itemTypes;
DFHack::memory_info *mem; DFHack::memory_info *mem;
vector< vector<string> > englishWords; vector< vector<string> > englishWords;
vector< vector<string> > foreignWords; vector< vector<string> > foreignWords;
DFHack::Creatures * Creatures = NULL;
/* /*
likeType printLike40d(DFHack::t_like like, const matGlosses & mat,const vector< vector <DFHack::t_itemType> > & itemTypes) likeType printLike40d(DFHack::t_like like, const matGlosses & mat,const vector< vector <DFHack::t_itemType> > & 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, { // 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,
@ -239,6 +241,69 @@ void printCreature(DFHack::API & DF, const DFHack::t_creature & creature)
cout <<"Male"; cout <<"Male";
} }
cout << endl; cout << endl;
if(creature.mood != -1)
{
cout << "mood: " << creature.mood << ", skill: " << mem->getSkill(creature.mood_skill) << endl;
vector<DFHack::t_material> mymat;
char maintype[512];
if(Creatures->ReadJob(&creature, mymat))
{
for(unsigned int i = 0; i < mymat.size(); i++)
{
strcpy(maintype, "???");
switch(mymat[i].typeA)
{
case 0:
if(mymat[i].typeD>=0)
{
if(mymat[i].typeD<=mat.metalMat.size())
sprintf(maintype, "%s bar", mat.metalMat[mymat[i].typeD].id);
else
strcpy(maintype, "invalid metal bar");
}
else
strcpy(maintype, "any metal bar");
break;
case 1:
strcpy(maintype, "cut gem");
break;
case 2:
strcpy(maintype, "block");
break;
case 3:
switch(mymat[i].typeC)
{
case 3: strcpy(maintype, "raw green glass"); break;
case 4: strcpy(maintype, "raw clear glass"); break;
case 5: strcpy(maintype, "raw crystal glass"); break;
default: strcpy(maintype, "raw gems"); break;
}
break;
case 4:
strcpy(maintype, "raw stone");
break;
case 5:
strcpy(maintype, "wood log");
break;
case 24:
strcpy(maintype, "weapon?");
break;
case 54:
strcpy(maintype, "leather");
break;
case 57:
strcpy(maintype, "cloth");
break;
default:
strcpy(maintype, "unknown");
break;
}
printf("\t%s(%d)\t%d %d %d - %.8x\n", maintype, mymat[i].typeA, mymat[i].typeB, mymat[i].typeC, mymat[i].typeD, mymat[i].flags);
}
}
}
/* /*
if(creature.pregnancy_timer > 0) if(creature.pregnancy_timer > 0)
cout << "gives birth in " << creature.pregnancy_timer/1200 << " days. "; cout << "gives birth in " << creature.pregnancy_timer/1200 << " days. ";
@ -376,7 +441,7 @@ int main (int numargs, char ** args)
if(numargs == 2) if(numargs == 2)
check = args[1]; check = args[1];
DFHack::Creatures * Creatures = DF.getCreatures(); Creatures = DF.getCreatures();
DFHack::Materials * Materials = DF.getMaterials(); DFHack::Materials * Materials = DF.getMaterials();
DFHack::Translation * Tran = DF.getTranslation(); DFHack::Translation * Tran = DF.getTranslation();
@ -399,7 +464,11 @@ int main (int numargs, char ** args)
} }
mem = DF.getMemoryInfo(); mem = DF.getMemoryInfo();
// get stone matgloss mapping if(!Materials->ReadInorganicMaterials(mat.metalMat))
{
cerr << "Can't get the inorganics types." << endl;
return 1;
}
if(!Materials->ReadCreatureTypesEx(creaturestypes)) if(!Materials->ReadCreatureTypesEx(creaturestypes))
{ {
cerr << "Can't get the creature types." << endl; cerr << "Can't get the creature types." << endl;

@ -1399,6 +1399,7 @@ map_data_1b60_offset 0x1B9c
<Offset name="creature_pickup_equipment_bit">0X21C</Offset> <Offset name="creature_pickup_equipment_bit">0X21C</Offset>
<!--<Offset name="creature_mood">0x238</Offset>--> <!--<Offset name="creature_mood">0x238</Offset>-->
<Offset name="creature_mood">0x288</Offset>
<Offset name="creature_physical">0x464</Offset> <Offset name="creature_physical">0x464</Offset>
<!-- <!--
<Offset name="creature_strength">0x464</Offset> <Offset name="creature_strength">0x464</Offset>
@ -1419,12 +1420,17 @@ map_data_1b60_offset 0x1B9c
Job structure Job structure
============= =============
<Offset name="job_type">0x4</Offset> seems to be just like the old occupations <Offset name="job_id">0x0</Offset> Incrementaly assigned
<Offset name="job_type">0x8</Offset> seems to be just like the old occupations
<Offset name="job_materials_vector">0xa4</Offset> <Offset name="job_materials_vector">0xa4</Offset>
Job materials Job materials
============= =============
<Offset name="job_material_maintype">0x0</Offset> like mood materials, 0=bars, 4=stone, 5=wood, 57=cloth, 54=leather ... <Offset name="job_material_maintype">0x0</Offset> like mood materials, 0=bars, 4=stone, 5=wood, 57=cloth, 54=leather ...
<Offset name="job_material_sectype1">0x2</Offset> subsubtype ?
<Offset name="job_material_sectype2">0x4</Offset> subtype ?
<Offset name="job_material_sectype3">0x8</Offset> index of material (for example, 2 is for silver)
<Offset name="job_material_flags">0x18</Offset> set only for shell / bone mood requirements ?
Materials Materials
========= =========

@ -9,6 +9,10 @@ ENDIF(UNIX)
ADD_EXECUTABLE(dfreveal reveal.cpp) ADD_EXECUTABLE(dfreveal reveal.cpp)
TARGET_LINK_LIBRARIES(dfreveal dfhack) TARGET_LINK_LIBRARIES(dfreveal dfhack)
# a reveal clone
ADD_EXECUTABLE(dfmoodump moodump.cpp)
TARGET_LINK_LIBRARIES(dfmoodump dfhack)
# prospector - produces a list of available materials and their quantities # prospector - produces a list of available materials and their quantities
ADD_EXECUTABLE(dfprospector prospector.cpp) ADD_EXECUTABLE(dfprospector prospector.cpp)
TARGET_LINK_LIBRARIES(dfprospector dfhack) TARGET_LINK_LIBRARIES(dfprospector dfhack)
@ -63,6 +67,7 @@ dfincremental
#dfmagma_create #dfmagma_create
dfprospector dfprospector
dfreveal dfreveal
dfmoodump
RUNTIME DESTINATION bin RUNTIME DESTINATION bin
) )
ENDIF(UNIX) ENDIF(UNIX)

@ -0,0 +1,142 @@
#include <iostream>
#include <climits>
#include <integers.h>
#include <vector>
#include <stdio.h>
using namespace std;
#include <DFGlobal.h>
#include <DFError.h>
#include <DFTypes.h>
#include <DFHackAPI.h>
#include <DFMemInfo.h>
#include <DFProcess.h>
#include <modules/Materials.h>
#include <modules/Creatures.h>
#include <modules/Translation.h>
struct matGlosses
{
vector<DFHack::t_matglossPlant> plantMat;
vector<DFHack::t_matgloss> woodMat;
vector<DFHack::t_matgloss> stoneMat;
vector<DFHack::t_matgloss> metalMat;
vector<DFHack::t_matgloss> creatureMat;
};
vector<DFHack::t_creaturetype> creaturestypes;
matGlosses mat;
vector< vector <DFHack::t_itemType> > itemTypes;
DFHack::memory_info *mem;
vector< vector<string> > englishWords;
vector< vector<string> > foreignWords;
int main (int numargs, char ** args)
{
DFHack::API DF("Memory.xml");
DFHack::Process * p;
try
{
DF.Attach();
}
catch (exception& e)
{
cerr << e.what() << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
p = DF.getProcess();
string check = "";
if(numargs == 2)
check = args[1];
DFHack::Creatures * Creatures = DF.getCreatures();
DFHack::Materials * Materials = DF.getMaterials();
DFHack::Translation * Tran = DF.getTranslation();
uint32_t numCreatures;
if(!Creatures->Start(numCreatures))
{
cerr << "Can't get creatures" << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
if(!numCreatures)
{
cerr << "No creatures to print" << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
mem = DF.getMemoryInfo();
if(!Materials->ReadInorganicMaterials(mat.metalMat))
{
cerr << "Can't get the inorganics types." << endl;
return 1;
}
if(!Materials->ReadCreatureTypesEx(creaturestypes))
{
cerr << "Can't get the creature types." << endl;
return 1;
}
if(!Tran->Start())
{
cerr << "Can't get name tables" << endl;
return 1;
}
vector<uint32_t> addrs;
//DF.InitViewAndCursor();
for(uint32_t i = 0; i < numCreatures; i++)
{
DFHack::t_creature temp;
unsigned int current_job;
unsigned int mat_start;
unsigned int mat_end;
unsigned int j,k;
unsigned int matptr;
unsigned int tmp;
Creatures->ReadCreature(i,temp);
if(temp.mood>=0)
{
current_job = p->readDWord(temp.origin + 0x390);
if(current_job == 0)
continue;
mat_start = p->readDWord(current_job + 0xa4 + 4*3);
mat_end = p->readDWord(current_job + 0xa4 + 4*4);
for(j=mat_start;j<mat_end;j+=4)
{
matptr = p->readDWord(j);
for(k=0;k<4;k++)
printf("%.4X ", p->readWord(matptr + k*2));
for(k=0;k<3;k++)
printf("%.8X ", p->readDWord(matptr + k*4 + 0x8));
for(k=0;k<2;k++)
printf("%.4X ", p->readWord(matptr + k*2 + 0x14));
for(k=0;k<3;k++)
printf("%.8X ", p->readDWord(matptr + k*4 + 0x18));
for(k=0;k<4;k++)
printf("%.2X ", p->readByte(matptr + k + 0x24));
for(k=0;k<6;k++)
printf("%.8X ", p->readDWord(matptr + k*4 + 0x28));
for(k=0;k<4;k++)
printf("%.2X ", p->readByte(matptr + k + 0x40));
for(k=0;k<9;k++)
printf("%.8X ", p->readDWord(matptr + k*4 + 0x44));
printf(" [%p]\n", matptr);
}
}
}
Creatures->Finish();
DF.Detach();
return 0;
}