Merge branch 'DF2010' of git://github.com/peterix/dfhack into Branch_remotes/origin/pydfhack

develop
doomchild 2010-04-07 14:51:41 -05:00
commit 5f5a53674b
25 changed files with 1197 additions and 959 deletions

@ -11,6 +11,8 @@
#include "modules/Maps.h"
#include "modules/Materials.h"
#include "modules/Position.h"
#include "modules/Translation.h"
#include "modules/Vegetation.h"
#include "modules/Gui.h"
using namespace DFHack;
@ -23,6 +25,8 @@ APIPrivate::APIPrivate()
position = 0;
gui = 0;
materials = 0;
translation = 0;
vegetation = 0;
}
APIPrivate::~APIPrivate()
@ -32,6 +36,8 @@ APIPrivate::~APIPrivate()
if(position) delete position;
if(gui) delete gui;
if(materials) delete materials;
if(translation) delete translation;
if(vegetation) delete vegetation;
}
bool APIPrivate::InitReadNames()

@ -37,6 +37,8 @@ modules/Gui.cpp
modules/Maps.cpp
modules/Materials.cpp
modules/Position.cpp
modules/Translation.cpp
modules/Vegetation.cpp
)
SET(PROJECT_HDRS_LINUX

@ -40,6 +40,8 @@ distribution.
#include "modules/Position.h"
#include "modules/Gui.h"
#include "modules/Creatures.h"
#include "modules/Translation.h"
#include "modules/Vegetation.h"
using namespace DFHack;
@ -201,6 +203,20 @@ Materials * API::getMaterials()
return d->materials;
}
Translation * API::getTranslation()
{
if(!d->translation)
d->translation = new Translation(d);
return d->translation;
}
Vegetation * API::getVegetation()
{
if(!d->vegetation)
d->vegetation = new Vegetation(d);
return d->vegetation;
}
/*
// returns number of buildings, expects v_buildingtypes that will later map t_building.type to its name
bool API::InitReadBuildings ( uint32_t& numbuildings )
@ -371,51 +387,6 @@ void API::FinishReadConstructions()
d->constructionsInited = false;
}
bool API::InitReadVegetation(uint32_t & numplants)
{
try
{
int vegetation = d->offset_descriptor->getAddress ("vegetation");
d->tree_offset = d->offset_descriptor->getOffset ("tree_desc_offset");
d->vegetationInited = true;
d->p_veg = new DfVector (d->p, vegetation, 4);
numplants = d->p_veg->getSize();
return true;
}
catch (Error::MissingMemoryDefinition&)
{
d->vegetationInited = false;
numplants = 0;
throw;
}
}
bool API::ReadVegetation (const int32_t index, t_tree_desc & shrubbery)
{
if(!d->vegetationInited)
return false;
// read pointer from vector at position
uint32_t temp = * (uint32_t *) d->p_veg->at (index);
//read construction from memory
g_pProcess->read (temp + d->tree_offset, sizeof (t_tree_desc), (uint8_t *) &shrubbery);
// FIXME: this is completely wrong. type isn't just tree/shrub but also different kinds of trees. stuff that grows around ponds has its own type ID
if (shrubbery.material.type == 3) shrubbery.material.type = 2;
return true;
}
void API::FinishReadVegetation()
{
if(d->p_veg)
{
delete d->p_veg;
d->p_veg = 0;
}
d->vegetationInited = false;
}
*/
/*
bool API::InitReadNotes( uint32_t &numnotes )
@ -588,129 +559,6 @@ bool API::getItemIndexesInBox(vector<uint32_t> &indexes,
}
*/
/*
bool API::InitReadNameTables(vector<vector<string> > & translations , vector<vector<string> > & foreign_languages) //(map< string, vector<string> > & nameTable)
{
try
{
int genericAddress = d->offset_descriptor->getAddress ("language_vector");
int transAddress = d->offset_descriptor->getAddress ("translation_vector");
int word_table_offset = d->offset_descriptor->getOffset ("word_table");
int sizeof_string = d->offset_descriptor->getHexValue ("sizeof_string");
DfVector genericVec (d->p, genericAddress, 4);
DfVector transVec (d->p, transAddress, 4);
translations.resize(10);
for (uint32_t i = 0;i < genericVec.getSize();i++)
{
uint32_t genericNamePtr = * (uint32_t *) genericVec.at (i);
for(int i=0; i<10;i++)
{
string word = d->p->readSTLString (genericNamePtr + i * sizeof_string);
translations[i].push_back (word);
}
}
foreign_languages.resize(transVec.getSize());
for (uint32_t i = 0; i < transVec.getSize();i++)
{
uint32_t transPtr = * (uint32_t *) transVec.at (i);
//string transName = d->p->readSTLString (transPtr);
DfVector trans_names_vec (d->p, transPtr + word_table_offset, 4);
for (uint32_t j = 0;j < trans_names_vec.getSize();j++)
{
uint32_t transNamePtr = * (uint32_t *) trans_names_vec.at (j);
string name = d->p->readSTLString (transNamePtr);
foreign_languages[i].push_back (name);
}
}
d->nameTablesInited = true;
return true;
}
catch (Error::MissingMemoryDefinition&)
{
d->nameTablesInited = false;
throw;
}
}
string API::TranslateName(const DFHack::t_name &name,const std::vector< std::vector<std::string> > & translations ,const std::vector< std::vector<std::string> > & foreign_languages, bool inEnglish)
{
string out;
assert (d->nameTablesInited);
map<string, vector<string> >::const_iterator it;
if(!inEnglish)
{
if(name.words[0] >=0 || name.words[1] >=0)
{
if(name.words[0]>=0) out.append(foreign_languages[name.language][name.words[0]]);
if(name.words[1]>=0) out.append(foreign_languages[name.language][name.words[1]]);
out[0] = toupper(out[0]);
}
if(name.words[5] >=0)
{
string word;
for(int i=2;i<=5;i++)
if(name.words[i]>=0) word.append(foreign_languages[name.language][name.words[i]]);
word[0] = toupper(word[0]);
if(out.length() > 0) out.append(" ");
out.append(word);
}
if(name.words[6] >=0)
{
string word;
word.append(foreign_languages[name.language][name.words[6]]);
word[0] = toupper(word[0]);
if(out.length() > 0) out.append(" ");
out.append(word);
}
}
else
{
if(name.words[0] >=0 || name.words[1] >=0)
{
if(name.words[0]>=0) out.append(translations[name.parts_of_speech[0]+1][name.words[0]]);
if(name.words[1]>=0) out.append(translations[name.parts_of_speech[1]+1][name.words[1]]);
out[0] = toupper(out[0]);
}
if(name.words[5] >=0)
{
if(out.length() > 0)
out.append(" the");
else
out.append("The");
string word;
for(int i=2;i<=5;i++)
{
if(name.words[i]>=0)
{
word = translations[name.parts_of_speech[i]+1][name.words[i]];
word[0] = toupper(word[0]);
out.append(" " + word);
}
}
}
if(name.words[6] >=0)
{
if(out.length() > 0)
out.append(" of");
else
out.append("Of");
string word;
word.append(translations[name.parts_of_speech[6]+1][name.words[6]]);
word[0] = toupper(word[0]);
out.append(" " + word);
}
}
return out;
}
void API::FinishReadNameTables()
{
d->nameTablesInited = false;
}
void API::FinishReadNotes()
{
if(d->p_notes)

@ -37,6 +37,7 @@ distribution.
namespace DFHack
{
class APIPrivate;
class memory_info;
class Process;
@ -47,6 +48,8 @@ namespace DFHack
class Position;
class Gui;
class Materials;
class Translation;
class Vegetation;
class DFHACK_EXPORT API
{
@ -89,6 +92,8 @@ namespace DFHack
Gui * getGui();
Position * getPosition();
Materials * getMaterials();
Translation * getTranslation();
Vegetation * getVegetation();
/*
* Constructions (costructed walls, floors, ramps, etc...)
@ -154,14 +159,6 @@ namespace DFHack
bool InitReadHotkeys( );
bool ReadHotkeys(t_hotkey hotkeys[]);
*/
/*
* DF translation tables and name translation
*/
/*
bool InitReadNameTables (std::vector< std::vector<std::string> > & translations , std::vector< std::vector<std::string> > & foreign_languages);
void FinishReadNameTables();
std::string TranslateName(const t_name & name,const std::vector< std::vector<std::string> > & translations ,const std::vector< std::vector<std::string> > & foreign_languages, bool inEnglish=true);
*/
/*
* Item reading

@ -64,20 +64,7 @@ struct t_vein
uint32_t address_of; // this is NOT part of the DF vein, but an address of the vein as seen by DFhack.
};
*/
struct t_vein
{
uint32_t vtable;
int32_t type;
int16_t assignment[16];
uint32_t flags;
uint32_t address_of; // this is NOT part of the DF vein, but an address of the vein as seen by DFhack.
};
// stores what tiles should appear when the ice melts
struct t_frozenliquidvein
{
uint32_t vtable;
int16_t tiles[16][16];
};
struct t_matglossPair
{
@ -121,10 +108,12 @@ struct t_construction_df40d
{
int16_t x;
int16_t y;
// 4
int16_t z;
int16_t unk1;
// 8
int16_t unk2;
t_matglossPair material; // 4B
t_matglossPair material; // C points to the index part
// int16_t mat_type;
// int16_t mat_idx;
};
@ -191,14 +180,6 @@ struct t_building
// FIXME: not complete, we need building presence bitmaps for stuff like farm plots and stockpiles, orientation (N,E,S,W) and state (open/closed)
};
struct t_tree_desc
{
t_matglossPair material;
uint16_t x;
uint16_t y;
uint16_t z;
};
/*
case 10:
ret += "leather";
@ -273,257 +254,6 @@ enum BiomeOffset
eSouthEast,
eBiomeCount
};
/*
bits:
0 Can the dwarf move or are they waiting for their movement timer
1 Dead (might also be set for incoming/leaving critters that are alive)
2 Currently in mood
3 Had a mood
4 "marauder" -- wide class of invader/inside creature attackers
5 Drowning
6 Active merchant
7 "forest" (used for units no longer linked to merchant/diplomacy, they just try to leave mostly)
8 Left (left the map)
9 Rider
10 Incoming
11 Diplomat
12 Zombie
13 Skeleton
14 Can swap tiles during movement (prevents multiple swaps)
15 On the ground (can be conscious)
16 Projectile
17 Active invader (for organized ones)
18 Hidden in ambush
19 Invader origin (could be inactive and fleeing)
20 Will flee if invasion turns around
21 Active marauder/invader moving inward
22 Marauder resident/invader moving in all the way
23 Check against flows next time you get a chance
24 Ridden
25 Caged
26 Tame
27 Chained
28 Royal guard
29 Fortress guard
30 Suppress wield for beatings/etc
31 Is an important historical figure
*/
struct naked_creaturflags1
{
unsigned int move_state : 1; // Can the dwarf move or are they waiting for their movement timer
unsigned int dead : 1; // might also be set for incoming/leaving critters that are alive
unsigned int has_mood : 1; // Currently in mood
unsigned int had_mood : 1; // Had a mood
unsigned int marauder : 1; // wide class of invader/inside creature attackers
unsigned int drowning : 1;
unsigned int merchant : 1; // active merchant
unsigned int forest : 1; // used for units no longer linked to merchant/diplomacy, they just try to leave mostly
unsigned int left : 1; // left the map
unsigned int rider : 1;
unsigned int incoming : 1;
unsigned int diplomat : 1;
unsigned int zombie : 1;
unsigned int skeleton : 1;
unsigned int can_swap : 1; // Can swap tiles during movement (prevents multiple swaps)
unsigned int on_ground : 1; // can be conscious
unsigned int projectile : 1;
unsigned int active_invader : 1; // for organized ones
unsigned int hidden_in_ambush : 1;
unsigned int invader_origin : 1; // could be inactive and fleeing
unsigned int coward : 1; // Will flee if invasion turns around
unsigned int hidden_ambusher : 1; // maybe
unsigned int invades : 1; // Active marauder/invader moving inward
unsigned int check_flows : 1; // Check against flows next time you get a chance
// 0100 0000 - 8000 0000
unsigned int ridden : 1;
unsigned int caged : 1;
unsigned int tame : 1;
unsigned int chained : 1;
unsigned int royal_guard : 1;
unsigned int fortress_guard : 1;
unsigned int suppress_wield : 1; // Suppress wield for beatings/etc
unsigned int important_historical_figure : 1; // Is an important historical figure
};
union t_creaturflags1
{
uint32_t whole;
naked_creaturflags1 bits;
};
/*
bits:
0 Swimming
1 Play combat for sparring
2 Do not notify about level gains (for embark etc)
3 Unused
4 Nerves calculated
5 Body part info calculated
6 Is important historical figure (slight variation)
7 Has been killed by kill function (slightly different from dead, not necessarily violent death)
8 Must be forgotten by forget function (just cleanup)
9 Must be deleted (cleanup)
10 Recently forgotten (cleanup)
11 Offered for trade
12 Trade resolved
13 Has breaks
14 Gutted
15 Circulatory spray
16 Locked in for trading (it's a projectile on the other set of flags, might be what the flying was)
17 Marked for slaughter
18 Underworld creature
19 Current resident
20 Marked for special cleanup as unused load from unit block on disk
21 Insulation from clothing calculated
22 Uninvited guest
23 Visitor
24 Inventory order calculated
25 Vision -- have good part
26 Vision -- have damaged part
27 Vision -- have missing part
28 Breathing -- have good part
29 Breathing -- having a problem
30 Roaming wilderness population source
31 Roaming wilderness population source -- not a map feature
*/
struct naked_creaturflags2
{
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; // slight variation
unsigned int killed : 1; // killed by kill() function
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;
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;
};
union t_creaturflags2
{
uint32_t whole;
naked_creaturflags2 bits;
};
/*
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;
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;
}
};
*/
/*
CREATURE
*/
//#pragma pack(push,4)
struct t_name
@ -536,70 +266,6 @@ struct t_name
bool has_name;
};
struct t_skill
{
uint16_t id;
uint32_t experience;
uint16_t rating;
};
struct t_job
{
bool active;
uint8_t jobId;
};
struct t_like
{
int16_t type;
int16_t itemClass;
int16_t itemIndex;
t_matglossPair material;
bool active;
};
//#pragma pack(pop)
#define NUM_CREATURE_TRAITS 30
#define NUM_CREATURE_LABORS 102
struct t_creature
{
uint32_t origin;
uint16_t x;
uint16_t y;
uint16_t z;
uint32_t type;
t_creaturflags1 flags1;
t_creaturflags2 flags2;
t_name name;
t_name squad_name;
t_name artifact_name;
uint8_t profession;
char custom_profession[128];
// enabled labors
uint8_t labors[NUM_CREATURE_LABORS];
// personality traits
uint16_t traits[NUM_CREATURE_TRAITS];
uint8_t numSkills;
t_skill skills[256];
/*
//string last_name;
string current_job;
*/
uint8_t numLikes;
t_like likes[32];
t_job current_job;
int16_t mood;
uint32_t happiness;
uint32_t id;
uint32_t agility;
uint32_t strength;
uint32_t toughness;
uint32_t money;
int32_t squad_leader_id;
uint8_t sex;
uint32_t pregnancy_timer; //Countdown timer to giving birth
int32_t blood_max;
int32_t blood_current;
uint32_t bleed_rate;
};
//raw
struct t_item_df40d
{
@ -695,165 +361,6 @@ struct t_itemType
char name[128];
};
enum e_traffic
{
traffic_normal,
traffic_low,
traffic_high,
traffic_restricted
};
enum e_designation
{
designation_no,
designation_default, // dig walls, remove stairs and ramps, gather plants, fell trees
designation_ud_stair, // dig up/down stairs
designation_channel, // dig a channel
designation_ramp, // dig ramp out of a wall
designation_d_stair, // dig a stair down
designation_u_stair, // dig a stair up
designation_7 // whatever
};
enum e_liquidtype
{
liquid_water,
liquid_magma
};
struct naked_designation
{
unsigned int flow_size : 3; // how much liquid is here?
unsigned int pile : 1; // stockpile?
/*
* All the different dig designations... needs more info, probably an enum
*/
e_designation dig : 3;
unsigned int smooth : 2;
unsigned int hidden : 1;
/*
* This one is rather involved, but necessary to retrieve the base layer matgloss index
* see http://www.bay12games.com/forum/index.php?topic=608.msg253284#msg253284 for details
*/
unsigned int geolayer_index :4;
unsigned int light : 1;
unsigned int subterranean : 1; // never seen the light of day?
unsigned int skyview : 1; // sky is visible now, it rains in here when it rains
/*
* Probably similar to the geolayer_index. Only with a different set of offsets and different data.
* we don't use this yet
*/
unsigned int biome : 4;
/*
* 0 = water
* 1 = magma
*/
e_liquidtype liquid_type : 1;
unsigned int water_table : 1; // srsly. wtf?
unsigned int rained : 1; // does this mean actual rain (as in the blue blocks) or a wet tile?
e_traffic traffic : 2; // needs enum
unsigned int flow_forbid : 1; // what?
unsigned int liquid_static : 1;
unsigned int moss : 1;// I LOVE MOSS
unsigned int feature_present : 1; // another wtf... is this required for magma pipes to work?
unsigned int liquid_character : 2; // those ripples on streams?
};
union t_designation
{
uint32_t whole;
naked_designation bits;
};
// occupancy flags (rat,dwarf,horse,built wall,not build wall,etc)
struct naked_occupancy
{
unsigned int building : 3;// building type... should be an enum?
// 7 = door
unsigned int unit : 1;
unsigned int unit_grounded : 1;
unsigned int item : 1;
// splatter. everyone loves splatter.
unsigned int mud : 1;
unsigned int vomit :1;
unsigned int broken_arrows_color :4;
unsigned int blood_g : 1;
unsigned int blood_g2 : 1;
unsigned int blood_b : 1;
unsigned int blood_b2 : 1;
unsigned int blood_y : 1;
unsigned int blood_y2 : 1;
unsigned int blood_m : 1;
unsigned int blood_m2 : 1;
unsigned int blood_c : 1;
unsigned int blood_c2 : 1;
unsigned int blood_w : 1;
unsigned int blood_w2 : 1;
unsigned int blood_o : 1;
unsigned int blood_o2 : 1;
unsigned int slime : 1;
unsigned int slime2 : 1;
unsigned int blood : 1;
unsigned int blood2 : 1;
unsigned int broken_arrows_variant : 1;
unsigned int snow : 1;
};
struct naked_occupancy_grouped
{
unsigned int building : 3;// building type... should be an enum?
// 7 = door
unsigned int unit : 1;
unsigned int unit_grounded : 1;
unsigned int item : 1;
// splatter. everyone loves splatter.
unsigned int splatter : 26;
};
union t_occupancy
{
uint32_t whole;
naked_occupancy bits;
naked_occupancy_grouped unibits;
};
// map block flags
struct naked_blockflags
{
unsigned int designated : 1;// designated for jobs (digging and stuff like that)
unsigned int unk_1 : 1; // possibly related to the designated flag
// two flags required for liquid flow. no idea why
unsigned int liquid_1 : 1;
unsigned int liquid_2 : 1;
unsigned int unk_2: 28; // rest of the flags is completely unknown
// there's a possibility that this flags field is shorter than 32 bits
};
union t_blockflags
{
uint32_t whole;
naked_blockflags bits;
};
typedef int16_t tiletypes40d [16][16];
typedef DFHack::t_designation designations40d [16][16];
typedef DFHack::t_occupancy occupancies40d [16][16];
typedef uint8_t biome_indices40d [16];
typedef struct
{
tiletypes40d tiletypes;
designations40d designation;
occupancies40d occupancy;
// really a '7', but I use 8 to make it neater :)
biome_indices40d biome_indices;
uint32_t origin; // the address where it came from
t_blockflags blockflags;
} mapblock40d;
struct t_viewscreen
{
int32_t type;

@ -6,6 +6,315 @@
#include "Export.h"
namespace DFHack
{
/*
bits:
0 Can the dwarf move or are they waiting for their movement timer
1 Dead (might also be set for incoming/leaving critters that are alive)
2 Currently in mood
3 Had a mood
4 "marauder" -- wide class of invader/inside creature attackers
5 Drowning
6 Active merchant
7 "forest" (used for units no longer linked to merchant/diplomacy, they just try to leave mostly)
8 Left (left the map)
9 Rider
10 Incoming
11 Diplomat
12 Zombie
13 Skeleton
14 Can swap tiles during movement (prevents multiple swaps)
15 On the ground (can be conscious)
16 Projectile
17 Active invader (for organized ones)
18 Hidden in ambush
19 Invader origin (could be inactive and fleeing)
20 Will flee if invasion turns around
21 Active marauder/invader moving inward
22 Marauder resident/invader moving in all the way
23 Check against flows next time you get a chance
24 Ridden
25 Caged
26 Tame
27 Chained
28 Royal guard
29 Fortress guard
30 Suppress wield for beatings/etc
31 Is an important historical figure
*/
struct naked_creaturflags1
{
unsigned int move_state : 1; // Can the dwarf move or are they waiting for their movement timer
unsigned int dead : 1; // might also be set for incoming/leaving critters that are alive
unsigned int has_mood : 1; // Currently in mood
unsigned int had_mood : 1; // Had a mood
unsigned int marauder : 1; // wide class of invader/inside creature attackers
unsigned int drowning : 1;
unsigned int merchant : 1; // active merchant
unsigned int forest : 1; // used for units no longer linked to merchant/diplomacy, they just try to leave mostly
unsigned int left : 1; // left the map
unsigned int rider : 1;
unsigned int incoming : 1;
unsigned int diplomat : 1;
unsigned int zombie : 1;
unsigned int skeleton : 1;
unsigned int can_swap : 1; // Can swap tiles during movement (prevents multiple swaps)
unsigned int on_ground : 1; // can be conscious
unsigned int projectile : 1;
unsigned int active_invader : 1; // for organized ones
unsigned int hidden_in_ambush : 1;
unsigned int invader_origin : 1; // could be inactive and fleeing
unsigned int coward : 1; // Will flee if invasion turns around
unsigned int hidden_ambusher : 1; // maybe
unsigned int invades : 1; // Active marauder/invader moving inward
unsigned int check_flows : 1; // Check against flows next time you get a chance
// 0100 0000 - 8000 0000
unsigned int ridden : 1;
unsigned int caged : 1;
unsigned int tame : 1;
unsigned int chained : 1;
unsigned int royal_guard : 1;
unsigned int fortress_guard : 1;
unsigned int suppress_wield : 1; // Suppress wield for beatings/etc
unsigned int important_historical_figure : 1; // Is an important historical figure
};
union t_creaturflags1
{
uint32_t whole;
naked_creaturflags1 bits;
};
/*
bits:
0 Swimming
1 Play combat for sparring
2 Do not notify about level gains (for embark etc)
3 Unused
4 Nerves calculated
5 Body part info calculated
6 Is important historical figure (slight variation)
7 Has been killed by kill function (slightly different from dead, not necessarily violent death)
8 Must be forgotten by forget function (just cleanup)
9 Must be deleted (cleanup)
10 Recently forgotten (cleanup)
11 Offered for trade
12 Trade resolved
13 Has breaks
14 Gutted
15 Circulatory spray
16 Locked in for trading (it's a projectile on the other set of flags, might be what the flying was)
17 Marked for slaughter
18 Underworld creature
19 Current resident
20 Marked for special cleanup as unused load from unit block on disk
21 Insulation from clothing calculated
22 Uninvited guest
23 Visitor
24 Inventory order calculated
25 Vision -- have good part
26 Vision -- have damaged part
27 Vision -- have missing part
28 Breathing -- have good part
29 Breathing -- having a problem
30 Roaming wilderness population source
31 Roaming wilderness population source -- not a map feature
*/
struct naked_creaturflags2
{
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; // slight variation
unsigned int killed : 1; // killed by kill() function
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;
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;
};
union t_creaturflags2
{
uint32_t whole;
naked_creaturflags2 bits;
};
/*
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;
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;
}
};
*/
struct t_skill
{
uint16_t id;
uint32_t experience;
uint16_t rating;
};
struct t_job
{
bool active;
uint8_t jobId;
};
struct t_like
{
int16_t type;
int16_t itemClass;
int16_t itemIndex;
t_matglossPair material;
bool active;
};
// FIXME: define in Memory.xml instead?
#define NUM_CREATURE_TRAITS 30
#define NUM_CREATURE_LABORS 102
struct t_creature
{
uint32_t origin;
uint16_t x;
uint16_t y;
uint16_t z;
uint32_t type;
t_creaturflags1 flags1;
t_creaturflags2 flags2;
t_name name;
t_name squad_name;
t_name artifact_name;
uint8_t profession;
char custom_profession[128];
// enabled labors
uint8_t labors[NUM_CREATURE_LABORS];
// personality traits
uint16_t traits[NUM_CREATURE_TRAITS];
uint8_t numSkills;
t_skill skills[256];
uint8_t numLikes;
t_like likes[32];
t_job current_job;
int16_t mood;
uint32_t happiness;
uint32_t id;
uint32_t agility;
uint32_t strength;
uint32_t toughness;
uint32_t money;
int32_t squad_leader_id;
uint8_t sex;
uint32_t pregnancy_timer; //Countdown timer to giving birth
int32_t blood_max;
int32_t blood_current;
uint32_t bleed_rate;
};
class APIPrivate;
struct t_creature;
class DFHACK_EXPORT Creatures
@ -23,7 +332,7 @@ namespace DFHack
const uint16_t x2, const uint16_t y2,const uint16_t z2);
bool ReadCreature(const int32_t index, t_creature & furball);
/// write labors of a creature (for Dwarf Therapist)
//bool WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]);
bool WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]);
private:
struct Private;

