Items refactor. readItem turned into copyItem, most Items methods now accept plain df_item * instead of the copies.

develop
Petr Mrázek 2011-10-26 22:18:13 +02:00
parent 70ebacead0
commit b545de7f43
9 changed files with 124 additions and 129 deletions

@ -9,7 +9,7 @@
#include "dfhack/Virtual.h" #include "dfhack/Virtual.h"
using namespace DFHack; using namespace DFHack;
std::string t_virtual::getClassName() std::string t_virtual::getClassName() const
{ {
Core & c = Core::getInstance(); Core & c = Core::getInstance();
return c.p->readClassName(vptr); return c.p->readClassName(vptr);

@ -31,6 +31,6 @@ namespace DFHack
struct t_virtual struct t_virtual
{ {
void * vptr; void * vptr;
std::string getClassName(); std::string getClassName() const;
}; };
} }

@ -23,9 +23,6 @@ distribution.
*/ */
#pragma once #pragma once
#ifndef CL_MOD_ITEMS
#define CL_MOD_ITEMS
/* /*
* Items! * Items!
*/ */
@ -133,8 +130,8 @@ public:
// 0x0 // 0x0
virtual int32_t getType(); virtual int32_t getType();
virtual int16_t getSubtype(); virtual int16_t getSubtype();
virtual int32_t getSubMaterial();
virtual int16_t getMaterial(); virtual int16_t getMaterial();
virtual int32_t getMaterialIndex();
// 0x10 // 0x10
/* /*
hm, [4] looks complicated * hm, [4] looks complicated *
@ -145,12 +142,12 @@ public:
*/ */
virtual void fn4(void); virtual void fn4(void);
virtual void setMaterial(int16_t mat); virtual void setMaterial(int16_t mat);
virtual void setSubMaterial (int32_t submat); virtual void setMaterialIndex (int32_t submat);
// another one? really? // another one? really?
virtual int16_t getMaterial2(); virtual int16_t getMaterial2();
// 0x20 // 0x20
// more of the same? // more of the same?
virtual int32_t getSubMaterial2(); virtual int32_t getMaterialIndex2();
virtual void fn9(void); virtual void fn9(void);
virtual void fn10(void); virtual void fn10(void);
virtual void fn11(void); virtual void fn11(void);
@ -374,7 +371,13 @@ public:
*/ */
struct dfh_item struct dfh_item
{ {
df_item * base; df_item *origin; // where this was read from
int16_t x;
int16_t y;
int16_t z;
t_itemflags flags;
uint32_t age;
uint32_t id;
t_material matdesc; t_material matdesc;
int32_t quantity; int32_t quantity;
int32_t quality; int32_t quality;
@ -408,32 +411,28 @@ public:
bool readItemVector(std::vector<df_item *> &items); bool readItemVector(std::vector<df_item *> &items);
df_item * findItemByID(int32_t id); df_item * findItemByID(int32_t id);
/// get a string describing an item
//std::string getItemDescription(const dfh_item & item, int type);
/// get a short name for an item
std::string getItemClass(const dfh_item & item);
/// read an item, including the extra attributes /// read an item, including the extra attributes
bool readItem(df_item * itembase, dfh_item & item); bool copyItem(df_item * source, dfh_item & target);
/// write item base (position and flags only = t_item part of dfh_item) /// write copied item back to its origin
bool writeItem(const dfh_item & item); bool writeItem(const dfh_item & item);
/// get the class name of an item
std::string getItemClass(const df_item * item);
/// who owns this item we already read? /// who owns this item we already read?
int32_t getItemOwnerID(const dfh_item & item); int32_t getItemOwnerID(const df_item * item);
/// which item is it contained in? /// which item is it contained in?
int32_t getItemContainerID(const dfh_item & item); int32_t getItemContainerID(const df_item * item);
/// which items does it contain? /// which items does it contain?
bool getContainedItems(const dfh_item & item, std::vector<int32_t> &items); bool getContainedItems(const df_item * item, /*output*/ std::vector<int32_t> &items);
/// wipe out the owner records /// wipe out the owner records
bool removeItemOwner(dfh_item &item, Creatures *creatures); bool removeItemOwner(df_item * item, Creatures *creatures);
/// read item references, filtered by class
bool readItemRefs(const dfh_item &item, const ClassNameCheck &classname, bool readItemRefs(const df_item * item, const ClassNameCheck &classname,
std::vector<int32_t> &values); /*output*/ std::vector<int32_t> &values);
bool unknownRefs(const dfh_item &item, std::vector<std::string>& names, /// get list of item references that are unknown along with their values
std::vector<int32_t>& values); bool unknownRefs(const df_item * item, /*output*/ std::vector<std::pair<std::string, int32_t> >& refs);
private: private:
class Private; class Private;
Private* d; Private* d;
}; };
} }
#endif

