diff --git a/library/Core.cpp b/library/Core.cpp index 30063a71f..53d1fe90c 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -1088,7 +1088,6 @@ TYPE * Core::get##TYPE() \ return s_mods.p##TYPE;\ } -MODULE_GETTER(Units); MODULE_GETTER(Engravings); MODULE_GETTER(Gui); MODULE_GETTER(World); diff --git a/library/include/Core.h b/library/include/Core.h index c2b947bc6..4d5a15749 100644 --- a/library/include/Core.h +++ b/library/include/Core.h @@ -52,7 +52,6 @@ namespace DFHack { class Process; class Module; - class Units; class Engravings; class Gui; class World; @@ -96,8 +95,6 @@ namespace DFHack /// Is everything OK? bool isValid(void) { return !errorstate; } - /// get the creatures module - Units * getUnits(); /// get the engravings module Engravings * getEngravings(); /// get the gui module @@ -158,7 +155,6 @@ namespace DFHack // Module storage struct { - Units * pUnits; Engravings * pEngravings; Gui * pGui; World * pWorld; diff --git a/library/include/ModuleFactory.h b/library/include/ModuleFactory.h index d87f0fc1d..0596a83fd 100644 --- a/library/include/ModuleFactory.h +++ b/library/include/ModuleFactory.h @@ -30,7 +30,6 @@ distribution. namespace DFHack { class Module; - Module* createUnits(); Module* createEngravings(); Module* createGui(); Module* createWorld(); diff --git a/library/include/modules/Items.h b/library/include/modules/Items.h index 4cd29766a..c0b5b8412 100644 --- a/library/include/modules/Items.h +++ b/library/include/modules/Items.h @@ -90,7 +90,6 @@ namespace DFHack class Context; class DFContextShared; -class Units; /** * Type for holding an item read from DF @@ -133,12 +132,14 @@ DFHACK_EXPORT bool writeItem(const dfh_item & item); DFHACK_EXPORT std::string getItemClass(const df::item * item); /// who owns this item we already read? DFHACK_EXPORT int32_t getItemOwnerID(const df::item * item); +DFHACK_EXPORT df::unit *getItemOwner(const df::item * item); /// which item is it contained in? DFHACK_EXPORT int32_t getItemContainerID(const df::item * item); +DFHACK_EXPORT df::item *getItemContainer(const df::item * item); /// which items does it contain? DFHACK_EXPORT bool getContainedItems(const df::item * item, /*output*/ std::vector &items); /// wipe out the owner records -DFHACK_EXPORT bool removeItemOwner(df::item * item, Units *creatures); +DFHACK_EXPORT bool removeItemOwner(df::item * item); /// read item references, filtered by class DFHACK_EXPORT bool readItemRefs(const df::item * item, const df::general_ref_type type, /*output*/ std::vector &values); diff --git a/library/include/modules/Units.h b/library/include/modules/Units.h index 493014e9d..eea3e6ecf 100644 --- a/library/include/modules/Units.h +++ b/library/include/modules/Units.h @@ -26,11 +26,11 @@ distribution. #ifndef CL_MOD_CREATURES #define CL_MOD_CREATURES /* -* Creatures -*/ + * Creatures + */ #include "Export.h" -#include "Module.h" #include "modules/Items.h" +#include "DataDefs.h" #include "df/unit.h" /** @@ -39,234 +39,161 @@ distribution. */ namespace DFHack { - // FIXME: WTF IS THIS SHIT? - /* - struct t_labor - { - string name; - uint8_t value; - t_labor() { - value =0; - } - t_labor(const t_labor & b){ - name=b.name; - value=b.value; - } - t_labor & operator=(const t_labor &b){ - name=b.name; - value=b.value; - return *this; - } - }; - struct t_skill - { - string name; - uint16_t id; +namespace Simple +{ +namespace Units +{ +/** + * \ingroup grp_units + */ +struct t_skill +{ + uint32_t id; + uint32_t rating; uint32_t experience; - uint16_t rating; - t_skill(){ - id=rating=0; - experience=0; - } - t_skill(const t_skill & b) - { - name=b.name; - id=b.id; - experience=b.experience; - rating=b.rating; - } - t_skill & operator=(const t_skill &b) - { - name=b.name; - id=b.id; - experience=b.experience; - rating=b.rating; - return *this; - } - }; - - struct t_trait - { - uint16_t value; - string displayTxt; - string name; - t_trait(){ - value=0; - } - t_trait(const t_trait &b) - { - name=b.name; - displayTxt=b.displayTxt; - value=b.value; - } - t_trait & operator=(const t_trait &b) - { - name=b.name; - displayTxt=b.displayTxt; - value=b.value; - return *this; - } - }; - */ - /** - * \ingroup grp_units - */ - struct t_skill - { - uint32_t id; - uint32_t rating; - uint32_t experience; - }; - /** - * \ingroup grp_units - */ - struct t_job - { - bool active; - uint32_t jobId; - uint8_t jobType; - uint32_t occupationPtr; - }; - /** - * \ingroup grp_units - */ - struct t_like - { - int16_t type; - int16_t itemClass; - int16_t itemIndex; - t_matglossPair material; - bool active; - uint32_t mystery; - }; - - // FIXME: THIS IS VERY, VERY BAD. - #define NUM_CREATURE_LABORS 96 - #define NUM_CREATURE_TRAITS 30 - #define NUM_CREATURE_MENTAL_ATTRIBUTES 13 - #define NUM_CREATURE_PHYSICAL_ATTRIBUTES 6 - /** - * Structure for holding a copy of a DF unit's soul - * \ingroup grp_units - */ - struct t_soul - { - uint8_t numSkills; - t_skill skills[256]; - //uint8_t numLikes; - //t_like likes[32]; - uint16_t traits[NUM_CREATURE_TRAITS]; - t_attrib analytical_ability; - t_attrib focus; - t_attrib willpower; - t_attrib creativity; - t_attrib intuition; - t_attrib patience; - t_attrib memory; - t_attrib linguistic_ability; - t_attrib spatial_sense; - t_attrib musicality; - t_attrib kinesthetic_sense; - t_attrib empathy; - t_attrib social_awareness; - }; - #define MAX_COLORS 15 - struct df_unit; - /** - * Structure for holding a limited copy of a DF unit - * \ingroup grp_units - */ - struct t_unit - { - df::unit * origin; - uint16_t x; - uint16_t y; - uint16_t z; - uint32_t race; - int32_t civ; - - df::unit_flags1 flags1; - df::unit_flags2 flags2; - df::unit_flags3 flags3; - - t_name name; - - int16_t mood; - int16_t mood_skill; - t_name artifact_name; - - uint8_t profession; - std::string custom_profession; - - // enabled labors - uint8_t labors[NUM_CREATURE_LABORS]; - t_job current_job; - - uint32_t happiness; - uint32_t id; - t_attrib strength; - t_attrib agility; - t_attrib toughness; - t_attrib endurance; - t_attrib recuperation; - t_attrib disease_resistance; - int32_t squad_leader_id; - uint8_t sex; - uint16_t caste; - uint32_t pregnancy_timer; //Countdown timer to giving birth - //bool has_default_soul; - //t_soul defaultSoul; - uint32_t nbcolors; - uint32_t color[MAX_COLORS]; - - int32_t birth_year; - uint32_t birth_time; - }; +}; +/** + * \ingroup grp_units + */ +struct t_job +{ + bool active; + uint32_t jobId; + uint8_t jobType; + uint32_t occupationPtr; +}; +/** + * \ingroup grp_units + */ +struct t_like +{ + int16_t type; + int16_t itemClass; + int16_t itemIndex; + t_matglossPair material; + bool active; + uint32_t mystery; +}; + +// FIXME: THIS IS VERY, VERY BAD. +#define NUM_CREATURE_LABORS 96 +#define NUM_CREATURE_TRAITS 30 +#define NUM_CREATURE_MENTAL_ATTRIBUTES 13 +#define NUM_CREATURE_PHYSICAL_ATTRIBUTES 6 +/** + * Structure for holding a copy of a DF unit's soul + * \ingroup grp_units + */ +struct t_soul +{ + uint8_t numSkills; + t_skill skills[256]; + //uint8_t numLikes; + //t_like likes[32]; + uint16_t traits[NUM_CREATURE_TRAITS]; + t_attrib analytical_ability; + t_attrib focus; + t_attrib willpower; + t_attrib creativity; + t_attrib intuition; + t_attrib patience; + t_attrib memory; + t_attrib linguistic_ability; + t_attrib spatial_sense; + t_attrib musicality; + t_attrib kinesthetic_sense; + t_attrib empathy; + t_attrib social_awareness; +}; +#define MAX_COLORS 15 +struct df_unit; +/** + * Structure for holding a limited copy of a DF unit + * \ingroup grp_units + */ +struct t_unit +{ + df::unit * origin; + uint16_t x; + uint16_t y; + uint16_t z; + uint32_t race; + int32_t civ; + + df::unit_flags1 flags1; + df::unit_flags2 flags2; + df::unit_flags3 flags3; + + t_name name; + + int16_t mood; + int16_t mood_skill; + t_name artifact_name; + + uint8_t profession; + std::string custom_profession; + + // enabled labors + uint8_t labors[NUM_CREATURE_LABORS]; + t_job current_job; + + uint32_t happiness; + uint32_t id; + t_attrib strength; + t_attrib agility; + t_attrib toughness; + t_attrib endurance; + t_attrib recuperation; + t_attrib disease_resistance; + int32_t squad_leader_id; + uint8_t sex; + uint16_t caste; + uint32_t pregnancy_timer; //Countdown timer to giving birth + //bool has_default_soul; + //t_soul defaultSoul; + uint32_t nbcolors; + uint32_t color[MAX_COLORS]; + + int32_t birth_year; + uint32_t birth_time; +}; - /** - * The Creatures module - allows reading all non-vermin creatures and their properties - * \ingroup grp_modules - * \ingroup grp_units - */ - class DFHACK_EXPORT Units : public Module - { - public: - Units(); - ~Units(); - bool Start( uint32_t & numCreatures ); - bool Finish(); +/** + * The Creatures module - allows reading all non-vermin creatures and their properties + * \ingroup grp_modules + * \ingroup grp_units + */ - /* Read Functions */ - // Read creatures in a box, starting with index. Returns -1 if no more creatures - // found. Call repeatedly do get all creatures in a specified box (uses tile coords) - int32_t GetCreatureInBox(const int32_t index, df::unit ** furball, - const uint16_t x1, const uint16_t y1,const uint16_t z1, - const uint16_t x2, const uint16_t y2,const uint16_t z2); - df::unit * GetCreature(const int32_t index); - void CopyCreature(df::unit * source, t_unit & target); +DFHACK_EXPORT bool isValid(); - bool ReadJob(const df::unit * unit, std::vector & mat); +/* Read Functions */ +// Read creatures in a box, starting with index. Returns -1 if no more creatures +// found. Call repeatedly do get all creatures in a specified box (uses tile coords) +DFHACK_EXPORT int32_t GetCreatureInBox(const int32_t index, df::unit ** furball, + const uint16_t x1, const uint16_t y1,const uint16_t z1, + const uint16_t x2, const uint16_t y2,const uint16_t z2); +DFHACK_EXPORT df::unit * GetCreature(const int32_t index); +DFHACK_EXPORT void CopyCreature(df::unit * source, t_unit & target); - bool ReadInventoryByIdx(const uint32_t index, std::vector & item); - bool ReadInventoryByPtr(const df::unit * unit, std::vector & item); +DFHACK_EXPORT bool ReadJob(const df::unit * unit, std::vector & mat); - bool ReadOwnedItemsByIdx(const uint32_t index, std::vector & item); - bool ReadOwnedItemsByPtr(const df::unit * unit, std::vector & item); +DFHACK_EXPORT bool ReadInventoryByIdx(const uint32_t index, std::vector & item); +DFHACK_EXPORT bool ReadInventoryByPtr(const df::unit * unit, std::vector & item); - int32_t FindIndexById(int32_t id); +DFHACK_EXPORT bool ReadOwnedItemsByIdx(const uint32_t index, std::vector & item); +DFHACK_EXPORT bool ReadOwnedItemsByPtr(const df::unit * unit, std::vector & item); - /* Getters */ - uint32_t GetDwarfRaceIndex ( void ); - int32_t GetDwarfCivId ( void ); +DFHACK_EXPORT int32_t FindIndexById(int32_t id); - void CopyNameTo(df::unit *creature, df::language_name * target); +/* Getters */ +DFHACK_EXPORT uint32_t GetDwarfRaceIndex ( void ); +DFHACK_EXPORT int32_t GetDwarfCivId ( void ); - bool RemoveOwnedItemByIdx(const uint32_t index, int32_t id); - bool RemoveOwnedItemByPtr(df::unit * unit, int32_t id); +DFHACK_EXPORT void CopyNameTo(df::unit *creature, df::language_name * target); - private: - struct Private; - Private *d; - }; +DFHACK_EXPORT bool RemoveOwnedItemByIdx(const uint32_t index, int32_t id); +DFHACK_EXPORT bool RemoveOwnedItemByPtr(df::unit * unit, int32_t id); +} +} } #endif diff --git a/library/modules/Items.cpp b/library/modules/Items.cpp index 8861ed322..28a7a81a3 100644 --- a/library/modules/Items.cpp +++ b/library/modules/Items.cpp @@ -436,6 +436,17 @@ int32_t Items::getItemOwnerID(const df::item * item) return -1; } +df::unit *Items::getItemOwner(const df::item * item) +{ + for (uint32_t i = 0; i < item->itemrefs.size(); i++) + { + df::general_ref *ref = item->itemrefs[i]; + if (ref->getType() == df::general_ref_type::UNIT_ITEMOWNER) + return ref->getUnit(); + } + return NULL; +} + int32_t Items::getItemContainerID(const df::item * item) { for (uint32_t i = 0; i < item->itemrefs.size(); i++) @@ -447,6 +458,17 @@ int32_t Items::getItemContainerID(const df::item * item) return -1; } +df::item *Items::getItemContainer(const df::item * item) +{ + for (uint32_t i = 0; i < item->itemrefs.size(); i++) + { + df::general_ref *ref = item->itemrefs[i]; + if (ref->getType() == df::general_ref_type::CONTAINED_IN_ITEM) + return ref->getItem(); + } + return NULL; +} + bool Items::getContainedItems(const df::item * item, std::vector &items) { return readItemRefs(item, df::general_ref_type::CONTAINS_ITEM, items); @@ -466,7 +488,7 @@ bool Items::readItemRefs(const df::item * item, df::general_ref_type type, std:: return !values.empty(); } -bool Items::removeItemOwner(df::item * item, Units *creatures) +bool Items::removeItemOwner(df::item * item) { for (uint32_t i = 0; i < item->itemrefs.size(); i++) { @@ -476,7 +498,7 @@ bool Items::removeItemOwner(df::item * item, Units *creatures) df::unit *unit = ref->getUnit(); - if (unit == NULL || !creatures->RemoveOwnedItemByPtr(unit, item->id)) + if (unit == NULL || !Units::RemoveOwnedItemByPtr(unit, item->id)) { cerr << "RemoveOwnedItemIdx: CREATURE " << ref->getID() << " ID " << item->id << " FAILED!" << endl; return false; diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index 91314bd78..9d48a5f3e 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -33,15 +33,14 @@ distribution. #include using namespace std; - #include "VersionInfo.h" #include "MemAccess.h" #include "Error.h" #include "Types.h" // we connect to those -#include "modules/Materials.h" #include "modules/Units.h" +#include "modules/Materials.h" #include "modules/Translation.h" #include "ModuleFactory.h" #include "Core.h" @@ -55,49 +54,14 @@ using namespace DFHack::Simple; using df::global::world; using df::global::ui; -struct Units::Private -{ - bool Inited; - bool Started; -}; - -Module* DFHack::createUnits() -{ - return new Units(); -} - -Units::Units() -{ - Core & c = Core::getInstance(); - d = new Private; - VersionInfo * minfo = c.vinfo; - d->Inited = false; - d->Started = false; - d->Inited = true; -} - -Units::~Units() -{ - if(d->Started) - Finish(); -} - -bool Units::Start( uint32_t &numcreatures ) +bool Units::isValid() { - d->Started = true; - numcreatures = world->units.all.size(); - return true; -} - -bool Units::Finish() -{ - d->Started = false; - return true; + return (world->units.all.size() > 0); } df::unit * Units::GetCreature (const int32_t index) { - if(!d->Started) return NULL; + if (!isValid()) return NULL; // read pointer from vector at position if(index > world->units.all.size()) @@ -110,7 +74,7 @@ int32_t Units::GetCreatureInBox (int32_t index, df::unit ** furball, 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->Started) + if (!isValid()) return -1; uint32_t size = world->units.all.size(); @@ -137,7 +101,7 @@ int32_t Units::GetCreatureInBox (int32_t index, df::unit ** furball, void Units::CopyCreature(df::unit * source, t_unit & furball) { - if(!d->Started) return; + if(!isValid()) return; // read pointer from vector at position furball.origin = source; @@ -505,15 +469,16 @@ bool Units::ReadInventoryByIdx(const uint32_t index, std::vector & i { if(index >= world->units.all.size()) return false; df::unit * temp = world->units.all[index]; - return this->ReadInventoryByPtr(temp, item); + return ReadInventoryByPtr(temp, item); } -bool Units::ReadInventoryByPtr(const df::unit * temp, std::vector & items) +bool Units::ReadInventoryByPtr(const df::unit * unit, std::vector & items) { - if(!d->Started) return false; + if(!isValid()) return false; + if(!unit) return false; items.clear(); - for (uint32_t i = 0; i < temp->inventory.size(); i++) - items.push_back(temp->inventory[i]->item); + for (uint32_t i = 0; i < unit->inventory.size(); i++) + items.push_back(unit->inventory[i]->item); return true; } @@ -521,13 +486,14 @@ bool Units::ReadOwnedItemsByIdx(const uint32_t index, std::vector & ite { if(index >= world->units.all.size()) return false; df::unit * temp = world->units.all[index]; - return this->ReadOwnedItemsByPtr(temp, item); + return ReadOwnedItemsByPtr(temp, item); } -bool Units::ReadOwnedItemsByPtr(const df::unit * temp, std::vector & items) +bool Units::ReadOwnedItemsByPtr(const df::unit * unit, std::vector & items) { - if(!d->Started) return false; - items = temp->owned_items; + if(!isValid()) return false; + if(!unit) return false; + items = unit->owned_items; return true; } @@ -535,24 +501,15 @@ bool Units::RemoveOwnedItemByIdx(const uint32_t index, int32_t id) { if(index >= world->units.all.size()) return false; df::unit * temp = world->units.all[index]; - return this->RemoveOwnedItemByPtr(temp, id); + return RemoveOwnedItemByPtr(temp, id); } -bool Units::RemoveOwnedItemByPtr(df::unit * temp, int32_t id) +bool Units::RemoveOwnedItemByPtr(df::unit * unit, int32_t id) { - if(!d->Started) return false; - vector & vec = temp->owned_items; + if(!isValid()) return false; + if(!unit) return false; + vector & vec = unit->owned_items; vec.erase(std::remove(vec.begin(), vec.end(), id), vec.end()); -/* - DfVector citem(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; } diff --git a/plugins/cleanowned.cpp b/plugins/cleanowned.cpp index 78dbb04e0..e20647d9c 100644 --- a/plugins/cleanowned.cpp +++ b/plugins/cleanowned.cpp @@ -97,12 +97,9 @@ DFhackCExport command_result df_cleanowned (Core * c, vector & paramete CoreSuspender suspend(c); DFHack::Materials *Materials = c->getMaterials(); - DFHack::Units *Creatures = c->getUnits(); uint32_t num_creatures; - bool ok = true; - ok &= Materials->ReadAllMaterials(); - ok &= Creatures->Start(num_creatures); + bool ok = Materials->ReadAllMaterials(); c->con.print("Found total %d items.\n", world->items.all.size()); @@ -184,24 +181,22 @@ DFhackCExport command_result df_cleanowned (Core * c, vector & paramete item->getWear() ); - int32_t owner = Items::getItemOwnerID(item); - int32_t owner_index = Creatures->FindIndexById(owner); + df::unit *owner = Items::getItemOwner(item); std::string info; - if (owner_index >= 0) + if (owner) { - df::unit * temp = Creatures->GetCreature(owner_index); - info = temp->name.first_name; - if (!temp->name.nickname.empty()) - info += std::string(" '") + temp->name.nickname + "'"; + info = owner->name.first_name; + if (!owner->name.nickname.empty()) + info += std::string(" '") + owner->name.nickname + "'"; info += " "; - info += Translation::TranslateName(&temp->name,false); + info += Translation::TranslateName(&owner->name,false); c->con.print(", owner %s", info.c_str()); } if (!dry_run) { - if (!Items::removeItemOwner(item, Creatures)) + if (!Items::removeItemOwner(item)) c->con.print("(unsuccessfully) "); if (dump) item->flags.bits.dump = 1; diff --git a/plugins/probe.cpp b/plugins/probe.cpp index 8d588f283..4fd91d3c1 100644 --- a/plugins/probe.cpp +++ b/plugins/probe.cpp @@ -21,10 +21,15 @@ using namespace std; #include "modules/MapCache.h" #include "MiscUtils.h" +#include "df/world.h" + + using std::vector; using std::string; using namespace DFHack; +using namespace DFHack::Simple; using namespace df::enums; +using df::global::world; DFhackCExport command_result df_probe (Core * c, vector & parameters); DFhackCExport command_result df_cprobe (Core * c, vector & parameters); @@ -56,7 +61,6 @@ DFhackCExport command_result df_cprobe (Core * c, vector & parameters) Console & con = c->con; CoreSuspender suspend(c); DFHack::Gui *Gui = c->getGui(); - DFHack::Units * cr = c->getUnits(); int32_t cursorX, cursorY, cursorZ; Gui->getCursorCoords(cursorX,cursorY,cursorZ); if(cursorX == -30000) @@ -65,11 +69,10 @@ DFhackCExport command_result df_cprobe (Core * c, vector & parameters) } else { - uint32_t ncr; - cr->Start(ncr); + uint32_t ncr = world->units.all.size(); for(auto i = 0; i < ncr; i++) { - df::unit * unit = cr->GetCreature( i ); + df::unit * unit = world->units.all[i]; if(unit->pos.x == cursorX && unit->pos.y == cursorY && unit->pos.z == cursorZ) { con.print("Creature %d, race %d (%x), civ %d (%x)\n", unit->id, unit->race, unit->race, unit->civ_id, unit->civ_id);