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) PROJECT (dfhack)
cmake_minimum_required(VERSION 2.6) cmake_minimum_required(VERSION 2.6)
SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMake/Modules) SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMake/Modules)
SET ( DFHACK_VERSION "0.4.0.3-dev" )
# disable warning, autosearch # disable warning, autosearch
if(COMMAND cmake_policy) 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( 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" ) 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/include/)
include_directories (${CMAKE_SOURCE_DIR}/library/shm/) include_directories (${CMAKE_SOURCE_DIR}/library/shm/)
include_directories (${CMAKE_SOURCE_DIR}/library/depends/md5/) 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/) include_directories (${CMAKE_SOURCE_DIR}/library/depends/argstream/)
add_subdirectory (library) add_subdirectory (library)
add_subdirectory (library/shm)
#add_subdirectory (dfhack/python) #add_subdirectory (dfhack/python)
add_subdirectory (tools/examples) add_subdirectory (tools/examples)
add_subdirectory (tools/playground) add_subdirectory (tools/playground)
add_subdirectory (tools/supported) 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. 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) Veinlook requires the wide-character ncurses library (libncursesw)
(Linux only) You'll need X11 dev libraries.
Building on Linux: 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: Currently supported Dwarf Fortress versions:
* Windows * Windows
0.31.01 - 0.31.03 legacy 0.31.01 - 0.31.03 legacy
0.31.04 - 0.31.06 SDL 0.31.04 - 0.31.08 SDL
* Linux * Linux
0.31.04 - 0.31.06 native. There are missing offsets but Map tools should be OK. 0.31.04 - 0.31.08 native.
All Windows versions through wine. 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 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(TARGETS dfhack LIBRARY DESTINATION lib)
install(FILES ${CMAKE_SOURCE_DIR}/output/Memory.xml DESTINATION share/dfhack) install(FILES ${CMAKE_SOURCE_DIR}/output/Memory.xml DESTINATION share/dfhack)
ENDIF(UNIX) 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() DFContextShared::DFContextShared()
{ {
// init modules // init modules
creatures = 0; allModules.clear();
maps = 0; memset(&(s_mods), 0, sizeof(s_mods));
position = 0;
gui = 0;
world = 0;
materials = 0;
translation = 0;
vegetation = 0;
buildings = 0;
constructions = 0;
items = 0;
windowio = 0;
} }
DFContextShared::~DFContextShared() DFContextShared::~DFContextShared()
{ {
if(creatures) delete creatures; // invalidate all modules
if(maps) delete maps; for(int i = 0 ; i < allModules.size(); i++)
if(position) delete position; {
if(gui) delete gui; delete allModules[i];
if(materials) delete materials; }
if(translation) delete translation; allModules.clear();
if(vegetation) delete vegetation;
if(buildings) delete buildings;
if(constructions) delete constructions;
if(world) delete world;
if(windowio) delete windowio;
} }
bool DFContextShared::InitReadNames() bool DFContextShared::InitReadNames()