@ -483,7 +483,7 @@ namespace DFHack
{ {
int16_t itemType; int16_t itemType;
int16_t subType; int16_t subType;
int16_t subIndex; int16_t material;
int32_t index; int32_t index;
uint32_t flags; uint32_t flags;
}; };

@ -187,23 +187,29 @@ Items::~Items()
delete d; delete d;
} }
bool Items::readItem(df_item * itembase, DFHack::dfh_item &item) bool Items::copyItem(df_item * itembase, DFHack::dfh_item &item)
{ {
if(!itembase) if(!itembase)
return false; return false;
df_item * itreal = (df_item *) itembase; df_item * itreal = (df_item *) itembase;
item.base = itembase; item.origin = itembase;
item.x = itreal->x;
item.y = itreal->y;
item.z = itreal->z;
item.id = itreal->id;
item.age = itreal->age;
item.flags = itreal->flags;
item.matdesc.itemType = itreal->getType(); item.matdesc.itemType = itreal->getType();
item.matdesc.subType = itreal->getSubtype(); item.matdesc.subType = itreal->getSubtype();
item.matdesc.index = itreal->getMaterial(); item.matdesc.material = itreal->getMaterial();
item.matdesc.subIndex = itreal->getSubMaterial(); item.matdesc.index = itreal->getMaterialIndex();
item.wear_level = itreal->getWear(); item.wear_level = itreal->getWear();
item.quality = itreal->getQuality(); item.quality = itreal->getQuality();
item.quantity = itreal->getStackSize(); item.quantity = itreal->getStackSize();
return true; return true;
} }
int32_t Items::getItemOwnerID(const DFHack::dfh_item &item) int32_t Items::getItemOwnerID(const DFHack::df_item * item)
{ {
std::vector<int32_t> vals; std::vector<int32_t> vals;
if (readItemRefs(item, d->isOwnerRefClass, vals)) if (readItemRefs(item, d->isOwnerRefClass, vals))
@ -212,7 +218,7 @@ int32_t Items::getItemOwnerID(const DFHack::dfh_item &item)
return -1; return -1;
} }
int32_t Items::getItemContainerID(const DFHack::dfh_item &item) int32_t Items::getItemContainerID(const DFHack::df_item * item)
{ {
std::vector<int32_t> vals; std::vector<int32_t> vals;
if (readItemRefs(item, d->isContainerRefClass, vals)) if (readItemRefs(item, d->isContainerRefClass, vals))
@ -221,14 +227,14 @@ int32_t Items::getItemContainerID(const DFHack::dfh_item &item)
return -1; return -1;
} }
bool Items::getContainedItems(const DFHack::dfh_item &item, std::vector<int32_t> &items) bool Items::getContainedItems(const DFHack::df_item * item, std::vector<int32_t> &items)
{ {
return readItemRefs(item, d->isContainsRefClass, items); return readItemRefs(item, d->isContainsRefClass, items);
} }
bool Items::readItemRefs(const dfh_item &item, const ClassNameCheck &classname, std::vector<int32_t> &values) bool Items::readItemRefs(const df_item * item, const ClassNameCheck &classname, std::vector<int32_t> &values)
{ {
std::vector <t_itemref *> &p_refs = item.base->itemrefs; const std::vector <t_itemref *> &p_refs = item->itemrefs;
values.clear(); values.clear();
for (uint32_t i=0; i<p_refs.size(); i++) for (uint32_t i=0; i<p_refs.size(); i++)
@ -240,13 +246,11 @@ bool Items::readItemRefs(const dfh_item &item, const ClassNameCheck &classname,
return !values.empty(); return !values.empty();
} }
bool Items::unknownRefs(const dfh_item &item, std::vector<std::string>& names, bool Items::unknownRefs(const df_item * item, std::vector<std::pair<std::string, int32_t> >& refs)
std::vector<int32_t>& values)
{ {
names.clear(); refs.clear();
values.clear();
std::vector <t_itemref *> &p_refs = item.base->itemrefs; const std::vector <t_itemref *> &p_refs = item->itemrefs;
for (uint32_t i=0; i<p_refs.size(); i++) for (uint32_t i=0; i<p_refs.size(); i++)
{ {
@ -254,17 +258,16 @@ bool Items::unknownRefs(const dfh_item &item, std::vector<std::string>& names,
if (d->knownItemRefTypes.find(name) == d->knownItemRefTypes.end()) if (d->knownItemRefTypes.find(name) == d->knownItemRefTypes.end())
{ {
names.push_back(name); refs.push_back(pair<string, int32_t>(name, p_refs[i]->value));
values.push_back(p_refs[i]->value);
} }
} }
return (names.size() > 0); return (refs.size() > 0);
} }
bool Items::removeItemOwner(dfh_item &item, Creatures *creatures) bool Items::removeItemOwner(df_item * item, Creatures *creatures)
{ {
std::vector <t_itemref *> &p_refs = item.base->itemrefs; std::vector <t_itemref *> &p_refs = item->itemrefs;
for (uint32_t i=0; i<p_refs.size(); i++) for (uint32_t i=0; i<p_refs.size(); i++)
{ {
if (!d->isOwnerRefClass(d->owner, p_refs[i]->vptr)) if (!d->isOwnerRefClass(d->owner, p_refs[i]->vptr))
@ -273,30 +276,22 @@ bool Items::removeItemOwner(dfh_item &item, Creatures *creatures)
int32_t & oid = p_refs[i]->value; int32_t & oid = p_refs[i]->value;
int32_t ix = creatures->FindIndexById(oid); int32_t ix = creatures->FindIndexById(oid);
if (ix < 0 || !creatures->RemoveOwnedItemByIdx(ix, item.base->id)) if (ix < 0 || !creatures->RemoveOwnedItemByIdx(ix, item->id))
{ {
cerr << "RemoveOwnedItemIdx: CREATURE " << ix << " ID " << item.base->id << " FAILED!" << endl; cerr << "RemoveOwnedItemIdx: CREATURE " << ix << " ID " << item->id << " FAILED!" << endl;
return false; return false;
} }
p_refs.erase(p_refs.begin() + i--); p_refs.erase(p_refs.begin() + i--);
} }
item.base->flags.owned = 0; item->flags.owned = 0;
return true; return true;
} }
std::string Items::getItemClass(const dfh_item & item) std::string Items::getItemClass(const df_item * item)
{ {
t_virtual * virt = (t_virtual *) item.base; const t_virtual * virt = (t_virtual *) item;
return virt->getClassName(); return virt->getClassName();
//return getItemClass(item.matdesc.itemType);
} }
/*
std::string Items::getItemDescription(const dfh_item & item, int type)
{
std::string strzzz;
item.base->getItemDescription(&strzzz,type);
// delete ptrs;
return strzzz;
}*/

@ -362,35 +362,35 @@ std::string Materials::getDescription(const t_material & mat)
{ {
std::string out; std::string out;
int32_t typeC; int32_t typeC;
if ( (mat.subIndex<419) || (mat.subIndex>618) ) if ( (mat.material<419) || (mat.material>618) )
{ {
if ( (mat.subIndex<19) || (mat.subIndex>218) ) if ( (mat.material<19) || (mat.material>218) )
{ {
if (mat.subIndex) if (mat.material)
if (mat.subIndex>0x292) if (mat.material>0x292)
return "?"; return "?";
else else
{ {
if (mat.subIndex>=this->other.size()) if (mat.material>=this->other.size())
{ {
if (mat.itemType == 0) { if (mat.itemType == 0) {
if(mat.subIndex<0) if(mat.material<0)
return "any inorganic"; return "any inorganic";
else else
return this->inorganic[mat.subIndex].id; return this->inorganic[mat.material].id;
} }
if(mat.subIndex<0) if(mat.material<0)
return "any"; return "any";
if(mat.subIndex>=this->raceEx.size()) if(mat.material>=this->raceEx.size())
return "stuff"; return "stuff";
return this->raceEx[mat.subIndex].id; return this->raceEx[mat.material].id;
} }
else else
{ {
if (mat.index==-1) if (mat.index==-1)
return std::string(this->other[mat.subIndex].id); return std::string(this->other[mat.material].id);
else else
return std::string(this->other[mat.subIndex].id) + " derivate"; return std::string(this->other[mat.material].id) + " derivate";
} }
} }
else else
@ -405,7 +405,7 @@ std::string Materials::getDescription(const t_material & mat)
{ {
if (mat.index>=this->raceEx.size()) if (mat.index>=this->raceEx.size())
return "unknown race"; return "unknown race";
typeC = mat.subIndex; typeC = mat.material;
typeC -=19; typeC -=19;
if ((typeC<0) || (typeC>=this->raceEx[mat.index].extract.size())) if ((typeC<0) || (typeC>=this->raceEx[mat.index].extract.size()))
{ {
@ -425,24 +425,24 @@ std::string Materials::getDescription(const t_material & mat)
// FIXME: this also contains potential errors when the indexes are -1 and compared to unsigned numbers! // FIXME: this also contains potential errors when the indexes are -1 and compared to unsigned numbers!
std::string Materials::getType(const t_material & mat) std::string Materials::getType(const t_material & mat)
{ {
if((mat.subIndex<419) || (mat.subIndex>618)) if((mat.material<419) || (mat.material>618))
{ {
if((mat.subIndex<19) || (mat.subIndex>218)) if((mat.material<19) || (mat.material>218))
{ {
if(mat.subIndex) if(mat.material)
{ {
if(mat.subIndex>0x292) if(mat.material>0x292)
{ {
return "unknown"; return "unknown";
} }
else else
{ {
if(mat.subIndex>=this->other.size()) if(mat.material>=this->other.size())
{ {
if(mat.subIndex<0) if(mat.material<0)
return "any"; return "any";
if(mat.subIndex>=this->raceEx.size()) if(mat.material>=this->raceEx.size())
return "unknown"; return "unknown";
return "racex"; return "racex";

@ -111,16 +111,13 @@ DFhackCExport command_result df_cleanowned (Core * c, vector <string> & paramete
for (std::size_t i=0; i < p_items.size(); i++) for (std::size_t i=0; i < p_items.size(); i++)
{ {
df_item * curItem = p_items[i]; df_item * item = p_items[i];
DFHack::dfh_item itm;
Items->readItem(curItem, itm);
bool confiscate = false; bool confiscate = false;
bool dump = false; bool dump = false;
if (!itm.base->flags.owned) if (!item->flags.owned)
{ {
int32_t owner = Items->getItemOwnerID(itm); int32_t owner = Items->getItemOwnerID(item);
if (owner >= 0) if (owner >= 0)
{ {
c->con.print("Fixing a misflagged item: "); c->con.print("Fixing a misflagged item: ");
@ -132,26 +129,26 @@ DFhackCExport command_result df_cleanowned (Core * c, vector <string> & paramete
} }
} }
std::string name = Items->getItemClass(itm); std::string name = Items->getItemClass(item);
if (itm.base->flags.rotten) if (item->flags.rotten)
{ {
c->con.print("Confiscating a rotten item: \t"); c->con.print("Confiscating a rotten item: \t");
confiscate = true; confiscate = true;
} }
else if (itm.base->flags.on_ground && // FIXME: this is wrong
(name == "food" || name == "meat" || name == "plant")) else if (item->flags.on_ground && (name == "food" || name == "meat" || name == "plant"))
{ {
c->con.print("Confiscating a dropped foodstuff: \t"); c->con.print("Confiscating a dropped foodstuff: \t");
confiscate = true; confiscate = true;
} }
else if (itm.wear_level >= wear_dump_level) else if (item->getWear() >= wear_dump_level)
{ {
c->con.print("Confiscating and dumping a worn item: \t"); c->con.print("Confiscating and dumping a worn item: \t");
confiscate = true; confiscate = true;
dump = true; dump = true;
} }
else if (dump_scattered && itm.base->flags.on_ground) else if (dump_scattered && item->flags.on_ground)
{ {
c->con.print("Confiscating and dumping litter: \t"); c->con.print("Confiscating and dumping litter: \t");
confiscate = true; confiscate = true;
@ -166,15 +163,15 @@ DFhackCExport command_result df_cleanowned (Core * c, vector <string> & paramete
if (confiscate) if (confiscate)
{ {
std::string description; std::string description;
itm.base->getItemDescription(&description, 0); item->getItemDescription(&description, 0);
c->con.print( c->con.print(
"0x%x %s (wear %d)", "0x%x %s (wear %d)",
itm.base, item,
description.c_str(), description.c_str(),
itm.wear_level item->getWear()
); );
int32_t owner = Items->getItemOwnerID(itm); int32_t owner = Items->getItemOwnerID(item);
int32_t owner_index = Creatures->FindIndexById(owner); int32_t owner_index = Creatures->FindIndexById(owner);
std::string info; std::string info;
@ -191,10 +188,10 @@ DFhackCExport command_result df_cleanowned (Core * c, vector <string> & paramete
if (!dry_run) if (!dry_run)
{ {
if (!Items->removeItemOwner(itm, Creatures)) if (!Items->removeItemOwner(item, Creatures))
c->con.print("(unsuccessfully) "); c->con.print("(unsuccessfully) ");
if (dump) if (dump)
itm.base->flags.dump = 1; item->flags.dump = 1;
} }
c->con.print("\n"); c->con.print("\n");
} }

@ -57,15 +57,14 @@ public:
virtual bool doPrint(DFHack::dfh_item *itm) virtual bool doPrint(DFHack::dfh_item *itm)
{ {
if (itm->base->unk1.size() > 0) if (itm->origin->unk1.size() > 0)
return true; return true;
std::vector<std::string> refs; std::vector<std::pair<std::string, int32_t> > refs;
std::vector<int32_t> values; if (Items->unknownRefs(itm->origin, refs))
if (Items->unknownRefs(*itm, refs, values))
return true; return true;
t_itemflags &f = itm->base->flags; t_itemflags &f = itm->origin->flags;
return (f.unk1 || f.unk2 || f.unk3 || f.unk4 || /*f.unk5 ||*/ return (f.unk1 || f.unk2 || f.unk3 || f.unk4 || /*f.unk5 ||*/
f.unk6 || f.unk7 || f.unk6 || f.unk7 ||
@ -77,19 +76,18 @@ public:
{ {
std::vector<std::string> flags; std::vector<std::string> flags;
t_itemflags &f = itm->base->flags; t_itemflags &f = itm->origin->flags;
if (itm->base->unk1.size() > 0) if (itm->origin->unk1.size() > 0)
c->con.print(" vec1: %p\n", itm->base->unk1[0]); c->con.print(" vec1: %p\n", itm->origin->unk1[0]);
std::vector<std::string> refs; std::vector<std::pair<std::string, int32_t> > refs;
std::vector<int32_t> values; if (Items->unknownRefs(itm->origin, refs))
if (Items->unknownRefs(*itm, refs, values))
{ {
c->con.print(" refs: "); c->con.print(" refs: ");
for (size_t i = 0; i < refs.size(); i++) for (size_t i = 0; i < refs.size(); i++)
{ {
c->con.print("%s: %d", refs[i].c_str(), values[i]); c->con.print("%s: %d", refs[i].first.c_str(), refs[i].second);
if ( (i + 1) < refs.size() ) if ( (i + 1) < refs.size() )
c->con.print(", "); c->con.print(", ");
} }
@ -133,11 +131,11 @@ public:
virtual bool doPrint(DFHack::dfh_item *itm) virtual bool doPrint(DFHack::dfh_item *itm)
{ {
return (itm->base->x == x && itm->base->y == y && itm->base->z == z return (itm->origin->x == x && itm->origin->y == y && itm->origin->z == z
&& itm->base->flags.on_ground && itm->origin->flags.on_ground
&& !itm->base->flags.in_chest && !itm->origin->flags.in_chest
&& !itm->base->flags.in_inventory && !itm->origin->flags.in_inventory
&& !itm->base->flags.in_building); && !itm->origin->flags.in_building);
} }
protected: protected:
@ -211,7 +209,7 @@ DFhackCExport command_result df_dumpitems (Core * c, vector <string> & parameter
{ {
DFHack::dfh_item itm; DFHack::dfh_item itm;
memset(&itm, 0, sizeof(DFHack::dfh_item)); memset(&itm, 0, sizeof(DFHack::dfh_item));
Items->readItem(p_items[i],itm); Items->copyItem(p_items[i],itm);
if (!chooser->doPrint(&itm)) if (!chooser->doPrint(&itm))
continue; continue;
@ -219,28 +217,28 @@ DFhackCExport command_result df_dumpitems (Core * c, vector <string> & parameter
// Print something useful, instead of (-30000,-30000,-30000), if // Print something useful, instead of (-30000,-30000,-30000), if
// the item isn't on the ground. // the item isn't on the ground.
char location[80]; char location[80];
if (itm.base->flags.in_chest) if (itm.origin->flags.in_chest)
sprintf(location, "chest"); sprintf(location, "chest");
else if (itm.base->flags.in_inventory) else if (itm.origin->flags.in_inventory)
sprintf(location, "inventory"); sprintf(location, "inventory");
else if (itm.base->flags.in_building) else if (itm.origin->flags.in_building)
sprintf(location, "building"); sprintf(location, "building");
else else
sprintf(location, "%d,%d,%d", itm.base->x, itm.base->y, sprintf(location, "%d,%d,%d", itm.origin->x, itm.origin->y,
itm.base->z); itm.origin->z);
std::string descr; std::string descr;
string name1,name2,name0; string name1,name2,name0;
itm.base->getItemDescription(&name0, 0); itm.origin->getItemDescription(&name0, 0);
itm.base->getItemDescription(&name1, 1); itm.origin->getItemDescription(&name1, 1);
itm.base->getItemDescription(&name2, 2); itm.origin->getItemDescription(&name2, 2);
c->con.print( c->con.print(
"%5d: addr:0x%08x %6d %08x (%s) vptr:0x%08x [%d]\n" "%5d: addr:0x%08x %6d %08x (%s) vptr:0x%08x [%d]\n"
" %s\n" " %s\n"
" %s\n" " %s\n"
" %s\n", " %s\n",
i, itm.base, itm.base->id, itm.base->flags.whole, i, itm.origin, itm.origin->id, itm.origin->flags.whole,
location, location,
((t_virtual *)itm.base)->vptr, ((t_virtual *)itm.origin)->vptr,
itm.wear_level, itm.wear_level,
name0.c_str(),// stacked name0.c_str(),// stacked
name1.c_str(),// singular name1.c_str(),// singular

@ -8,6 +8,7 @@
#include "dfhack/modules/Maps.h" #include "dfhack/modules/Maps.h"
#include "dfhack/modules/Items.h" #include "dfhack/modules/Items.h"
#include <dfhack/modules/Gui.h> #include <dfhack/modules/Gui.h>
#include <llimits.h>
using std::vector; using std::vector;
using std::string; using std::string;
@ -130,11 +131,14 @@ DFhackCExport command_result mapitems (Core * c, vector <string> & parameters)
df_block * b = m->getBlock(cx/16,cy/16,cz); df_block * b = m->getBlock(cx/16,cy/16,cz);
if(b) if(b)
{ {
c->con.print("Items in block:\n"); c->con.print("Item IDs present in block:\n");
auto iter_b = b->items.begin(); auto iter_b = b->items.begin();
while (iter_b != b->items.end()) while (iter_b != b->items.end())
{ {
c->con.print("%d\n",*iter_b); df_item * itmz = it->findItemByID(*iter_b);
string s;
itmz->getItemDescription(&s);
c->con.print("%d = %s\n",*iter_b, s.c_str());
iter_b++; iter_b++;
} }
c->con.print("Items under cursor:\n"); c->con.print("Items under cursor:\n");
@ -144,7 +148,9 @@ DFhackCExport command_result mapitems (Core * c, vector <string> & parameters)
df_item * itm = *iter_it; df_item * itm = *iter_it;
if(itm->x == cx && itm->y == cy && itm->z == cz) if(itm->x == cx && itm->y == cy && itm->z == cz)
{ {
c->con.print("%d\n",itm->id); string s;
itm->getItemDescription(&s,0);
c->con.print("%d = %s\n",itm->id, s.c_str());
} }
iter_it ++; iter_it ++;
} }