From a7be2aee337c16bbd587b0dd42bff911f98889e9 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Thu, 12 May 2011 21:09:49 +0400 Subject: [PATCH] Support actually removing owner links between items and creatures. --- library/include/dfhack/modules/Creatures.h | 5 ++++ library/include/dfhack/modules/Items.h | 4 ++++ library/modules/Creatures.cpp | 24 +++++++++++++++++++ library/modules/Items.cpp | 25 ++++++++++++++++++++ tools/supported/cleanowned.cpp | 27 ++++++++++++++-------- 5 files changed, 76 insertions(+), 9 deletions(-) diff --git a/library/include/dfhack/modules/Creatures.h b/library/include/dfhack/modules/Creatures.h index f175aad3a..99f6fd9c3 100644 --- a/library/include/dfhack/modules/Creatures.h +++ b/library/include/dfhack/modules/Creatures.h @@ -347,6 +347,11 @@ namespace DFHack void CopyNameTo(t_creature &creature, uint32_t address); + protected: + friend class Items; + bool RemoveOwnedItemIdx(const uint32_t index, int32_t id); + bool RemoveOwnedItemPtr(const uint32_t index, int32_t id); + private: struct Private; Private *d; diff --git a/library/include/dfhack/modules/Items.h b/library/include/dfhack/modules/Items.h index c009f3b9f..1ea509c5c 100644 --- a/library/include/dfhack/modules/Items.h +++ b/library/include/dfhack/modules/Items.h @@ -14,6 +14,7 @@ namespace DFHack class Context; class DFContextShared; +class Creatures; //From http://dwarffortresswiki.net/index.php/User:Rick/Memory_research //They all seem to be valid on 40d as well @@ -139,6 +140,9 @@ public: /// which items does it contain? bool getContainedItems(const dfh_item & item, std::vector &items); + /// wipe out the owner records + bool removeItemOwner(dfh_item &item, Creatures *creatures); + bool readItemRefs(const dfh_item &item, const ClassNameCheck &classname, std::vector &values); private: class Private; diff --git a/library/modules/Creatures.cpp b/library/modules/Creatures.cpp index d2eb757e3..fc6615616 100644 --- a/library/modules/Creatures.cpp +++ b/library/modules/Creatures.cpp @@ -722,6 +722,30 @@ bool Creatures::ReadOwnedItemsPtr(const uint32_t temp, std::vector & it return true; } +bool Creatures::RemoveOwnedItemIdx(const uint32_t index, int32_t id) +{ + if(!d->Started || !d->Ft_owned_items) return false; + uint32_t temp = d->p_cre->at (index); + return this->RemoveOwnedItemPtr(temp, id); +} + +bool Creatures::RemoveOwnedItemPtr(const uint32_t temp, int32_t id) +{ + if(!d->Started || !d->Ft_owned_items) return false; + Process * p = d->owner; + + DfVector citem(p, temp + d->creatures.owned_items_offset); + + for (unsigned i = 0; i < citem.size(); i++) { + if (citem[i] != id) + continue; + if (!citem.remove(i--)) + return false; + } + + return true; +} + void Creatures::CopyNameTo(t_creature &creature, uint32_t address) { Private::t_offsets &offs = d->creatures; diff --git a/library/modules/Items.cpp b/library/modules/Items.cpp index 9ab8c9c18..e9affec1a 100644 --- a/library/modules/Items.cpp +++ b/library/modules/Items.cpp @@ -38,6 +38,7 @@ using namespace std; #include "dfhack/DFVector.h" #include "dfhack/modules/Materials.h" #include "dfhack/modules/Items.h" +#include "dfhack/modules/Creatures.h" #include "ModuleFactory.h" using namespace DFHack; @@ -579,6 +580,30 @@ bool Items::readItemRefs(const dfh_item &item, const ClassNameCheck &classname, return !values.empty(); } +bool Items::removeItemOwner(dfh_item &item, Creatures *creatures) +{ + DFHack::DfVector p_refs(d->owner, item.origin + d->refVectorOffset); + + for (uint32_t i=0; iowner->readDWord(p_refs[i]); + if (!d->isOwnerRefClass(d->owner, vtbl)) continue; + + int32_t oid = d->owner->readDWord(p_refs[i]+4); + int32_t ix = creatures->FindIndexById(oid); + + if (ix < 0 || !creatures->RemoveOwnedItemIdx(ix, item.id)) + return false; + + if (!p_refs.remove(i--)) + return false; + } + + item.base.flags.owned = 0; + + return true; +} + std::string Items::getItemClass(const dfh_item & item) { return getItemClass(item.matdesc.itemType); diff --git a/tools/supported/cleanowned.cpp b/tools/supported/cleanowned.cpp index d26ae5c99..050c03434 100644 --- a/tools/supported/cleanowned.cpp +++ b/tools/supported/cleanowned.cpp @@ -91,14 +91,21 @@ int main (int argc, char *argv[]) DFHack::dfh_item itm; Items->readItem(curItem, itm); - if (!itm.base.flags.owned) - continue; - - std::string name = Items->getItemClass(itm.matdesc.itemType); - bool confiscate = false; bool dump = false; + if (!itm.base.flags.owned) { + int32_t owner = Items->getItemOwnerID(itm); + if (owner >= 0) { + printf("Fixing a misflagged item: "); + confiscate = true; + } + else + continue; + } + + std::string name = Items->getItemClass(itm.matdesc.itemType); + if (itm.base.flags.rotten) { printf("Confiscating a rotten item: \t"); @@ -130,12 +137,14 @@ int main (int argc, char *argv[]) if (confiscate) { - itm.base.flags.owned = 0; - if (dump) - itm.base.flags.dump = 1; + if (!dry_run) { + if (!Items->removeItemOwner(itm, Creatures)) + printf("(unsuccessfully) "); + if (dump) + itm.base.flags.dump = 1; - if (!dry_run) Items->writeItem(itm); + } printf( "%s (wear %d)",