Kill the Units module, and add another pair of methods to the Items module to simplify some things

develop
Quietust 2012-01-24 11:32:34 -06:00
parent 02d75e2c94
commit cc7c7795a1
9 changed files with 212 additions and 313 deletions

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

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

@ -30,7 +30,6 @@ distribution.
namespace DFHack
{
class Module;
Module* createUnits();
Module* createEngravings();
Module* createGui();
Module* createWorld();

@ -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<int32_t> &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<int32_t> &values);

@ -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<t_material> & 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<df::item *> & item);
bool ReadInventoryByPtr(const df::unit * unit, std::vector<df::item *> & item);
DFHACK_EXPORT bool ReadJob(const df::unit * unit, std::vector<t_material> & mat);
bool ReadOwnedItemsByIdx(const uint32_t index, std::vector<int32_t> & item);
bool ReadOwnedItemsByPtr(const df::unit * unit, std::vector<int32_t> & item);
DFHACK_EXPORT bool ReadInventoryByIdx(const uint32_t index, std::vector<df::item *> & item);
DFHACK_EXPORT bool ReadInventoryByPtr(const df::unit * unit, std::vector<df::item *> & item);
int32_t FindIndexById(int32_t id);
DFHACK_EXPORT bool ReadOwnedItemsByIdx(const uint32_t index, std::vector<int32_t> & item);
DFHACK_EXPORT bool ReadOwnedItemsByPtr(const df::unit * unit, std::vector<int32_t> & 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

@ -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<int32_t> &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;

@ -33,15 +33,14 @@ distribution.
#include <algorithm>
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<df::item *> & 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<df::item *> & items)
bool Units::ReadInventoryByPtr(const df::unit * unit, std::vector<df::item *> & 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<int32_t> & 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<int32_t> & items)
bool Units::ReadOwnedItemsByPtr(const df::unit * unit, std::vector<int32_t> & 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 <int32_t> & vec = temp->owned_items;
if(!isValid()) return false;
if(!unit) return false;
vector <int32_t> & vec = unit->owned_items;
vec.erase(std::remove(vec.begin(), vec.end(), id), vec.end());
/*
DfVector <int32_t> 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;
}

@ -97,12 +97,9 @@ DFhackCExport command_result df_cleanowned (Core * c, vector <string> & 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 <string> & 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;

@ -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 <string> & parameters);
DFhackCExport command_result df_cprobe (Core * c, vector <string> & parameters);
@ -56,7 +61,6 @@ DFhackCExport command_result df_cprobe (Core * c, vector <string> & 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 <string> & 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);