Support retrieving the item owner reference.

Reference is done by item id, and stored in some kind
of generic reference vector in the item structure.
develop
Alexander Gavrilov 2011-04-11 14:32:53 +04:00
parent 109d20d251
commit 2e0ec2db72
6 changed files with 81 additions and 3 deletions

@ -870,7 +870,7 @@
<Offset name="flags2" description="Second set of flags" /> <Offset name="flags2" description="Second set of flags" />
<Offset name="caste" description="Caste of the creature. Same as sex most of the time." /> <Offset name="caste" description="Caste of the creature. Same as sex most of the time." />
<Offset name="sex" description="Sex of the creature." /> <Offset name="sex" description="Sex of the creature." />
<Offset name="id" description="Unique ID of the creature, probably index into some global vector.." /> <Offset name="id" description="Unique ID of the creature, seems to be used for binary search in the creature vector." />
<Offset name="civ" description="What civ the creature belongs to." /> <Offset name="civ" description="What civ the creature belongs to." />
<Group name="advanced"> <Group name="advanced">
<Offset name="pickup_equipment_bit" description="Setting this makes creatures re-check the status of their equip." /> <Offset name="pickup_equipment_bit" description="Setting this makes creatures re-check the status of their equip." />
@ -996,6 +996,8 @@
<Offset name="item_improvement_index" /> <Offset name="item_improvement_index" />
<Offset name="item_improvement_quality" /> <Offset name="item_improvement_quality" />
<Offset name="item_wear_accessor" /> <Offset name="item_wear_accessor" />
<Offset name="item_ref_vector" description="Contains the owner among other things"/>
<Offset name="owner_ref_id_field" description="Creature ID offset in general_ref_unit_itemownerst"/>
</Group> </Group>
<Group name="World"> <Group name="World">
<Address name="current_tick" description="Current time of the year" /> <Address name="current_tick" description="Current time of the year" />
@ -2956,6 +2958,8 @@
<Offset name="item_index_accessor" value="0xC" /> <Offset name="item_index_accessor" value="0xC" />
<Offset name="item_quality_accessor" value="0x25C" /> <Offset name="item_quality_accessor" value="0x25C" />
<Offset name="item_wear_accessor" value="0xCC" /> <Offset name="item_wear_accessor" value="0xCC" />
<Offset name="item_ref_vector" value="0x24" />
<Offset name="owner_ref_id_field" value="0x4" />
</Group> </Group>
</Offsets> </Offsets>
</Version> </Version>

@ -128,10 +128,10 @@ struct naked_itemflags
unsigned int u_ngrd2 : 1; // 0000 0010 unknown, lost (artifact)?, unseen unsigned int u_ngrd2 : 1; // 0000 0010 unknown, lost (artifact)?, unseen
unsigned int in_building : 1; // 0000 0020 Part of a building (including mechanisms, bodies in coffins) unsigned int in_building : 1; // 0000 0020 Part of a building (including mechanisms, bodies in coffins)
unsigned int u_ngrd3 : 1; // 0000 0040 unknown, unseen unsigned int u_ngrd3 : 1; // 0000 0040 unknown, unseen
unsigned int dead_body : 1; // 0000 0080 Dwarf's dead body or body part unsigned int dead_dwarf : 1; // 0000 0080 Dwarf's dead body or body part
unsigned int rotten : 1; // 0000 0100 Rotten food unsigned int rotten : 1; // 0000 0100 Rotten food
unsigned int spider_web : 1; // 0000 0200 Spider web unsigned int spider_web : 1; // 0000 0200 Thread in spider web
unsigned int construction : 1; // 0000 0400 Material used in construction unsigned int construction : 1; // 0000 0400 Material used in construction
unsigned int u_ngrd5 : 1; // 0000 0800 unknown, unseen unsigned int u_ngrd5 : 1; // 0000 0800 unknown, unseen

@ -320,6 +320,8 @@ namespace DFHack
bool ReadInventoryIdx(const uint32_t index, std::vector<uint32_t> & item); bool ReadInventoryIdx(const uint32_t index, std::vector<uint32_t> & item);
bool ReadInventoryPtr(const uint32_t index, std::vector<uint32_t> & item); bool ReadInventoryPtr(const uint32_t index, std::vector<uint32_t> & item);
int32_t FindIndexById(int32_t id);
/* Getters */ /* Getters */
uint32_t GetDwarfRaceIndex ( void ); uint32_t GetDwarfRaceIndex ( void );
int32_t GetDwarfCivId ( void ); int32_t GetDwarfCivId ( void );

@ -47,6 +47,7 @@ public:
std::string getItemDescription(uint32_t itemptr, Materials * Materials); std::string getItemDescription(uint32_t itemptr, Materials * Materials);
std::string getItemClass(int32_t index); std::string getItemClass(int32_t index);
bool getItemData(uint32_t itemptr, t_item & item); bool getItemData(uint32_t itemptr, t_item & item);
int32_t getItemOwnerID(uint32_t itemptr);
void setItemFlags(uint32_t itemptr, t_itemflags new_flags); void setItemFlags(uint32_t itemptr, t_itemflags new_flags);
private: private:
class Private; class Private;

@ -106,6 +106,8 @@ struct Creatures::Private
uint32_t creature_module; uint32_t creature_module;
uint32_t dwarf_race_index_addr; uint32_t dwarf_race_index_addr;
uint32_t dwarf_civ_id_addr; uint32_t dwarf_civ_id_addr;
bool IdMapReady;
std::map<int32_t, int32_t> IdMap;
DfVector <uint32_t> *p_cre; DfVector <uint32_t> *p_cre;
DFContextShared *d; DFContextShared *d;
Process *owner; Process *owner;
@ -123,6 +125,7 @@ Creatures::Creatures(DFContextShared* _d)
d->owner = _d->p; d->owner = _d->p;
d->Inited = false; d->Inited = false;
d->Started = false; d->Started = false;
d->IdMapReady = false;
d->p_cre = NULL; d->p_cre = NULL;
d->d->InitReadNames(); // throws on error d->d->InitReadNames(); // throws on error
VersionInfo * minfo = d->d->offset_descriptor; VersionInfo * minfo = d->d->offset_descriptor;
@ -228,6 +231,7 @@ bool Creatures::Start( uint32_t &numcreatures )
d->p_cre = new DfVector <uint32_t> (d->owner, d->creatures.vector); d->p_cre = new DfVector <uint32_t> (d->owner, d->creatures.vector);
d->Started = true; d->Started = true;
numcreatures = d->p_cre->size(); numcreatures = d->p_cre->size();
d->IdMapReady = false;
return true; return true;
} }
return false; return false;
@ -407,6 +411,35 @@ int32_t Creatures::ReadCreatureInBox (int32_t index, t_creature & furball,
return -1; return -1;
} }
int32_t Creatures::FindIndexById(int32_t creature_id)
{
if (!d->Started || !d->Ft_basic)
return -1;
if (!d->IdMapReady)
{
d->IdMap.clear();
Process * p = d->owner;
Private::t_offsets &offs = d->creatures;
uint32_t size = d->p_cre->size();
for (uint32_t index = 0; index < size; index++)
{
uint32_t temp = d->p_cre->at(index);
int32_t id = p->readDWord (temp + offs.id_offset);
d->IdMap[id] = index;
}
}
std::map<int32_t,int32_t>::iterator it;
it = d->IdMap.find(creature_id);
if(it == d->IdMap.end())
return -1;
else
return it->second;
}
bool Creatures::WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]) bool Creatures::WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS])
{ {
if(!d->Started || !d->Ft_advanced) return false; if(!d->Started || !d->Ft_advanced) return false;

@ -326,6 +326,9 @@ class Items::Private
Process * owner; Process * owner;
std::map<int32_t, ItemDesc *> descType; std::map<int32_t, ItemDesc *> descType;
std::map<uint32_t, ItemDesc *> descVTable; std::map<uint32_t, ItemDesc *> descVTable;
uint32_t refVectorOffset;
uint32_t refIDOffset;
uint32_t ownerRefVTable;
}; };
Items::Items(DFContextShared * d_) Items::Items(DFContextShared * d_)
@ -333,6 +336,7 @@ Items::Items(DFContextShared * d_)
d = new Private; d = new Private;
d->d = d_; d->d = d_;
d->owner = d_->p; d->owner = d_->p;
d->ownerRefVTable = d->refVectorOffset = d->refIDOffset = 0;
} }
bool Items::Start() bool Items::Start()
@ -385,6 +389,40 @@ void Items::setItemFlags(uint32_t itemptr, t_itemflags new_flags)
d->owner->writeDWord(itemptr + 0x0C, new_flags.whole); d->owner->writeDWord(itemptr + 0x0C, new_flags.whole);
} }
int32_t Items::getItemOwnerID(uint32_t itemptr)
{
if (!d->refVectorOffset)
{
OffsetGroup * Items = d->owner->getDescriptor()->getGroup("Items");
d->refVectorOffset = Items->getOffset("item_ref_vector");
d->refIDOffset = Items->getOffset("owner_ref_id_field");
}
DFHack::DfVector<uint32_t> p_refs(d->owner, itemptr + d->refVectorOffset);
uint32_t size = p_refs.size();
for (uint32_t i=0;i<size;i++)
{
uint32_t curRef = p_refs[i];
uint32_t vtbl = d->owner->readDWord(curRef);
if (!d->ownerRefVTable)
{
std::string className = d->owner->readClassName(vtbl);
if (className == "general_ref_unit_itemownerst")
d->ownerRefVTable = vtbl;
else
continue;
}
else if (d->ownerRefVTable != vtbl)
continue;
return d->owner->readDWord(curRef + d->refIDOffset);
}
return -1;
}
std::string Items::getItemClass(int32_t index) std::string Items::getItemClass(int32_t index)
{ {
std::map<int32_t, ItemDesc *>::iterator it; std::map<int32_t, ItemDesc *>::iterator it;