diff --git a/Memory.xml b/Memory.xml
index 25df466d4..3e6b2e998 100644
--- a/Memory.xml
+++ b/Memory.xml
@@ -895,6 +895,7 @@
+
@@ -3013,6 +3014,7 @@
+
diff --git a/library/include/dfhack/modules/Creatures.h b/library/include/dfhack/modules/Creatures.h
index 3d0520c40..f175aad3a 100644
--- a/library/include/dfhack/modules/Creatures.h
+++ b/library/include/dfhack/modules/Creatures.h
@@ -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 & mat);
+
bool ReadInventoryIdx(const uint32_t index, std::vector & item);
bool ReadInventoryPtr(const uint32_t index, std::vector & item);
+ bool ReadOwnedItemsIdx(const uint32_t index, std::vector & item);
+ bool ReadOwnedItemsPtr(const uint32_t index, std::vector & item);
+
int32_t FindIndexById(int32_t id);
/* Getters */
diff --git a/library/include/dfhack/modules/Items.h b/library/include/dfhack/modules/Items.h
index b164ff287..966bd1b99 100644
--- a/library/include/dfhack/modules/Items.h
+++ b/library/include/dfhack/modules/Items.h
@@ -116,6 +116,10 @@ public:
~Items();
bool Start();
bool Finish();
+
+ bool readItemVector(std::vector &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
diff --git a/library/modules/Creatures.cpp b/library/modules/Creatures.cpp
index 4aa12063d..d2eb757e3 100644
--- a/library/modules/Creatures.cpp
+++ b/library/modules/Creatures.cpp
@@ -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 & it
return true;
}
+bool Creatures::ReadOwnedItemsIdx(const uint32_t index, std::vector & 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 & item)
+{
+ unsigned int i;
+ if(!d->Started || !d->Ft_owned_items) return false;
+ Process * p = d->owner;
+
+ DfVector citem(p, temp + d->creatures.owned_items_offset);
+ if(citem.size() == 0)
+ return false;
+ item.resize(citem.size());
+ for(i=0;icreatures;
diff --git a/library/modules/Items.cpp b/library/modules/Items.cpp
index 238352c08..033a2b929 100644
--- a/library/modules/Items.cpp
+++ b/library/modules/Items.cpp
@@ -421,9 +421,11 @@ class Items::Private
Process * owner;
std::map descType;
std::map descVTable;
+ std::map 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 &items)
+{
+ DFHack::DfVector 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 tmp;
+ readItemVector(tmp);
+ }
+
+ return d->idLookupTable[id];
+}
+
Items::~Items()
{
Finish();
diff --git a/tools/examples/creaturedump.cpp b/tools/examples/creaturedump.cpp
index ad8ac7c8a..32beae150 100644
--- a/tools/examples/creaturedump.cpp
+++ b/tools/examples/creaturedump.cpp
@@ -285,19 +285,34 @@ void printCreature(DFHack::Context * DF, const DFHack::t_creature & creature)
}
}
- //std::vector inventory;
// FIXME: TOO BAD...
- /*
- if( Creatures->ReadInventoryPtr(creature.origin, inventory) )
+ std::vector 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 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)