@ -1,12 +1,194 @@
/*******************************************************************************
M A P S
Read and write DF's map
*******************************************************************************/
#ifndef CL_MOD_MAPS
#define CL_MOD_MAPS
#include "Export.h"
/*
* Maps: Read and write DF's map
*/
namespace DFHack
{
/***************************************************************************
T Y P E S
***************************************************************************/
struct t_vein
{
uint32_t vtable;
int32_t type;
int16_t assignment[16];
uint32_t flags;
uint32_t address_of; // this is NOT part of the DF vein, but an address of the vein as seen by DFhack.
};
// stores what tiles should appear when the ice melts
struct t_frozenliquidvein
{
uint32_t vtable;
int16_t tiles[16][16];
};
enum e_traffic
{
traffic_normal,
traffic_low,
traffic_high,
traffic_restricted
};
enum e_designation
{
designation_no,
designation_default, // dig walls, remove stairs and ramps, gather plants, fell trees
designation_ud_stair, // dig up/down stairs
designation_channel, // dig a channel
designation_ramp, // dig ramp out of a wall
designation_d_stair, // dig a stair down
designation_u_stair, // dig a stair up
designation_7 // whatever
};
enum e_liquidtype
{
liquid_water,
liquid_magma
};
struct naked_designation
{
unsigned int flow_size : 3; // how much liquid is here?
unsigned int pile : 1; // stockpile?
/*
* All the different dig designations... needs more info, probably an enum
*/
e_designation dig : 3;
unsigned int smooth : 2;
unsigned int hidden : 1;
/*
* This one is rather involved, but necessary to retrieve the base layer matgloss index
* see http://www.bay12games.com/forum/index.php?topic=608.msg253284#msg253284 for details
*/
unsigned int geolayer_index :4;
unsigned int light : 1;
unsigned int subterranean : 1; // never seen the light of day?
unsigned int skyview : 1; // sky is visible now, it rains in here when it rains
/*
* Probably similar to the geolayer_index. Only with a different set of offsets and different data.
* we don't use this yet
*/
unsigned int biome : 4;
/*
* 0 = water
* 1 = magma
*/
e_liquidtype liquid_type : 1;
unsigned int water_table : 1; // srsly. wtf?
unsigned int rained : 1; // does this mean actual rain (as in the blue blocks) or a wet tile?
e_traffic traffic : 2; // needs enum
unsigned int flow_forbid : 1; // what?
unsigned int liquid_static : 1;
unsigned int moss : 1;// I LOVE MOSS
unsigned int feature_present : 1; // another wtf... is this required for magma pipes to work?
unsigned int liquid_character : 2; // those ripples on streams?
};
union t_designation
{
uint32_t whole;
naked_designation bits;
};
// occupancy flags (rat,dwarf,horse,built wall,not build wall,etc)
struct naked_occupancy
{
unsigned int building : 3;// building type... should be an enum?
// 7 = door
unsigned int unit : 1;
unsigned int unit_grounded : 1;
unsigned int item : 1;
// splatter. everyone loves splatter.
unsigned int mud : 1;
unsigned int vomit :1;
unsigned int broken_arrows_color :4;
unsigned int blood_g : 1;
unsigned int blood_g2 : 1;
unsigned int blood_b : 1;
unsigned int blood_b2 : 1;
unsigned int blood_y : 1;
unsigned int blood_y2 : 1;
unsigned int blood_m : 1;
unsigned int blood_m2 : 1;
unsigned int blood_c : 1;
unsigned int blood_c2 : 1;
unsigned int blood_w : 1;
unsigned int blood_w2 : 1;
unsigned int blood_o : 1;
unsigned int blood_o2 : 1;
unsigned int slime : 1;
unsigned int slime2 : 1;
unsigned int blood : 1;
unsigned int blood2 : 1;
unsigned int broken_arrows_variant : 1;
unsigned int snow : 1;
};
struct naked_occupancy_grouped
{
unsigned int building : 3;// building type... should be an enum?
// 7 = door
unsigned int unit : 1;
unsigned int unit_grounded : 1;
unsigned int item : 1;
// splatter. everyone loves splatter.
unsigned int splatter : 26;
};
union t_occupancy
{
uint32_t whole;
naked_occupancy bits;
naked_occupancy_grouped unibits;
};
// map block flags
struct naked_blockflags
{
unsigned int designated : 1;// designated for jobs (digging and stuff like that)
unsigned int unk_1 : 1; // possibly related to the designated flag
// two flags required for liquid flow. no idea why
unsigned int liquid_1 : 1;
unsigned int liquid_2 : 1;
unsigned int unk_2: 28; // rest of the flags is completely unknown
// there's a possibility that this flags field is shorter than 32 bits
};
union t_blockflags
{
uint32_t whole;
naked_blockflags bits;
};
typedef int16_t tiletypes40d [16][16];
typedef DFHack::t_designation designations40d [16][16];
typedef DFHack::t_occupancy occupancies40d [16][16];
typedef uint8_t biome_indices40d [16];
typedef struct
{
tiletypes40d tiletypes;
designations40d designation;
occupancies40d occupancy;
// really a '7', but I use 8 to make it neater :)
biome_indices40d biome_indices;
uint32_t origin; // the address where it came from
t_blockflags blockflags;
} mapblock40d;
/***************************************************************************
C L I E N T M O D U L E
***************************************************************************/
class APIPrivate;
struct t_viewscreen;
class DFHACK_EXPORT Maps

@ -0,0 +1,35 @@
#ifndef CL_MOD_TRANSLATION
#define CL_MOD_TRANSLATION
/*
* DF translation tables and name translation
*/
#include "Export.h"
namespace DFHack
{
struct APIPrivate;
typedef std::vector< std::vector<std::string> > DFDict;
typedef struct
{
DFDict translations;
DFDict foreign_languages;
} Dicts;
class DFHACK_EXPORT Translation
{
public:
Translation(APIPrivate * d);
~Translation();
bool Start();
bool Finish();
// Get pointer to the two dictionary structures
Dicts * getDicts();
// translate a name using the loaded dictionaries
std::string TranslateName(const DFHack::t_name& name, bool inEnglish = true);
private:
struct Private;
Private *d;
};
}
#endif

@ -0,0 +1,45 @@
#ifndef CL_MOD_VEGETATION
#define CL_MOD_VEGETATION
/*
* DF vegetation - stuff that grows and gets cut down or trampled by dwarves
*/
#include "Export.h"
namespace DFHack
{
/*
types
0: sapling?, dead sapling?, grown maple tree
1: willow sapling?
2: shrub
3: shrub near water!
*/
struct t_tree
{
uint16_t type; // +0x6C
uint16_t material; // +0x6E
uint16_t x; // +0x70
uint16_t y; // +0x72
uint16_t z; // +0x74
/*
junk_fill<0xA> junk;
uint32_t flags; // +0x80 maybe?
*/
uint32_t address;
};
struct APIPrivate;
class DFHACK_EXPORT Vegetation
{
public:
Vegetation(APIPrivate * d);
~Vegetation();
bool Start(uint32_t & numTrees);
bool Read (const uint32_t index, t_tree & shrubbery);
bool Finish();
private:
struct Private;
Private *d;
};
}
#endif

@ -25,17 +25,19 @@ distribution.
#include "DFCommonInternal.h"
#include "../private/APIPrivate.h"
// we connect to those
#include <shms.h>
#include <mod-core.h>
#include <mod-creature2010.h>
#include "modules/Creatures.h"
#include "DFVector.h"
#include "DFMemInfo.h"
#include "DFProcess.h"
#include "DFError.h"
#include "DFTypes.h"
// we connect to those
#include <shms.h>
#include <mod-core.h>
#include <mod-creature2010.h>
#include "modules/Creatures.h"
#define SHMCREATURESHDR ((Creatures2010::shm_creature_hdr *)d->d->shm_start)
#define SHMCMD(num) ((shm_cmd *)d->d->shm_start)[num]->pingpong
#define SHMHDR ((shm_core_hdr *)d->d->shm_start)
@ -67,6 +69,7 @@ Creatures::Creatures(APIPrivate* _d)
creatures.creature_vector = minfo->getAddress ("creature_vector");
creatures.creature_pos_offset = minfo->getOffset ("creature_position");
creatures.creature_profession_offset = minfo->getOffset ("creature_profession");
creatures.creature_custom_profession_offset = minfo->getOffset ("creature_custom_profession");
creatures.creature_race_offset = minfo->getOffset ("creature_race");
creatures.creature_flags1_offset = minfo->getOffset ("creature_flags1");
creatures.creature_flags2_offset = minfo->getOffset ("creature_flags2");
@ -76,6 +79,10 @@ Creatures::Creatures(APIPrivate* _d)
creatures.creature_labors_offset = minfo->getOffset ("creature_labors");
creatures.creature_happiness_offset = minfo->getOffset ("creature_happiness");
creatures.creature_artifact_name_offset = minfo->getOffset("creature_artifact_name");
creatures.creature_soul_vector_offset = minfo->getOffset("creature_soul_vector");
// soul offsets
creatures.soul_skills_vector_offset = minfo->getOffset("soul_skills_vector");
// name offsets for the creature module
creatures.name_firstname_offset = minfo->getOffset("name_firstname");
@ -153,26 +160,14 @@ bool Creatures::ReadCreature (const int32_t index, t_creature & furball)
//d->readName(furball.squad_name, temp + offs.creature_squad_name_offset);
d->d->readName(furball.artifact_name, temp + offs.creature_artifact_name_offset);
// custom profession
//fill_char_buf (furball.custom_profession, d->p->readSTLString (temp + offs.creature_custom_profession_offset));
fill_char_buf (furball.custom_profession, g_pProcess->readSTLString (temp + offs.creature_custom_profession_offset));
// labors
g_pProcess->read (temp + offs.creature_labors_offset, NUM_CREATURE_LABORS, furball.labors);
// traits
//g_pProcess->read (temp + offs.creature_traits_offset, sizeof (uint16_t) * NUM_CREATURE_TRAITS, (uint8_t *) &furball.traits);
// learned skills
/*
DfVector skills (d->p, temp + offs.creature_skills_offset, 4 );
furball.numSkills = skills.getSize();
for (uint32_t i = 0; i < furball.numSkills;i++)
{
uint32_t temp2 = * (uint32_t *) skills[i];
//skills.read(i, (uint8_t *) &temp2);
// a byte: this gives us 256 skills maximum.
furball.skills[i].id = g_pProcess->readByte (temp2);
furball.skills[i].rating = g_pProcess->readByte (temp2 + 4);
furball.skills[i].experience = g_pProcess->readWord (temp2 + 8);
}
*/
// profession
furball.profession = g_pProcess->readByte (temp + offs.creature_profession_offset);
// current job HACK: the job object isn't cleanly represented here
@ -219,6 +214,20 @@ bool Creatures::ReadCreature (const int32_t index, t_creature & furball)
g_pProcess->readDWord(temp + offs.creature_bleed_offset, furball.bleed_rate);
*/
// enum soul pointer vector
DfVector souls(g_pProcess,temp + offs.creature_soul_vector_offset,4);
// get first soul's skills
DfVector skills(g_pProcess, *(uint32_t *)souls.at(0) + offs.soul_skills_vector_offset,4 );
furball.numSkills = skills.getSize();
for (uint32_t i = 0; i < furball.numSkills;i++)
{
uint32_t temp2 = * (uint32_t *) skills[i];
//skills.read(i, (uint8_t *) &temp2);
// a byte: this gives us 256 skills maximum.
furball.skills[i].id = g_pProcess->readByte (temp2);
furball.skills[i].rating = g_pProcess->readByte (temp2 + 4);
furball.skills[i].experience = g_pProcess->readWord (temp2 + 8);
}
return true;
}
@ -271,14 +280,14 @@ int32_t Creatures::ReadCreatureInBox (int32_t index, t_creature & furball,
}
/*
bool API::WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS])
bool Creatures::WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS])
{
if(!d->creaturesInited) return false;
if(!d->Started) return false;
uint32_t temp = * (uint32_t *) d->p_cre->at (index);
WriteRaw(temp + d->creatures.creature_labors_offset, NUM_CREATURE_LABORS, labors);
g_pProcess->write(temp + d->creatures.creature_labors_offset, NUM_CREATURE_LABORS, labors);
}
*/
/*
bool API::getCurrentCursorCreature(uint32_t & creature_index)
{

@ -53,7 +53,6 @@ struct Maps::Private
APIPrivate *d;
bool Inited;
bool Started;
//uint32_t biome_stuffs;
vector<uint16_t> v_geology[eBiomeCount];
};

@ -0,0 +1,197 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include "DFCommonInternal.h"
#include "../private/APIPrivate.h"
#include "modules/Translation.h"
#include "DFMemInfo.h"
#include "DFProcess.h"
#include "DFVector.h"
#include "DFTypes.h"
#include "modules/Translation.h"
using namespace DFHack;
struct Translation::Private
{
uint32_t genericAddress;
uint32_t transAddress;
uint32_t word_table_offset;
uint32_t sizeof_string;
// translation
Dicts dicts;
APIPrivate *d;
bool Inited;
bool Started;
};
Translation::Translation(APIPrivate * d_)
{
d = new Private;
d->d = d_;
d->Inited = d->Started = false;
memory_info * mem = d->d->offset_descriptor;
d->genericAddress = mem->getAddress ("language_vector");
d->transAddress = mem->getAddress ("translation_vector");
d->word_table_offset = mem->getOffset ("word_table");
d->sizeof_string = mem->getHexValue ("sizeof_string");
d->Inited = true;
}
Translation::~Translation()
{
if(d->Started)
Finish();
delete d;
}
bool Translation::Start()
{
if(!d->Inited)
return false;
Process * p = d->d->p;
DfVector genericVec (p, d->genericAddress, 4);
DfVector transVec (p, d->transAddress, 4);
DFDict & translations = d->dicts.translations;
DFDict & foreign_languages = d->dicts.foreign_languages;
translations.resize(10);
for (uint32_t i = 0;i < genericVec.getSize();i++)
{
uint32_t genericNamePtr = * (uint32_t *) genericVec.at (i);
for(int i=0; i<10;i++)
{
string word = p->readSTLString (genericNamePtr + i * d->sizeof_string);
translations[i].push_back (word);
}
}
foreign_languages.resize(transVec.getSize());
for (uint32_t i = 0; i < transVec.getSize();i++)
{
uint32_t transPtr = * (uint32_t *) transVec.at (i);
//string transName = d->p->readSTLString (transPtr);
DfVector trans_names_vec (p, transPtr + d->word_table_offset, 4);
for (uint32_t j = 0;j < trans_names_vec.getSize();j++)
{
uint32_t transNamePtr = * (uint32_t *) trans_names_vec.at (j);
string name = p->readSTLString (transNamePtr);
foreign_languages[i].push_back (name);
}
}
d->Started = true;
return true;
}
bool Translation::Finish()
{
d->dicts.foreign_languages.clear();
d->dicts.translations.clear();
d->Started = false;
return true;
}
Dicts * Translation::getDicts()
{
assert(d->Started);
if(d->Started)
return &d->dicts;
return 0;
}
string Translation::TranslateName(const t_name &name, bool inEnglish)
{
string out;
assert (d->Started);
map<string, vector<string> >::const_iterator it;
if(!inEnglish)
{
if(name.words[0] >=0 || name.words[1] >=0)
{
if(name.words[0]>=0) out.append(d->dicts.foreign_languages[name.language][name.words[0]]);
if(name.words[1]>=0) out.append(d->dicts.foreign_languages[name.language][name.words[1]]);
out[0] = toupper(out[0]);
}
if(name.words[5] >=0)
{
string word;
for(int i=2;i<=5;i++)
if(name.words[i]>=0) word.append(d->dicts.foreign_languages[name.language][name.words[i]]);
word[0] = toupper(word[0]);
if(out.length() > 0) out.append(" ");
out.append(word);
}
if(name.words[6] >=0)
{
string word;
word.append(d->dicts.foreign_languages[name.language][name.words[6]]);
word[0] = toupper(word[0]);
if(out.length() > 0) out.append(" ");
out.append(word);
}
}
else
{
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[1]>=0) out.append(d->dicts.translations[name.parts_of_speech[1]+1][name.words[1]]);
out[0] = toupper(out[0]);
}
if(name.words[5] >=0)
{
if(out.length() > 0)
out.append(" the");
else
out.append("The");
string word;
for(int i=2;i<=5;i++)
{
if(name.words[i]>=0)
{
word = d->dicts.translations[name.parts_of_speech[i]+1][name.words[i]];
word[0] = toupper(word[0]);
out.append(" " + word);
}
}
}
if(name.words[6] >=0)
{
if(out.length() > 0)
out.append(" of");
else
out.append("Of");
string word;
word.append(d->dicts.translations[name.parts_of_speech[6]+1][name.words[6]]);
word[0] = toupper(word[0]);
out.append(" " + word);
}
}
return out;
}

@ -0,0 +1,96 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include "DFCommonInternal.h"
#include "../private/APIPrivate.h"
#include "modules/Translation.h"
#include "DFMemInfo.h"
#include "DFProcess.h"
#include "DFVector.h"
#include "DFTypes.h"
#include "modules/Vegetation.h"
using namespace DFHack;
struct Vegetation::Private
{
uint32_t vegetation_vector;
uint32_t tree_desc_offset;
// translation
DfVector * p_veg;
APIPrivate *d;
bool Inited;
bool Started;
};
Vegetation::Vegetation(APIPrivate * d_)
{
d = new Private;
d->d = d_;
d->Inited = d->Started = false;
memory_info * mem = d->d->offset_descriptor;
d->vegetation_vector = mem->getAddress ("vegetation_vector");
d->tree_desc_offset = mem->getOffset ("tree_desc_offset");
d->Inited = true;
}
Vegetation::~Vegetation()
{
if(d->Started)
Finish();
delete d;
}
bool Vegetation::Start(uint32_t & numplants)
{
d->p_veg = new DfVector (g_pProcess, d->vegetation_vector, 4);
numplants = d->p_veg->getSize();
d->Started = true;
return true;
}
bool Vegetation::Read (const uint32_t index, t_tree & shrubbery)
{
if(!d->Started)
return false;
// read pointer from vector at position
uint32_t temp = * (uint32_t *) d->p_veg->at (index);
// read from memory
g_pProcess->read (temp + d->tree_desc_offset, sizeof (t_tree), (uint8_t *) &shrubbery);
shrubbery.address = temp;
return true;
}
bool Vegetation::Finish()
{
if(d->p_veg)
{
delete d->p_veg;
d->p_veg = 0;
}
d->Started = false;
return true;
}

@ -36,8 +36,10 @@ namespace DFHack
class Position;
class Maps;
class Creatures;
class Translation;
class ProcessEnumerator;
class Process;
class Vegetation;
class memory_info;
struct t_name;
class APIPrivate
@ -67,6 +69,8 @@ namespace DFHack
Position * position;
Gui * gui;
Materials * materials;
Translation * translation;
Vegetation * vegetation;
/*
uint32_t item_material_offset;

@ -37,6 +37,7 @@ typedef struct
uint32_t creature_vector;
uint32_t creature_pos_offset;
uint32_t creature_profession_offset;
uint32_t creature_custom_profession_offset;
uint32_t creature_race_offset;
uint32_t creature_flags1_offset;
uint32_t creature_flags2_offset;
@ -46,6 +47,9 @@ typedef struct
uint32_t creature_labors_offset;
uint32_t creature_happiness_offset;
uint32_t creature_artifact_name_offset;
uint32_t creature_soul_vector_offset;
// soul offsets
uint32_t soul_skills_vector_offset;
// name offsets (needed for reading creature names)
uint32_t name_firstname_offset;
uint32_t name_nickname_offset;

@ -57,6 +57,10 @@ TARGET_LINK_LIBRARIES(dfsuspend dfhack)
ADD_EXECUTABLE(dfvecc veccheck.cpp)
TARGET_LINK_LIBRARIES(dfvecc dfhack)
# treedump - dump them trees!
ADD_EXECUTABLE(dftreedump treedump.cpp)
TARGET_LINK_LIBRARIES(dftreedump dfhack)
# catsplosion - Makes every cat pregnant, and almost due...
# Author: Zhentar
# ADD_EXECUTABLE(dfcatsplosion catsplosion.cpp)

@ -12,96 +12,7 @@ using namespace std;
#include <DFTypes.h>
#include <DFHackAPI.h>
#include <DFMemInfo.h>
/*
address = absolute address of dump start
length = length in lines. 1 line = 16 bytes
*/
void hexdump (DFHack::API& DF, uint32_t address, uint32_t length)
{
char *buf = new char[length * 16];
DF.ReadRaw(address, length * 16, (uint8_t *) buf);
for (int i = 0; i < length; i++)
{
// leading offset
cout << "0x" << hex << setw(4) << i*16 << " ";
// groups
for(int j = 0; j < 4; j++)
{
// bytes
for(int k = 0; k < 4; k++)
{
int idx = i * 16 + j * 4 + k;
cout << hex << setw(2) << int(static_cast<unsigned char>(buf[idx])) << " ";
}
cout << " ";
}
cout << endl;
}
delete buf;
}
void interleave_hex (DFHack::API& DF, vector < uint32_t > & addresses, uint32_t length)
{
vector <char * > bufs;
for(int counter = 0; counter < addresses.size(); counter ++)
{
char * buf = new char[length * 16];
DF.ReadRaw(addresses[counter], length * 16, (uint8_t *) buf);
bufs.push_back(buf);
}
cout << setfill('0');
// output a header
cout << "line offset ";
for (int obj = 0; obj < addresses.size(); obj++)
{
cout << "0x" << hex << setw(9) << addresses[obj] << " ";
}
cout << endl;
for(int offs = 0 ; offs < length * 16; offs += 4)
{
if((!(offs % 16)) && offs != 0)
{
cout << endl;
}
cout << setfill(' ');
cout << dec << setw(4) << offs/4 << " ";
cout << setfill('0');
cout << "0x" << hex << setw(4) << offs << " ";
for (int object = 0; object < bufs.size(); object++)
{
// bytes
for(int k = 0; k < 4; k++)
{
uint8_t data = bufs[object][offs + k];
cout << hex << setw(2) << int(static_cast<unsigned char>(data)) << " ";
}
cout << " ";
}
cout << endl;
}
for(int counter = 0; counter < addresses.size(); counter ++)
{
delete bufs[counter];
}
}
template <typename T>
void print_bits ( T val, std::ostream& out )
{
T n_bits = sizeof ( val ) * CHAR_BIT;
for ( unsigned i = 0; i < n_bits; ++i ) {
out<< !!( val & 1 ) << " ";
val >>= 1;
}
}
#include "miscutils.h"
int main (int argc,const char* argv[])
{

@ -12,6 +12,7 @@ using namespace std;
#include <DFMemInfo.h>
#include <modules/Materials.h>
#include <modules/Creatures.h>
#include <modules/Translation.h>
template <typename T>
void print_bits ( T val, std::ostream& out )
@ -165,14 +166,17 @@ void printCreature(DFHack::API & DF, const DFHack::t_creature & creature)
cout << ", nick name: " << creature.name.nickname;
addendl = true;
}
/*
string transName = DF.TranslateName(creature.name,englishWords,foreignWords,false);
DFHack::Translation *Tran = DF.getTranslation();
DFHack::memory_info *mem = DF.getMemoryInfo();
string transName = Tran->TranslateName(creature.name,false);
if(!transName.empty())
{
cout << ", trans name: " << transName;
addendl=true;
}
*/
/*
cout << ", likes: ";
for(uint32_t i = 0;i<creature.numLikes; i++)
@ -189,11 +193,12 @@ void printCreature(DFHack::API & DF, const DFHack::t_creature & creature)
addendl = false;
}
cout << "profession: " << mem->getProfession(creature.profession) << "(" << (int) creature.profession << ")";
/*
if(creature.custom_profession[0])
{
cout << ", custom profession: " << creature.custom_profession;
}
/*
if(creature.current_job.active)
{
cout << ", current job: " << mem->getJob(creature.current_job.jobId);
@ -227,15 +232,37 @@ void printCreature(DFHack::API & DF, const DFHack::t_creature & creature)
*/
cout << endl;
/*
//skills
for(unsigned int i = 0; i < creature.skills.size();i++){
if(i > 0){
cout << "Skills" << endl;
for(unsigned int i = 0; i < creature.numSkills;i++)
{
if(i > 0)
{
cout << ", ";
}
cout << creature.skills[i].name << ": " << creature.skills[i].rating;
cout << mem->getSkill(creature.skills[i].id) << ": " << creature.skills[i].rating;
}
*/
cout << endl;
// labors
cout << "Labors" << endl;
for(unsigned int i = 0; i < NUM_CREATURE_LABORS;i++)
{
if(!creature.labors[i])
continue;
string laborname;
try
{
laborname = mem->getLabor(i);
}
catch(exception &)
{
break;
}
cout << laborname << ", ";
}
cout << endl;
/*
* FLAGS 1
*/
@ -325,6 +352,7 @@ int main (void)
DFHack::Creatures * Creatures = DF.getCreatures();
DFHack::Materials * Materials = DF.getMaterials();
DFHack::Translation * Tran = DF.getTranslation();
uint32_t numCreatures;
if(!Creatures->Start(numCreatures))
@ -358,19 +386,19 @@ int main (void)
cerr << "Can't get the creature types." << endl;
return 1;
}
/*
if(!DF.InitReadNameTables(englishWords,foreignWords))
if(!Tran->Start())
{
cerr << "Can't get name tables" << endl;
return 1;
}
*/
//DF.InitViewAndCursor();
for(uint32_t i = 0; i < numCreatures; i++)
{
DFHack::t_creature temp;
Creatures->ReadCreature(i,temp);
//if(string(creaturestypes[temp.type].id) == "DWARF")
if(string(creaturestypes[temp.type].id) == "DWARF")
{
cout << "index " << i << " ";
printCreature(DF,temp);

@ -15,30 +15,6 @@ using namespace std;
#include <DFVector.h>
#include <modules/Materials.h>
void DumpObjStr0Vector (const char * name, DFHack::Process *p, uint32_t addr)
{
cout << "----==== " << name << " ====----" << endl;
DFHack::DfVector vect(p,addr,4);
for(int i = 0; i < vect.getSize();i++)
{
uint32_t addr = *(uint32_t *) vect[i];
cout << p->readSTLString(addr) << endl;
}
cout << endl;
}
void DumpDWordVector (const char * name, DFHack::Process *p, uint32_t addr)
{
cout << "----==== " << name << " ====----" << endl;
DFHack::DfVector vect(p,addr,4);
for(int i = 0; i < vect.getSize();i++)
{
uint32_t number = *(uint32_t *) vect[i];
cout << number << endl;
}
cout << endl;
}
int main (int numargs, const char ** args)
{
uint32_t addr;
@ -65,33 +41,6 @@ int main (int numargs, const char ** args)
DFHack::memory_info* mem = DF.getMemoryInfo();
DFHack::Materials *Materials = DF.getMaterials();
//const vector<string> * names = mem->getClassIDMapping();
/*
DumpObjStr0Vector("Material templates",p, mem->getAddress("mat_templates"));
DumpObjStr0Vector("Inorganics",p, mem->getAddress("mat_inorganics"));
DumpObjStr0Vector("Organics - all",p, mem->getAddress("mat_organics_all"));
DumpObjStr0Vector("Organics - plants",p, mem->getAddress("mat_organics_plants"));
DumpDWordVector("Maybe map between all organics and plants",p, mem->getAddress("mat_unk1_numbers"));
DumpObjStr0Vector("Trees/wood",p, mem->getAddress("mat_organics_trees"));
DumpDWordVector("Maybe map between all organics and trees",p, mem->getAddress("mat_unk2_numbers"));
DumpObjStr0Vector("Body material templates",p, mem->getAddress("mat_body_material_templates"));
DumpObjStr0Vector("Body detail plans",p, mem->getAddress("mat_body_detail_plans"));
DumpObjStr0Vector("Bodies",p, mem->getAddress("mat_bodies"));
DumpObjStr0Vector("Bodygloss",p, mem->getAddress("mat_bodygloss"));
DumpObjStr0Vector("Creature variations",p, mem->getAddress("mat_creature_variations"));
*/
cout << "----==== Inorganic ====----" << endl;
vector<DFHack::t_matgloss> matgloss;
Materials->ReadInorganicMaterials (matgloss);

@ -12,18 +12,10 @@ using namespace std;
#include <DFHackAPI.h>
#include <DFMemInfo.h>
#include <DFProcess.h>
template <typename T>
void print_bits ( T val, std::ostream& out )
{
T n_bits = sizeof ( val ) * CHAR_BIT;
for ( unsigned i = 0; i < n_bits; ++i )
{
out<< !!( val & 1 ) << " ";
val >>= 1;
}
}
#include <modules/Materials.h>
#include <modules/Creatures.h>
#include <modules/Translation.h>
#include "miscutils.h"
vector< vector<string> > englishWords;
vector< vector<string> > foreignWords;
@ -33,10 +25,11 @@ vector<DFHack::t_matgloss> creaturestypes;
void printDwarves(DFHack::API & DF)
{
int dwarfCounter = 0;
DFHack::Creatures * c = DF.getCreatures();
for (uint32_t i = 0; i < numCreatures; i++)
{
DFHack::t_creature temp;
DF.ReadCreature(i, temp);
c->ReadCreature(i, temp);
string type = creaturestypes[temp.type].id;
if (type == "DWARF" && !temp.flags1.bits.dead && !temp.flags2.bits.killed)
{
@ -148,6 +141,7 @@ bool getDwarfSelection(DFHack::API & DF, DFHack::t_creature & toChange,string &
changeString = lastText;
return true;
}
bool waitTillChanged(DFHack::API &DF, int creatureToCheck, string changeValue, bool isName)
{
DFHack::DFWindow * w = DF.getWindow();
@ -313,9 +307,13 @@ bool setCursorToCreature(DFHack::API &DF)
int main (void)
{
DFHack::API DF("Memory.xml");
DFHack::Creatures *c;
DFHack::Materials *m;
try
{
DF.Attach();
c = DF.getCreatures();
}
catch (exception& e)
{
@ -328,15 +326,16 @@ int main (void)
DFHack::memory_info * mem = DF.getMemoryInfo();
if (!DF.ReadCreatureMatgloss(creaturestypes))
if (!m->ReadCreatureTypes(creaturestypes))
{
cerr << "Can't get the creature types." << endl;
return 1;
}
DF.InitReadNameTables(englishWords,foreignWords);
DF.InitReadCreatures(numCreatures);
DF.InitViewAndCursor();
c->Start(numCreatures);
// DF.InitViewAndCursor();
DFHack::Process * p = DF.getProcess();
DFHack::DFWindow * w = DF.getWindow();

@ -0,0 +1,107 @@
// Just show some position data
#include <iostream>
#include <iomanip>
#include <climits>
#include <integers.h>
#include <vector>
#include <sstream>
#include <ctime>
#include <cstdio>
using namespace std;
#include <DFTypes.h>
#include <DFHackAPI.h>
#include <DFProcess.h>
#include <DFMemInfo.h>
#include <DFVector.h>
#include <DFTypes.h>
#include <modules/Vegetation.h>
#include <modules/Materials.h>
#include <modules/Position.h>
#include "miscutils.h"
int main (int numargs, const char ** args)
{
uint32_t addr;
if (numargs == 2)
{
istringstream input (args[1],istringstream::in);
input >> std::hex >> addr;
}
DFHack::API DF("Memory.xml");
try
{
DF.Attach();
}
catch (exception& e)
{
cerr << e.what() << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
DFHack::Process* p = DF.getProcess();
DFHack::memory_info* mem = DF.getMemoryInfo();
DFHack::Position * pos = DF.getPosition();
DFHack::Vegetation * v = DF.getVegetation();
DFHack::Materials * mat = DF.getMaterials();
vector<DFHack::t_matgloss> organics;
mat->ReadOrganicMaterials(organics);
int32_t x,y,z;
pos->getCursorCoords(x,y,z);
uint32_t numVegs = 0;
v->Start(numVegs);
if(x == -30000)
{
cout << "----==== Trees ====----" << endl;
for(uint32_t i =0; i < numVegs; i++)
{
DFHack::t_tree tree;
v->Read(i,tree);
printf("%d/%d/%d, %d:%d\n",tree.x,tree.y,tree.z,tree.type,tree.material);
}
}
else
{
cout << "----==== Tree at "<< x << "/" << y << "/" << z << " ====----" << endl;
for(uint32_t i =0; i < numVegs; i++)
{
DFHack::t_tree tree;
v->Read(i,tree);
if(tree.x == x && tree.y == y && tree.z == z)
{
printf("%d:%d = ",tree.type,tree.material);
if(tree.type == 1 || tree.type == 3)
{
cout << "near-water ";
}
cout << organics[tree.material].id << " ";
if(tree.type == 0 || tree.type == 1)
{
cout << "tree";
}
if(tree.type == 2 || tree.type == 3)
{
cout << "shrub";
}
cout << endl;
printf("Address: 0x%x\n", tree.address);
hexdump(DF,tree.address,13);
break;
}
}
}
v->Finish();
#ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl;
cin.ignore();
#endif
return 0;
}

@ -1,11 +1,13 @@
// Just show some position data
#include <iostream>
#include <iomanip>
#include <climits>
#include <integers.h>
#include <vector>
#include <sstream>
#include <ctime>
#include <cstdio>
using namespace std;
#include <DFTypes.h>
@ -13,30 +15,11 @@ using namespace std;
#include <DFProcess.h>
#include <DFMemInfo.h>
#include <DFVector.h>
void DumpObjStr0Vector (const char * name, DFHack::Process *p, uint32_t addr)
{
cout << "----==== " << name << " ====----" << endl;
DFHack::DfVector vect(p,addr,4);
for(int i = 0; i < vect.getSize();i++)
{
uint32_t addr = *(uint32_t *) vect[i];
cout << p->readSTLString(addr) << endl;
}
cout << endl;
}
void DumpDWordVector (const char * name, DFHack::Process *p, uint32_t addr)
{
cout << "----==== " << name << " ====----" << endl;
DFHack::DfVector vect(p,addr,4);
for(int i = 0; i < vect.getSize();i++)
{
uint32_t number = *(uint32_t *) vect[i];
cout << number << endl;
}
cout << endl;
}
#include <DFTypes.h>
#include <modules/Vegetation.h>
#include <modules/Materials.h>
#include <modules/Position.h>
#include "miscutils.h"
int main (int numargs, const char ** args)
{
@ -59,38 +42,7 @@ int main (int numargs, const char ** args)
#endif
return 1;
}
DFHack::Process* p = DF.getProcess();
DFHack::memory_info* mem = DF.getMemoryInfo();
//const vector<string> * names = mem->getClassIDMapping();
DumpObjStr0Vector("Material templates",p, mem->getAddress("mat_templates"));
DumpObjStr0Vector("Inorganics",p, mem->getAddress("mat_inorganics"));
DumpObjStr0Vector("Organics - all",p, mem->getAddress("mat_organics_all"));
DumpObjStr0Vector("Organics - plants",p, mem->getAddress("mat_organics_plants"));
DumpDWordVector("Maybe map between all organics and plants",p, mem->getAddress("mat_unk1_numbers"));
DumpObjStr0Vector("Trees/wood",p, mem->getAddress("mat_organics_trees"));
DumpDWordVector("Maybe map between all organics and trees",p, mem->getAddress("mat_unk2_numbers"));
DumpObjStr0Vector("Body material templates",p, mem->getAddress("mat_body_material_templates"));
DumpObjStr0Vector("Body detail plans",p, mem->getAddress("mat_body_detail_plans"));
DumpObjStr0Vector("Bodies",p, mem->getAddress("mat_bodies"));
DumpObjStr0Vector("Bodygloss",p, mem->getAddress("mat_bodygloss"));
DumpObjStr0Vector("Creature variations",p, mem->getAddress("mat_creature_variations"));
DumpObjStr0Vector("Creature types",p, mem->getAddress("mat_creature_types"));
#ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl;
cin.ignore();

@ -2800,6 +2800,7 @@
<Labor name="Wood Burning">64</Labor>
<Labor name="Pump Operating">65</Labor>
<!--
* Labor groups *
<Labor name="Woodworking">4294967294</Labor>
<Labor name="Stoneworking">4294967293</Labor>
@ -2813,6 +2814,7 @@
<Labor name="Engineering">4294967285</Labor>
<Labor name="Hauling">4294967284</Labor>
<Labor name="Other Jobs">4294967283</Labor>
-->
====================================================================
V -- T A B L E S
(for stonesense)
@ -2857,7 +2859,7 @@
<HexValue name="sizeof_vector">0x18</HexValue>
<Offset name="vector_triplet">0xC</Offset>
Vector layout in MSVC 9:
DWORD Allocator
DWORD Allocator?
DWORD ?
DWORD ?
DWORD Start
@ -2865,6 +2867,9 @@
DWORD AllocationEnd
<HexValue name="sizeof_string">0x1C</HexValue>
<!-- most probably a static object, because its parts are often
referenced as offset to this address *and* as addresses -->
<Address name="WORLD">0x0165B188</Address>
Position and window dimensions
==============================
@ -2962,6 +2967,7 @@ map_data_1b60_offset 0x1B9c
=========
<Address name="creature_vector">0x0166ecc4</Address>
<Offset name="creature_name">0x0</Offset>
<Offset name="creature_custom_profession">0x6c</Offset>
<Offset name="creature_profession">0x88</Offset>
<Offset name="creature_race">0x8C</Offset>
<Offset name="creature_position">0x90</Offset>
@ -2972,6 +2978,14 @@ map_data_1b60_offset 0x1B9c
<Offset name="creature_artifact_name">0x6D0</Offset>
<Offset name="creature_labors">0x770</Offset>
<Offset name="creature_happiness">0x830</Offset>
<Offset name="creature_soul_vector">0x073C</Offset>
<Offset name="soul_skills_vector">0x1F4</Offset>
<!-- from DT -->
<Address name="dwarf_race_index">0x01470fbc</Address>DWORD, OK
This seems to be wrong:
creature_vector = 0x0166ed2c
Materials
=========
@ -3012,6 +3026,39 @@ map_data_1b60_offset 0x1B9c
<Address name="creature_type_vector">0x016AFE58</Address>
<!--<Address name="mat_creature_types2">0x16AEE08</Address>-->
Constructions
=============
<Address name="construction_vector">0x165b290</Address>
<Offset name="sizeof_construction">0x14</Offset>
Translations
============
<Address name="language_vector">0x016AFFD8</Address>
<Address name="translation_vector">0x016B0008</Address>
<Offset name="word_table">0x4C</Offset>
Vegetation
==========
<Address name="vegetation_vector">0x0167030C</Address> belal: 0x017f6d98 ... what?
<Offset name="tree_desc_offset">0x6C</Offset>
Buildings
=========
:(
Effects
=======
:(
Settlements
===========
:(
<!--
addresses from belal: vectors might need 8 subtracted from them
buildings 0x0166f9a8
@ -3034,7 +3081,6 @@ map_data_1b60_offset 0x1B9c
settlement_current 0xffffffff
settlements 0x016af4a4
translation_vector 0x016b0010
vegetation 0x017f6da0
view_screen 0xffffffff
window_dims 0x017f5abc
window_x 0x00e32798

@ -42,8 +42,8 @@ ENDIF(UNIX)
# a magma creation tool
# Author: Aleric
#ADD_EXECUTABLE(dfmagma_create magma_create.cpp)
#TARGET_LINK_LIBRARIES(dfmagma_create dfhack)
ADD_EXECUTABLE(dfmagma_create magma_create.cpp)
TARGET_LINK_LIBRARIES(dfmagma_create dfhack)
IF(UNIX)
install(TARGETS

@ -8,6 +8,8 @@ using namespace std;
#include <DFTypes.h>
#include <DFHackAPI.h>
#include <modules/Maps.h>
#include <modules/Position.h>
int main (void)
{
@ -15,9 +17,13 @@ int main (void)
DFHack::designations40d designations;
DFHack::API DF("Memory.xml");
DFHack::Maps * Maps;
DFHack::Position * Position;
try
{
DF.Attach();
Maps = DF.getMaps();
Position = DF.getPosition();
}
catch (exception& e)
{
@ -28,39 +34,35 @@ int main (void)
return 1;
}
DF.InitMap();
Maps->Start();
if (DF.InitViewAndCursor())
if(Position->getCursorCoords(x,y,z))
{
if(DF.getCursorCoords(x,y,z))
cout << "cursor coords: " << x << "/" << y << "/" << z << endl;
if(Maps->isValidBlock(x/16,y/16,z))
{
cout << "cursor coords: " << x << "/" << y << "/" << z << endl;
if(DF.isValidBlock(x/16,y/16,z))
{
// place the magma
DF.ReadDesignations((x/16),(y/16),z, &designations);
designations[x%16][y%16].bits.flow_size = 7;
designations[x%16][y%16].bits.liquid_type = DFHack::liquid_magma;
DF.WriteDesignations(x/16,y/16,z, &designations);
// make the magma flow :)
DFHack::t_blockflags bflags;
DF.ReadBlockFlags((x/16),(y/16),z,bflags);
// 0x00000001 = job-designated
// 0x0000000C = run flows? - both bit 3 and 4 required for making magma placed on a glacier flow
bflags.bits.liquid_1 = true;
bflags.bits.liquid_2 = true;
DF.WriteBlockFlags((x/16),(y/16),z,bflags);
cout << "Success" << endl;
}
else
cout << "Failure 1" << endl;
// place the magma
Maps->ReadDesignations((x/16),(y/16),z, &designations);
designations[x%16][y%16].bits.flow_size = 7;
designations[x%16][y%16].bits.liquid_type = DFHack::liquid_magma;
Maps->WriteDesignations(x/16,y/16,z, &designations);
// make the magma flow :)
DFHack::t_blockflags bflags;
Maps->ReadBlockFlags((x/16),(y/16),z,bflags);
// 0x00000001 = job-designated
// 0x0000000C = run flows? - both bit 3 and 4 required for making magma placed on a glacier flow
bflags.bits.liquid_1 = true;
bflags.bits.liquid_2 = true;
Maps->WriteBlockFlags((x/16),(y/16),z,bflags);
Maps->Finish();
cout << "Success" << endl;
}
else
cout << "Failure 2" << endl;
cout << "Failure 1" << endl;
}
else
cout << "Process Failed" << endl;
cout << "Failure 2" << endl;
DF.Detach();
#ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl;