Merge remote-tracking branch 'quietust/master'

develop
Mike Stewart 2012-01-21 11:26:12 -08:00
commit debeebb7c4
19 changed files with 353 additions and 1496 deletions

@ -235,7 +235,7 @@ namespace df
#define ENUM_NEXT_ITEM(enum,val) \ #define ENUM_NEXT_ITEM(enum,val) \
(DFHack::next_enum_item_<df::enum,ENUM_FIRST_ITEM(enum),df::enums::enum::is_valid>(val)) (DFHack::next_enum_item_<df::enum,ENUM_FIRST_ITEM(enum),df::enums::enum::is_valid>(val))
#define FOR_ENUM_ITEMS(enum,iter) \ #define FOR_ENUM_ITEMS(enum,iter) \
for(df::enum iter = ENUM_FIRST_ITEM(enum); iter < ENUM_LAST_ITEM(enum); iter = df::enum(1+int(iter))) for(df::enum iter = ENUM_FIRST_ITEM(enum); iter <= ENUM_LAST_ITEM(enum); iter = df::enum(1+int(iter)))
namespace df { namespace df {
#define DF_KNOWN_GLOBALS \ #define DF_KNOWN_GLOBALS \

@ -42,17 +42,6 @@ namespace DFHack
uint8_t data[SIZE]; uint8_t data[SIZE];
}; };
struct df_name
{
std::string first_name;
std::string nick_name;
int32_t words[7];
int16_t parts_of_speech[7];
int32_t language;
int16_t unknown;
int16_t has_name;
};
// DF effects, by darius from the bay12 forum // DF effects, by darius from the bay12 forum
enum EFFECT_TYPE enum EFFECT_TYPE
{ {

@ -0,0 +1,20 @@
unsigned size() const { return x.size(); }
coord2d operator[] (unsigned idx) const {
if (idx >= x.size())
return coord2d();
else
return coord2d(x[idx], y[idx]);
}
void erase(unsigned idx) {
if (idx < x.size()) {
x.erase(x.begin()+idx);
y.erase(y.begin()+idx);
}
}
void push_back(const coord2d &crd) {
x.push_back(crd.x);
y.push_back(crd.y);
}

@ -1,8 +1,22 @@
unsigned size() const { return x.size(); } unsigned size() const { return x.size(); }
coord operator[] (unsigned idx) const { coord operator[] (unsigned idx) const {
if (idx >= x.size() || idx >= y.size() || idx >= z.size()) if (idx >= x.size())
return coord(); return coord();
else else
return coord(x[idx], y[idx], z[idx]); return coord(x[idx], y[idx], z[idx]);
} }
void erase(unsigned idx) {
if (idx < x.size()) {
x.erase(x.begin()+idx);
y.erase(y.begin()+idx);
z.erase(z.begin()+idx);
}
}
void push_back(const coord &crd) {
x.push_back(crd.x);
y.push_back(crd.y);
z.push_back(crd.z);
}

@ -0,0 +1,4 @@
bool isOre()
{
return flags.is_set(df::inorganic_flags::METAL_ORE) || flags.is_set(df::inorganic_flags::THREAD_METAL);
}

@ -0,0 +1,8 @@
bool isGem()
{
return flags.is_set(df::material_flags::IS_GEM);
}
bool isStone()
{
return flags.is_set(df::material_flags::IS_STONE);
}

@ -36,6 +36,8 @@ distribution.
#include "DataDefs.h" #include "DataDefs.h"
#include "df/material.h" #include "df/material.h"
#include "df/inorganic_raw.h"
#include "df/plant_raw.h"
#include <vector> #include <vector>
#include <string> #include <string>
@ -43,7 +45,6 @@ distribution.
namespace df namespace df
{ {
struct item; struct item;
struct inorganic_raw;
struct plant_raw; struct plant_raw;
struct creature_raw; struct creature_raw;
struct historical_figure; struct historical_figure;
@ -144,317 +145,6 @@ namespace DFHack
typedef int32_t t_materialIndex; typedef int32_t t_materialIndex;
typedef int16_t t_materialType, t_itemType, t_itemSubtype; typedef int16_t t_materialType, t_itemType, t_itemSubtype;
struct t_syndrome
{
// it's lonely here...
};
/**
* \ingroup grp_materials
*/
enum e_matter_state
{
state_solid,
state_liquid,
state_gas,
state_powder,
state_paste,
state_pressed,
NUM_MATTER_STATES
};
/**
* \ingroup grp_materials
*/
enum material_flags
{
MATERIAL_BONE = 0,
MATERIAL_MEAT,
MATERIAL_EDIBLE_VERMIN,
MATERIAL_EDIBLE_RAW,
MATERIAL_EDIBLE_COOKED,
MATERIAL_UNK5,
MATERIAL_ITEMS_METAL,
MATERIAL_ITEMS_BARRED,
MATERIAL_ITEMS_SCALED = 8,
MATERIAL_ITEMS_LEATHER,
MATERIAL_ITEMS_SOFT,
MATERIAL_ITEMS_HARD,
MATERIAL_IMPLIES_ANIMAL_KILL,
MATERIAL_ALCOHOL_PLANT,
MATERIAL_ALCOHOL_CREATURE,
MATERIAL_CHEESE_PLANT,
MATERIAL_CHEESE_CREATURE = 16,
MATERIAL_POWDER_MISC_PLANT,
MATERIAL_POWDER_MISC_CREATURE,
MATERIAL_STOCKPILE_GLOB,
MATERIAL_LIQUID_MISC_PLANT,
MATERIAL_LIQUID_MISC_CREATURE,
MATERIAL_LIQUID_MISC_OTHER,
MATERIAL_WOOD,
MATERIAL_THREAD_PLANT = 24,
MATERIAL_TOOTH,
MATERIAL_HORN,
MATERIAL_PEARL,
MATERIAL_SHELL,
MATERIAL_LEATHER,
MATERIAL_SILK,
MATERIAL_SOAP,
MATERIAL_ROTS = 32,
MATERIAL_UNK33,
MATERIAL_UNK34,
MATERIAL_UNK35,
MATERIAL_STRUCTURAL_PLANT_MAT,
MATERIAL_SEED_MAT,
MATERIAL_LEAF_MAT,
MATERIAL_UNK39,
MATERIAL_ENTERS_BLOOD = 40,
MATERIAL_BLOOD_MAP_DESCRIPTOR,
MATERIAL_ICHOR_MAP_DESCRIPTOR,
MATERIAL_GOO_MAP_DESCRIPTOR,
MATERIAL_SLIME_MAP_DESCRIPTOR,
MATERIAL_PUS_MAP_DESCRIPTOR,
MATERIAL_GENERATES_MIASMA,
MATERIAL_IS_METAL,
MATERIAL_IS_GEM = 48,
MATERIAL_IS_GLASS,
MATERIAL_CRYSTAL_GLASSABLE,
MATERIAL_ITEMS_WEAPON,
MATERIAL_ITEMS_WEAPON_RANGED,
MATERIAL_ITEMS_ANVIL,
MATERIAL_ITEMS_AMMO,
MATERIAL_ITEMS_DIGGER,
MATERIAL_ITEMS_ARMOR = 56,
MATERIAL_ITEMS_DELICATE,
MATERIAL_ITEMS_SIEGE_ENGINE,
MATERIAL_ITEMS_QUERN,
MATERIAL_IS_STONE,
MATERIAL_UNDIGGABLE,
MATERIAL_YARN,
MATERIAL_STOCKPILE_GLOB_PASTE,
MATERIAL_STOCKPILE_GLOB_PRESSED = 64,
MATERIAL_DISPLAY_UNGLAZED,
MATERIAL_DO_NOT_CLEAN_GLOB,
MATERIAL_NO_STONE_STOCKPILE,
MATERIAL_STOCKPILE_THREAD_METAL,
MATERIAL_UNK69,
MATERIAL_UNK70,
MATERIAL_UNK71,
MATERIAL_UNK72 = 72,
MATERIAL_UNK73,
MATERIAL_UNK74,
MATERIAL_UNK75,
MATERIAL_UNK76,
MATERIAL_UNK77,
MATERIAL_UNK78,
MATERIAL_UNK79,
};
/**
* \ingroup grp_materials
*/
enum inorganic_flags
{
INORGANIC_LAVA = 0,
INORGANIC_UNK1,
INORGANIC_UNK2,
INORGANIC_SEDIMENTARY,
INORGANIC_SEDIMENTARY_OCEAN_SHALLOW,
INORGANIC_IGNEOUS_INTRUSIVE,
INORGANIC_IGNEOUS_EXTRUSIVE,
INORGANIC_METAMORPHIC,
INORGANIC_DEEP_SURFACE = 8,
INORGANIC_METAL_ORE, // maybe
INORGANIC_AQUIFER,
INORGANIC_SOIL_ANY, // any soil
INORGANIC_SOIL_OCEAN,
INORGANIC_SOIL_SAND,
INORGANIC_SEDIMENTARY_OCEAN_DEEP,
INORGANIC_THREAD_METAL, // maybe
INORGANIC_DEEP = 16, // in general
INORGANIC_SOIL, // specific soil
INORGANIC_DEEP_SPECIAL,
INORGANIC_UNK19,
INORGANIC_UNK20,
INORGANIC_UNK21,
INORGANIC_UNK22,
INORGANIC_UNK23,
INORGANIC_UNK24 = 24,
INORGANIC_WAFERS,
INORGANIC_UNK26,
INORGANIC_UNK27,
INORGANIC_UNK28,
INORGANIC_UNK29,
INORGANIC_UNK30,
INORGANIC_UNK31,
};
/**
* Environment locations
* \ingroup grp_materials
*/
enum environment_location
{
ENV_SOIL,
ENV_SOIL_OCEAN,
ENV_SOIL_SAND,
ENV_METAMORPHIC,
ENV_SEDIMENTARY,
ENV_IGNEOUS_INTRUSIVE,
ENV_IGNEOUS_EXTRUSIVE,
ENV_ALLUVIAL,
};
/**
* Inclusion types
* \ingroup grp_materials
*/
enum inclusion_type
{
INCLUSION_NONE, // maybe
INCLUSION_VEIN,
INCLUSION_CLUSTER,
INCLUSION_CLUSTER_SMALL,
INCLUSION_CLUSTER_ONE,
};
/**
* The reversed generic material struct
* Research by Quietust
* \ingroup grp_materials
*/
struct df_material
{
std::string Material_ID;
std::string IS_GEM_singular;
std::string IS_GEM_plural;
std::string STONE_NAME;
int16_t SPEC_HEAT;
int16_t HEATDAM_POINT;
int16_t COLDDAM_POINT;
int16_t IGNITE_POINT;
int16_t MELTING_POINT;
int16_t BOILING_POINT;
int16_t MAT_FIXED_TEMP;
//int16_t padding; // added by compiler automatically
int32_t SOLID_DENSITY;
int32_t LIQUID_DENSITY;
int32_t MOLAR_MASS;
int32_t state_color[NUM_MATTER_STATES]; // color token indexes
std::string state_name[NUM_MATTER_STATES];
std::string state_adj[NUM_MATTER_STATES];
int32_t ABSORPTION;
int32_t BENDING_YIELD;
int32_t SHEAR_YIELD;
int32_t TORSION_YIELD;
int32_t IMPACT_YIELD;
int32_t TENSILE_YIELD;
int32_t COMPRESSIVE_YIELD;
int32_t BENDING_FRACTURE;
int32_t SHEAR_FRACTURE;
int32_t TORSION_FRACTURE;
int32_t IMPACT_FRACTURE;
int32_t TENSILE_FRACTURE;
int32_t COMPRESSIVE_FRACTURE;
int32_t BENDING_STRAIN_AT_YIELD;
int32_t SHEAR_STRAIN_AT_YIELD;
int32_t TORSION_STRAIN_AT_YIELD;
int32_t IMPACT_STRAIN_AT_YIELD;
int32_t TENSILE_STRAIN_AT_YIELD;
int32_t COMPRESSIVE_STRAIN_AT_YIELD;
int32_t MAX_EDGE;
int32_t MATERIAL_VALUE;
BitArray <material_flags> mat_flags;
t_itemType EXTRACT_STORAGE;
t_itemType BUTCHER_SPECIAL_type;
t_itemSubtype BUTCHER_SPECIAL_subtype;
//int16_t padding; // added by compiler
std::string MEAT_NAME_1st_parm; // (adj)
std::string MEAT_NAME_2nd_parm;
std::string MEAT_NAME_3rd_parm;
std::string BLOCK_NAME_1st_parm;
std::string BLOCK_NAME_2nd_parm;
std::vector <std::string> MATERIAL_REACTION_PRODUCT_1st_parm;// (e.g. TAN_MAT)
std::vector <void *> unknown1;
std::vector <void *> unknown2;
std::vector <std::string> MATERIAL_REACTION_PRODUCT_2nd_parm;// (e.g. LOCAL_CREATURE_MAT)
std::vector <std::string> MATERIAL_REACTION_PRODUCT_3rd_parm;// (e.g. LEATHER)
std::vector <std::string> MATERIAL_REACTION_PRODUCT_4th_parm;// (if you used CREATURE_MAT or PLANT_MAT)
int16_t unknown3;
//int16_t padding; // added by compiler
int32_t unknown4;
std::string HARDENS_WITH_WATER_1st_parm;// (e.g. INORGANIC)
std::string HARDENS_WITH_WATER_2nd_parm;// (e.g. GYPSUM)
std::string HARDENS_WITH_WATER_3rd_parm;// (if you used CREATURE_MAT or PLANT_MAT)
std::vector <std::string> REACTION_CLASS;
int8_t TILE; // Tile when material is a natural wall
int16_t BASIC_COLOR_foreground;
int16_t BASIC_COLOR_bright;
// what exactly ARE those colors?
int16_t BUILD_COLOR_foreground;
int16_t BUILD_COLOR_background;
int16_t BUILD_COLOR_bright;
// same...
int16_t TILE_COLOR_foreground;
int16_t TILE_COLOR_background;
int16_t TILE_COLOR_bright;
int8_t ITEM_SYMBOL; // Tile when material is a dug out stone
int16_t POWDER_DYE; // (color token index)
int16_t TEMP_DIET_INFO;// (whatever it means)
std::vector <t_syndrome *> SYNDROME;
int32_t SOAP_LEVEL;
std::string PREFIX;
// etc...
bool isGem()
{
return mat_flags.is_set(MATERIAL_IS_GEM);
};
bool isStone()
{
return mat_flags.is_set(MATERIAL_IS_STONE);
};
};
/**
* The reversed inorganic material struct
* Research by Quietust
* \ingroup grp_materials
*/
struct df_inorganic_type
{
std::string ID;
BitArray<inorganic_flags> inorg_flags;
std::vector <uint32_t> empty1;
std::vector <int16_t> METAL_ORE_matID; // Vector of indexes of metals produced when ore is smelted
std::vector <int16_t> METAL_ORE_prob; // Vector of percent chance of each type of metal being produced on smelting
std::vector <uint32_t> empty2;
std::vector <int16_t> THREAD_METAL_matID;// Vector of indexes of metals produced when ore undergoes strand extraction
std::vector <int16_t> THREAD_METAL_prob; // Vector of percent chance of each type of metal being produced on strand extraction
std::vector <uint32_t> unknown_in_1;
std::vector <uint32_t> empty3;
std::vector <int16_t> ENVIRONMENT_SPEC_matID;
std::vector <int16_t> ENVIRONMENT_SPEC_inclusion_type;
std::vector <int8_t> ENVIRONMENT_SPEC_prob;
std::vector <int16_t> ENVIRONMENT_location;
std::vector <int16_t> ENVIRONMENT_inclusion_type;
std::vector <int8_t> ENVIRONMENT_prob;
int32_t unknown_in_2;
df_material mat;
bool isOre()
{
if(!METAL_ORE_matID.empty())
return true;
if(!THREAD_METAL_matID.empty())
return true;
return false;
}
};
/** /**
* A copy of the game's material data. * A copy of the game's material data.
* \ingroup grp_materials * \ingroup grp_materials
@ -505,173 +195,7 @@ namespace DFHack
bool isOre(); bool isOre();
bool isGem(); bool isGem();
}; };
/**
* The plant flags
* \ingroup grp_materials
*/
enum plant_flags
{
// byte 0
PLANT_SPRING,
PLANT_SUMMER,
PLANT_AUTUMN,
PLANT_WINTER,
PLANT_UNK1,
PLANT_SEED,
PLANT_LEAVES,
PLANT_DRINK,
// byte 1
PLANT_EXTRACT_BARREL,
PLANT_EXTRACT_VIAL,
PLANT_EXTRACT_STILL_VIAL,
PLANT_UNK2,
PLANT_THREAD,
PLANT_MILL,
PLANT_UNK3,
PLANT_UNK4,
// byte 2
PLANT_UNK5,
PLANT_UNK6,
PLANT_UNK7,
PLANT_UNK8,
PLANT_WET,
PLANT_DRY,
PLANT_BIOME_MOUNTAIN,
PLANT_BIOME_GLACIER,
// byte 3
PLANT_BIOME_TUNDRA,
PLANT_BIOME_SWAMP_TEMPERATE_FRESHWATER,
PLANT_BIOME_SWAMP_TEMPERATE_SALTWATER,
PLANT_BIOME_MARSH_TEMPERATE_FRESHWATER,
PLANT_BIOME_MARSH_TEMPERATE_SALTWATER,
PLANT_BIOME_SWAMP_TROPICAL_FRESHWATER,
PLANT_BIOME_SWAMP_TROPICAL_SALTWATER,
PLANT_BIOME_SWAMP_MANGROVE,
// byte 4
PLANT_BIOME_MARSH_TROPICAL_FRESHWATER,
PLANT_BIOME_MARSH_TROPICAL_SALTWATER,
PLANT_BIOME_FOREST_TAIGA,
PLANT_BIOME_FOREST_TEMPERATE_CONIFER,
PLANT_BIOME_FOREST_TEMPERATE_BROADLEAF,
PLANT_BIOME_FOREST_TROPICAL_CONIFER,
PLANT_BIOME_FOREST_TROPICAL_DRY_BROADLEAF,
PLANT_BIOME_FOREST_TROPICAL_MOIST_BROADLEAF,
// byte 5
PLANT_BIOME_GRASSLAND_TEMPERATE,
PLANT_BIOME_SAVANNA_TEMPERATE,
PLANT_BIOME_SHRUBLAND_TEMPERATE,
PLANT_BIOME_GRASSLAND_TROPICAL,
PLANT_BIOME_SAVANNA_TROPICAL,
PLANT_BIOME_SHRUBLAND_TROPICAL,
PLANT_BIOME_DESERT_BADLAND,
PLANT_BIOME_DESERT_ROCK,
// byte 6
PLANT_BIOME_DESERT_SAND,
PLANT_BIOME_OCEAN_TROPICAL,
PLANT_BIOME_OCEAN_TEMPERATE,
PLANT_BIOME_OCEAN_ARCTIC,
PLANT_BIOME_POOL_TEMPERATE_FRESHWATER,
PLANT_BIOME_SUBTERRANEAN_WATER,
PLANT_BIOME_SUBTERRANEAN_CHASM,
PLANT_BIOME_SUBTERRANEAN_LAVA,
// byte 7
PLANT_GOOD,
PLANT_EVIL,
PLANT_SAVAGE,
PLANT_BIOME_POOL_TEMPERATE_BRACKISHWATER,
PLANT_BIOME_POOL_TEMPERATE_SALTWATER,
PLANT_BIOME_POOL_TROPICAL_FRESHWATER,
PLANT_BIOME_POOL_TROPICAL_BRACKISHWATER,
PLANT_BIOME_POOL_TROPICAL_SALTWATER,
// byte 8
PLANT_BIOME_LAKE_TEMPERATE_FRESHWATER,
PLANT_BIOME_LAKE_TEMPERATE_BRACKISHWATER,
PLANT_BIOME_LAKE_TEMPERATE_SALTWATER,
PLANT_BIOME_LAKE_TROPICAL_FRESHWATER,
PLANT_BIOME_LAKE_TROPICAL_BRACKISHWATER,
PLANT_BIOME_LAKE_TROPICAL_SALTWATER,
PLANT_BIOME_RIVER_TEMPERATE_FRESHWATER,
PLANT_BIOME_RIVER_TEMPERATE_BRACKISHWATER,
// byte 9
PLANT_BIOME_RIVER_TEMPERATE_SALTWATER,
PLANT_BIOME_RIVER_TROPICAL_FRESHWATER,
PLANT_BIOME_RIVER_TROPICAL_BRACKISHWATER,
PLANT_BIOME_RIVER_TROPICAL_SALTWATER,
PLANT_AUTUMNCOLOR,
PLANT_SAPLING,
PLANT_TREE,
PLANT_GRASS,
};
/**
* The plant RAWs in memory
* \ingroup grp_materials
*/
struct df_plant_type
{
std::string ID;
BitArray <plant_flags> flags;
std::string name, name_plural, adj;
std::string seed_singular, seed_plural;
std::string leaves_singular, leaves_plural;
uint8_t unk1;
uint8_t unk2;
char picked_tile, dead_picked_tile;
char shrub_tile, dead_shrub_tile;
char leaves_tile;
char tree_tile, dead_tree_tile;
char sapling_tile, dead_sapling_tile;
char grass_tiles[16];
char alt_grass_tiles[12];
int32_t growdur;
int32_t value;
int8_t picked_color[3], dead_picked_color[3];
int8_t shrub_color[3], dead_shrub_color[3];
int8_t seed_color[3];
int8_t leaves_color[3], dead_leaves_color[3];
int8_t tree_color[3], dead_tree_color[3];
int8_t sapling_color[3], dead_sapling_color[3];
int8_t grass_colors_0[20], grass_colors_1[20], grass_colors_2[20];
int32_t alt_period[2];
int8_t shrub_drown_level;
int8_t tree_drown_level;
int8_t sapling_drown_level;
int16_t frequency;
int16_t clustersize;
std::vector<std::string *> prefstring;
std::vector<df_material *> materials;
// materials and material indexes - only valid when appropriate flags in the BitArray are set
int16_t material_type_basic_mat;
int16_t material_type_tree;
int16_t material_type_drink;
int16_t material_type_seed;
int16_t material_type_thread;
int16_t material_type_mill;
int16_t material_type_extract_vial;
int16_t material_type_extract_barrel;
int16_t material_type_extract_still_vial;
int16_t material_type_leaves;
int32_t material_idx_basic_mat;
int32_t material_idx_tree;
int32_t material_idx_drink;
int32_t material_idx_seed;
int32_t material_idx_thread;
int32_t material_idx_mill;
int32_t material_idx_extract_vial;
int32_t material_idx_extract_barrel;
int32_t material_idx_extract_still_vial;
int32_t material_idx_leaves;
std::string material_str_basic_mat[3];
std::string material_str_tree[3];
std::string material_str_drink[3];
std::string material_str_seed[3];
std::string material_str_thread[3];
std::string material_str_mill[3];
std::string material_str_extract_vial[3];
std::string material_str_extract_barrel[3];
std::string material_str_extract_still_vial[3];
std::string material_str_leaves[3];
int32_t underground_depth[2];
};
/** /**
* \ingroup grp_materials * \ingroup grp_materials
*/ */
@ -746,8 +270,9 @@ namespace DFHack
t_attrib spatial_sense; t_attrib spatial_sense;
t_attrib musicality; t_attrib musicality;
t_attrib kinesthetic_sense; t_attrib kinesthetic_sense;
t_attrib empathy;
t_attrib social_awareness;
}; };
#define NUM_CREAT_ATTRIBS 17
/** /**
* \ingroup grp_materials * \ingroup grp_materials
@ -804,34 +329,6 @@ namespace DFHack
~Materials(); ~Materials();
bool Finish(); bool Finish();
enum base_material
{
INORGANIC,
AMBER,
CORAL,
GLASS_GREEN,
GLASS_CLEAR,
GLASS_CRYSTAL,
WATER,
COAL,
POTASH,
ASH,
PEARLASH,
LYE,
MUD,
VOMIT,
SALT,
FILTH_B,
FILTH_Y,
UNKNOWN_SUBSTANCE,
GRIME
};
std::vector<df_inorganic_type*>* df_inorganic;
std::vector<df_plant_type*>* df_organic;
std::vector<df_plant_type*>* df_trees;
std::vector<df_plant_type*>* df_plants;
std::vector<t_matgloss> race; std::vector<t_matgloss> race;
std::vector<t_creaturetype> raceEx; std::vector<t_creaturetype> raceEx;
std::vector<t_descriptor_color> color; std::vector<t_descriptor_color> color;

@ -33,6 +33,9 @@ distribution.
#include "Export.h" #include "Export.h"
#include "Module.h" #include "Module.h"
#include "Types.h" #include "Types.h"
#include "DataDefs.h"
#include "df/language_name.h"
namespace DFHack namespace DFHack
{ {
@ -67,10 +70,10 @@ namespace DFHack
// names, used by a few other modules. // names, used by a few other modules.
bool InitReadNames(); bool InitReadNames();
bool readName(t_name & name, df_name * address); bool readName(t_name & name, df::language_name * address);
bool copyName(df_name * address, df_name * target); bool copyName(df::language_name * address, df::language_name * target);
// translate a name using the loaded dictionaries // translate a name using the loaded dictionaries
std::string TranslateName(const DFHack::df_name * name, bool inEnglish = true); std::string TranslateName(const df::language_name * name, bool inEnglish = true);
private: private:
struct Private; struct Private;

@ -31,144 +31,14 @@ distribution.
#include "Export.h" #include "Export.h"
#include "Module.h" #include "Module.h"
#include "modules/Items.h" #include "modules/Items.h"
#include "df/unit.h"
/** /**
* \defgroup grp_units Unit module parts * \defgroup grp_units Unit module parts
* @ingroup grp_modules * @ingroup grp_modules
*/ */
namespace DFHack namespace DFHack
{ {
/**
* easy access to first crature flags block
* \ingroup grp_units
*/
union t_unitflags1
{
uint32_t whole;/*!< Access all flags as a single 32bit number. */
struct
{
unsigned int move_state : 1; /*!< 0 : Can the dwarf move or are they waiting for their movement timer */
unsigned int dead : 1; /*!< 1 : Dead (might also be set for incoming/leaving critters that are alive) */
unsigned int has_mood : 1; /*!< 2 : Currently in mood */
unsigned int had_mood : 1; /*!< 3 : Had a mood already */
unsigned int marauder : 1; /*!< 4 : wide class of invader/inside creature attackers */
unsigned int drowning : 1; /*!< 5 : Is currently drowning */
unsigned int merchant : 1; /*!< 6 : An active merchant */
unsigned int forest : 1; /*!< 7 : used for units no longer linked to merchant/diplomacy, they just try to leave mostly */
unsigned int left : 1; /*!< 8 : left the map */
unsigned int rider : 1; /*!< 9 : Is riding an another creature */
unsigned int incoming : 1; /*!< 10 */
unsigned int diplomat : 1; /*!< 11 */
unsigned int zombie : 1; /*!< 12 */
unsigned int skeleton : 1; /*!< 13 */
unsigned int can_swap : 1; /*!< 14: Can swap tiles during movement (prevents multiple swaps) */
unsigned int on_ground : 1; /*!< 15: The creature is laying on the floor, can be conscious */
unsigned int projectile : 1; /*!< 16: Launched into the air? Funny. */
unsigned int active_invader : 1; /*!< 17: Active invader (for organized ones) */
unsigned int hidden_in_ambush : 1; /*!< 18 */
unsigned int invader_origin : 1; /*!< 19: Invader origin (could be inactive and fleeing) */
unsigned int coward : 1; /*!< 20: Will flee if invasion turns around */
unsigned int hidden_ambusher : 1; /*!< 21: Active marauder/invader moving inward? */
unsigned int invades : 1; /*!< 22: Marauder resident/invader moving in all the way */
unsigned int check_flows : 1; /*!< 23: Check against flows next time you get a chance */
unsigned int ridden : 1; /*!< 24*/
unsigned int caged : 1; /*!< 25*/
unsigned int tame : 1; /*!< 26*/
unsigned int chained : 1; /*!< 27*/
unsigned int royal_guard : 1; /*!< 28*/
unsigned int fortress_guard : 1; /*!< 29*/
unsigned int suppress_wield : 1; /*!< 30: Suppress wield for beatings/etc */
unsigned int important_historical_figure : 1; /*!< 31: Is an important historical figure */
} bits;
};
union t_unitflags2
{
uint32_t whole; /*!< Access all flags as a single 32bit number. */
struct
{
unsigned int swimming : 1;
unsigned int sparring : 1;
unsigned int no_notify : 1; /*!< Do not notify about level gains (for embark etc)*/
unsigned int unused : 1;
unsigned int calculated_nerves : 1;
unsigned int calculated_bodyparts : 1;
unsigned int important_historical_figure : 1; /*!< Is important historical figure (slight variation)*/
unsigned int killed : 1; /*!< Has been killed by kill function (slightly different from dead, not necessarily violent death)*/
unsigned int cleanup_1 : 1; /*!< Must be forgotten by forget function (just cleanup) */
unsigned int cleanup_2 : 1; /*!< Must be deleted (cleanup) */
unsigned int cleanup_3 : 1; /*!< Recently forgotten (cleanup) */
unsigned int for_trade : 1; /*!< Offered for trade */
unsigned int trade_resolved : 1;
unsigned int has_breaks : 1;
unsigned int gutted : 1;
unsigned int circulatory_spray : 1;
unsigned int locked_in_for_trading : 1; /*!< Locked in for trading (it's a projectile on the other set of flags, might be what the flying was) */
unsigned int slaughter : 1; /*!< marked for slaughter */
unsigned int underworld : 1; /*!< Underworld creature */
unsigned int resident : 1; /*!< Current resident */
unsigned int cleanup_4 : 1; /*!< Marked for special cleanup as unused load from unit block on disk */
unsigned int calculated_insulation : 1; /*!< Insulation from clothing calculated */
unsigned int visitor_uninvited : 1; /*!< Uninvited guest */
unsigned int visitor : 1; /*!< visitor */
unsigned int calculated_inventory : 1; /*!< Inventory order calculated */
unsigned int vision_good : 1; /*!< Vision -- have good part */
unsigned int vision_damaged : 1; /*!< Vision -- have damaged part */
unsigned int vision_missing : 1; /*!< Vision -- have missing part */
unsigned int breathing_good : 1; /*!< Breathing -- have good part */
unsigned int breathing_problem : 1; /*!< Breathing -- having a problem */
unsigned int roaming_wilderness_population_source : 1;
unsigned int roaming_wilderness_population_source_not_a_map_feature : 1;
} bits;
};
union t_unitflags3
{
uint32_t whole; /*!< Access all flags as a single 32bit number. */
struct
{
unsigned int unk0 : 1; /*!< Is 1 for new and dead creatures,
periodicaly set to 0 for non-dead creatures.
*/
unsigned int unk1 : 1; /*!< Is 1 for new creatures, periodically set
to 0 for non-dead creatures. */
unsigned int unk2 : 1; /*!< Is set to 1 every tick for non-dead
creatures. */
unsigned int unk3 : 1; /*!< Is periodically set to 0 for non-dead
creatures. */
unsigned int announce_titan : 1; /*!< Announces creature like an
FB or titan. */
unsigned int unk5 : 1;
unsigned int unk6 : 1;
unsigned int unk7 : 1;
unsigned int unk8 : 1; /*!< Is set to 1 every tick for non-dead
creatures. */
unsigned int unk9 : 1; /*!< Is set to 0 every tick for non-dead
creatures. */
unsigned int scuttle : 1; /*!< Scuttle creature: causes creature
to be killed, leaving a behind corpse
and generating negative thoughts like
a real kill. */
unsigned int unk11 : 1;
unsigned int ghostly : 1; /*!< Creature is a ghost. */
unsigned int unk13_31 : 19;
} bits;
};
// FIXME: WTF IS THIS SHIT? // FIXME: WTF IS THIS SHIT?
/* /*
struct t_labor struct t_labor
@ -308,16 +178,16 @@ namespace DFHack
*/ */
struct t_unit struct t_unit
{ {
df_unit * origin; df::unit * origin;
uint16_t x; uint16_t x;
uint16_t y; uint16_t y;
uint16_t z; uint16_t z;
uint32_t race; uint32_t race;
int32_t civ; int32_t civ;
t_unitflags1 flags1; df::unit_flags1 flags1;
t_unitflags2 flags2; df::unit_flags2 flags2;
t_unitflags3 flags3; df::unit_flags3 flags3;
t_name name; t_name name;
@ -353,404 +223,6 @@ namespace DFHack
uint32_t birth_time; uint32_t birth_time;
}; };
/**
* Unit attribute descriptor
* \ingroup grp_units
*/
struct df_attrib
{
uint32_t unk_0;
uint32_t unk_4;
uint32_t unk_8;
uint32_t unk_c;
uint32_t unk_10;
uint32_t unk_14;
uint32_t unk_18;
};
/**
* Unit skill descriptor
* \ingroup grp_units
*/
struct df_skill
{
uint16_t id; // 0
int32_t rating; // 4
uint32_t experience; // 8
uint32_t unk_c;
uint32_t rusty; // 10
uint32_t unk_14;
uint32_t unk_18;
uint32_t unk_1c;
};
/**
* Unit like descriptor
* \ingroup grp_units
*/
struct df_like
{
int16_t type;
int16_t itemClass;
int16_t itemIndex;
int16_t material_type;
int32_t material_index;
bool active;
uint32_t mystery;
};
/**
* A creature's soul, as it appears in DF memory
* \ingroup grp_units
*/
struct df_soul
{
uint32_t creature_id;
df_name name; // 4
uint32_t unk_70;
uint16_t unk_74;
uint16_t unk_76;
int32_t unk_78;
int32_t unk_7c;
int32_t unk_80;
int32_t unk_84;
df_attrib mental[NUM_CREATURE_MENTAL_ATTRIBUTES]; // 88..1f3
std::vector<df_skill*> skills; // 1f4;
std::vector<df_like*> likes; // pointers to 14 0x14-byte structures ... likes?
uint16_t traits[NUM_CREATURE_TRAITS]; // 214
std::vector<int16_t*> unk_250; // 1 pointer to 2 shorts
uint32_t unk_260;
uint32_t unk_264;
uint32_t unk_268;
uint32_t unk_26c;
};
/**
* A creature job - what it's supposed to be doing.
* \ingroup grp_units
*/
struct df_job
{
};
/**
* A creature though - dwarves staring at waterfalls!
* \ingroup grp_units
*/
struct df_thought
{
// needs enum
int16_t type;
// possible int16_t here
int32_t age;
int32_t subtype;
int32_t severity;
//possibly more.
};
/**
* A creature, as it appears in DF memory
* \ingroup grp_units
*/
struct df_unit
{
df_name name; // 0
std::string custom_profession; // 6c (MSVC)
uint8_t profession; // 88
uint32_t race; // 8c
uint16_t x; // 90
uint16_t y; // 92
uint16_t z; // 94
uint16_t unk_x96; // 96
uint16_t unk_y98; // 98
uint16_t unk_z9a; // 9a
uint32_t unk_9c;
uint16_t unk_a0;
int16_t unk_a2;
uint32_t unk_a4;
uint16_t dest_x; // a8
uint16_t dest_y; // aa
uint16_t dest_z; // ac
uint16_t unk_ae; // -1
std::vector<uint32_t> unk_b0; // b0->df (3*4 in MSVC) -> 68->8b (3*3 in glibc)
std::vector<uint32_t> unk_c0;
std::vector<uint32_t> unk_d0;
t_unitflags1 flags1; // e0
t_unitflags2 flags2; // e4
t_unitflags3 flags3; // e8
void ** unk_ec;
int32_t unk_f0;
int16_t unk_f4;
int16_t unk_f6;
uint16_t caste; // f8
uint8_t sex; // fa
uint32_t id; // fc
uint16_t unk_100;
uint16_t unk_102;
int32_t unk_104;
uint32_t civ; // 108
uint32_t unk_10c;
int32_t unk_110;
std::vector<uint32_t> unk_114;
std::vector<uint32_t> unk_124;
std::vector<uint32_t> unk_134;
uint32_t unk_144;
std::vector<void*> unk_148;
std::vector<void*> unk_158;
int32_t unk_168;
int32_t unk_16c;
uint32_t unk_170;
uint32_t unk_174;
uint16_t unk_178;
std::vector<uint32_t> unk_17c;
std::vector<uint32_t> unk_18c;
std::vector<uint32_t> unk_19c;
std::vector<uint32_t> unk_1ac;
uint32_t pickup_equipment_bit; // 1bc
std::vector<uint32_t> unk_1c0;
std::vector<uint32_t> unk_1d0;
std::vector<uint32_t> unk_1e0;
int32_t unk_1f0;
int16_t unk_1f4;
int32_t unk_1f8;
int32_t unk_1fc;
int32_t unk_200;
int16_t unk_204;
uint32_t unk_208;
uint32_t unk_20c;
int16_t mood; // 210
uint32_t pregnancy_timer; // 214
void* pregnancy_ptr; // 218
int32_t unk_21c;
uint32_t unk_220;
uint32_t birth_year; // 224
uint32_t birth_time; // 228
uint32_t unk_22c;
uint32_t unk_230;
df_unit * unk_234; // suspiciously close to the pregnancy/birth stuff. Mother?
uint32_t unk_238;
int32_t unk_23c;
int32_t unk_240;
int32_t unk_244;
int32_t unk_248;
int32_t unk_24c;
int32_t unk_250;
int32_t unk_254;
int32_t unk_258;
int32_t unk_25c;
int32_t unk_260;
int16_t unk_264;
int32_t unk_268;
int32_t unk_26c;
int16_t unk_270;
int32_t unk_274;
int32_t unk_278;
int32_t unk_27c;
int16_t unk_280;
int32_t unk_284;
std::vector<df::item *> inventory; // 288 - vector of item pointers
std::vector<int32_t> owned_items; // 298 - vector of item IDs
std::vector<uint32_t> unk_2a8;
std::vector<uint32_t> unk_2b8;
std::vector<uint32_t> unk_2c8;
uint32_t unk_2d8;
uint32_t unk_2dc;
uint32_t unk_2e0;
uint32_t unk_2e4;
uint32_t unk_2e8;
uint32_t unk_2ec;
uint32_t unk_2f0;
df_job * current_job; // 2f4
uint32_t unk_2f8; // possibly current skill?
uint32_t unk_2fc;
uint32_t unk_300;
uint32_t unk_304;
std::vector<uint32_t> unk_308;
std::vector<uint32_t> unk_318;
std::vector<uint32_t> unk_328;
std::vector<uint32_t> unk_338;
std::vector<uint32_t> unk_348;
std::vector<uint32_t> unk_358;
std::vector<uint32_t> unk_368;
std::vector<uint32_t> unk_378;
std::vector<uint32_t> unk_388;
uint32_t unk_398;
int32_t unk_39c;
int32_t unk_3a0;
int32_t unk_3a4;
int32_t unk_3a8;
int32_t unk_3ac;
int32_t unk_3b0;
int32_t unk_3b4;
int32_t unk_3b8;
int32_t unk_3bc;
int32_t unk_3c0;
uint32_t unk_3c4;
uint32_t unk_3c8;
df_attrib physical[NUM_CREATURE_PHYSICAL_ATTRIBUTES]; // 3cc..473
uint32_t unk_474;
uint32_t unk_478;
uint32_t unk_47c;
uint32_t unk_480;
uint32_t unk_484;
uint32_t unk_488;
uint32_t unk_48c; // blood_max?
uint32_t blood_count; // 490
uint32_t unk_494;
// dirt, grime, FB blood, mud and plain old filth stuck to the poor thing's parts and pieces
std::vector<void*> contaminants;
std::vector<uint16_t> unk_4a8;
std::vector<uint16_t> unk_4b8;
uint32_t unk_4c8;
std::vector<int16_t> unk_4cc;
std::vector<int32_t> unk_4dc;
std::vector<int32_t> unk_4ec;
std::vector<int32_t> unk_4fc;
std::vector<uint16_t> unk_50c;
void* unk_51c;
uint16_t unk_520;
uint16_t unk_522;
uint16_t* unk_524;
uint16_t unk_528;
uint16_t unk_52a;
std::vector<uint32_t> appearance; // 52c
int16_t unk_53c;
int16_t unk_53e;
int16_t job_counter; // tick until next job update?
int16_t unk_542;
int16_t unk_544;
int16_t unk_546;
int16_t unk_548;
int16_t unk_54a;
int16_t unk_54c;
int16_t unk_54e;
int16_t unk_550;
int16_t unk_552;
int16_t unk_x554; // coords ? (-30.000x3)
int16_t unk_y556;
int16_t unk_z558;
int16_t unk_x55a; // coords again
int16_t unk_y55c;
int16_t unk_z55e;
int16_t unk_560;
int16_t unk_562;
uint32_t unk_564;
uint32_t unk_568;
uint32_t unk_56c;
uint32_t unk_570;
uint32_t unk_574;
uint32_t unk_578;
uint32_t unk_57c;
uint32_t unk_580;
uint32_t unk_584;
uint32_t unk_588;
uint32_t unk_58c;
uint32_t unk_590;
uint32_t unk_594;
uint32_t unk_598;
uint32_t unk_59c;
std::vector<void*> unk_5a0;
void* unk_5b0; // pointer to X (12?) vector<int16_t>
uint32_t unk_5b4; // 0x3e8 (1000)
uint32_t unk_5b8; // 0x3e8 (1000)
std::vector<uint32_t> unk_5bc;
std::vector<uint32_t> unk_5cc;
int16_t unk_5dc;
int16_t unk_5de;
df_name artifact_name; // 5e0
std::vector<df_soul*> souls; // 64c
df_soul* current_soul; // 65c
std::vector<uint32_t> unk_660;
uint8_t labors[NUM_CREATURE_LABORS]; // 670..6cf
std::vector<uint32_t> unk_6d0;
std::vector<uint32_t> unk_6e0;
std::vector<df_thought *> thoughts;
std::vector<uint32_t> unk_700;
uint32_t happiness; // 710
uint16_t unk_714;
uint16_t unk_716;
std::vector<void*> unk_718;
std::vector<void*> unk_728;
std::vector<void*> unk_738;
std::vector<void*> unk_748;
uint16_t unk_758;
uint16_t unk_x75a; // coords (-30000*3)
uint16_t unk_y75c;
uint16_t unk_z75e;
std::vector<uint16_t> unk_760;
std::vector<uint16_t> unk_770;
std::vector<uint16_t> unk_780;
uint32_t hist_figure_id; // 790
uint16_t able_stand; // 794
uint16_t able_stand_impair; // 796
uint16_t able_grasp; // 798
uint16_t able_grasp_impair; // 79a
uint32_t unk_79c; // able_fly/impair (maybe)
uint32_t unk_7a0; // able_fly/impair (maybe)
std::vector<void*> unk_7a4;
uint32_t unk_7b4;
uint32_t unk_7b8;
uint32_t unk_7bc;
int32_t unk_7c0;
std::vector<uint32_t> unk_7c4;
std::vector<uint32_t> unk_7d4;
std::vector<uint32_t> unk_7e4;
std::vector<uint32_t> unk_7f4;
std::vector<uint32_t> unk_804;
std::vector<uint32_t> unk_814;
uint32_t unk_824;
void* unk_828;
void* unk_82c;
uint32_t unk_830;
void* unk_834;
void* unk_838;
void* unk_83c;
std::vector<void*> unk_840;
std::vector<uint32_t> unk_850;
std::vector<uint32_t> unk_860;
uint32_t unk_870;
uint32_t unk_874;
std::vector<uint8_t> unk_878;
std::vector<uint8_t> unk_888;
std::vector<uint32_t> unk_898;
std::vector<uint8_t> unk_8a8;
std::vector<uint16_t> unk_8b8;
std::vector<uint16_t> unk_8c8;
std::vector<uint32_t> unk_8d8;
std::vector<uint32_t> unk_8e8;
std::vector<uint32_t> unk_8f8;
std::vector<uint32_t> unk_908;
int32_t unk_918;
uint16_t unk_91c;
uint16_t unk_91e;
uint16_t unk_920;
uint16_t unk_922;
uint32_t unk_924;
uint32_t unk_928;
std::vector<uint16_t> unk_92c;
uint32_t unk_93c;
};
/** /**
* The Creatures module - allows reading all non-vermin creatures and their properties * The Creatures module - allows reading all non-vermin creatures and their properties
* \ingroup grp_modules * \ingroup grp_modules
@ -758,8 +230,6 @@ namespace DFHack
*/ */
class DFHACK_EXPORT Units : public Module class DFHACK_EXPORT Units : public Module
{ {
public:
std::vector <df_unit *> * creatures;
public: public:
Units(); Units();
~Units(); ~Units();
@ -769,19 +239,19 @@ namespace DFHack
/* Read Functions */ /* Read Functions */
// Read creatures in a box, starting with index. Returns -1 if no more creatures // 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) // found. Call repeatedly do get all creatures in a specified box (uses tile coords)
int32_t GetCreatureInBox(const int32_t index, df_unit ** furball, 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 x1, const uint16_t y1,const uint16_t z1,
const uint16_t x2, const uint16_t y2,const uint16_t z2); const uint16_t x2, const uint16_t y2,const uint16_t z2);
df_unit * GetCreature(const int32_t index); df::unit * GetCreature(const int32_t index);
void CopyCreature(df_unit * source, t_unit & target); void CopyCreature(df::unit * source, t_unit & target);
bool ReadJob(const df_unit * unit, std::vector<t_material> & mat); bool ReadJob(const df::unit * unit, std::vector<t_material> & mat);
bool ReadInventoryByIdx(const uint32_t index, std::vector<df::item *> & item); bool ReadInventoryByIdx(const uint32_t index, std::vector<df::item *> & item);
bool ReadInventoryByPtr(const df_unit * unit, std::vector<df::item *> & item); bool ReadInventoryByPtr(const df::unit * unit, std::vector<df::item *> & item);
bool ReadOwnedItemsByIdx(const uint32_t index, std::vector<int32_t> & item); bool ReadOwnedItemsByIdx(const uint32_t index, std::vector<int32_t> & item);
bool ReadOwnedItemsByPtr(const df_unit * unit, std::vector<int32_t> & item); bool ReadOwnedItemsByPtr(const df::unit * unit, std::vector<int32_t> & item);
int32_t FindIndexById(int32_t id); int32_t FindIndexById(int32_t id);
@ -789,26 +259,10 @@ namespace DFHack
uint32_t GetDwarfRaceIndex ( void ); uint32_t GetDwarfRaceIndex ( void );
int32_t GetDwarfCivId ( void ); int32_t GetDwarfCivId ( void );
/* Write Functions */ void CopyNameTo(df::unit *creature, df::language_name * target);
//bool WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]);
//bool WriteHappiness(const uint32_t index, const uint32_t happinessValue);
//bool WriteFlags(const uint32_t index, const uint32_t flags1, const uint32_t flags2);
//bool WriteFlags(const uint32_t index, const uint32_t flags1, const uint32_t flags2, uint32_t flags3);
//bool WriteSkills(const uint32_t index, const t_soul &soul);
//bool WriteAttributes(const uint32_t index, const t_creature &creature);
//bool WriteSex(const uint32_t index, const uint8_t sex);
//bool WriteTraits(const uint32_t index, const t_soul &soul);
//bool WriteMood(const uint32_t index, const uint16_t mood);
//bool WriteMoodSkill(const uint32_t index, const uint16_t moodSkill);
//bool WriteJob(const t_creature * furball, std::vector<t_material> const& mat);
//bool WritePos(const uint32_t index, const t_creature &creature);
//bool WriteCiv(const uint32_t index, const int32_t civ);
//bool WritePregnancy(const uint32_t index, const uint32_t pregTimer);
void CopyNameTo(df_unit *creature, df_name * target);
bool RemoveOwnedItemByIdx(const uint32_t index, int32_t id); bool RemoveOwnedItemByIdx(const uint32_t index, int32_t id);
bool RemoveOwnedItemByPtr(df_unit * unit, int32_t id); bool RemoveOwnedItemByPtr(df::unit * unit, int32_t id);
private: private:
struct Private; struct Private;

@ -33,6 +33,8 @@ distribution.
#include "Export.h" #include "Export.h"
#include "Module.h" #include "Module.h"
#include "Types.h" #include "Types.h"
#include "DataDefs.h"
#include "df/language_name.h"
namespace DFHack namespace DFHack
{ {
/** /**
@ -45,7 +47,7 @@ namespace DFHack
#pragma pack(push, 2) #pragma pack(push, 2)
struct df_plant struct df_plant
{ {
df_name name; df::language_name name;
union union
{ {
uint16_t type; uint16_t type;

@ -474,7 +474,7 @@ bool Items::removeItemOwner(df::item * item, Units *creatures)
if (ref->getType() != df::general_ref_type::UNIT_ITEMOWNER) if (ref->getType() != df::general_ref_type::UNIT_ITEMOWNER)
continue; continue;
df_unit *unit = (df_unit *)ref->getUnit(); df::unit *unit = ref->getUnit();
if (unit == NULL || !creatures->RemoveOwnedItemByPtr(unit, item->id)) if (unit == NULL || !creatures->RemoveOwnedItemByPtr(unit, item->id))
{ {

@ -567,7 +567,7 @@ bool Maps::ReadGeology (vector < vector <uint16_t> >& assign)
if (bioRY >= world->world_data->world_height) bioRY = world->world_data->world_height - 1; if (bioRY >= world->world_data->world_height) bioRY = world->world_data->world_height - 1;
// get index into geoblock vector // get index into geoblock vector
uint16_t geoindex = world->world_data->unk_1c0[bioRX][bioRY].geo_index; uint16_t geoindex = world->world_data->region_map[bioRX][bioRY].geo_index;
/// geology blocks have a vector of layer descriptors /// geology blocks have a vector of layer descriptors
// get the vector with pointer to layers // get the vector with pointer to layers

@ -44,10 +44,9 @@ using namespace std;
#include "df/world.h" #include "df/world.h"
#include "df/ui.h" #include "df/ui.h"
#include "df/item.h" #include "df/item.h"
#include "df/inorganic_raw.h"
#include "df/plant_raw.h"
#include "df/plant_raw_flags.h"
#include "df/creature_raw.h" #include "df/creature_raw.h"
#include "df/caste_raw.h"
#include "df/body_part_raw.h"
#include "df/historical_figure.h" #include "df/historical_figure.h"
#include "df/job_item.h" #include "df/job_item.h"
@ -55,9 +54,15 @@ using namespace std;
#include "df/dfhack_material_category.h" #include "df/dfhack_material_category.h"
#include "df/matter_state.h" #include "df/matter_state.h"
#include "df/material_vec_ref.h" #include "df/material_vec_ref.h"
#include "df/builtin_mats.h"
#include "df/descriptor_color.h"
#include "df/descriptor_pattern.h"
#include "df/descriptor_shape.h"
using namespace DFHack; using namespace DFHack;
using namespace df::enums; using namespace df::enums;
using df::global::world;
bool MaterialInfo::decode(df::item *item) bool MaterialInfo::decode(df::item *item)
{ {
@ -514,16 +519,8 @@ Materials::Materials()
Core & c = Core::getInstance(); Core & c = Core::getInstance();
d = new Private; d = new Private;
d->owner = c.p; d->owner = c.p;
df_organic = 0;
df_trees = 0;
df_plants = 0;
df_inorganic = 0;
OffsetGroup *OG_Materials = d->OG_Materials = c.vinfo->getGroup("Materials"); OffsetGroup *OG_Materials = d->OG_Materials = c.vinfo->getGroup("Materials");
{ {
OG_Materials->getSafeAddress("inorganics",(void * &)df_inorganic);
OG_Materials->getSafeAddress("organics_all",(void * &)df_organic);
OG_Materials->getSafeAddress("organics_plants",(void * &)df_plants);
OG_Materials->getSafeAddress("organics_trees",(void * &)df_trees);
d->vector_races = OG_Materials->getAddress("creature_type_vector"); d->vector_races = OG_Materials->getAddress("creature_type_vector");
} }
} }
@ -563,47 +560,29 @@ bool t_matglossInorganic::isGem()
return is_gem; return is_gem;
} }
// good for now
inline bool ReadNamesOnly(Process* p, void * address, vector<t_matgloss> & names)
{
vector <string *> * p_names = (vector <string *> *) address;
uint32_t size = p_names->size();
names.clear();
names.reserve (size);
for (uint32_t i = 0; i < size;i++)
{
t_matgloss mat;
mat.id = *p_names->at(i);
names.push_back(mat);
}
return true;
}
bool Materials::CopyInorganicMaterials (std::vector<t_matglossInorganic> & inorganic) bool Materials::CopyInorganicMaterials (std::vector<t_matglossInorganic> & inorganic)
{ {
Process * p = d->owner; Process * p = d->owner;
if(!df_inorganic) uint32_t size = world->raws.inorganics.size();
return false;
uint32_t size = df_inorganic->size();
inorganic.clear(); inorganic.clear();
inorganic.reserve (size); inorganic.reserve (size);
for (uint32_t i = 0; i < size;i++) for (uint32_t i = 0; i < size;i++)
{ {
df_inorganic_type * orig = df_inorganic->at(i); df::inorganic_raw *orig = world->raws.inorganics[i];
t_matglossInorganic mat; t_matglossInorganic mat;
mat.id = orig->ID; mat.id = orig->id;
mat.name = orig->mat.STONE_NAME; mat.name = orig->material.stone_name;
mat.ore_types = orig->METAL_ORE_matID; mat.ore_types = orig->metal_ore.mat_index;
mat.ore_chances = orig->METAL_ORE_prob; mat.ore_chances = orig->metal_ore.probability;
mat.strand_types = orig->THREAD_METAL_matID; mat.strand_types = orig->thread_metal.mat_index;
mat.strand_chances = orig->THREAD_METAL_prob; mat.strand_chances = orig->thread_metal.probability;
mat.value = orig->mat.MATERIAL_VALUE; mat.value = orig->material.material_value;
mat.wall_tile = orig->mat.TILE; mat.wall_tile = orig->material.tile;
mat.boulder_tile = orig->mat.ITEM_SYMBOL; mat.boulder_tile = orig->material.item_symbol;
mat.bright = orig->mat.BASIC_COLOR_bright; mat.fore = orig->material.basic_color[0];
mat.fore = orig->mat.BASIC_COLOR_foreground; mat.bright = orig->material.basic_color[1];
mat.is_gem = orig->mat.mat_flags.is_set(MATERIAL_IS_GEM); mat.is_gem = orig->material.flags.is_set(material_flags::IS_GEM);
inorganic.push_back(mat); inorganic.push_back(mat);
} }
return true; return true;
@ -611,58 +590,77 @@ bool Materials::CopyInorganicMaterials (std::vector<t_matglossInorganic> & inorg
bool Materials::CopyOrganicMaterials (std::vector<t_matgloss> & organic) bool Materials::CopyOrganicMaterials (std::vector<t_matgloss> & organic)
{ {
if(df_organic) uint32_t size = world->raws.plants.all.size();
return ReadNamesOnly(d->owner, (void *) df_organic, organic ); organic.clear();
else return false; organic.reserve (size);
for (uint32_t i = 0; i < size;i++)
{
t_matgloss mat;
mat.id = world->raws.plants.all[i]->id;
organic.push_back(mat);
}
return true;
} }
bool Materials::CopyWoodMaterials (std::vector<t_matgloss> & tree) bool Materials::CopyWoodMaterials (std::vector<t_matgloss> & tree)
{ {
if(df_trees) uint32_t size = world->raws.plants.trees.size();
return ReadNamesOnly(d->owner, (void *) df_trees, tree ); tree.clear();
else return false; tree.reserve (size);
for (uint32_t i = 0; i < size;i++)
{
t_matgloss mat;
mat.id = world->raws.plants.trees[i]->id;
tree.push_back(mat);
}
return true;
} }
bool Materials::CopyPlantMaterials (std::vector<t_matgloss> & plant) bool Materials::CopyPlantMaterials (std::vector<t_matgloss> & plant)
{ {
if(df_plants) uint32_t size = world->raws.plants.bushes.size();
return ReadNamesOnly(d->owner, (void *) df_plants, plant ); plant.clear();
else return false; plant.reserve (size);
for (uint32_t i = 0; i < size;i++)
{
t_matgloss mat;
mat.id = world->raws.plants.bushes[i]->id;
plant.push_back(mat);
}
return true;
} }
bool Materials::ReadCreatureTypes (void) bool Materials::ReadCreatureTypes (void)
{ {
return ReadNamesOnly(d->owner, d->vector_races, race ); uint32_t size = world->raws.creatures.all.size();
race.clear();
race.reserve (size);
for (uint32_t i = 0; i < size;i++)
{
t_matgloss mat;
mat.id = world->raws.creatures.all[i]->creature_id;
race.push_back(mat);
}
return true;
} }
bool Materials::ReadOthers(void) bool Materials::ReadOthers(void)
{ {
Process * p = d->owner; uint32_t size = df::enums::builtin_mats::_last_item_of_builtin_mats + 1;
char * matBase = d->OG_Materials->getAddress ("other");
uint32_t i = 0;
std::string * ptr;
other.clear(); other.clear();
other.reserve(size);
while(1) for (uint32_t i = 0; i < size;i++)
{ {
t_matglossOther mat; t_matglossOther mat;
ptr = (std::string *) p->readPtr(matBase + i*4); mat.id = world->raws.mat_table.builtin[i]->id;
if(ptr==0)
break;
mat.id = *ptr;
other.push_back(mat); other.push_back(mat);
i++;
} }
return true; return true;
} }
bool Materials::ReadDescriptorColors (void) bool Materials::ReadDescriptorColors (void)
{ {
Process * p = d->owner; uint32_t size = world->raws.language.colors.size();
OffsetGroup * OG_Descriptors = p->getDescriptor()->getGroup("Materials")->getGroup("descriptors");
vector <char *> & p_colors = *(vector<char*> *) OG_Descriptors->getAddress ("colors_vector");
uint32_t size = p_colors.size();
color.clear(); color.clear();
if(size == 0) if(size == 0)
@ -670,100 +668,64 @@ bool Materials::ReadDescriptorColors (void)
color.reserve(size); color.reserve(size);
for (uint32_t i = 0; i < size;i++) for (uint32_t i = 0; i < size;i++)
{ {
df::descriptor_color *c = world->raws.language.colors[i];
t_descriptor_color col; t_descriptor_color col;
col.id = p->readSTLString (p_colors[i] + OG_Descriptors->getOffset ("rawname") ); col.id = c->id;
col.name = p->readSTLString (p_colors[i] + OG_Descriptors->getOffset ("name") ); col.name = c->name;
col.red = p->readFloat( p_colors[i] + OG_Descriptors->getOffset ("color_r") ); col.red = c->red;
col.green = p->readFloat( p_colors[i] + OG_Descriptors->getOffset ("color_v") ); col.green = c->green;
col.blue = p->readFloat( p_colors[i] + OG_Descriptors->getOffset ("color_b") ); col.blue = c->blue;
color.push_back(col); color.push_back(col);
} }
return ReadNamesOnly(d->owner, OG_Descriptors->getAddress ("all_colors_vector"), alldesc );
size = world->raws.language.patterns.size();
alldesc.clear();
alldesc.reserve(size);
for (uint32_t i = 0; i < size;i++)
{
t_matgloss mat;
mat.id = world->raws.language.patterns[i]->id;
alldesc.push_back(mat);
}
return true; return true;
} }
bool Materials::ReadCreatureTypesEx (void) bool Materials::ReadCreatureTypesEx (void)
{ {
Process *p = d->owner; uint32_t size = world->raws.creatures.all.size();
VersionInfo *mem = p->getDescriptor();
OffsetGroup * OG_string = mem->getGroup("string");
uint32_t sizeof_string = OG_string->getHexValue ("sizeof");
OffsetGroup * OG_Mats = mem->getGroup("Materials");
vector <char *> & p_races = *(vector<char*> *) OG_Mats->getAddress ("creature_type_vector");
OffsetGroup * OG_Creature = OG_Mats->getGroup("creature");
uint32_t castes_vector_offset = OG_Creature->getOffset ("caste_vector");
uint32_t extract_vector_offset = OG_Creature->getOffset ("extract_vector");
uint32_t tile_offset = OG_Creature->getOffset ("tile");
uint32_t tile_color_offset = OG_Creature->getOffset ("tile_color");
bool have_advanced = false;
uint32_t caste_colormod_offset;
uint32_t caste_attributes_offset;
uint32_t caste_bodypart_offset;
uint32_t bodypart_id_offset;
uint32_t bodypart_category_offset;
uint32_t color_modifier_part_offset;
uint32_t color_modifier_startdate_offset;
uint32_t color_modifier_enddate_offset;
try
{
OffsetGroup * OG_Caste = OG_Creature->getGroup("caste");
caste_colormod_offset = OG_Caste->getOffset ("color_modifiers");
caste_attributes_offset = OG_Caste->getOffset ("attributes");
caste_bodypart_offset = OG_Caste->getOffset ("bodypart_vector");
OffsetGroup * OG_CasteBodyparts = OG_Creature->getGroup("caste_bodyparts");
bodypart_id_offset = OG_CasteBodyparts->getOffset ("id");
bodypart_category_offset = OG_CasteBodyparts->getOffset ("category");
OffsetGroup * OG_CasteColorMods = OG_Creature->getGroup("caste_color_mods");
color_modifier_part_offset = OG_CasteColorMods->getOffset ("part");
color_modifier_startdate_offset = OG_CasteColorMods->getOffset ("startdate");
color_modifier_enddate_offset = OG_CasteColorMods->getOffset ("enddate");
have_advanced = true;
}
catch (Error::All &){};
uint32_t size = p_races.size();
uint32_t sizecas = 0;
uint32_t sizecolormod;
uint32_t sizecolorlist;
uint32_t sizebp;
raceEx.clear(); raceEx.clear();
raceEx.reserve (size); raceEx.reserve (size);
for (uint32_t i = 0; i < size;i++) for (uint32_t i = 0; i < size; i++)
{ {
df::creature_raw *cr = world->raws.creatures.all[i];
t_creaturetype mat; t_creaturetype mat;
mat.id = p->readSTLString (p_races[i]); mat.id = cr->creature_id;
mat.tile_character = p->readByte( p_races[i] + tile_offset ); mat.tile_character = cr->creature_tile;
mat.tilecolor.fore = p->readWord( p_races[i] + tile_color_offset ); mat.tilecolor.fore = cr->color[0];
mat.tilecolor.back = p->readWord( p_races[i] + tile_color_offset + 2 ); mat.tilecolor.back = cr->color[1];
mat.tilecolor.bright = p->readWord( p_races[i] + tile_color_offset + 4 ); mat.tilecolor.bright = cr->color[2];
vector <char *> & p_castes = *(vector<char*> *) (p_races[i] + castes_vector_offset); uint32_t sizecas = cr->caste.size();
sizecas = p_castes.size();
for (uint32_t j = 0; j < sizecas;j++) for (uint32_t j = 0; j < sizecas;j++)
{ {
df::caste_raw *ca = cr->caste[j];
/* caste name */ /* caste name */
t_creaturecaste caste; t_creaturecaste caste;
char * caste_start = p_castes[j]; caste.id = ca->caste_id;
caste.id = p->readSTLString (caste_start); caste.singular = ca->caste_name[0];
caste.singular = p->readSTLString (caste_start + sizeof_string); caste.plural = ca->caste_name[1];
caste.plural = p->readSTLString (caste_start + 2 * sizeof_string); caste.adjective = ca->caste_name[2];
caste.adjective = p->readSTLString (caste_start + 3 * sizeof_string); /*
//cout << "Caste " << caste.rawname << " " << caste.singular << ": 0x" << hex << caste_start << endl; // color mod reading
if(have_advanced)
{
/* color mod reading */
// Caste + offset > color mod vector // Caste + offset > color mod vector
vector <char *> & p_colormod = *(vector<char*> *) (caste_start + caste_colormod_offset); vector <char *> & p_colormod = *(vector<char*> *) (world->raws.creatures.all[i]->caste + caste_colormod_offset);
sizecolormod = p_colormod.size(); uint32_t sizecolormod = p_colormod.size();
caste.ColorModifier.resize(sizecolormod); caste.ColorModifier.resize(sizecolormod);
for(uint32_t k = 0; k < sizecolormod;k++) for(uint32_t k = 0; k < sizecolormod;k++)
{ {
// color mod [0] -> color list // color mod [0] -> color list
vector <uint32_t> & p_colorlist = *(vector<uint32_t> *) (p_colormod[k]); vector <uint32_t> & p_colorlist = *(vector<uint32_t> *) (p_colormod[k]);
sizecolorlist = p_colorlist.size(); uint32_t sizecolorlist = p_colorlist.size();
caste.ColorModifier[k].colorlist.resize(sizecolorlist); caste.ColorModifier[k].colorlist.resize(sizecolorlist);
for(uint32_t l = 0; l < sizecolorlist; l++) for(uint32_t l = 0; l < sizecolorlist; l++)
caste.ColorModifier[k].colorlist[l] = p_colorlist[l]; caste.ColorModifier[k].colorlist[l] = p_colorlist[l];
@ -772,30 +734,68 @@ bool Materials::ReadCreatureTypesEx (void)
caste.ColorModifier[k].startdate = p->readDWord( p_colormod[k] + color_modifier_startdate_offset ); caste.ColorModifier[k].startdate = p->readDWord( p_colormod[k] + color_modifier_startdate_offset );
caste.ColorModifier[k].enddate = p->readDWord( p_colormod[k] + color_modifier_enddate_offset ); caste.ColorModifier[k].enddate = p->readDWord( p_colormod[k] + color_modifier_enddate_offset );
} }
/* body parts */ */
vector <char *> & p_bodypart = *(vector<char*> *) (caste_start + caste_bodypart_offset); // body parts
caste.bodypart.empty(); caste.bodypart.empty();
sizebp = p_bodypart.size(); uint32_t sizebp = ca->body_parts.size();
for(uint32_t k = 0; k < sizebp; k++) for (uint32_t k = 0; k < sizebp; k++)
{ {
df::body_part_raw *bp = ca->body_parts[k];
t_bodypart part; t_bodypart part;
part.id = p->readSTLString (p_bodypart[k] + bodypart_id_offset); part.id = bp->part_code;
part.category = p->readSTLString (p_bodypart[k] + bodypart_category_offset); part.category = bp->part_name;
caste.bodypart.push_back(part); caste.bodypart.push_back(part);
} }
p->read(caste_start + caste_attributes_offset, sizeof(t_attrib) * NUM_CREAT_ATTRIBS, (uint8_t *)&caste.strength);
} t_attrib *phys[] = {
else &caste.strength,
{ &caste.agility,
memset(&caste.strength, 0, sizeof(t_attrib) * NUM_CREAT_ATTRIBS); &caste.toughness,
&caste.endurance,
&caste.recuperation,
&caste.disease_resistance
};
for (uint32_t k = 0; k < 6; k++)
{
phys[k]->level = ca->attributes.phys_att_range[k][0];
phys[k]->field_4 = ca->attributes.phys_att_range[k][1];
phys[k]->field_8 = ca->attributes.phys_att_range[k][2];
phys[k]->field_C = ca->attributes.phys_att_range[k][3];
phys[k]->leveldiff = ca->attributes.phys_att_range[k][4];
phys[k]->field_14 = ca->attributes.phys_att_range[k][5];
phys[k]->field_18 = ca->attributes.phys_att_range[k][6];
}
t_attrib *ment[] = {
&caste.analytical_ability,
&caste.focus,
&caste.willpower,
&caste.creativity,
&caste.intuition,
&caste.patience,
&caste.memory,
&caste.linguistic_ability,
&caste.spatial_sense,
&caste.musicality,
&caste.kinesthetic_sense,
&caste.empathy,
&caste.social_awareness
};
for (uint32_t k = 0; k < 13; k++)
{
ment[k]->level = ca->attributes.ment_att_range[k][0];
ment[k]->field_4 = ca->attributes.ment_att_range[k][1];
ment[k]->field_8 = ca->attributes.ment_att_range[k][2];
ment[k]->field_C = ca->attributes.ment_att_range[k][3];
ment[k]->leveldiff = ca->attributes.ment_att_range[k][4];
ment[k]->field_14 = ca->attributes.ment_att_range[k][5];
ment[k]->field_18 = ca->attributes.ment_att_range[k][6];
} }
mat.castes.push_back(caste); mat.castes.push_back(caste);
} }
vector <void *> & p_extract = *(vector<void*> *) (p_races[i] + extract_vector_offset); for (uint32_t j = 0; j < world->raws.creatures.all[i]->material.size(); j++)
for(uint32_t j = 0; j < p_extract.size(); j++)
{ {
t_creatureextract extract; t_creatureextract extract;
extract.id = p->readSTLString( p_extract[j] ); extract.id = world->raws.creatures.all[i]->material[j]->id;
mat.extract.push_back(extract); mat.extract.push_back(extract);
} }
raceEx.push_back(mat); raceEx.push_back(mat);
@ -813,119 +813,33 @@ bool Materials::ReadAllMaterials(void)
return ok; return ok;
} }
/// miserable pile of magic. The material system is insane.
// FIXME: this contains potential errors when the indexes are -1 and compared to unsigned numbers!
std::string Materials::getDescription(const t_material & mat) std::string Materials::getDescription(const t_material & mat)
{ {
std::string out; MaterialInfo mi(mat.material, mat.index);
int32_t typeC; if (mi.creature)
if ( (mat.material<419) || (mat.material>618) ) return mi.creature->creature_id + " " + mi.material->id;
{ else if (mi.plant)
if ( (mat.material<19) || (mat.material>218) ) return mi.plant->id + " " + mi.material->id;
{
if (mat.material)
if (mat.material>0x292)
return "?";
else
{
if (mat.material>=this->other.size())
{
if (mat.itemType == 0) {
if(mat.material<0)
return "any inorganic";
else
return this->df_inorganic->at(mat.material)->ID;
}
if(mat.material<0)
return "any";
if(mat.material>=this->raceEx.size())
return "stuff";
return this->raceEx[mat.material].id;
}
else
{
if (mat.index==-1)
return std::string(this->other[mat.material].id);
else
return std::string(this->other[mat.material].id) + " derivate";
}
}
else
if(mat.index<0)
return "any inorganic";
else if (mat.index < df_inorganic->size())
return this->df_inorganic->at(mat.index)->ID;
else else
return "INDEX OUT OF BOUNDS!"; return mi.material->id;
}
else
{
if (mat.index>=this->raceEx.size())
return "unknown race";
typeC = mat.material;
typeC -=19;
if ((typeC<0) || (typeC>=this->raceEx[mat.index].extract.size()))
{
return string(this->raceEx[mat.index].id).append(" extract");
}
return std::string(this->raceEx[mat.index].id).append(" ").append(this->raceEx[mat.index].extract[typeC].id);
}
}
else
{
return this->df_organic->at(mat.material)->ID;
}
return out;
} }
//type of material only so we know which vector to retrieve // type of material only so we know which vector to retrieve
// FIXME: this also contains potential errors when the indexes are -1 and compared to unsigned numbers! // This is completely worthless now
std::string Materials::getType(const t_material & mat) std::string Materials::getType(const t_material & mat)
{ {
if((mat.material<419) || (mat.material>618)) MaterialInfo mi(mat.material, mat.index);
{ switch (mi.mode)
if((mat.material<19) || (mat.material>218))
{
if(mat.material)
{ {
if(mat.material>0x292) case MaterialInfo::Builtin:
{ return "builtin";
return "unknown"; case MaterialInfo::Inorganic:
}
else
{
if(mat.material>=this->other.size())
{
if(mat.material<0)
return "any";
if(mat.material>=this->raceEx.size())
return "unknown";
return "racex";
}
else
{
if (mat.index==-1)
return "other";
else
return "other derivate";
}
}
}
else
return "inorganic"; return "inorganic";
} case MaterialInfo::Creature:
else return "creature";
{ case MaterialInfo::Plant:
if (mat.index>=this->raceEx.size()) return "plant";
default:
return "unknown"; return "unknown";
return "racex extract";
}
}
else
{
return "organic";
} }
} }

@ -36,6 +36,7 @@ using namespace std;
#include "Types.h" #include "Types.h"
#include "ModuleFactory.h" #include "ModuleFactory.h"
#include "Core.h" #include "Core.h"
using namespace DFHack; using namespace DFHack;
Module* DFHack::createTranslation() Module* DFHack::createTranslation()
@ -167,7 +168,7 @@ bool Translation::InitReadNames()
return true; return true;
} }
bool Translation::readName(t_name & name, df_name * source) bool Translation::readName(t_name & name, df::language_name * source)
{ {
Core & c = Core::getInstance(); Core & c = Core::getInstance();
Process * p = c.p; Process * p = c.p;
@ -180,7 +181,7 @@ bool Translation::readName(t_name & name, df_name * source)
if(!InitReadNames()) return false; if(!InitReadNames()) return false;
} }
strncpy(name.first_name,source->first_name.c_str(),127); strncpy(name.first_name,source->first_name.c_str(),127);
strncpy(name.nickname,source->nick_name.c_str(),127); strncpy(name.nickname,source->nickname.c_str(),127);
memcpy(&name.parts_of_speech, &source->parts_of_speech, sizeof (source->parts_of_speech)); memcpy(&name.parts_of_speech, &source->parts_of_speech, sizeof (source->parts_of_speech));
memcpy(&name.words, &source->words, sizeof (source->words)); memcpy(&name.words, &source->words, sizeof (source->words));
name.language = source->language; name.language = source->language;
@ -188,7 +189,7 @@ bool Translation::readName(t_name & name, df_name * source)
return true; return true;
} }
bool Translation::copyName(df_name * source, df_name * target) bool Translation::copyName(df::language_name * source, df::language_name * target)
{ {
if (source == target) if (source == target)
return true; return true;
@ -196,7 +197,7 @@ bool Translation::copyName(df_name * source, df_name * target)
Process * p = c.p; Process * p = c.p;
target->first_name = source->first_name; target->first_name = source->first_name;
target->nick_name = source->nick_name; target->nickname = source->nickname;
target->has_name = source->has_name; target->has_name = source->has_name;
target->language = source->language; target->language = source->language;
memcpy(&target->parts_of_speech, &source->parts_of_speech, sizeof (source->parts_of_speech)); memcpy(&target->parts_of_speech, &source->parts_of_speech, sizeof (source->parts_of_speech));
@ -205,7 +206,7 @@ bool Translation::copyName(df_name * source, df_name * target)
return true; return true;
} }
string Translation::TranslateName(const df_name * name, bool inEnglish) string Translation::TranslateName(const df::language_name * name, bool inEnglish)
{ {
string out; string out;
assert (d->Started); assert (d->Started);
@ -242,8 +243,8 @@ string Translation::TranslateName(const df_name * name, bool inEnglish)
{ {
if(name->words[0] >=0 || name->words[1] >=0) if(name->words[0] >=0 || name->words[1] >=0)
{ {
if(name->words[0]>=0) out.append(d->dicts.translations[name->parts_of_speech[0]+1][name->words[0]]); if(name->words[0]>=0) out.append(d->dicts.translations[name->parts_of_speech[0].value+1][name->words[0]]);
if(name->words[1]>=0) out.append(d->dicts.translations[name->parts_of_speech[1]+1][name->words[1]]); if(name->words[1]>=0) out.append(d->dicts.translations[name->parts_of_speech[1].value+1][name->words[1]]);
out[0] = toupper(out[0]); out[0] = toupper(out[0]);
} }
if(name->words[5] >=0) if(name->words[5] >=0)
@ -257,7 +258,7 @@ string Translation::TranslateName(const df_name * name, bool inEnglish)
{ {
if(name->words[i]>=0) if(name->words[i]>=0)
{ {
word = d->dicts.translations[name->parts_of_speech[i]+1][name->words[i]]; word = d->dicts.translations[name->parts_of_speech[i].value+1][name->words[i]];
word[0] = toupper(word[0]); word[0] = toupper(word[0]);
out.append(" " + word); out.append(" " + word);
} }
@ -270,7 +271,7 @@ string Translation::TranslateName(const df_name * name, bool inEnglish)
else else
out.append("Of"); out.append("Of");
string word; string word;
word.append(d->dicts.translations[name->parts_of_speech[6]+1][name->words[6]]); word.append(d->dicts.translations[name->parts_of_speech[6].value+1][name->words[6]]);
word[0] = toupper(word[0]); word[0] = toupper(word[0]);
out.append(" " + word); out.append(" " + word);
} }

@ -46,15 +46,19 @@ using namespace std;
#include "ModuleFactory.h" #include "ModuleFactory.h"
#include "Core.h" #include "Core.h"
#include "df/world.h"
#include "df/ui.h"
#include "df/unit_inventory_item.h"
using namespace DFHack; using namespace DFHack;
using df::global::world;
using df::global::ui;
struct Units::Private struct Units::Private
{ {
bool Inited; bool Inited;
bool Started; bool Started;
void * dwarf_race_index_addr;
void * dwarf_civ_id_addr;
bool IdMapReady; bool IdMapReady;
std::map<int32_t, int32_t> IdMap; std::map<int32_t, int32_t> IdMap;
@ -81,14 +85,6 @@ Units::Units()
OffsetGroup *OG_Creatures = minfo->getGroup("Creatures"); OffsetGroup *OG_Creatures = minfo->getGroup("Creatures");
creatures = 0;
try
{
creatures = (vector <df_unit *> *) OG_Creatures->getAddress ("vector");
d->dwarf_race_index_addr = (void *) OG_Creatures->getAddress("current_race");
d->dwarf_civ_id_addr = (void *) OG_Creatures->getAddress("current_civ");
}
catch(Error::All&){};
d->Inited = true; d->Inited = true;
} }
@ -100,15 +96,11 @@ Units::~Units()
bool Units::Start( uint32_t &numcreatures ) bool Units::Start( uint32_t &numcreatures )
{ {
if(creatures)
{
d->Started = true; d->Started = true;
numcreatures = creatures->size(); numcreatures = world->units.all.size();
d->IdMap.clear(); d->IdMap.clear();
d->IdMapReady = false; d->IdMapReady = false;
return true; return true;
}
return false;
} }
bool Units::Finish() bool Units::Finish()
@ -117,35 +109,34 @@ bool Units::Finish()
return true; return true;
} }
df_unit * Units::GetCreature (const int32_t index) df::unit * Units::GetCreature (const int32_t index)
{ {
if(!d->Started) return NULL; if(!d->Started) return NULL;
// read pointer from vector at position // read pointer from vector at position
if(index > creatures->size()) if(index > world->units.all.size())
return 0; return 0;
return creatures->at(index); return world->units.all[index];
} }
// returns index of creature actually read or -1 if no creature can be found // returns index of creature actually read or -1 if no creature can be found
int32_t Units::GetCreatureInBox (int32_t index, df_unit ** furball, 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 x1, const uint16_t y1, const uint16_t z1,
const uint16_t x2, const uint16_t y2, const uint16_t z2) const uint16_t x2, const uint16_t y2, const uint16_t z2)
{ {
if (!d->Started) if (!d->Started)
return -1; return -1;
Process *p = d->owner; uint32_t size = world->units.all.size();
uint32_t size = creatures->size();
while (uint32_t(index) < size) while (uint32_t(index) < size)
{ {
// read pointer from vector at position // read pointer from vector at position
df_unit * temp = creatures->at(index); df::unit * temp = world->units.all[index];
if (temp->x >= x1 && temp->x < x2) if (temp->pos.x >= x1 && temp->pos.x < x2)
{ {
if (temp->y >= y1 && temp->y < y2) if (temp->pos.y >= y1 && temp->pos.y < y2)
{ {
if (temp->z >= z1 && temp->z < z2) if (temp->pos.z >= z1 && temp->pos.z < z2)
{ {
*furball = temp; *furball = temp;
return index; return index;
@ -158,7 +149,7 @@ int32_t Units::GetCreatureInBox (int32_t index, df_unit ** furball,
return -1; return -1;
} }
void Units::CopyCreature(df_unit * source, t_unit & furball) void Units::CopyCreature(df::unit * source, t_unit & furball)
{ {
if(!d->Started) return; if(!d->Started) return;
// read pointer from vector at position // read pointer from vector at position
@ -166,15 +157,15 @@ void Units::CopyCreature(df_unit * source, t_unit & furball)
//read creature from memory //read creature from memory
// name // name
d->trans->readName(furball.name,&source->name); d->trans->readName(furball.name, &source->name);
// basic stuff // basic stuff
furball.id = source->id; furball.id = source->id;
furball.x = source->x; furball.x = source->pos.x;
furball.y = source->y; furball.y = source->pos.y;
furball.z = source->z; furball.z = source->pos.z;
furball.race = source->race; furball.race = source->race;
furball.civ = source->civ; furball.civ = source->civ_id;
furball.sex = source->sex; furball.sex = source->sex;
furball.caste = source->caste; furball.caste = source->caste;
furball.flags1.whole = source->flags1.whole; furball.flags1.whole = source->flags1.whole;
@ -185,28 +176,28 @@ void Units::CopyCreature(df_unit * source, t_unit & furball)
// profession // profession
furball.profession = source->profession; furball.profession = source->profession;
// happiness // happiness
furball.happiness = source->happiness; furball.happiness = source->status.happiness;
// physical attributes // physical attributes
memcpy(&furball.strength, source->physical, sizeof(source->physical)); memcpy(&furball.strength, source->body.physical_attrs, sizeof(source->body.physical_attrs));
// mood stuff // mood stuff
furball.mood = source->mood; furball.mood = source->mood;
furball.mood_skill = source->unk_2f8; // FIXME: really? More like currently used skill anyway. furball.mood_skill = source->job.unk_2f8; // FIXME: really? More like currently used skill anyway.
d->trans->readName(furball.artifact_name, &source->artifact_name); d->trans->readName(furball.artifact_name, &source->status.artifact_name);
// labors // labors
memcpy(&furball.labors, &source->labors, sizeof(furball.labors)); memcpy(&furball.labors, &source->status.labors, sizeof(furball.labors));
furball.birth_year = source->birth_year; furball.birth_year = source->relations.birth_year;
furball.birth_time = source->birth_time; furball.birth_time = source->relations.birth_time;
furball.pregnancy_timer = source->pregnancy_timer; furball.pregnancy_timer = source->relations.pregnancy_timer;
// appearance // appearance
furball.nbcolors = source->appearance.size(); furball.nbcolors = source->appearance.colors.size();
if(furball.nbcolors>MAX_COLORS) if(furball.nbcolors>MAX_COLORS)
furball.nbcolors = MAX_COLORS; furball.nbcolors = MAX_COLORS;
for(uint32_t i = 0; i < furball.nbcolors; i++) for(uint32_t i = 0; i < furball.nbcolors; i++)
{ {
furball.color[i] = source->appearance[i]; furball.color[i] = source->appearance.colors[i];
} }
//likes. FIXME: where do they fit in now? The soul? //likes. FIXME: where do they fit in now? The soul?
@ -275,28 +266,7 @@ void Units::CopyCreature(df_unit * source, t_unit & furball)
} }
int32_t Units::FindIndexById(int32_t creature_id) int32_t Units::FindIndexById(int32_t creature_id)
{ {
if (!d->Started) return df::unit::binsearch_index(world->units.all, creature_id);
return -1;
if (!d->IdMapReady)
{
d->IdMap.clear();
uint32_t size = creatures->size();
for (uint32_t index = 0; index < size; index++)
{
df_unit * temp = creatures->at(index);
int32_t id = temp->id;
d->IdMap[id] = index;
}
}
std::map<int32_t,int32_t>::iterator it;
it = d->IdMap.find(creature_id);
if(it == d->IdMap.end())
return -1;
else
return it->second;
} }
/* /*
bool Creatures::WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]) bool Creatures::WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS])
@ -507,16 +477,12 @@ bool Creatures::WritePregnancy(const uint32_t index, const uint32_t pregTimer)
*/ */
uint32_t Units::GetDwarfRaceIndex() uint32_t Units::GetDwarfRaceIndex()
{ {
if(!d->Inited) return 0; return ui->race_id;
Process * p = d->owner;
return p->readDWord(d->dwarf_race_index_addr);
} }
int32_t Units::GetDwarfCivId() int32_t Units::GetDwarfCivId()
{ {
if(!d->Inited) return -1; return ui->civ_id;
Process * p = d->owner;
return p->readDWord(d->dwarf_civ_id_addr);
} }
/* /*
bool Creatures::getCurrentCursorCreature(uint32_t & creature_index) bool Creatures::getCurrentCursorCreature(uint32_t & creature_index)
@ -551,28 +517,28 @@ bool Creatures::ReadJob(const t_creature * furball, vector<t_material> & mat)
*/ */
bool Units::ReadInventoryByIdx(const uint32_t index, std::vector<df::item *> & item) bool Units::ReadInventoryByIdx(const uint32_t index, std::vector<df::item *> & item)
{ {
if(!d->Started) return false; if(index >= world->units.all.size()) return false;
if(index >= creatures->size()) return false; df::unit * temp = world->units.all[index];
df_unit * temp = creatures->at(index);
return this->ReadInventoryByPtr(temp, item); return this->ReadInventoryByPtr(temp, item);
} }
bool Units::ReadInventoryByPtr(const df_unit * temp, std::vector<df::item *> & items) bool Units::ReadInventoryByPtr(const df::unit * temp, std::vector<df::item *> & items)
{ {
if(!d->Started) return false; if(!d->Started) return false;
items = temp->inventory; items.clear();
for (uint32_t i = 0; i < temp->inventory.size(); i++)
items.push_back(temp->inventory[i]->item);
return true; return true;
} }
bool Units::ReadOwnedItemsByIdx(const uint32_t index, std::vector<int32_t> & item) bool Units::ReadOwnedItemsByIdx(const uint32_t index, std::vector<int32_t> & item)
{ {
if(!d->Started ) return false; if(index >= world->units.all.size()) return false;
if(index >= creatures->size()) return false; df::unit * temp = world->units.all[index];
df_unit * temp = creatures->at(index);
return this->ReadOwnedItemsByPtr(temp, item); return this->ReadOwnedItemsByPtr(temp, item);
} }
bool Units::ReadOwnedItemsByPtr(const df_unit * temp, std::vector<int32_t> & items) bool Units::ReadOwnedItemsByPtr(const df::unit * temp, std::vector<int32_t> & items)
{ {
if(!d->Started) return false; if(!d->Started) return false;
items = temp->owned_items; items = temp->owned_items;
@ -581,16 +547,12 @@ bool Units::ReadOwnedItemsByPtr(const df_unit * temp, std::vector<int32_t> & ite
bool Units::RemoveOwnedItemByIdx(const uint32_t index, int32_t id) bool Units::RemoveOwnedItemByIdx(const uint32_t index, int32_t id)
{ {
if(!d->Started) if(index >= world->units.all.size()) return false;
{ df::unit * temp = world->units.all[index];
cerr << "!d->Started FAIL" << endl;
return false;
}
df_unit * temp = creatures->at (index);
return this->RemoveOwnedItemByPtr(temp, id); return this->RemoveOwnedItemByPtr(temp, id);
} }
bool Units::RemoveOwnedItemByPtr(df_unit * temp, int32_t id) bool Units::RemoveOwnedItemByPtr(df::unit * temp, int32_t id)
{ {
if(!d->Started) return false; if(!d->Started) return false;
Process * p = d->owner; Process * p = d->owner;
@ -609,7 +571,7 @@ bool Units::RemoveOwnedItemByPtr(df_unit * temp, int32_t id)
return true; return true;
} }
void Units::CopyNameTo(df_unit * creature, df_name * target) void Units::CopyNameTo(df::unit * creature, df::language_name * target)
{ {
d->trans->copyName(&creature->name, target); d->trans->copyName(&creature->name, target);
} }

@ -1 +1 @@
Subproject commit 8f9f7cf3bc4cff3dc721dc9e0ba51bc54b069587 Subproject commit 0b23a6e28b72f8383647b317635d9b75a69529e0

@ -188,10 +188,10 @@ DFhackCExport command_result df_cleanowned (Core * c, vector <string> & paramete
if (owner_index >= 0) if (owner_index >= 0)
{ {
DFHack::df_unit * temp = Creatures->GetCreature(owner_index); df::unit * temp = Creatures->GetCreature(owner_index);
info = temp->name.first_name; info = temp->name.first_name;
if (!temp->name.nick_name.empty()) if (!temp->name.nickname.empty())
info += std::string(" '") + temp->name.nick_name + "'"; info += std::string(" '") + temp->name.nickname + "'";
info += " "; info += " ";
info += Tran->TranslateName(&temp->name,false); info += Tran->TranslateName(&temp->name,false);
c->con.print(", owner %s", info.c_str()); c->con.print(", owner %s", info.c_str());

@ -68,10 +68,10 @@ DFhackCExport command_result df_cprobe (Core * c, vector <string> & parameters)
cr->Start(ncr); cr->Start(ncr);
for(auto i = 0; i < ncr; i++) for(auto i = 0; i < ncr; i++)
{ {
df_unit * unit = cr->GetCreature( i ); df::unit * unit = cr->GetCreature( i );
if(unit->x == cursorX && unit->y == cursorY && unit->z == cursorZ) 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, unit->civ); con.print("Creature %d, race %d (%x), civ %d (%x)\n", unit->id, unit->race, unit->race, unit->civ_id, unit->civ_id);
break; break;
} }
} }

@ -23,6 +23,7 @@ using namespace std;
#include "df/world.h" #include "df/world.h"
using namespace DFHack; using namespace DFHack;
using df::global::world;
struct matdata struct matdata
{ {
@ -95,18 +96,16 @@ static void printMatdata(DFHack::Console & con, const matdata &data)
con <<" Z:" << std::setw(4) << data.lower_z << std::endl; con <<" Z:" << std::setw(4) << data.lower_z << std::endl;
} }
static int getValue(const df_inorganic_type &info) static int getValue(const df::inorganic_raw &info)
{ {
return info.mat.MATERIAL_VALUE; return info.material.material_value;
} }
static int getValue(const df_plant_type &info) static int getValue(const df::plant_raw &info)
{ {
return info.value; return info.value;
} }
// printMats() accepts a vector of pointers to t_matgloss so that it can
// deal t_matgloss and all subclasses.
template <typename T> template <typename T>
void printMats(DFHack::Console & con, MatMap &mat, std::vector<T*> &materials, bool show_value) void printMats(DFHack::Console & con, MatMap &mat, std::vector<T*> &materials, bool show_value)
{ {
@ -128,7 +127,8 @@ void printMats(DFHack::Console & con, MatMap &mat, std::vector<T*> &materials, b
continue; continue;
} }
T* mat = materials[it->first]; T* mat = materials[it->first];
con << std::setw(25) << mat->ID << " : "; // Somewhat of a hack, but it works because df::inorganic_raw and df::plant_raw both have a field named "id"
con << std::setw(25) << mat->id << " : ";
if (show_value) if (show_value)
con << std::setw(3) << getValue(*mat) << " : "; con << std::setw(3) << getValue(*mat) << " : ";
printMatdata(con, it->second); printMatdata(con, it->second);
@ -147,9 +147,9 @@ void printVeins(DFHack::Console & con, MatMap &mat_map,
for (MatMap::const_iterator it = mat_map.begin(); it != mat_map.end(); ++it) for (MatMap::const_iterator it = mat_map.begin(); it != mat_map.end(); ++it)
{ {
DFHack::df_inorganic_type *gloss = mats->df_inorganic->at(it->first); df::inorganic_raw *gloss = world->raws.inorganics[it->first];
if (gloss->mat.isGem()) if (gloss->material.isGem())
gems[it->first] = it->second; gems[it->first] = it->second;
else if (gloss->isOre()) else if (gloss->isOre())
ores[it->first] = it->second; ores[it->first] = it->second;
@ -158,13 +158,13 @@ void printVeins(DFHack::Console & con, MatMap &mat_map,
} }
con << "Ores:" << std::endl; con << "Ores:" << std::endl;
printMats(con, ores, *mats->df_inorganic, show_value); printMats(con, ores, world->raws.inorganics, show_value);
con << "Gems:" << std::endl; con << "Gems:" << std::endl;
printMats(con, gems, *mats->df_inorganic, show_value); printMats(con, gems, world->raws.inorganics, show_value);
con << "Other vein stone:" << std::endl; con << "Other vein stone:" << std::endl;
printMats(con, rest, *mats->df_inorganic, show_value); printMats(con, rest, world->raws.inorganics, show_value);
} }
DFhackCExport command_result prospector (Core * c, vector <string> & parameters); DFhackCExport command_result prospector (Core * c, vector <string> & parameters);
@ -234,17 +234,6 @@ DFhackCExport command_result prospector (DFHack::Core * c, vector <string> & par
MapExtras::MapCache map; MapExtras::MapCache map;
DFHack::Materials *mats = c->getMaterials(); DFHack::Materials *mats = c->getMaterials();
if (!mats->df_inorganic)
{
con.printerr("Unable to read inorganic material definitons!\n");
c->Resume();
return CR_FAILURE;
}
if (showPlants && !mats->df_organic)
{
con.printerr("Unable to read organic material definitons; plants won't be listed!\n");
showPlants = false;
}
DFHack::t_feature blockFeatureGlobal; DFHack::t_feature blockFeatureGlobal;
DFHack::t_feature blockFeatureLocal; DFHack::t_feature blockFeatureLocal;
@ -459,16 +448,16 @@ DFhackCExport command_result prospector (DFHack::Core * c, vector <string> & par
} }
con << std::endl << "Layer materials:" << std::endl; con << std::endl << "Layer materials:" << std::endl;
printMats(con, layerMats, *mats->df_inorganic, showValue); printMats(con, layerMats, world->raws.inorganics, showValue);
printVeins(con, veinMats, mats, showValue); printVeins(con, veinMats, mats, showValue);
if (showPlants) if (showPlants)
{ {
con << "Shrubs:" << std::endl; con << "Shrubs:" << std::endl;
printMats(con, plantMats, *mats->df_organic, showValue); printMats(con, plantMats, world->raws.plants.all, showValue);
con << "Wood in trees:" << std::endl; con << "Wood in trees:" << std::endl;
printMats(con, treeMats, *mats->df_organic, showValue); printMats(con, treeMats, world->raws.plants.all, showValue);
} }
if (hasAquifer) if (hasAquifer)