Merge remote branch 'upstream/master'

develop
doomchild 2010-07-06 10:57:24 -05:00
commit c77a049d8b
45 changed files with 1801 additions and 702 deletions

@ -3,6 +3,7 @@ INCLUDE(CPack)
PROJECT (dfhack)
cmake_minimum_required(VERSION 2.6)
SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMake/Modules)
SET ( DFHACK_VERSION "0.4.0.3-dev" )
# disable warning, autosearch
if(COMMAND cmake_policy)
@ -20,6 +21,8 @@ ENDIF(NOT DEFINED CMAKE_BUILD_TYPE)
SET( LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/output CACHE PATH "Output directory for the dfhack library" )
SET( EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/output CACHE PATH "Output directory for the dfhack tools" )
OPTION(BUILD_DFHACK_DOCUMENTATION "Create doxygen documentation for developers" OFF)
include_directories (${CMAKE_SOURCE_DIR}/library/include/)
include_directories (${CMAKE_SOURCE_DIR}/library/shm/)
include_directories (${CMAKE_SOURCE_DIR}/library/depends/md5/)
@ -27,7 +30,9 @@ include_directories (${CMAKE_SOURCE_DIR}/library/depends/tinyxml/)
include_directories (${CMAKE_SOURCE_DIR}/library/depends/argstream/)
add_subdirectory (library)
add_subdirectory (library/shm)
#add_subdirectory (dfhack/python)
add_subdirectory (tools/examples)
add_subdirectory (tools/playground)
add_subdirectory (tools/supported)
add_subdirectory (doc)

@ -6,6 +6,7 @@ Dependencies
You'll need cmake and 'a' compiler for building the main lib and the various tools.
(Linux only) Veinlook requires the wide-character ncurses library (libncursesw)
(Linux only) You'll need X11 dev libraries.
Building on Linux:
--------------------

@ -33,11 +33,12 @@ OSX is also not supported due to lack of developers with a Mac.
Currently supported Dwarf Fortress versions:
* Windows
0.31.01 - 0.31.03 legacy
0.31.04 - 0.31.06 SDL
0.31.04 - 0.31.08 SDL
* Linux
0.31.04 - 0.31.06 native. There are missing offsets but Map tools should be OK.
All Windows versions through wine.
0.31.04 - 0.31.08 native.
There are missing offsets but Map tools should be OK. Linux support is a bit lacking, I'm working on it.
All supported Windows versions running in wine can be used with DFHack.
Using the library as a developer
--------------------------------