@ -27,7 +27,6 @@ distribution.
#include "dfhack/DFProcess.h" #include "dfhack/DFProcess.h"
#include "dfhack/DFProcessEnumerator.h" #include "dfhack/DFProcessEnumerator.h"
#include "dfhack/DFContext.h" #include "dfhack/DFContext.h"
#include "dfhack/DFContext.h"
#include "dfhack/DFError.h" #include "dfhack/DFError.h"
#include <shms.h> #include <shms.h>
@ -93,6 +92,13 @@ bool Context::Detach()
} }
d->shm_start = 0; d->shm_start = 0;
// invalidate all modules // 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) if(d->creatures)
{ {
delete d->creatures; delete d->creatures;
@ -147,7 +153,7 @@ bool Context::Detach()
{ {
delete d->translation; delete d->translation;
d->translation = 0; d->translation = 0;
} }*/
return true; return true;
} }
@ -201,13 +207,39 @@ Process * Context::getProcess()
/******************************************************************************* /*******************************************************************************
M O D U L E S 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() Creatures * Context::getCreatures()
{ {
if(!d->creatures) if(!d->creatures)
d->creatures = new Creatures(d); d->creatures = new Creatures(d);
return d->creatures; return d->creatures;
} }
*/
/*
Maps * Context::getMaps() Maps * Context::getMaps()
{ {
if(!d->maps) if(!d->maps)
@ -284,7 +316,7 @@ Constructions * Context::getConstructions()
d->constructions = new Constructions(d); d->constructions = new Constructions(d);
return d->constructions; return d->constructions;
} }
*/
/* /*
// returns number of buildings, expects v_buildingtypes that will later map t_building.type to its name // 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) if(context != NULL)
{ {
return (DFHackObject*)((DFHack::Context*)context)->getWindow(); return (DFHackObject*)((DFHack::Context*)context)->getWindowIO();
} }
return NULL; return NULL;

@ -29,6 +29,7 @@ distribution.
//Inital amount of space in levels vector (since we usually know the number, efficent!) //Inital amount of space in levels vector (since we usually know the number, efficent!)
#define NUM_RESERVE_LVLS 20 #define NUM_RESERVE_LVLS 20
#define NUM_RESERVE_MOODS 6
using namespace DFHack; using namespace DFHack;
/* /*
@ -96,6 +97,7 @@ class memory_info::Private
vector<string> skills; vector<string> skills;
vector<DFHack::t_level> levels; vector<DFHack::t_level> levels;
vector< vector<string> > traits; vector< vector<string> > traits;
vector<string> moods;
map <uint32_t, string> labors; map <uint32_t, string> labors;
// storage for class and multiclass // storage for class and multiclass
@ -124,6 +126,7 @@ memory_info::memory_info()
d->p = 0; d->p = 0;
d->classindex = 0; d->classindex = 0;
d->levels.reserve(NUM_RESERVE_LVLS); d->levels.reserve(NUM_RESERVE_LVLS);
d->moods.reserve(NUM_RESERVE_MOODS);
} }
// copy constructor // copy constructor
@ -151,6 +154,7 @@ memory_info::memory_info(const memory_info &old)
d->traits = old.d->traits; d->traits = old.d->traits;
d->labors = old.d->labors; d->labors = old.d->labors;
d->levels = old.d->levels; d->levels = old.d->levels;
d->moods = old.d->moods;
} }
void memory_info::setParentProcess(Process * _p) 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); 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, void memory_info::setTrait(const string & key,
const string & value, const string & value,
const string & zero, 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 string memory_info::getJob (const uint32_t key) const
{ {
if(d->jobs.size() > key) if(d->jobs.size() > key)
{ {
return d->jobs[key]; return d->jobs[key];
} }
@ -698,6 +713,11 @@ string memory_info::getTraitName(const uint32_t traitIdx) const
throw Error::MissingMemoryDefinition("traitname", traitIdx); 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) string memory_info::getLabor (const uint32_t laborIdx)
{ {
if(d->labors.count(laborIdx)) if(d->labors.count(laborIdx))
@ -707,3 +727,43 @@ string memory_info::getLabor (const uint32_t laborIdx)
throw Error::MissingMemoryDefinition("labor", 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")); mem->setLevel(value, name, pMemEntry->Attribute("xpNxtLvl"));
} }
else if (type == "Mood")
{
mem->setMood(value, name);
}
else else
{ {
throw Error::MemoryXmlUnknownType(type.c_str()); throw Error::MemoryXmlUnknownType(type.c_str());

@ -1,6 +1,16 @@
#ifndef DFHACK_API_H #ifndef DFHACK_API_H
#define 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 // DFHack core classes and types
#include "dfhack/DFIntegers.h" #include "dfhack/DFIntegers.h"
#include "dfhack/DFGlobal.h" #include "dfhack/DFGlobal.h"

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

@ -297,6 +297,16 @@ namespace DFHack
return "SHM ATTACH FAILURE"; 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!";
}
};
} }
} }

@ -66,6 +66,7 @@ namespace DFHack
uint32_t getAddress (const char *); uint32_t getAddress (const char *);
uint32_t getHexValue (const char *); uint32_t getHexValue (const char *);
std::string getMood(const uint32_t moodID);
std::string getString (const std::string&); std::string getString (const std::string&);
std::string getProfession(const uint32_t) const; std::string getProfession(const uint32_t) const;
std::string getJob(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 getTrait (const uint32_t, const uint32_t) const;
std::string getTraitName(const uint32_t) const; std::string getTraitName(const uint32_t) const;
std::string getLabor (const uint32_t); 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 char *);
void setVersion(const std::string&); void setVersion(const std::string&);
@ -103,11 +105,12 @@ namespace DFHack
void setJob(const std::string &, const std::string &); void setJob(const std::string &, const std::string &);
void setSkill(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 &, 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 setLabor(const std::string &, const std::string &);
void setLevel(const std::string &nLevel, const std::string &nName, void setLevel(const std::string &nLevel, const std::string &nName,
const std::string &nXp); const std::string &nXp);
void setMood(const std::string &id, const std::string &mood);
void RebaseVTable(const int32_t offset); void RebaseVTable(const int32_t offset);
void setParentProcess(Process * _p); void setParentProcess(Process * _p);
@ -142,6 +145,11 @@ namespace DFHack
* Get the internal classID->classname mapping (for speed). DO NOT MANIPULATE THE VECTOR! * Get the internal classID->classname mapping (for speed). DO NOT MANIPULATE THE VECTOR!
*/ */
const std::vector<std::string> * getClassIDMapping(); const std::vector<std::string> * getClassIDMapping();
/**
* Get a string with all addresses and offsets
*/
std::string PrintOffsets();
}; };
} }
#endif // MEMINFO_H_INCLUDED #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 struct t_attrib
{ {
uint32_t level; uint32_t level;
uint32_t field_4; uint32_t field_4; // offset from beginning, purpose unknown
uint32_t field_8; uint32_t field_8;
uint32_t field_C; uint32_t field_C;
uint32_t leveldiff; uint32_t leveldiff;

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

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

@ -4,6 +4,7 @@
* Creatures * Creatures
*/ */
#include "dfhack/DFExport.h" #include "dfhack/DFExport.h"
#include "dfhack/DFModule.h"
namespace DFHack namespace DFHack
{ {
/* /*
@ -188,84 +189,84 @@ namespace DFHack
/* /*
struct t_labor struct t_labor
{ {
string name; string name;
uint8_t value; uint8_t value;
t_labor() { t_labor() {
value =0; value =0;
} }
t_labor(const t_labor & b){ t_labor(const t_labor & b){
name=b.name; name=b.name;
value=b.value; value=b.value;
} }
t_labor & operator=(const t_labor &b){ t_labor & operator=(const t_labor &b){
name=b.name; name=b.name;
value=b.value; value=b.value;
return *this; return *this;
} }
}; };
struct t_skill struct t_skill
{ {
string name; string name;
uint16_t id; uint16_t id;
uint32_t experience; uint32_t experience;
uint16_t rating; uint16_t rating;
t_skill(){ t_skill(){
id=rating=0; id=rating=0;
experience=0; experience=0;
} }
t_skill(const t_skill & b) t_skill(const t_skill & b)
{ {
name=b.name; name=b.name;
id=b.id; id=b.id;
experience=b.experience; experience=b.experience;
rating=b.rating; rating=b.rating;
} }
t_skill & operator=(const t_skill &b) t_skill & operator=(const t_skill &b)
{ {
name=b.name; name=b.name;
id=b.id; id=b.id;
experience=b.experience; experience=b.experience;
rating=b.rating; rating=b.rating;
return *this; return *this;
} }
}; };
struct t_trait struct t_trait
{ {
uint16_t value; uint16_t value;
string displayTxt; string displayTxt;
string name; string name;
t_trait(){ t_trait(){
value=0; value=0;
} }
t_trait(const t_trait &b) t_trait(const t_trait &b)
{ {
name=b.name; name=b.name;
displayTxt=b.displayTxt; displayTxt=b.displayTxt;
value=b.value; value=b.value;
} }
t_trait & operator=(const t_trait &b) t_trait & operator=(const t_trait &b)
{ {
name=b.name; name=b.name;
displayTxt=b.displayTxt; displayTxt=b.displayTxt;
value=b.value; value=b.value;
return *this; return *this;
} }
}; };
*/ */
struct t_skill struct t_skill
{ {
uint16_t id; uint32_t id;
uint32_t rating;
uint32_t experience; uint32_t experience;
uint16_t rating;
}; };
struct t_job struct t_job
{ {
bool active; bool active;
uint32_t jobId; uint32_t jobId;
uint8_t jobType; uint8_t jobType;
uint32_t occupationPtr; uint32_t occupationPtr;
}; };
struct t_like struct t_like
{ {
@ -280,6 +281,8 @@ namespace DFHack
// FIXME: define in Memory.xml instead? // FIXME: define in Memory.xml instead?
#define NUM_CREATURE_TRAITS 30 #define NUM_CREATURE_TRAITS 30
#define NUM_CREATURE_LABORS 102 #define NUM_CREATURE_LABORS 102
#define NUM_CREATURE_MENTAL_ATTRIBUTES 13
#define NUM_CREATURE_PHYSICAL_ATTRIBUTES 6
struct t_soul struct t_soul
{ {
@ -305,7 +308,7 @@ namespace DFHack
t_attrib social_awareness; t_attrib social_awareness;
}; };
#define MAX_COLORS 15 #define MAX_COLORS 15
struct t_creature struct t_creature
{ {
@ -355,26 +358,42 @@ namespace DFHack
class DFContextShared; class DFContextShared;
struct t_creature; struct t_creature;
class DFHACK_EXPORT Creatures class DFHACK_EXPORT Creatures : public Module
{ {
public: public:
Creatures(DFHack::DFContextShared * d); Creatures(DFHack::DFContextShared * d);
~Creatures(); ~Creatures();
bool Start( uint32_t & numCreatures); bool Start( uint32_t & numCreatures );
bool Finish(); bool Finish();
/* Read Functions */
// Read creatures in a box, starting with index. Returns -1 if no more creatures // Read creatures in a box, starting with index. Returns -1 if no more creatures
// found. Call repeatedly do get all creatures in a specified box (uses tile coords) // found. Call repeatedly do get all creatures in a specified box (uses tile coords)
int32_t ReadCreatureInBox(const int32_t index, t_creature & furball, 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 x1, const uint16_t y1,const uint16_t z1,
const uint16_t x2, const uint16_t y2,const uint16_t z2); const uint16_t x2, const uint16_t y2,const uint16_t z2);
bool ReadCreature(const int32_t index, t_creature & furball); bool ReadCreature(const int32_t index, t_creature & furball);
/// write labors of a creature (for Dwarf Therapist) bool ReadJob(const t_creature * furball, std::vector<t_material> & mat);
bool WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]);
/* Getters */
uint32_t GetDwarfRaceIndex ( void ); uint32_t GetDwarfRaceIndex ( void );
int32_t GetDwarfCivId ( 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; struct Private;
Private *d; Private *d;
}; };

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

@ -4,89 +4,39 @@
* Creatures * Creatures
*/ */
#include "dfhack/DFExport.h" #include "dfhack/DFExport.h"
#include "dfhack/DFModule.h"
namespace DFHack namespace DFHack
{ {
class Context; class Context;
class DFContextShared; 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 struct t_item
{ {
t_material matdesc; t_material matdesc;
int32_t quantity; int32_t quantity;
int32_t quality; int32_t quality;
}; };
struct t_improvement struct t_improvement
{ {
t_material matdesc; t_material matdesc;
int32_t quality; 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;
}; };
class DFHACK_EXPORT Items class DFHACK_EXPORT Items : public Module
{ {
public: public:
Items(DFContextShared * _d); Items(DFContextShared * _d);
~Items(); ~Items();
std::string getItemDescription(uint32_t itemptr, Materials * Materials); bool Start();
std::string getItemClass(int32_t index); bool Finish();
bool getItemData(uint32_t itemptr, t_item & item); std::string getItemDescription(uint32_t itemptr, Materials * Materials);
std::string getItemClass(int32_t index);
bool getItemData(uint32_t itemptr, t_item & item);
private: private:
class Private; class Private;
Private* d; Private* d;
std::map<int32_t, ItemDesc *> descType;
std::map<uint32_t, ItemDesc *> descVTable;
}; };
} }
#endif #endif

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

@ -1,9 +1,10 @@
#ifndef CL_MOD_MATERIALS #ifndef CL_MOD_MATERIALS
#define CL_MOD_MATERIALS #define CL_MOD_MATERIALS
/* /*
* Creatures * Materials
*/ */
#include "dfhack/DFExport.h" #include "dfhack/DFExport.h"
#include "dfhack/DFModule.h"
namespace DFHack namespace DFHack
{ {
class DFContextShared; class DFContextShared;
@ -116,11 +117,12 @@ namespace DFHack
uint32_t flags; uint32_t flags;
}; };
class DFHACK_EXPORT Materials class DFHACK_EXPORT Materials : public Module
{ {
public: public:
Materials(DFHack::DFContextShared * _d); Materials(DFHack::DFContextShared * _d);
~Materials(); ~Materials();
bool Finish();
std::vector<t_matgloss> inorganic; std::vector<t_matgloss> inorganic;
std::vector<t_matgloss> organic; std::vector<t_matgloss> organic;

@ -4,6 +4,7 @@
* View position and size and cursor position * View position and size and cursor position
*/ */
#include "dfhack/DFExport.h" #include "dfhack/DFExport.h"
#include "dfhack/DFModule.h"
namespace DFHack namespace DFHack
{ {
#define NUM_HOTKEYS 16 #define NUM_HOTKEYS 16
@ -17,12 +18,13 @@ namespace DFHack
}; };
class DFContextShared; class DFContextShared;
class DFHACK_EXPORT Position class DFHACK_EXPORT Position : public Module
{ {
public: public:
Position(DFContextShared * d); Position(DFContextShared * d);
~Position(); ~Position();
bool Finish(){return true;};
/* /*
* Cursor and window coords * Cursor and window coords
*/ */

@ -4,6 +4,7 @@
* DF translation tables and name translation * DF translation tables and name translation
*/ */
#include "dfhack/DFExport.h" #include "dfhack/DFExport.h"
#include "dfhack/DFModule.h"
namespace DFHack namespace DFHack
{ {
class DFContextShared; class DFContextShared;
@ -14,7 +15,7 @@ namespace DFHack
DFDict foreign_languages; DFDict foreign_languages;
} Dicts; } Dicts;
class DFHACK_EXPORT Translation class DFHACK_EXPORT Translation : public Module
{ {
public: public:
Translation(DFContextShared * d); Translation(DFContextShared * d);

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

@ -27,6 +27,7 @@ distribution.
#include "dfhack/DFPragma.h" #include "dfhack/DFPragma.h"
#include "dfhack/DFExport.h" #include "dfhack/DFExport.h"
#include "dfhack/DFModule.h"
namespace DFHack namespace DFHack
{ {
@ -88,12 +89,13 @@ enum t_special
NUM_SPECIALS NUM_SPECIALS
}; };
class DFContextShared; class DFContextShared;
class DFHACK_EXPORT WindowIO class DFHACK_EXPORT WindowIO : public Module
{ {
class Private; class Private;
private: private:
Private * d; Private * d;
public: public:
bool Finish(){return true;};
WindowIO(DFHack::DFContextShared * d); WindowIO(DFHack::DFContextShared * d);
~WindowIO(); ~WindowIO();
void TypeStr (const char *input, int delay = 0, bool useShift = false); 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 * World: all kind of stuff related to the current world state
*/ */
#include "dfhack/DFExport.h" #include "dfhack/DFExport.h"
#include "dfhack/DFModule.h"
namespace DFHack namespace DFHack
{ {
class DFContextShared; class DFContextShared;
class DFHACK_EXPORT World class DFHACK_EXPORT World : public Module
{ {
public: public:

@ -92,7 +92,7 @@ Creatures::Creatures(DFContextShared* _d)
creatures.mood_offset = minfo->getOffset("creature_mood"); creatures.mood_offset = minfo->getOffset("creature_mood");
creatures.mood_skill_offset = minfo->getOffset("creature_mood_skill"); creatures.mood_skill_offset = minfo->getOffset("creature_mood_skill");
creatures.pickup_equipment_bit = minfo->getOffset("creature_pickup_equipment_bit"); 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 // soul offsets
creatures.soul_skills_vector_offset = minfo->getOffset("soul_skills_vector"); creatures.soul_skills_vector_offset = minfo->getOffset("soul_skills_vector");
creatures.soul_mental_offset = minfo->getOffset("soul_mental"); creatures.soul_mental_offset = minfo->getOffset("soul_mental");
@ -195,7 +195,9 @@ bool Creatures::ReadCreature (const int32_t index, t_creature & furball)
p->readDWord (temp + offs.flags2_offset, furball.flags2.whole); p->readDWord (temp + offs.flags2_offset, furball.flags2.whole);
// physical attributes // 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 // mood stuff
furball.mood = (int16_t) p->readWord (temp + offs.mood_offset); furball.mood = (int16_t) p->readWord (temp + offs.mood_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); uint32_t soul = p->readDWord(temp + offs.default_soul_offset);
furball.has_default_soul = false; furball.has_default_soul = false;
if(soul) if(soul)
{ {
furball.has_default_soul = true; furball.has_default_soul = true;
// get first soul's skills // get first soul's skills
DfVector <uint32_t> skills(p, soul + offs.soul_skills_vector_offset); DfVector <uint32_t> skills(p, soul + offs.soul_skills_vector_offset);
furball.defaultSoul.numSkills = skills.size(); furball.defaultSoul.numSkills = skills.size();
for (uint32_t i = 0; i < furball.defaultSoul.numSkills;i++) for (uint32_t i = 0; i < furball.defaultSoul.numSkills;i++)
{ {
uint32_t temp2 = skills[i]; uint32_t temp2 = skills[i];
// a byte: this gives us 256 skills maximum. // a byte: this gives us 256 skills maximum.
furball.defaultSoul.skills[i].id = p->readByte (temp2); furball.defaultSoul.skills[i].id = p->readByte (temp2);
furball.defaultSoul.skills[i].rating = p->readByte (temp2 + 4); furball.defaultSoul.skills[i].rating =
furball.defaultSoul.skills[i].experience = p->readWord (temp2 + 8); 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 // 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 // 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); DfVector <uint32_t> app(p, temp + offs.appearance_vector_offset);
@ -346,11 +357,12 @@ int32_t Creatures::ReadCreatureInBox (int32_t index, t_creature & furball,
} }
} }
bool Creatures::WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]) bool Creatures::WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS])
{ {
if(!d->Started) return false; if(!d->Started)
{
return false;
}
uint32_t temp = d->p_cre->at (index); uint32_t temp = d->p_cre->at (index);
Process * p = d->owner; Process * p = d->owner;
@ -362,6 +374,177 @@ bool Creatures::WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LA
return true; 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() uint32_t Creatures::GetDwarfRaceIndex()
{ {
if(!d->Inited) return 0; if(!d->Inited) return 0;

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

@ -37,7 +37,7 @@ distribution.
#define SHMCMD(num) ((shm_cmd *)d->d->shm_start)[num]->pingpong #define SHMCMD(num) ((shm_cmd *)d->d->shm_start)[num]->pingpong
#define SHMHDR ((shm_core_hdr *)d->d->shm_start) #define SHMHDR ((shm_core_hdr *)d->d->shm_start)
#define SHMDATA(type) ((type *)(d->d->shm_start + SHM_HEADER)) #define SHMDATA(type) ((type *)(d->d->shm_start + SHM_HEADER))
#define MAPS_GUARD if(!d->Started) throw DFHack::Error::ModuleNotInitialized();
using namespace DFHack; using namespace DFHack;
struct Maps::Private struct Maps::Private
@ -90,7 +90,6 @@ Maps::Maps(DFContextShared* _d)
off.region_y_offset = mem->getAddress ("region_y"); off.region_y_offset = mem->getAddress ("region_y");
off.region_z_offset = mem->getAddress ("region_z"); off.region_z_offset = mem->getAddress ("region_z");
off.world_regions = mem->getAddress ("ptr2_region_array"); off.world_regions = mem->getAddress ("ptr2_region_array");
off.region_size = mem->getHexValue ("region_size"); off.region_size = mem->getHexValue ("region_size");
off.region_geo_index_offset = mem->getOffset ("region_geo_index_off"); off.region_geo_index_offset = mem->getOffset ("region_geo_index_off");
@ -101,9 +100,6 @@ Maps::Maps(DFContextShared* _d)
off.world_size_x = mem->getAddress ("world_size_x"); off.world_size_x = mem->getAddress ("world_size_x");
off.world_size_y = mem->getAddress ("world_size_y"); off.world_size_y = mem->getAddress ("world_size_y");
// these can fail and will be found when looking at the actual veins later // these can fail and will be found when looking at the actual veins later
// basically a cache // basically a cache
off.vein_ice_vptr = 0; off.vein_ice_vptr = 0;
@ -140,8 +136,10 @@ bool Maps::Start()
return false; return false;
if(d->Started) if(d->Started)
Finish(); Finish();
Process *p = d->owner; Process *p = d->owner;
Server::Maps::maps_offsets &off = d->offsets; Server::Maps::maps_offsets &off = d->offsets;
// get the map pointer // get the map pointer
uint32_t x_array_loc = p->readDWord (off.map_offset); uint32_t x_array_loc = p->readDWord (off.map_offset);
if (!x_array_loc) if (!x_array_loc)
@ -193,6 +191,7 @@ bool Maps::Start()
// getter for map size // getter for map size
void Maps::getSize (uint32_t& x, uint32_t& y, uint32_t& z) void Maps::getSize (uint32_t& x, uint32_t& y, uint32_t& z)
{ {
MAPS_GUARD
x = d->x_block_count; x = d->x_block_count;
y = d->y_block_count; y = d->y_block_count;
z = d->z_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) 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) if ( x >= d->x_block_count || y >= d->y_block_count || z >= d->z_block_count)
return false; return false;
return d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z] != 0; 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) 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) if ( x >= d->x_block_count || y >= d->y_block_count || z >= d->z_block_count)
return 0; return 0;
return d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; 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) bool Maps::ReadBlock40d(uint32_t x, uint32_t y, uint32_t z, mapblock40d * buffer)
{ {
MAPS_GUARD
Process *p = d->owner; Process *p = d->owner;
if(d->d->shm_start && d->maps_module) // ACCELERATE! if(d->d->shm_start && d->maps_module) // ACCELERATE!
{ {
@ -268,6 +270,7 @@ bool Maps::ReadBlock40d(uint32_t x, uint32_t y, uint32_t z, mapblock40d * buffer
bool Maps::ReadTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buffer) 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]; uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr) 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) 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]; uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr) 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) 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]; uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if(addr) 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) 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]; uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr) if (addr)
{ {
@ -321,9 +327,12 @@ bool Maps::WriteDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool dirtybit)
return false; return false;
} }
/// read/write the block flags /*
* Block flags
*/
bool Maps::ReadBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags &blockflags) 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]; uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if(addr) 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) 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]; uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr) if (addr)
{ {
@ -350,9 +360,9 @@ bool Maps::WriteBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags bloc
/* /*
* Designations * Designations
*/ */
bool Maps::ReadDesignations (uint32_t x, uint32_t y, uint32_t z, designations40d *buffer) 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]; uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr) 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) 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]; uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr) if (addr)
{ {
@ -376,9 +387,9 @@ bool Maps::WriteDesignations (uint32_t x, uint32_t y, uint32_t z, designations40
/* /*
* Occupancies * Occupancies
*/ */
bool Maps::ReadOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *buffer) 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]; uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr) 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) 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]; uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr) if (addr)
{ {
@ -404,6 +416,7 @@ bool Maps::WriteOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *b
*/ */
bool Maps::ReadTemperatures(uint32_t x, uint32_t y, uint32_t z, t_temperatures *temp1, t_temperatures *temp2) 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]; uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr) 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) 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]; uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr) 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) 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]; uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr) 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) 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]; uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr) 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) 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]; uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr) 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) 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]; uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr) 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) 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_vein v;
t_frozenliquidvein fv; t_frozenliquidvein fv;
t_spattervein sv; 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) bool Maps::ReadGeology (vector < vector <uint16_t> >& assign)
{ {
MAPS_GUARD
memory_info * minfo = d->d->offset_descriptor; memory_info * minfo = d->d->offset_descriptor;
Process *p = d->owner; Process *p = d->owner;
// get needed addresses and offsets. Now this is what I call crazy. // get needed addresses and offsets. Now this is what I call crazy.
@ -694,6 +714,7 @@ bool Maps::ReadGeology (vector < vector <uint16_t> >& assign)
bool Maps::ReadLocalFeatures( std::map <planecoord, std::vector<t_feature *> > & local_features ) bool Maps::ReadLocalFeatures( std::map <planecoord, std::vector<t_feature *> > & local_features )
{ {
MAPS_GUARD
// can't be used without a map! // can't be used without a map!
if(!d->block) if(!d->block)
return false; return false;
@ -715,26 +736,20 @@ bool Maps::ReadLocalFeatures( std::map <planecoord, std::vector<t_feature *> > &
for(uint32_t blockX = 0; blockX < d->x_block_count; blockX ++) for(uint32_t blockX = 0; blockX < d->x_block_count; blockX ++)
for(uint32_t blockY = 0; blockY < d->x_block_count; blockY ++) for(uint32_t blockY = 0; blockY < d->x_block_count; blockY ++)
{ {
//uint64_t block48_x = blockX / 3 + d->regionX; // region X coord (48x48 tiles)
//uint16_t region_x_plus8 = ( block48_x + 8 ) / 16; uint16_t region_x_local = ( (blockX / 3) + d->regionX ) / 16;
// region Y coord (48x48 tiles)
// 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
uint64_t region_y_local = ( (blockY / 3) + d->regionY ) / 16; uint64_t region_y_local = ( (blockY / 3) + d->regionY ) / 16;
// this is just a few pointers to arrays of 16B (4 DWORD) structs // 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 // 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); uint32_t wtf = p->readDWord(array_elem + ( sizeof_elem * ( (uint32_t)region_y_local/16)) + offset_elem);
if(wtf) if(wtf)
{ {
// wtf + sizeof(vector<ptr>) * crap; // 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); DfVector<uint32_t> p_features(p, feat_vector);
uint32_t size = p_features.size(); uint32_t size = p_features.size();
planecoord pc; planecoord pc;
@ -792,6 +807,7 @@ bool Maps::ReadLocalFeatures( std::map <planecoord, std::vector<t_feature *> > &
bool Maps::ReadGlobalFeatures( std::vector <t_feature> & features) bool Maps::ReadGlobalFeatures( std::vector <t_feature> & features)
{ {
MAPS_GUARD
// can't be used without a map! // can't be used without a map!
if(!d->block) if(!d->block)
return false; return false;

@ -53,6 +53,21 @@ Materials::~Materials()
{ {
delete d; 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: LABEL_53:
@ -301,8 +316,8 @@ bool Materials::ReadCreatureTypesEx (void)
uint32_t bodypart_id_offset = mem->getOffset ("bodypart_id"); uint32_t bodypart_id_offset = mem->getOffset ("bodypart_id");
uint32_t bodypart_category_offset = mem->getOffset ("bodypart_category"); uint32_t bodypart_category_offset = mem->getOffset ("bodypart_category");
uint32_t bodypart_layers_offset = mem->getOffset ("bodypart_layers_vector"); uint32_t bodypart_layers_offset = mem->getOffset ("bodypart_layers_vector");
uint32_t bodypart_singular_offset = mem->getOffset ("bodypart_singular_vector"); uint32_t bodypart_singular_offset = mem->getOffset ("bodypart_singular_vector"); // unused
uint32_t bodypart_plural_offset = mem->getOffset ("bodypart_plural_vector"); 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_part_offset = mem->getOffset ("color_modifier_part");
uint32_t color_modifier_startdate_offset = mem->getOffset ("color_modifier_startdate"); uint32_t color_modifier_startdate_offset = mem->getOffset ("color_modifier_startdate");
uint32_t color_modifier_enddate_offset = mem->getOffset ("color_modifier_enddate"); 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++) for (uint32_t i = 0; i < size;i++)
{ {
t_creaturetype mat; 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)); 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); DfVector <uint32_t> p_castes(p, p_races[i] + castes_vector_offset);
sizecas = p_castes.size(); sizecas = p_castes.size();
for (uint32_t j = 0; j < sizecas;j++) for (uint32_t j = 0; j < sizecas;j++)
@ -364,11 +390,6 @@ bool Materials::ReadCreatureTypesEx (void)
mat.castes.push_back(caste); 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); DfVector <uint32_t> p_extract(p, p_races[i] + extract_vector_offset);
for(uint32_t j = 0; j < p_extract.size(); j++) 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 Materials::getDescription(t_material & mat)
{ {
std::string out; std::string out;
int32_t typeC; int32_t typeC;
if ( (mat.subIndex<419) || (mat.subIndex>618) ) if ( (mat.subIndex<419) || (mat.subIndex>618) )
{ {
if ( (mat.subIndex<19) || (mat.subIndex>218) ) if ( (mat.subIndex<19) || (mat.subIndex>218) )
{ {
@ -408,13 +429,13 @@ std::string Materials::getDescription(t_material & mat)
else else
{ {
if (mat.subIndex>=this->other.size()) if (mat.subIndex>=this->other.size())
{ {
if(mat.subIndex<0) if(mat.subIndex<0)
return "any"; return "any";
if(mat.subIndex>=this->raceEx.size()) if(mat.subIndex>=this->raceEx.size())
return "stuff"; return "stuff";
return this->raceEx[mat.subIndex].rawname; return this->raceEx[mat.subIndex].rawname;
} }
else else
{ {
if (mat.index==-1) if (mat.index==-1)
@ -424,17 +445,17 @@ std::string Materials::getDescription(t_material & mat)
} }
} }
else else
if(mat.index<0) if(mat.index<0)
return "any inorganic"; return "any inorganic";
else else
return this->inorganic[mat.index].id; return this->inorganic[mat.index].id;
} }
else else
{ {
if (mat.index>=this->raceEx.size()) if (mat.index>=this->raceEx.size())
return "unknown race"; return "unknown race";
typeC = mat.subIndex; typeC = mat.subIndex;
typeC -=19; typeC -=19;
if ((typeC<0) || (typeC>=this->raceEx[mat.index].extract.size())) if ((typeC<0) || (typeC>=this->raceEx[mat.index].extract.size()))
{ {
return string(this->raceEx[mat.index].rawname).append(" extract"); 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 this->organic[mat.index].id;
} }
return out; return out;
} }

@ -31,20 +31,23 @@ distribution.
namespace DFHack namespace DFHack
{ {
class Materials; class Module;
class Creatures;
class Maps;
class Position;
class Gui; class Gui;
class World; class World;
class Position; class Materials;
class Maps;
class Creatures;
class Items; class Items;
class Translation; class Translation;
class Vegetation;
class Buildings; class Buildings;
class Constructions;
class WindowIO;
class ProcessEnumerator; class ProcessEnumerator;
class Process; class Process;
class WindowIO;
class Vegetation;
class Constructions;
class memory_info; class memory_info;
struct t_name; struct t_name;
class DFContextShared class DFContextShared
@ -69,19 +72,22 @@ namespace DFHack
string xml; string xml;
// Modules // Modules
Creatures * creatures; struct
Maps * maps; {
Position * position; Creatures * pCreatures;
Gui * gui; Maps * pMaps;
World * world; Position * pPosition;
Materials * materials; Gui * pGui;
Items * items; World * pWorld;
Translation * translation; Materials * pMaterials;
Vegetation * vegetation; Items * pItems;
Buildings * buildings; Translation * pTranslation;
Constructions * constructions; Vegetation * pVegetation;
WindowIO * windowio; Buildings * pBuildings;
Constructions * pConstructions;
WindowIO * pWindowIO;
} s_mods;
std::vector <Module *> allModules;
/* /*
uint32_t item_material_offset; uint32_t item_material_offset;

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

@ -219,6 +219,16 @@
level_1="Acts impulsively" level_1="Acts impulsively"
level_0="Always acts without considering alternatives or thinking through possibilities">29</Trait> 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 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_mood">0x288</Offset>
<Offset name="creature_birth_year">0x298</Offset> <Offset name="creature_birth_year">0x298</Offset>
<Offset name="creature_birth_time">0x29C</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_physical">0x464</Offset>
<!-- <!--
<Offset name="creature_strength">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_recuperation">0x4D4</Offset>
<Offset name="creature_disease_resistance">0x4F0</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_appearance_vector">0x604</Offset>
<Offset name="creature_artifact_name">0x6D4</Offset> <Offset name="creature_artifact_name">0x6D4</Offset>
<Offset name="creature_labors">0x774</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"> <Entry version="v0.31.05" os="windows" id="0.31.05" base="0.31.04" rebase="0x8010">
<String name="md5">394ff63fc00fedd5df0b36e4beb589bc</String> <String name="md5">394ff63fc00fedd5df0b36e4beb589bc</String>
<HexValue name="pe_timestamp">0x4c091569</HexValue> <HexValue name="pe_timestamp">0x4c091569</HexValue>
<!--<Address name="creature_vector">0x1678704</Address> CHMOD-->
<Address name="dwarf_race_index">0x014abee4</Address> CHMOD <Address name="dwarf_race_index">0x014abee4</Address> CHMOD
<Address name="dwarf_civ_id">0x1471FB0</Address> BOGUS! <Address name="dwarf_civ_id">0x1471FB0</Address> BOGUS!
<Address name="window_dims">0x180b10c</Address> LOOKS O.K. <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="cursor_xyz">0xaf12cc</Address> VERIFIED
<Address name="current_tick">0xE80780</Address> LOOKS O.K. <Address name="current_tick">0xE80780</Address> LOOKS O.K.
<Address name="current_year">0xEB2878</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 ??? <Offset name="item_type_accessor">0x0</Offset> Why do i have to redefine this ???
... what? ... what?
</Entry> </Entry>
@ -1687,11 +1654,31 @@ map_data_1b60_offset 0x1B9c
<String name="md5">c4b7e37dafa2716e31d29110968ac64e</String> <String name="md5">c4b7e37dafa2716e31d29110968ac64e</String>
<HexValue name="pe_timestamp">0x4c0f83d5</HexValue> <HexValue name="pe_timestamp">0x4c0f83d5</HexValue>
<Address name="cursor_xyz">0xaf12d0</Address> <Address name="cursor_xyz">0xaf12d0</Address>
[addresses] </Entry>
translation_vector = 0x016c53dc <Entry version="v0.31.07" os="windows" id="0.31.07" base="0.31.06" rebase="0x2000">
language_vector = 0x016c53ac <String name="md5">1c0b5254af1b8ff9a34b51c3f6609da3</String>
creature_vector = 0x0168071c <HexValue name="pe_timestamp">0x4c1cbe4b</HexValue>
dwarf_race_index = 0x014abef4 <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> </Entry>
.-"""-. .-"""-.
@ -1831,9 +1818,23 @@ dwarf_race_index = 0x014abef4
Creature type offsets Creature type offsets
===================== =====================
<Offset name="creature_type_caste_vector">0x60</Offset> VERIFIED <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_type_extract_vector">0x1A14</Offset>
<Offset name="creature_tile">0xE0</Offset> <Offset name="creature_tile">0xE0</Offset>
<Offset name="creature_tile_color">0xF6</Offset> <Offset name="creature_tile_color">0xF6</Offset>
-->
<!-- <!--
struct CreatureType struct CreatureType
{ {
@ -2153,10 +2154,37 @@ dwarf_race_index = 0x014abef4
<Address name="language_vector">0x931aff4</Address> <Address name="language_vector">0x931aff4</Address>
WORLD + 0x54E80 WORLD + 0x54E80
<Address name="translation_vector">0x931b00c</Address> <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>
<Entry version="v0.31.06" os="linux" id="30_06lin" base="30_05lin" rebase="-0x20E0"> <Entry version="v0.31.06" os="linux" id="30_06lin" base="30_05lin" rebase="-0x20E0">
<String name="md5">13a1c19e8f59b74e307e094e2a0f28c3</String> <String name="md5">13a1c19e8f59b74e307e094e2a0f28c3</String>
<Address name="cursor_xyz">0x8b0b328</Address> VERIFIED <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> </Entry>
</MemoryDescriptors> </MemoryDescriptors>
</DFExtractor> </DFExtractor>

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

@ -13,6 +13,10 @@ TARGET_LINK_LIBRARIES(dfmoodump dfhack)
ADD_EXECUTABLE(dftest test.cpp) ADD_EXECUTABLE(dftest test.cpp)
TARGET_LINK_LIBRARIES(dftest dfhack) 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 # bauxite - turn all mechanisms into bauxite mechanisms
# Author: Alex Legg # Author: Alex Legg
#ADD_EXECUTABLE(dfbauxite dfbauxite.cpp) #ADD_EXECUTABLE(dfbauxite dfbauxite.cpp)

@ -17,31 +17,45 @@ class SegmentFinder
{ {
delete mr_.buffer; delete mr_.buffer;
} }
template <class needleType, class hayType, typename comparator > 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 if( oper(_SF,(hayType *)(mr_.buffer + offset), needle) )
for(uint64_t offset = 0; offset < (mr_.end - mr_.start) - sizeof(hayType); offset += increment) 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) )
uint64_t corrected = found[i] - mr_.start; newfound.push_back(found[i]);
if( oper(_SF,(hayType *)(mr_.buffer + corrected), needle) )
newfound.push_back(found[i]);
}
} }
} }
return true; return !newfound.empty();
} }
private: private:
friend class SegmentedFinder; friend class SegmentedFinder;
@ -81,16 +95,52 @@ class SegmentedFinder
} }
template <class needleType, class hayType, typename comparator > template <class needleType, class hayType, typename comparator >
bool Find (const needleType needle, const uint8_t increment, vector <uint64_t> &found, comparator oper) 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; vector <uint64_t> newfound;
for(int i = 0; i < segments.size(); i++) 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.clear();
found = newfound; found = newfound;
return !(found.empty()); 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> template <typename T>
T * Translate(uint64_t address) T * Translate(uint64_t address)
{ {
@ -103,11 +153,13 @@ class SegmentedFinder
} }
return 0; return 0;
} }
template <typename T> template <typename T>
T Read(uint64_t address) T Read(uint64_t address)
{ {
return *Translate<T>(address); return *Translate<T>(address);
} }
template <typename T> template <typename T>
bool Read(uint64_t address, T& target) bool Read(uint64_t address, T& target)
{ {
@ -234,6 +286,19 @@ bool vectorAll (SegmentedFinder* s, vecTriplet *x, int )
return false; 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 ) bool findString (SegmentedFinder* s, uint32_t *addr, const char * compare )
{ {
// read string pointer, translate to local scheme // 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 <DFHack.h>
#include "SegmentedFinder.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) 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) else if(p->getDescriptor()->getOS() == DFHack::memory_info::OS_LINUX)
{ {
start = min(11, (int)ranges.size()); start = min(2, (int)ranges.size());
end = min(14, (int)ranges.size()); end = min(4, (int)ranges.size());
} }
else else
{ {
@ -258,13 +367,13 @@ void FindIntegers(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& r
switch(size) switch(size)
{ {
case 1: 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; break;
case 2: 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; break;
case 4: 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; break;
} }
DF->Detach(); DF->Detach();
@ -288,8 +397,8 @@ void FindVectorByLength(DFHack::ContextManager & DFMgr, vector <DFHack::t_memran
DFHack::Context * DF = DFMgr.getSingleContext(); DFHack::Context * DF = DFMgr.getSingleContext();
DF->Attach(); DF->Attach();
SegmentedFinder sf(ranges,DF); SegmentedFinder sf(ranges,DF);
sf.Find<int ,vecTriplet>(0,4,found,vectorAll); sf.Incremental<int ,vecTriplet>(0,4,found,vectorAll);
sf.Find<uint32_t,vecTriplet>(length * element_size,4,found,vectorLength<uint32_t>); sf.Filter<uint32_t,vecTriplet>(length * element_size,found,vectorLength<uint32_t>);
DF->Detach(); DF->Detach();
} }
} }
@ -300,14 +409,12 @@ void FindVectorByObjectRawname(DFHack::ContextManager & DFMgr, vector <DFHack::t
string select; string select;
while (Incremental(found, "raw name",select,"vector","vectors")) while (Incremental(found, "raw name",select,"vector","vectors"))
{ {
// clear the list of found addresses -- this is a one-shot
found.clear();
DFMgr.Refresh(); DFMgr.Refresh();
DFHack::Context * DF = DFMgr.getSingleContext(); DFHack::Context * DF = DFMgr.getSingleContext();
DF->Attach(); DF->Attach();
SegmentedFinder sf(ranges,DF); SegmentedFinder sf(ranges,DF);
sf.Find<int ,vecTriplet>(0,4,found, vectorAll); 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(); DF->Detach();
} }
} }
@ -318,14 +425,12 @@ void FindVectorByFirstObjectRawname(DFHack::ContextManager & DFMgr, vector <DFHa
string select; string select;
while (Incremental(found, "raw name",select,"vector","vectors")) while (Incremental(found, "raw name",select,"vector","vectors"))
{ {
// clear the list of found addresses -- this is a one-shot
found.clear();
DFMgr.Refresh(); DFMgr.Refresh();
DFHack::Context * DF = DFMgr.getSingleContext(); DFHack::Context * DF = DFMgr.getSingleContext();
DF->Attach(); DF->Attach();
SegmentedFinder sf(ranges,DF); SegmentedFinder sf(ranges,DF);
sf.Find<int ,vecTriplet>(0,4,found, vectorAll); 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(); DF->Detach();
} }
} }
@ -348,14 +453,12 @@ void FindVectorByBounds(DFHack::ContextManager & DFMgr, vector <DFHack::t_memran
uint32_t select; uint32_t select;
while (Incremental(found, "address between vector.start and vector.end",select,"vector","vectors")) 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(); DFMgr.Refresh();
DFHack::Context * DF = DFMgr.getSingleContext(); DFHack::Context * DF = DFMgr.getSingleContext();
DF->Attach(); DF->Attach();
SegmentedFinder sf(ranges,DF); SegmentedFinder sf(ranges,DF);
sf.Find<int ,vecTriplet>(0,4,found, vectorAll); 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 // sort by size of vector
std::sort(found.begin(), found.end(), VectorSizeFunctor(sf)); std::sort(found.begin(), found.end(), VectorSizeFunctor(sf));
DF->Detach(); DF->Detach();
@ -368,14 +471,12 @@ void FindPtrVectorsByObjectAddress(DFHack::ContextManager & DFMgr, vector <DFHac
uint32_t select; uint32_t select;
while (Incremental(found, "object address",select,"vector","vectors")) while (Incremental(found, "object address",select,"vector","vectors"))
{ {
// clear the list of found addresses -- this is a one-shot
found.clear();
DFMgr.Refresh(); DFMgr.Refresh();
DFHack::Context * DF = DFMgr.getSingleContext(); DFHack::Context * DF = DFMgr.getSingleContext();
DF->Attach(); DF->Attach();
SegmentedFinder sf(ranges,DF); SegmentedFinder sf(ranges,DF);
sf.Find<int ,vecTriplet>(0,4,found, vectorAll); 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(); DF->Detach();
} }
} }
@ -391,7 +492,7 @@ void FindStrings(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& ra
DFHack::Context * DF = DFMgr.getSingleContext(); DFHack::Context * DF = DFMgr.getSingleContext();
DF->Attach(); DF->Attach();
SegmentedFinder sf(ranges,DF); 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(); 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) 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) // find lang vector (neutral word table)
to_filter = filtVectors; 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]; uint64_t lang_addr = to_filter[0];
// find dwarven language word table // find dwarven language word table
to_filter = filtVectors; 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]; kulet_vector = to_filter[0];
// find vector of languages // find vector of languages
to_filter = filtVectors; to_filter = filtVectors;
sf.Find<const char * ,vecTriplet>("DWARF",4,to_filter, vectorStringFirst); sf.Filter<const char * ,vecTriplet>("DWARF",to_filter, vectorStringFirst);
// verify // verify
for(int i = 0; i < to_filter.size(); i++) 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 // inorganics vector
to_filter = filtVectors; to_filter = filtVectors;
//sf.Find<uint32_t,vecTriplet>(257 * 4,4,to_filter,vectorLength<uint32_t>); //sf.Find<uint32_t,vecTriplet>(257 * 4,4,to_filter,vectorLength<uint32_t>);
sf.Find<const char * ,vecTriplet>("IRON",4,to_filter, vectorString); sf.Filter<const char * ,vecTriplet>("IRON",to_filter, vectorString);
sf.Find<const char * ,vecTriplet>("ONYX",4,to_filter, vectorString); sf.Filter<const char * ,vecTriplet>("ONYX",to_filter, vectorString);
sf.Find<const char * ,vecTriplet>("RAW_ADAMANTINE",4,to_filter, vectorString); sf.Filter<const char * ,vecTriplet>("RAW_ADAMANTINE",to_filter, vectorString);
sf.Find<const char * ,vecTriplet>("BLOODSTONE",4,to_filter, vectorString); sf.Filter<const char * ,vecTriplet>("BLOODSTONE",to_filter, vectorString);
printFound(to_filter,"inorganics"); printFound(to_filter,"inorganics");
// organics vector // organics vector
to_filter = filtVectors; to_filter = filtVectors;
sf.Find<uint32_t,vecTriplet>(52 * 4,4,to_filter,vectorLength<uint32_t>); sf.Filter<uint32_t,vecTriplet>(52 * 4,to_filter,vectorLength<uint32_t>);
sf.Find<const char * ,vecTriplet>("MUSHROOM_HELMET_PLUMP",4,to_filter, vectorStringFirst); sf.Filter<const char * ,vecTriplet>("MUSHROOM_HELMET_PLUMP",to_filter, vectorStringFirst);
printFound(to_filter,"organics"); printFound(to_filter,"organics");
// tree vector // tree vector
to_filter = filtVectors; to_filter = filtVectors;
sf.Find<uint32_t,vecTriplet>(31 * 4,4,to_filter,vectorLength<uint32_t>); sf.Filter<uint32_t,vecTriplet>(31 * 4,to_filter,vectorLength<uint32_t>);
sf.Find<const char * ,vecTriplet>("MANGROVE",4,to_filter, vectorStringFirst); sf.Filter<const char * ,vecTriplet>("MANGROVE",to_filter, vectorStringFirst);
printFound(to_filter,"trees"); printFound(to_filter,"trees");
// plant vector // plant vector
to_filter = filtVectors; to_filter = filtVectors;
sf.Find<uint32_t,vecTriplet>(21 * 4,4,to_filter,vectorLength<uint32_t>); sf.Filter<uint32_t,vecTriplet>(21 * 4,to_filter,vectorLength<uint32_t>);
sf.Find<const char * ,vecTriplet>("MUSHROOM_HELMET_PLUMP",4,to_filter, vectorStringFirst); sf.Filter<const char * ,vecTriplet>("MUSHROOM_HELMET_PLUMP",to_filter, vectorStringFirst);
printFound(to_filter,"plants"); printFound(to_filter,"plants");
// color descriptors // color descriptors
//AMBER, 112 //AMBER, 112
to_filter = filtVectors; to_filter = filtVectors;
sf.Find<uint32_t,vecTriplet>(112 * 4,4,to_filter,vectorLength<uint32_t>); sf.Filter<uint32_t,vecTriplet>(112 * 4,to_filter,vectorLength<uint32_t>);
sf.Find<const char * ,vecTriplet>("AMBER",4,to_filter, vectorStringFirst); sf.Filter<const char * ,vecTriplet>("AMBER",to_filter, vectorStringFirst);
printFound(to_filter,"color descriptors"); printFound(to_filter,"color descriptors");
if(!to_filter.empty()) if(!to_filter.empty())
{ {
@ -567,28 +677,98 @@ void automatedLangtables(DFHack::Context * DF, vector <DFHack::t_memrange>& rang
// all descriptors // all descriptors
//AMBER, 338 //AMBER, 338
to_filter = filtVectors; to_filter = filtVectors;
sf.Find<uint32_t,vecTriplet>(338 * 4,4,to_filter,vectorLength<uint32_t>); sf.Filter<uint32_t,vecTriplet>(338 * 4,to_filter,vectorLength<uint32_t>);
sf.Find<const char * ,vecTriplet>("AMBER",4,to_filter, vectorStringFirst); sf.Filter<const char * ,vecTriplet>("AMBER",to_filter, vectorStringFirst);
printFound(to_filter,"all descriptors"); printFound(to_filter,"all descriptors");
// creature type // creature type
//ELEPHANT, ?? (demons abound) //ELEPHANT, ?? (demons abound)
to_filter = filtVectors; to_filter = filtVectors;
//sf.Find<uint32_t,vecTriplet>(338 * 4,4,to_filter,vectorLength<uint32_t>); //sf.Find<uint32_t,vecTriplet>(338 * 4,4,to_filter,vectorLength<uint32_t>);
sf.Find<const char * ,vecTriplet>("ELEPHANT",4,to_filter, vectorString); sf.Filter<const char * ,vecTriplet>("ELEPHANT",to_filter, vectorString);
sf.Find<const char * ,vecTriplet>("CAT",4,to_filter, vectorString); sf.Filter<const char * ,vecTriplet>("CAT",to_filter, vectorString);
sf.Find<const char * ,vecTriplet>("DWARF",4,to_filter, vectorString); sf.Filter<const char * ,vecTriplet>("DWARF",to_filter, vectorString);
sf.Find<const char * ,vecTriplet>("WAMBLER_FLUFFY",4,to_filter, vectorString); sf.Filter<const char * ,vecTriplet>("WAMBLER_FLUFFY",to_filter, vectorString);
sf.Find<const char * ,vecTriplet>("TOAD",4,to_filter, vectorString); sf.Filter<const char * ,vecTriplet>("TOAD",to_filter, vectorString);
sf.Find<const char * ,vecTriplet>("DEMON_1",4,to_filter, vectorString); sf.Filter<const char * ,vecTriplet>("DEMON_1",to_filter, vectorString);
vector <uint64_t> toad_first = to_filter; vector <uint64_t> toad_first = to_filter;
vector <uint64_t> elephant_first = to_filter; vector <uint64_t> elephant_first = to_filter;
sf.Find<const char * ,vecTriplet>("TOAD",4,toad_first, vectorStringFirst); sf.Filter<const char * ,vecTriplet>("TOAD",toad_first, vectorStringFirst);
sf.Find<const char * ,vecTriplet>("ELEPHANT",4,elephant_first, vectorStringFirst); sf.Filter<const char * ,vecTriplet>("ELEPHANT",elephant_first, vectorStringFirst);
printFoundStrVec(toad_first,"toad-first creature types",sf); printFoundStrVec(toad_first,"toad-first creature types",sf);
printFound(elephant_first,"elephant-first creature types"); printFound(elephant_first,"elephant-first creature types");
printFound(to_filter,"all 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) 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=DFMgr.getSingleContext();
DF->Attach(); DF->Attach();
Maps = DF->getMaps(); Maps = DF->getMaps();
Maps->Start();
Maps->getSize(x_max,y_max,z_max);
Position = DF->getPosition(); Position = DF->getPosition();
} }
catch (exception& e) catch (exception& e)
@ -44,7 +46,6 @@ int main (void)
int amount = 7; int amount = 7;
while(!end) while(!end)
{ {
Maps->getSize(x_max,y_max,z_max);
DF->Resume(); DF->Resume();
string command = ""; string command = "";
cout <<"[" << mode << ":" << amount << ":" << flowmode << "]# "; cout <<"[" << mode << ":" << amount << ":" << flowmode << "]# ";
@ -71,7 +72,6 @@ int main (void)
<< endl << endl
<< "Usage: point the DF cursor at a tile you want to modify" << endl << "Usage: point the DF cursor at a tile you want to modify" << endl
<< "and use the commands available :)" << endl; << "and use the commands available :)" << endl;
} }
else if(command == "m") else if(command == "m")
{ {

@ -13,11 +13,32 @@
#include <vector> #include <vector>
#include <map> #include <map>
#include <stdio.h> #include <stdio.h>
#include <algorithm>
using namespace std; using namespace std;
#include <DFHack.h> #include <DFHack.h>
#include <dfhack/DFTileTypes.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[]) 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 << "Number of overflows: " << num_overflows;
} }
cout << endl; cout << endl;
vector <pair <int16_t, uint32_t> > matss;
map<int16_t, uint32_t>::iterator p; map<int16_t, uint32_t>::iterator p;
for(p = materials.begin(); p != materials.end(); p++) for(p = materials.begin(); p != materials.end(); p++)
{ {
@ -286,9 +307,14 @@ int main (int argc, const char* argv[])
} }
else 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(); DF->Detach();
#ifndef LINUX_BUILD #ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl; cout << "Done. Press any key to continue" << endl;