Support listing items owned by a creature.

develop
Alexander Gavrilov 2011-05-09 14:49:44 +04:00
parent 14f291d539
commit ed1477b53d
6 changed files with 97 additions and 6 deletions

@ -895,6 +895,7 @@
<Offset name="physical" value="0x464" description="An array of physical attributes." />
<Offset name="appearance_vector" description="seems to be indexes in the list of possible colors defined in the raws for each group" />
<Offset name="inventory_vector" />
<Offset name="owned_items_vector" />
<Offset name="artifact_name" description="Name of the artifact created by this creature." />
<Offset name="soul_vector" description="A vector of souls attached to the creature." />
<Offset name="current_soul" description="Currently active soul?" />
@ -3013,6 +3014,7 @@
<Group name="creature">
<Offset name="flags3" value="0x94"/>
<Group name="advanced">
<Offset name="owned_items_vector" value="0x210"/>
<Offset name="hist_figure_id" value="0x640"/>
</Group>
</Group>

@ -318,9 +318,13 @@ namespace DFHack
const uint16_t x2, const uint16_t y2,const uint16_t z2);
bool ReadCreature(const int32_t index, t_creature & furball);
bool ReadJob(const t_creature * furball, std::vector<t_material> & mat);
bool ReadInventoryIdx(const uint32_t index, std::vector<uint32_t> & item);
bool ReadInventoryPtr(const uint32_t index, std::vector<uint32_t> & item);
bool ReadOwnedItemsIdx(const uint32_t index, std::vector<int32_t> & item);
bool ReadOwnedItemsPtr(const uint32_t index, std::vector<int32_t> & item);
int32_t FindIndexById(int32_t id);
/* Getters */

@ -116,6 +116,10 @@ public:
~Items();
bool Start();
bool Finish();
bool readItemVector(std::vector<uint32_t> &items);
uint32_t findItemByID(int32_t id);
/// get a string describing an item
std::string getItemDescription(const dfh_item & item, Materials * Materials);
/// get a short name for an item

@ -56,6 +56,7 @@ struct Creatures::Private
bool Ft_job_materials;
bool Ft_soul;
bool Ft_inventory;
bool Ft_owned_items;
struct t_offsets
{
// creature offsets
@ -93,6 +94,7 @@ struct Creatures::Private
uint32_t birth_year_offset;
uint32_t birth_time_offset;
uint32_t inventory_offset;
uint32_t owned_items_offset;
// creature job stuff
int32_t job_type_offset;
int32_t job_id_offset;
@ -137,7 +139,7 @@ Creatures::Creatures(DFContextShared* _d)
OffsetGroup * OG_name = minfo->getGroup("name");
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;
d->Ft_basic = d->Ft_advanced = d->Ft_jobs = d->Ft_soul = d->Ft_inventory = d->Ft_owned_items = d->Ft_job_materials = false;
Private::t_offsets &creatures = d->creatures;
try
@ -187,6 +189,12 @@ Creatures::Creatures(DFContextShared* _d)
}
catch(Error::All&){};
try
{
creatures.owned_items_offset = OG_creature_ex->getOffset("owned_items_vector");
d->Ft_owned_items = true;
}
catch(Error::All&){};
try
{
creatures.soul_vector_offset = OG_creature_ex->getOffset("soul_vector");
creatures.default_soul_offset = OG_creature_ex->getOffset("current_soul");
@ -692,6 +700,28 @@ bool Creatures::ReadInventoryPtr(const uint32_t temp, std::vector<uint32_t> & it
return true;
}
bool Creatures::ReadOwnedItemsIdx(const uint32_t index, std::vector<int32_t> & item)
{
if(!d->Started || !d->Ft_owned_items) return false;
uint32_t temp = d->p_cre->at (index);
return this->ReadOwnedItemsPtr(temp, item);
}
bool Creatures::ReadOwnedItemsPtr(const uint32_t temp, std::vector<int32_t> & item)
{
unsigned int i;
if(!d->Started || !d->Ft_owned_items) return false;
Process * p = d->owner;
DfVector <int32_t> citem(p, temp + d->creatures.owned_items_offset);
if(citem.size() == 0)
return false;
item.resize(citem.size());
for(i=0;i<citem.size();i++)
item[i] = citem[i];
return true;
}
void Creatures::CopyNameTo(t_creature &creature, uint32_t address)
{
Private::t_offsets &offs = d->creatures;

@ -421,9 +421,11 @@ class Items::Private
Process * owner;
std::map<int32_t, ItemDesc *> descType;
std::map<uint32_t, ItemDesc *> descVTable;
std::map<int32_t, uint32_t> idLookupTable;
uint32_t refVectorOffset;
uint32_t refIDOffset;
uint32_t idFieldOffset;
uint32_t itemVectorAddress;
ClassNameCheck isOwnerRefClass;
};
@ -434,10 +436,15 @@ Items::Items(DFContextShared * d_)
d->owner = d_->p;
d->refVectorOffset = d->refIDOffset = 0;
d->isOwnerRefClass = ClassNameCheck("general_ref_unit_itemownerst");
DFHack::OffsetGroup* itemGroup = d_->offset_descriptor->getGroup("Items");
d->itemVectorAddress = itemGroup->getAddress("items_vector");
d->idFieldOffset = itemGroup->getOffset("id");
}
bool Items::Start()
{
d->idLookupTable.clear();
return true;
}
@ -446,6 +453,35 @@ bool Items::Finish()
return true;
}
bool Items::readItemVector(std::vector<uint32_t> &items)
{
DFHack::DfVector <uint32_t> p_items(d->owner, d->itemVectorAddress);
d->idLookupTable.clear();
items.resize(p_items.size());
for (unsigned i = 0; i < p_items.size(); i++) {
uint32_t ptr = p_items[i];
items[i] = ptr;
d->idLookupTable[d->owner->readDWord(ptr + d->idFieldOffset)] = ptr;
}
return true;
}
uint32_t Items::findItemByID(int32_t id)
{
if (id < 0)
return 0;
if (d->idLookupTable.empty()) {
std::vector<uint32_t> tmp;
readItemVector(tmp);
}
return d->idLookupTable[id];
}
Items::~Items()
{
Finish();

@ -285,19 +285,34 @@ void printCreature(DFHack::Context * DF, const DFHack::t_creature & creature)
}
}
//std::vector<uint32_t> inventory;
// FIXME: TOO BAD...
/*
if( Creatures->ReadInventoryPtr(creature.origin, inventory) )
std::vector<uint32_t> inventory;
if( Creatures->ReadInventoryPtr(creature.origin, inventory))
{
DFHack::Items * Items = DF->getItems();
printf("\tInventory:\n");
for(unsigned int i = 0; i < inventory.size(); i++)
{
printf("\t\t%s\n", Items->getItemDescription(inventory[i], Materials).c_str());
DFHack::dfh_item item;
if (Items->readItem(inventory[i], item))
printf("\t\t%d: %s\n", item.id, Items->getItemDescription(item, Materials).c_str());
}
}
std::vector<int32_t> owned;
if( Creatures->ReadOwnedItemsPtr(creature.origin, owned))
{
DFHack::Items * Items = DF->getItems();
printf("\tOwns:\n");
for (int i = 0; i < owned.size(); i++) {
uint32_t pitem = Items->findItemByID(owned[i]);
DFHack::dfh_item item;
if (!pitem || !Items->readItem(pitem,item))
pitem = 0;
printf("\t\t%d: %s\n", owned[i],
pitem ? Items->getItemDescription(item, Materials).c_str() : "?");
}
}
*/
/*
if(creature.pregnancy_timer > 0)