Big creature jobs read/write fix (it was cmpletely broken)

develop
Petr Mrázek 2011-04-03 21:27:47 +02:00
parent fcc23149db
commit 8b8c70b5ff
3 changed files with 168 additions and 147 deletions

@ -2702,6 +2702,10 @@
<Group name="Constructions" valid="true">
<Address name="vector" value="0x93f7984" />
</Group>
<Group name="GUI">
<Address name="pause_state" value="0x93f0850" />
</Group>
<Group name="Position">
<Address name="cursor_xyz" value="0x8c3dfc0" />
<Address name="window_dims" value="0x8c3e4c8" />
@ -2743,6 +2747,66 @@
<Offset name="ptr2_region_array_from_wdata" value="0x15C" />
</Group>
</Group>
<Group name="Creatures">
<Address name="current_civ" value="0x093f2cb0" /> MAYBE
<Address name="current_race" value="0x093f2cbc" />
<Address name="vector" value="0x0940b310" />
<Group name="creature">
<Offset name="name" value="0x0" />
<Offset name="custom_profession" value="0x3c" />
<Offset name="profession" value="0x40" />
<Offset name="race" value="0x44" />
<Offset name="position" value="0x48" />
<Offset name="flags1" value="0x8c" />
<Offset name="flags2" value="0x90" />
<Offset name="caste" value="0xa4" />
<Offset name="sex" value="0xa6" />
<Offset name="id" value="0xa8" />
<Offset name="civ" value="0xb4" /> MAYBE
0xf312df68
<!--
<Group name="advanced"> THIS IS ONE BIG HAPPY PILE OF FAIL
<Offset name="pickup_equipment_bit" value="0x1bc" />
<Offset name="mood" value="0x210" />
<Offset name="pregnancy" value="0x214" />
<Offset name="pregnancy_ptr" value="0x218" />
<Offset name="birth_year" value="0x224" />
<Offset name="birth_time" value="0x228" />
<Offset name="inventory_vector" value="0x288" />
<Offset name="current_job" value="0x2f4" />
<Offset name="current_job_skill" value="0x2f8" />
<Offset name="physical" value="0x310 0x3cc" />
<Offset name="appearance_vector" value="0x52c" />
<Offset name="artifact_name" value="0x5e0" />
<Offset name="soul_vector" value="0x64c" />
<Offset name="current_soul" value="0x65c" />
<Offset name="labors" value="0x54C 0x670" />
<Offset name="happiness" value="0x05dc 0x710" />
</Group>
-->
</Group>
<Group name="job">
<Offset name="id" value="0x8" />
<!--<Offset name="materials_vector" />-->
<Offset name="type" value="0x40" /> MAYBE, DT
<!--
<Group name="material">
<Offset name="flags" /> NOT SET!
<Offset name="maintype" /> NOT SET!
<Offset name="sectype1" /> NOT SET!
<Offset name="sectype2" /> NOT SET!
<Offset name="sectype3" /> NOT SET!
</Group>
-->
</Group>
<Group name="soul">
<Offset name="name" value="0x4" />
<Offset name="mental" value="0x88" />
<Offset name="skills_vector" value="0x1c4" />
<Offset name="traits" value="0x1dc" />
</Group>
</Group>
<Group name="Materials">
<Address name="inorganics" value="0x944c320" />
<Address name="organics_all" value="0x944c338" />
@ -2753,30 +2817,27 @@
0x944c3c8
0x944c3d4
<Address name="other" value="0x9450c54" />
<Group name="creature">
<Group name="creature" valid="true">
<Offset name="tile_color" value="0x38" />
<Offset name="extract_vector" value="0x1f74" />
<!--
<Group name="caste">
<Offset name="attributes" /> NOT SET!
<Offset name="bodypart_vector" /> NOT SET!
<Offset name="color_modifiers" /> NOT SET!
<Offset name="attributes" value="0xa48" /> FIXME: this is 0xa40 really, the struct is wrong
<Offset name="bodypart_vector" value="0x264" />
<Offset name="color_modifiers" value="0xe48" />
</Group>
<Group name="caste_bodyparts">
<Offset name="category" /> NOT SET!
<Offset name="id" /> NOT SET!
<Offset name="layers_vector" /> NOT SET!
<Offset name="plural_vector" /> NOT SET!
<Offset name="singular_vector" /> NOT SET!
<Offset name="category" value="0x4" />
<Offset name="id" value="0x0" />
<Offset name="layers_vector" value="0x14" />
<Offset name="plural_vector" value="0x48" />
<Offset name="singular_vector" value="0x3C" />
</Group>
<Group name="caste_color_mods">
<Offset name="enddate" /> NOT SET!
<Offset name="part" /> NOT SET!
<Offset name="startdate" /> NOT SET!
<Offset name="enddate" value="0x38" />
<Offset name="part" value="0x40" />
<Offset name="startdate" value="0x34" />
</Group>
-->
</Group>
<Group name="descriptors" valid="true">
<Address name="colors_vector" value="0x94506c8 0x93cdff4" />
<Address name="all_colors_vector" value="0x94506E0 0x93ce00c" />

