From 212500ee00a9cc07ec60c330257318fc4d90fbcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Mon, 11 Apr 2011 22:13:06 +0200 Subject: [PATCH] Big Items refactor, made all the Accessor offsets optional. --- Memory.xml | 77 +------ library/VersionInfo.cpp | 23 ++ library/include/dfhack-c/modules/Items_C.h | 4 +- library/include/dfhack/DFTypes.h | 69 +----- library/include/dfhack/VersionInfo.h | 3 + library/include/dfhack/modules/Items.h | 91 +++++++- library/modules/Items.cpp | 231 +++++++-------------- library/modules/Items_C.cpp | 8 +- library/modules/Materials.cpp | 92 ++++---- tools/examples/dfitemdump.cpp | 48 +++-- tools/playground/cleanowned.cpp | 37 ++-- 11 files changed, 293 insertions(+), 390 deletions(-) diff --git a/Memory.xml b/Memory.xml index d92156255..bb0c78fdd 100644 --- a/Memory.xml +++ b/Memory.xml @@ -1,7 +1,7 @@ - - + + @@ -31,16 +31,16 @@ - - - - - + + + + + - - -
- List of offsets in the VTable : - - - - - - - - - - (in the vtable) - +
- @@ -1966,10 +1945,6 @@ - @@ -1986,15 +1961,6 @@ - MISSING! - MISSING! - - MISSING! - MISSING! - MISSING! - MISSING! - MISSING! - @@ -2076,22 +2042,6 @@
- @@ -2181,11 +2131,6 @@ - diff --git a/library/VersionInfo.cpp b/library/VersionInfo.cpp index 2e88be602..720121f63 100644 --- a/library/VersionInfo.cpp +++ b/library/VersionInfo.cpp @@ -319,6 +319,17 @@ uint32_t OffsetGroup::getAddress (const string & key) throw Error::MissingMemoryDefinition("address", getFullName() + key); } +// Get named offset, return bool instead of throwing exceptions +bool OffsetGroup::getSafeAddress (const string & key, uint32_t & out) +{ + uint32_Iter iter = OGd->addresses.find(key); + if(iter != OGd->addresses.end() && (*iter).second.first == IS_VALID) + { + out = (*iter).second.second; + return true; + } + return false; +} // Get named offset int32_t OffsetGroup::getOffset (const string & key) @@ -335,6 +346,18 @@ int32_t OffsetGroup::getOffset (const string & key) throw Error::MissingMemoryDefinition("offset", getFullName() + key); } +// Get named offset, return bool instead of throwing exceptions +bool OffsetGroup::getSafeOffset (const string & key, int32_t & out) +{ + int32_Iter iter = OGd->offsets.find(key); + if(iter != OGd->offsets.end() && (*iter).second.first == IS_VALID) + { + out = (*iter).second.second; + return true; + } + return false; +} + // Get named numerical value uint32_t OffsetGroup::getHexValue (const string & key) diff --git a/library/include/dfhack-c/modules/Items_C.h b/library/include/dfhack-c/modules/Items_C.h index 2aa90cc3d..5f43dc0a7 100644 --- a/library/include/dfhack-c/modules/Items_C.h +++ b/library/include/dfhack-c/modules/Items_C.h @@ -37,9 +37,9 @@ extern "C" { DFHACK_EXPORT int Items_Start(DFHackObject* items); DFHACK_EXPORT int Items_Finish(DFHackObject* items); -DFHACK_EXPORT char* Items_getItemDescription(DFHackObject* items, uint32_t itemptr, DFHackObject* mats); +DFHACK_EXPORT char* Items_getItemDescription(DFHackObject* items, dfh_item* item, DFHackObject* mats); DFHACK_EXPORT char* Items_getItemClass(DFHackObject* items, int32_t index); -DFHACK_EXPORT int Items_getItemData(DFHackObject* items, uint32_t itemptr, t_item* item); +DFHACK_EXPORT int Items_getItemData(DFHackObject* items, uint32_t itemptr, dfh_item* item); #ifdef __cplusplus } diff --git a/library/include/dfhack/DFTypes.h b/library/include/dfhack/DFTypes.h index f53e5afa3..e40c02791 100644 --- a/library/include/dfhack/DFTypes.h +++ b/library/include/dfhack/DFTypes.h @@ -106,73 +106,6 @@ struct t_name bool has_name; }; -//raw -struct t_item_df40d -{ - uint32_t vtable; - uint16_t x; - uint16_t y; - uint16_t z; - uint32_t flags; - uint32_t unk1; - uint32_t unk2; - uint32_t ID; - // not complete -}; - -//From http://dwarffortresswiki.net/index.php/User:Rick/Memory_research -//They all seem to be valid on 40d as well -struct naked_itemflags -{ - unsigned int on_ground : 1; // 0000 0001 Item on ground - unsigned int in_job : 1; // 0000 0002 Item currently being used in a job - unsigned int u_ngrd1 : 1; // 0000 0004 unknown, unseen - unsigned int in_inventory : 1; // 0000 0008 Item in a creature or workshop inventory - - unsigned int u_ngrd2 : 1; // 0000 0010 unknown, lost (artifact)?, unseen - unsigned int in_building : 1; // 0000 0020 Part of a building (including mechanisms, bodies in coffins) - unsigned int u_ngrd3 : 1; // 0000 0040 unknown, unseen - unsigned int dead_dwarf : 1; // 0000 0080 Dwarf's dead body or body part - - unsigned int rotten : 1; // 0000 0100 Rotten food - unsigned int spider_web : 1; // 0000 0200 Thread in spider web - unsigned int construction : 1; // 0000 0400 Material used in construction - unsigned int u_ngrd5 : 1; // 0000 0800 unknown, unseen - - unsigned int unk3 : 1; // 0000 1000 unknown, unseen - unsigned int u_ngrd6 : 1; // 0000 2000 unknown, unseen - unsigned int foreign : 1; // 0000 4000 Item is imported - unsigned int u_ngrd7 : 1; // 0000 8000 unknown, unseen - - unsigned int owned : 1; // 0001 0000 Item is owned by a dwarf - unsigned int unk4 : 1; // 0002 0000 unknown, unseen - unsigned int artifact1 : 1; // 0004 0000 Artifact ? - unsigned int forbid : 1; // 0008 0000 Forbidden item - - unsigned int unk5 : 1; // 0010 0000 unknown, unseen - unsigned int dump : 1; // 0020 0000 Designated for dumping - unsigned int on_fire: 1; // 0040 0000 Indicates if item is on fire, Will Set Item On Fire if Set! - unsigned int melt : 1; // 0080 0000 Designated for melting, if applicable - - // 0100 0000 - 8000 0000 - unsigned int hidden : 1; // 0100 0000 Hidden item - unsigned int in_chest : 1; // 0200 0000 Stored in chest/part of well? - unsigned int unk6 : 1; // 0400 0000 unknown, unseen - unsigned int artifact2 : 1; // 0800 0000 Artifact ? - - unsigned int unk8 : 1; // 1000 0000 unknown, unseen - unsigned int unk9 : 1; // 2000 0000 unknown, set when viewing details - unsigned int unk10 : 1; // 4000 0000 unknown, unseen - unsigned int unk11 : 1; // 8000 0000 unknown, unseen -}; - -union t_itemflags -{ - uint32_t whole; - naked_itemflags bits; -}; - - struct t_note { char symbol; @@ -197,7 +130,7 @@ struct t_settlement int16_t local_y1; int16_t local_y2; }; - + struct t_attrib { uint32_t level; diff --git a/library/include/dfhack/VersionInfo.h b/library/include/dfhack/VersionInfo.h index 9b9184b0d..0bff54ed3 100644 --- a/library/include/dfhack/VersionInfo.h +++ b/library/include/dfhack/VersionInfo.h @@ -77,6 +77,9 @@ namespace DFHack std::string getString (const std::string & key); OffsetGroup * getGroup ( const std::string & name ); + bool getSafeOffset (const std::string & key, int32_t & out); + bool getSafeAddress (const std::string & key, uint32_t & out); + void setOffset (const std::string& key, const std::string& value, const DFHack::INVAL_TYPE inval = IS_VALID); void setOffsetValidity(const std::string& key, const DFHack::INVAL_TYPE inval = IS_VALID); void setAddress (const std::string& key, const std::string& value, const DFHack::INVAL_TYPE inval = IS_VALID); diff --git a/library/include/dfhack/modules/Items.h b/library/include/dfhack/modules/Items.h index 4b6021eed..d0f1c3e79 100644 --- a/library/include/dfhack/modules/Items.h +++ b/library/include/dfhack/modules/Items.h @@ -3,7 +3,7 @@ #define CL_MOD_ITEMS /* -* Creatures +* Items! */ #include "dfhack/DFExport.h" #include "dfhack/DFModule.h" @@ -15,22 +15,92 @@ namespace DFHack class Context; class DFContextShared; -struct t_item_header +//From http://dwarffortresswiki.net/index.php/User:Rick/Memory_research +//They all seem to be valid on 40d as well + + +union t_itemflags +{ + uint32_t whole; + struct + { + unsigned int on_ground : 1; // 0000 0001 Item on ground + unsigned int in_job : 1; // 0000 0002 Item currently being used in a job + unsigned int u_ngrd1 : 1; // 0000 0004 unknown, unseen + unsigned int in_inventory : 1; // 0000 0008 Item in a creature or workshop inventory + + unsigned int u_ngrd2 : 1; // 0000 0010 unknown, lost (artifact)?, unseen + unsigned int in_building : 1; // 0000 0020 Part of a building (including mechanisms, bodies in coffins) + unsigned int u_ngrd3 : 1; // 0000 0040 unknown, unseen + unsigned int dead_dwarf : 1; // 0000 0080 Dwarf's dead body or body part + + unsigned int rotten : 1; // 0000 0100 Rotten food + unsigned int spider_web : 1; // 0000 0200 Thread in spider web + unsigned int construction : 1; // 0000 0400 Material used in construction + unsigned int u_ngrd5 : 1; // 0000 0800 unknown, unseen + + unsigned int unk3 : 1; // 0000 1000 unknown, unseen + unsigned int u_ngrd6 : 1; // 0000 2000 unknown, unseen + unsigned int foreign : 1; // 0000 4000 Item is imported + unsigned int u_ngrd7 : 1; // 0000 8000 unknown, unseen + + unsigned int owned : 1; // 0001 0000 Item is owned by a dwarf + unsigned int unk4 : 1; // 0002 0000 unknown, unseen + unsigned int artifact1 : 1; // 0004 0000 Artifact ? + unsigned int forbid : 1; // 0008 0000 Forbidden item + + unsigned int unk5 : 1; // 0010 0000 unknown, unseen + unsigned int dump : 1; // 0020 0000 Designated for dumping + unsigned int on_fire: 1; // 0040 0000 Indicates if item is on fire, Will Set Item On Fire if Set! + unsigned int melt : 1; // 0080 0000 Designated for melting, if applicable + + // 0100 0000 - 8000 0000 + unsigned int hidden : 1; // 0100 0000 Hidden item + unsigned int in_chest : 1; // 0200 0000 Stored in chest/part of well? + unsigned int unk6 : 1; // 0400 0000 unknown, unseen + unsigned int artifact2 : 1; // 0800 0000 Artifact ? + + unsigned int unk8 : 1; // 1000 0000 unknown, unseen + unsigned int unk9 : 1; // 2000 0000 unknown, set when viewing details + unsigned int unk10 : 1; // 4000 0000 unknown, unseen + unsigned int unk11 : 1; // 8000 0000 unknown, unseen + }; +}; + +struct t_item { + uint32_t vtable; int16_t x; int16_t y; int16_t z; t_itemflags flags; }; -struct t_item +struct dfh_item { - t_item_header header; + t_item base; t_material matdesc; int32_t quantity; int32_t quality; int16_t wear_level; + uint32_t origin; +}; + +/* +//raw +struct t_item_df40d +{ + uint32_t vtable; + uint16_t x; + uint16_t y; + uint16_t z; + uint32_t flags; + uint32_t unk1; + uint32_t unk2; + uint32_t ID; + // not complete }; +*/ struct t_improvement { @@ -45,11 +115,16 @@ public: ~Items(); bool Start(); bool Finish(); - std::string getItemDescription(uint32_t itemptr, Materials * Materials); + /// get a string describing an item + std::string getItemDescription(const dfh_item & item, Materials * Materials); + /// get a short name for an item std::string getItemClass(int32_t index); - bool getItemData(uint32_t itemptr, t_item & item); - int32_t getItemOwnerID(uint32_t itemptr); - void setItemFlags(uint32_t itemptr, t_itemflags new_flags); + /// read an item, including the extra attributes + bool readItem(uint32_t itemptr, dfh_item & item); + /// write item base (position and flags only = t_item part of dfh_item) + bool writeItem(const dfh_item & item); + /// who owns this item we already read? + int32_t getItemOwnerID(const dfh_item & item); private: class Private; Private* d; diff --git a/library/modules/Items.cpp b/library/modules/Items.cpp index d29753b7d..d62aadec9 100644 --- a/library/modules/Items.cpp +++ b/library/modules/Items.cpp @@ -95,7 +95,7 @@ private: bool hasDecoration; public: ItemDesc(uint32_t VTable, Process * p); - bool getItem(uint32_t itemptr, t_item & item); + bool readItem(uint32_t itemptr, dfh_item & item); std::string className; uint32_t vtable; uint32_t mainType; @@ -165,18 +165,22 @@ static bool match_MOV_MEM(uint32_t &ptr, uint64_t v, int in_reg, int &out_reg, i } else return false; - + return match_MEM_ACCESS(ptr, v, prefix, in_reg, out_reg, offset); } -// FIXME: this is crazy Accessor::Accessor(uint32_t function, Process *p) { this->p = p; this->type = ACCESSOR_CONSTANT; + if(!p) + { + this->constant = 0; + return; + } uint32_t ptr = function; - uint64_t v = p->readQuad(ptr); int data_reg = -1; + uint64_t v = p->readQuad(ptr); if (do_match(ptr, v, 2, 0xFFFF, 0xC033) || do_match(ptr, v, 2, 0xFFFF, 0xC031)) // XOR EAX, EAX @@ -214,7 +218,7 @@ Accessor::Accessor(uint32_t function, Process *p) if (xsize == Data32) { v = p->readQuad(ptr); - + if (match_MOV_MEM(ptr, v, data_reg, tmp, this->offset2, xsize)) { data_reg = tmp; this->type = ACCESSOR_DOUBLE_INDIRECT; @@ -223,9 +227,9 @@ Accessor::Accessor(uint32_t function, Process *p) } } } - + v = p->readQuad(ptr); - + if (data_reg == 0 && do_match(ptr, v, 1, 0xFF, 0xC3)) // RET return; else @@ -275,44 +279,62 @@ int32_t Accessor::getValue(uint32_t objectPtr) } } +// FIXME: turn into a proper factory with caching +Accessor * buildAccessor (OffsetGroup * I, Process * p, const char * name, uint32_t vtable) +{ + int32_t offset; + if(I->getSafeOffset("item_type_accessor",offset)) + return new Accessor( p->readDWord( vtable + offset ), p); + else + { + fprintf(stderr,"Missing offset for item accessor \"%s\"\n", name); + return new Accessor(-1,0); // dummy accessor. always returns -1 + } +} + ItemDesc::ItemDesc(uint32_t VTable, Process *p) { + int32_t funcOffsetA, funcOffsetB, funcOffsetC, funcOffsetD, funcOffsetQuality, funcOffsetWear; OffsetGroup * Items = p->getDescriptor()->getGroup("Items"); - uint32_t funcOffsetA = Items->getOffset("item_type_accessor"); - uint32_t funcOffsetB = Items->getOffset("item_subtype_accessor"); - uint32_t funcOffsetC = Items->getOffset("item_subindex_accessor"); - uint32_t funcOffsetD = Items->getOffset("item_index_accessor"); - uint32_t funcOffsetQuality = Items->getOffset("item_quality_accessor"); - uint32_t funcOffsetWear = Items->getOffset("item_wear_accessor"); + + /* + * FIXME: and what about types, different sets of methods depending on class? + * what about more complex things than constants and integers? + * If this is to be generally useful, it needs much more power. + */ + AMainType = buildAccessor(Items, p, "item_type_accessor", VTable); + ASubType = buildAccessor(Items, p, "item_subtype_accessor", VTable); + ASubIndex = buildAccessor(Items, p, "item_subindex_accessor", VTable); + AIndex = buildAccessor(Items, p, "item_index_accessor", VTable); + AQuality = buildAccessor(Items, p, "item_quality_accessor", VTable); + AWear = buildAccessor(Items, p, "item_wear_accessor", VTable); + this->vtable = VTable; this->p = p; this->className = p->readClassName(VTable).substr(5); this->className.resize(this->className.size()-2); - this->AMainType = new Accessor( p->readDWord( VTable + funcOffsetA ), p); - this->ASubType = new Accessor( p->readDWord( VTable + funcOffsetB ), p); - this->ASubIndex = new Accessor( p->readDWord( VTable + funcOffsetC ), p); - this->AIndex = new Accessor( p->readDWord( VTable + funcOffsetD ), p); - this->AQuality = new Accessor( p->readDWord( VTable + funcOffsetQuality ), p); - this->AWear = new Accessor( p->readDWord( VTable + funcOffsetWear ), p); + this->hasDecoration = false; - if(this->AMainType->isConstant()) - this->mainType = this->AMainType->getValue(0); + if(AMainType->isConstant()) + mainType = this->AMainType->getValue(0); else { fprintf(stderr, "Bad item main type at function %p\n", (void*) p->readDWord( VTable + funcOffsetA )); - this->mainType = 0; + mainType = 0; } } -bool ItemDesc::getItem(uint32_t itemptr, DFHack::t_item &item) +bool ItemDesc::readItem(uint32_t itemptr, DFHack::dfh_item &item) { - this->p->read(itemptr+4, sizeof(t_item_header), (uint8_t*)&item.header); - item.matdesc.itemType = this->AMainType->getValue(itemptr); - item.matdesc.subType = this->ASubType->getValue(itemptr); - item.matdesc.subIndex = this->ASubIndex->getValue(itemptr); - item.matdesc.index = this->AIndex->getValue(itemptr); - item.quality = this->AQuality->getValue(itemptr); + p->read(itemptr, sizeof(t_item), (uint8_t*)&item.base); + item.matdesc.itemType = AMainType->getValue(itemptr); + item.matdesc.subType = ASubType->getValue(itemptr); + item.matdesc.subIndex = ASubIndex->getValue(itemptr); + item.matdesc.index = AIndex->getValue(itemptr); + item.quality = AQuality->getValue(itemptr); item.quantity = 1; /* TODO */ + item.origin = itemptr; + // FIXME: use templates. seriously. // Note: this accessor returns a 32-bit value with the higher // half sometimes containing garbage, so the cast is essential: item.wear_level = (int16_t)this->AWear->getValue(itemptr); @@ -364,7 +386,7 @@ Items::~Items() delete d; } -bool Items::getItemData(uint32_t itemptr, DFHack::t_item &item) +bool Items::readItem(uint32_t itemptr, DFHack::dfh_item &item) { std::map::iterator it; Process * p = d->owner; @@ -381,15 +403,26 @@ bool Items::getItemData(uint32_t itemptr, DFHack::t_item &item) else desc = it->second; - return desc->getItem(itemptr, item); + return desc->readItem(itemptr, item); +} + +bool Items::writeItem(const DFHack::dfh_item &item) +{ + if(item.origin) + { + d->owner->write(item.origin, sizeof(t_item),(uint8_t *)&(item.base)); + return true; + } + return false; } +/* void Items::setItemFlags(uint32_t itemptr, t_itemflags new_flags) { d->owner->writeDWord(itemptr + 0x0C, new_flags.whole); } - -int32_t Items::getItemOwnerID(uint32_t itemptr) +*/ +int32_t Items::getItemOwnerID(const DFHack::dfh_item &item) { if (!d->refVectorOffset) { @@ -398,7 +431,7 @@ int32_t Items::getItemOwnerID(uint32_t itemptr) d->refIDOffset = Items->getOffset("owner_ref_id_field"); } - DFHack::DfVector p_refs(d->owner, itemptr + d->refVectorOffset); + DFHack::DfVector p_refs(d->owner, item.origin + d->refVectorOffset); uint32_t size = p_refs.size(); for (uint32_t i=0;igetDescription(item.matdesc)); out.append(" "); out.append(this->getItemClass(item.matdesc.itemType)); - return out; -} - -// The OLD items code follows (40d era) -// TODO: merge with the current Items module -/* -bool API::InitReadItems(uint32_t & numitems) -{ - try - { - int items = d->offset_descriptor->getAddress ("items"); - d->item_material_offset = d->offset_descriptor->getOffset ("item_materials"); - - d->p_itm = new DfVector (d->p, items); - d->itemsInited = true; - numitems = d->p_itm->getSize(); - return true; - } - catch (Error::AllMemdef&) - { - d->itemsInited = false; - numitems = 0; - throw; - } -} - -bool API::getItemIndexesInBox(vector &indexes, - const uint16_t x1, const uint16_t y1, const uint16_t z1, - const uint16_t x2, const uint16_t y2, const uint16_t z2) -{ - if(!d->itemsInited) return false; - indexes.clear(); - uint32_t size = d->p_itm->getSize(); - struct temp2{ - uint16_t coords[3]; - uint32_t flags; - }; - temp2 temp2; - for(uint32_t i =0;ip_itm->at(i); - d->p->read(temp+sizeof(uint32_t),5 * sizeof(uint16_t), (uint8_t *) &temp2); - if(temp2.flags & (1 << 0)){ - if (temp2.coords[0] >= x1 && temp2.coords[0] < x2) - { - if (temp2.coords[1] >= y1 && temp2.coords[1] < y2) - { - if (temp2.coords[2] >= z1 && temp2.coords[2] < z2) - { - indexes.push_back(i); - } - } - } - } - } - return true; -} - -bool API::ReadItem (const uint32_t index, t_item & item) -{ - if (!d->itemsInited) return false; - - t_item_df40d item_40d; - - // read pointer from vector at position - uint32_t temp = d->p_itm->at (index); - - //read building from memory - d->p->read (temp, sizeof (t_item_df40d), (uint8_t *) &item_40d); - - // transform - int32_t type = -1; - d->offset_descriptor->resolveObjectToClassID (temp, type); - item.origin = temp; - item.vtable = item_40d.vtable; - item.x = item_40d.x; - item.y = item_40d.y; - item.z = item_40d.z; - item.type = type; - item.ID = item_40d.ID; - item.flags.whole = item_40d.flags; - - //TODO certain item types (creature based, threads, seeds, bags do not have the first matType byte, instead they have the material index only located at 0x68 - d->p->read (temp + d->item_material_offset, sizeof (t_matglossPair), (uint8_t *) &item.material); - //for(int i = 0; i < 0xCC; i++){ // used for item research - // uint8_t byte = MreadByte(temp+i); - // item.bytes.push_back(byte); - //} - return true; -} -void API::FinishReadItems() -{ - if(d->p_itm) - { - delete d->p_itm; - d->p_itm = NULL; - } - d->itemsInited = false; -} -*/ -/* -bool API::ReadItemTypes(vector< vector< t_itemType > > & itemTypes) -{ - memory_info * minfo = d->offset_descriptor; - int matgloss_address = minfo->getAddress("matgloss"); - int matgloss_skip = minfo->getHexValue("matgloss_skip"); - int item_type_name_offset = minfo->getOffset("item_type_name"); - for(int i = 8;i<20;i++) - { - DfVector p_temp (d->p, matgloss_address + i*matgloss_skip); - vector< t_itemType > typesForVec; - for(uint32_t j =0; jp->readSTLString(temp+4,currType.id,128); - d->p->readSTLString(temp+item_type_name_offset,currType.name,128); - //stringsForVec.push_back(string(name)); - typesForVec.push_back(currType); - } - itemTypes.push_back(typesForVec); - } - return true; + */ + //return out; + return getItemClass(item.matdesc.itemType); } -*/ \ No newline at end of file diff --git a/library/modules/Items_C.cpp b/library/modules/Items_C.cpp index 05ead2929..ce56292a6 100644 --- a/library/modules/Items_C.cpp +++ b/library/modules/Items_C.cpp @@ -54,11 +54,11 @@ int Items_Finish(DFHackObject* items) //FIXME: beware of bad null-termination! I haven't tested anything here, but it seems that it could be corrupting or truncating strings. -char* Items_getItemDescription(DFHackObject* items, uint32_t itemptr, DFHackObject* mats) +char* Items_getItemDescription(DFHackObject* items, dfh_item * item, DFHackObject* mats) { if(items != NULL && mats != NULL) { - std::string desc = ((DFHack::Items*)items)->getItemDescription(itemptr, (DFHack::Materials*)mats); + std::string desc = ((DFHack::Items*)items)->getItemDescription(*item, (DFHack::Materials*)mats); if(desc.size() > 0) { @@ -112,11 +112,11 @@ char* Items_getItemClass(DFHackObject* items, int32_t index) return NULL; } -int Items_getItemData(DFHackObject* items, uint32_t itemptr, t_item* item) +int Items_getItemData(DFHackObject* items, uint32_t itemptr, dfh_item* item) { if(items != NULL) { - return ((DFHack::Items*)items)->getItemData(itemptr, *item); + return ((DFHack::Items*)items)->readItem(itemptr, *item); } return -1; diff --git a/library/modules/Materials.cpp b/library/modules/Materials.cpp index 20e19f9b1..2a7ecf917 100644 --- a/library/modules/Materials.cpp +++ b/library/modules/Materials.cpp @@ -544,50 +544,50 @@ std::string Materials::getDescription(t_material & mat) //type of material only so we know which vector to retrieve std::string Materials::getType(t_material & mat) { - if((mat.subIndex<419) || (mat.subIndex>618)) - { - if((mat.subIndex<19) || (mat.subIndex>218)) - { - if(mat.subIndex) - { - if(mat.subIndex>0x292) - { - return "unknown"; - } - else - { - if(mat.subIndex>=this->other.size()) - { - if(mat.subIndex<0) - return "any"; - - if(mat.subIndex>=this->raceEx.size()) - return "unknown"; - - return "racex"; - } - else - { - if (mat.index==-1) - return "other"; - else - return "other derivate"; - } - } - } - else - return "inorganic"; - } - else - { - if (mat.index>=this->raceEx.size()) - return "unknown"; - - return "racex extract"; - } - } - else - { - return "organic"; - } + if((mat.subIndex<419) || (mat.subIndex>618)) + { + if((mat.subIndex<19) || (mat.subIndex>218)) + { + if(mat.subIndex) + { + if(mat.subIndex>0x292) + { + return "unknown"; + } + else + { + if(mat.subIndex>=this->other.size()) + { + if(mat.subIndex<0) + return "any"; + + if(mat.subIndex>=this->raceEx.size()) + return "unknown"; + + return "racex"; + } + else + { + if (mat.index==-1) + return "other"; + else + return "other derivate"; + } + } + } + else + return "inorganic"; + } + else + { + if (mat.index>=this->raceEx.size()) + return "unknown"; + + return "racex extract"; + } + } + else + { + return "organic"; + } } \ No newline at end of file diff --git a/tools/examples/dfitemdump.cpp b/tools/examples/dfitemdump.cpp index 7633a243a..875f38b76 100644 --- a/tools/examples/dfitemdump.cpp +++ b/tools/examples/dfitemdump.cpp @@ -1,28 +1,19 @@ /* - * dumps vtables, items types and class name for all items in game - * best used this way : ./dfitemdump | sort -ug + * Simple, pretty item dump example. */ -// THIS IS NOT A GOOD EXAMPLE! -// ... just look at all the magic numbers. -// I'm not fixing it though. -// ~px - -#include +#include #include #include #include #include #include +#include using namespace std; #include #include - -DFHack::Materials * Materials; -DFHack::Items * Items; - int main () { DFHack::Process * p; @@ -42,17 +33,36 @@ int main () #endif return 1; } + DFHack::Materials * Materials = DF->getMaterials(); + Materials->ReadAllMaterials(); + + DFHack::Items * Items = DF->getItems(); + Items->Start(); DFHack::VersionInfo * mem = DF->getMemoryInfo(); - Materials = DF->getMaterials(); - Materials->ReadAllMaterials(); p = DF->getProcess(); + + // FIXME: tools should never be exposed to DFHack internals! DFHack::OffsetGroup* itemGroup = mem->getGroup("Items"); DFHack::DfVector p_items (p, itemGroup->getAddress("items_vector")); uint32_t size = p_items.size(); - Items = DF->getItems(); - + for(int i = 0; i < size; i++) + { + DFHack::dfh_item itm; + memset(&itm, 0, sizeof(DFHack::dfh_item)); + Items->readItem(p_items[i],itm); + printf( + "%5d: %08x %08x (%d,%d,%d) #%08x [%d] %s - %s\n", + i, itm.origin, itm.base.flags.whole, + itm.base.x, itm.base.y, itm.base.z, + itm.base.vtable, + itm.wear_level, + Items->getItemClass(itm.matdesc.itemType).c_str(), + Items->getItemDescription(itm, Materials).c_str() + ); + } +/* printf("type\tvtable\tname\tquality\tdecorate\n"); for (i=0;ireadClassName(vtable); - DFHack::t_item itm; + DFHack::dfh_item itm; - Items->getItemData(p_items[i], itm); + Items->readItem(p_items[i], itm); if ( (funct0&0xFFFFFFFFFF000000LL) != 0xCCCCC30000000000LL ) { @@ -226,7 +236,7 @@ int main () } printf("\n"); } - +*/ #ifndef LINUX_BUILD cout << "Done. Press any key to continue" << endl; cin.ignore(); diff --git a/tools/playground/cleanowned.cpp b/tools/playground/cleanowned.cpp index 116754dc8..f68d4eb9a 100644 --- a/tools/playground/cleanowned.cpp +++ b/tools/playground/cleanowned.cpp @@ -2,7 +2,7 @@ * Confiscates and dumps garbage owned by dwarfs. */ -#include +#include #include #include #include @@ -88,16 +88,16 @@ int main (int argc, char *argv[]) for (i=0;igetItemData(curItem, itm); + DFHack::dfh_item itm; + Items->readItem(curItem, itm); - if (!itm.header.flags.bits.owned) + if (!itm.base.flags.owned) continue; bool confiscate = false; bool dump = false; - if (itm.header.flags.bits.rotten) + if (itm.base.flags.rotten) { printf("Confiscating a rotten item: \t"); confiscate = true; @@ -108,7 +108,7 @@ int main (int argc, char *argv[]) confiscate = true; dump = true; } - else if (dump_scattered && itm.header.flags.bits.on_ground) + else if (dump_scattered && itm.base.flags.on_ground) { printf("Confiscating and dumping litter: \t"); confiscate = true; @@ -122,20 +122,20 @@ int main (int argc, char *argv[]) if (confiscate) { - itm.header.flags.bits.owned = 0; + itm.base.flags.owned = 0; if (dump) - itm.header.flags.bits.dump = 1; + itm.base.flags.dump = 1; if (!dry_run) - Items->setItemFlags(curItem, itm.header.flags); + Items->writeItem(itm); printf( "%s (wear %d)", - Items->getItemDescription(curItem, Materials).c_str(), + Items->getItemDescription(itm, Materials).c_str(), itm.wear_level ); - int32_t owner = Items->getItemOwnerID(curItem); + int32_t owner = Items->getItemOwnerID(itm); int32_t owner_index = Creatures->FindIndexById(owner); std::string info; @@ -153,17 +153,18 @@ int main (int argc, char *argv[]) } printf("\n"); - -/* printf( +/* + printf( "%5d: %08x %08x (%d,%d,%d) #%08x [%d] %s - %s %s\n", - i, curItem, itm.header.flags.whole, - itm.header.x, itm.header.y, itm.header.z, - p->readDWord(curItem), + i, itm.origin, itm.base.flags.whole, + itm.base.x, itm.base.y, itm.base.z, + itm.base.vtable, itm.wear_level, Items->getItemClass(itm.matdesc.itemType).c_str(), - Items->getItemDescription(curItem, Materials).c_str(), + Items->getItemDescription(itm, Materials).c_str(), info.c_str() - );*/ + ); + */ } }