@ -0,0 +1,67 @@
# repurposed from libnoise: http://github.com/qknight/libnoise/tree/master/doc/
# following code and comments is by the original author, with some changes by
# me (peterix)
# ------------------------------------------------------------------------------
#
# many thanks go to Philippe Poilbarbe for writing the code this file is based on
# http://www.cmake.org/pipermail/cmake/2006-August/010794.html
#
# much later i also found this:
# http://tobias.rautenkranz.ch/cmake/doxygen/
# but it is hard to understand...
IF (BUILD_DFHACK_DOCUMENTATION)
FIND_PACKAGE(Doxygen)
IF(DOXYGEN_FOUND)
SET(DOXYGEN_LANGUAGE "English" CACHE STRING "Language used by doxygen")
MARK_AS_ADVANCED(DOXYGEN_LANGUAGE)
# you could also set the version with this, see Doxygen.in
# there you will find a line like this:
# PROJECT_NUMBER = @DFHACK_VERSION@
# @DFHACK_VERSION@ is then replaced by our global DFHACK_VERSION
#
# for instance you could uncomment the next 3 lines and change the version for testing
# SET(DFHACK_VERSION
# "1.2.3-foo500"
# )
# doxygen can reference external images with IMAGE_PATH, this is how we set it dynamically
SET( CMAKE_DOXYGEN_IMAGE_PATH
"${CMAKE_CURRENT_SOURCE_DIR}/img"
)
# doxygen searches for source code (defined in FILE_PATTERNS, for example: *.cpp *.h)
# with DOXYGEN_SOURCE_DIR we fill a list of directories and later we write it into
# the Doxyfile with a REGEX REPLACE (see below)
SET( DOXYGEN_SOURCE_DIR
# "${CMAKE_SOURCE_DIR}/library"
"${CMAKE_SOURCE_DIR}/library/include"
"${CMAKE_SOURCE_DIR}/library/include/dfhack"
"${CMAKE_SOURCE_DIR}/library/include/dfhack/modules"
"${CMAKE_SOURCE_DIR}/library/include/dfhack-c"
"${CMAKE_SOURCE_DIR}/library/include/dfhack-c/modules"
# "${CMAKE_SOURCE_DIR}/library/modules"
# "${CMAKE_SOURCE_DIR}/library/shm"
# "${CMAKE_SOURCE_DIR}/library/private"
)
SET(DOXYGEN_OUTPUT_DIR html)
STRING(REGEX REPLACE ";" " " CMAKE_DOXYGEN_INPUT_LIST "${DOXYGEN_SOURCE_DIR}")
CONFIGURE_FILE(Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
SET(HTML_TARGET "html" )
ADD_CUSTOM_TARGET(${HTML_TARGET} ALL
/usr/bin/doxygen ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
INSTALL( DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/html/" DESTINATION "/usr/share/doc/dfhack-${DFHACK_VERSION}" )
ELSE(DOXYGEN_FOUND)
MESSAGE (FATAL_ERROR "doxygen binary couldn't be found")
ENDIF(DOXYGEN_FOUND)
ENDIF (BUILD_DFHACK_DOCUMENTATION)

@ -0,0 +1,216 @@
# Doxyfile 1.3.9.1
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
PROJECT_NAME = dfhack
PROJECT_NUMBER = @DFHACK_VERSION@
OUTPUT_DIRECTORY = .
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
USE_WINDOWS_ENCODING = YES
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF =
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = NO
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = YES
MULTILINE_CPP_IS_BRIEF = NO
DETAILS_AT_TOP = YES
INHERIT_DOCS = YES
DISTRIBUTE_GROUP_DOC = NO
TAB_SIZE = 4
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = NO
OPTIMIZE_OUTPUT_JAVA = NO
SUBGROUPING = YES
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = YES
EXTRACT_PRIVATE = NO
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = NO
EXTRACT_LOCAL_METHODS = NO
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = YES
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
SORT_BY_SCOPE_NAME = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_DIRECTORIES = YES
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = @CMAKE_DOXYGEN_INPUT_LIST@
FILE_PATTERNS = *.cpp *.h
RECURSIVE = NO
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS =
EXAMPLE_RECURSIVE = NO
IMAGE_PATH = @CMAKE_DOXYGEN_IMAGE_PATH@
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = NO
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
# this code is needed if you want to build this doxygen docu for a static wep page as http://libnoise.sourceforge.net/
#HTML_HEADER = htmldata/templateheader.html
#HTML_FOOTER = htmldata/templatefooter.html
#HTML_STYLESHEET = htmldata/doxygen.css
HTML_ALIGN_MEMBERS = YES
GENERATE_HTMLHELP = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
BINARY_TOC = NO
TOC_EXPAND = NO
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 8
GENERATE_TREEVIEW = NO
TREEVIEW_WIDTH = 250
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4wide
EXTRA_PACKAGES =
LATEX_HEADER =
PDF_HYPERLINKS = NO
USE_PDFLATEX = NO
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = NO
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = NO
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
UML_LOOK = NO
TEMPLATE_RELATIONS = YES
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = YES
GRAPHICAL_HIERARCHY = YES
DOT_IMAGE_FORMAT = png
DOT_PATH =
DOTFILE_DIRS =
MAX_DOT_GRAPH_WIDTH = 1024
MAX_DOT_GRAPH_HEIGHT = 1024
MAX_DOT_GRAPH_DEPTH = 0
GENERATE_LEGEND = YES
DOT_CLEANUP = YES
#---------------------------------------------------------------------------
# Configuration::additions related to the search engine
#---------------------------------------------------------------------------
SEARCHENGINE = NO

@ -168,61 +168,3 @@ IF(UNIX)
install(TARGETS dfhack LIBRARY DESTINATION lib)
install(FILES ${CMAKE_SOURCE_DIR}/output/Memory.xml DESTINATION share/dfhack)
ENDIF(UNIX)
################################################################################
# DFCONNECT
###
SET(DFCONNECT_HDRS
shm/shms.h
shm/mod-core.h
shm/mod-maps.h
)
SET(PROJECT_SRCS
shm/mod-core.cpp
shm/mod-maps.cpp
#mod-creature40d.cpp
)
SET(PROJECT_HDRS_LINUX
)
SET(PROJECT_HDRS_WINDOWS
)
SET(PROJECT_SRCS_LINUX
shm/shms-linux.cpp
)
SET(PROJECT_SRCS_WINDOWS
shm/shms-windows.cpp
)
IF(UNIX)
LIST(APPEND PROJECT_HDRS ${PROJECT_HDRS_LINUX})
LIST(APPEND PROJECT_SRCS ${PROJECT_SRCS_LINUX})
ELSE(UNIX)
LIST(APPEND PROJECT_HDRS ${PROJECT_HDRS_WINDOWS})
LIST(APPEND PROJECT_SRCS ${PROJECT_SRCS_WINDOWS})
ENDIF(UNIX)
SET_SOURCE_FILES_PROPERTIES( ${PROJECT_HDRS} PROPERTIES HEADER_FILE_ONLY TRUE )
LIST(APPEND PROJECT_SRCS ${PROJECT_HDRS})
#IF(CMAKE_SIZEOF_VOID_P EQUAL 4)
IF(UNIX)
add_definitions(-DLINUX_BUILD)
SET(PROJECT_LIBS rt)
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden")
ADD_LIBRARY(dfconnect SHARED ${PROJECT_SRCS})
TARGET_LINK_LIBRARIES(dfconnect ${PROJECT_LIBS})
ELSE(UNIX)
# SET(PROJECT_LIBS psapi)
ADD_LIBRARY(SDL SHARED ${PROJECT_SRCS})
TARGET_LINK_LIBRARIES(SDL ${PROJECT_LIBS})
ENDIF(UNIX)
#ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 4)

@ -24,33 +24,18 @@ using namespace DFHack;
DFContextShared::DFContextShared()
{
// init modules
creatures = 0;
maps = 0;
position = 0;
gui = 0;
world = 0;
materials = 0;
translation = 0;
vegetation = 0;
buildings = 0;
constructions = 0;
items = 0;
windowio = 0;
allModules.clear();
memset(&(s_mods), 0, sizeof(s_mods));
}
DFContextShared::~DFContextShared()
{
if(creatures) delete creatures;
if(maps) delete maps;
if(position) delete position;
if(gui) delete gui;
if(materials) delete materials;
if(translation) delete translation;
if(vegetation) delete vegetation;
if(buildings) delete buildings;
if(constructions) delete constructions;
if(world) delete world;
if(windowio) delete windowio;
// invalidate all modules
for(int i = 0 ; i < allModules.size(); i++)
{
delete allModules[i];
}
allModules.clear();
}
bool DFContextShared::InitReadNames()

@ -27,7 +27,6 @@ distribution.
#include "dfhack/DFProcess.h"
#include "dfhack/DFProcessEnumerator.h"
#include "dfhack/DFContext.h"
#include "dfhack/DFContext.h"
#include "dfhack/DFError.h"
#include <shms.h>
@ -93,6 +92,13 @@ bool Context::Detach()
}
d->shm_start = 0;
// invalidate all modules
for(int i = 0 ; i < d->allModules.size(); i++)
{
delete d->allModules[i];
}
d->allModules.clear();
memset(&(d->s_mods), 0, sizeof(d->s_mods));
/*
if(d->creatures)
{
delete d->creatures;
@ -147,7 +153,7 @@ bool Context::Detach()
{
delete d->translation;
d->translation = 0;
}
}*/
return true;
}
@ -201,13 +207,39 @@ Process * Context::getProcess()
/*******************************************************************************
M O D U L E S
*******************************************************************************/
#define MODULE_GETTER(TYPE) \
TYPE * Context::get##TYPE() \
{ \
if(!d->s_mods.p##TYPE)\
{\
d->s_mods.p##TYPE = new TYPE(d);\
d->allModules.push_back(d->s_mods.p##TYPE);\
}\
return d->s_mods.p##TYPE;\
}
MODULE_GETTER(Creatures);
MODULE_GETTER(Maps);
MODULE_GETTER(Gui);
MODULE_GETTER(WindowIO);
MODULE_GETTER(World);
MODULE_GETTER(Position);
MODULE_GETTER(Materials);
MODULE_GETTER(Items);
MODULE_GETTER(Translation);
MODULE_GETTER(Vegetation);
MODULE_GETTER(Buildings);
MODULE_GETTER(Constructions);
/*
Creatures * Context::getCreatures()
{
if(!d->creatures)
d->creatures = new Creatures(d);
return d->creatures;
}
*/
/*
Maps * Context::getMaps()
{
if(!d->maps)
@ -284,7 +316,7 @@ Constructions * Context::getConstructions()
d->constructions = new Constructions(d);
return d->constructions;
}
*/
/*
// returns number of buildings, expects v_buildingtypes that will later map t_building.type to its name

@ -240,7 +240,7 @@ DFHackObject* Context_getWindow(DFHackObject* context)
{
if(context != NULL)
{
return (DFHackObject*)((DFHack::Context*)context)->getWindow();
return (DFHackObject*)((DFHack::Context*)context)->getWindowIO();
}
return NULL;

@ -29,6 +29,7 @@ distribution.
//Inital amount of space in levels vector (since we usually know the number, efficent!)
#define NUM_RESERVE_LVLS 20
#define NUM_RESERVE_MOODS 6
using namespace DFHack;
/*
@ -96,6 +97,7 @@ class memory_info::Private
vector<string> skills;
vector<DFHack::t_level> levels;
vector< vector<string> > traits;
vector<string> moods;
map <uint32_t, string> labors;
// storage for class and multiclass
@ -124,6 +126,7 @@ memory_info::memory_info()
d->p = 0;
d->classindex = 0;
d->levels.reserve(NUM_RESERVE_LVLS);
d->moods.reserve(NUM_RESERVE_MOODS);
}
// copy constructor
@ -151,6 +154,7 @@ memory_info::memory_info(const memory_info &old)
d->traits = old.d->traits;
d->labors = old.d->labors;
d->levels = old.d->levels;
d->moods = old.d->moods;
}
void memory_info::setParentProcess(Process * _p)
{
@ -319,6 +323,16 @@ void memory_info::setLevel(const std::string &nLevel,
d->levels[keyInt].xpNxtLvl = strtol(nXp.c_str(), NULL, 10);
}
void memory_info::setMood(const std::string &id, const std::string &mood)
{
uint32_t keyInt = strtol(id.c_str(), NULL, 10);
if(d->moods.size() <= keyInt)
d->moods.resize(keyInt+1);
d->moods[keyInt] = mood;
}
void memory_info::setTrait(const string & key,
const string & value,
const string & zero,
@ -632,6 +646,7 @@ string memory_info::getProfession (const uint32_t key) const
string memory_info::getJob (const uint32_t key) const
{
if(d->jobs.size() > key)
{
return d->jobs[key];
}
@ -698,6 +713,11 @@ string memory_info::getTraitName(const uint32_t traitIdx) const
throw Error::MissingMemoryDefinition("traitname", traitIdx);
}
std::vector< std::vector<std::string> > const& memory_info::getAllTraits()
{
return d->traits;
}
string memory_info::getLabor (const uint32_t laborIdx)
{
if(d->labors.count(laborIdx))
@ -707,3 +727,43 @@ string memory_info::getLabor (const uint32_t laborIdx)
throw Error::MissingMemoryDefinition("labor", laborIdx);
}
std::string memory_info::getMood(const uint32_t moodID)
{
if(d->moods.size() > moodID)
{
return d->moods[moodID];
}
throw Error::MissingMemoryDefinition("Mood", moodID);
}
std::string memory_info::PrintOffsets()
{
ostringstream ss;
ss << "version: " << getVersion();
switch (getOS())
{
case OS_LINUX:
ss << " LINUX" << endl;
ss << "md5 hash: " << getString("md5") << endl;
break;
case OS_WINDOWS:
ss << " WINDOWS" << endl;
ss << "PE timestamp: " << hex << "0x" << getHexValue("pe_timestamp") << endl;
ss << "md5 hash: " << getString("md5") << endl;
break;
default:
ss << " UNKNOWN" << endl;
}
map<string,uint32_t>::const_iterator iter;
for(iter = d->addresses.begin(); iter != d->addresses.end(); iter++)
{
ss << "address " << (*iter).first << " : " << hex << "0x" << (*iter).second << endl;
}
map<string,int32_t>::const_iterator iter2;
for(iter2 = d->offsets.begin(); iter2 != d->offsets.end(); iter2++)
{
ss << "offset " << (*iter2).first << " : " << hex << "0x" << (*iter2).second << endl;
}
return ss.str();
}

@ -212,6 +212,10 @@ void MemInfoManager::ParseEntry (TiXmlElement* entry, memory_info* mem, map <str
{
mem->setLevel(value, name, pMemEntry->Attribute("xpNxtLvl"));
}
else if (type == "Mood")
{
mem->setMood(value, name);
}
else
{
throw Error::MemoryXmlUnknownType(type.c_str());

@ -1,6 +1,16 @@
#ifndef DFHACK_API_H
#define DFHACK_API_H
// Defines
#ifdef __GNUC__
#define DEPRECATED(func) func __attribute__ ((deprecated))
#elif defined(_MSC_VER)
#define DEPRECATED(func) __declspec(deprecated) func
#else
#pragma message("WARNING: You need to implement DEPRECATED for this compiler")
#define DEPRECATED(func) func
#endif
// DFHack core classes and types
#include "dfhack/DFIntegers.h"
#include "dfhack/DFGlobal.h"

@ -113,7 +113,7 @@ namespace DFHack
Constructions * getConstructions();
/// get the Window management and I/O module
WindowIO * getWindow();
WindowIO * getWindowIO();
// DEAD CODE, WAITING TO BE UPDATED TO DF2010
/*

@ -297,6 +297,16 @@ namespace DFHack
return "SHM ATTACH FAILURE";
}
};
class DFHACK_EXPORT ModuleNotInitialized : public std::exception
{
public:
ModuleNotInitialized() {}
virtual ~ModuleNotInitialized() throw(){};
virtual const char* what() const throw()
{
return "Programmer error: module not initialized!";
}
};
}
}

@ -41,7 +41,7 @@ namespace DFHack
{
private:
class Private;
Private * d;
Private * d;
public:
enum OSType
{
@ -66,6 +66,7 @@ namespace DFHack
uint32_t getAddress (const char *);
uint32_t getHexValue (const char *);
std::string getMood(const uint32_t moodID);
std::string getString (const std::string&);
std::string getProfession(const uint32_t) const;
std::string getJob(const uint32_t) const;
@ -73,8 +74,9 @@ namespace DFHack
std::string getTrait (const uint32_t, const uint32_t) const;
std::string getTraitName(const uint32_t) const;
std::string getLabor (const uint32_t);
std::vector< std::vector<std::string> > const& getAllTraits();
DFHack::t_level getLevelInfo(const uint32_t level) const;
DFHack::t_level getLevelInfo(const uint32_t level) const;
void setVersion(const char *);
void setVersion(const std::string&);
@ -103,11 +105,12 @@ namespace DFHack
void setJob(const std::string &, const std::string &);
void setSkill(const std::string &, const std::string &);
void setTrait(const std::string &, const std::string &, const std::string &,
const std::string &, const std::string &,
const std::string &, const std::string &, const std::string &);
const std::string &, const std::string &,
const std::string &, const std::string &, const std::string &);
void setLabor(const std::string &, const std::string &);
void setLevel(const std::string &nLevel, const std::string &nName,
const std::string &nXp);
void setLevel(const std::string &nLevel, const std::string &nName,
const std::string &nXp);
void setMood(const std::string &id, const std::string &mood);
void RebaseVTable(const int32_t offset);
void setParentProcess(Process * _p);
@ -142,6 +145,11 @@ namespace DFHack
* Get the internal classID->classname mapping (for speed). DO NOT MANIPULATE THE VECTOR!
*/
const std::vector<std::string> * getClassIDMapping();
/**
* Get a string with all addresses and offsets
*/
std::string PrintOffsets();
};
}
#endif // MEMINFO_H_INCLUDED

@ -0,0 +1,45 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#ifndef MODULE_H_INCLUDED
#define MODULE_H_INCLUDED
#include "DFExport.h"
namespace DFHack
{
class Context;
class DFHACK_EXPORT Module
{
public:
~Module(){};
virtual bool Start(){return true;};// default start...
virtual bool Finish() = 0;// everything should have a Finish()
virtual bool doFinishOnResume(){return true;}; // should Context call Finish when Resume is called?
virtual bool doFinishOnMapChange(){return false;}; // Finish when map change is detected?
virtual bool doFinishOnDetach(){return false;}; // Finish in Context::Detach?
};
}
#endif //MODULE_H_INCLUDED

@ -203,7 +203,7 @@ struct t_settlement
struct t_attrib
{
uint32_t level;
uint32_t field_4;
uint32_t field_4; // offset from beginning, purpose unknown
uint32_t field_8;
uint32_t field_C;
uint32_t leveldiff;

@ -4,6 +4,7 @@
* Buildings - also includes zones and stockpiles
*/
#include "dfhack/DFExport.h"
#include "dfhack/DFModule.h"
namespace DFHack
{
struct t_building
@ -26,7 +27,7 @@ namespace DFHack
};
class DFContextShared;
class DFHACK_EXPORT Buildings
class DFHACK_EXPORT Buildings : public Module
{
public:
Buildings(DFContextShared * d);

@ -4,6 +4,7 @@
* DF constructions
*/
#include "dfhack/DFExport.h"
#include "dfhack/DFModule.h"
namespace DFHack
{
// type of item the construction is made of
@ -40,7 +41,7 @@ namespace DFHack
};
#pragma pack (pop)
class DFContextShared;
class DFHACK_EXPORT Constructions
class DFHACK_EXPORT Constructions : public Module
{
public:
Constructions(DFContextShared * d);

@ -4,6 +4,7 @@
* Creatures
*/
#include "dfhack/DFExport.h"
#include "dfhack/DFModule.h"
namespace DFHack
{
/*
@ -49,12 +50,12 @@ namespace DFHack
unsigned int dead : 1; // might also be set for incoming/leaving critters that are alive
unsigned int has_mood : 1; // Currently in mood
unsigned int had_mood : 1; // Had a mood
unsigned int marauder : 1; // wide class of invader/inside creature attackers
unsigned int drowning : 1;
unsigned int merchant : 1; // active merchant
unsigned int forest : 1; // used for units no longer linked to merchant/diplomacy, they just try to leave mostly
unsigned int left : 1; // left the map
unsigned int rider : 1;
unsigned int incoming : 1;
@ -64,12 +65,12 @@ namespace DFHack
unsigned int skeleton : 1;
unsigned int can_swap : 1; // Can swap tiles during movement (prevents multiple swaps)
unsigned int on_ground : 1; // can be conscious
unsigned int projectile : 1;
unsigned int active_invader : 1; // for organized ones
unsigned int hidden_in_ambush : 1;
unsigned int invader_origin : 1; // could be inactive and fleeing
unsigned int coward : 1; // Will flee if invasion turns around
unsigned int hidden_ambusher : 1; // maybe
unsigned int invades : 1; // Active marauder/invader moving inward
@ -80,7 +81,7 @@ namespace DFHack
unsigned int caged : 1;
unsigned int tame : 1;
unsigned int chained : 1;
unsigned int royal_guard : 1;
unsigned int fortress_guard : 1;
unsigned int suppress_wield : 1; // Suppress wield for beatings/etc
@ -142,43 +143,43 @@ namespace DFHack
unsigned int sparring : 1;
unsigned int no_notify : 1; // Do not notify about level gains (for embark etc)
unsigned int unused : 1;
unsigned int calculated_nerves : 1;
unsigned int calculated_bodyparts : 1;
unsigned int important_historical_figure : 1; // slight variation
unsigned int killed : 1; // killed by kill() function
unsigned int cleanup_1 : 1; // Must be forgotten by forget function (just cleanup)
unsigned int cleanup_2 : 1; // Must be deleted (cleanup)
unsigned int cleanup_3 : 1; // Recently forgotten (cleanup)
unsigned int for_trade : 1; // Offered for trade
unsigned int trade_resolved : 1;
unsigned int has_breaks : 1;
unsigned int gutted : 1;
unsigned int circulatory_spray : 1;
unsigned int locked_in_for_trading : 1;
unsigned int slaughter : 1; // marked for slaughter
unsigned int underworld : 1; // Underworld creature
unsigned int resident : 1; // Current resident
unsigned int cleanup_4 : 1; // Marked for special cleanup as unused load from unit block on disk
unsigned int calculated_insulation : 1; // Insulation from clothing calculated
unsigned int visitor_uninvited : 1; // Uninvited guest
unsigned int visitor : 1; // visitor
unsigned int calculated_inventory : 1; // Inventory order calculated
unsigned int vision_good : 1; // Vision -- have good part
unsigned int vision_damaged : 1; // Vision -- have damaged part
unsigned int vision_missing : 1; // Vision -- have missing part
unsigned int breathing_good : 1; // Breathing -- have good part
unsigned int breathing_problem : 1; // Breathing -- having a problem
unsigned int roaming_wilderness_population_source : 1;
unsigned int roaming_wilderness_population_source_not_a_map_feature : 1;
};
union t_creaturflags2
{
uint32_t whole;
@ -188,84 +189,84 @@ namespace DFHack
/*
struct t_labor
{
string name;
uint8_t value;
t_labor() {
value =0;
}
t_labor(const t_labor & b){
name=b.name;
value=b.value;
}
t_labor & operator=(const t_labor &b){
name=b.name;
value=b.value;
return *this;
}
string name;
uint8_t value;
t_labor() {
value =0;
}
t_labor(const t_labor & b){
name=b.name;
value=b.value;
}
t_labor & operator=(const t_labor &b){
name=b.name;
value=b.value;
return *this;
}
};
struct t_skill
{
string name;
uint16_t id;
uint32_t experience;
uint16_t rating;
t_skill(){
id=rating=0;
experience=0;
}
t_skill(const t_skill & b)
{
name=b.name;
id=b.id;
experience=b.experience;
rating=b.rating;
}
t_skill & operator=(const t_skill &b)
{
name=b.name;
id=b.id;
experience=b.experience;
rating=b.rating;
return *this;
}
string name;
uint16_t id;
uint32_t experience;
uint16_t rating;
t_skill(){
id=rating=0;
experience=0;
}
t_skill(const t_skill & b)
{
name=b.name;
id=b.id;
experience=b.experience;
rating=b.rating;
}
t_skill & operator=(const t_skill &b)
{
name=b.name;
id=b.id;
experience=b.experience;
rating=b.rating;
return *this;
}
};
struct t_trait
{
uint16_t value;
string displayTxt;
string name;
t_trait(){
value=0;
}
t_trait(const t_trait &b)
{
name=b.name;
displayTxt=b.displayTxt;
value=b.value;
}
t_trait & operator=(const t_trait &b)
{
name=b.name;
displayTxt=b.displayTxt;
value=b.value;
return *this;
}
uint16_t value;
string displayTxt;
string name;
t_trait(){
value=0;
}
t_trait(const t_trait &b)
{
name=b.name;
displayTxt=b.displayTxt;
value=b.value;
}
t_trait & operator=(const t_trait &b)
{
name=b.name;
displayTxt=b.displayTxt;
value=b.value;
return *this;
}
};
*/
struct t_skill
{
uint16_t id;
uint32_t id;
uint32_t rating;
uint32_t experience;
uint16_t rating;
};
struct t_job
{
bool active;
uint32_t jobId;
uint8_t jobType;
uint32_t occupationPtr;
uint32_t occupationPtr;
};
struct t_like
{
@ -280,7 +281,9 @@ namespace DFHack
// FIXME: define in Memory.xml instead?
#define NUM_CREATURE_TRAITS 30
#define NUM_CREATURE_LABORS 102
#define NUM_CREATURE_MENTAL_ATTRIBUTES 13
#define NUM_CREATURE_PHYSICAL_ATTRIBUTES 6
struct t_soul
{
uint8_t numSkills;
@ -305,7 +308,7 @@ namespace DFHack
t_attrib social_awareness;
};
#define MAX_COLORS 15
#define MAX_COLORS 15
struct t_creature
{
@ -315,23 +318,23 @@ namespace DFHack
uint16_t z;
uint32_t race;
int32_t civ;
t_creaturflags1 flags1;
t_creaturflags2 flags2;
t_name name;
int16_t mood;
int16_t mood_skill;
t_name artifact_name;
uint8_t profession;
char custom_profession[128];
// enabled labors
uint8_t labors[NUM_CREATURE_LABORS];
t_job current_job;
uint32_t happiness;
uint32_t id;
t_attrib strength;
@ -352,29 +355,45 @@ namespace DFHack
uint32_t birth_year;
uint32_t birth_time;
};
class DFContextShared;
struct t_creature;
class DFHACK_EXPORT Creatures
class DFHACK_EXPORT Creatures : public Module
{
public:
public:
Creatures(DFHack::DFContextShared * d);
~Creatures();
bool Start( uint32_t & numCreatures);
bool Start( uint32_t & numCreatures );
bool Finish();
/* Read Functions */
// Read creatures in a box, starting with index. Returns -1 if no more creatures
// found. Call repeatedly do get all creatures in a specified box (uses tile coords)
int32_t ReadCreatureInBox(const int32_t index, t_creature & furball,
const uint16_t x1, const uint16_t y1,const uint16_t z1,
const uint16_t x2, const uint16_t y2,const uint16_t z2);
const uint16_t x1, const uint16_t y1,const uint16_t z1,
const uint16_t x2, const uint16_t y2,const uint16_t z2);
bool ReadCreature(const int32_t index, t_creature & furball);
/// write labors of a creature (for Dwarf Therapist)
bool WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]);
bool ReadJob(const t_creature * furball, std::vector<t_material> & mat);
/* Getters */
uint32_t GetDwarfRaceIndex ( void );
int32_t GetDwarfCivId ( void );
bool ReadJob(const t_creature * furball, std::vector<t_material> & mat);
private:
/* Write Functions */
// write labors of a creature (for Dwarf Therapist)
bool WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]);
bool WriteHappiness(const uint32_t index, const uint32_t happinessValue);
bool WriteFlags(const uint32_t index, const uint32_t flags1, const uint32_t flags2);
bool WriteSkills(const uint32_t index, const t_soul &soul);
bool WriteAttributes(const uint32_t index, const t_creature &creature);
bool WriteSex(const uint32_t index, const uint8_t sex);
bool WriteTraits(const uint32_t index, const t_soul &soul);
bool WriteMood(const uint32_t index, const uint16_t mood);
bool WriteMoodSkill(const uint32_t index, const uint16_t moodSkill);
bool WritePos(const uint32_t index, const t_creature &creature);
bool WriteCiv(const uint32_t index, const int32_t civ);
private:
struct Private;
Private *d;
};

@ -5,12 +5,13 @@
* Gui: Query the DF's GUI state
*/
#include "dfhack/DFExport.h"
#include "dfhack/DFModule.h"
namespace DFHack
{
class DFContextShared;
struct t_viewscreen;
class DFHACK_EXPORT Gui
class DFHACK_EXPORT Gui: public Module
{
public:

@ -4,89 +4,39 @@
* Creatures
*/
#include "dfhack/DFExport.h"
#include "dfhack/DFModule.h"
namespace DFHack
{
class Context;
class DFContextShared;
enum accessor_type {ACCESSOR_CONSTANT, ACCESSOR_INDIRECT, ACCESSOR_DOUBLE_INDIRECT};
/* this is used to store data about the way accessors work */
class DFHACK_EXPORT Accessor
{
private:
accessor_type type;
int32_t constant;
uint32_t offset1;
uint32_t offset2;
Process * p;
uint32_t dataWidth;
public:
Accessor(uint32_t function, Process * p);
Accessor(accessor_type type, int32_t constant, uint32_t offset1, uint32_t offset2, uint32_t dataWidth, Process * p);
int32_t getValue(uint32_t objectPtr);
bool isConstant();
};
struct t_item
{
t_material matdesc;
int32_t quantity;
int32_t quality;
t_material matdesc;
int32_t quantity;
int32_t quality;
};
struct t_improvement
{
t_material matdesc;
int32_t quality;
};
class DFHACK_EXPORT ItemImprovementDesc
{
private:
Accessor * AType;
Process * p;
public:
ItemImprovementDesc(uint32_t VTable, Process * p);
bool getImprovement(uint32_t descptr, t_improvement & imp);
uint32_t vtable;
uint32_t maintype;
};
class DFHACK_EXPORT ItemDesc
{
private:
Accessor * AMainType;
Accessor * ASubType;
Accessor * ASubIndex;
Accessor * AIndex;
Accessor * AQuality;
Process * p;
bool hasDecoration;
public:
ItemDesc(uint32_t VTable, Process * p);
bool getItem(uint32_t itemptr, t_item & item);
std::string className;
uint32_t vtable;
uint32_t mainType;
std::vector<ItemImprovementDesc> improvement;
t_material matdesc;
int32_t quality;
};
class DFHACK_EXPORT Items
class DFHACK_EXPORT Items : public Module
{
public:
Items(DFContextShared * _d);
~Items();
std::string getItemDescription(uint32_t itemptr, Materials * Materials);
std::string getItemClass(int32_t index);
bool getItemData(uint32_t itemptr, t_item & item);
Items(DFContextShared * _d);
~Items();
bool Start();
bool Finish();
std::string getItemDescription(uint32_t itemptr, Materials * Materials);
std::string getItemClass(int32_t index);
bool getItemData(uint32_t itemptr, t_item & item);
private:
class Private;
Private* d;
std::map<int32_t, ItemDesc *> descType;
std::map<uint32_t, ItemDesc *> descVTable;
class Private;
Private* d;
};
}
#endif

@ -6,6 +6,7 @@
#define CL_MOD_MAPS
#include "dfhack/DFExport.h"
#include "dfhack/DFModule.h"
namespace DFHack
{
/***************************************************************************
@ -304,10 +305,10 @@ namespace DFHack
/***************************************************************************
C L I E N T M O D U L E
***************************************************************************/
#ifndef BUILD_SHM
class DFContextShared;
struct t_viewscreen;
class DFHACK_EXPORT Maps
class DFHACK_EXPORT Maps : public Module
{
public:
@ -422,5 +423,6 @@ namespace DFHack
struct Private;
Private *d;
};
#endif
}
#endif

@ -1,13 +1,14 @@
#ifndef CL_MOD_MATERIALS
#define CL_MOD_MATERIALS
/*
* Creatures
*/
* Materials
*/
#include "dfhack/DFExport.h"
#include "dfhack/DFModule.h"
namespace DFHack
{
class DFContextShared;
struct t_matgloss
{
char id[128]; //the id in the raws
@ -53,7 +54,7 @@ namespace DFHack
uint32_t startdate; /* in days */
uint32_t enddate; /* in days */
};
struct t_creaturecaste
{
char rawname[128];
@ -115,12 +116,13 @@ namespace DFHack
int32_t index;
uint32_t flags;
};
class DFHACK_EXPORT Materials
class DFHACK_EXPORT Materials : public Module
{
public:
Materials(DFHack::DFContextShared * _d);
~Materials();
bool Finish();
std::vector<t_matgloss> inorganic;
std::vector<t_matgloss> organic;

@ -4,6 +4,7 @@
* View position and size and cursor position
*/
#include "dfhack/DFExport.h"
#include "dfhack/DFModule.h"
namespace DFHack
{
#define NUM_HOTKEYS 16
@ -15,33 +16,34 @@ namespace DFHack
int32_t y;
int32_t z;
};
class DFContextShared;
class DFHACK_EXPORT Position
class DFHACK_EXPORT Position : public Module
{
public:
Position(DFContextShared * d);
~Position();
bool Finish(){return true;};
/*
* Cursor and window coords
*/
bool getViewCoords (int32_t &x, int32_t &y, int32_t &z);
bool setViewCoords (const int32_t x, const int32_t y, const int32_t z);
bool getCursorCoords (int32_t &x, int32_t &y, int32_t &z);
bool setCursorCoords (const int32_t x, const int32_t y, const int32_t z);
/*
* Hotkeys (DF's zoom locations)
*/
bool ReadHotkeys(t_hotkey hotkeys[]);
/*
* Window size in tiles
*/
bool getWindowSize(int32_t & width, int32_t & height);
private:
struct Private;
Private *d;

@ -4,6 +4,7 @@
* DF translation tables and name translation
*/
#include "dfhack/DFExport.h"
#include "dfhack/DFModule.h"
namespace DFHack
{
class DFContextShared;
@ -13,8 +14,8 @@ namespace DFHack
DFDict translations;
DFDict foreign_languages;
} Dicts;
class DFHACK_EXPORT Translation
class DFHACK_EXPORT Translation : public Module
{
public:
Translation(DFContextShared * d);
@ -26,7 +27,7 @@ namespace DFHack
Dicts * getDicts();
// translate a name using the loaded dictionaries
std::string TranslateName(const DFHack::t_name& name, bool inEnglish = true);
private:
struct Private;
Private *d;

@ -4,6 +4,7 @@
* DF vegetation - stuff that grows and gets cut down or trampled by dwarves
*/
#include "dfhack/DFExport.h"
#include "dfhack/DFModule.h"
namespace DFHack
{
/*
@ -28,7 +29,7 @@ namespace DFHack
};
class DFContextShared;
class DFHACK_EXPORT Vegetation
class DFHACK_EXPORT Vegetation : public Module
{
public:
Vegetation(DFContextShared * d);

@ -27,6 +27,7 @@ distribution.
#include "dfhack/DFPragma.h"
#include "dfhack/DFExport.h"
#include "dfhack/DFModule.h"
namespace DFHack
{
@ -88,12 +89,13 @@ enum t_special
NUM_SPECIALS
};
class DFContextShared;
class DFHACK_EXPORT WindowIO
class DFHACK_EXPORT WindowIO : public Module
{
class Private;
private:
Private * d;
public:
bool Finish(){return true;};
WindowIO(DFHack::DFContextShared * d);
~WindowIO();
void TypeStr (const char *input, int delay = 0, bool useShift = false);

@ -5,11 +5,12 @@
* World: all kind of stuff related to the current world state
*/
#include "dfhack/DFExport.h"
#include "dfhack/DFModule.h"
namespace DFHack
{
class DFContextShared;
class DFHACK_EXPORT World
class DFHACK_EXPORT World : public Module
{
public:

@ -92,19 +92,19 @@ Creatures::Creatures(DFContextShared* _d)
creatures.mood_offset = minfo->getOffset("creature_mood");
creatures.mood_skill_offset = minfo->getOffset("creature_mood_skill");
creatures.pickup_equipment_bit = minfo->getOffset("creature_pickup_equipment_bit");
creatures.current_job_offset = minfo->getOffset("creature_current_job");
creatures.current_job_offset = minfo->getOffset("creature_current_job");
// soul offsets
creatures.soul_skills_vector_offset = minfo->getOffset("soul_skills_vector");
creatures.soul_mental_offset = minfo->getOffset("soul_mental");
creatures.soul_traits_offset = minfo->getOffset("soul_traits");
// appearance
creatures.appearance_vector_offset = minfo->getOffset("creature_appearance_vector");
//birth
creatures.birth_year_offset = minfo->getOffset("creature_birth_year");
creatures.birth_time_offset = minfo->getOffset("creature_birth_time");
// name offsets for the creature module
creatures.name_firstname_offset = minfo->getOffset("name_firstname");
creatures.name_nickname_offset = minfo->getOffset("name_nickname");
@ -172,17 +172,17 @@ bool Creatures::ReadCreature (const int32_t index, t_creature & furball)
*/
// non-SHM slow path
memory_info * minfo = d->d->offset_descriptor;
// read pointer from vector at position
uint32_t temp = d->p_cre->at (index);
furball.origin = temp;
Creatures2010::creature_offsets &offs = d->creatures;
//read creature from memory
// name
d->d->readName(furball.name,temp + offs.name_offset);
// basic stuff
p->readDWord (temp + offs.happiness_offset, furball.happiness);
p->readDWord (temp + offs.id_offset, furball.id);
@ -193,22 +193,24 @@ bool Creatures::ReadCreature (const int32_t index, t_creature & furball)
p->readWord (temp + offs.caste_offset, furball.caste);
p->readDWord (temp + offs.flags1_offset, furball.flags1.whole);
p->readDWord (temp + offs.flags2_offset, furball.flags2.whole);
// physical attributes
p->read(temp + offs.physical_offset, sizeof(t_attrib) * 6, (uint8_t *)&furball.strength);
p->read(temp + offs.physical_offset,
sizeof(t_attrib) * NUM_CREATURE_PHYSICAL_ATTRIBUTES,
(uint8_t *)&furball.strength);
// mood stuff
furball.mood = (int16_t) p->readWord (temp + offs.mood_offset);
furball.mood_skill = p->readWord (temp + offs.mood_skill_offset);
d->d->readName(furball.artifact_name, temp + offs.artifact_name_offset);
// custom profession
p->readSTLString(temp + offs.custom_profession_offset, furball.custom_profession, sizeof(furball.custom_profession));
//fill_char_buf (furball.custom_profession, p->readSTLString (temp + offs.custom_profession_offset));
// labors
p->read (temp + offs.labors_offset, NUM_CREATURE_LABORS, furball.labors);
// profession
furball.profession = p->readByte (temp + offs.profession_offset);
@ -252,25 +254,34 @@ bool Creatures::ReadCreature (const int32_t index, t_creature & furball)
*/
uint32_t soul = p->readDWord(temp + offs.default_soul_offset);
furball.has_default_soul = false;
if(soul)
{
furball.has_default_soul = true;
// get first soul's skills
DfVector <uint32_t> skills(p, soul + offs.soul_skills_vector_offset);
furball.defaultSoul.numSkills = skills.size();
for (uint32_t i = 0; i < furball.defaultSoul.numSkills;i++)
{
uint32_t temp2 = skills[i];
// a byte: this gives us 256 skills maximum.
furball.defaultSoul.skills[i].id = p->readByte (temp2);
furball.defaultSoul.skills[i].rating = p->readByte (temp2 + 4);
furball.defaultSoul.skills[i].experience = p->readWord (temp2 + 8);
furball.defaultSoul.skills[i].rating =
p->readByte (temp2 + offsetof(t_skill, rating));
furball.defaultSoul.skills[i].experience =
p->readWord (temp2 + offsetof(t_skill, experience));
}
// mental attributes are part of the soul
p->read(soul + offs.soul_mental_offset, sizeof(t_attrib) * 13, (uint8_t *)&furball.defaultSoul.analytical_ability);
p->read(soul + offs.soul_mental_offset,
sizeof(t_attrib) * NUM_CREATURE_MENTAL_ATTRIBUTES,
(uint8_t *)&furball.defaultSoul.analytical_ability);
// traits as well
p->read(soul + offs.soul_traits_offset, sizeof (uint16_t) * NUM_CREATURE_TRAITS, (uint8_t *) &furball.defaultSoul.traits);
p->read(soul + offs.soul_traits_offset,
sizeof (uint16_t) * NUM_CREATURE_TRAITS,
(uint8_t *) &furball.defaultSoul.traits);
}
DfVector <uint32_t> app(p, temp + offs.appearance_vector_offset);
@ -301,7 +312,7 @@ int32_t Creatures::ReadCreatureInBox (int32_t index, t_creature & furball,
{
if (!d->Started)
return -1;
Process *p = d->owner;
/*
if(d->creature_module)
@ -346,14 +357,15 @@ int32_t Creatures::ReadCreatureInBox (int32_t index, t_creature & furball,
}
}
bool Creatures::WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS])
{
if(!d->Started) return false;
if(!d->Started)
{
return false;
}
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
p->write(temp + d->creatures.labors_offset, NUM_CREATURE_LABORS, labors);
uint32_t pickup_equip;
p->readDWord(temp + d->creatures.pickup_equipment_bit, pickup_equip);
@ -362,6 +374,177 @@ bool Creatures::WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LA
return true;
}
bool Creatures::WriteHappiness(const uint32_t index, const uint32_t happinessValue)
{
if(!d->Started)
{
return false;
}
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
p->writeDWord (temp + d->creatures.happiness_offset, happinessValue);
return true;
}
bool Creatures::WriteFlags(const uint32_t index,
const uint32_t flags1,
const uint32_t flags2)
{
if(!d->Started)
{
return false;
}
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
p->writeDWord (temp + d->creatures.flags1_offset, flags1);
p->writeDWord (temp + d->creatures.flags2_offset, flags2);
return true;
}
bool Creatures::WriteSkills(const uint32_t index, const t_soul &soul)
{
if(!d->Started)
{
return false;
}
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
uint32_t souloff = p->readDWord(temp + d->creatures.default_soul_offset);
if(!souloff)
{
return false;
}
DfVector<uint32_t> skills(p, souloff + d->creatures.soul_skills_vector_offset);
for (uint32_t i=0; i<soul.numSkills; i++)
{
uint32_t temp2 = skills[i];
p->writeByte(temp2 + offsetof(t_skill, rating), soul.skills[i].rating);
p->writeWord(temp2 + offsetof(t_skill, experience), soul.skills[i].experience);
}
return true;
}
bool Creatures::WriteAttributes(const uint32_t index, const t_creature &creature)
{
if(!d->Started)
{
return false;
}
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
uint32_t souloff = p->readDWord(temp + d->creatures.default_soul_offset);
if(!souloff)
{
return false;
}
// physical attributes
p->write(temp + d->creatures.physical_offset,
sizeof(t_attrib) * NUM_CREATURE_PHYSICAL_ATTRIBUTES,
(uint8_t *)&creature.strength);
// mental attributes are part of the soul
p->write(souloff + d->creatures.soul_mental_offset,
sizeof(t_attrib) * NUM_CREATURE_MENTAL_ATTRIBUTES,
(uint8_t *)&creature.defaultSoul.analytical_ability);
return true;
}
bool Creatures::WriteSex(const uint32_t index, const uint8_t sex)
{
if(!d->Started)
{
return false;
}
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
p->writeByte (temp + d->creatures.sex_offset, sex);
}
bool Creatures::WriteTraits(const uint32_t index, const t_soul &soul)
{
if(!d->Started)
{
return false;
}
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
uint32_t souloff = p->readDWord(temp + d->creatures.default_soul_offset);
if(!souloff)
{
return false;
}
p->write(souloff + d->creatures.soul_traits_offset,
sizeof (uint16_t) * NUM_CREATURE_TRAITS,
(uint8_t *) &soul.traits);
return true;
}
bool Creatures::WriteMood(const uint32_t index, const uint16_t mood)
{
if(!d->Started)
{
return false;
}
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
p->writeWord(temp + d->creatures.mood_offset, mood);
return true;
}
bool Creatures::WriteMoodSkill(const uint32_t index, const uint16_t moodSkill)
{
if(!d->Started)
{
return false;
}
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
p->writeWord(temp + d->creatures.mood_skill_offset, moodSkill);
return true;
}
bool Creatures::WritePos(const uint32_t index, const t_creature &creature)
{
if(!d->Started)
{
return false;
}
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
p->write (temp + d->creatures.pos_offset, 3 * sizeof (uint16_t), (uint8_t *) & (creature.x));
return true;
}
bool Creatures::WriteCiv(const uint32_t index, const int32_t civ)
{
if(!d->Started)
{
return false;
}
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
p->writeDWord(temp + d->creatures.civ_offset, civ);
return true;
}
uint32_t Creatures::GetDwarfRaceIndex()
{
if(!d->Inited) return 0;

@ -33,235 +33,294 @@ distribution.
using namespace DFHack;
class Items::Private
enum accessor_type {ACCESSOR_CONSTANT, ACCESSOR_INDIRECT, ACCESSOR_DOUBLE_INDIRECT};
/* this is used to store data about the way accessors work */
class DFHACK_EXPORT Accessor
{
public:
DFContextShared *d;
Process * owner;
/*
bool Inited;
bool Started;
*/
private:
accessor_type type;
int32_t constant;
uint32_t offset1;
uint32_t offset2;
Process * p;
uint32_t dataWidth;
public:
Accessor(uint32_t function, Process * p);
Accessor(accessor_type type, int32_t constant, uint32_t offset1, uint32_t offset2, uint32_t dataWidth, Process * p);
int32_t getValue(uint32_t objectPtr);
bool isConstant();
};
Items::Items(DFContextShared * d_)
class DFHACK_EXPORT ItemImprovementDesc
{
d = new Private;
d->d = d_;
d->owner = d_->p;
}
Items::~Items()
private:
Accessor * AType;
Process * p;
public:
ItemImprovementDesc(uint32_t VTable, Process * p);
bool getImprovement(uint32_t descptr, t_improvement & imp);
uint32_t vtable;
uint32_t maintype;
};
class DFHACK_EXPORT ItemDesc
{
delete d;
/* TODO : delete all item descs */
}
private:
Accessor * AMainType;
Accessor * ASubType;
Accessor * ASubIndex;
Accessor * AIndex;
Accessor * AQuality;
Process * p;
bool hasDecoration;
public:
ItemDesc(uint32_t VTable, Process * p);
bool getItem(uint32_t itemptr, t_item & item);
std::string className;
uint32_t vtable;
uint32_t mainType;
std::vector<ItemImprovementDesc> improvement;
};
// FIXME: this is crazy
Accessor::Accessor(uint32_t function, Process *p)
{
this->p = p;
this->constant = 0;
this->offset1 = 0;
this->offset2 = 0;
this->type = ACCESSOR_CONSTANT;
this->dataWidth = 2;
uint64_t funcText = p->readQuad(function);
if( funcText == 0xCCCCCCCCCCC3C033LL )
{
return;
}
if( funcText == 0xCCCCCCCCC3FFC883LL )
{
/* or eax,-1; ret; */
this->constant = -1;
return;
}
if( (funcText&0xFFFFFFFFFF0000FFLL) == 0xCCCCC300000000B8LL )
{
/* mov eax, xx; ret; */
this->constant = (funcText>>8) & 0xffff;
return;
}
if( (funcText&0xFFFFFF0000FFFFFFLL) == 0xC300000000818B66LL )
{
/* mov ax, [ecx+xx]; ret; */
this->type = ACCESSOR_INDIRECT;
this->offset1 = (funcText>>24) & 0xffff;
return;
}
if( (funcText&0xFFFFFFFF0000FFFFLL) == 0x8B6600000000818BLL )
{
uint64_t funcText2 = p->readQuad(function+8);
if( (funcText2&0xFFFFFFFFFFFF00FFLL) == 0xCCCCCCCCCCC30040LL )
this->p = p;
this->constant = 0;
this->offset1 = 0;
this->offset2 = 0;
this->type = ACCESSOR_CONSTANT;
this->dataWidth = 2;
uint64_t funcText = p->readQuad(function);
if( funcText == 0xCCCCCCCCCCC3C033LL )
{
return;
}
if( funcText == 0xCCCCCCCCC3FFC883LL )
{
/* or eax,-1; ret; */
this->constant = -1;
return;
}
if( (funcText&0xFFFFFFFFFF0000FFLL) == 0xCCCCC300000000B8LL )
{
/* mov eax, xx; ret; */
this->constant = (funcText>>8) & 0xffff;
return;
}
if( (funcText&0xFFFFFF0000FFFFFFLL) == 0xC300000000818B66LL )
{
/* mov ax, [ecx+xx]; ret; */
this->type = ACCESSOR_INDIRECT;
this->offset1 = (funcText>>24) & 0xffff;
return;
}
if( (funcText&0xFFFFFFFF0000FFFFLL) == 0x8B6600000000818BLL )
{
uint64_t funcText2 = p->readQuad(function+8);
if( (funcText2&0xFFFFFFFFFFFF00FFLL) == 0xCCCCCCCCCCC30040LL )
{
this->type = ACCESSOR_DOUBLE_INDIRECT;
this->offset1 = (funcText>>16) & 0xffff;
this->offset2 = (funcText2>>8) & 0xff;
return;
}
}
if( (funcText&0xFFFFFF0000FFFFFFLL) == 0xC30000000081BF0FLL )
{
/* movsx eax, word ptr [ecx+xx]; ret */
this->type = ACCESSOR_INDIRECT;
this->offset1 = (funcText>>24) & 0xffff;
return;
}
if( (funcText&0xFFFFFFFF0000FFFFLL) == 0xCCC300000000818BLL )
{
/* mov eax, [ecx+xx]; ret; */
this->type = ACCESSOR_INDIRECT;
this->offset1 = (funcText>>16) & 0xffff;
this->dataWidth = 4;
return;
}
printf("bad accessor @0x%x\n", function);
this->type = ACCESSOR_DOUBLE_INDIRECT;
this->offset1 = (funcText>>16) & 0xffff;
this->offset2 = (funcText2>>8) & 0xff;
return;
}
}
if( (funcText&0xFFFFFF0000FFFFFFLL) == 0xC30000000081BF0FLL )
{
/* movsx eax, word ptr [ecx+xx]; ret */
this->type = ACCESSOR_INDIRECT;
this->offset1 = (funcText>>24) & 0xffff;
return;
}
if( (funcText&0xFFFFFFFF0000FFFFLL) == 0xCCC300000000818BLL )
{
/* mov eax, [ecx+xx]; ret; */
this->type = ACCESSOR_INDIRECT;
this->offset1 = (funcText>>16) & 0xffff;
this->dataWidth = 4;
return;
}
printf("bad accessor @0x%x\n", function);
}
bool Accessor::isConstant()
{
if(this->type == ACCESSOR_CONSTANT)
return true;
else
return false;
if(this->type == ACCESSOR_CONSTANT)
return true;
else
return false;
}
int32_t Accessor::getValue(uint32_t objectPtr)
{
switch(this->type)
{
case ACCESSOR_CONSTANT:
return this->constant;
break;
case ACCESSOR_INDIRECT:
switch(this->dataWidth)
{
case 2:
return (int16_t) p->readWord(objectPtr + this->offset1);
case 4:
return p->readDWord(objectPtr + this->offset1);
default:
return -1;
}
break;
case ACCESSOR_DOUBLE_INDIRECT:
switch(this->dataWidth)
{
case 2:
return (int16_t) p->readWord(p->readDWord(objectPtr + this->offset1) + this->offset2);
case 4:
return p->readDWord(p->readDWord(objectPtr + this->offset1) + this->offset2);
default:
return -1;
}
break;
default:
return -1;
}
switch(this->type)
{
case ACCESSOR_CONSTANT:
return this->constant;
break;
case ACCESSOR_INDIRECT:
switch(this->dataWidth)
{
case 2:
return (int16_t) p->readWord(objectPtr + this->offset1);
case 4:
return p->readDWord(objectPtr + this->offset1);
default:
return -1;
}
break;
case ACCESSOR_DOUBLE_INDIRECT:
switch(this->dataWidth)
{
case 2:
return (int16_t) p->readWord(p->readDWord(objectPtr + this->offset1) + this->offset2);
case 4:
return p->readDWord(p->readDWord(objectPtr + this->offset1) + this->offset2);
default:
return -1;
}
break;
default:
return -1;
}
}
ItemDesc::ItemDesc(uint32_t VTable, Process *p)
{
uint32_t funcOffsetA = p->getDescriptor()->getOffset("item_type_accessor");
uint32_t funcOffsetB = p->getDescriptor()->getOffset("item_subtype_accessor");
uint32_t funcOffsetC = p->getDescriptor()->getOffset("item_subindex_accessor");
uint32_t funcOffsetD = p->getDescriptor()->getOffset("item_index_accessor");
uint32_t funcOffsetQuality = p->getDescriptor()->getOffset("item_quality_accessor");
this->vtable = VTable;
this->p = p;
this->className = p->readClassName(VTable).substr(5);
this->className.resize(this->className.size()-2);
this->AMainType = new Accessor( p->readDWord( VTable + funcOffsetA ), p);
this->ASubType = new Accessor( p->readDWord( VTable + funcOffsetB ), p);
this->ASubIndex = new Accessor( p->readDWord( VTable + funcOffsetC ), p);
this->AIndex = new Accessor( p->readDWord( VTable + funcOffsetD ), p);
this->AQuality = new Accessor( p->readDWord( VTable + funcOffsetQuality ), p);
this->hasDecoration = false;
if(this->AMainType->isConstant())
this->mainType = this->AMainType->getValue(0);
else
{
fprintf(stderr, "Bad item main type at function %p\n", (void*) p->readDWord( VTable + funcOffsetA ));
this->mainType = 0;
}
uint32_t funcOffsetA = p->getDescriptor()->getOffset("item_type_accessor");
uint32_t funcOffsetB = p->getDescriptor()->getOffset("item_subtype_accessor");
uint32_t funcOffsetC = p->getDescriptor()->getOffset("item_subindex_accessor");
uint32_t funcOffsetD = p->getDescriptor()->getOffset("item_index_accessor");
uint32_t funcOffsetQuality = p->getDescriptor()->getOffset("item_quality_accessor");
this->vtable = VTable;
this->p = p;
this->className = p->readClassName(VTable).substr(5);
this->className.resize(this->className.size()-2);
this->AMainType = new Accessor( p->readDWord( VTable + funcOffsetA ), p);
this->ASubType = new Accessor( p->readDWord( VTable + funcOffsetB ), p);
this->ASubIndex = new Accessor( p->readDWord( VTable + funcOffsetC ), p);
this->AIndex = new Accessor( p->readDWord( VTable + funcOffsetD ), p);
this->AQuality = new Accessor( p->readDWord( VTable + funcOffsetQuality ), p);
this->hasDecoration = false;
if(this->AMainType->isConstant())
this->mainType = this->AMainType->getValue(0);
else
{
fprintf(stderr, "Bad item main type at function %p\n", (void*) p->readDWord( VTable + funcOffsetA ));
this->mainType = 0;
}
}
bool ItemDesc::getItem(uint32_t itemptr, DFHack::t_item &item)
{
item.matdesc.itemType = this->AMainType->getValue(itemptr);
item.matdesc.subType = this->ASubType->getValue(itemptr);
item.matdesc.subIndex = this->ASubIndex->getValue(itemptr);
item.matdesc.index = this->AIndex->getValue(itemptr);
item.quality = this->AQuality->getValue(itemptr);
item.quantity = 1; /* TODO */
return true;
item.matdesc.itemType = this->AMainType->getValue(itemptr);
item.matdesc.subType = this->ASubType->getValue(itemptr);
item.matdesc.subIndex = this->ASubIndex->getValue(itemptr);
item.matdesc.index = this->AIndex->getValue(itemptr);
item.quality = this->AQuality->getValue(itemptr);
item.quantity = 1; /* TODO */
return true;
}
class Items::Private
{
public:
DFContextShared *d;
Process * owner;
std::map<int32_t, ItemDesc *> descType;
std::map<uint32_t, ItemDesc *> descVTable;
};
Items::Items(DFContextShared * d_)
{
d = new Private;
d->d = d_;
d->owner = d_->p;
}
bool Items::Start(){return true;}
bool Items::Finish(){return true;}
Items::~Items()
{
Finish();
std::map<uint32_t, ItemDesc *>::iterator it;
it = d->descVTable.begin();
while (it != d->descVTable.end())
{
delete (*it).second;
}
d->descType.clear();
d->descVTable.clear();
delete d;
}
bool Items::getItemData(uint32_t itemptr, DFHack::t_item &item)
{
std::map<uint32_t, ItemDesc *>::iterator it;
Process * p = d->owner;
ItemDesc * desc;
std::map<uint32_t, ItemDesc *>::iterator it;
Process * p = d->owner;
ItemDesc * desc;
it = this->descVTable.find(itemptr);
if(it==descVTable.end())
{
uint32_t vtable = p->readDWord(itemptr);
desc = new ItemDesc(vtable, p);
this->descVTable[vtable] = desc;
this->descType[desc->mainType] = desc;
}
else
desc = it->second;
it = d->descVTable.find(itemptr);
if(it==d->descVTable.end())
{
uint32_t vtable = p->readDWord(itemptr);
desc = new ItemDesc(vtable, p);
d->descVTable[vtable] = desc;
d->descType[desc->mainType] = desc;
}
else
desc = it->second;
return desc->getItem(itemptr, item);
return desc->getItem(itemptr, item);
}
std::string Items::getItemClass(int32_t index)
{
std::map<int32_t, ItemDesc *>::iterator it;
std::string out;
std::map<int32_t, ItemDesc *>::iterator it;
std::string out;
it = this->descType.find(index);
if(it==this->descType.end())
{
/* these are dummy values for mood decoding */
switch(index)
{
case 0: return "bar";
case 1: return "cut gem";
case 2: return "block";
case 3: return "raw gem";
case 4: return "raw stone";
case 5: return "log";
case 54: return "leather";
case 57: return "cloth";
case -1: return "probably bone or shell, but I really don't know";
default: return "unknown";
}
}
out = it->second->className;
return out;
it = d->descType.find(index);
if(it==d->descType.end())
{
/* these are dummy values for mood decoding */
switch(index)
{
case 0: return "bar";
case 1: return "cut gem";
case 2: return "block";
case 3: return "raw gem";
case 4: return "raw stone";
case 5: return "log";
case 54: return "leather";
case 57: return "cloth";
case -1: return "probably bone or shell, but I really don't know";
default: return "unknown";
}
}
out = it->second->className;
return out;
}
std::string Items::getItemDescription(uint32_t itemptr, Materials * Materials)
{
DFHack::t_item item;
std::string out;
DFHack::t_item item;
std::string out;
if(!this->getItemData(itemptr, item))
return "??";
switch(item.quality)
{
case 0: break;
case 1: out.append("Well crafted "); break;
case 2: out.append("Finely crafted "); break;
case 3: out.append("Superior quality "); break;
case 4: out.append("Exceptionnal "); break;
case 5: out.append("Masterful "); break;
default: out.append("Crazy quality "); break;
}
out.append(Materials->getDescription(item.matdesc));
out.append(" ");
out.append(this->getItemClass(item.matdesc.itemType));
return out;
if(!this->getItemData(itemptr, item))
return "??";
switch(item.quality)
{
case 0: break;
case 1: out.append("Well crafted "); break;
case 2: out.append("Finely crafted "); break;
case 3: out.append("Superior quality "); break;
case 4: out.append("Exceptionnal "); break;
case 5: out.append("Masterful "); break;
default: out.append("Crazy quality "); break;
}
out.append(Materials->getDescription(item.matdesc));
out.append(" ");
out.append(this->getItemClass(item.matdesc.itemType));
return out;
}

@ -37,7 +37,7 @@ distribution.
#define SHMCMD(num) ((shm_cmd *)d->d->shm_start)[num]->pingpong
#define SHMHDR ((shm_core_hdr *)d->d->shm_start)
#define SHMDATA(type) ((type *)(d->d->shm_start + SHM_HEADER))
#define MAPS_GUARD if(!d->Started) throw DFHack::Error::ModuleNotInitialized();
using namespace DFHack;
struct Maps::Private
@ -49,15 +49,15 @@ struct Maps::Private
uint32_t maps_module;
Server::Maps::maps_offsets offsets;
DFContextShared *d;
Process * owner;
bool Inited;
bool Started;
// map between feature address and the read object
map <uint32_t, t_feature> local_feature_store;
vector<uint16_t> v_geology[eBiomeCount];
};
@ -67,10 +67,10 @@ Maps::Maps(DFContextShared* _d)
d->d = _d;
Process *p = d->owner = _d->p;
d->Inited = d->Started = false;
DFHack::memory_info * mem = p->getDescriptor();
Server::Maps::maps_offsets &off = d->offsets;
// get the offsets once here
off.map_offset = mem->getAddress ("map_data");
off.x_count_offset = mem->getAddress ("x_count_block");
@ -83,27 +83,23 @@ Maps::Maps(DFContextShared* _d)
off.veinvector = mem->getOffset ("map_data_vein_vector");
off.local_feature_offset = mem->getOffset ("map_data_feature_local");
off.global_feature_offset = mem->getOffset ("map_data_feature_global");
off.temperature1_offset = mem->getOffset ("map_data_temperature1_offset");
off.temperature2_offset = mem->getOffset ("map_data_temperature2_offset");
off.region_x_offset = mem->getAddress ("region_x");
off.region_y_offset = mem->getAddress ("region_y");
off.region_z_offset = mem->getAddress ("region_z");
off.world_regions = mem->getAddress ("ptr2_region_array");
off.region_size = mem->getHexValue ("region_size");
off.region_geo_index_offset = mem->getOffset ("region_geo_index_off");
off.geolayer_geoblock_offset = mem->getOffset ("geolayer_geoblock_offset");
off.world_geoblocks_vector = mem->getAddress ("geoblock_vector");
off.type_inside_geolayer = mem->getOffset ("type_inside_geolayer");
off.world_size_x = mem->getAddress ("world_size_x");
off.world_size_y = mem->getAddress ("world_size_y");
// these can fail and will be found when looking at the actual veins later
// basically a cache
off.vein_ice_vptr = 0;
@ -140,15 +136,17 @@ bool Maps::Start()
return false;
if(d->Started)
Finish();
Process *p = d->owner;
Server::Maps::maps_offsets &off = d->offsets;
// get the map pointer
uint32_t x_array_loc = p->readDWord (off.map_offset);
if (!x_array_loc)
{
return false;
}
// get the size
uint32_t mx, my, mz;
mx = d->x_block_count = p->readDWord (off.x_count_offset);
@ -193,6 +191,7 @@ bool Maps::Start()
// getter for map size
void Maps::getSize (uint32_t& x, uint32_t& y, uint32_t& z)
{
MAPS_GUARD
x = d->x_block_count;
y = d->y_block_count;
z = d->z_block_count;
@ -216,6 +215,7 @@ bool Maps::Finish()
bool Maps::isValidBlock (uint32_t x, uint32_t y, uint32_t z)
{
MAPS_GUARD
if ( x >= d->x_block_count || y >= d->y_block_count || z >= d->z_block_count)
return false;
return d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z] != 0;
@ -223,6 +223,7 @@ bool Maps::isValidBlock (uint32_t x, uint32_t y, uint32_t z)
uint32_t Maps::getBlockPtr (uint32_t x, uint32_t y, uint32_t z)
{
MAPS_GUARD
if ( x >= d->x_block_count || y >= d->y_block_count || z >= d->z_block_count)
return 0;
return d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
@ -230,6 +231,7 @@ uint32_t Maps::getBlockPtr (uint32_t x, uint32_t y, uint32_t z)
bool Maps::ReadBlock40d(uint32_t x, uint32_t y, uint32_t z, mapblock40d * buffer)
{
MAPS_GUARD
Process *p = d->owner;
if(d->d->shm_start && d->maps_module) // ACCELERATE!
{
@ -264,10 +266,11 @@ bool Maps::ReadBlock40d(uint32_t x, uint32_t y, uint32_t z, mapblock40d * buffer
/*
* Tiletypes
*/
*/
bool Maps::ReadTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buffer)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
@ -279,6 +282,7 @@ bool Maps::ReadTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buff
bool Maps::WriteTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buffer)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
@ -289,11 +293,12 @@ bool Maps::WriteTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buf
}
/*
* Dirty flags
*/
* Dirty bit
*/
bool Maps::ReadDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool &dirtybit)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if(addr)
{
@ -307,6 +312,7 @@ bool Maps::ReadDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool &dirtybit)
bool Maps::WriteDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool dirtybit)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
@ -321,9 +327,12 @@ bool Maps::WriteDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool dirtybit)
return false;
}
/// read/write the block flags
/*
* Block flags
*/
bool Maps::ReadBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags &blockflags)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if(addr)
{
@ -336,6 +345,7 @@ bool Maps::ReadBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags &bloc
}
bool Maps::WriteBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags blockflags)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
@ -349,10 +359,10 @@ bool Maps::WriteBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags bloc
/*
* Designations
*/
*/
bool Maps::ReadDesignations (uint32_t x, uint32_t y, uint32_t z, designations40d *buffer)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
@ -364,6 +374,7 @@ bool Maps::ReadDesignations (uint32_t x, uint32_t y, uint32_t z, designations40d
bool Maps::WriteDesignations (uint32_t x, uint32_t y, uint32_t z, designations40d *buffer)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
@ -375,10 +386,10 @@ bool Maps::WriteDesignations (uint32_t x, uint32_t y, uint32_t z, designations40
/*
* Occupancies
*/
*/
bool Maps::ReadOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *buffer)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
@ -390,6 +401,7 @@ bool Maps::ReadOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *bu
bool Maps::WriteOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *buffer)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
@ -401,9 +413,10 @@ bool Maps::WriteOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *b
/*
* Temperatures
*/
*/
bool Maps::ReadTemperatures(uint32_t x, uint32_t y, uint32_t z, t_temperatures *temp1, t_temperatures *temp2)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
@ -417,6 +430,7 @@ bool Maps::ReadTemperatures(uint32_t x, uint32_t y, uint32_t z, t_temperatures *
}
bool Maps::WriteTemperatures (uint32_t x, uint32_t y, uint32_t z, t_temperatures *temp1, t_temperatures *temp2)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
@ -434,6 +448,7 @@ bool Maps::WriteTemperatures (uint32_t x, uint32_t y, uint32_t z, t_temperatures
*/
bool Maps::ReadRegionOffsets (uint32_t x, uint32_t y, uint32_t z, biome_indices40d *buffer)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
@ -445,6 +460,7 @@ bool Maps::ReadRegionOffsets (uint32_t x, uint32_t y, uint32_t z, biome_indices4
bool Maps::ReadFeatures(uint32_t x, uint32_t y, uint32_t z, int16_t & local, int16_t & global)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
@ -458,6 +474,7 @@ bool Maps::ReadFeatures(uint32_t x, uint32_t y, uint32_t z, int16_t & local, int
bool Maps::WriteLocalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t local)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
@ -470,6 +487,7 @@ bool Maps::WriteLocalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t local)
bool Maps::WriteGlobalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t global)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
@ -485,6 +503,7 @@ bool Maps::WriteGlobalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t global
*/
bool Maps::ReadVeins(uint32_t x, uint32_t y, uint32_t z, vector <t_vein>* veins, vector <t_frozenliquidvein>* ices, vector <t_spattervein> *splatter)
{
MAPS_GUARD
t_vein v;
t_frozenliquidvein fv;
t_spattervein sv;
@ -625,6 +644,7 @@ __int16 __userpurge GetGeologicalRegion<ax>(__int16 block_X<cx>, int X<ebx>, __i
*/
bool Maps::ReadGeology (vector < vector <uint16_t> >& assign)
{
MAPS_GUARD
memory_info * minfo = d->d->offset_descriptor;
Process *p = d->owner;
// get needed addresses and offsets. Now this is what I call crazy.
@ -694,10 +714,11 @@ bool Maps::ReadGeology (vector < vector <uint16_t> >& assign)
bool Maps::ReadLocalFeatures( std::map <planecoord, std::vector<t_feature *> > & local_features )
{
MAPS_GUARD
// can't be used without a map!
if(!d->block)
return false;
Process * p = d->owner;
memory_info * mem = p->getDescriptor();
// deref pointer to the humongo-structure
@ -709,32 +730,26 @@ bool Maps::ReadLocalFeatures( std::map <planecoord, std::vector<t_feature *> > &
const uint32_t offset_elem = 4;
const uint32_t main_mat_offset = mem->getOffset("local_feature_mat"); // 0x30
const uint32_t sub_mat_offset = mem->getOffset("local_feature_submat"); // 0x34
local_features.clear();
for(uint32_t blockX = 0; blockX < d->x_block_count; blockX ++)
for(uint32_t blockY = 0; blockY < d->x_block_count; blockY ++)
{
//uint64_t block48_x = blockX / 3 + d->regionX;
//uint16_t region_x_plus8 = ( block48_x + 8 ) / 16;
// region X coord offset by 8 big blocks (48x48 tiles)
uint16_t region_x_plus8 = ( (blockX / 3 ) + d->regionX /*+ 8*/ ) / 16;
//((BYTE4(region_x_local) & 0xF) + (_DWORD)region_x_local) >> 4;
//int16_t region_x_local = (blockX / 3) + d->regionX;
//int16_t region_x_plus8 = ((region_x_local & 0xF) + region_x_local) >> 4;
// plain region Y coord
// region X coord (48x48 tiles)
uint16_t region_x_local = ( (blockX / 3) + d->regionX ) / 16;
// region Y coord (48x48 tiles)
uint64_t region_y_local = ( (blockY / 3) + d->regionY ) / 16;
// this is just a few pointers to arrays of 16B (4 DWORD) structs
uint32_t array_elem = p->readDWord(base + (region_x_plus8 / 16) * 4);
uint32_t array_elem = p->readDWord(base + (region_x_local / 16) * 4);
// 16B structs, second DWORD of the struct is a pointer
uint32_t wtf = p->readDWord(array_elem + ( sizeof_elem * ( (uint32_t)region_y_local/16)) + offset_elem);
if(wtf)
{
// wtf + sizeof(vector<ptr>) * crap;
uint32_t feat_vector = wtf + sizeof_vec * (16 * (region_x_plus8 % 16) + (region_y_local % 16));
uint32_t feat_vector = wtf + sizeof_vec * (16 * (region_x_local % 16) + (region_y_local % 16));
DfVector<uint32_t> p_features(p, feat_vector);
uint32_t size = p_features.size();
planecoord pc;
@ -744,7 +759,7 @@ bool Maps::ReadLocalFeatures( std::map <planecoord, std::vector<t_feature *> > &
for(uint32_t i = 0; i < size; i++)
{
uint32_t cur_ptr = p_features[i];
map <uint32_t, t_feature>::iterator it;
it = d->local_feature_store.find(cur_ptr);
// do we already have the feature?
@ -792,19 +807,20 @@ bool Maps::ReadLocalFeatures( std::map <planecoord, std::vector<t_feature *> > &
bool Maps::ReadGlobalFeatures( std::vector <t_feature> & features)
{
MAPS_GUARD
// can't be used without a map!
if(!d->block)
return false;
Process * p = d->owner;
memory_info * mem = p->getDescriptor();
uint32_t global_feature_vector = mem->getAddress("global_feature_vector");
uint32_t global_feature_funcptr = mem->getOffset("global_feature_funcptr_");
const uint32_t main_mat_offset = mem->getOffset("global_feature_mat"); // 0x34
const uint32_t sub_mat_offset = mem->getOffset("global_feature_submat"); // 0x38
DfVector<uint32_t> p_features (p,global_feature_vector);
features.clear();
uint32_t size = p_features.size();
features.reserve(size);
@ -815,7 +831,7 @@ bool Maps::ReadGlobalFeatures( std::vector <t_feature> & features)
temp.origin = feat_ptr;
//temp.discovered = p->readDWord( feat_ptr + 4 ); // maybe, placeholder
temp.discovered = false;
// FIXME: use the memory_info cache mechanisms
string name = p->readClassName(p->readDWord( feat_ptr));
if(name == "feature_init_underworld_from_layerst")

@ -53,6 +53,21 @@ Materials::~Materials()
{
delete d;
}
bool Materials::Finish()
{
inorganic.clear();
organic.clear();
tree.clear();
plant.clear();
race.clear();
raceEx.clear();
color.clear();
other.clear();
alldesc.clear();
return true;
}
/*
{
LABEL_53:
@ -301,8 +316,8 @@ bool Materials::ReadCreatureTypesEx (void)
uint32_t bodypart_id_offset = mem->getOffset ("bodypart_id");
uint32_t bodypart_category_offset = mem->getOffset ("bodypart_category");
uint32_t bodypart_layers_offset = mem->getOffset ("bodypart_layers_vector");
uint32_t bodypart_singular_offset = mem->getOffset ("bodypart_singular_vector");
uint32_t bodypart_plural_offset = mem->getOffset ("bodypart_plural_vector");
uint32_t bodypart_singular_offset = mem->getOffset ("bodypart_singular_vector"); // unused
uint32_t bodypart_plural_offset = mem->getOffset ("bodypart_plural_vector"); // unused
uint32_t color_modifier_part_offset = mem->getOffset ("color_modifier_part");
uint32_t color_modifier_startdate_offset = mem->getOffset ("color_modifier_startdate");
uint32_t color_modifier_enddate_offset = mem->getOffset ("color_modifier_enddate");
@ -318,7 +333,18 @@ bool Materials::ReadCreatureTypesEx (void)
for (uint32_t i = 0; i < size;i++)
{
t_creaturetype mat;
// FROM race READ
// std::string rawname AT 0,
// char tile_character AT tile_offset,
// word tilecolor.fore : tile_color_offset,
// word tilecolor.back : tile_color_offset + 2,
// word tilecolor.bright : tile_color_offset + 4
p->readSTLString (p_races[i], mat.rawname, sizeof(mat.rawname));
mat.tile_character = p->readByte( p_races[i] + tile_offset );
mat.tilecolor.fore = p->readWord( p_races[i] + tile_color_offset );
mat.tilecolor.back = p->readWord( p_races[i] + tile_color_offset + 2 );
mat.tilecolor.bright = p->readWord( p_races[i] + tile_color_offset + 4 );
DfVector <uint32_t> p_castes(p, p_races[i] + castes_vector_offset);
sizecas = p_castes.size();
for (uint32_t j = 0; j < sizecas;j++)
@ -364,11 +390,6 @@ bool Materials::ReadCreatureTypesEx (void)
mat.castes.push_back(caste);
}
mat.tile_character = p->readByte( p_races[i] + tile_offset );
mat.tilecolor.fore = p->readWord( p_races[i] + tile_color_offset );
mat.tilecolor.back = p->readWord( p_races[i] + tile_color_offset + 2 );
mat.tilecolor.bright = p->readWord( p_races[i] + tile_color_offset + 4 );
DfVector <uint32_t> p_extract(p, p_races[i] + extract_vector_offset);
for(uint32_t j = 0; j < p_extract.size(); j++)
{
@ -395,10 +416,10 @@ void Materials::ReadAllMaterials(void)
std::string Materials::getDescription(t_material & mat)
{
std::string out;
int32_t typeC;
std::string out;
int32_t typeC;
if ( (mat.subIndex<419) || (mat.subIndex>618) )
if ( (mat.subIndex<419) || (mat.subIndex>618) )
{
if ( (mat.subIndex<19) || (mat.subIndex>218) )
{
@ -408,13 +429,13 @@ std::string Materials::getDescription(t_material & mat)
else
{
if (mat.subIndex>=this->other.size())
{
if(mat.subIndex<0)
return "any";
if(mat.subIndex>=this->raceEx.size())
return "stuff";
return this->raceEx[mat.subIndex].rawname;
}
{
if(mat.subIndex<0)
return "any";
if(mat.subIndex>=this->raceEx.size())
return "stuff";
return this->raceEx[mat.subIndex].rawname;
}
else
{
if (mat.index==-1)
@ -424,17 +445,17 @@ std::string Materials::getDescription(t_material & mat)
}
}
else
if(mat.index<0)
return "any inorganic";
else
return this->inorganic[mat.index].id;
if(mat.index<0)
return "any inorganic";
else
return this->inorganic[mat.index].id;
}
else
{
if (mat.index>=this->raceEx.size())
return "unknown race";
typeC = mat.subIndex;
typeC -=19;
typeC -=19;
if ((typeC<0) || (typeC>=this->raceEx[mat.index].extract.size()))
{
return string(this->raceEx[mat.index].rawname).append(" extract");
@ -446,6 +467,6 @@ std::string Materials::getDescription(t_material & mat)
{
return this->organic[mat.index].id;
}
return out;
return out;
}

@ -31,20 +31,23 @@ distribution.
namespace DFHack
{
class Materials;
class Module;
class Creatures;
class Maps;
class Position;
class Gui;
class World;
class Position;
class Maps;
class Creatures;
class Materials;
class Items;
class Translation;
class Vegetation;
class Buildings;
class Constructions;
class WindowIO;
class ProcessEnumerator;
class Process;
class WindowIO;
class Vegetation;
class Constructions;
class memory_info;
struct t_name;
class DFContextShared
@ -52,7 +55,7 @@ namespace DFHack
public:
DFContextShared();
~DFContextShared();
// names, used by a few other modules.
void readName(t_name & name, uint32_t address);
// get the name offsets
@ -61,27 +64,30 @@ namespace DFHack
uint32_t name_nickname_offset;
uint32_t name_words_offset;
bool namesInited;
ProcessEnumerator* pm;
Process* p;
char * shm_start;
memory_info* offset_descriptor;
string xml;
// Modules
Creatures * creatures;
Maps * maps;
Position * position;
Gui * gui;
World * world;
Materials * materials;
Items * items;
Translation * translation;
Vegetation * vegetation;
Buildings * buildings;
Constructions * constructions;
WindowIO * windowio;
// Modules
struct
{
Creatures * pCreatures;
Maps * pMaps;
Position * pPosition;
Gui * pGui;
World * pWorld;
Materials * pMaterials;
Items * pItems;
Translation * pTranslation;
Vegetation * pVegetation;
Buildings * pBuildings;
Constructions * pConstructions;
WindowIO * pWindowIO;
} s_mods;
std::vector <Module *> allModules;
/*
uint32_t item_material_offset;
@ -93,7 +99,7 @@ namespace DFHack
uint32_t settlement_name_offset;
uint32_t settlement_world_xy_offset;
uint32_t settlement_local_xy_offset;
uint32_t dwarf_lang_table_offset;
DfVector *p_effect;

@ -0,0 +1,56 @@
################################################################################
# DFCONNECT
###
SET(DFCONNECT_HDRS
shms.h
mod-core.h
mod-maps.h
)
SET(PROJECT_SRCS
mod-core.cpp
mod-maps.cpp
#mod-creature40d.cpp
)
SET(PROJECT_HDRS_LINUX
)
SET(PROJECT_HDRS_WINDOWS
)
SET(PROJECT_SRCS_LINUX
shms-linux.cpp
)
SET(PROJECT_SRCS_WINDOWS
shms-windows.cpp
)
IF(UNIX)
LIST(APPEND PROJECT_HDRS ${PROJECT_HDRS_LINUX})
LIST(APPEND PROJECT_SRCS ${PROJECT_SRCS_LINUX})
ELSE(UNIX)
LIST(APPEND PROJECT_HDRS ${PROJECT_HDRS_WINDOWS})
LIST(APPEND PROJECT_SRCS ${PROJECT_SRCS_WINDOWS})
ENDIF(UNIX)
SET_SOURCE_FILES_PROPERTIES( ${PROJECT_HDRS} PROPERTIES HEADER_FILE_ONLY TRUE )
LIST(APPEND PROJECT_SRCS ${PROJECT_HDRS})
#IF(CMAKE_SIZEOF_VOID_P EQUAL 4)
add_definitions(-DBUILD_SHM)
IF(UNIX)
add_definitions(-DLINUX_BUILD)
SET(PROJECT_LIBS rt)
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden")
ADD_LIBRARY(dfconnect SHARED ${PROJECT_SRCS})
TARGET_LINK_LIBRARIES(dfconnect ${PROJECT_LIBS})
ELSE(UNIX)
# SET(PROJECT_LIBS psapi)
ADD_LIBRARY(SDL SHARED ${PROJECT_SRCS})
TARGET_LINK_LIBRARIES(SDL ${PROJECT_LIBS})
ENDIF(UNIX)
#ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 4)

@ -218,7 +218,17 @@
level_2="Often does the first thing that comes to mind"
level_1="Acts impulsively"
level_0="Always acts without considering alternatives or thinking through possibilities">29</Trait>
====================================================================
M O O D S
====================================================================
<Mood id="0" name="Fey"/>
<Mood id="1" name="Secretive"/>
<Mood id="2" name="Possesed"/>
<Mood id="3" name="Macabre"/>
<Mood id="4" name="Fell"/>
<Mood id="5" name="Melancholy"/>
====================================================================
P R O F E S S I O N S
====================================================================
@ -1455,6 +1465,8 @@ map_data_1b60_offset 0x1B9c
<Offset name="creature_mood">0x288</Offset>
<Offset name="creature_birth_year">0x298</Offset>
<Offset name="creature_birth_time">0x29C</Offset>
<Offset name="creature_current_job">0x390</Offset> <!-- from chmod -->
<Offset name="creature_mood_skill">0x394</Offset> the skill that will be increased at the end of the mood (or not)
<Offset name="creature_physical">0x464</Offset>
<!--
<Offset name="creature_strength">0x464</Offset>
@ -1464,8 +1476,6 @@ map_data_1b60_offset 0x1B9c
<Offset name="creature_recuperation">0x4D4</Offset>
<Offset name="creature_disease_resistance">0x4F0</Offset>
-->
<Offset name="creature_current_job">0x390</Offset> <!-- from chmod -->
<Offset name="creature_mood_skill">0x394</Offset> the skill that will be increased at the end of the mood (or not)
<Offset name="creature_appearance_vector">0x604</Offset>
<Offset name="creature_artifact_name">0x6D4</Offset>
<Offset name="creature_labors">0x774</Offset>
@ -1628,7 +1638,6 @@ map_data_1b60_offset 0x1B9c
<Entry version="v0.31.05" os="windows" id="0.31.05" base="0.31.04" rebase="0x8010">
<String name="md5">394ff63fc00fedd5df0b36e4beb589bc</String>
<HexValue name="pe_timestamp">0x4c091569</HexValue>
<!--<Address name="creature_vector">0x1678704</Address> CHMOD-->
<Address name="dwarf_race_index">0x014abee4</Address> CHMOD
<Address name="dwarf_civ_id">0x1471FB0</Address> BOGUS!
<Address name="window_dims">0x180b10c</Address> LOOKS O.K.
@ -1638,48 +1647,6 @@ map_data_1b60_offset 0x1B9c
<Address name="cursor_xyz">0xaf12cc</Address> VERIFIED
<Address name="current_tick">0xE80780</Address> LOOKS O.K.
<Address name="current_year">0xEB2878</Address> LOOKS O.K.
<!--
<Address name="mat_inorganics">0x16BD0B0</Address>
<Address name="mat_organics_all">0x16BD0C8</Address>
<Address name="mat_organics_plants">0x16bd0e0</Address>
<Address name="mat_organics_trees">0x16bd110</Address>
<Address name="creature_type_vector">0x16BD204</Address>
<Address name="descriptor_colors_vector">0x16C5ACC</Address>
<Address name="descriptor_all_colors">0x16C5AFC</Address>
-->
<!--<Address name="mat_other">0x16C6478</Address>-->
<!--<Address name="mat_stuff">0x16C6478</Address> -->
<!--<Address name="descriptor_vectors_start">0x16C5AE4</Address> -->
<!--
<Address name="language_vector">0x16BD384</Address> OLD
<Address name="translation_vector">0x16BD3B4</Address> OLD
<Address name="language_vector">0x016c539c</Address> CHMOD
<Address name="translation_vector">0x016c53cc</Address> CHMOD
-->
<!--
<Address name="map_data">0x16c2ad4</Address> old 0x016BAAC4
<Address name="x_count_block">0x16c2af4</Address> old 0x016BAAE4
<Address name="y_count_block">0x16c2af8</Address> old 0x016BAAE8
<Address name="z_count_block">0x16c2afc</Address> old 0x016BAAEC
<Address name="x_count">0x16c2b00</Address> old 0x016BAAF0
<Address name="y_count">0x16c2b04</Address> old 0x016BAAF4
<Address name="z_count">0x16c2b08</Address> old 0x016BAAF8
<Address name="region_x">0x16c2b0C</Address> old 0x016BAAFC
<Address name="region_y">0x16c2b10</Address> old 0x016BAB00
<Address name="region_z">0x16c2b14</Address> old 0x016BAB04
<Address name="world_size_x">0x16C4190</Address> VERIFIED
<Address name="world_size_y">0x16C4192</Address> VERIFIED
<Address name="geoblock_vector">0x16C48E8</Address> LOOKS O.K.
<Address name="ptr2_region_array">0x16C4930</Address> LOOKS O.K.
<Address name="global_feature_vector">0x16C48B8</Address> LOOKS O.K.
<Address name="local_feature_start_ptr">0x16BC974</Address>
<Address name="construction_vector">0x1664CD8</Address>
<Address name="vegetation_vector">0x1679D54</Address>
<Address name="buildings_vector">0x16793e8</Address>
<Address name="items_vector">0x1678800</Address>
-->
<Offset name="item_type_accessor">0x0</Offset> Why do i have to redefine this ???
... what?
</Entry>
@ -1687,11 +1654,31 @@ map_data_1b60_offset 0x1B9c
<String name="md5">c4b7e37dafa2716e31d29110968ac64e</String>
<HexValue name="pe_timestamp">0x4c0f83d5</HexValue>
<Address name="cursor_xyz">0xaf12d0</Address>
[addresses]
translation_vector = 0x016c53dc
language_vector = 0x016c53ac
creature_vector = 0x0168071c
dwarf_race_index = 0x014abef4
</Entry>
<Entry version="v0.31.07" os="windows" id="0.31.07" base="0.31.06" rebase="0x2000">
<String name="md5">1c0b5254af1b8ff9a34b51c3f6609da3</String>
<HexValue name="pe_timestamp">0x4c1cbe4b</HexValue>
<Address name="cursor_xyz">0xaf32d8</Address>0xaf12d0
<Address name="window_dims">0x180d11c</Address> 0x180b10c
<Address name="window_x">0xe6e0ec</Address>
<Address name="window_y">0xe9c1c0</Address>
<Address name="window_z">0xe9c19c</Address>
map size X: 0x16c4b10
map size Y: 0x16c4b14
</Entry>
<Entry version="v0.31.08" os="windows" id="0.31.08" base="0.31.07" rebase="-0x1000">
<String name="md5">a83e6b21307cf41fb54c315fa40dec86</String>
<HexValue name="pe_timestamp">0x4c1d69fe</HexValue>
<Address name="dwarf_civ_id">0x14acee8</Address>
<!--
<Address name="cursor_xyz">0xaf32d8</Address>0xaf12d0
<Address name="window_dims">0x180d11c</Address> 0x180b10c
<Address name="window_x">0xe6e0ec</Address>
<Address name="window_y">0xe9c1c0</Address>
<Address name="window_z">0xe9c19c</Address>
map size X: 0x16c4b10
map size Y: 0x16c4b14
-->
</Entry>
.-"""-.
@ -1831,9 +1818,23 @@ dwarf_race_index = 0x014abef4
Creature type offsets
=====================
<Offset name="creature_type_caste_vector">0x60</Offset> VERIFIED
from 0.31.08
Toad: 0xaf75b68
Toad: rawname = 0x0
Toad: character (not reliable) = 0x20
Toad: caste vector = 0x60
Toad: extract? vector = 0x18f4
Toad: colors = 0x36
<Offset name="creature_type_extract_vector">0x18f4</Offset> VERIFIED
<Offset name="creature_tile">0x20</Offset> VERIFIED
<Offset name="creature_tile_color">0x36</Offset> LOOKS OK
<!--
<Offset name="creature_type_caste_vector">0x138</Offset>
<Offset name="creature_type_extract_vector">0x1A14</Offset>
<Offset name="creature_tile">0xE0</Offset>
<Offset name="creature_tile_color">0xF6</Offset>
-->
<!--
struct CreatureType
{
@ -2153,10 +2154,37 @@ dwarf_race_index = 0x014abef4
<Address name="language_vector">0x931aff4</Address>
WORLD + 0x54E80
<Address name="translation_vector">0x931b00c</Address>
Creatures
=========
<Address name="creature_vector">0x92D9AC0</Address>
<Address name="dwarf_race_index">0x92C1628</Address>0x092CB608
<Address name="dwarf_civ_id">0x92C161C</Address>0x092CB5FC
Time
====
<Address name="current_year">0x92BF6A0</Address>
<Address name="current_tick">0x92BF6A8</Address>
YEAR 0x92BF6A0, WORLD - 0x6A40
TICKS 0x92BF6A8, WORLD - 0x6A40 + 0x08
</Entry>
<Entry version="v0.31.06" os="linux" id="30_06lin" base="30_05lin" rebase="-0x20E0">
<String name="md5">13a1c19e8f59b74e307e094e2a0f28c3</String>
<Address name="cursor_xyz">0x8b0b328</Address> VERIFIED
WORLD = 0x92C4000
Creatures
=========
WORLD + 0x139E0
0x92d79d4
0x92d79e0 = real one? seems like it
0x92d7a10
</Entry>
<Entry version="v0.31.07" os="linux" id="30_07lin" base="30_06lin" rebase="0x2000">
<String name="md5">b31979551782e89c049b11db8d2d86d7</String>
</Entry>
<Entry version="v0.31.08" os="linux" id="30_08lin" base="30_07lin">
<String name="md5">e37750890350d7b9d8203879aff8fa5c</String>
</Entry>
</MemoryDescriptors>
</DFExtractor>

@ -170,6 +170,11 @@ void printCreature(DFHack::Context * DF, const DFHack::t_creature & creature)
addendl=true;
}
if(creature.civ)
{
cout << "civilization: " << creature.civ;
addendl = true;
}
/*
cout << ", likes: ";

@ -13,6 +13,10 @@ TARGET_LINK_LIBRARIES(dfmoodump dfhack)
ADD_EXECUTABLE(dftest test.cpp)
TARGET_LINK_LIBRARIES(dftest dfhack)
# just dump offsets of the current version
ADD_EXECUTABLE(dfdoffsets dumpoffsets.cpp)
TARGET_LINK_LIBRARIES(dfdoffsets dfhack)
# bauxite - turn all mechanisms into bauxite mechanisms
# Author: Alex Legg
#ADD_EXECUTABLE(dfbauxite dfbauxite.cpp)
@ -55,4 +59,4 @@ TARGET_LINK_LIBRARIES(dfcatsplosion dfhack)
# df directly
# Author: belal
#ADD_EXECUTABLE(dfrenamer renamer.cpp)
#TARGET_LINK_LIBRARIES(dfrenamer dfhack)
#TARGET_LINK_LIBRARIES(dfrenamer dfhack)

@ -17,31 +17,45 @@ class SegmentFinder
{
delete mr_.buffer;
}
template <class needleType, class hayType, typename comparator >
bool Find (needleType needle, const uint8_t increment ,vector <uint64_t> &found, vector <uint64_t> &newfound, comparator oper)
bool Find (needleType needle, const uint8_t increment , vector <uint64_t> &newfound, comparator oper)
{
if(found.empty())
//loop
for(uint64_t offset = 0; offset < (mr_.end - mr_.start) - sizeof(hayType); offset += increment)
{
//loop
for(uint64_t offset = 0; offset < (mr_.end - mr_.start) - sizeof(hayType); offset += increment)
{
if( oper(_SF,(hayType *)(mr_.buffer + offset), needle) )
newfound.push_back(mr_.start + offset);
}
if( oper(_SF,(hayType *)(mr_.buffer + offset), needle) )
newfound.push_back(mr_.start + offset);
}
else
return !newfound.empty();
}
template < class needleType, class hayType, typename comparator >
uint64_t FindInRange (needleType needle, comparator oper, uint64_t start, uint64_t length)
{
uint64_t stopper = min((mr_.end - mr_.start) - sizeof(hayType), (start - mr_.start) - sizeof(hayType) + length);
//loop
for(uint64_t offset = start - mr_.start; offset < stopper; offset +=1)
{
if( oper(_SF,(hayType *)(mr_.buffer + offset), needle) )
return mr_.start + offset;
}
return 0;
}
template <class needleType, class hayType, typename comparator >
bool Filter (needleType needle, vector <uint64_t> &found, vector <uint64_t> &newfound, comparator oper)
{
for( uint64_t i = 0; i < found.size(); i++)
{
for( uint64_t i = 0; i < found.size(); i++)
if(mr_.isInRange(found[i]))
{
if(mr_.isInRange(found[i]))
{
uint64_t corrected = found[i] - mr_.start;
if( oper(_SF,(hayType *)(mr_.buffer + corrected), needle) )
newfound.push_back(found[i]);
}
uint64_t corrected = found[i] - mr_.start;
if( oper(_SF,(hayType *)(mr_.buffer + corrected), needle) )
newfound.push_back(found[i]);
}
}
return true;
return !newfound.empty();
}
private:
friend class SegmentedFinder;
@ -81,16 +95,52 @@ class SegmentedFinder
}
template <class needleType, class hayType, typename comparator >
bool Find (const needleType needle, const uint8_t increment, vector <uint64_t> &found, comparator oper)
{
found.clear();
for(int i = 0; i < segments.size(); i++)
{
segments[i]->Find<needleType,hayType,comparator>(needle, increment, found, oper);
}
return !(found.empty());
}
template < class needleType, class hayType, typename comparator >
uint64_t FindInRange (needleType needle, comparator oper, uint64_t start, uint64_t length)
{
SegmentFinder * sf = getSegmentForAddress(start);
if(sf)
{
return sf->FindInRange<needleType,hayType,comparator>(needle, oper, start, length);
}
return 0;
}
template <class needleType, class hayType, typename comparator >
bool Filter (const needleType needle, vector <uint64_t> &found, comparator oper)
{
vector <uint64_t> newfound;
for(int i = 0; i < segments.size(); i++)
{
segments[i]->Find<needleType,hayType,comparator>(needle, increment, found, newfound, oper);
segments[i]->Filter<needleType,hayType,comparator>(needle, found, newfound, oper);
}
found.clear();
found = newfound;
return !(found.empty());
}
template <class needleType, class hayType, typename comparator >
bool Incremental (needleType needle, const uint8_t increment ,vector <uint64_t> &found, comparator oper)
{
if(found.empty())
{
return Find <needleType, hayType, comparator>(needle,increment,found,oper);
}
else
{
return Filter <needleType, hayType, comparator>(needle,found,oper);
}
}
template <typename T>
T * Translate(uint64_t address)
{
@ -103,11 +153,13 @@ class SegmentedFinder
}
return 0;
}
template <typename T>
T Read(uint64_t address)
{
return *Translate<T>(address);
}
template <typename T>
bool Read(uint64_t address, T& target)
{
@ -234,6 +286,19 @@ bool vectorAll (SegmentedFinder* s, vecTriplet *x, int )
return false;
}
struct Bytestream
{
uint32_t length;
void * object;
};
bool findBytestream (SegmentedFinder* s, void *addr, Bytestream compare )
{
if(memcmp(addr, compare.object, compare.length) == 0)
return true;
return false;
}
bool findString (SegmentedFinder* s, uint32_t *addr, const char * compare )
{
// read string pointer, translate to local scheme

@ -0,0 +1,38 @@
#include <iostream>
#include <iomanip>
#include <climits>
#include <vector>
#include <sstream>
#include <ctime>
#include <cstdio>
using namespace std;
#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 (exception& e)
{
cerr << e.what() << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
memory_info * minfo = DF->getMemoryInfo();
if(minfo)
cout << minfo->PrintOffsets();
#ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl;
cin.ignore();
#endif
return 0;
}

@ -20,6 +20,115 @@ using namespace std;
#include <DFHack.h>
#include "SegmentedFinder.h"
template <class T>
class holder
{
public:
vector <T> values;
SegmentedFinder & sf;
holder(SegmentedFinder& sff):sf(sff){};
bool isValid(size_t idx)
{
};
};
class address
{
public:
uint64_t addr_;
unsigned int valid : 1;
virtual void print(SegmentedFinder& sff)
{
cout << hex << "0x" << addr_ << endl;
};
address(const uint64_t addr)
{
addr_ = addr;
valid = false;
}
virtual address & operator=(const uint64_t in)
{
addr_ = in;
valid = false;
return *this;
}
virtual bool isValid(SegmentedFinder& sff)
{
if(valid) return true;
if(sff.getSegmentForAddress(addr_))
{
valid = 1;
}
}
virtual bool equals (SegmentedFinder & sf, address & rhs)
{
return rhs.addr_ == addr_;
}
};
// pointer to a null-terminated byte string
class Cstr: public address
{
void print(SegmentedFinder & sf)
{
cout << hex << "0x" << addr_ << ": \"" << sf.Translate<char>(addr_) << "\"" << endl;
}
bool equals(SegmentedFinder & sf,const char * rhs)
{
uint32_t addr2 = *(sf.Translate<uint32_t>(addr_));
return strcmp(sf.Translate<const char>(addr2), rhs) == 0;
}
template <class Predicate, class inType>
bool equalsP(SegmentedFinder & sf,inType rhs)
{
return Predicate(addr_, sf, rhs);
}
bool isValid(SegmentedFinder& sf)
{
if (address::isValid(sf))
{
// read the pointer
uint32_t addr2 = *(sf.Translate<uint32_t>(addr_));
// is it a real pointer? a pretty weak test, but whatever.
if(sf.getSegmentForAddress(addr2))
return true;
}
return false;
}
};
// STL STRING
#ifdef LINUX_BUILD
class STLstr: public address
{
};
#endif
#ifndef LINUX_BUILD
class STLstr: public address
{
};
#endif
// STL VECTOR
#ifdef LINUX_BUILD
class Vector: public address
{
};
#endif
#ifndef LINUX_BUILD
class Vector: public address
{
};
#endif
class Int64: public address{};
class Int32: public address{};
class Int16: public address{};
class Int8: public address{};
inline void printRange(DFHack::t_memrange * tpr)
{
@ -79,8 +188,8 @@ bool getRanges(DFHack::Process * p, vector <DFHack::t_memrange>& selected_ranges
}
else if(p->getDescriptor()->getOS() == DFHack::memory_info::OS_LINUX)
{
start = min(11, (int)ranges.size());
end = min(14, (int)ranges.size());
start = min(2, (int)ranges.size());
end = min(4, (int)ranges.size());
}
else
{
@ -258,13 +367,13 @@ void FindIntegers(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& r
switch(size)
{
case 1:
sf.Find<uint8_t,uint8_t>(test1,alignment,found, equalityP<uint8_t>);
sf.Incremental<uint8_t,uint8_t>(test1,alignment,found, equalityP<uint8_t>);
break;
case 2:
sf.Find<uint16_t,uint16_t>(test1,alignment,found, equalityP<uint16_t>);
sf.Incremental<uint16_t,uint16_t>(test1,alignment,found, equalityP<uint16_t>);
break;
case 4:
sf.Find<uint32_t,uint32_t>(test1,alignment,found, equalityP<uint32_t>);
sf.Incremental<uint32_t,uint32_t>(test1,alignment,found, equalityP<uint32_t>);
break;
}
DF->Detach();
@ -288,8 +397,8 @@ void FindVectorByLength(DFHack::ContextManager & DFMgr, vector <DFHack::t_memran
DFHack::Context * DF = DFMgr.getSingleContext();
DF->Attach();
SegmentedFinder sf(ranges,DF);
sf.Find<int ,vecTriplet>(0,4,found,vectorAll);
sf.Find<uint32_t,vecTriplet>(length * element_size,4,found,vectorLength<uint32_t>);
sf.Incremental<int ,vecTriplet>(0,4,found,vectorAll);
sf.Filter<uint32_t,vecTriplet>(length * element_size,found,vectorLength<uint32_t>);
DF->Detach();
}
}
@ -300,14 +409,12 @@ void FindVectorByObjectRawname(DFHack::ContextManager & DFMgr, vector <DFHack::t
string select;
while (Incremental(found, "raw name",select,"vector","vectors"))
{
// clear the list of found addresses -- this is a one-shot
found.clear();
DFMgr.Refresh();
DFHack::Context * DF = DFMgr.getSingleContext();
DF->Attach();
SegmentedFinder sf(ranges,DF);
sf.Find<int ,vecTriplet>(0,4,found, vectorAll);
sf.Find<const char * ,vecTriplet>(select.c_str(),4,found, vectorString);
sf.Filter<const char * ,vecTriplet>(select.c_str(),found, vectorString);
DF->Detach();
}
}
@ -318,14 +425,12 @@ void FindVectorByFirstObjectRawname(DFHack::ContextManager & DFMgr, vector <DFHa
string select;
while (Incremental(found, "raw name",select,"vector","vectors"))
{
// clear the list of found addresses -- this is a one-shot
found.clear();
DFMgr.Refresh();
DFHack::Context * DF = DFMgr.getSingleContext();
DF->Attach();
SegmentedFinder sf(ranges,DF);
sf.Find<int ,vecTriplet>(0,4,found, vectorAll);
sf.Find<const char * ,vecTriplet>(select.c_str(),4,found, vectorStringFirst);
sf.Filter<const char * ,vecTriplet>(select.c_str(),found, vectorStringFirst);
DF->Detach();
}
}
@ -348,14 +453,12 @@ void FindVectorByBounds(DFHack::ContextManager & DFMgr, vector <DFHack::t_memran
uint32_t select;
while (Incremental(found, "address between vector.start and vector.end",select,"vector","vectors"))
{
// clear the list of found addresses -- this is a one-shot
found.clear();
DFMgr.Refresh();
DFHack::Context * DF = DFMgr.getSingleContext();
DF->Attach();
SegmentedFinder sf(ranges,DF);
sf.Find<int ,vecTriplet>(0,4,found, vectorAll);
sf.Find<uint32_t ,vecTriplet>(select,4,found, vectorAddrWithin);
sf.Filter<uint32_t ,vecTriplet>(select,found, vectorAddrWithin);
// sort by size of vector
std::sort(found.begin(), found.end(), VectorSizeFunctor(sf));
DF->Detach();
@ -368,14 +471,12 @@ void FindPtrVectorsByObjectAddress(DFHack::ContextManager & DFMgr, vector <DFHac
uint32_t select;
while (Incremental(found, "object address",select,"vector","vectors"))
{
// clear the list of found addresses -- this is a one-shot
found.clear();
DFMgr.Refresh();
DFHack::Context * DF = DFMgr.getSingleContext();
DF->Attach();
SegmentedFinder sf(ranges,DF);
sf.Find<int ,vecTriplet>(0,4,found, vectorAll);
sf.Find<uint32_t ,vecTriplet>(select,4,found, vectorOfPtrWithin);
sf.Filter<uint32_t ,vecTriplet>(select,found, vectorOfPtrWithin);
DF->Detach();
}
}
@ -391,7 +492,7 @@ void FindStrings(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& ra
DFHack::Context * DF = DFMgr.getSingleContext();
DF->Attach();
SegmentedFinder sf(ranges,DF);
sf.Find< const char * ,uint32_t>(select.c_str(),1,found, findString);
sf.Incremental< const char * ,uint32_t>(select.c_str(),1,found, findString);
DF->Detach();
}
}
@ -452,6 +553,15 @@ void printFoundStrVec(vector <uint64_t> &found, const char * what, SegmentedFind
}
}
// meh
#pragma pack(1)
struct tilecolors
{
uint16_t fore;
uint16_t back;
uint16_t bright;
};
#pragma pack()
void automatedLangtables(DFHack::Context * DF, vector <DFHack::t_memrange>& ranges)
{
@ -490,17 +600,17 @@ void automatedLangtables(DFHack::Context * DF, vector <DFHack::t_memrange>& rang
// find lang vector (neutral word table)
to_filter = filtVectors;
sf.Find<const char * ,vecTriplet>("ABBEY",4,to_filter, vectorStringFirst);
sf.Filter<const char * ,vecTriplet>("ABBEY",to_filter, vectorStringFirst);
uint64_t lang_addr = to_filter[0];
// find dwarven language word table
to_filter = filtVectors;
sf.Find<const char * ,vecTriplet>("kulet",4,to_filter, vectorStringFirst);
sf.Filter<const char * ,vecTriplet>("kulet",to_filter, vectorStringFirst);
kulet_vector = to_filter[0];
// find vector of languages
to_filter = filtVectors;
sf.Find<const char * ,vecTriplet>("DWARF",4,to_filter, vectorStringFirst);
sf.Filter<const char * ,vecTriplet>("DWARF",to_filter, vectorStringFirst);
// verify
for(int i = 0; i < to_filter.size(); i++)
@ -525,35 +635,35 @@ void automatedLangtables(DFHack::Context * DF, vector <DFHack::t_memrange>& rang
// inorganics vector
to_filter = filtVectors;
//sf.Find<uint32_t,vecTriplet>(257 * 4,4,to_filter,vectorLength<uint32_t>);
sf.Find<const char * ,vecTriplet>("IRON",4,to_filter, vectorString);
sf.Find<const char * ,vecTriplet>("ONYX",4,to_filter, vectorString);
sf.Find<const char * ,vecTriplet>("RAW_ADAMANTINE",4,to_filter, vectorString);
sf.Find<const char * ,vecTriplet>("BLOODSTONE",4,to_filter, vectorString);
sf.Filter<const char * ,vecTriplet>("IRON",to_filter, vectorString);
sf.Filter<const char * ,vecTriplet>("ONYX",to_filter, vectorString);
sf.Filter<const char * ,vecTriplet>("RAW_ADAMANTINE",to_filter, vectorString);
sf.Filter<const char * ,vecTriplet>("BLOODSTONE",to_filter, vectorString);
printFound(to_filter,"inorganics");
// organics vector
to_filter = filtVectors;
sf.Find<uint32_t,vecTriplet>(52 * 4,4,to_filter,vectorLength<uint32_t>);
sf.Find<const char * ,vecTriplet>("MUSHROOM_HELMET_PLUMP",4,to_filter, vectorStringFirst);
sf.Filter<uint32_t,vecTriplet>(52 * 4,to_filter,vectorLength<uint32_t>);
sf.Filter<const char * ,vecTriplet>("MUSHROOM_HELMET_PLUMP",to_filter, vectorStringFirst);
printFound(to_filter,"organics");
// tree vector
to_filter = filtVectors;
sf.Find<uint32_t,vecTriplet>(31 * 4,4,to_filter,vectorLength<uint32_t>);
sf.Find<const char * ,vecTriplet>("MANGROVE",4,to_filter, vectorStringFirst);
sf.Filter<uint32_t,vecTriplet>(31 * 4,to_filter,vectorLength<uint32_t>);
sf.Filter<const char * ,vecTriplet>("MANGROVE",to_filter, vectorStringFirst);
printFound(to_filter,"trees");
// plant vector
to_filter = filtVectors;
sf.Find<uint32_t,vecTriplet>(21 * 4,4,to_filter,vectorLength<uint32_t>);
sf.Find<const char * ,vecTriplet>("MUSHROOM_HELMET_PLUMP",4,to_filter, vectorStringFirst);
sf.Filter<uint32_t,vecTriplet>(21 * 4,to_filter,vectorLength<uint32_t>);
sf.Filter<const char * ,vecTriplet>("MUSHROOM_HELMET_PLUMP",to_filter, vectorStringFirst);
printFound(to_filter,"plants");
// color descriptors
//AMBER, 112
to_filter = filtVectors;
sf.Find<uint32_t,vecTriplet>(112 * 4,4,to_filter,vectorLength<uint32_t>);
sf.Find<const char * ,vecTriplet>("AMBER",4,to_filter, vectorStringFirst);
sf.Filter<uint32_t,vecTriplet>(112 * 4,to_filter,vectorLength<uint32_t>);
sf.Filter<const char * ,vecTriplet>("AMBER",to_filter, vectorStringFirst);
printFound(to_filter,"color descriptors");
if(!to_filter.empty())
{
@ -567,28 +677,98 @@ void automatedLangtables(DFHack::Context * DF, vector <DFHack::t_memrange>& rang
// all descriptors
//AMBER, 338
to_filter = filtVectors;
sf.Find<uint32_t,vecTriplet>(338 * 4,4,to_filter,vectorLength<uint32_t>);
sf.Find<const char * ,vecTriplet>("AMBER",4,to_filter, vectorStringFirst);
sf.Filter<uint32_t,vecTriplet>(338 * 4,to_filter,vectorLength<uint32_t>);
sf.Filter<const char * ,vecTriplet>("AMBER",to_filter, vectorStringFirst);
printFound(to_filter,"all descriptors");
// creature type
//ELEPHANT, ?? (demons abound)
to_filter = filtVectors;
//sf.Find<uint32_t,vecTriplet>(338 * 4,4,to_filter,vectorLength<uint32_t>);
sf.Find<const char * ,vecTriplet>("ELEPHANT",4,to_filter, vectorString);
sf.Find<const char * ,vecTriplet>("CAT",4,to_filter, vectorString);
sf.Find<const char * ,vecTriplet>("DWARF",4,to_filter, vectorString);
sf.Find<const char * ,vecTriplet>("WAMBLER_FLUFFY",4,to_filter, vectorString);
sf.Find<const char * ,vecTriplet>("TOAD",4,to_filter, vectorString);
sf.Find<const char * ,vecTriplet>("DEMON_1",4,to_filter, vectorString);
sf.Filter<const char * ,vecTriplet>("ELEPHANT",to_filter, vectorString);
sf.Filter<const char * ,vecTriplet>("CAT",to_filter, vectorString);
sf.Filter<const char * ,vecTriplet>("DWARF",to_filter, vectorString);
sf.Filter<const char * ,vecTriplet>("WAMBLER_FLUFFY",to_filter, vectorString);
sf.Filter<const char * ,vecTriplet>("TOAD",to_filter, vectorString);
sf.Filter<const char * ,vecTriplet>("DEMON_1",to_filter, vectorString);
vector <uint64_t> toad_first = to_filter;
vector <uint64_t> elephant_first = to_filter;
sf.Find<const char * ,vecTriplet>("TOAD",4,toad_first, vectorStringFirst);
sf.Find<const char * ,vecTriplet>("ELEPHANT",4,elephant_first, vectorStringFirst);
sf.Filter<const char * ,vecTriplet>("TOAD",toad_first, vectorStringFirst);
sf.Filter<const char * ,vecTriplet>("ELEPHANT",elephant_first, vectorStringFirst);
printFoundStrVec(toad_first,"toad-first creature types",sf);
printFound(elephant_first,"elephant-first creature types");
printFound(to_filter,"all creature types");
uint64_t to_use = 0;
if(!elephant_first.empty())
{
to_use = elephant_first[0];
vecTriplet *vtCretypes = sf.Translate<vecTriplet>(to_use);
uint32_t elephant = sf.Read<uint32_t>(vtCretypes->start);
uint64_t Eoffset;
cout << "Elephant: 0x" << hex << elephant << endl;
cout << "Elephant: rawname = 0x0" << endl;
Eoffset = sf.FindInRange<uint8_t,uint8_t> ('E',equalityP<uint8_t>, elephant, 0x300 );
if(Eoffset)
{
cout << "Elephant: big E = 0x" << hex << Eoffset - elephant << endl;
}
Eoffset = sf.FindInRange<const char *,vecTriplet> ("FEMALE",vectorStringFirst, elephant, 0x300 );
if(Eoffset)
{
cout << "Elephant: caste vector = 0x" << hex << Eoffset - elephant << endl;
}
Eoffset = sf.FindInRange<const char *,vecTriplet> ("SKIN",vectorStringFirst, elephant, 0x2000 );
if(Eoffset)
{
cout << "Elephant: extract? vector = 0x" << hex << Eoffset - elephant << endl;
}
tilecolors eletc = {7,0,0};
Bytestream bs_eletc = {sizeof(tilecolors), &eletc};
Eoffset = sf.FindInRange<Bytestream,tilecolors> (bs_eletc, findBytestream, elephant, 0x300 );
if(Eoffset)
{
cout << "Elephant: colors = 0x" << hex << Eoffset - elephant << endl;
}
//cout << "Amber color:" << hex << "0x" << colorObj << endl;
// TODO: find string 'amber', the floats
}
if(!toad_first.empty())
{
to_use = toad_first[0];
vecTriplet *vtCretypes = sf.Translate<vecTriplet>(to_use);
uint32_t toad = sf.Read<uint32_t>(vtCretypes->start);
uint64_t Eoffset;
cout << "Toad: 0x" << hex << toad << endl;
cout << "Toad: rawname = 0x0" << endl;
Eoffset = sf.FindInRange<uint8_t,uint8_t> (0xF9,equalityP<uint8_t>, toad, 0x300 );
if(Eoffset)
{
cout << "Toad: character (not reliable) = 0x" << hex << Eoffset - toad << endl;
}
Eoffset = sf.FindInRange<const char *,vecTriplet> ("FEMALE",vectorStringFirst, toad, 0x300 );
if(Eoffset)
{
cout << "Toad: caste vector = 0x" << hex << Eoffset - toad << endl;
}
Eoffset = sf.FindInRange<const char *,vecTriplet> ("SKIN",vectorStringFirst, toad, 0x2000 );
if(Eoffset)
{
cout << "Toad: extract? vector = 0x" << hex << Eoffset - toad << endl;
}
tilecolors toadtc = {2,0,0};
Bytestream bs_toadc = {sizeof(tilecolors), &toadtc};
Eoffset = sf.FindInRange<Bytestream,tilecolors> (bs_toadc, findBytestream, toad, 0x300 );
if(Eoffset)
{
cout << "Toad: colors = 0x" << hex << Eoffset - toad << endl;
}
}
if(to_use)
{
}
}
int main (void)

@ -0,0 +1,43 @@
#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;
}

@ -26,6 +26,8 @@ int main (void)
DF=DFMgr.getSingleContext();
DF->Attach();
Maps = DF->getMaps();
Maps->Start();
Maps->getSize(x_max,y_max,z_max);
Position = DF->getPosition();
}
catch (exception& e)
@ -44,7 +46,6 @@ int main (void)
int amount = 7;
while(!end)
{
Maps->getSize(x_max,y_max,z_max);
DF->Resume();
string command = "";
cout <<"[" << mode << ":" << amount << ":" << flowmode << "]# ";
@ -71,7 +72,6 @@ int main (void)
<< endl
<< "Usage: point the DF cursor at a tile you want to modify" << endl
<< "and use the commands available :)" << endl;
}
else if(command == "m")
{

@ -13,11 +13,32 @@
#include <vector>
#include <map>
#include <stdio.h>
#include <algorithm>
using namespace std;
#include <DFHack.h>
#include <dfhack/DFTileTypes.h>
template<template <typename> class P = std::less >
struct compare_pair_first
{
template<class T1, class T2>
bool operator()(const std::pair<T1, T2>& left, const std::pair<T1, T2>& right)
{
return P<T1>()(left.first, right.first);
}
};
template<template <typename> class P = std::less >
struct compare_pair_second
{
template<class T1, class T2>
bool operator()(const std::pair<T1, T2>& left, const std::pair<T1, T2>& right)
{
return P<T2>()(left.second, right.second);
}
};
int main (int argc, const char* argv[])
{
@ -276,7 +297,7 @@ int main (int argc, const char* argv[])
cout << "Number of overflows: " << num_overflows;
}
cout << endl;
vector <pair <int16_t, uint32_t> > matss;
map<int16_t, uint32_t>::iterator p;
for(p = materials.begin(); p != materials.end(); p++)
{
@ -286,9 +307,14 @@ int main (int argc, const char* argv[])
}
else
{
cout << Mats->inorganic[p->first].id << " : " << p->second << endl;
matss.push_back( pair<int16_t,uint32_t>(p->first, p->second) );
}
}
std::sort(matss.begin(), matss.end(), compare_pair_second<>());
for(int i = 0; i < matss.size();i++)
{
cout << Mats->inorganic[matss[i].first].id << " : " << matss[i].second << endl;
}
DF->Detach();
#ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl;