Support actually removing owner links between items and creatures.

develop
Alexander Gavrilov 2011-05-12 21:09:49 +04:00
parent c7f4f8c281
commit a7be2aee33
5 changed files with 76 additions and 9 deletions

@ -347,6 +347,11 @@ namespace DFHack
void CopyNameTo(t_creature &creature, uint32_t address); 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: private:
struct Private; struct Private;
Private *d; Private *d;

@ -14,6 +14,7 @@ namespace DFHack
class Context; class Context;
class DFContextShared; class DFContextShared;
class Creatures;
//From http://dwarffortresswiki.net/index.php/User:Rick/Memory_research //From http://dwarffortresswiki.net/index.php/User:Rick/Memory_research
//They all seem to be valid on 40d as well //They all seem to be valid on 40d as well
@ -139,6 +140,9 @@ public:
/// which items does it contain? /// which items does it contain?
bool getContainedItems(const dfh_item & item, std::vector<int32_t> &items); bool getContainedItems(const dfh_item & item, std::vector<int32_t> &items);
/// wipe out the owner records
bool removeItemOwner(dfh_item &item, Creatures *creatures);
bool readItemRefs(const dfh_item &item, const ClassNameCheck &classname, std::vector<int32_t> &values); bool readItemRefs(const dfh_item &item, const ClassNameCheck &classname, std::vector<int32_t> &values);
private: private:
class Private; class Private;

@ -722,6 +722,30 @@ bool Creatures::ReadOwnedItemsPtr(const uint32_t temp, std::vector<int32_t> & it
return true; 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 <int32_t> 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) void Creatures::CopyNameTo(t_creature &creature, uint32_t address)
{ {
Private::t_offsets &offs = d->creatures; Private::t_offsets &offs = d->creatures;

@ -38,6 +38,7 @@ using namespace std;
#include "dfhack/DFVector.h" #include "dfhack/DFVector.h"
#include "dfhack/modules/Materials.h" #include "dfhack/modules/Materials.h"
#include "dfhack/modules/Items.h" #include "dfhack/modules/Items.h"
#include "dfhack/modules/Creatures.h"
#include "ModuleFactory.h" #include "ModuleFactory.h"
using namespace DFHack; using namespace DFHack;
@ -579,6 +580,30 @@ bool Items::readItemRefs(const dfh_item &item, const ClassNameCheck &classname,
return !values.empty(); return !values.empty();
} }
bool Items::removeItemOwner(dfh_item &item, Creatures *creatures)
{
DFHack::DfVector<uint32_t> p_refs(d->owner, item.origin + d->refVectorOffset);
for (uint32_t i=0; i<p_refs.size(); i++)
{
uint32_t vtbl = d->owner->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) std::string Items::getItemClass(const dfh_item & item)
{ {
return getItemClass(item.matdesc.itemType); return getItemClass(item.matdesc.itemType);

@ -91,14 +91,21 @@ int main (int argc, char *argv[])
DFHack::dfh_item itm; DFHack::dfh_item itm;
Items->readItem(curItem, itm); Items->readItem(curItem, itm);
if (!itm.base.flags.owned)
continue;
std::string name = Items->getItemClass(itm.matdesc.itemType);
bool confiscate = false; bool confiscate = false;
bool dump = 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) if (itm.base.flags.rotten)
{ {
printf("Confiscating a rotten item: \t"); printf("Confiscating a rotten item: \t");
@ -130,12 +137,14 @@ int main (int argc, char *argv[])
if (confiscate) if (confiscate)
{ {
itm.base.flags.owned = 0; if (!dry_run) {
if (dump) if (!Items->removeItemOwner(itm, Creatures))
itm.base.flags.dump = 1; printf("(unsuccessfully) ");
if (dump)
itm.base.flags.dump = 1;
if (!dry_run)
Items->writeItem(itm); Items->writeItem(itm);
}
printf( printf(
"%s (wear %d)", "%s (wear %d)",