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"
using namespace DFHack;
std::string t_virtual::getClassName()
std::string t_virtual::getClassName() const
{
Core & c = Core::getInstance();
return c.p->readClassName(vptr);

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

@ -23,9 +23,6 @@ distribution.
*/
#pragma once
#ifndef CL_MOD_ITEMS
#define CL_MOD_ITEMS
/*
* Items!
*/
@ -133,8 +130,8 @@ public:
// 0x0
virtual int32_t getType();
virtual int16_t getSubtype();
virtual int32_t getSubMaterial();
virtual int16_t getMaterial();
virtual int32_t getMaterialIndex();
// 0x10
/*
hm, [4] looks complicated *
@ -145,12 +142,12 @@ public:
*/
virtual void fn4(void);
virtual void setMaterial(int16_t mat);
virtual void setSubMaterial (int32_t submat);
virtual void setMaterialIndex (int32_t submat);
// another one? really?
virtual int16_t getMaterial2();
// 0x20
// more of the same?
virtual int32_t getSubMaterial2();
virtual int32_t getMaterialIndex2();
virtual void fn9(void);
virtual void fn10(void);
virtual void fn11(void);
@ -374,7 +371,13 @@ public:
*/
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;
int32_t quantity;
int32_t quality;
@ -408,32 +411,28 @@ public:
bool readItemVector(std::vector<df_item *> &items);
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
bool readItem(df_item * itembase, dfh_item & item);
/// write item base (position and flags only = t_item part of dfh_item)
bool copyItem(df_item * source, dfh_item & target);
/// write copied item back to its origin
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?
int32_t getItemOwnerID(const dfh_item & item);
int32_t getItemOwnerID(const df_item * item);
/// 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?
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
bool removeItemOwner(dfh_item &item, Creatures *creatures);
bool readItemRefs(const dfh_item &item, const ClassNameCheck &classname,
std::vector<int32_t> &values);
bool unknownRefs(const dfh_item &item, std::vector<std::string>& names,
std::vector<int32_t>& values);
bool removeItemOwner(df_item * item, Creatures *creatures);
/// read item references, filtered by class
bool readItemRefs(const df_item * item, const ClassNameCheck &classname,
/*output*/ std::vector<int32_t> &values);
/// get list of item references that are unknown along with their values
bool unknownRefs(const df_item * item, /*output*/ std::vector<std::pair<std::string, int32_t> >& refs);
private:
class Private;
Private* d;
};
}
#endif

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

@ -187,23 +187,29 @@ Items::~Items()
delete d;
}
bool Items::readItem(df_item * itembase, DFHack::dfh_item &item)
bool Items::copyItem(df_item * itembase, DFHack::dfh_item &item)
{
if(!itembase)
return false;
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.subType = itreal->getSubtype();
item.matdesc.index = itreal->getMaterial();
item.matdesc.subIndex = itreal->getSubMaterial();
item.matdesc.material = itreal->getMaterial();
item.matdesc.index = itreal->getMaterialIndex();
item.wear_level = itreal->getWear();
item.quality = itreal->getQuality();
item.quantity = itreal->getStackSize();
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;
if (readItemRefs(item, d->isOwnerRefClass, vals))
@ -212,7 +218,7 @@ int32_t Items::getItemOwnerID(const DFHack::dfh_item &item)
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;
if (readItemRefs(item, d->isContainerRefClass, vals))
@ -221,14 +227,14 @@ int32_t Items::getItemContainerID(const DFHack::dfh_item &item)
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);
}
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();
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();
}
bool Items::unknownRefs(const dfh_item &item, std::vector<std::string>& names,
std::vector<int32_t>& values)
bool Items::unknownRefs(const df_item * item, std::vector<std::pair<std::string, int32_t> >& refs)
{
names.clear();
values.clear();
refs.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++)
{
@ -254,17 +258,16 @@ bool Items::unknownRefs(const dfh_item &item, std::vector<std::string>& names,
if (d->knownItemRefTypes.find(name) == d->knownItemRefTypes.end())
{
names.push_back(name);
values.push_back(p_refs[i]->value);
refs.push_back(pair<string, int32_t>(name, 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++)
{
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 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;
}
p_refs.erase(p_refs.begin() + i--);
}
item.base->flags.owned = 0;
item->flags.owned = 0;
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 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;
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.subIndex>0x292)
if (mat.material)
if (mat.material>0x292)
return "?";
else
{
if (mat.subIndex>=this->other.size())
if (mat.material>=this->other.size())
{
if (mat.itemType == 0) {
if(mat.subIndex<0)
if(mat.material<0)
return "any inorganic";
else
return this->inorganic[mat.subIndex].id;
return this->inorganic[mat.material].id;
}
if(mat.subIndex<0)
if(mat.material<0)
return "any";
if(mat.subIndex>=this->raceEx.size())
if(mat.material>=this->raceEx.size())
return "stuff";
return this->raceEx[mat.subIndex].id;
return this->raceEx[mat.material].id;
}
else
{
if (mat.index==-1)
return std::string(this->other[mat.subIndex].id);
return std::string(this->other[mat.material].id);
else
return std::string(this->other[mat.subIndex].id) + " derivate";
return std::string(this->other[mat.material].id) + " derivate";
}
}
else
@ -405,7 +405,7 @@ std::string Materials::getDescription(const t_material & mat)
{
if (mat.index>=this->raceEx.size())
return "unknown race";
typeC = mat.subIndex;
typeC = mat.material;
typeC -=19;
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!
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";
}
else
{
if(mat.subIndex>=this->other.size())
if(mat.material>=this->other.size())
{
if(mat.subIndex<0)
if(mat.material<0)
return "any";
if(mat.subIndex>=this->raceEx.size())
if(mat.material>=this->raceEx.size())
return "unknown";
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++)
{
df_item * curItem = p_items[i];
DFHack::dfh_item itm;
Items->readItem(curItem, itm);
df_item * item = p_items[i];
bool confiscate = 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)
{
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");
confiscate = true;
}
else if (itm.base->flags.on_ground &&
(name == "food" || name == "meat" || name == "plant"))
// FIXME: this is wrong
else if (item->flags.on_ground && (name == "food" || name == "meat" || name == "plant"))
{
c->con.print("Confiscating a dropped foodstuff: \t");
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");
confiscate = 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");
confiscate = true;
@ -166,15 +163,15 @@ DFhackCExport command_result df_cleanowned (Core * c, vector <string> & paramete
if (confiscate)
{
std::string description;
itm.base->getItemDescription(&description, 0);
item->getItemDescription(&description, 0);
c->con.print(
"0x%x %s (wear %d)",
itm.base,
item,
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);
std::string info;
@ -191,10 +188,10 @@ DFhackCExport command_result df_cleanowned (Core * c, vector <string> & paramete
if (!dry_run)
{
if (!Items->removeItemOwner(itm, Creatures))
if (!Items->removeItemOwner(item, Creatures))
c->con.print("(unsuccessfully) ");
if (dump)
itm.base->flags.dump = 1;
item->flags.dump = 1;
}
c->con.print("\n");
}

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

@ -8,6 +8,7 @@
#include "dfhack/modules/Maps.h"
#include "dfhack/modules/Items.h"
#include <dfhack/modules/Gui.h>
#include <llimits.h>
using std::vector;
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);
if(b)
{
c->con.print("Items in block:\n");
c->con.print("Item IDs present in block:\n");
auto iter_b = b->items.begin();
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++;
}
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;
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 ++;
}