@ -45,7 +45,9 @@ struct Creatures::Private
bool Ft_basic;
bool Ft_advanced;
bool Ft_jobs;
bool Ft_job_materials;
bool Ft_soul;
bool Ft_inventory;
struct t_offsets
{
// creature offsets
@ -83,12 +85,20 @@ struct Creatures::Private
uint32_t birth_year_offset;
uint32_t birth_time_offset;
uint32_t inventory_offset;
// creature job stuff
int32_t job_type_offset;
int32_t job_id_offset;
int32_t job_materials_vector;
int32_t job_material_itemtype_o;
int32_t job_material_subtype_o;
int32_t job_material_subindex_o;
int32_t job_material_index_o;
int32_t job_material_flags_o;
// creature job material stuff
} creatures;
uint32_t creature_module;
uint32_t dwarf_race_index_addr;
uint32_t dwarf_civ_id_addr;
OffsetGroup * OG_jobs;
OffsetGroup * OG_job_mats;
DfVector <uint32_t> *p_cre;
DFContextShared *d;
Process *owner;
@ -114,9 +124,9 @@ Creatures::Creatures(DFContextShared* _d)
OffsetGroup *OG_creature_ex = OG_creature->getGroup("advanced");
OffsetGroup *OG_soul = OG_Creatures->getGroup("soul");
OffsetGroup * OG_name = minfo->getGroup("name");
d->OG_jobs = OG_Creatures->getGroup("job");
d->OG_job_mats = d->OG_jobs->getGroup("material");
d->Ft_basic = d->Ft_advanced = d->Ft_jobs = d->Ft_soul = false;
OffsetGroup * OG_jobs = OG_Creatures->getGroup("job");
OffsetGroup * OG_job_mats = OG_jobs->getGroup("material");
d->Ft_basic = d->Ft_advanced = d->Ft_jobs = d->Ft_soul = d->Ft_inventory = d->Ft_job_materials = false;
Private::t_offsets &creatures = d->creatures;
try
@ -144,7 +154,6 @@ Creatures::Creatures(DFContextShared* _d)
d->Ft_basic = true;
try
{
creatures.inventory_offset = OG_creature_ex->getOffset("inventory_vector");
creatures.pickup_equipment_bit = OG_creature_ex->getOffset("pickup_equipment_bit");
creatures.mood_offset = OG_creature_ex->getOffset("mood");
// pregnancy
@ -159,6 +168,11 @@ Creatures::Creatures(DFContextShared* _d)
creatures.labors_offset = OG_creature_ex->getOffset ("labors");
creatures.happiness_offset = OG_creature_ex->getOffset ("happiness");
d->Ft_advanced = true;
}catch(Error::All&){};
try
{
creatures.inventory_offset = OG_creature_ex->getOffset("inventory_vector");
d->Ft_inventory = true;
}
catch(Error::All&){};
try
@ -171,6 +185,24 @@ Creatures::Creatures(DFContextShared* _d)
d->Ft_soul = true;
}
catch(Error::All&){};
try
{
creatures.job_type_offset = OG_jobs->getOffset("type");
creatures.job_id_offset = OG_jobs->getOffset("id");
d->Ft_jobs = true;
try
{
creatures.job_materials_vector = OG_jobs->getOffset("materials_vector");
creatures.job_material_itemtype_o = OG_job_mats->getOffset("maintype");
creatures.job_material_subtype_o = OG_job_mats->getOffset("sectype1");
creatures.job_material_subindex_o = OG_job_mats->getOffset("sectype2");
creatures.job_material_index_o = OG_job_mats->getOffset("sectype3");
creatures.job_material_flags_o = OG_job_mats->getOffset("flags");
d->Ft_job_materials = true;
}
catch(Error::All&){};
}
catch(Error::All&){};
}
catch(Error::All&){};
d->Inited = true;
@ -211,17 +243,6 @@ bool Creatures::ReadCreature (const int32_t index, t_creature & furball)
memset(&furball, 0, sizeof(t_creature));
// SHM fast path
Process * p = d->owner;
/*
if(d->creature_module)
{
SHMCREATURESHDR->index = index;
const uint32_t cmd = Creatures2010::CREATURE_AT_INDEX + (d->creature_module << 16);
p->SetAndWait(cmd);
memcpy(&furball,SHMDATA(t_creature),sizeof(t_creature));
return true;
}
*/
// non-SHM slow path
// read pointer from vector at position
uint32_t temp = d->p_cre->at (index);
@ -265,6 +286,7 @@ bool Creatures::ReadCreature (const int32_t index, t_creature & furball)
// labors
p->read (temp + offs.labors_offset, NUM_CREATURE_LABORS, furball.labors);
furball.birth_year = p->readDWord (temp + offs.birth_year_offset );
furball.birth_time = p->readDWord (temp + offs.birth_time_offset );
/*
@ -335,12 +357,12 @@ bool Creatures::ReadCreature (const int32_t index, t_creature & furball)
if(furball.current_job.occupationPtr)
{
furball.current_job.active = true;
furball.current_job.jobType = p->readByte (furball.current_job.occupationPtr + d->OG_jobs->getOffset("type") );
furball.current_job.jobId = p->readDWord (furball.current_job.occupationPtr + d->OG_jobs->getOffset("id") );
furball.current_job.jobType = p->readByte (furball.current_job.occupationPtr + offs.job_type_offset );
furball.current_job.jobId = p->readDWord (furball.current_job.occupationPtr + offs.job_id_offset);
}
else
{
furball.current_job.active = false;;
furball.current_job.active = false;
}
}
return true;
@ -355,55 +377,33 @@ int32_t Creatures::ReadCreatureInBox (int32_t index, t_creature & furball,
return -1;
Process *p = d->owner;
/*
if(d->creature_module)
{
// supply the module with offsets so it can work with them
SHMCREATURESHDR->index = index;
SHMCREATURESHDR->x = x1;
SHMCREATURESHDR->y = y1;
SHMCREATURESHDR->z = z1;
SHMCREATURESHDR->x2 = x2;
SHMCREATURESHDR->y2 = y2;
SHMCREATURESHDR->z2 = z2;
const uint32_t cmd = Creatures2010::CREATURE_FIND_IN_BOX + (d->creature_module << 16);
p->SetAndWait(cmd);
if(SHMCREATURESHDR->index != -1)
memcpy(&furball,SHMDATA(void),sizeof(t_creature));
return SHMCREATURESHDR->index;
}
else*/
uint16_t coords[3];
uint32_t size = d->p_cre->size();
while (uint32_t(index) < size)
{
uint16_t coords[3];
uint32_t size = d->p_cre->size();
while (uint32_t(index) < size)
// read pointer from vector at position
uint32_t temp = d->p_cre->at(index);
p->read (temp + d->creatures.pos_offset, 3 * sizeof (uint16_t), (uint8_t *) &coords);
if (coords[0] >= x1 && coords[0] < x2)
{
// read pointer from vector at position
uint32_t temp = d->p_cre->at(index);
p->read (temp + d->creatures.pos_offset, 3 * sizeof (uint16_t), (uint8_t *) &coords);
if (coords[0] >= x1 && coords[0] < x2)
if (coords[1] >= y1 && coords[1] < y2)
{
if (coords[1] >= y1 && coords[1] < y2)
if (coords[2] >= z1 && coords[2] < z2)
{
if (coords[2] >= z1 && coords[2] < z2)
{
ReadCreature (index, furball);
return index;
}
ReadCreature (index, furball);
return index;
}
}
index++;
}
return -1;
index++;
}
return -1;
}
bool Creatures::WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS])
{
if(!d->Started)
{
return false;
}
if(!d->Started || !d->Ft_advanced) return false;
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
@ -417,10 +417,8 @@ bool Creatures::WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LA
bool Creatures::WriteHappiness(const uint32_t index, const uint32_t happinessValue)
{
if(!d->Started)
{
return false;
}
if(!d->Started || !d->Ft_advanced) return false;
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
p->writeDWord (temp + d->creatures.happiness_offset, happinessValue);
@ -431,10 +429,8 @@ bool Creatures::WriteFlags(const uint32_t index,
const uint32_t flags1,
const uint32_t flags2)
{
if(!d->Started)
{
return false;
}
if(!d->Started || !d->Ft_basic) return false;
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
p->writeDWord (temp + d->creatures.flags1_offset, flags1);
@ -444,10 +440,7 @@ bool Creatures::WriteFlags(const uint32_t index,
bool Creatures::WriteSkills(const uint32_t index, const t_soul &soul)
{
if(!d->Started)
{
return false;
}
if(!d->Started || !d->Ft_soul) return false;
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
@ -472,10 +465,7 @@ bool Creatures::WriteSkills(const uint32_t index, const t_soul &soul)
bool Creatures::WriteAttributes(const uint32_t index, const t_creature &creature)
{
if(!d->Started)
{
return false;
}
if(!d->Started || !d->Ft_advanced || !d->Ft_soul) return false;
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
@ -501,10 +491,7 @@ bool Creatures::WriteAttributes(const uint32_t index, const t_creature &creature
bool Creatures::WriteSex(const uint32_t index, const uint8_t sex)
{
if(!d->Started)
{
return false;
}
if(!d->Started || !d->Ft_basic ) return false;
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
@ -515,10 +502,7 @@ bool Creatures::WriteSex(const uint32_t index, const uint8_t sex)
bool Creatures::WriteTraits(const uint32_t index, const t_soul &soul)
{
if(!d->Started)
{
return false;
}
if(!d->Started || !d->Ft_soul) return false;
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
@ -538,10 +522,7 @@ bool Creatures::WriteTraits(const uint32_t index, const t_soul &soul)
bool Creatures::WriteMood(const uint32_t index, const uint16_t mood)
{
if(!d->Started)
{
return false;
}
if(!d->Started || !d->Ft_advanced) return false;
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
@ -551,10 +532,7 @@ bool Creatures::WriteMood(const uint32_t index, const uint16_t mood)
bool Creatures::WriteMoodSkill(const uint32_t index, const uint16_t moodSkill)
{
if(!d->Started)
{
return false;
}
if(!d->Started || !d->Ft_advanced) return false;
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
@ -564,42 +542,38 @@ bool Creatures::WriteMoodSkill(const uint32_t index, const uint16_t moodSkill)
bool Creatures::WriteJob(const t_creature * furball, std::vector<t_material> const& mat)
{
unsigned int i;
if(!d->Inited) return false;
if(!d->Inited || !d->Ft_job_materials) return false;
if(!furball->current_job.active) return false;
unsigned int i;
Process * p = d->owner;
DfVector <uint32_t> cmats(p, furball->current_job.occupationPtr + d->OG_jobs->getOffset("materials_vector"));
Private::t_offsets & off = d->creatures;
DfVector <uint32_t> cmats(p, furball->current_job.occupationPtr + off.job_materials_vector);
for(i=0;i<cmats.size();i++)
{
p->writeWord(cmats[i] + d->OG_job_mats->getOffset("maintype"), mat[i].itemType);
p->writeWord(cmats[i] + d->OG_job_mats->getOffset("sectype1"), mat[i].subType);
p->writeWord(cmats[i] + d->OG_job_mats->getOffset("sectype2"), mat[i].subIndex);
p->writeDWord(cmats[i] + d->OG_job_mats->getOffset("sectype3"), mat[i].index);
p->writeDWord(cmats[i] + d->OG_job_mats->getOffset("flags"), mat[i].flags);
p->writeWord(cmats[i] + off.job_material_itemtype_o, mat[i].itemType);
p->writeWord(cmats[i] + off.job_material_subtype_o, mat[i].subType);
p->writeWord(cmats[i] + off.job_material_subindex_o, mat[i].subIndex);
p->writeDWord(cmats[i] + off.job_material_index_o, mat[i].index);
p->writeDWord(cmats[i] + off.job_material_flags_o, mat[i].flags);
}
return true;
}
bool Creatures::WritePos(const uint32_t index, const t_creature &creature)
{
if(!d->Started)
{
return false;
}
if(!d->Started) return false;
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
p->write (temp + d->creatures.pos_offset, 3 * sizeof (uint16_t), (uint8_t *) & (creature.x));
return true;
p->write (temp + d->creatures.pos_offset, 3 * sizeof (uint16_t), (uint8_t *) & (creature.x));
return true;
}
bool Creatures::WriteCiv(const uint32_t index, const int32_t civ)
{
if(!d->Started)
{
return false;
}
if(!d->Started) return false;
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
@ -633,26 +607,27 @@ bool Creatures::getCurrentCursorCreature(uint32_t & creature_index)
bool Creatures::ReadJob(const t_creature * furball, vector<t_material> & mat)
{
unsigned int i;
if(!d->Inited) return false;
if(!d->Inited || !d->Ft_job_materials) return false;
if(!furball->current_job.active) return false;
Process * p = d->owner;
DfVector <uint32_t> cmats(p, furball->current_job.occupationPtr + d->OG_jobs->getOffset("materials_vector"));
Process * p = d->owner;
Private::t_offsets & off = d->creatures;
DfVector <uint32_t> cmats(p, furball->current_job.occupationPtr + off.job_materials_vector);
mat.resize(cmats.size());
for(i=0;i<cmats.size();i++)
{
mat[i].itemType = p->readWord(cmats[i] + d->OG_job_mats->getOffset("maintype"));
mat[i].subType = p->readWord(cmats[i] + d->OG_job_mats->getOffset("sectype1"));
mat[i].subIndex = p->readWord(cmats[i] + d->OG_job_mats->getOffset("sectype2"));
mat[i].index = p->readDWord(cmats[i] + d->OG_job_mats->getOffset("sectype3"));
mat[i].flags = p->readDWord(cmats[i] + d->OG_job_mats->getOffset("flags"));
mat[i].itemType = p->readWord(cmats[i] + off.job_material_itemtype_o);
mat[i].subType = p->readWord(cmats[i] + off.job_material_subtype_o);
mat[i].subIndex = p->readWord(cmats[i] + off.job_material_subindex_o);
mat[i].index = p->readDWord(cmats[i] + off.job_material_index_o);
mat[i].flags = p->readDWord(cmats[i] + off.job_material_flags_o);
}
return true;
}
bool Creatures::ReadInventoryIdx(const uint32_t index, std::vector<uint32_t> & item)
{
if(!d->Started) return false;
if(!d->Started || !d->Ft_inventory) return false;
uint32_t temp = d->p_cre->at (index);
return this->ReadInventoryPtr(temp, item);
}
@ -660,7 +635,7 @@ bool Creatures::ReadInventoryIdx(const uint32_t index, std::vector<uint32_t> & i
bool Creatures::ReadInventoryPtr(const uint32_t temp, std::vector<uint32_t> & item)
{
unsigned int i;
if(!d->Started) return false;
if(!d->Started || !d->Ft_inventory) return false;
Process * p = d->owner;
DfVector <uint32_t> citem(p, temp + d->creatures.inventory_offset);

@ -475,35 +475,20 @@ int main (int numargs, char ** args)
return 1;
}
vector<uint32_t> addrs;
//DF.InitViewAndCursor();
for(uint32_t i = 0; i < numCreatures; i++)
{
printf("%d/%d\n", i, numCreatures);
DFHack::t_creature temp;
Creatures->ReadCreature(i,temp);
if(check.empty() || string(Materials->raceEx[temp.race].rawname) == check)
{
cout << "index " << i << " ";
printCreature(DF,temp);
addrs.push_back(temp.origin);
}
printf("!\n");
}
if(addrs.size() <= 10)
{
interleave_hex(DF,addrs,200);
}
/*
uint32_t currentIdx;
DFHack::t_creature currentCreature;
DF.getCurrentCursorCreature(currentIdx);
cout << "current creature at index " << currentIdx << endl;
DF.ReadCreature(currentIdx, currentCreature);
printCreature(DF,currentCreature);
*/
Creatures->Finish();
DF->Detach();
#ifndef LINUX_BUILD