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);
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;

@ -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<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);
private:
class Private;

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

@ -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<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)
{
return getItemClass(item.matdesc.itemType);

@ -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)",