Merge remote-tracking branch 'q-github/master'

develop
Alexander Gavrilov 2012-03-02 09:26:52 +04:00
commit d014554679
58 changed files with 89 additions and 4902 deletions

@ -27,10 +27,10 @@ endif()
# set up versioning.
set(DF_VERSION_MAJOR "0")
set(DF_VERSION_MINOR "34")
set(DF_VERSION_PATCH "03")
set(DF_VERSION_PATCH "04")
set(DF_VERSION "${DF_VERSION_MAJOR}.${DF_VERSION_MINOR}.${DF_VERSION_PATCH}")
set(DFHACK_RELEASE "1-dev0")
set(DFHACK_RELEASE "1")
set(DFHACK_VERSION "${DF_VERSION_MAJOR}.${DF_VERSION_MINOR}.${DF_VERSION_PATCH}-r${DFHACK_RELEASE}")
add_definitions(-DDFHACK_VERSION="${DFHACK_VERSION}")

@ -104,7 +104,7 @@ void cheap_tokenise(string const& input, vector<string> &output)
string *cur = NULL;
for (size_t i = 0; i < input.size(); i++) {
char c = input[i];
unsigned char c = input[i];
if (isspace(c)) {
cur = NULL;
} else {
@ -470,28 +470,11 @@ static void runInteractiveCommand(Core *core, PluginManager *plug_mgr, int &clue
}
else
{
vector <string> parts;
cheap_tokenise(command,parts);
if(parts.size() == 0)
command_result res = plug_mgr->InvokeCommand(first, parts);
if(res == CR_NOT_IMPLEMENTED)
{
clueless_counter++;
}
else
{
string first = parts[0];
parts.erase(parts.begin());
command_result res = plug_mgr->InvokeCommand(first, parts);
if(res == CR_NOT_IMPLEMENTED)
{
con.printerr("%s is not a recognized command.\n", first.c_str());
clueless_counter ++;
}
/*
else if(res == CR_FAILURE)
{
con.printerr("ERROR!\n");
}
*/
con.printerr("%s is not a recognized command.\n", first.c_str());
clueless_counter ++;
}
}
}

@ -181,17 +181,17 @@ bool Plugin::load()
return false;
}
const char ** plug_name =(const char ** ) LookupPlugin(plug, "name");
if(!plug_name)
const char ** plug_version =(const char ** ) LookupPlugin(plug, "version");
if(!plug_name || !plug_version)
{
con.printerr("Plugin %s has no name.\n", filename.c_str());
con.printerr("Plugin %s has no name or version.\n", filename.c_str());
ClosePlugin(plug);
state = PS_BROKEN;
return false;
}
const char ** plug_version =(const char ** ) LookupPlugin(plug, "version");
if(!plug_version || strcmp(DFHACK_VERSION, *plug_version) != 0)
if(strcmp(DFHACK_VERSION, *plug_version) != 0)
{
con.printerr("Plugin sx was not built for this version of DFHack.\n"
con.printerr("Plugin %s was not built for this version of DFHack.\n"
"Plugin: %s, DFHack: %s\n", *plug_name, *plug_version, DFHACK_VERSION);
ClosePlugin(plug);
state = PS_BROKEN;

@ -60,7 +60,6 @@ void VersionInfoFactory::clear()
VersionInfo * VersionInfoFactory::getVersionInfoByMD5(string hash)
{
VersionInfo * vinfo;
for(size_t i = 0; i < versions.size();i++)
{
if(versions[i]->hasMD5(hash))
@ -167,7 +166,6 @@ bool VersionInfoFactory::loadFile(string path_to_xml)
TiXmlHandle hDoc(&doc);
TiXmlElement* pElem;
TiXmlHandle hRoot(0);
VersionInfo *mem;
// block: name
{

@ -29,6 +29,7 @@ distribution.
#include <string.h>
#include <stdlib.h>
#include <sstream>
#include <exception>
//#include <ostream>
namespace DFHack
{
@ -62,7 +63,10 @@ namespace DFHack
{
if (newsize == size)
return;
bits = (uint8_t*)realloc(bits, newsize);
uint8_t* mem = (uint8_t *) realloc(bits, newsize);
if(!mem)
throw std::bad_alloc();
bits = mem;
if (newsize > size)
memset(bits+size, 0, newsize-size);
size = newsize;
@ -197,7 +201,10 @@ namespace DFHack
}
else
{
m_data = (T*)realloc(m_data, sizeof(T)*new_size);
T* mem = (T*) realloc(m_data, sizeof(T)*new_size);
if(!mem)
throw std::bad_alloc();
m_data = mem;
}
if (new_size > m_size)
memset(m_data+sizeof(T)*m_size, 0, sizeof(T)*(new_size - m_size));

@ -51,6 +51,9 @@ distribution.
#pragma warning( disable: 4068 )
// no signed value outside enum range bs
#pragma warning( disable: 4341)
// just shut up already.
#pragma warning( disable: 4244)
#pragma warning( disable: 4018)
#endif
#endif

@ -241,19 +241,19 @@ df::job *DFHack::getSelectedJob(Core *c, bool quiet)
{
df::viewscreen *top = c->getTopViewscreen();
if (VIRTUAL_CAST_VAR(screen, df::viewscreen_joblistst, top))
if (VIRTUAL_CAST_VAR(joblist, df::viewscreen_joblistst, top))
{
df::job *job = vector_get(screen->jobs, screen->cursor_pos);
df::job *job = vector_get(joblist->jobs, joblist->cursor_pos);
if (!job && !quiet)
c->con.printerr("Selected unit has no job\n");
return job;
}
else if (VIRTUAL_CAST_VAR(screen, df::viewscreen_unitlistst, top))
else if (VIRTUAL_CAST_VAR(unitlist, df::viewscreen_unitlistst, top))
{
int page = screen->page;
df::job *job = vector_get(screen->jobs[page], screen->cursor_pos[page]);
int page = unitlist->page;
df::job *job = vector_get(unitlist->jobs[page], unitlist->cursor_pos[page]);
if (!job && !quiet)
c->con.printerr("Selected unit has no job\n");

@ -761,29 +761,32 @@ bool Materials::ReadCreatureTypesEx (void)
part.category = bp->part_name;
caste.bodypart.push_back(part);
}
using namespace df::enums::mental_attribute_type;
using namespace df::enums::physical_attribute_type;
for (int32_t k = 0; k < 7; k++)
{
caste.strength[k] = ca->attributes.phys_att_range[physical_attribute_type::STRENGTH][k];
caste.agility[k] = ca->attributes.phys_att_range[physical_attribute_type::AGILITY][k];
caste.toughness[k] = ca->attributes.phys_att_range[physical_attribute_type::TOUGHNESS][k];
caste.endurance[k] = ca->attributes.phys_att_range[physical_attribute_type::ENDURANCE][k];
caste.recuperation[k] = ca->attributes.phys_att_range[physical_attribute_type::RECUPERATION][k];
caste.disease_resistance[k] = ca->attributes.phys_att_range[physical_attribute_type::DISEASE_RESISTANCE][k];
caste.analytical_ability[k] = ca->attributes.phys_att_range[mental_attribute_type::ANALYTICAL_ABILITY][k];
caste.focus[k] = ca->attributes.phys_att_range[mental_attribute_type::FOCUS][k];
caste.willpower[k] = ca->attributes.phys_att_range[mental_attribute_type::WILLPOWER][k];
caste.creativity[k] = ca->attributes.phys_att_range[mental_attribute_type::CREATIVITY][k];
caste.intuition[k] = ca->attributes.phys_att_range[mental_attribute_type::INTUITION][k];
caste.patience[k] = ca->attributes.phys_att_range[mental_attribute_type::PATIENCE][k];
caste.memory[k] = ca->attributes.phys_att_range[mental_attribute_type::MEMORY][k];
caste.linguistic_ability[k] = ca->attributes.phys_att_range[mental_attribute_type::LINGUISTIC_ABILITY][k];
caste.spatial_sense[k] = ca->attributes.phys_att_range[mental_attribute_type::SPATIAL_SENSE][k];
caste.musicality[k] = ca->attributes.phys_att_range[mental_attribute_type::MUSICALITY][k];
caste.kinesthetic_sense[k] = ca->attributes.phys_att_range[mental_attribute_type::KINESTHETIC_SENSE][k];
caste.empathy[k] = ca->attributes.phys_att_range[mental_attribute_type::EMPATHY][k];
caste.social_awareness[k] = ca->attributes.phys_att_range[mental_attribute_type::SOCIAL_AWARENESS][k];
auto & physical = ca->attributes.phys_att_range;
caste.strength[k] = physical[STRENGTH][k];
caste.agility[k] = physical[AGILITY][k];
caste.toughness[k] = physical[TOUGHNESS][k];
caste.endurance[k] = physical[ENDURANCE][k];
caste.recuperation[k] = physical[RECUPERATION][k];
caste.disease_resistance[k] = physical[DISEASE_RESISTANCE][k];
auto & mental = ca->attributes.ment_att_range;
caste.analytical_ability[k] = mental[ANALYTICAL_ABILITY][k];
caste.focus[k] = mental[FOCUS][k];
caste.willpower[k] = mental[WILLPOWER][k];
caste.creativity[k] = mental[CREATIVITY][k];
caste.intuition[k] = mental[INTUITION][k];
caste.patience[k] = mental[PATIENCE][k];
caste.memory[k] = mental[MEMORY][k];
caste.linguistic_ability[k] = mental[LINGUISTIC_ABILITY][k];
caste.spatial_sense[k] = mental[SPATIAL_SENSE][k];
caste.musicality[k] = mental[MUSICALITY][k];
caste.kinesthetic_sense[k] = mental[KINESTHETIC_SENSE][k];
caste.empathy[k] = mental[EMPATHY][k];
caste.social_awareness[k] = mental[SOCIAL_AWARENESS][k];
}
mat.castes.push_back(caste);
}

@ -1 +1 @@
Subproject commit 0c8d7fbf2eae4814947ac4eeb22f39a7cafaf40c
Subproject commit 0b7140582457982434df8d5756b5132d15a6b1f4

@ -120,6 +120,26 @@ command_result nopause (Core * c, std::vector <std::string> & parameters)
return CR_OK;
}
void revealAdventure(DFHack::Core * c)
{
for (size_t i = 0; i < world->map.map_blocks.size(); i++)
{
df::map_block *block = world->map.map_blocks[i];
// in 'no-hell'/'safe' mode, don't reveal blocks with hell and adamantine
if (!isSafe(block->map_pos))
continue;
DFHack::designations40d & designations = block->designation;
// for each tile in block
for (uint32_t x = 0; x < 16; x++) for (uint32_t y = 0; y < 16; y++)
{
// set to revealed
designations[x][y].bits.hidden = 0;
// and visible
designations[x][y].bits.pile = 1;
}
}
c->con.print("Local map revealed.\n");
}
command_result reveal(DFHack::Core * c, std::vector<std::string> & params)
{
@ -157,16 +177,21 @@ command_result reveal(DFHack::Core * c, std::vector<std::string> & params)
CoreSuspender suspend(c);
DFHack::World *World =c->getWorld();
if (!Maps::IsValid())
{
c->con.printerr("Map is not available!\n");
return CR_FAILURE;
}
t_gamemodes gm;
World->ReadGameMode(gm);
if(gm.g_mode != GAMEMODE_DWARF)
if(gm.g_mode == GAMEMODE_ADVENTURE)
{
con.printerr("Only in fortress mode.\n");
return CR_FAILURE;
revealAdventure(c);
return CR_OK;
}
if (!Maps::IsValid())
if(gm.g_mode != GAMEMODE_DWARF)
{
c->con.printerr("Map is not available!\n");
con.printerr("Only in fortress mode.\n");
return CR_FAILURE;
}
@ -231,6 +256,11 @@ command_result unreveal(DFHack::Core * c, std::vector<std::string> & params)
CoreSuspender suspend(c);
DFHack::World *World =c->getWorld();
if (!Maps::IsValid())
{
c->con.printerr("Map is not available!\n");
return CR_FAILURE;
}
t_gamemodes gm;
World->ReadGameMode(gm);
if(gm.g_mode != GAMEMODE_DWARF)
@ -238,11 +268,6 @@ command_result unreveal(DFHack::Core * c, std::vector<std::string> & params)
con.printerr("Only in fortress mode.\n");
return CR_FAILURE;
}
if (!Maps::IsValid())
{
c->con.printerr("Map is not available!\n");
return CR_FAILURE;
}
// Sanity check: map size
uint32_t x_max_b, y_max_b, z_max_b;

@ -1,43 +0,0 @@
if(NOT DEFINED DFHACK_CONSISTENCY)
MESSAGE(FATAL_ERROR "Please build the whole thing, not parts. You can turn parts on/off using options.")
ENDIF()
# this is required to ensure we use the right configuration for the system.
IF(UNIX)
add_definitions(-DLINUX_BUILD)
ENDIF(UNIX)
# buildingsdump - dump buildings and their raw data filtered by type
DFHACK_TOOL(dfbuildingsdump buildingsdump.cpp)
# constructiondump - dump engravings!
DFHACK_TOOL(dfengravingdump engravingdump.cpp)
# constructiondump - dump constructions!
DFHACK_TOOL(dfconstructiondump construction_dump.cpp)
# creaturedump - basic creature dump - a test of the creature related exports
DFHACK_TOOL(dfcreaturedump creaturedump.cpp)
# materialtest - just list the first material of each type
DFHACK_TOOL(dfmaterialtest materialtest.cpp)
# itemdump - dump the item under the cursor
DFHACK_TOOL(dfitemdump dfitemdump.cpp)
# hotkeynotedump - dumps the hotkeys and notes for the loaded map
# Author: belal
DFHACK_TOOL(dfhotkeynotedump hotkeynotedump.cpp)
# settlementdump - dumps the settlements on the loaded map
# Author: belal
# DFHACK_TOOL(dfsettlementdump settlementdump.cpp)
# treedump - dump them trees!
DFHACK_TOOL(dftreedump treedump.cpp)
# spatterdump - dump spatter 'veins'
DFHACK_TOOL(dfspatterdump spatterdump.cpp)
# processenum - demonstrates the use of ProcessEnumerator
DFHACK_TOOL(dfprocessenum processenum.cpp)

@ -1,179 +0,0 @@
// Building dump
#include <iostream>
#include <iomanip>
#include <sstream>
#include <climits>
#include <vector>
#include <stdio.h>
//using namespace std;
#define DFHACK_WANT_MISCUTILS
#include <DFHack.h>
void doWordPerLine(DFHack::Context *DF, DFHack::VersionInfo * mem,
DFHack::Buildings * Bld, uint32_t numBuildings,
const char* type, int lines)
{
std::cout << numBuildings << std::endl;
std::vector < uint32_t > addresses;
for(uint32_t i = 0; i < numBuildings; i++)
{
DFHack::t_building temp;
Bld->Read(i, temp);
if(temp.type != 0xFFFFFFFF) // check if type isn't invalid
{
std::string typestr;
mem->resolveClassIDToClassname(temp.type, typestr);
std::cout << typestr << std::endl;
if(typestr == type)
addresses.push_back(temp.origin);
}
else
{
// couldn't translate type, print out the vtable
std::cout << "unknown vtable: " << temp.vtable << std::endl;
}
}
if (addresses.empty())
{
std::cout << "No buildings matching '" << type << "'" << endl;
return;
}
interleave_hex(DF,addresses,lines / 4);
}
void doUnderCursor(DFHack::Context *DF, DFHack::VersionInfo * mem,
DFHack::Buildings * Bld, uint32_t numBuildings,
int32_t x, int32_t y, int32_t z)
{
std::map <uint32_t, std::string> custom_workshop_types;
Bld->ReadCustomWorkshopTypes(custom_workshop_types);
uint32_t num_under_cursor = 0;
for(uint32_t i = 0; i < numBuildings; i++)
{
DFHack::t_building temp;
Bld->Read(i, temp);
if( (uint32_t)x >= temp.x1
&& (uint32_t)x <= temp.x2
&& (uint32_t)y >= temp.y1
&& (uint32_t)y <= temp.y2
&& (uint32_t)z == temp.z
)
{
num_under_cursor++;
std::string typestr;
mem->resolveClassIDToClassname(temp.type, typestr);
printf("Address 0x%x, type %d (%s), %d/%d/%d\n", temp.origin,
temp.type, typestr.c_str(), temp.x1, temp.y1, temp.z);
printf("Material %d %d\n", temp.material.type,
temp.material.index);
int32_t custom;
if((custom = Bld->GetCustomWorkshopType(temp)) != -1)
{
printf("Custom workshop type %s (%d)\n",
custom_workshop_types[custom].c_str(), custom);
}
hexdump(DF, temp.origin, 34*16);
}
}
if (num_under_cursor == 0)
std::cout << "No buildings present under cursor." << endl;
}
void doListAll(DFHack::VersionInfo * mem, DFHack::Buildings * Bld,
uint32_t numBuildings)
{
std::cout << "Num buildings present: " << numBuildings << std::endl;
for(uint32_t i = 0; i < numBuildings; i++)
{
DFHack::t_building temp;
Bld->Read(i, temp);
std::string typestr;
mem->resolveClassIDToClassname(temp.type, typestr);
printf("Address 0x%x, type %d (%s), Coord %d/%d/%d\n", temp.origin,
temp.type, typestr.c_str(), temp.x1,temp.y1,temp.z);
}
}
void doFinish(DFHack::Context *DF)
{
DF->Detach();
#ifndef LINUX_BUILD
std::cout << "Done. Press any key to continue" << std::endl;
cin.ignore();
#endif
}
int main (int argc,const char* argv[])
{
int lines = 16;
bool word_per_line = false;
if (argc == 3)
{
std::string num = argv[2]; //blah. I don't care
std::istringstream ins; // Declare an input string stream.
ins.str(num); // Specify string to read.
ins >> lines; // Reads the integers from the string.
word_per_line = true;
}
DFHack::ContextManager DFMgr ("Memory.xml");
DFHack::Context *DF;
try
{
DF = DFMgr.getSingleContext();
DF->Attach();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
DFHack::VersionInfo * mem = DF->getMemoryInfo();
DFHack::Buildings * Bld = DF->getBuildings();
DFHack::Gui * Gui = DF->getGui();
uint32_t numBuildings;
if(!Bld->Start(numBuildings))
{
std::cerr << "buildings not supported for this DF version" << std::endl;
doFinish(DF);
return 1;
}
if (numBuildings == 0)
{
cout << "No buildings on site." << endl;
doFinish(DF);
return 0;
}
if (word_per_line)
doWordPerLine(DF, mem, Bld, numBuildings, argv[1], lines);
else
{
int32_t x,y,z;
Gui->getCursorCoords(x,y,z);
if(x != -30000)
doUnderCursor(DF, mem, Bld, numBuildings, x, y, z);
else
doListAll(mem, Bld, numBuildings);
}
Bld->Finish();
doFinish(DF);
return 0;
}

@ -1,95 +0,0 @@
// Just show some position data
#include <iostream>
#include <iomanip>
#include <climits>
#include <vector>
#include <sstream>
#include <ctime>
#include <cstdio>
#include <stdio.h>
#define DFHACK_WANT_MISCUTILS
#include <DFHack.h>
using namespace DFHack;
int main (int numargs, const char ** args)
{
DFHack::ContextManager DFMgr("Memory.xml");
DFHack::Context* DF;
try
{
DF = DFMgr.getSingleContext();
DF->Attach();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
DFHack::Gui *Gui = DF->getGui();
DFHack::Constructions *Cons = DF->getConstructions();
DFHack::Materials *Mats = DF->getMaterials();
Mats->ReadInorganicMaterials();
Mats->ReadOrganicMaterials();
uint32_t numConstr;
Cons->Start(numConstr);
int32_t cx, cy, cz;
Gui->getCursorCoords(cx,cy,cz);
if(cx != -30000)
{
t_construction con;
for(uint32_t i = 0; i < numConstr; i++)
{
Cons->Read(i,con);
if(cx == con.x && cy == con.y && cz == con.z)
{
printf("Construction %d/%d/%d @ 0x%x\n", con.x, con.y, con.z,con.origin);
// inorganic stuff - we can recognize that
printf("Material: form %d, type %d, index %d\n",con.form, con.mat_type, con.mat_idx);
std::string matstr = "unknown";
if(con.mat_type == 0)
{
if(con.mat_idx != 0xffffffff)
matstr = Mats->inorganic[con.mat_idx].id;
else matstr = "inorganic";
}
if(con.mat_type == 420)
{
if(con.mat_idx != 0xffffffff)
matstr = Mats->organic[con.mat_idx].id;
else matstr = "organic";
}
switch(con.form)
{
case constr_bar:
printf("It is made of %s bars!\n",matstr.c_str());
break;
case constr_block:
printf("It is made of %s blocks!\n",matstr.c_str());
break;
case constr_boulder:
printf("It is made of %s stones!\n",matstr.c_str());
break;
case constr_logs:
printf("It is made of %s logs!\n",matstr.c_str());
break;
default:
printf("It is made of something we don't know yet! The material is %s.\n",matstr.c_str());
}
hexdump(DF,con.origin,32);
}
}
}
#ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl;
cin.ignore();
#endif
return 0;
}

@ -1,528 +0,0 @@
// Creature dump
#include <iostream>
#include <climits>
#include <string.h>
#include <vector>
#include <stdio.h>
using namespace std;
#define DFHACK_WANT_MISCUTILS
#include <DFHack.h>
enum likeType
{
FAIL = 0,
MATERIAL = 1,
ITEM = 2,
FOOD = 3
};
DFHack::Materials * Materials;
DFHack::VersionInfo *mem;
vector< vector<string> > englishWords;
vector< vector<string> > foreignWords;
DFHack::Creatures * Creatures = NULL;
uint32_t current_year;
uint32_t current_tick;
/*
likeType printLike40d(DFHack::t_like like, const matGlosses & mat,const vector< vector <DFHack::t_itemType> > & itemTypes)
{ // The function in DF which prints out the likes is a monster, it is a huge switch statement with tons of options and calls a ton of other functions as well,
//so I am not going to try and put all the possibilites here, only the low hanging fruit, with stones and metals, as well as items,
//you can easily find good canidates for military duty for instance
//The ideal thing to do would be to call the df function directly with the desired likes, the df function modifies a string, so it should be possible to do...
if(like.active){
if(like.type ==0){
switch (like.material.type)
{
case 0:
cout << mat.woodMat[like.material.index].name;
return(MATERIAL);
case 1:
cout << mat.stoneMat[like.material.index].name;
return(MATERIAL);
case 2:
cout << mat.metalMat[like.material.index].name;
return(MATERIAL);
case 12: // don't ask me why this has such a large jump, maybe this is not actually the matType for plants, but they all have this set to 12
cout << mat.plantMat[like.material.index].name;
return(MATERIAL);
case 32:
cout << mat.plantMat[like.material.index].name;
return(MATERIAL);
case 121:
cout << mat.creatureMat[like.material.index].name;
return(MATERIAL);
default:
return(FAIL);
}
}
else if(like.type == 4 && like.itemIndex != -1){
switch(like.itemClass)
{
case 24:
cout << itemTypes[0][like.itemIndex].name;
return(ITEM);
case 25:
cout << itemTypes[4][like.itemIndex].name;
return(ITEM);
case 26:
cout << itemTypes[8][like.itemIndex].name;
return(ITEM);
case 27:
cout << itemTypes[9][like.itemIndex].name;
return(ITEM);
case 28:
cout << itemTypes[10][like.itemIndex].name;
return(ITEM);
case 29:
cout << itemTypes[7][like.itemIndex].name;
return(ITEM);
case 38:
cout << itemTypes[5][like.itemIndex].name;
return(ITEM);
case 63:
cout << itemTypes[11][like.itemIndex].name;
return(ITEM);
case 68:
case 69:
cout << itemTypes[6][like.itemIndex].name;
return(ITEM);
case 70:
cout << itemTypes[1][like.itemIndex].name;
return(ITEM);
default:
// cout << like.itemClass << ":" << like.itemIndex;
return(FAIL);
}
}
else if(like.material.type != -1){// && like.material.index == -1){
if(like.type == 2){
switch(like.itemClass)
{
case 52:
case 53:
case 58:
cout << mat.plantMat[like.material.type].name;
return(FOOD);
case 72:
if(like.material.type =! 10){ // 10 is for milk stuff, which I don't know how to do
cout << mat.plantMat[like.material.index].extract_name;
return(FOOD);
}
return(FAIL);
case 74:
cout << mat.plantMat[like.material.index].drink_name;
return(FOOD);
case 75:
cout << mat.plantMat[like.material.index].food_name;
return(FOOD);
case 47:
case 48:
cout << mat.creatureMat[like.material.type].name;
return(FOOD);
default:
return(FAIL);
}
}
}
}
return(FAIL);
}
*/
void printCreature(DFHack::Context * DF, const DFHack::t_creature & creature)
{
uint32_t dayoflife;
cout << "address: " << hex << creature.origin << dec << ", creature race: " << creature.race << "/" << Materials->raceEx[creature.race].rawname
<< "[" << Materials->raceEx[creature.race].tile_character
<< "," << Materials->raceEx[creature.race].tilecolor.fore
<< "," << Materials->raceEx[creature.race].tilecolor.back
<< "," << Materials->raceEx[creature.race].tilecolor.bright
<< "]"
<< ", position: " << creature.x << "x " << creature.y << "y "<< creature.z << "z" << endl;
bool addendl = false;
if(creature.name.first_name[0])
{
cout << "first name: " << creature.name.first_name;
addendl = true;
}
if(creature.name.nickname[0])
{
cout << ", nick name: " << creature.name.nickname;
addendl = true;
}
DFHack::Translation *Tran = DF->getTranslation();
DFHack::VersionInfo *mem = DF->getMemoryInfo();
string transName = Tran->TranslateName(creature.name,false);
if(!transName.empty())
{
cout << ", trans name: " << transName;
addendl=true;
}
transName = Tran->TranslateName(creature.name,true);
if(!transName.empty())
{
cout << ", last name: " << transName;
addendl=true;
}
if(creature.civ)
{
cout << ", civilization: " << creature.civ;
addendl = true;
}
/*
cout << ", likes: ";
for(uint32_t i = 0;i<creature.numLikes; i++)
{
if(printLike(creature.likes[i],mat,itemTypes))
{
cout << ", ";
}
}
*/
if(addendl)
{
cout << endl;
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)
{
try{
cout << ", current job: " << mem->getJob(creature.current_job.jobId);
}
catch(exception & e)
{
cout << e.what() << endl;
}
}
cout << endl;
dayoflife = creature.birth_year*12*28 + creature.birth_time/1200;
cout << "Born on the year " << creature.birth_year << ", month " << (creature.birth_time/1200/28) << ", day " << ((creature.birth_time/1200) % 28 + 1) << ", " << dayoflife << " days lived." << endl;
cout << "Appearance : ";
for(unsigned int i = 0; i<creature.nbcolors ; i++)
{
cout << Materials->raceEx[creature.race].castes[creature.caste].ColorModifier[i].part << " ";
uint32_t color = Materials->raceEx[creature.race].castes[creature.caste].ColorModifier[i].colorlist[creature.color[i]];
if(color<Materials->color.size())
{
cout << Materials->color[color].name << "["
<< (unsigned int) (Materials->color[color].red*255) << ":"
<< (unsigned int) (Materials->color[color].green*255) << ":"
<< (unsigned int) (Materials->color[color].blue*255) << "]";
}
else if (color < Materials->alldesc.size())
{
cout << Materials->alldesc[color].id;
}
else
{
cout << "Unknown color " << color << endl;
}
if( Materials->raceEx[creature.race].castes[creature.caste].ColorModifier[i].startdate > 0 )
{
if( (Materials->raceEx[creature.race].castes[creature.caste].ColorModifier[i].startdate <= dayoflife) &&
(Materials->raceEx[creature.race].castes[creature.caste].ColorModifier[i].enddate > dayoflife) )
cout << "[active]";
else
cout << "[inactive]";
}
cout << " - ";
}
cout << endl;
cout << "happiness: " << creature.happiness
<< ", strength: " << creature.strength.level
<< ", agility: " << creature.agility.level
<< ", toughness: " << creature.toughness.level
<< ", endurance: " << creature.endurance.level
<< ", recuperation: " << creature.recuperation.level
<< ", disease resistance: " << creature.disease_resistance.level
//<< ", money: " << creature.money
<< ", id: " << creature.id;
/*
if(creature.squad_leader_id != -1)
{
cout << ", squad_leader_id: " << creature.squad_leader_id;
}
if(creature.mood != -1){
cout << ", mood: " << creature.mood << " ";
}*/
cout << ", sex: ";
if(creature.sex == 0)
{
cout << "Female";
}
else
{
cout <<"Male";
}
cout << endl;
if((creature.mood != -1) && (creature.mood<5))
{
cout << "mood: " << creature.mood << ", skill: " << mem->getSkill(creature.mood_skill) << endl;
vector<DFHack::t_material> mymat;
if(Creatures->ReadJob(&creature, mymat))
{
for(unsigned int i = 0; i < mymat.size(); i++)
{
printf("\t%s(%d)\t%d %d %d - %.8x\n", Materials->getDescription(mymat[i]).c_str(), mymat[i].itemType, mymat[i].subType, mymat[i].subIndex, mymat[i].index, mymat[i].flags);
}
}
}
// FIXME: TOO BAD...
std::vector<uint32_t> inventory;
if( Creatures->ReadInventoryPtr(creature.origin, inventory))
{
DFHack::Items * Items = DF->getItems();
printf("\tInventory:\n");
for(unsigned int i = 0; i < inventory.size(); i++)
{
DFHack::dfh_item item;
if (Items->readItem(inventory[i], item))
printf("\t\t%d: %s\n", item.id, Items->getItemDescription(item, Materials).c_str());
}
}
std::vector<int32_t> owned;
if( Creatures->ReadOwnedItemsPtr(creature.origin, owned))
{
DFHack::Items * Items = DF->getItems();
printf("\tOwns:\n");
for (int i = 0; i < owned.size(); i++) {
uint32_t pitem = Items->findItemByID(owned[i]);
DFHack::dfh_item item;
if (!pitem || !Items->readItem(pitem,item))
pitem = 0;
printf("\t\t%d: %s\n", owned[i],
pitem ? Items->getItemDescription(item, Materials).c_str() : "?");
}
}
/*
if(creature.pregnancy_timer > 0)
cout << "gives birth in " << creature.pregnancy_timer/1200 << " days. ";
cout << "Blood: " << creature.blood_current << "/" << creature.blood_max << " bleeding: " << creature.bleed_rate;
*/
cout << endl;
if(creature.has_default_soul)
{
//skills
cout << "Skills" << endl;
for(unsigned int i = 0; i < creature.defaultSoul.numSkills;i++)
{
if(i > 0)
{
cout << ", ";
}
try
{
cout << mem->getSkill(creature.defaultSoul.skills[i].id) << ": " << creature.defaultSoul.skills[i].rating;
}
catch(DFHack::Error::AllMemdef &e)
{
cout << "Unknown skill! : " << creature.defaultSoul.skills[i].id <<", rating: " << creature.defaultSoul.skills[i].rating << endl;
cout << e.what() << endl;
}
}
cout << endl;
cout << "Traits" << endl;
for(uint32_t i = 0; i < 30;i++)
{
string trait = mem->getTrait (i, creature.defaultSoul.traits[i]);
if(!trait.empty()) cout << trait << ", ";
}
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
*/
cout << "flags1: ";
print_bits(creature.flags1.whole, cout);
cout << endl;
if(creature.flags1.bits.dead)
{
cout << "dead ";
}
if(creature.flags1.bits.on_ground)
{
cout << "on the ground, ";
}
if(creature.flags1.bits.skeleton)
{
cout << "skeletal ";
}
if(creature.flags1.bits.zombie)
{
cout << "zombie ";
}
if(creature.flags1.bits.tame)
{
cout << "tame ";
}
if(creature.flags1.bits.royal_guard)
{
cout << "royal_guard ";
}
if(creature.flags1.bits.fortress_guard)
{
cout << "fortress_guard ";
}
/*
* FLAGS 2
*/
cout << endl << "flags2: ";
print_bits(creature.flags2.whole, cout);
cout << endl;
if(creature.flags2.bits.killed)
{
cout << "killed by kill function, ";
}
if(creature.flags2.bits.resident)
{
cout << "resident, ";
}
if(creature.flags2.bits.gutted)
{
cout << "gutted, ";
}
if(creature.flags2.bits.slaughter)
{
cout << "marked for slaughter, ";
}
if(creature.flags2.bits.underworld)
{
cout << "from the underworld, ";
}
cout << endl;
if(creature.flags1.bits.had_mood && (creature.mood == -1 || creature.mood == 8 ) )
{
string artifact_name = Tran->TranslateName(creature.artifact_name,false);
cout << "artifact: " << artifact_name << endl;
}
cout << endl;
}
int main (int numargs, char ** args)
{
DFHack::World * World;
DFHack::ContextManager DFMgr("Memory.xml");
DFHack::Context* DF;
try
{
DF = DFMgr.getSingleContext();
DF->Attach();
}
catch (exception& e)
{
cerr << e.what() << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
string check = "";
if(numargs == 2)
check = args[1];
Creatures = DF->getCreatures();
Materials = DF->getMaterials();
World = DF->getWorld();
current_year = World->ReadCurrentYear();
current_tick = World->ReadCurrentTick();
DFHack::Translation * Tran = DF->getTranslation();
uint32_t numCreatures;
if(!Creatures->Start(numCreatures))
{
cerr << "Can't get creatures" << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
if(!numCreatures)
{
cerr << "No creatures to print" << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
mem = DF->getMemoryInfo();
Materials->ReadInorganicMaterials();
Materials->ReadOrganicMaterials();
Materials->ReadWoodMaterials();
Materials->ReadPlantMaterials();
Materials->ReadCreatureTypes();
Materials->ReadCreatureTypesEx();
//Materials->ReadDescriptorColors();
if(!Tran->Start())
{
cerr << "Can't get name tables" << endl;
return 1;
}
vector<uint32_t> addrs;
for(uint32_t i = 0; i < numCreatures; i++)
{
DFHack::t_creature temp;
Creatures->ReadCreature(i,temp);
if(check.empty() || string(Materials->raceEx[temp.race].rawname) == check)
{
printCreature(DF,temp);
addrs.push_back(temp.origin);
}
}
if(addrs.size() <= 10)
{
interleave_hex(DF,addrs,200);
}
Creatures->Finish();
DF->Detach();
#ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl;
cin.ignore();
#endif
return 0;
}

@ -1,121 +0,0 @@
/*
* Simple, pretty item dump example.
*/
#include <cstdio>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <climits>
#include <vector>
#include <cstring>
using namespace std;
#define DFHACK_WANT_MISCUTILS
#include <DFHack.h>
#include <DFVector.h>
int main (int argc, char *argv[])
{
bool print_refs = false;
bool print_hex = false;
bool print_acc = false;
for(int i = 1; i < argc; i++)
{
char *arg = argv[i];
if (arg[0] != '-')
continue;
for (; *arg; arg++) {
switch (arg[0]) {
case 'r': print_refs = true; break;
case 'x': print_hex = true; break;
case 'a': print_acc = true; break;
}
}
}
DFHack::Process * p;
DFHack::ContextManager DFMgr("Memory.xml");
DFHack::Context * DF;
try
{
DF = DFMgr.getSingleContext();
DF->Attach();
}
catch (exception& e)
{
cerr << e.what() << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
DFHack::Materials * Materials = DF->getMaterials();
Materials->ReadAllMaterials();
DFHack::Gui * Gui = DF->getGui();
DFHack::Items * Items = DF->getItems();
Items->Start();
DFHack::VersionInfo * mem = DF->getMemoryInfo();
p = DF->getProcess();
int32_t x,y,z;
Gui->getCursorCoords(x,y,z);
std::vector<uint32_t> p_items;
Items->readItemVector(p_items);
uint32_t size = p_items.size();
// FIXME: tools should never be exposed to DFHack internals!
DFHack::OffsetGroup* itemGroup = mem->getGroup("Items");
uint32_t ref_vector = itemGroup->getOffset("item_ref_vector");
for(size_t i = 0; i < size; i++)
{
DFHack::dfh_item itm;
memset(&itm, 0, sizeof(DFHack::dfh_item));
Items->readItem(p_items[i],itm);
if (x != -30000
&& !(itm.base.x == x && itm.base.y == y && itm.base.z == z
&& itm.base.flags.on_ground
&& !itm.base.flags.in_chest
&& !itm.base.flags.in_inventory
&& !itm.base.flags.in_building))
continue;
printf(
"%5d: %08x %6d %08x (%d,%d,%d) #%08x [%d] *%d %s - %s\n",
i, itm.origin, itm.id, itm.base.flags.whole,
itm.base.x, itm.base.y, itm.base.z,
itm.base.vtable,
itm.wear_level,
itm.quantity,
Items->getItemClass(itm).c_str(),
Items->getItemDescription(itm, Materials).c_str()
);
if (print_hex)
hexdump(DF,p_items[i],0x300);
if (print_acc)
cout << Items->dumpAccessors(itm) << endl;
if (print_refs) {
DFHack::DfVector<uint32_t> p_refs(p, itm.origin + ref_vector);
for (size_t j = 0; j < p_refs.size(); j++) {
uint32_t vptr = p->readDWord(p_refs[j]);
uint32_t val = p->readDWord(p_refs[j]+4);
printf("\t-> %d \t%s\n", int(val), p->readClassName(vptr).c_str());
}
}
}
#ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl;
cin.ignore();
#endif
return 0;
}

@ -1,105 +0,0 @@
// Just show some position data
#include <iostream>
#include <iomanip>
#include <climits>
#include <vector>
#include <sstream>
#include <ctime>
#include <cstdio>
#include <stdio.h>
#define DFHACK_WANT_MISCUTILS
#include <DFHack.h>
using namespace DFHack;
void describe (dfh_engraving &engraving)
{
t_engraving &data = engraving.s;
printf("Engraving %d/%d/%d @ 0x%x\n", data.x, data.y, data.z, engraving.origin);
// inorganic stuff - we can recognize that
printf("type %d, index %d, character %c\n",data.type, data.subtype_idx, data.display_character);
printf("quality %d\n",data.quality);
printf("engraved: ");
if(data.flags.floor)
printf("On the floor.");
if(data.flags.north)
printf("From north.");
if(data.flags.south)
printf("From south.");
if(data.flags.east)
printf("From east.");
if(data.flags.west)
printf("From west.");
if(data.flags.northeast)
printf("From north-east.");
if(data.flags.northwest)
printf("From north-west.");
if(data.flags.southeast)
printf("From south-east.");
if(data.flags.southwest)
printf("From south-west.");
printf("\n");
if(data.flags.hidden)
printf("The symbol is hidden.\n");
};
int main (int numargs, const char ** args)
{
DFHack::ContextManager DFMgr("Memory.xml");
DFHack::Context* DF;
try
{
DF = DFMgr.getSingleContext();
DF->Attach();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
DFHack::Gui *Gui = DF->getGui();
DFHack::Engravings *Cons = DF->getEngravings();
uint32_t numEngr;
Cons->Start(numEngr);
int32_t cx, cy, cz;
Gui->getCursorCoords(cx,cy,cz);
if(cx != -30000)
{
dfh_engraving engraved;
t_engraving &data = engraved.s;
for(uint32_t i = 0; i < numEngr; i++)
{
Cons->Read(i,engraved);
if(cx == data.x && cy == data.y && cz == data.z)
{
describe(engraved);
hexdump(DF,engraved.origin,0x28);
}
}
}
else
{
dfh_engraving engraved;
t_engraving &data = engraved.s;
for(uint32_t i = 0; i < numEngr; i++)
{
Cons->Read(i,engraved);
{
describe(engraved);
hexdump(DF,engraved.origin,0x28);
}
}
}
#ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl;
cin.ignore();
#endif
return 0;
}

@ -1,66 +0,0 @@
// Hotkey and Note Dump
// Or Hot Keynote Dump? :P
#include <iostream>
#include <climits>
#include <vector>
using namespace std;
#include <DFHack.h>
int main (void)
{
DFHack::ContextManager DFMgr("Memory.xml");
DFHack::Context * DF;
try
{
DF = DFMgr.getSingleContext();
DF->Attach();
}
catch (exception& e)
{
cerr << e.what() << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
DFHack::VersionInfo * mem = DF->getMemoryInfo();
DFHack::Gui * Gui = DF->getGui();
// get stone matgloss mapping
/*
uint32_t numNotes;
if(!DF.InitReadNotes(numNotes))
{
cerr << "Can't get notes" << endl;
return 1;
}
*/
/*
cout << "Notes" << endl;
for(uint32_t i = 0; i < numNotes; i++)
{
DFHack::t_note temp;
DF.ReadNote(i,temp);
cout << "x: " << temp.x << "\ty: " << temp.y << "\tz: " << temp.z <<
"\tsymbol: " << temp.symbol << "\tfg: " << temp.foreground << "\tbg: " << temp.background <<
"\ttext: " << temp.name << endl;
}
*/
cout << "Hotkeys" << endl;
DFHack::t_hotkey hotkeys[NUM_HOTKEYS];
Gui->ReadHotkeys(hotkeys);
for(uint32_t i =0;i< NUM_HOTKEYS;i++)
{
cout << "x: " << hotkeys[i].x << "\ty: " << hotkeys[i].y << "\tz: " << hotkeys[i].z <<
"\ttext: " << hotkeys[i].name << endl;
}
//DF.FinishReadNotes();
DF->Detach();
#ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl;
cin.ignore();
#endif
return 0;
}

@ -1,149 +0,0 @@
// Just show some position data
#include <iostream>
#include <climits>
#include <vector>
#include <sstream>
#include <ctime>
using namespace std;
#include <DFHack.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::ContextManager DFMgr("Memory.xml");
DFHack::Context * DF;
try
{
DF = DFMgr.getSingleContext();
DF->Attach();
}
catch (exception& e)
{
cerr << e.what() << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
DFHack::Process* p = DF->getProcess();
DFHack::VersionInfo* mem = DF->getMemoryInfo();
DFHack::Materials *Materials = DF->getMaterials();
cout << "----==== Inorganic ====----" << endl;
Materials->ReadInorganicMaterials ();
for(uint32_t i = 0; i < Materials->inorganic.size();i++)
{
cout << i << ": " << Materials->inorganic[i].id << endl;
}
cout << endl << "----==== Organic ====----" << endl;
Materials->ReadOrganicMaterials ();
for(uint32_t i = 0; i < Materials->organic.size();i++)
{
cout << i << ": " << Materials->organic[i].id << endl;
}
cout << endl << "----==== Organic - trees ====----" << endl;
Materials->ReadWoodMaterials ();
for(uint32_t i = 0; i < Materials->tree.size();i++)
{
cout << i << ": " << Materials->tree[i].id << endl;
}
cout << endl << "----==== Organic - plants ====----" << endl;
Materials->ReadPlantMaterials ();
for(uint32_t i = 0; i < Materials->plant.size();i++)
{
cout << i << ": " << Materials->plant[i].id << endl;
}
cout << endl << "----==== Color descriptors ====----" << endl;
Materials->ReadDescriptorColors();
for(uint32_t i = 0; i < Materials->color.size();i++)
{
cout << i << ": " << Materials->color[i].id << " - " << Materials->color[i].name << "["
<< (unsigned int) (Materials->color[i].red*255) << ":"
<< (unsigned int) (Materials->color[i].green*255) << ":"
<< (unsigned int) (Materials->color[i].blue*255)
<< "]" << endl;
}
cout << endl << "----==== All descriptors ====----" << endl;
Materials->ReadDescriptorColors();
for(uint32_t i = 0; i < Materials->alldesc.size();i++)
{
cout << i << ": " << Materials->alldesc[i].id << endl;
}
cout << endl << "----==== Creature types ====----" << endl;
Materials->ReadCreatureTypesEx ();
for(uint32_t i = 0; i < Materials->raceEx.size();i++)
{
cout << i << ": " << Materials->raceEx[i].rawname << endl;
vector<DFHack::t_creaturecaste> & castes = Materials->raceEx[i].castes;
for(uint32_t j = 0; j < castes.size();j++)
{
cout << " ["
<< castes[j].rawname << ":"
<< castes[j].singular << ":"
<< castes[j].plural << ":"
<< castes[j].adjective << "] ["
<< "st:" << castes[j].strength.level << "/"
<< "ag:" << castes[j].agility.level << "/"
<< "to:" << castes[j].toughness.level << "/"
<< "en:" << castes[j].endurance.level << "/"
<< "re:" << castes[j].recuperation.level << "/"
<< "di:" << castes[j].disease_resistance.level << "/"
<< "an:" << castes[j].analytical_ability.level << "/"
<< "fo:" << castes[j].focus.level << "/"
<< "wi:" << castes[j].willpower.level << "/"
<< "cr:" << castes[j].creativity.level << "/"
<< "in:" << castes[j].intuition.level << "/"
<< "pa:" << castes[j].patience.level << "/"
<< "me:" << castes[j].memory.level << "/"
<< "li:" << castes[j].linguistic_ability.level << "/"
<< "sp:" << castes[j].spatial_sense.level << "/"
<< "mu:" << castes[j].musicality.level << "/"
<< "ki:" << castes[j].kinesthetic_sense.level << "]";
cout << endl;
for(uint32_t k = 0; k < castes[j].ColorModifier.size(); k++)
{
cout << " colormod[" << castes[j].ColorModifier[k].part;
if(castes[j].ColorModifier[k].startdate>0)
cout << " start:" << castes[j].ColorModifier[k].startdate << " days, end:" << castes[j].ColorModifier[k].enddate << " days";
cout << "] ";
for(uint32_t l = 0; l < castes[j].ColorModifier[k].colorlist.size(); l++)
{
if( castes[j].ColorModifier[k].colorlist[l] < Materials->color.size() )
cout << Materials->color[castes[j].ColorModifier[k].colorlist[l]].name << " ";
else
cout << Materials->alldesc[castes[j].ColorModifier[k].colorlist[l]].id << " ";
}
cout << endl;
}
cout << " body: ";
for(uint32_t k = 0; k < castes[j].bodypart.size(); k++)
{
cout << castes[j].bodypart[k].category << " ";
}
cout << endl;
}
cout << endl;
}
cout << endl << "----==== Other ====----" << endl;
Materials->ReadOthers ();
for(uint32_t i = 0; i < Materials->other.size();i++)
{
cout << i << ": " << Materials->other[i].rawname << endl;
}
#ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl;
cin.ignore();
#endif
return 0;
}

@ -1,146 +0,0 @@
// Demonstrates the use of ProcessEnumerator
// queries the Enumerator for all DF Processes on user input. Prints them to the terminal.
// also tracks processes that were invalidated
#include <iostream>
#include <climits>
#include <vector>
#include <ctime>
using namespace std;
#include <DFHack.h>
#include <DFProcessEnumerator.h>
using namespace DFHack;
#ifndef LINUX_BUILD
#endif
void printhelp ()
{
cout << "enter empty line for next try." << endl;
cout << "enter 'next' or 'n' for next test." << endl;
cout << "enter 'help' to show this text again." << endl;
}
int inputwait (const char * prompt)
{
inputwait_reset:
string command = "";
cout <<"[" << prompt << "]# ";
getline(cin, command);
if(command == "help")
{
printhelp();
goto inputwait_reset;
}
else if(command == "")
{
return 1;
}
else if(command == "next")
{
return 0;
}
else
{
cout << "Command not recognized. Try 'help' for a list of valid commands." << endl;
goto inputwait_reset;
}
return 0;
}
int main (void)
{
printhelp();
cout << endl;
// first test ProcessEnumerator and BadProcesses
{
cout << "Testing ProcessEnumerator" << endl;
ProcessEnumerator Penum("Memory.xml");
VersionInfo * mem;
do
{
// make the ProcessEnumerator update its list of Processes
// by passing the pointer to 'inval', we make it export expired
// processes instead of destroying them outright
// (processes expire when the OS kills them for whatever reason)
BadProcesses inval;
Penum.Refresh(&inval);
int nProc = Penum.size();
int nInval = inval.size();
cout << "Processes:" << endl;
for(int i = 0; i < nProc; i++)
{
mem = Penum[i]->getDescriptor();
cout << "DF instance: " << Penum[i]->getPID()
<< ", " << mem->getVersion() << endl;
}
cout << "Invalidated:" << endl;
for(int i = 0; i < nInval; i++)
{
mem = inval[i]->getDescriptor();
cout << "DF instance: " << inval[i]->getPID()
<< ", " << mem->getVersion() << endl;
}
}
while(inputwait("ProcessEnumerator"));
}
// next test ContextManager and BadContexts
{
cout << "Testing ContextManager" << endl;
ContextManager Cman("Memory.xml");
VersionInfo * mem;
do
{
// make the ContextManager update its list of Contexts
// by passing the pointer to 'inval', we make it export expired
// contexts instead of destroying them outright
// (contexts expire when the OS kills their process for whatever
// reason)
BadContexts inval;
Cman.Refresh(&inval);
int nCont = Cman.size();
int nInval = inval.size();
DFHack::Context * cont = Cman.getSingleContext();
if(cont)
{
if(cont->Attach())
{
DFHack::Maps * mapz = cont->getMaps();
cont->Suspend();
mapz->Start();
cont->Resume();
}
bool result = cont->Detach();
if(!result)
{
cerr << "Something went horribly wrong during detach" << endl;
}
}
cout << "Contexts:" << endl;
for(int i = 0; i < nCont; i++)
{
mem = Cman[i]->getMemoryInfo();
cout << "DF instance: " << Cman[i]->getProcess()->getPID()
<< ", " << mem->getVersion() << endl;
}
cout << "Invalidated:" << endl;
for(int i = 0; i < nInval; i++)
{
mem = inval[i]->getMemoryInfo();
cout << "DF instance: " << inval[i]->getProcess()->getPID()
<< ", " << mem->getVersion() << endl;
}
}
while(inputwait("ContextManager"));
}
#ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl;
cin.ignore();
#endif
return 0;
}

@ -1,85 +0,0 @@
#include <iostream>
#include <iomanip>
#include <sstream>
#include <climits>
#include <integers.h>
#include <vector>
using namespace std;
#include <DFTypes.h>
#include <DFHackAPI.h>
#include <stdio.h>
void printSettlement(DFHack::ContextManager & DF, const DFHack::t_settlement & settlement, const vector< vector<string> > &englishWords, const vector< vector<string> > &foreignWords)
{
cout << "First name: " << settlement.name.first_name << endl << "Nickname: " << settlement.name.nickname << endl;
cout << settlement.name.words[0] << " " << settlement.name.words[1] << " " << settlement.name.words[2] << " "
<< settlement.name.words[3] << " " << settlement.name.words[4] << " " << settlement.name.words[5] << " "
<< settlement.name.words[6] << " " << settlement.name.words[7] << endl;
cout << settlement.name.parts_of_speech[0] << " " << settlement.name.parts_of_speech[1] << " " << settlement.name.parts_of_speech[2] << " "
<< settlement.name.parts_of_speech[3] << " " << settlement.name.parts_of_speech[4] << " " << settlement.name.parts_of_speech[5] << " "
<< settlement.name.parts_of_speech[6] << " " << settlement.name.parts_of_speech[7] << endl;
printf("Origin: 0x%x\n",settlement.origin);
string genericName = DF.TranslateName(settlement.name,englishWords,foreignWords,true);
string dwarfName = DF.TranslateName(settlement.name,englishWords,foreignWords,false);
cout << dwarfName << " " << genericName << " " << "world x: " << settlement.world_x << " world y: " << settlement.world_y
<< " local_x: " << settlement.local_x1 << " local_y: " << settlement.local_y1 << " size: " << settlement.local_x2 - settlement.local_x1 << " by " << settlement.local_y2 - settlement.local_y1 << "\n";
}
int main (int argc,const char* argv[])
{
DFHack::ContextManager DF("Memory.xml");
try
{
DF.Attach();
}
catch (exception& e)
{
cerr << e.what() << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
DFHack::t_settlement current;
uint32_t numSettlements;
if(!DF.InitReadSettlements(numSettlements))
{
cerr << "Could not read Settlements" << endl;
return 1;
}
vector< vector<string> > englishWords;
vector< vector<string> > foreignWords;
if(!DF.InitReadNameTables(englishWords,foreignWords))
{
cerr << "Can't get name tables" << endl;
return 1;
}
cout << "Settlements\n";
/*for(uint32_t i =0;i<numSettlements;i++){
DFHack::t_settlement temp;
DF.ReadSettlement(i,temp);
printSettlement(DF,temp,englishWords,foreignWords);
}*/
// MSVC claims this is causing the heap to be corrupted, I think it is because the currentSettlement vector only has 1 item in it
cout << "Current Settlement\n";
if(DF.ReadCurrentSettlement(current))
printSettlement(DF,current,englishWords,foreignWords);
DF.FinishReadNameTables();
DF.FinishReadSettlements();
DF.Detach();
#ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl;
cin.ignore();
#endif
return 0;
}

@ -1,197 +0,0 @@
// Just show some position data
#include <iostream>
#include <iomanip>
#include <climits>
#include <vector>
#include <sstream>
#include <ctime>
#include <cstdio>
using namespace std;
#define DFHACK_WANT_MISCUTILS
#include <DFHack.h>
using namespace DFHack;
//FIXME: A pile of magic numbers. looks like decompiled number
typedef uint32_t _DWORD;
int get_material_vector(uint32_t vein_8, uint16_t vein_4, int WORLD_)
{
int result; // eax@2
int v4; // ecx@11
int v5; // eax@12
if ( (uint16_t)(vein_4 - 0x1A3) > 0xC7u )
{
if ( ((int16_t)vein_4 < 19 || (int16_t)vein_4 > 0xDAu)
&& (uint16_t)(vein_4 - 219) > 0xC7u )
{
if ( vein_4 )
{
if ( vein_4 > 0x292u )
result = 0;
else
result = *(_DWORD *)(WORLD_ + 4 * (int16_t)vein_4 + 0x5DF44);
}
else
{
if ( (signed int)vein_8 >= 0
&& (v4 = *(_DWORD *)(WORLD_ + 0x54B88), vein_8 < (*(_DWORD *)(WORLD_ + 0x54B8C) - v4) >> 2)
&& (v5 = *(_DWORD *)(v4 + 4 * vein_8)) != 0 )
result = v5 + 0x178;
else
result = *(_DWORD *)(WORLD_ + 0x5DF44);
}
}
else
{
/*
result = sub_4D47A0(vein_8, vein_4, WORLD_ + 0x54C84);
if ( !result )
result = *(_DWORD *)(WORLD_ + 0x5DF90);
*/
}
}
else
{
/*
result = sub_41F430(WORLD_ + 0x54B94, vein_4);
if ( !result )
result = *(_DWORD *)(WORLD_ + 0x5E5D0);
*/
}
return result;
}
char shades[10] = {'#','$','O','=','+','|','-','^','.',' '};
void printSpatter(DFHack::Context * DF, t_spattervein & spatter)
{
DFHack::Materials *Mats = DF->getMaterials();
printf("Splatter\nmat1: %d\nunknown: %d\nmat2: %d\n",spatter.mat1,spatter.unk1,spatter.mat2);
printf ("Material : %d - ", spatter.matter_state);
// FIXME: stupid
switch(spatter.matter_state)
{
case state_gas:
printf("Gas ");
break;
case state_solid:
printf("Solid ");
break;
case state_liquid:
printf("Liquid ");
break;
case state_paste:
printf("Paste ");
break;
case state_powder:
printf("Powder ");
break;
case state_pressed:
printf("Pressed ");
break;
default:
printf("Unknown state ");
}
cout << PrintSplatterType(spatter.mat1,spatter.mat2,Mats->race) << endl;
printf("Address 0x%08x\n",spatter.address_of);
for(uint32_t yyy = 0; yyy < 16; yyy++)
{
cout << "|";
for(uint32_t xxx = 0; xxx < 16; xxx++)
{
uint8_t intensity = spatter.intensity[xxx][yyy];
cout << shades[9 - (intensity / 28)];
}
cout << "|" << endl;
}
hexdump(DF, spatter.address_of,20*16);
}
int main (int numargs, const char ** args)
{
uint32_t x_max,y_max,z_max;
vector<t_vein> veinVector;
vector<t_frozenliquidvein> IceVeinVector;
vector<t_spattervein> splatter;
DFHack::ContextManager DFMgr("Memory.xml");
DFHack::Context * DF;
try
{
DF = DFMgr.getSingleContext();
DF->Attach();
}
catch (exception& e)
{
cerr << e.what() << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
DFHack::Maps *Maps =DF->getMaps();
DFHack::Gui *Gui =DF->getGui();
DFHack::Materials *Mats =DF->getMaterials();
Mats->ReadCreatureTypes();
// init the map
if(!Maps->Start())
{
cerr << "Can't init map." << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
int32_t cx, cy, cz;
Maps->getSize(x_max,y_max,z_max);
Gui->getCursorCoords(cx,cy,cz);
if(cx == -30000)
{
// walk the map
for(uint32_t x = 0; x< x_max;x++) for(uint32_t y = 0; y< y_max;y++) for(uint32_t z = 0; z< z_max;z++)
{
if(Maps->isValidBlock(x,y,z))
{
// look for splater veins
Maps->ReadVeins(x,y,z,0,0,&splatter);
if(splatter.size())
{
printf("Block %d/%d/%d\n",x,y,z);
for(uint32_t i = 0; i < splatter.size(); i++)
{
cout << i << ":" << endl;
printSpatter(DF,splatter[i]);
}
}
}
}
}
else
{
uint32_t bx,by,bz;
bx = cx / 16;
by = cy / 16;
bz = cz;
// look for splater veins
Maps->ReadVeins(bx,by,bz,0,0,&splatter);
if(splatter.size())
{
printf("Block %d/%d/%d\n",bx,by,bz);
for(uint32_t i = 0; i < splatter.size(); i++)
{
printSpatter(DF,splatter[i]);
cout << endl;
}
}
}
#ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl;
cin.ignore();
#endif
return 0;
}

@ -1,146 +0,0 @@
// Just show some position data
#include <iostream>
#include <iomanip>
#include <climits>
#include <vector>
#include <sstream>
#include <ctime>
#include <cstdio>
using namespace std;
#define DFHACK_WANT_MISCUTILS
#include <DFHack.h>
/*
uint16_t material; // +0x3E
uint16_t x; // +0x40
uint16_t y; // +0x42
uint16_t z; // +0x44
uint16_t padding; // +0x46
uint32_t unknown_1; // +0x48
uint16_t temperature_1; // +0x4C
uint16_t temperature_2; // +0x4E - maybe fraction?
uint32_t mystery_flag; // 0x50: yes, just one
uint32_t unknown_2; // 0x54
uint32_t unknown_3; // 0x58
// a vector is here
uint32_t address;
*/
void print_tree( DFHack::Context * DF , DFHack::dfh_plant & tree)
{
DFHack::Materials * mat = DF->getMaterials();
DFHack::t_plant & tdata = tree.sdata;
printf("%d:%d = ",tdata.type,tdata.material);
if(tdata.watery)
{
cout << "near-water ";
}
cout << mat->organic[tdata.material].id << " ";
if(!tdata.is_shrub)
{
cout << "tree";
}
else
{
cout << "shrub";
}
cout << endl;
printf("Grow counter: 0x%08x\n", tdata.grow_counter);
printf("temperature 1: %d\n", tdata.temperature_1);
printf("temperature 2: %d\n", tdata.temperature_2);
printf("On fire: %d\n", tdata.is_burning);
printf("hitpoints: 0x%08x\n", tdata.hitpoints);
printf("update order: %d\n", tdata.update_order);
printf("Address: 0x%x\n", tree.address);
hexdump(DF,tree.address,13*16);
}
int main (int numargs, const char ** args)
{
uint32_t addr;
if (numargs == 2)
{
istringstream input (args[1],istringstream::in);
input >> std::hex >> addr;
}
DFHack::ContextManager DFMgr("Memory.xml");
DFHack::Context * DF;
try
{
DF = DFMgr.getSingleContext();
DF->Attach();
}
catch (exception& e)
{
cerr << e.what() << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
DFHack::Process* p = DF->getProcess();
DFHack::VersionInfo* mem = DF->getMemoryInfo();
DFHack::Gui * Gui = DF->getGui();
DFHack::Vegetation * v = DF->getVegetation();
DFHack::Maps * mps = DF->getMaps();
DFHack::Materials * mat = DF->getMaterials();
mat->ReadOrganicMaterials();
int32_t x,y,z;
Gui->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::dfh_plant tree;
v->Read(i,tree);
printf("%d/%d/%d, %d:%d\n",tree.sdata.x,tree.sdata.y,tree.sdata.z,tree.sdata.type,tree.sdata.material);
}
}
else
{
// new method, gets the vector of trees in a block. can show farm plants
if(mps->Start())
{
vector<DFHack::dfh_plant> alltrees;
if(mps->ReadVegetation(x/16,y/16,z,&alltrees))
{
for(int i = 0 ; i < alltrees.size(); i++)
{
DFHack::dfh_plant & tree = alltrees[i];
// you could take the tree coords from the struct and % them with 16 for use in loops over the whole block
if(tree.sdata.x == x && tree.sdata.y == y && tree.sdata.z == z)
{
cout << "----==== Tree at "<< x << "/" << y << "/" << z << " ====----" << endl;
print_tree(DF, tree);
break;
}
}
}
}
// old method, gets the tree from the global vegetation vector. can't show farm plants
for(uint32_t i =0; i < numVegs; i++)
{
DFHack::dfh_plant tree;
v->Read(i,tree);
if(tree.sdata.x == x && tree.sdata.y == y && tree.sdata.z == z)
{
cout << "----==== Tree at "<< dec << x << "/" << y << "/" << z << " ====----" << endl;
print_tree(DF, tree);
break;
}
}
}
v->Finish();
#ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl;
cin.ignore();
#endif
return 0;
}

@ -1,114 +0,0 @@
if(NOT DEFINED DFHACK_CONSISTENCY)
MESSAGE(FATAL_ERROR "Please build the whole thing, not parts. You can turn parts on/off using options.")
ENDIF()
# this is required to ensure we use the right configuration for the system.
IF(UNIX)
add_definitions(-DLINUX_BUILD)
ENDIF(UNIX)
# a creature mood dump hack. has hardcoded offsets
DFHACK_TOOL(dfmoodump moodump.cpp)
# bauxite - turn all mechanisms into bauxite mechanisms
# Author: Alex Legg
# FIXME: turned off. there is no reliable Items module.
#DFHACK_TOOL(dfbauxite dfbauxite.cpp)
# digger - designate for digging by tile class
# Author: mizipzor
DFHACK_TOOL(dfdigger digger.cpp)
# digger2 - designate for digging from a text file
# Author: rOut
DFHACK_TOOL(dfdigger2 digger2.cpp)
# itemdesignator - change some item designations (dump, forbid, on-fire) for all
# items of a given type and material
# Author: belal
DFHACK_TOOL(dfitemdesignator itemdesignator.cpp)
# catsplosion - Accelerates pregnancy
# Author: Zhentar
# FIXME: no longer works due to changes in DF
#DFHACK_TOOL(dfcatsplosion catsplosion.cpp)
# findnameindexes
# Author: belal
DFHACK_TOOL(dffindnameindexes findnameindexes.cpp)
# try things
DFHACK_TOOL(dftry dftry.cpp)
# renamer - change the custom names and professions of creatures, sends keys to
# df directly
# Author: belal
# DFHACK_TOOL(dfrenamer renamer.cpp)
# copypaste
# Author: belal
# copies the current buildings in a df map, and then designates the area to be dug
# mainly a proof of concept for my gui application dfCopyPaste
DFHACK_TOOL(dfcopypaste copypaste.cpp)
# paths
# Author: belal
# dumps the current path to the DF exe, as well as the relative paths to the
# current tileset and color files
DFHACK_TOOL(dfpaths paths.cpp)
# printtiletypes
# Author: zilpin
# Prints CSV dump of all tile type information.
# No DF process needed. Intended only for debugging and information purposes.
DFHACK_TOOL(dfprinttiletypes printtiletypes.cpp)
# hellhole
# Author: zilpin
# Creates a bottomless hole to hell.
# Experimental version hard-codes values.
# Will have many options in the future.
DFHACK_TOOL(dfhellhole hellhole.cpp)
# drawtile
# Author: zilpin
# Arbitrary tile drawing at the cursor.
# Does not fix tiles above/below for consistency (e.g. ramps).
DFHACK_TOOL(dfdrawtile drawtile.cpp)
# veinswap
# Author: zilpin
# Randomly swap a percentage of the specified vein material with another material.
# Or, set the material of a vein under the cursor.
DFHACK_TOOL(dfveinswap veinswap.cpp)
# lumberjack
# Author: zilpin
# Designate all trees of the given type which can be reached from the cursor.
DFHACK_TOOL(dflumberjack lumberjack.cpp)
# dfcreaturemanager
# Author: raoulxq
# - Display creatures (overview & detail)
# - Modify skills and labors of creatures
# - Kill creatures
# - Etc.
DFHACK_TOOL(dfcreaturemanager creaturemanager.cpp)
# digpattern
# Author: raoulxq
# Dig a specific pattern (in this case 3x3 bedrooms, modify as you like)
DFHACK_TOOL(dfdigpattern digpattern.cpp)
DFHACK_TOOL(dffixbug-3708 fix-3708.cpp)
# blockflags
# Author: matthew cline
# Invert/toggle all block flags, to see what they do.
DFHACK_TOOL(dfblockflags blockflags.cpp)
# this needs the C bindings
IF(BUILD_DFHACK_C_BINDINGS)
# The C bindings won't be real C bindings until this compiles.
#DFHACK_TOOL(dftest test.c)
ENDIF(BUILD_DFHACK_C_BINDINGS)

@ -1,66 +0,0 @@
// Invert/toggle all block flags, to see what they do.
// Seems like they don't do anything...
#include <iostream>
#include <iomanip>
using namespace std;
#include <DFHack.h>
#include <extra/MapExtras.h>
#include <extra/termutil.h>
int main(int argc, char *argv[])
{
bool temporary_terminal = TemporaryTerminal();
uint32_t x_max = 0, y_max = 0, z_max = 0;
DFHack::ContextManager manager("Memory.xml");
DFHack::Context *context = manager.getSingleContext();
if (!context->Attach())
{
std::cerr << "Unable to attach to DF!" << std::endl;
if(temporary_terminal)
std::cin.ignore();
return 1;
}
DFHack::Maps *maps = context->getMaps();
if (!maps->Start())
{
std::cerr << "Cannot get map info!" << std::endl;
context->Detach();
if(temporary_terminal)
std::cin.ignore();
return 1;
}
maps->getSize(x_max, y_max, z_max);
MapExtras::MapCache map(maps);
for(uint32_t z = 0; z < z_max; z++)
{
for(uint32_t b_y = 0; b_y < y_max; b_y++)
{
for(uint32_t b_x = 0; b_x < x_max; b_x++)
{
// Get the map block
DFHack::DFCoord blockCoord(b_x, b_y);
MapExtras::Block *b = map.BlockAt(DFHack::DFCoord(b_x, b_y, z));
if (!b || !b->valid)
{
continue;
}
DFHack::t_blockflags flags = b->BlockFlags();
flags.whole = flags.whole ^ 0xFFFFFFFF;
b->setBlockFlags(flags);
b->Write();
} // block x
} // block y
} // z
maps->Finish();
context->Detach();
return 0;
}

@ -1,133 +0,0 @@
#include <iostream>
#include <fstream>
#include <sstream>
#include <DFHack.h>
using namespace std;
bool getNumber (string prompt, int & output, int def, bool pdef = true)
{
cout << prompt;
if(pdef)
cout << ", default=" << def << endl;
while (1)
{
string select;
cout << ">>";
std::getline(cin, select);
if(select.empty())
{
output = def;
break;
}
else if( sscanf(select.c_str(), "%d", &output) == 1 )
{
break;
}
else
{
continue;
}
}
return true;
}
bool splitvector(const vector<uint64_t> & in, vector<uint64_t> & out1, vector<uint64_t> & out2)
{
size_t length = in.size();
if(length > 1)
{
size_t split = length / 2;
out1.clear();
out2.clear();
out1.insert(out1.begin(),in.begin(),in.begin() + split);
out2.insert(out2.begin(),in.begin() + split,in.end());
return true;
}
return false;
}
void printvector (const vector<uint64_t> &in)
{
cout << "[" << endl;
for(size_t i = 0; i < in.size(); i++)
{
cout << hex << in[i] << endl;
}
cout << "]" << endl;
}
bool tryvals (DFHack::Context * DF, const vector<uint64_t> &in, uint8_t current, uint8_t testing)
{
DF->Suspend();
DFHack::Process * p = DF->getProcess();
for(size_t i = 0; i < in.size(); i++)
{
p->writeByte(in[i],testing);
}
DF->Resume();
int result;
while (!getNumber("Is the change good? 0 for no, positive for yes.",result,0));
DF->Suspend();
for(size_t i = 0; i < in.size(); i++)
{
p->writeByte(in[i],current);
}
DF->Resume();
if(result)
return true;
return false;
}
bool dotry (DFHack::Context * DF, const vector<uint64_t> &in, uint8_t current, uint8_t testing)
{
vector <uint64_t> a, b;
bool found = false;
if(!tryvals(DF,in,current,testing))
return false;
if(splitvector(in, a,b))
{
if(dotry(DF, a, current, testing))
return true;
if(dotry(DF, b, current, testing))
return true;
return false;
}
return false;
}
int main()
{
vector <uint64_t> addresses;
vector <uint64_t> a1;
vector <uint64_t> a2;
vector <uint8_t> values;
string line;
DFHack::ContextManager CM("Memory.xml");
DFHack::Context * DF = CM.getSingleContext();
if(!DF)
return 1;
DF->Resume();
ifstream fin("siege.txt");
if(!fin.is_open())
return 1;
do
{
getline(fin,line);
stringstream input (line);
input << hex;
uint64_t value;
input >> value;
if(value)
{
cout << hex << value << endl;
addresses.push_back(value);
}
} while (!fin.eof());
int val_current,val_testing;
while (!getNumber("Insert current value",val_current,1));
while (!getNumber("Insert testing value",val_testing,0));
dotry(DF, addresses,val_current,val_testing);
return 0;
}

@ -1,111 +0,0 @@
// Dwarf fortress names are a complicated beast, in objects they are displayed
// as indexes into the language vectors
//
// use this tool if you are trying to find what the indexes are for a displayed
// name, so you can then search for it in your object
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <sstream>
using namespace std;
#include <DFHack.h>
// returns a lower case version of the string
string tolower (const string & s)
{
string d (s);
transform (d.begin (), d.end (), d.begin (), (int(*)(int)) tolower);
return d;
}
string groupBy2(const string & s)
{
string d;
for(int i =2;i<s.length();i++){
if(i%2==0)
{
d+= s.substr(i-2,2) + " ";
}
}
d+=s.substr(s.length()-2,2);
return(d);
}
uint32_t endian_swap(uint32_t x)
{
x = (x>>24) |
((x<<8) & 0x00FF0000) |
((x>>8) & 0x0000FF00) |
(x<<24);
return x;
}
int main (void)
{
DFHack::ContextManager DF("Memory.xml");
DFHack::Context * C;
DFHack::Translation * Tran;
try
{
C = DF.getSingleContext();
}
catch (exception& e)
{
cerr << e.what() << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
Tran = C->getTranslation();
if(!Tran->Start())
{
cerr << "Could not get Names" << endl;
return 1;
}
DFHack::Dicts dicts = *(Tran->getDicts());
DFHack::DFDict & englishWords = dicts.translations;
DFHack::DFDict & foreignWords = dicts.foreign_languages;
C->Detach();
string input;
cout << "\nSelect Name to search or q to Quit" << endl;
getline (cin, input);
while(input != "q"){
for( uint32_t i = 0; i < englishWords.size();i++){
for( uint32_t j = 0;j < englishWords[i].size();j++){
if(englishWords[i][j] != ""){
uint32_t found = tolower(input).find(tolower(englishWords[i][j]));
if(found != string::npos){
stringstream value;
value << setfill('0') << setw(8) << hex << endian_swap(j);
cout << englishWords[i][j] << " " << groupBy2(value.str()) << endl;
}
}
}
}
for( uint32_t i = 0; i < foreignWords.size();i++){
for( uint32_t j = 0;j < foreignWords[i].size();j++){
uint32_t found = tolower(input).find(tolower(foreignWords[i][j]));
if(found != string::npos){
stringstream value;
value << setfill('0') << setw(8) << hex << endian_swap(j);
cout << foreignWords[i][j] << " " << groupBy2(value.str()) << endl;
}
}
}
getline(cin,input);
}
#ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl;
cin.ignore();
#endif
return 0;
}

File diff suppressed because it is too large Load Diff

@ -1,219 +0,0 @@
/*
* Author: Silas Dunsmore aka 0x517A5D vim:ts=4:sw=4
*
* Released under the MIT X11 license; feel free to use some or all of this
* code, as long as you include the copyright and license statement (below)
* in all copies of the source code. In fact, I truly encourage reuse.
*
* If you do use large portions of this code, I suggest but do not require
* that you keep this code in a seperate file (such as this hexsearch.h file)
* so that it is clear that the terms of the license do not also apply to
* your code.
*
* Should you make fundamental changes, or bugfixes, to this code, I would
* appreciate it if you would give me a copy of your changes.
*
*
* Copyright (C) 2007-2008 Silas Dunsmore
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* See also: http://www.opensource.org/licenses/mit-license.php
* and http://en.wikipedia.org/wiki/MIT_License
*/
#ifndef HEXSEARCH_H
#define HEXSEARCH_H
#ifdef __cplusplus
extern "C"
{
#endif
extern DWORD df_memory_base, df_memory_start, df_memory_end;
extern HANDLE df_h_process, df_h_thread;
extern DWORD df_pid, df_main_win_tid;
extern DWORD here[16];
extern DWORD target[16];
// ============================================================================
// export these in case you need to work with them directly.
//extern HANDLE df_h_process, df_h_thread;
//extern DWORD df_pid, df_main_win_tid;
extern char *errormessage;
// ============================================================================
// send info to KERNEL32:OutputDebugString(), useful for non-console programs.
// (you can watch this with SysInternals' DebugView.)
// http://www.microsoft.com/technet/sysinternals/Miscellaneous/DebugView.mspx
void d_printf(const char *format, ...);
// it turned out that dprintf() is semi-standard to printf to a file descriptor.
// ============================================================================
// encapsulate the housekeeping.
BOOL open_dwarf_fortress(void);
void close_dwarf_fortress(void); // is not (normally) necessary because
// it is done at exit time.
// ============================================================================
// memory reads and writes (peeks and pokes, in old BASIC terminology)
BOOL isvalidaddress(DWORD ea);
BOOL peekarb(DWORD ea, OUT void *data, DWORD len);
BYTE peekb(DWORD ea);
WORD peekw(DWORD ea);
DWORD peekd(DWORD ea);
char *peekstr(DWORD ea, OUT char *data, DWORD maxlen);
char *peekustr(DWORD ea, OUT char *data, DWORD maxlen);
BOOL pokearb(DWORD ea, const void *data, DWORD len);
BOOL pokeb(DWORD ea, BYTE data);
BOOL pokew(DWORD ea, WORD data);
BOOL poked(DWORD ea, DWORD data);
BOOL pokestr(DWORD ea, const BYTE *data);
// ============================================================================
// The name has changed because the API HAS CHANGED!
//
// Now instead of returning HERE, it always returns the start of the match.
//
// However, there is an array, here[], that is filled with the locations of
// the HERE tokens.
// (Starting at 1. here[0] is a copy of the start of the match.)
//
// The here[] array, starting at 1, is filled with the locations of the
// HERE token.
// here[0] is a copy of the start of the match.
//
// Also, the target[] array, starting at 1, is filled with the target
// addresses of all CALL, JMP, JZ, JNZ, and JCC tokens.
//
// Finally, you no longer pass it a search length. Instead, each set of
// search terms must end with an EOL.
//
//
//
// Okay, I admit this one is complicated. Treat it as a black box.
//
// Search Dwarf Fortress's code and initialized data segments for a pattern.
// (Does not search stack, heap, or thread-local memory.)
//
// Parameters: any number of search tokens, all unsigned ints.
// The last token must be EOL.
//
// 0x00 - 0xFF: Match this byte.
// EOL: End-of-list. The match succeeds when this token is reached.
// ANYBYTE: Match any byte.
// DWORD_: Followed by a dword. Exact-match the dword.
// Equivalent to 4 match-this-byte tokens.
// ANYDWORD: Match any dword. Equivalant to 4 ANYBYTEs.
// HERE: Put the current address into the here[] array.
// SKIP_UP_TO, nn: Allow up to nn bytes between the previous match
// and the next match. The next token must be a match-this-byte
// token. There is sweet, sweet backtracking.
// EITHER: Accept either of the next two tokens as a match.
// Both must be match-this-byte tokens.
// RANGE_LO, nn: Set low byte for a range comparison. DEPRECATED.
// RANGE_HI, nn: Set high byte for a range comparison, and do the
// comparison. Should immediately follow a RANGE_LO. DEPRECATED.
// BYTERANGE, nn, mm: followed by two bytes, the low and high limits
// of the range. This is the new way to do ranges.
// DWORDRANGE, nnnnnnnn, mmmmmmmm: works like BYTERANGE.
// ADDRESS: Accept any legal address in the program's text.
// DOES NOT accept pointers into heap space and such.
// CALL: Match a near call instruction to a reasonable address.
// JUMP: Match a short or near unconditional jump to a reasonable
// address.
// JZ: Match a short or long jz (jump if zero) instruction.
// JNZ: Match a short or long jnz (jump if not zero) instruction.
// JCC: Match any short or long conditional jump instruction.
// More tokens can easily be added.
//
// Returns the offset in Dwarf Fortress of the first match of the pattern.
// Also sets global variables here[] and target[].
//
// Note: starting a pattern with ANYBYTE, ANYDWORD, SKIP_UP_TO, or EOL
// is explicitly illegal.
//
#define EOL 0x100
#define ANYBYTE 0x101
//#define FF_OR_00 0x102 // deprecated
#define HERE 0x103
#define EITHER 0x104
#define SKIP_UP_TO 0x105
#define RANGE_LO 0x106 // deprecated
#define RANGE_HI 0x107 // deprecated
#define DWORD_ 0x108
#define ANYDWORD 0x109
#define ADDRESS 0x10A
#define BYTERANGE 0x10B
#define DWORDRANGE 0x10C
#define JZ 0x174
#define JNZ 0x175
#define JCC 0x170
#define CALL 0x1E8
#define JUMP 0x1E9
DWORD hexsearch2(DWORD token1, ...);
// You can use this to limit the search to a particular part of memory.
// Use 0 for start to search from the very start of Dwarf Fortress.
// Use 0 for end to stop searching at the very end of Dwarf Fortress.
void set_hexsearch2_limits(DWORD start, DWORD end);
// ============================================================================
// patch2() and verify2() support a modified subset of hex_search2() tokens:
// The names changed because the API HAS CHANGED!
//
// 0x00 - 0xFF: pokes the byte.
// EOL: End-of-list. Allows you to specify count as 10000 or so
// and terminate (with success) when this token is reached.
// DWORD_: Followed by a DWORD. Pokes the DWORD.
// CALL: given an _address_; pokes near call with the proper _delta_.
// JUMP: given an _address_; pokes near jump with the proper _delta_.
// JZ: given an _address_; assembles a near (not short) jz & delta.
// JNZ: given an _address_; assembles a near jnz & delta.
//
// Particularly note that, unlike hex_search(), CALL, JUMP, JZ, and JNZ
// are followed by a dword-sized target address.
//
// Note that patch2() does its own verify(), so you don't have to.
// TODO: is verify() useful enough to maintain?
// Make an offset in Dwarf Fortress have certain bytes.
BOOL patch2(DWORD offset, ...);
// Check that an offset in Dwarf Fortress has certain bytes.
BOOL verify2(DWORD offset, ...);
#ifdef __cplusplus
}
#endif
#endif // HEXSEARCH_H

@ -1,5 +0,0 @@
int main (int numargs, const char ** args)
{
return 0;
}

@ -1,119 +0,0 @@
#include <iostream>
#include <climits>
#include <vector>
#include <stdio.h>
using namespace std;
#include <DFHack.h>
DFHack::Materials * Materials;
DFHack::VersionInfo *mem;
vector< vector<string> > englishWords;
vector< vector<string> > foreignWords;
int main (int numargs, char ** args)
{
DFHack::ContextManager DFMgr("Memory.xml");
DFHack::Context *DF = DFMgr.getSingleContext();
DFHack::Process * p;
try
{
DF->Attach();
}
catch (exception& e)
{
cerr << e.what() << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
p = DF->getProcess();
string check = "";
if(numargs == 2)
check = args[1];
DFHack::Creatures * Creatures = DF->getCreatures();
Materials = DF->getMaterials();
DFHack::Translation * Tran = DF->getTranslation();
uint32_t numCreatures;
if(!Creatures->Start(numCreatures))
{
cerr << "Can't get creatures" << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
if(!numCreatures)
{
cerr << "No creatures to print" << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
mem = DF->getMemoryInfo();
if(!Materials->ReadInorganicMaterials())
{
cerr << "Can't get the inorganics types." << endl;
return 1;
}
if(!Materials->ReadCreatureTypesEx())
{
cerr << "Can't get the creature types." << endl;
return 1;
}
if(!Tran->Start())
{
cerr << "Can't get name tables" << endl;
return 1;
}
vector<uint32_t> addrs;
//DF.InitViewAndCursor();
for(uint32_t i = 0; i < numCreatures; i++)
{
DFHack::t_creature temp;
unsigned int current_job;
unsigned int mat_start;
unsigned int mat_end;
unsigned int j,k;
unsigned int matptr;
Creatures->ReadCreature(i,temp);
if(temp.mood>=0)
{
current_job = p->readDWord(temp.origin + 0x390);
if(current_job == 0)
continue;
mat_start = p->readDWord(current_job + 0xa4 + 4*3);
mat_end = p->readDWord(current_job + 0xa4 + 4*4);
for(j=mat_start;j<mat_end;j+=4)
{
matptr = p->readDWord(j);
for(k=0;k<4;k++)
printf("%.4X ", p->readWord(matptr + k*2));
for(k=0;k<3;k++)
printf("%.8X ", p->readDWord(matptr + k*4 + 0x8));
for(k=0;k<2;k++)
printf("%.4X ", p->readWord(matptr + k*2 + 0x14));
for(k=0;k<3;k++)
printf("%.8X ", p->readDWord(matptr + k*4 + 0x18));
for(k=0;k<4;k++)
printf("%.2X ", p->readByte(matptr + k + 0x24));
for(k=0;k<6;k++)
printf("%.8X ", p->readDWord(matptr + k*4 + 0x28));
for(k=0;k<4;k++)
printf("%.2X ", p->readByte(matptr + k + 0x40));
for(k=0;k<9;k++)
printf("%.8X ", p->readDWord(matptr + k*4 + 0x44));
printf(" [%p]\n", matptr);
}
}
}
Creatures->Finish();
DF->Detach();
return 0;
}

@ -1,31 +0,0 @@
#include <iostream>
using namespace std;
#include <DFHack.h>
using namespace DFHack;
int main ()
{
DFHack::ContextManager DFMgr("Memory.xml");
DFHack::Context *DF = DFMgr.getSingleContext();
try
{
DF->Attach();
}
catch (exception& e)
{
cerr << e.what() << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
DFHack::Process * Process = DF->getProcess();
DFHack::Gui * gui = DF->getGui();
cout << Process->getPath() << endl;
#ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl;
cin.ignore();
#endif
return 0;
}

@ -1,27 +0,0 @@
#include <iostream>
#include <iomanip>
#include <climits>
#include <vector>
#include <sstream>
#include <ctime>
#include <cstdio>
using namespace std;
std::string teststr1;
std::string * teststr2;
std::string teststr3("test");
int main (int numargs, const char ** args)
{
printf("std::string E : 0x%x\n", &teststr1);
teststr1 = "This is a fairly long string, much longer than the one made by default constructor.";
cin.ignore();
printf("std::string L : 0x%x\n", &teststr1);
teststr1 = "This one is shorter";
cin.ignore();
printf("std::string S : 0x%x\n", &teststr1);
cin.ignore();
teststr2 = new string();
printf("std::string * : 0x%x\n", &teststr2);
printf("std::string(\"test\") : 0x%x\n", &teststr3);
cin.ignore();
return 0;
}

@ -1,100 +0,0 @@
// Prints all the Tile Types known by DFHack.
// File is both fixed-field and CSV parsable.
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <vector>
#include <map>
#include <stddef.h>
#include <assert.h>
using namespace std;
#include <DFHack.h>
#include <DFTileTypes.h>
using namespace DFHack;
int main (int argc, char **argv)
{
FILE *f=stdout;
const int Columns = 7;
const char * Headings[Columns] = {"TileTypeID","Class","Material","V","Special","Direction","Description"};
size_t Size[ Columns ] = {};
int i;
//First, figure out column widths.
for(i=0;i<Columns;++i)
{
Size[i]=strlen(Headings[i])+1;
}
//Classes
fprintf(f,"\nTile Type Classes:\n");
for(i=0;i<tileshape_count;++i)
{
Size[1]=max<size_t>(Size[1],strlen(TileShapeString[i]));
fprintf(f,"%4i ; %s\n", i, TileShapeString[i] ,0 );
}
//Materials
fprintf(f,"\nTile Type Materials:\n");
for(i=0;i<tilematerial_count;++i)
{
Size[2]=max<size_t>(Size[2],strlen(TileMaterialString[i]));
fprintf(f,"%4i ; %s\n", i, TileMaterialString[i] ,0 );
}
//Specials
fprintf(f,"\nTile Type Specials:\n");
for(i=0;i<tilespecial_count;++i)
{
Size[4]=max<size_t>(Size[4],strlen(TileSpecialString[i]));
fprintf(f,"%4i ; %s\n", i, TileSpecialString[i] ,0 );
}
/* - Not needed for now -
//Direction is tricky
for(i=0;i<TILE_TYPE_ARRAY_LENGTH;++i)
Size[5]=max(Size[5], tileTypeTable[i].d.sum()+1 );
*/
//Print the headings first.
fprintf(f,"\nTile Types:\n");
for(i=0;i<Columns;++i)
{
if(i) putc(';',f);
fprintf(f," %-*s ",Size[i],Headings[i],0);
}
fprintf(f,"\n");
//Process the whole array.
//A macro should be used for making the strings safe, but they are left in naked ? blocks
//to illustrate the array references more clearly.
for(i=0;i<TILE_TYPE_ARRAY_LENGTH;++i)
{
fprintf(f," %*i ; %-*s ; %-*s ; %*c ; %-*s ; %-*s ; %s\n",
Size[0], i,
Size[1], ( tileTypeTable[i].name ? TileShapeString[ tileTypeTable[i].shape ] : "" ),
Size[2], ( tileTypeTable[i].name ? TileMaterialString[ tileTypeTable[i].material ] : "" ),
Size[3], ( tileTypeTable[i].variant ? '0'+tileTypeTable[i].variant : ' ' ),
Size[4], ( tileTypeTable[i].special ? TileSpecialString[ tileTypeTable[i].special ] : "" ),
Size[5], ( tileTypeTable[i].direction.whole ? tileTypeTable[i].direction.getStr() : "" ),
( tileTypeTable[i].name ? tileTypeTable[i].name : "" ),
0
);
}
fprintf(f,"\n");
#ifndef LINUX_BUILD
if( 1== argc)
{
cout << "Done. Press any key to continue" << endl;
cin.ignore();
}
#endif
return 0;
}

@ -1,470 +0,0 @@
// Creature dump
#include <iostream>
#include <sstream>
#include <climits>
#include <vector>
using namespace std;
#define DFHACK_WANT_MISCUTILS
#include <DFHack.h>
#include <modules/Materials.h>
#include <modules/Units.h>
#include <modules/Translation.h>
vector< vector<string> > englishWords;
vector< vector<string> > foreignWords;
uint32_t numCreatures;
vector<DFHack::t_matgloss> creaturestypes;
void printDwarves(DFHack::ContextManager & DF)
{
int dwarfCounter = 0;
DFHack::Creatures * c = DF.getCreatures();
for (uint32_t i = 0; i < numCreatures; i++)
{
DFHack::t_creature temp;
c->ReadCreature(i, temp);
string type = creaturestypes[temp.type].id;
if (type == "DWARF" && !temp.flags1.bits.dead && !temp.flags2.bits.killed)
{
cout << i << ":";
if (temp.name.nickname[0])
{
cout << temp.name.nickname;
}
else
{
cout << temp.name.first_name;
}
string transName = DF.TranslateName(temp.name,englishWords,foreignWords, false);
cout << " " << temp.custom_profession; //transName;
if (dwarfCounter%3 != 2)
{
cout << '\t';
}
else
{
cout << endl;
}
dwarfCounter++;
}
}
}
bool getDwarfSelection(DFHack::ContextManager & DF, DFHack::t_creature & toChange,string & changeString, string & commandString,int & eraseAmount,int &dwarfNum,bool &isName)
{
static string lastText;
bool dwarfSuccess = false;
while (!dwarfSuccess)
{
string input;
cout << "\nSelect Dwarf to Change or q to Quit" << endl;
DF.Resume();
getline (cin, input);
DF.Suspend();
if (input == "q")
{
return false;
}
else if (input == "r")
{
printDwarves(DF);
}
else if (!input.empty())
{
int num;
stringstream(input) >> num;//= atol(input.c_str());
dwarfSuccess = DF.ReadCreature(num,toChange);
string type = creaturestypes[toChange.type].id;
if (type != "DWARF")
{
dwarfSuccess = false;
}
else
{
dwarfNum = num;
}
}
}
bool changeType = false;
while (!changeType)
{
string input;
cout << "\n(n)ickname or (p)rofession?" << endl;
getline(cin, input);
if (input == "q")
{
return false;
}
if (input == "n")
{
commandString = "pzyn";
eraseAmount = string(toChange.name.nickname).length();
changeType = true;
isName = true;
}
else if (input == "p")
{
commandString = "pzyp";
eraseAmount = string(toChange.custom_profession).length();
changeType = true;
isName = false;
}
}
bool changeValue = false;
while (!changeValue)
{
string input;
cout << "value to change to?" << endl;
getline(cin, input);
if (input == "q")
{
return false;
}
if (!lastText.empty() && input.empty())
{
changeValue = true;
}
else if ( !input.empty())
{
lastText = input;
changeValue = true;
}
}
changeString = lastText;
return true;
}
bool waitTillChanged(DFHack::ContextManager &DF, int creatureToCheck, string changeValue, bool isName)
{
DFHack::DFWindow * w = DF.getWindow();
DF.Suspend();
DFHack::t_creature testCre;
DF.ReadCreature(creatureToCheck,testCre);
int tryCount = 0;
if (isName)
{
while (testCre.name.nickname != changeValue && tryCount <50)
{
DF.Resume();
w->TypeSpecial(DFHack::WAIT,1,100);
DF.Suspend();
DF.ReadCreature(creatureToCheck,testCre);
tryCount++;
}
}
else
{
while (testCre.custom_profession != changeValue && tryCount < 50)
{
DF.Resume();
w->TypeSpecial(DFHack::WAIT,1,100);
DF.Suspend();
DF.ReadCreature(creatureToCheck,testCre);
tryCount++;
}
}
if (tryCount >= 50)
{
cerr << "Something went wrong, make sure that DF is at the correct screen";
return false;
}
DF.Resume();
return true;
}
bool waitTillScreenState(DFHack::ContextManager &DF, string screenState,bool EqualTo=true)
{
DFHack::DFWindow * w = DF.getWindow();
DFHack::t_viewscreen current;
DF.Suspend();
DF.ReadViewScreen(current);
string nowScreenState;
DF.getMemoryInfo()->resolveClassIDToClassname(current.type,nowScreenState);
int tryCount = 0;
while (((EqualTo && nowScreenState != screenState) || (!EqualTo && nowScreenState == screenState)) && tryCount < 50)
{
DF.Resume();
w->TypeSpecial(DFHack::WAIT,1,100);
DF.Suspend();
DF.ReadViewScreen(current);
tryCount++;
}
if (tryCount >= 50) {
cerr << "Something went wrong, DF at " << nowScreenState << endl;
return false;
}
DF.Resume();
return true;
}
bool waitTillCursorState(DFHack::ContextManager &DF, bool On)
{
DFHack::DFWindow * w = DF.getWindow();
int32_t x,y,z;
int tryCount = 0;
DF.Suspend();
bool cursorResult = DF.getCursorCoords(x,y,z);
while (tryCount < 50 && On && !cursorResult || !On && cursorResult)
{
DF.Resume();
w->TypeSpecial(DFHack::WAIT,1,100);
tryCount++;
DF.Suspend();
cursorResult = DF.getCursorCoords(x,y,z);
}
if (tryCount >= 50)
{
cerr << "Something went wrong, cursor at x: " << x << " y: " << y << " z: " << z << endl;
return false;
}
DF.Resume();
return true;
}
bool waitTillMenuState(DFHack::ContextManager &DF, uint32_t menuState,bool EqualTo=true)
{
int tryCount = 0;
DFHack::DFWindow * w = DF.getWindow();
DF.Suspend();
uint32_t testState = DF.ReadMenuState();
while (tryCount < 50 && ((EqualTo && menuState != testState) || (!EqualTo && menuState == testState)))
{
DF.Resume();
w->TypeSpecial(DFHack::WAIT,1,100);
tryCount++;
DF.Suspend();
testState = DF.ReadMenuState();
}
if (tryCount >= 50)
{
cerr << "Something went wrong, menuState: "<<testState << endl;
return false;
}
DF.Resume();
return true;
}
bool moveToBaseWindow(DFHack::ContextManager &DF)
{
DFHack::DFWindow * w = DF.getWindow();
DFHack::t_viewscreen current;
DF.ReadViewScreen(current);
string classname;
DF.getMemoryInfo()->resolveClassIDToClassname(current.type,classname);
while (classname != "viewscreen_dwarfmode")
{
w->TypeSpecial(DFHack::F9); // cancel out of text input in names
// DF.TypeSpecial(DFHack::ENTER); // cancel out of text input in hotkeys
w->TypeSpecial(DFHack::SPACE); // should move up a level
if (!waitTillScreenState(DF,classname,false)) return false; // wait until screen changes from current
DF.ReadViewScreen(current);
DF.getMemoryInfo()->resolveClassIDToClassname(current.type,classname);
}
if (DF.ReadMenuState() != 0) {// if menu state != 0 then there is a menu, so escape it
w->TypeSpecial(DFHack::F9);
w->TypeSpecial(DFHack::ENTER); // exit out of any text prompts
w->TypeSpecial(DFHack::SPACE); // go back to base state
if (!waitTillMenuState(DF,0))return false;
}
DF.Resume();
return true;
}
bool setCursorToCreature(DFHack::ContextManager &DF)
{
DFHack::DFWindow * w = DF.getWindow();
int32_t x,y,z;
DF.Suspend();
DF.getCursorCoords(x,y,z);
DF.Resume();
if (x == -30000) {
w->TypeStr("v");
if (!waitTillCursorState(DF,true)) return false;
}
else { // reset the cursor to be the creature cursor
w->TypeSpecial(DFHack::SPACE);
if (!waitTillCursorState(DF,false)) return false;
w->TypeStr("v");
if (!waitTillCursorState(DF,true)) return false;
}
return true;
}
int main (void)
{
DFHack::ContextManager DF("Memory.xml");
DFHack::Creatures *c;
DFHack::Materials *m;
try
{
DF.Attach();
c = DF.getCreatures();
}
catch (exception& e)
{
cerr << e.what() << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
DFHack::memory_info * mem = DF.getMemoryInfo();
if (!m->ReadCreatureTypes(creaturestypes))
{
cerr << "Can't get the creature types." << endl;
return 1;
}
DF.InitReadNameTables(englishWords,foreignWords);
c->Start(numCreatures);
// DF.InitViewAndCursor();
DFHack::Process * p = DF.getProcess();
DFHack::DFWindow * w = DF.getWindow();
DFHack::t_creature toChange;
string changeString,commandString;
int eraseAmount;
int toChangeNum;
bool isName;
bool useKeys = true;
string input2;
// use key event emulation or direct writing?
cout << "\nUse \n1:Key simulation\n2:Direct Writing" << endl;
getline(cin,input2);
if (input2 == "1")
{
useKeys = true;
}
else {
useKeys = false;
}
printDwarves(DF);
while (getDwarfSelection(DF,toChange,changeString,commandString,eraseAmount,toChangeNum,isName))
{
// limit length, DF doesn't accept input after this point
if (changeString.size() > 39)
{
changeString.resize(39);
}
start:
bool completed = false;
if (useKeys) {
if (moveToBaseWindow(DF) && setCursorToCreature(DF))
{
DF.Suspend();
DF.setCursorCoords(toChange.x, toChange.y,toChange.z);
uint32_t underCursor;
DF.getCurrentCursorCreature(underCursor);
while (underCursor != toChangeNum)
{
DF.Resume();
w->TypeStr("v",100);
DF.Suspend();
DF.setCursorCoords(toChange.x, toChange.y,toChange.z);
DF.ReadCreature(toChangeNum,toChange);
DF.getCurrentCursorCreature(underCursor);
}
/*//CurrentCursorCreatures gives the creatures in the order that you see them with the 'k' cursor.
//The 'v' cursor displays them in the order of last, then first,second,third and so on
//Pretty weird, but it works
//The only place that seems to display which creature is currently selected is on the stack, whose location is likely not static, so not usable
if (underCursor[underCursor.size()-1] != toChange.origin)
{
for (int i = 0;i<underCursor.size()-1;i++)
{
DF.Resume();
w->TypeStr("v",100);
if (underCursor[i] == toChange.origin)
{
break;
}
}
}*/
DF.Resume();
w->TypeStr(commandString.c_str());
if (waitTillScreenState(DF,"viewscreen_customize_unit"))
{
DF.Resume();
w->TypeSpecial(DFHack::BACK_SPACE,eraseAmount);
if (waitTillChanged(DF,toChangeNum,"",isName))
{
DF.Resume();
w->TypeStr(changeString.c_str());
if (waitTillChanged(DF,toChangeNum,changeString,isName))
{
DF.Resume();
w->TypeSpecial(DFHack::ENTER);
w->TypeSpecial(DFHack::SPACE); // should take you to unit screen if everything worked
if (waitTillScreenState(DF,"viewscreen_unit"))
{
DF.Resume();
w->TypeSpecial(DFHack::SPACE);
if (waitTillScreenState(DF,"viewscreen_dwarfmode"))
{
DF.Resume();
w->TypeSpecial(DFHack::SPACE);
if (waitTillCursorState(DF,false))
{
completed = true;
}
}
}
}
}
}
}
if (!completed) {
cerr << "Something went wrong, please reset DF to its original state, then press any key to continue" << endl;
goto start;
}
}
else
{
// will only work with the shm probably should check for it, but I don't know how,
// I have the writeString function do nothing for normal mode
if (commandString == "pzyn") // change nickname
{
try
{
uint32_t nickname = mem->getOffset("creature_name") + mem->getOffset("name_nickname");
p->writeSTLString(toChange.origin+nickname,changeString);
}
catch (DFHack::Error::AllMemdef&)
{
cerr << "Writing creature nicknames unsupported in this version!" << endl;
}
}
else
{
try
{
uint32_t custom_prof = mem->getOffset("creature_custom_profession");
p->writeSTLString(toChange.origin+custom_prof,changeString);
}
catch (DFHack::Error::AllMemdef&)
{
cerr << "Writing creature custom profession unsupported in this version!" << endl;
}
}
}
DF.Suspend();
printDwarves(DF);
}
return 0;
}

@ -1,58 +0,0 @@
#include <limits.h>
#include <time.h>
#include <stdio.h>
#include <DFHack_C.h>
#include <dfhack-c/DFTypes_C.h>
#include <dfhack-c/DFContext_C.h>
#include <dfhack-c/modules/Maps_C.h>
int main (int numargs, const char ** args)
{
printf("From C: ");
DFHackObject* cman = ContextManager_Alloc("Memory.xml");
DFHackObject* context = ContextManager_getSingleContext(cman);
if(context)
{
Context_Attach(context);
DFHackObject * maps = Context_getMaps(context);
if(maps)
{
Maps_Start(maps);
uint32_t x,y,z;
Maps_getSize(maps, &x, &y, &z);
printf("Map size: %d, %d, %d\n", x,y,z);
}
}
ContextManager_Free(cman);
cout << "From C++:";
DFHack::ContextManager DFMgr("Memory.xml");
DFHack::Context * DF;
try
{
DF = DFMgr.getSingleContext();
DF->Attach();
}
catch (exception& e)
{
cerr << e.what() << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
// DO STUFF HERE
Maps * m = DF->getMaps();
m->Start();
uint32_t x,y,z;
m->getSize(x,y,z);
cout << "Map size " << x << ", "<< y << ", " << z << endl;
#ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl;
cin.ignore();
#endif
return 0;
}

@ -1,43 +0,0 @@
#include <iostream>
#include <iomanip>
#include <climits>
#include <vector>
#include <sstream>
#include <ctime>
#include <cstdio>
using namespace std;
#include <DFHack.h>
using namespace DFHack;
namespace TBlocks
{
}
int main (int numargs, const char ** args)
{
DFHack::ContextManager DFMgr("Memory.xml");
DFHack::Context * DF;
try
{
DF = DFMgr.getSingleContext();
DF->Attach();
}
catch (exception& e)
{
cerr << e.what() << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
// DO STUFF HERE
#ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl;
cin.ignore();
#endif
return 0;
}

@ -1,121 +0,0 @@
if(NOT DEFINED DFHACK_CONSISTENCY)
MESSAGE(FATAL_ERROR "Please build the whole thing, not parts. You can turn parts on/off using options/ccmake during build.")
ENDIF()
# this is required to ensure we use the right configuration for the system.
IF(UNIX)
add_definitions(-DLINUX_BUILD)
ENDIF()
# burn trees and shrubs to ashes
DFHACK_TOOL(dfimmolate immolate.cpp)
IF(WIN32)
INSTALL(
PROGRAMS dfimmolate-all.bat dfimmolate-fire.bat dfimmolate-shrubs.bat dfimmolate-shrubs-fire.bat dfimmolate-trees.bat dfimmolate-trees-fire.bat
DESTINATION ${DFHACK_BINARY_DESTINATION}
)
ENDIF()
# grow saplings into trees instantly
DFHACK_TOOL(dfgrow grow.cpp)
# a reveal clone
DFHACK_TOOL(dfreveal reveal.cpp)
# re-hide borked reveals
DFHACK_TOOL(dfunreveal unreveal.cpp)
# designate all visible floor tiles as lair, freezing items in place
DFHACK_TOOL(dflair lair.cpp)
# force pause!
DFHACK_TOOL(dfpause forcepause.cpp)
# prospector - produces a list of available materials and their quantities
DFHACK_TOOL(dfprospector prospector.cpp)
IF(WIN32)
INSTALL(PROGRAMS dfprospector-text.bat dfprospector-all.bat DESTINATION ${DFHACK_BINARY_DESTINATION})
ENDIF()
# vdig - dig the vein under the cursor
DFHACK_TOOL(dfvdig vdig.cpp)
IF(WIN32)
INSTALL(PROGRAMS dfXvdig.bat DESTINATION ${DFHACK_BINARY_DESTINATION})
ENDIF()
# cleanmap - removes mud, snow, blood and similar stuff from a map. farmers beware
DFHACK_TOOL(dfcleanmap cleanmap.cpp)
# cleanowned - confiscate items owned by dwarves so they can be atomsmashed/reused/etc.
DFHACK_TOOL(dfcleanowned cleanowned.cpp)
IF(WIN32)
INSTALL(PROGRAMS dfconfiscate.bat dfremovelitter.bat DESTINATION ${DFHACK_BINARY_DESTINATION})
ENDIF()
# unstuck - make DF run if something goes wrong with the 'normal' memory access method
DFHACK_TOOL(dfunstuck unstuck.cpp)
# probe - map tile probe
DFHACK_TOOL(dfprobe probe.cpp)
# attachtest - 100x attach/detach, suspend/resume
DFHACK_TOOL(dfattachtest attachtest.cpp)
# a benchmark program, reads the map 1000x
DFHACK_TOOL(dfexpbench expbench.cpp)
# suspendtest - test if suspend works. df should stop responding when suspended
# by dfhack
DFHACK_TOOL(dfsuspend suspendtest.cpp)
# flows - check flows impact on fps
DFHACK_TOOL(dfflows flows.cpp)
# liquids manipulation tool
# Original author: Aleric
DFHACK_TOOL(dfliquids liquids.cpp)
# Solves the problem of unusable items after reclaim by clearing the 'in_job' bit of all items.
# Original author: Quietust
DFHACK_TOOL(dfcleartask cleartask.cpp)
# position - check the DF window and cursor parameters
DFHACK_TOOL(dfposition position.cpp)
# mode - a utility to change the current game and control modes
DFHACK_TOOL(dfmode mode.cpp)
# just dump offsets of the current version
DFHACK_TOOL(dfdoffsets dumpoffsets.cpp)
# change the weather
DFHACK_TOOL(dfweather weather.cpp)
# refill adamantine veins
DFHACK_TOOL(dftubefill dftubefill.cpp)
# deramp
# Author: zilpin
# seeks entire map for 'remove ramp' designation, makes a floor, removes designation.
# intended use is to simulate old 'channel' functionality.
DFHACK_TOOL(dfderamp deramp.cpp)
# incrementalsearch - a bit like cheat engine, only DF-specific, very basic
#DFHACK_TOOL(dfautosearch autosearch.cpp)
DFHACK_TOOL(dfincremental incrementalsearch.cpp)
# auto dump. dumps all items marked for dumping at the cursor position without the need for dwarf labor.
# ... or just kills the items? :P
DFHACK_TOOL(dfautodump autodump.cpp)
IF(WIN32)
INSTALL(PROGRAMS dfautodestroy.bat DESTINATION ${DFHACK_BINARY_DESTINATION})
ENDIF()
# tile types. tile shape, material, and special information manipulation tool
DFHACK_TOOL(dftiletypes tiletypes.cpp)
# veinlook - look at the map... sort of, kind of
DFHACK_CURSES_TOOL(dfveinlook veinlook.cpp)
# dfstatus - watches DF and prints stuff in a window
DFHACK_CURSES_TOOL(dfstatus dfstatus.cpp)