Merge remote branch 'upstream/master'

develop
doomchild 2011-03-14 09:54:19 -05:00
commit d347713860
25 changed files with 1175 additions and 869 deletions

@ -2,7 +2,7 @@
PROJECT (dfhack)
cmake_minimum_required(VERSION 2.6)
SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMake/Modules)
SET ( DFHACK_VERSION "0.5.2" )
SET ( DFHACK_VERSION "0.5.5" )
# Set this to project source dir. When dfhack is used
# as a submodule, CMAKE_SOURCE_DIR is not pointing to
@ -25,6 +25,7 @@ ENDIF(NOT DEFINED CMAKE_BUILD_TYPE)
SET( LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/output CACHE PATH "Output directory for the dfhack library" )
SET( EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/output CACHE PATH "Output directory for the dfhack tools" )
SET( DATA_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/output CACHE PATH "Output directory for the dfhack data (offset files)" )
SET( DOXYGEN_OUTPUT_DIR ${CMAKE_SOURCE_DIR}/output/doxygen CACHE PATH "Output directory for doxygen")
OPTION(BUILD_DFHACK_DOCUMENTATION "Create doxygen documentation for developers" OFF)
OPTION(BUILD_DFHACK_EXAMPLES "Build example tools" OFF)

@ -26,6 +26,16 @@ is simple. Enter the build folder, run the tools. Like this::
make
This will build the library and its tools and place them in ``/output``.
Alternatively, you can use ccmake instead of cmake:
cd build
ccmake ..
make
This will show a curses-based interface that lets you set all of the
extra options.
You can also use a cmake-friendly IDE like KDevelop 4 or the cmake GUI
program.
@ -133,3 +143,124 @@ Valid an useful build types include 'Release', 'Debug' and
'RelWithDebInfo'. There are others, but they aren't really that useful.
Have fun.
================================
Using the library as a developer
================================
DFHack is using the zlib/libpng license. This makes it easy to link to
it, use it in-source or add your own extensions. Contributing back to
the dfhack repository is welcome and the right thing to do :)
Rudimentary API documentation can be built using doxygen.
Contributing to DFHack
======================
Several things should be kept in mind when contributing to DFHack.
------------
Coding style
------------
DFhack uses ANSI formatting and four spaces as indentation. Line
endings are UNIX. The files use UTF-8 encoding. Code not following this
won't make me happy, because I'll have to fix it. There's a good chance
I'll make *you* fix it ;)
-------------------------------
How to get new code into DFHack
-------------------------------
You can send patches or make a clone of the github repo and ask me on
the IRC channel to pull your code in. I'll review it and see if there
are any problems. I'll fix them if they are minor.
Fixes are higher in priority. If you want to work on something, but
don't know what, check out http://github.com/peterix/dfhack/issues --
this is also a good place to dump new ideas and/or bugs that need
fixing.
----------------
Layout for tools
----------------
Tools live in the tools/ folder. There, they are split into three
categories.
distributed
these tools get distributed with binary releases and are installed
by doing 'make install' on linux. They are supposed to be stable
and supported. Experimental, useless, buggy or untested stuff
doesn't belong here.
examples
examples are tools that aren't very useful, but show how DF and
DFHack work. They should use only DFHack API functions. No actual
hacking or 'magic offsets' are allowed.
playground
This is a catch-all folder for tools that aren't ready to be
examples or be distributed in binary releases. All new tools should
start here. They can contain actual hacking, magic values and other
nasty business.
------------------------
Modules - what are they?
------------------------
DFHack uses modules to partition sets of features into manageable
chunks. A module can have both client and server side.
Client side is the part that goes into the main library and is
generally written in C++. It is exposed to the users of DFHack.
Server side is used inside DF and serves to accelerate the client
modules. This is written mostly in C style.
There's a Core module that shouldn't be changed, because it defines the
basic commands like reading and writing raw data. The client parts for
the Core module are the various implementations of the Process
interface.
A good example of a module is Maps. Named the same in both client and
server, it allows accelerating the reading of map blocks.
Communication between modules happens by using shared memory. This is
pretty fast, but needs quite a bit of care to not break.
------------
Dependencies
------------
Internal
either part of the codebase or statically linked.
External
linked as dynamic loaded libraries (.dll, .so, etc.)
If you want to add dependencies, think twice about it. All internal
dependencies for core dfhack should be either public domain or require
attribution at most. External dependencies for tools can be either
that, or any Free Software licenses.
Current internal dependencies
-----------------------------
tinyxml
used by core dfhack to read offset definitions from Memory.xml
md5
an implementation of the MD5 hash algorithm. Used for identifying
DF binaries on Linux.
argstream
Allows reading terminal application arguments. GPL!
Current external dependencies
-----------------------------
wide-character ncurses
used for the veinlook tool on Linux.
x11 libraries
used for sending key events on linux
Build-time dependencies
-----------------------
cmake
you need cmake to generate the build system and some configuration
headers
=========================
Memory offset definitions
=========================
The files with memory offset definitions used by dfhack can be found in the
data folder.

@ -312,28 +312,49 @@ ul.auto-toc {
<body>
<div class="document" id="compiling-dfhack">
<h1 class="title">Compiling DFHACK</h1>
<h2 class="subtitle" id="here-s-how-you-build-dfhack">Here's how you build dfhack!</h2>
<div class="section" id="here-s-how-you-build-dfhack">
<h1><a class="toc-backref" href="#id2">Here's how you build dfhack!</a></h1>
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#dependencies" id="id1">Dependencies</a></li>
<li><a class="reference internal" href="#building-on-linux" id="id2">Building on Linux</a></li>
<li><a class="reference internal" href="#building-on-windows" id="id3">Building on Windows</a><ul>
<li><a class="reference internal" href="#using-mingw" id="id4">Using mingw</a><ul>
<li><a class="reference internal" href="#building" id="id5">Building</a></li>
<li><a class="reference internal" href="#here-s-how-you-build-dfhack" id="id2">Here's how you build dfhack!</a><ul>
<li><a class="reference internal" href="#dependencies" id="id3">Dependencies</a></li>
<li><a class="reference internal" href="#building-on-linux" id="id4">Building on Linux</a></li>
<li><a class="reference internal" href="#building-on-windows" id="id5">Building on Windows</a><ul>
<li><a class="reference internal" href="#using-mingw" id="id6">Using mingw</a><ul>
<li><a class="reference internal" href="#building" id="id7">Building</a></li>
</ul>
</li>
<li><a class="reference internal" href="#using-msvc" id="id6">Using MSVC</a></li>
<li><a class="reference internal" href="#using-some-other-compiler" id="id7">Using some other compiler</a></li>
<li><a class="reference internal" href="#using-msvc" id="id8">Using MSVC</a></li>
<li><a class="reference internal" href="#using-some-other-compiler" id="id9">Using some other compiler</a></li>
</ul>
</li>
<li><a class="reference internal" href="#build-targets" id="id8">Build targets</a></li>
<li><a class="reference internal" href="#build-types" id="id9">Build types</a></li>
<li><a class="reference internal" href="#build-targets" id="id10">Build targets</a></li>
<li><a class="reference internal" href="#build-types" id="id11">Build types</a></li>
</ul>
</li>
<li><a class="reference internal" href="#using-the-library-as-a-developer" id="id12">Using the library as a developer</a><ul>
<li><a class="reference internal" href="#contributing-to-dfhack" id="id13">Contributing to DFHack</a><ul>
<li><a class="reference internal" href="#coding-style" id="id14">Coding style</a></li>
<li><a class="reference internal" href="#how-to-get-new-code-into-dfhack" id="id15">How to get new code into DFHack</a></li>
<li><a class="reference internal" href="#layout-for-tools" id="id16">Layout for tools</a></li>
<li><a class="reference internal" href="#modules-what-are-they" id="id17">Modules - what are they?</a></li>
<li><a class="reference internal" href="#id1" id="id18">Dependencies</a><ul>
<li><a class="reference internal" href="#current-internal-dependencies" id="id19">Current internal dependencies</a></li>
<li><a class="reference internal" href="#current-external-dependencies" id="id20">Current external dependencies</a></li>
<li><a class="reference internal" href="#build-time-dependencies" id="id21">Build-time dependencies</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#memory-offset-definitions" id="id22">Memory offset definitions</a></li>
</ul>
</div>
<div class="section" id="dependencies">
<h1><a class="toc-backref" href="#id1">Dependencies</a></h1>
<h2><a class="toc-backref" href="#id3">Dependencies</a></h2>
<ul class="simple">
<li><tt class="docutils literal">cmake</tt></li>
<li>A compiler for building the main lib and the various tools.</li>
@ -342,7 +363,7 @@ ul.auto-toc {
</ul>
</div>
<div class="section" id="building-on-linux">
<h1><a class="toc-backref" href="#id2">Building on Linux</a></h1>
<h2><a class="toc-backref" href="#id4">Building on Linux</a></h2>
<p>To run in the output folder (without installing) building the library
is simple. Enter the build folder, run the tools. Like this:</p>
<pre class="literal-block">
@ -350,8 +371,15 @@ cd build
cmake .. -DCMAKE_BUILD_TYPE:string=Release
make
</pre>
<p>This will build the library and its tools and place them in <tt class="docutils literal">/output</tt>.
You can also use a cmake-friendly IDE like KDevelop 4 or the cmake GUI
<p>This will build the library and its tools and place them in <tt class="docutils literal">/output</tt>.</p>
<p>Alternatively, you can use ccmake instead of cmake:</p>
<blockquote>
cd build
ccmake ..
make</blockquote>
<p>This will show a curses-based interface that lets you set all of the
extra options.</p>
<p>You can also use a cmake-friendly IDE like KDevelop 4 or the cmake GUI
program.</p>
<p>To be installed into the system or packaged:</p>
<pre class="literal-block">
@ -370,19 +398,19 @@ make install
</ul>
</div>
<div class="section" id="building-on-windows">
<h1><a class="toc-backref" href="#id3">Building on Windows</a></h1>
<h2><a class="toc-backref" href="#id5">Building on Windows</a></h2>
<p>You need <tt class="docutils literal">cmake</tt>. Get the win32 installer version from the official
site: <a class="reference external" href="http://www.cmake.org/cmake/resources/software.html">http://www.cmake.org/cmake/resources/software.html</a></p>
<p>It has the usual installer wizard thing.</p>
<div class="section" id="using-mingw">
<h2><a class="toc-backref" href="#id4">Using mingw</a></h2>
<h3><a class="toc-backref" href="#id6">Using mingw</a></h3>
<p>You also need a compiler. I build dfhack using mingw. You can get it
from the mingw site: <a class="reference external" href="http://www.mingw.org/">http://www.mingw.org/</a></p>
<p>Get the automated installer, it will download newest version of mingw
and set things up nicely.</p>
<p>You'll have to add <tt class="docutils literal"><span class="pre">C:\MinGW\</span></tt> to your PATH variable.</p>
<div class="section" id="building">
<h3><a class="toc-backref" href="#id5">Building</a></h3>
<h4><a class="toc-backref" href="#id7">Building</a></h4>
<p>open up cmd and navigate to the <tt class="docutils literal">dfhack\build</tt> folder, run <tt class="docutils literal">cmake</tt>
and the mingw version of make:</p>
<pre class="literal-block">
@ -393,7 +421,7 @@ mingw32-make
</div>
</div>
<div class="section" id="using-msvc">
<h2><a class="toc-backref" href="#id6">Using MSVC</a></h2>
<h3><a class="toc-backref" href="#id8">Using MSVC</a></h3>
<p>open up <tt class="docutils literal">cmd</tt> and navigate to the <tt class="docutils literal">dfhack\build</tt> folder, run
<tt class="docutils literal">cmake</tt>:</p>
<pre class="literal-block">
@ -410,14 +438,14 @@ by changing cmake configs and running <tt class="docutils literal">cmake</tt> on
</div>
</div>
<div class="section" id="using-some-other-compiler">
<h2><a class="toc-backref" href="#id7">Using some other compiler</a></h2>
<h3><a class="toc-backref" href="#id9">Using some other compiler</a></h3>
<p>I'm afraid you are on your own. dfhack wasn't tested with any other
compiler.</p>
<p>Try using a different cmake generator that's intended for your tools.</p>
</div>
</div>
<div class="section" id="build-targets">
<h1><a class="toc-backref" href="#id8">Build targets</a></h1>
<h2><a class="toc-backref" href="#id10">Build targets</a></h2>
<p>dfhack has a few build targets:</p>
<ul>
<li><p class="first">If you're only after the library run <tt class="docutils literal">make dfhack</tt>.</p>
@ -443,7 +471,7 @@ cmake .. -DBUILD_DFHACK_EXAMPLES=ON
</ul>
</div>
<div class="section" id="build-types">
<h1><a class="toc-backref" href="#id9">Build types</a></h1>
<h2><a class="toc-backref" href="#id11">Build types</a></h2>
<p><tt class="docutils literal">cmake</tt> allows you to pick a build type by changing this
variable: <tt class="docutils literal">CMAKE_BUILD_TYPE</tt></p>
<pre class="literal-block">
@ -456,5 +484,119 @@ cmake .. -DCMAKE_BUILD_TYPE:string=BUILD_TYPE
<p>Have fun.</p>
</div>
</div>
<div class="section" id="using-the-library-as-a-developer">
<h1><a class="toc-backref" href="#id12">Using the library as a developer</a></h1>
<p>DFHack is using the zlib/libpng license. This makes it easy to link to
it, use it in-source or add your own extensions. Contributing back to
the dfhack repository is welcome and the right thing to do :)</p>
<p>Rudimentary API documentation can be built using doxygen.</p>
<div class="section" id="contributing-to-dfhack">
<h2><a class="toc-backref" href="#id13">Contributing to DFHack</a></h2>
<p>Several things should be kept in mind when contributing to DFHack.</p>
<div class="section" id="coding-style">
<h3><a class="toc-backref" href="#id14">Coding style</a></h3>
<p>DFhack uses ANSI formatting and four spaces as indentation. Line
endings are UNIX. The files use UTF-8 encoding. Code not following this
won't make me happy, because I'll have to fix it. There's a good chance
I'll make <em>you</em> fix it ;)</p>
</div>
<div class="section" id="how-to-get-new-code-into-dfhack">
<h3><a class="toc-backref" href="#id15">How to get new code into DFHack</a></h3>
<p>You can send patches or make a clone of the github repo and ask me on
the IRC channel to pull your code in. I'll review it and see if there
are any problems. I'll fix them if they are minor.</p>
<p>Fixes are higher in priority. If you want to work on something, but
don't know what, check out <a class="reference external" href="http://github.com/peterix/dfhack/issues">http://github.com/peterix/dfhack/issues</a> --
this is also a good place to dump new ideas and/or bugs that need
fixing.</p>
</div>
<div class="section" id="layout-for-tools">
<h3><a class="toc-backref" href="#id16">Layout for tools</a></h3>
<p>Tools live in the tools/ folder. There, they are split into three
categories.</p>
<dl class="docutils">
<dt>distributed</dt>
<dd>these tools get distributed with binary releases and are installed
by doing 'make install' on linux. They are supposed to be stable
and supported. Experimental, useless, buggy or untested stuff
doesn't belong here.</dd>
<dt>examples</dt>
<dd>examples are tools that aren't very useful, but show how DF and
DFHack work. They should use only DFHack API functions. No actual
hacking or 'magic offsets' are allowed.</dd>
<dt>playground</dt>
<dd>This is a catch-all folder for tools that aren't ready to be
examples or be distributed in binary releases. All new tools should
start here. They can contain actual hacking, magic values and other
nasty business.</dd>
</dl>
</div>
<div class="section" id="modules-what-are-they">
<h3><a class="toc-backref" href="#id17">Modules - what are they?</a></h3>
<p>DFHack uses modules to partition sets of features into manageable
chunks. A module can have both client and server side.</p>
<p>Client side is the part that goes into the main library and is
generally written in C++. It is exposed to the users of DFHack.</p>
<p>Server side is used inside DF and serves to accelerate the client
modules. This is written mostly in C style.</p>
<p>There's a Core module that shouldn't be changed, because it defines the
basic commands like reading and writing raw data. The client parts for
the Core module are the various implementations of the Process
interface.</p>
<p>A good example of a module is Maps. Named the same in both client and
server, it allows accelerating the reading of map blocks.</p>
<p>Communication between modules happens by using shared memory. This is
pretty fast, but needs quite a bit of care to not break.</p>
</div>
<div class="section" id="id1">
<h3><a class="toc-backref" href="#id18">Dependencies</a></h3>
<dl class="docutils">
<dt>Internal</dt>
<dd>either part of the codebase or statically linked.</dd>
<dt>External</dt>
<dd>linked as dynamic loaded libraries (.dll, .so, etc.)</dd>
</dl>
<p>If you want to add dependencies, think twice about it. All internal
dependencies for core dfhack should be either public domain or require
attribution at most. External dependencies for tools can be either
that, or any Free Software licenses.</p>
<div class="section" id="current-internal-dependencies">
<h4><a class="toc-backref" href="#id19">Current internal dependencies</a></h4>
<dl class="docutils">
<dt>tinyxml</dt>
<dd>used by core dfhack to read offset definitions from Memory.xml</dd>
<dt>md5</dt>
<dd>an implementation of the MD5 hash algorithm. Used for identifying
DF binaries on Linux.</dd>
<dt>argstream</dt>
<dd>Allows reading terminal application arguments. GPL!</dd>
</dl>
</div>
<div class="section" id="current-external-dependencies">
<h4><a class="toc-backref" href="#id20">Current external dependencies</a></h4>
<dl class="docutils">
<dt>wide-character ncurses</dt>
<dd>used for the veinlook tool on Linux.</dd>
<dt>x11 libraries</dt>
<dd>used for sending key events on linux</dd>
</dl>
</div>
<div class="section" id="build-time-dependencies">
<h4><a class="toc-backref" href="#id21">Build-time dependencies</a></h4>
<dl class="docutils">
<dt>cmake</dt>
<dd>you need cmake to generate the build system and some configuration
headers</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="section" id="memory-offset-definitions">
<h1><a class="toc-backref" href="#id22">Memory offset definitions</a></h1>
<p>The files with memory offset definitions used by dfhack can be found in the
data folder.</p>
</div>
</div>
</body>
</html>

@ -45,12 +45,17 @@ Windows
fix it :)
0.31.01 - 0.31.03 legacy
0.31.04 - 0.31.21 SDL
There are missing offsets but Map tools should be OK. Wait for updates...
You need have the MSVC 2010 redistributable_ package installed! The tools will fail to run otherwise.
.. _redistributable: http://www.microsoft.com/downloads/en/details.aspx?FamilyID=a7b7a05e-6de6-4d3a-a423-37bf0912db84
Linux
=====
0.31.05 - 0.31.19 native.
There are missing offsets but Map tools should be OK. Linux support is
a bit lacking, I'm working on it. Slowly. All supported Windows versions
running in wine can be used with native DFHack binaries.
@ -150,130 +155,3 @@ I take no responsibility of anything that happens as a result of using this tool
Your tool here
==============
Write one ;)
================================
Using the library as a developer
================================
The library is compilable under Linux with GCC and under Windows with
MinGW32 and MSVC compilers. It is using the cmake build system. See
COMPILE for details.
DFHack is using the zlib/libpng license. This makes it easy to link to
it, use it in-source or add your own extensions. Contributing back to
the dfhack repository is welcome and the right thing to do :)
At the time of writing there's no API reference or documentation. The
code does have a lot of comments though (and getting better all the
time).
Contributing to DFHack
======================
Several things should be kept in mind when contributing to DFHack.
------------
Coding style
------------
DFhack uses ANSI formatting and four spaces as indentation. Line
endings are UNIX. The files use UTF-8 encoding. Code not following this
won't make me happy, because I'll have to fix it. There's a good chance
I'll make *you* fix it ;)
-------------------------------
How to get new code into DFHack
-------------------------------
You can send patches or make a clone of the github repo and ask me on
the IRC channel to pull your code in. I'll review it and see if there
are any problems. I'll fix them if they are minor.
Fixes are higher in priority. If you want to work on something, but
don't know what, check out http://github.com/peterix/dfhack/issues --
this is also a good place to dump new ideas and/or bugs that need
fixing.
----------------
Layout for tools
----------------
Tools live in the tools/ folder. There, they are split into three
categories.
distributed
these tools get distributed with binary releases and are installed
by doing 'make install' on linux. They are supposed to be stable
and supported. Experimental, useless, buggy or untested stuff
doesn't belong here.
examples
examples are tools that aren't very useful, but show how DF and
DFHack work. They should use only DFHack API functions. No actual
hacking or 'magic offsets' are allowed.
playground
This is a catch-all folder for tools that aren't ready to be
examples or be distributed in binary releases. All new tools should
start here. They can contain actual hacking, magic values and other
nasty business.
------------------------
Modules - what are they?
------------------------
DFHack uses modules to partition sets of features into manageable
chunks. A module can have both client and server side.
Client side is the part that goes into the main library and is
generally written in C++. It is exposed to the users of DFHack.
Server side is used inside DF and serves to accelerate the client
modules. This is written mostly in C style.
There's a Core module that shouldn't be changed, because it defines the
basic commands like reading and writing raw data. The client parts for
the Core module are the various implementations of the Process
interface.
A good example of a module is Maps. Named the same in both client and
server, it allows accelerating the reading of map blocks.
Communication between modules happens by using shared memory. This is
pretty fast, but needs quite a bit of care to not break.
------------
Dependencies
------------
Internal
either part of the codebase or statically linked.
External
linked as dynamic loaded libraries (.dll, .so, etc.)
If you want to add dependencies, think twice about it. All internal
dependencies for core dfhack should be either public domain or require
attribution at most. External dependencies for tools can be either
that, or any Free Software licenses.
Current internal dependencies
-----------------------------
tinyxml
used by core dfhack to read offset definitions from Memory.xml
md5
an implementation of the MD5 hash algorithm. Used for identifying
DF binaries on Linux.
argstream
Allows reading terminal application arguments. GPL!
Current external dependencies
-----------------------------
wide-character ncurses
used for the veinlook tool on Linux.
x11 libraries
used for sending key events on linux
Build-time dependencies
-----------------------
cmake
you need cmake to generate the build system and some configuration
headers
=========================
Memory offset definitions
=========================
The files with memory offset definitions used by dfhack can be found in the
data folder.

@ -353,23 +353,6 @@ allow for easier development of new tools.</p>
<li><a class="reference internal" href="#your-tool-here" id="id24">Your tool here</a></li>
</ul>
</li>
<li><a class="reference internal" href="#using-the-library-as-a-developer" id="id25">Using the library as a developer</a><ul>
<li><a class="reference internal" href="#contributing-to-dfhack" id="id26">Contributing to DFHack</a><ul>
<li><a class="reference internal" href="#coding-style" id="id27">Coding style</a></li>
<li><a class="reference internal" href="#how-to-get-new-code-into-dfhack" id="id28">How to get new code into DFHack</a></li>
<li><a class="reference internal" href="#layout-for-tools" id="id29">Layout for tools</a></li>
<li><a class="reference internal" href="#modules-what-are-they" id="id30">Modules - what are they?</a></li>
<li><a class="reference internal" href="#dependencies" id="id31">Dependencies</a><ul>
<li><a class="reference internal" href="#current-internal-dependencies" id="id32">Current internal dependencies</a></li>
<li><a class="reference internal" href="#current-external-dependencies" id="id33">Current external dependencies</a></li>
<li><a class="reference internal" href="#build-time-dependencies" id="id34">Build-time dependencies</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#memory-offset-definitions" id="id35">Memory offset definitions</a></li>
</ul>
</div>
</div>
@ -397,14 +380,14 @@ in AUR and the arch-games repository.</p>
functionality. If you know how to easily suspend processes, you can
fix it :)</p>
</div>
<p>0.31.01 - 0.31.03 legacy
0.31.04 - 0.31.21 SDL
There are missing offsets but Map tools should be OK. Wait for updates...</p>
<p>0.31.01 - 0.31.03 legacy</p>
<p>0.31.04 - 0.31.21 SDL</p>
<p>You need have the MSVC 2010 <a class="reference external" href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=a7b7a05e-6de6-4d3a-a423-37bf0912db84">redistributable</a> package installed! The tools will fail to run otherwise.</p>
</div>
<div class="section" id="linux">
<h2><a class="toc-backref" href="#id6">Linux</a></h2>
<p>0.31.05 - 0.31.19 native.
There are missing offsets but Map tools should be OK. Linux support is
<p>0.31.05 - 0.31.19 native.</p>
<p>There are missing offsets but Map tools should be OK. Linux support is
a bit lacking, I'm working on it. Slowly. All supported Windows versions
running in wine can be used with native DFHack binaries.</p>
</div>
@ -503,124 +486,6 @@ You just lost a fortress and gained an adventurer.</p>
<p>Write one ;)</p>
</div>
</div>
<div class="section" id="using-the-library-as-a-developer">
<h1><a class="toc-backref" href="#id25">Using the library as a developer</a></h1>
<p>The library is compilable under Linux with GCC and under Windows with
MinGW32 and MSVC compilers. It is using the cmake build system. See
COMPILE for details.</p>
<p>DFHack is using the zlib/libpng license. This makes it easy to link to
it, use it in-source or add your own extensions. Contributing back to
the dfhack repository is welcome and the right thing to do :)</p>
<p>At the time of writing there's no API reference or documentation. The
code does have a lot of comments though (and getting better all the
time).</p>
<div class="section" id="contributing-to-dfhack">
<h2><a class="toc-backref" href="#id26">Contributing to DFHack</a></h2>
<p>Several things should be kept in mind when contributing to DFHack.</p>
<div class="section" id="coding-style">
<h3><a class="toc-backref" href="#id27">Coding style</a></h3>
<p>DFhack uses ANSI formatting and four spaces as indentation. Line
endings are UNIX. The files use UTF-8 encoding. Code not following this
won't make me happy, because I'll have to fix it. There's a good chance
I'll make <em>you</em> fix it ;)</p>
</div>
<div class="section" id="how-to-get-new-code-into-dfhack">
<h3><a class="toc-backref" href="#id28">How to get new code into DFHack</a></h3>
<p>You can send patches or make a clone of the github repo and ask me on
the IRC channel to pull your code in. I'll review it and see if there
are any problems. I'll fix them if they are minor.</p>
<p>Fixes are higher in priority. If you want to work on something, but
don't know what, check out <a class="reference external" href="http://github.com/peterix/dfhack/issues">http://github.com/peterix/dfhack/issues</a> --
this is also a good place to dump new ideas and/or bugs that need
fixing.</p>
</div>
<div class="section" id="layout-for-tools">
<h3><a class="toc-backref" href="#id29">Layout for tools</a></h3>
<p>Tools live in the tools/ folder. There, they are split into three
categories.</p>
<dl class="docutils">
<dt>distributed</dt>
<dd>these tools get distributed with binary releases and are installed
by doing 'make install' on linux. They are supposed to be stable
and supported. Experimental, useless, buggy or untested stuff
doesn't belong here.</dd>
<dt>examples</dt>
<dd>examples are tools that aren't very useful, but show how DF and
DFHack work. They should use only DFHack API functions. No actual
hacking or 'magic offsets' are allowed.</dd>
<dt>playground</dt>
<dd>This is a catch-all folder for tools that aren't ready to be
examples or be distributed in binary releases. All new tools should
start here. They can contain actual hacking, magic values and other
nasty business.</dd>
</dl>
</div>
<div class="section" id="modules-what-are-they">
<h3><a class="toc-backref" href="#id30">Modules - what are they?</a></h3>
<p>DFHack uses modules to partition sets of features into manageable
chunks. A module can have both client and server side.</p>
<p>Client side is the part that goes into the main library and is
generally written in C++. It is exposed to the users of DFHack.</p>
<p>Server side is used inside DF and serves to accelerate the client
modules. This is written mostly in C style.</p>
<p>There's a Core module that shouldn't be changed, because it defines the
basic commands like reading and writing raw data. The client parts for
the Core module are the various implementations of the Process
interface.</p>
<p>A good example of a module is Maps. Named the same in both client and
server, it allows accelerating the reading of map blocks.</p>
<p>Communication between modules happens by using shared memory. This is
pretty fast, but needs quite a bit of care to not break.</p>
</div>
<div class="section" id="dependencies">
<h3><a class="toc-backref" href="#id31">Dependencies</a></h3>
<dl class="docutils">
<dt>Internal</dt>
<dd>either part of the codebase or statically linked.</dd>
<dt>External</dt>
<dd>linked as dynamic loaded libraries (.dll, .so, etc.)</dd>
</dl>
<p>If you want to add dependencies, think twice about it. All internal
dependencies for core dfhack should be either public domain or require
attribution at most. External dependencies for tools can be either
that, or any Free Software licenses.</p>
<div class="section" id="current-internal-dependencies">
<h4><a class="toc-backref" href="#id32">Current internal dependencies</a></h4>
<dl class="docutils">
<dt>tinyxml</dt>
<dd>used by core dfhack to read offset definitions from Memory.xml</dd>
<dt>md5</dt>
<dd>an implementation of the MD5 hash algorithm. Used for identifying
DF binaries on Linux.</dd>
<dt>argstream</dt>
<dd>Allows reading terminal application arguments. GPL!</dd>
</dl>
</div>
<div class="section" id="current-external-dependencies">
<h4><a class="toc-backref" href="#id33">Current external dependencies</a></h4>
<dl class="docutils">
<dt>wide-character ncurses</dt>
<dd>used for the veinlook tool on Linux.</dd>
<dt>x11 libraries</dt>
<dd>used for sending key events on linux</dd>
</dl>
</div>
<div class="section" id="build-time-dependencies">
<h4><a class="toc-backref" href="#id34">Build-time dependencies</a></h4>
<dl class="docutils">
<dt>cmake</dt>
<dd>you need cmake to generate the build system and some configuration
headers</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="section" id="memory-offset-definitions">
<h1><a class="toc-backref" href="#id35">Memory offset definitions</a></h1>
<p>The files with memory offset definitions used by dfhack can be found in the
data folder.</p>
</div>
</div>
</body>
</html>

@ -0,0 +1,5 @@
mkdir build-real
cd build-real
cmake ..\.. -G"Visual Studio 10"
msbuild ALL_BUILD.vcxproj /p:Configuration=Release
echo FINISHED_BUILD

@ -0,0 +1,39 @@
#!/usr/bin/expect
# procedure to attempt connecting; result 0 if OK, 1 otherwise
proc connect {} {
expect "login:"
send "kitteh\r"
expect "password:"
send "a\r"
expect {
kitteh {return 0}
failed return 1
"invalid password" return 1
timeout return 1
connected
}
# timed out
return 1
}
spawn telnet win7
set rez [connect]
if { $rez == 0 } {
send "net use X: \\\\vboxsvr\\projects\r\n"
expect "The command completed successfully."
send "X:\r\n"
expect "X:"
send "cd X:\\dfhack\\build\r\n"
expect "build"
send "\"C:\\Program Files (x86)\\MSVC10\\VC\\vcvarsall.bat\" x86\r\n"
expect "build"
set timeout -1
send "auto.bat\r\n"
expect "FINISHED_BUILD"
send "exit\r"
expect eof
exit 0
}
puts "\nError connecting to server!\n"
exit 1

@ -0,0 +1,49 @@
#/bin/sh
# VARS
export WINEARCH=win32
export WINEPREFIX=$HOME/.wine-mscv/
export WINEDEBUG=-all
export DFHACK_VER=0.5.6
export PKG=dfhack-bin-$DFHACK_VER
export VCBUILD="/home/peterix/.wine-mscv/drive_c/Program Files/Microsoft Visual Studio 9.0/VC/vcpackages/vcbuild.exe"
export TARGET=Release
export PROJECTS="library\\dfhack.vcproj
tools\\supported\\dfattachtest.vcproj
tools\\supported\\dfautosearch.vcproj
tools\\supported\\dfcleanmap.vcproj
tools\\supported\\dfcleartask.vcproj
tools\\supported\\dfdoffsets.vcproj
tools\\supported\\dfexpbench.vcproj
tools\\supported\\dfflows.vcproj
tools\\supported\\dfincremental.vcproj
tools\\supported\\dfliquids.vcproj
tools\\supported\\dfmode.vcproj
tools\\supported\\dfpause.vcproj
tools\\supported\\dfposition.vcproj
tools\\supported\\dfprobe.vcproj
tools\\supported\\dfprospector.vcproj
tools\\supported\\dfreveal.vcproj
tools\\supported\\dfsuspend.vcproj
tools\\supported\\dfunstuck.vcproj
tools\\supported\\dfvdig.vcproj
tools\\supported\\dfweather.vcproj"
# let's build it all
rm -r build-real
mkdir build-real
cd build-real
wine cmake ..\\.. -G"Visual Studio 9 2008"
for proj in $PROJECTS
do
wine "$VCBUILD" $proj $TARGET
done
echo "Creating package..."
cd ../../output/$TARGET
rm -r $PKG
rm $PKG.zip
mkdir $PKG
mv *.exe *.dll *.html *.txt *.xml $PKG
zip -r $PKG.zip $PKG
echo "DONE"

@ -0,0 +1,20 @@
#/bin/sh
# VARS
export DFHACK_VER=0.5.6
export PKG=dfhack-bin-$DFHACK_VER
export TARGET=Release
# let's build it all
VBoxManage startvm "7 Prof"
sleep 5
expect buildremote.expect $TARGET
echo "Creating package..."
cd ../output/$TARGET
rm -r $PKG
rm $PKG.zip
mkdir $PKG
mv *.exe *.dll *.html *.txt *.xml $PKG
zip -r $PKG.zip $PKG
echo "DONE"

@ -47,7 +47,6 @@ IF(DOXYGEN_FOUND)
# "${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)
@ -57,7 +56,7 @@ IF(DOXYGEN_FOUND)
/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}" )
# 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")

@ -38,7 +38,7 @@ PROJECT_NUMBER = @DFHACK_VERSION@
# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.
OUTPUT_DIRECTORY = .
OUTPUT_DIRECTORY = @DOXYGEN_OUTPUT_DIR@
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
# 4096 sub-directories (in 2 levels) under the output directory of each output
@ -60,7 +60,7 @@ CREATE_SUBDIRS = NO
# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak,
# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
OUTPUT_LANGUAGE = English
OUTPUT_LANGUAGE = @DOXYGEN_LANGUAGE@
# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
# include brief member descriptions after the members that are listed in
@ -225,7 +225,7 @@ EXTENSION_MAPPING =
# func(std::string) {}). This also make the inheritance and collaboration
# diagrams that involve STL classes more complete and accurate.
BUILTIN_STL_SUPPORT = NO
BUILTIN_STL_SUPPORT = YES
# If you use Microsoft's C++/CLI language, you should set this option to YES to
# enable parsing support.
@ -521,7 +521,7 @@ LAYOUT_FILE =
# The QUIET tag can be used to turn on/off the messages that are generated
# by doxygen. Possible values are YES and NO. If left blank NO is used.
QUIET = NO
QUIET = YES
# The WARNINGS tag can be used to turn on/off the warning messages that are
# generated by doxygen. Possible values are YES and NO. If left blank
@ -775,7 +775,7 @@ GENERATE_HTML = YES
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `html' will be used as the default path.
HTML_OUTPUT = html
HTML_OUTPUT = .
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
# each generated HTML page (for example: .htm,.php,.asp). If it is left blank

@ -51,7 +51,7 @@ PLACEHOLDER TERRITORY!
Second part has some details on DFHack development:
<ul>
<li>Section \ref starting tells you how to cromulate at a distance!
<li>Section \ref starting tells you how to cromulate at a distance, with a difference!
</ul>
The third part describes how to use the supported DFHack utilities

@ -130,7 +130,7 @@ NormalProcess::NormalProcess(uint32_t pid, VersionInfoFactory * factory)
if(EnumProcessModules(my_handle, &hmod, sizeof(hmod), &needed) == 0)
{
CloseHandle(my_handle);
my_handle=0;
my_handle=0;
// cout << "EnumProcessModules fail'd" << endl;
return; //if enumprocessModules fails, give up
}

@ -880,6 +880,53 @@ namespace DFHack
{"constructed ramp",RAMP,CONSTRUCTED, VAR_1},
{0 ,EMPTY, AIR, VAR_1} // end
};
// tile is missing a floor
inline
bool LowPassable(uint16_t tiletype)
{
switch(DFHack::tileTypeTable[tiletype].c)
{
case DFHack::EMPTY:
case DFHack::STAIR_DOWN:
case DFHack::STAIR_UPDOWN:
case DFHack::RAMP_TOP:
return true;
default:
return false;
}
};
// tile is missing a roof
inline
bool HighPassable(uint16_t tiletype)
{
switch(DFHack::tileTypeTable[tiletype].c)
{
case DFHack::EMPTY:
case DFHack::STAIR_DOWN:
case DFHack::STAIR_UPDOWN:
case DFHack::STAIR_UP:
case DFHack::RAMP:
case DFHack::RAMP_TOP:
case DFHack::FLOOR:
case DFHack::SAPLING_DEAD:
case DFHack::SAPLING_OK:
case DFHack::SHRUB_DEAD:
case DFHack::SHRUB_OK:
case DFHack::BOULDER:
case DFHack::PEBBLES:
return true;
default:
return false;
}
};
inline
bool FlowPassable(uint16_t tiletype)
{
TileClass tc = tileTypeTable[tiletype].c;
return tc != WALL && tc != PILLAR && tc != TREE_DEAD && tc != TREE_OK;
};
inline
bool isWallTerrain(int in)

@ -0,0 +1,342 @@
#ifndef MAPEXTRAS_H
#define MAPEXTRAS_H
#include "../modules/Maps.h"
#include "../DFTileTypes.h"
#include "../DFIntegers.h"
#include <cstring>
namespace MapExtras
{
void SquashVeins (DFHack::Maps *m, DFHack::DFCoord bcoord, DFHack::mapblock40d & mb, DFHack::t_blockmaterials & materials)
{
memset(materials,-1,sizeof(materials));
vector <DFHack::t_vein> veins;
m->ReadVeins(bcoord.x,bcoord.y,bcoord.z,&veins);
//iterate through block rows
for(uint32_t j = 0;j<16;j++)
{
//iterate through columns
for (uint32_t k = 0; k< 16;k++)
{
int16_t tt = mb.tiletypes[k][j];
DFHack::TileMaterial mat = DFHack::tileTypeTable[tt].m;
if(mat == DFHack::VEIN)
{
for(int i = (int) veins.size() - 1; i >= 0;i--)
{
if(!!(((1 << k) & veins[i].assignment[j]) >> k))
{
materials[k][j] = veins[i].type;
i = -1;
}
}
}
}
}
}
class Block
{
public:
Block(DFHack::Maps *_m, DFHack::DFCoord _bcoord)
{
m = _m;
dirty_designations = false;
dirty_tiletypes = false;
dirty_temperatures = false;
dirty_blockflags = false;
valid = false;
bcoord = _bcoord;
if(m->ReadBlock40d(bcoord.x,bcoord.y,bcoord.z,&raw))
{
SquashVeins(m,bcoord,raw,materials);
valid = true;
}
m->ReadTemperatures(bcoord.x,bcoord.y, bcoord.z,&temp1,&temp2);
}
int16_t MaterialAt(DFHack::DFCoord p)
{
return materials[p.x][p.y];
}
void ClearMaterialAt(DFHack::DFCoord p)
{
materials[p.x][p.y] = -1;
}
uint16_t TileTypeAt(DFHack::DFCoord p)
{
return raw.tiletypes[p.x][p.y];
}
bool setTiletypeAt(DFHack::DFCoord p, uint16_t tiletype)
{
if(!valid) return false;
dirty_tiletypes = true;
//printf("setting block %d/%d/%d , %d %d\n",x,y,z, p.x, p.y);
raw.tiletypes[p.x][p.y] = tiletype;
return true;
}
uint16_t temperature1At(DFHack::DFCoord p)
{
return temp1[p.x][p.y];
}
bool setTemp1At(DFHack::DFCoord p, uint16_t temp)
{
if(!valid) return false;
dirty_temperatures = true;
temp1[p.x][p.y] = temp;
return true;
}
uint16_t temperature2At(DFHack::DFCoord p)
{
return temp2[p.x][p.y];
}
bool setTemp2At(DFHack::DFCoord p, uint16_t temp)
{
if(!valid) return false;
dirty_temperatures = true;
temp2[p.x][p.y] = temp;
return true;
}
DFHack::t_designation DesignationAt(DFHack::DFCoord p)
{
return raw.designation[p.x][p.y];
}
bool setDesignationAt(DFHack::DFCoord p, DFHack::t_designation des)
{
if(!valid) return false;
dirty_designations = true;
//printf("setting block %d/%d/%d , %d %d\n",x,y,z, p.x, p.y);
raw.designation[p.x][p.y] = des;
return true;
}
DFHack::t_blockflags BlockFlags()
{
return raw.blockflags;
}
bool setBlockFlags(DFHack::t_blockflags des)
{
if(!valid) return false;
dirty_blockflags = true;
//printf("setting block %d/%d/%d , %d %d\n",x,y,z, p.x, p.y);
raw.blockflags = des;
return true;
}
bool Write ()
{
if(!valid) return false;
if(dirty_designations)
{
m->WriteDesignations(bcoord.x,bcoord.y,bcoord.z, &raw.designation);
m->WriteDirtyBit(bcoord.x,bcoord.y,bcoord.z,true);
dirty_designations = false;
}
if(dirty_tiletypes)
{
m->WriteTileTypes(bcoord.x,bcoord.y,bcoord.z, &raw.tiletypes);
dirty_tiletypes = false;
}
if(dirty_temperatures)
{
m->WriteTemperatures(bcoord.x,bcoord.y,bcoord.z, &temp1, &temp2);
dirty_temperatures = false;
}
if(dirty_blockflags)
{
m->WriteBlockFlags(bcoord.x,bcoord.y,bcoord.z,raw.blockflags);
dirty_blockflags = false;
}
return true;
}
bool valid:1;
bool dirty_designations:1;
bool dirty_tiletypes:1;
bool dirty_temperatures:1;
bool dirty_blockflags:1;
DFHack::Maps * m;
DFHack::mapblock40d raw;
DFHack::DFCoord bcoord;
DFHack::t_blockmaterials materials;
DFHack::t_temperatures temp1;
DFHack::t_temperatures temp2;
};
class MapCache
{
public:
MapCache(DFHack::Maps * Maps)
{
valid = 0;
this->Maps = Maps;
Maps->getSize(x_bmax, y_bmax, z_max);
valid = true;
};
~MapCache()
{
map<DFHack::DFCoord, Block *>::iterator p;
for(p = blocks.begin(); p != blocks.end(); p++)
{
delete p->second;
//cout << stonetypes[p->first].id << " : " << p->second << endl;
}
}
bool isValid ()
{
return valid;
}
/// get the map block at a *block* coord. Block coord = tile coord / 16
Block * BlockAt (DFHack::DFCoord blockcoord)
{
if(!valid)
return 0;
map <DFHack::DFCoord, Block*>::iterator iter = blocks.find(blockcoord);
if(iter != blocks.end())
{
return (*iter).second;
}
else
{
if(blockcoord.x < x_bmax && blockcoord.y < y_bmax && blockcoord.z < z_max)
{
Block * nblo = new Block(Maps,blockcoord);
blocks[blockcoord] = nblo;
return nblo;
}
return 0;
}
}
uint16_t tiletypeAt (DFHack::DFCoord tilecoord)
{
Block * b= BlockAt(tilecoord / 16);
if(b && b->valid)
{
return b->TileTypeAt(tilecoord % 16);
}
return 0;
}
bool setTiletypeAt(DFHack::DFCoord& tilecoord, uint16_t tiletype)
{
Block * b= BlockAt(tilecoord / 16);
if(b && b->valid)
{
b->setTiletypeAt(tilecoord % 16, tiletype);
return true;
}
return false;
}
uint16_t temperature1At (DFHack::DFCoord tilecoord)
{
Block * b= BlockAt(tilecoord / 16);
if(b && b->valid)
{
return b->temperature1At(tilecoord % 16);
}
return 0;
}
bool setTemp1At(DFHack::DFCoord& tilecoord, uint16_t temperature)
{
Block * b= BlockAt(tilecoord / 16);
if(b && b->valid)
{
b->setTemp1At(tilecoord % 16, temperature);
return true;
}
return false;
}
uint16_t temperature2At (DFHack::DFCoord tilecoord)
{
Block * b= BlockAt(tilecoord / 16);
if(b && b->valid)
{
return b->temperature2At(tilecoord % 16);
}
return 0;
}
bool setTemp2At(DFHack::DFCoord& tilecoord, uint16_t temperature)
{
Block * b= BlockAt(tilecoord / 16);
if(b && b->valid)
{
b->setTemp2At(tilecoord % 16, temperature);
return true;
}
return false;
}
int16_t materialAt (DFHack::DFCoord tilecoord)
{
Block * b= BlockAt(tilecoord / 16);
if(b && b->valid)
{
return b->MaterialAt(tilecoord % 16);
}
return 0;
}
bool clearMaterialAt (DFHack::DFCoord tilecoord)
{
Block * b= BlockAt(tilecoord / 16);
if(b && b->valid)
{
b->ClearMaterialAt(tilecoord % 16);
}
return 0;
}
DFHack::t_designation designationAt (DFHack::DFCoord tilecoord)
{
Block * b= BlockAt(tilecoord / 16);
if(b && b->valid)
{
return b->DesignationAt(tilecoord % 16);
}
DFHack:: t_designation temp;
temp.whole = 0;
return temp;
}
bool setDesignationAt (DFHack::DFCoord tilecoord, DFHack::t_designation des)
{
Block * b= BlockAt(tilecoord / 16);
if(b && b->valid)
{
b->setDesignationAt(tilecoord % 16, des);
return true;
}
return false;
}
bool testCoord (DFHack::DFCoord tilecoord)
{
Block * b= BlockAt(tilecoord / 16);
if(b && b->valid)
{
return true;
}
return false;
}
bool WriteAll()
{
map<DFHack::DFCoord, Block *>::iterator p;
for(p = blocks.begin(); p != blocks.end(); p++)
{
p->second->Write();
}
return true;
}
private:
volatile bool valid;
uint32_t x_bmax;
uint32_t y_bmax;
uint32_t x_tmax;
uint32_t y_tmax;
uint32_t z_max;
DFHack::Maps * Maps;
map<DFHack::DFCoord, Block *> blocks;
};
}
#endif

@ -23,23 +23,68 @@ namespace DFHack
};
extern DFHACK_EXPORT const char * sa_feature(int index);
/// used as a key for the local feature map. combines X an Y coords.
union planecoord
class DFCoord
{
uint32_t xy;
struct
public:
DFCoord(uint16_t _x, uint16_t _y, uint16_t _z = 0): x(_x), y(_y), z(_z) {}
DFCoord()
{
comparate = 0;
}
bool operator==(const DFCoord &other) const
{
return (other.comparate == comparate);
}
// FIXME: <tomprince> peterix_: you could probably get away with not defining operator< if you defined a std::less specialization for Vertex.
bool operator<(const DFCoord &other) const
{
uint16_t x;
uint16_t y;
} dim;
bool operator<(const planecoord &other) const
return comparate < other.comparate;
}
DFCoord operator/(int number) const
{
if(other.xy < xy) return true;
return false;
return DFCoord(x/number, y/number, z);
}
DFCoord operator*(int number) const
{
return DFCoord(x*number, y*number, z);
}
DFCoord operator%(int number) const
{
return DFCoord(x%number, y%number, z);
}
DFCoord operator-(int number) const
{
return DFCoord(x,y,z-number);
}
DFCoord operator+(int number) const
{
return DFCoord(x,y,z+number);
}
// this is a hack. beware.
// x,y,z share the same space with comparate. comparate can be used for fast comparisons
union
{
// new shiny DFCoord struct. notice the ludicrous space for Z-levels
struct
{
uint16_t x;
uint16_t y;
uint32_t z;
};
// old planeccord struct for compatibility
struct
{
uint16_t x;
uint16_t y;
} dim;
// comparing thing
uint64_t comparate;
};
};
typedef DFCoord planecoord;
struct t_feature
{
e_feature type;
@ -217,6 +262,7 @@ namespace DFHack
};
// occupancy flags (rat,dwarf,horse,built wall,not build wall,etc)
//FIXME: THIS IS NOT VALID FOR 31.xx versions!!!!
struct naked_occupancy
{
// building type... should be an enum?
@ -296,6 +342,7 @@ namespace DFHack
};
typedef int16_t tiletypes40d [16][16];
typedef int16_t t_blockmaterials [16][16]; ///< used for squashed block materials
typedef DFHack::t_designation designations40d [16][16];
typedef DFHack::t_occupancy occupancies40d [16][16];
typedef uint8_t biome_indices40d [16];
@ -373,7 +420,7 @@ namespace DFHack
// map between mangled coords and pointer to feature
bool ReadGlobalFeatures( std::vector <t_feature> & features);
bool ReadLocalFeatures( std::map <planecoord, std::vector<t_feature *> > & local_features );
bool ReadLocalFeatures( std::map <DFCoord, std::vector<t_feature *> > & local_features );
/*
* BLOCK DATA
*/

@ -635,6 +635,7 @@ bool Maps::ReadVeins(uint32_t x, uint32_t y, uint32_t z, vector <t_vein>* veins,
// read all veins
for (uint32_t i = 0; i < size;i++)
{
retry:
// read the vein pointer from the vector
uint32_t temp = p_veins[i];
uint32_t type = p->readDWord(temp);
@ -681,26 +682,32 @@ bool Maps::ReadVeins(uint32_t x, uint32_t y, uint32_t z, vector <t_vein>* veins,
else
{
string cname = p->readClassName(type);
if(cname == "block_square_event_frozen_liquidst")
if(!off.vein_ice_vptr && cname == "block_square_event_frozen_liquidst")
{
off.vein_ice_vptr = type;
goto retry;
}
else if(cname == "block_square_event_mineralst")
else if(!off.vein_mineral_vptr &&cname == "block_square_event_mineralst")
{
off.vein_mineral_vptr = type;
goto retry;
}
else if(cname == "block_square_event_material_spatterst")
else if(!off.vein_spatter_vptr && cname == "block_square_event_material_spatterst")
{
off.vein_spatter_vptr = type;
goto retry;
}
else if(cname=="block_square_event_grassst")
else if(!off.vein_grass_vptr && cname=="block_square_event_grassst")
{
off.vein_grass_vptr = type;
goto retry;
}
else if(cname=="block_square_event_world_constructionst")
else if(!off.vein_worldconstruction_vptr && cname=="block_square_event_world_constructionst")
{
off.vein_worldconstruction_vptr = type;
goto retry;
}
#ifdef DEBUG
else // this is something we've never seen before
{
if(!d->unknown_veins.count(type))
@ -709,6 +716,7 @@ bool Maps::ReadVeins(uint32_t x, uint32_t y, uint32_t z, vector <t_vein>* veins,
d->unknown_veins.insert(type);
}
}
#endif
}
}
return true;
@ -854,7 +862,7 @@ bool Maps::ReadGeology (vector < vector <uint16_t> >& assign)
return true;
}
bool Maps::ReadLocalFeatures( std::map <planecoord, std::vector<t_feature *> > & local_features )
bool Maps::ReadLocalFeatures( std::map <DFCoord, std::vector<t_feature *> > & local_features )
{
MAPS_GUARD
if(!d->hasFeatures) return false;
@ -905,9 +913,7 @@ bool Maps::ReadLocalFeatures( std::map <planecoord, std::vector<t_feature *> > &
uint32_t feat_vector = wtf + sizeof_vec * (16 * (region_x_local % 16) + (region_y_local % 16));
DfVector<uint32_t> p_features(p, feat_vector);
uint32_t size = p_features.size();
planecoord pc;
pc.dim.x = blockX;
pc.dim.y = blockY;
DFCoord pc(blockX,blockY);
std::vector<t_feature *> tempvec;
for(uint32_t i = 0; i < size; i++)
{

@ -81,7 +81,7 @@ using namespace std;
#include <winnt.h>
#include <psapi.h>
#include <tlhelp32.h>
#include <Dbghelp.h>
//#include <Dbghelp.h> // NOT present in mingw32
typedef LONG NTSTATUS;
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)

@ -320,8 +320,8 @@ void settileat(unsigned char pattern[16][16], const unsigned char needle, const
//Is a given feature present at the given tile?
int isfeature(
vector<DFHack::t_feature> global_features,
std::map <DFHack::planecoord, std::vector<DFHack::t_feature *> > local_features,
const mapblock40d &block, const planecoord &pc, const int x, const int y, const e_feature Feat
std::map <DFHack::DFCoord, std::vector<DFHack::t_feature *> > local_features,
const mapblock40d &block, const DFCoord &pc, const int x, const int y, const e_feature Feat
)
{
//const TileRow * tp;
@ -681,7 +681,7 @@ int main (void)
return 1;
}
std::map <DFHack::planecoord, std::vector<DFHack::t_feature *> > local_features;
std::map <DFHack::DFCoord, std::vector<DFHack::t_feature *> > local_features;
if (!Mapz->ReadLocalFeatures(local_features))
{
cout << "Couldn't load local features! Probably a version problem." << endl;
@ -695,9 +695,7 @@ int main (void)
mapblock40d topblock;
Mapz->ReadBlock40d( bx, by, bz , &topblock );
//Related block info
planecoord pc;
pc.dim.x=bx;
pc.dim.y=by;
DFCoord pc(bx,by);
mapblock40d block;
const TileRow * tp;
t_designation * d;

@ -1,5 +1,3 @@
// TO BE DEPRECATED SOON.
#include <iostream>
#include <vector>
#include <map>
@ -7,7 +5,128 @@
using namespace std;
#include <DFHack.h>
#include <dfhack/DFTileTypes.h>
#include <dfhack/extra/MapExtras.h>
#include <set>
using namespace MapExtras;
typedef vector <DFHack::DFCoord> coord_vec;
class Brush
{
public:
virtual ~Brush(){};
virtual coord_vec points(MapCache & mc,DFHack::DFCoord start) = 0;
};
/**
* generic 3D rectangle brush. you can specify the dimensions of
* the rectangle and optionally which tile is its 'center'
*/
class RectangleBrush : public Brush
{
public:
RectangleBrush(int x, int y, int z = 1, int centerx = -1, int centery = -1, int centerz = -1)
{
if(centerx == -1)
cx_ = x/2;
else
cx_ = centerx;
if(centery == -1)
cy_ = y/2;
else
cy_ = centery;
if(centerz == -1)
cz_ = z/2;
else
cz_ = centerz;
x_ = x;
y_ = y;
z_ = z;
};
coord_vec points(MapCache & mc, DFHack::DFCoord start)
{
coord_vec v;
DFHack::DFCoord iterstart(start.x - cx_, start.y - cy_, start.z - cz_);
DFHack::DFCoord iter = iterstart;
for(int xi = 0; xi < x_; xi++)
{
for(int yi = 0; yi < y_; yi++)
{
for(int zi = 0; zi < z_; zi++)
{
if(mc.testCoord(iter))
v.push_back(iter);
iter.z++;
}
iter.z = iterstart.z;
iter.y++;
}
iter.y = iterstart.y;
iter.x ++;
}
return v;
};
~RectangleBrush(){};
private:
int x_, y_, z_;
int cx_, cy_, cz_;
};
/**
* stupid block brush, legacy. use when you want to apply something to a whole DF map block.
*/
class BlockBrush : public Brush
{
public:
BlockBrush(){};
~BlockBrush(){};
coord_vec points(MapCache & mc, DFHack::DFCoord start)
{
coord_vec v;
DFHack::DFCoord blockc = start % 16;
DFHack::DFCoord iterc = blockc * 16;
if( !mc.testCoord(start) )
return v;
for(int xi = 0; xi < 16; xi++)
{
for(int yi = 0; yi < 16; yi++)
{
v.push_back(iterc);
iterc.y++;
}
iterc.x ++;
}
return v;
};
};
/**
* Column from a position through open space tiles
* example: create a column of magma
*/
class ColumnBrush : public Brush
{
public:
ColumnBrush(){};
~ColumnBrush(){};
coord_vec points(MapCache & mc, DFHack::DFCoord start)
{
coord_vec v;
bool juststarted = true;
while (mc.testCoord(start))
{
uint16_t tt = mc.tiletypeAt(start);
if(DFHack::LowPassable(tt) || juststarted && DFHack::HighPassable(tt))
{
v.push_back(start);
juststarted = false;
start.z++;
}
else break;
}
return v;
};
};
int main (int argc, char** argv)
{
@ -21,15 +140,18 @@ int main (int argc, char** argv)
}
}
int32_t x,y,z;
/*
DFHack::designations40d designations;
DFHack::tiletypes40d tiles;
DFHack::t_temperatures temp1,temp2;
*/
uint32_t x_max,y_max,z_max;
DFHack::ContextManager DFMgr("Memory.xml");
DFHack::Context *DF;
DFHack::Maps * Maps;
DFHack::Position * Position;
Brush * brush = new RectangleBrush(1,1);
try
{
DF=DFMgr.getSingleContext();
@ -50,12 +172,11 @@ int main (int argc, char** argv)
bool end = false;
cout << "Welcome to the liquid spawner. type 'help' for a list of available commands, 'q' to quit." << endl;
string mode="magma";
string brush="point";
string flowmode="f+";
string setmode ="s.";
int amount = 7;
int width = 1;
int height = 1;
int width = 1, height = 1, z_levels = 1;
while(!end)
{
DF->Resume();
@ -68,6 +189,8 @@ int main (int argc, char** argv)
<< "m - switch to magma" << endl
<< "w - switch to water" << endl
<< "o - make obsidian wall instead" << endl
<< "of - make obsidian floors" << endl
<< "rs - make a river source" << endl
<< "f - flow bits only" << endl
<< "Set-Modes:" << endl
<< "s+ - only add" << endl
@ -80,8 +203,9 @@ int main (int argc, char** argv)
<< "0-7 - set liquid amount" << endl
<< "Brush:" << endl
<< "point - single tile [p]" << endl
<< "range - rectangle with cursor at top left [r]" << endl
<< "block - block with cursor in it" << endl
<< "range - block with cursor at bottom north-west [r]" << endl
<< "block - DF map block with cursor in it" << endl
<< "column - Column up through free space" << endl
<< "Other:" << endl
<< "q - quit" << endl
<< "help - print this list of commands" << endl
@ -98,17 +222,9 @@ int main (int argc, char** argv)
{
mode = "obsidian";
}
else if(command == "clmn")
{
mode = "column";
}
else if(command == "starruby")
{
mode = "starruby";
}
else if(command == "darkhide")
else if(command == "of")
{
mode = "darkhide";
mode = "obsidian_floor";
}
else if(command == "w")
{
@ -118,9 +234,14 @@ int main (int argc, char** argv)
{
mode = "flowbits";
}
else if(command == "rs")
{
mode = "riversource";
}
else if(command == "point" || command == "p")
{
brush = "point";
delete brush;
brush = new RectangleBrush(1,1);
}
else if(command == "range" || command == "r")
{
@ -128,15 +249,28 @@ int main (int argc, char** argv)
getline(cin, command);
width = command == "" ? width : atoi (command.c_str());
if(width < 1) width = 1;
cout << " :set range height<" << height << "># ";
getline(cin, command);
height = command == "" ? height : atoi (command.c_str());
if(height < 1) height = 1;
brush = "range";
cout << " :set range z-levels<" << z_levels << "># ";
getline(cin, command);
z_levels = command == "" ? z_levels : atoi (command.c_str());
if(z_levels < 1) z_levels = 1;
delete brush;
brush = new RectangleBrush(width,height,z_levels,0,0,0);
}
else if(command == "block")
{
brush = "block";
delete brush;
brush = new BlockBrush();
}
else if(command == "column")
{
delete brush;
brush = new ColumnBrush();
}
else if(command == "q")
{
@ -199,273 +333,134 @@ int main (int argc, char** argv)
break;
}
cout << "cursor coords: " << x << "/" << y << "/" << z << endl;
if(!Maps->isValidBlock(x/16,y/16,z))
{
cout << "Not a valid block." << endl;
break;
}
MapCache mcache(Maps);
cout << "getting tiles from brush" << endl;
DFHack::DFCoord cursor(x,y,z);
coord_vec all_tiles = brush->points(mcache,cursor);
cout << "doing things" << endl;
if(mode == "obsidian")
{
Maps->ReadTileTypes((x/16),(y/16),z, &tiles);
tiles[x%16][y%16] = 331;
Maps->WriteTileTypes((x/16),(y/16),z, &tiles);
}
else if(mode == "column")
{
int zzz = z;
int16_t tile;
while ( zzz < z_max )
coord_vec::iterator iter = all_tiles.begin();
while (iter != all_tiles.end())
{
Maps->ReadTileTypes((x/16),(y/16),zzz, &tiles);
tile = tiles[x%16][y%16];
if (DFHack::tileTypeTable[tile].c == DFHack::WALL)
break;
tiles[x%16][y%16] = 331;
Maps->WriteTileTypes((x/16),(y/16),zzz, &tiles);
zzz++;
}
mcache.setTiletypeAt(*iter, 331);
iter ++;
}
}
// quick hack, do not use for serious stuff
/*
else if(mode == "starruby")
if(mode == "obsidian_floor")
{
if(Maps->isValidBlock((x/16),(y/16),z))
coord_vec::iterator iter = all_tiles.begin();
while (iter != all_tiles.end())
{
Maps->ReadTileTypes((x/16),(y/16),z, &tiles);
Maps->ReadDesignations((x/16),(y/16),z, &designations);
Maps->ReadTemperatures((x/16),(y/16),z, &temp1, &temp2);
cout << "sizeof(designations) = " << sizeof(designations) << endl;
cout << "sizeof(tiletypes) = " << sizeof(tiles) << endl;
for(uint32_t xx = 0; xx < 16; xx++) for(uint32_t yy = 0; yy < 16; yy++)
{
cout<< xx << " " << yy <<": " << tiles[xx][yy] << endl;
tiles[xx][yy] = 335;// 45
DFHack::naked_designation & des = designations[xx][yy].bits;
des.feature_local = true;
des.feature_global = false;
des.flow_size = 0;
des.skyview = 0;
des.light = 0;
des.subterranean = 1;
temp1[xx][yy] = 10015;
temp2[xx][yy] = 10015;
}
Maps->WriteTemperatures((x/16),(y/16),z, &temp1, &temp2);
Maps->WriteDesignations((x/16),(y/16),z, &designations);
Maps->WriteTileTypes((x/16),(y/16),z, &tiles);
Maps->WriteLocalFeature((x/16),(y/16),z, 36);
mcache.setTiletypeAt(*iter, 340);
iter ++;
}
}
else if(mode == "darkhide")
else if(mode == "riversource")
{
int16_t zzz = z;
while ( zzz >=0 )
set <Block *> seen_blocks;
coord_vec::iterator iter = all_tiles.begin();
while (iter != all_tiles.end())
{
if(Maps->isValidBlock((x/16),(y/16),zzz))
{
int xx = x %16;
int yy = y %16;
Maps->ReadDesignations((x/16),(y/16),zzz, &designations);
designations[xx][yy].bits.skyview = 0;
designations[xx][yy].bits.light = 0;
designations[xx][yy].bits.subterranean = 1;
Maps->WriteDesignations((x/16),(y/16),zzz, &designations);
}
zzz --;
mcache.setTiletypeAt(*iter, 90);
DFHack::t_designation a = mcache.designationAt(*iter);
a.bits.liquid_type = DFHack::liquid_water;
a.bits.liquid_static = false;
a.bits.flow_size = 7;
mcache.setDesignationAt(*iter,a);
Block * b = mcache.BlockAt((*iter)/16);
DFHack::t_blockflags bf = b->BlockFlags();
bf.bits.liquid_1 = true;
bf.bits.liquid_2 = true;
b->setBlockFlags(bf);
iter++;
}
}
*/
else
else if(mode== "magma" || mode== "water" || mode == "flowbits")
{
// place the magma
if(brush != "range")
set <Block *> seen_blocks;
coord_vec::iterator iter = all_tiles.begin();
while (iter != all_tiles.end())
{
Maps->ReadDesignations((x/16),(y/16),z, &designations);
Maps->ReadTemperatures((x/16),(y/16),z, &temp1, &temp2);
if(brush == "point")
DFHack::DFCoord current = *iter;
DFHack::t_designation des = mcache.designationAt(current);
uint16_t tt = mcache.tiletypeAt(current);
DFHack::naked_designation & flow = des.bits;
if(mode != "flowbits")
{
if(mode != "flowbits")
if(!DFHack::FlowPassable(tt))
{
iter++;
continue;
}
// if we are setting the levels to 0 or changing magma into water
if(amount == 0 || des.bits.liquid_type == DFHack::liquid_magma && mode == "water")
{
// reset temperature to sane default
mcache.setTemp1At(current,10015);
mcache.setTemp2At(current,10015);
}
if(setmode == "s.")
{
// fix temperatures so we don't produce lethal heat traps
if(amount == 0 || designations[x%16][y%16].bits.liquid_type == DFHack::liquid_magma && mode == "water")
temp1[x%16][y%16] = temp2[x%16][y%16] = 10015;
DFHack::naked_designation & flow = designations[x%16][y%16].bits;
if(setmode == "s.")
{
flow.flow_size = amount;
}
else if(setmode == "s+")
{
if(flow.flow_size < amount)
flow.flow_size = amount;
}
else if(setmode == "s+")
{
if(flow.flow_size < amount)
flow.flow_size = amount;
}
else if(setmode == "s-")
{
if (flow.flow_size > amount)
flow.flow_size = amount;
}
}
if(mode == "magma")
designations[x%16][y%16].bits.liquid_type = DFHack::liquid_magma;
else if(mode == "water")
designations[x%16][y%16].bits.liquid_type = DFHack::liquid_water;
}
else
{
for(uint32_t xx = 0; xx < 16; xx++) for(uint32_t yy = 0; yy < 16; yy++)
else if(setmode == "s-")
{
if(mode != "flowbits")
{
// fix temperatures so we don't produce lethal heat traps
if(amount == 0 || designations[xx][yy].bits.liquid_type == DFHack::liquid_magma && mode == "water")
temp1[xx%16][yy%16] = temp2[xx%16][yy%16] = 10015;
DFHack::naked_designation & flow= designations[xx][yy].bits;
if(setmode == "s.")
{
flow.flow_size = amount;
}
else if(setmode == "s+")
{
if(flow.flow_size < amount)
flow.flow_size = amount;
}
else if(setmode == "s-")
{
if (flow.flow_size > amount)
flow.flow_size = amount;
}
}
if(mode == "magma")
designations[xx][yy].bits.liquid_type = DFHack::liquid_magma;
else if(mode == "water")
designations[xx][yy].bits.liquid_type = DFHack::liquid_water;
if (flow.flow_size > amount)
flow.flow_size = amount;
}
if(mode == "magma")
flow.liquid_type = DFHack::liquid_magma;
else if(mode == "water")
flow.liquid_type = DFHack::liquid_water;
mcache.setDesignationAt(current,des);
}
Maps->WriteTemperatures((x/16),(y/16),z, &temp1, &temp2);
Maps->WriteDesignations(x/16,y/16,z, &designations);
// make the magma flow :)
DFHack::t_blockflags bflags;
Maps->ReadBlockFlags((x/16),(y/16),z,bflags);
// 0x00000001 = job-designated
// 0x0000000C = run flows? - both bit 3 and 4 required for making magma placed on a glacier flow
seen_blocks.insert(mcache.BlockAt((*iter) / 16));
iter++;
}
set <Block *>::iterator biter = seen_blocks.begin();
while (biter != seen_blocks.end())
{
DFHack::t_blockflags bflags = (*biter)->BlockFlags();
if(flowmode == "f+")
{
bflags.bits.liquid_1 = true;
bflags.bits.liquid_2 = true;
(*biter)->setBlockFlags(bflags);
}
else if(flowmode == "f-")
{
bflags.bits.liquid_1 = false;
bflags.bits.liquid_2 = false;
(*biter)->setBlockFlags(bflags);
}
else
{
cout << "flow bit 1 = " << bflags.bits.liquid_1 << endl;
cout << "flow bit 2 = " << bflags.bits.liquid_2 << endl;
}
Maps->WriteBlockFlags((x/16),(y/16),z,bflags);
biter ++;
}
else if (brush == "range")
{
// Crop the range into each block if necessary
int beginxblock = x/16;
int endxblock = (x+width)/16;
int beginyblock = y/16;
int endyblock = (y+height)/16;
for(uint32_t bx = beginxblock; bx < endxblock+1; bx++) for(uint32_t by = beginyblock; by < endyblock+1; by++)
{
if(Maps->isValidBlock(bx,by,z))
{
Maps->ReadDesignations(bx,by,z, &designations);
Maps->ReadTemperatures(bx,by,z, &temp1, &temp2);
// Take original range and crop it into current block
int nx = x;
int ny = y;
int nwidth = width;
int nheight = height;
if(x/16 < bx) //Start point is left of block
{
nx = bx*16;
nwidth -= nx - x;
}
if (nx/16 < (nx+nwidth-1)/16)// End point is right of block
{
nwidth = (bx*16)+16-nx;
}
if(y/16 < by) //Start point is above block
{
ny = by*16;
nheight -= ny - y;
}
if (ny/16 < (ny+nheight-1)/16) // End point is below block
{
nheight = (by*16)+16-ny;
}
cout << " Block:" << bx << "," << by << ":" << endl;
cout << " Start:" << nx << "," << ny << ":" << endl;
cout << " Area: " << nwidth << "," << nheight << ":" << endl;
for(uint32_t xx = nx; xx < nx+nwidth; xx++) for(uint32_t yy = ny; yy < ny+nheight; yy++)
{
if(mode != "flowbits")
{
// fix temperatures so we don't produce lethal heat traps
if(amount == 0 || designations[xx%16][yy%16].bits.liquid_type == DFHack::liquid_magma && mode == "water")
temp1[xx%16][yy%16] = temp2[xx%16][yy%16] = 10015;
DFHack::naked_designation & flow= designations[xx%16][yy%16].bits;
if(setmode == "s.")
{
flow.flow_size = amount;
}
else if(setmode == "s+")
{
if(flow.flow_size < amount)
flow.flow_size = amount;
}
else if(setmode == "s-")
{
if (flow.flow_size > amount)
flow.flow_size = amount;
}
}
if(mode == "magma")
designations[xx%16][yy%16].bits.liquid_type = DFHack::liquid_magma;
else if(mode == "water")
designations[xx%16][yy%16].bits.liquid_type = DFHack::liquid_water;
}
Maps->WriteTemperatures(bx,by,z, &temp1, &temp2);
Maps->WriteDesignations(bx,by,z, &designations);
// make the magma flow :)
DFHack::t_blockflags bflags;
Maps->ReadBlockFlags(bx,by,z,bflags);
// 0x00000001 = job-designated
// 0x0000000C = run flows? - both bit 3 and 4 required for making magma placed on a glacier flow
if(flowmode == "f+")
{
bflags.bits.liquid_1 = true;
bflags.bits.liquid_2 = true;
}
else if(flowmode == "f-")
{
bflags.bits.liquid_1 = false;
bflags.bits.liquid_2 = false;
}
else
{
cout << "flow bit 1 = " << bflags.bits.liquid_1 << endl;
cout << "flow bit 2 = " << bflags.bits.liquid_2 << endl;
}
Maps->WriteBlockFlags(bx,by,z,bflags);
}
}
}
}
cout << "OK" << endl;
if(mcache.WriteAll())
cout << "OK" << endl;
else
cout << "Something failed horribly! RUN!" << endl;
Maps->Finish();
} while (0);
}
else
{
cout << command << " : unknown command." << endl;
}
}
DF->Detach();
#ifndef LINUX_BUILD

@ -59,7 +59,7 @@ int main (int numargs, const char ** args)
Maps->Start();
vector<DFHack::t_feature> global_features;
std::map <DFHack::planecoord, std::vector<DFHack::t_feature *> > local_features;
std::map <DFHack::DFCoord, std::vector<DFHack::t_feature *> > local_features;
bool have_local = Maps->ReadLocalFeatures(local_features);
bool have_global = Maps->ReadGlobalFeatures(global_features);
@ -133,9 +133,7 @@ int main (int numargs, const char ** args)
PRINT_FLAG( water_table );
PRINT_FLAG( rained );
planecoord pc;
pc.dim.x=blockX; pc.dim.y=blockY;
DFCoord pc(blockX, blockY);
PRINT_FLAG( feature_local );
if( des.feature_local && have_local )

@ -74,7 +74,7 @@ int main (int argc, const char* argv[])
map <int16_t, uint32_t> materials;
materials.clear();
vector<DFHack::t_feature> global_features;
std::map <DFHack::planecoord, std::vector<DFHack::t_feature *> > local_features;
std::map <DFHack::DFCoord, std::vector<DFHack::t_feature *> > local_features;
vector< vector <uint16_t> > layerassign;
@ -236,15 +236,14 @@ int main (int argc, const char* argv[])
idx = Block.local_feature;
if( idx != -1 )
{
DFHack::planecoord pc;
pc.dim.x = x;
pc.dim.y = y;
std::map <DFHack::planecoord, std::vector<DFHack::t_feature *> >::iterator it;
DFHack::DFCoord pc(x,y);
std::map <DFHack::DFCoord, std::vector<DFHack::t_feature *> >::iterator it;
it = local_features.find(pc);
if(it != local_features.end())
{
std::vector<DFHack::t_feature *>& vectr = (*it).second;
if(uint16_t(idx) < vectr.size() && vectr[idx]->type == DFHack::feature_Adamantine_Tube)
{
for(uint32_t xi = 0 ; xi< 16 ; xi++) for(uint32_t yi = 0 ; yi< 16 ; yi++)
{
if(Block.designation[xi][yi].bits.feature_local && DFHack::isWallTerrain(Block.tiletypes[xi][yi]))
@ -259,6 +258,7 @@ int main (int argc, const char* argv[])
}
}
}
}
}
}

@ -9,264 +9,10 @@
using namespace std;
#include <DFHack.h>
#include <dfhack/DFTileTypes.h>
#include <dfhack/extra/MapExtras.h>
using namespace MapExtras;
//#include <argstream.h>
#define MAX_DIM 0x300
//TODO: turn into the official coord class for DFHack/DF
class Vertex
{
public:
Vertex(uint32_t _x, uint32_t _y, uint32_t _z):x(_x),y(_y),z(_z) {}
Vertex()
{
x = y = z = 0;
}
bool operator==(const Vertex &other) const
{
return (other.x == x && other.y == y && other.z == z);
}
// FIXME: <tomprince> peterix_: you could probably get away with not defining operator< if you defined a std::less specialization for Vertex.
bool operator<(const Vertex &other) const
{
// FIXME: could be changed to eliminate MAX_DIM and make std::map lookups faster?
return ( (z*MAX_DIM*MAX_DIM + y*MAX_DIM + x) < (other.z*MAX_DIM*MAX_DIM + other.y*MAX_DIM + other.x));
}
Vertex operator/(int number) const
{
return Vertex(x/number, y/number, z);
}
Vertex operator%(int number) const
{
return Vertex(x%number, y%number, z);
}
Vertex operator-(int number) const
{
return Vertex(x,y,z-number);
}
Vertex operator+(int number) const
{
return Vertex(x,y,z+number);
}
uint32_t x;
uint32_t y;
uint32_t z;
};
class Block
{
public:
Block(DFHack::Maps *_m, Vertex _bcoord)
{
vector <DFHack::t_vein> veins;
m = _m;
dirty = false;
valid = false;
bcoord = _bcoord;
if(m->ReadBlock40d(bcoord.x,bcoord.y,bcoord.z,&raw))
{
memset(materials,-1,sizeof(materials));
memset(bitmap,0,sizeof(bitmap));
m->ReadVeins(bcoord.x,bcoord.y,bcoord.z,&veins);
// for each vein
for(int i = 0; i < (int)veins.size();i++)
{
//iterate through vein rows
for(uint32_t j = 0;j<16;j++)
{
//iterate through the bits
for (uint32_t k = 0; k< 16;k++)
{
// check if it's really a vein (FIXME: doing this too many times)
int16_t tt = raw.tiletypes[k][j];
if(DFHack::isWallTerrain(tt) && DFHack::tileTypeTable[tt].m == DFHack::VEIN)
{
// and the bit array with a one-bit mask, check if the bit is set
bool set = !!(((1 << k) & veins[i].assignment[j]) >> k);
if(set)
{
// store matgloss
materials[k][j] = veins[i].type;
}
}
}
}
}
valid = true;
}
}
int16_t MaterialAt(Vertex p)
{
return materials[p.x][p.y];
}
void ClearMaterialAt(Vertex p)
{
materials[p.x][p.y] = -1;
}
int16_t TileTypeAt(Vertex p)
{
return raw.tiletypes[p.x][p.y];
}
DFHack::t_designation DesignationAt(Vertex p)
{
return raw.designation[p.x][p.y];
}
bool setDesignationAt(Vertex p, DFHack::t_designation des)
{
if(!valid) return false;
dirty = true;
//printf("setting block %d/%d/%d , %d %d\n",x,y,z, p.x, p.y);
raw.designation[p.x][p.y] = des;
return true;
}
bool WriteDesignations ()
{
if(!valid) return false;
if(dirty)
{
//printf("writing %d/%d/%d\n",x,y,z);
m->WriteDesignations(bcoord.x,bcoord.y,bcoord.z, &raw.designation);
m->WriteDirtyBit(bcoord.x,bcoord.y,bcoord.z,true);
}
return true;
}
volatile bool valid;
volatile bool dirty;
DFHack::Maps * m;
DFHack::mapblock40d raw;
Vertex bcoord;
int16_t materials[16][16];
int8_t bitmap[16][16];
};
class MapCache
{
public:
MapCache(DFHack::Maps * Maps)
{
valid = 0;
this->Maps = Maps;
Maps->getSize(x_bmax, y_bmax, z_max);
valid = true;
};
~MapCache()
{
map<Vertex, Block *>::iterator p;
for(p = blocks.begin(); p != blocks.end(); p++)
{
delete p->second;
//cout << stonetypes[p->first].id << " : " << p->second << endl;
}
}
bool isValid ()
{
return valid;
}
Block * BlockAt (Vertex blockcoord)
{
if(!valid) return 0;
map <Vertex, Block*>::iterator iter = blocks.find(blockcoord);
if(iter != blocks.end())
{
return (*iter).second;
}
else
{
if(blockcoord.x < x_bmax && blockcoord.y < y_bmax && blockcoord.z < z_max)
{
Block * nblo = new Block(Maps,blockcoord);
blocks[blockcoord] = nblo;
return nblo;
}
return 0;
}
}
uint16_t tiletypeAt (Vertex tilecoord)
{
Block * b= BlockAt(tilecoord / 16);
if(b && b->valid)
{
return b->TileTypeAt(tilecoord % 16);
}
return 0;
}
int16_t materialAt (Vertex tilecoord)
{
Block * b= BlockAt(tilecoord / 16);
if(b && b->valid)
{
return b->MaterialAt(tilecoord % 16);
}
return 0;
}
bool clearMaterialAt (Vertex tilecoord)
{
Block * b= BlockAt(tilecoord / 16);
if(b && b->valid)
{
b->ClearMaterialAt(tilecoord % 16);
}
return 0;
}
DFHack::t_designation designationAt (Vertex tilecoord)
{
Block * b= BlockAt(tilecoord / 16);
if(b && b->valid)
{
return b->DesignationAt(tilecoord % 16);
}
DFHack:: t_designation temp;
temp.whole = 0;
return temp;
}
bool setDesignationAt (Vertex tilecoord, DFHack::t_designation des)
{
Block * b= BlockAt(tilecoord / 16);
if(b && b->valid)
{
b->setDesignationAt(tilecoord % 16, des);
return true;
}
return false;
}
bool testCoord (Vertex tilecoord)
{
Block * b= BlockAt(tilecoord / 16);
if(b && b->valid)
{
return true;
}
return false;
}
bool WriteAll()
{
map<Vertex, Block *>::iterator p;
for(p = blocks.begin(); p != blocks.end(); p++)
{
p->second->WriteDesignations();
//cout << stonetypes[p->first].id << " : " << p->second << endl;
}
return true;
}
private:
volatile bool valid;
uint32_t x_bmax;
uint32_t y_bmax;
uint32_t x_tmax;
uint32_t y_tmax;
uint32_t z_max;
DFHack::Maps * Maps;
map<Vertex, Block *> blocks;
};
int main (int argc, char* argv[])
{
// Command line options
@ -333,7 +79,7 @@ int main (int argc, char* argv[])
DF->Suspend();
Pos->getCursorCoords(cx,cy,cz);
}
Vertex xy ((uint32_t)cx,(uint32_t)cy,cz);
DFHack::DFCoord xy ((uint32_t)cx,(uint32_t)cy,cz);
if(xy.x == 0 || xy.x == tx_max - 1 || xy.y == 0 || xy.y == ty_max - 1)
{
cerr << "I won't dig the borders. That would be cheating!" << endl;
@ -344,12 +90,11 @@ int main (int argc, char* argv[])
return 1;
}
MapCache * MCache = new MapCache(Maps);
DFHack::t_designation des = MCache->designationAt(xy);
int16_t tt = MCache->tiletypeAt(xy);
int16_t veinmat = MCache->materialAt(xy);
if( veinmat == -1 )
{
cerr << "This tile is non-vein. Bye :)" << endl;
@ -361,21 +106,22 @@ int main (int argc, char* argv[])
return 1;
}
printf("%d/%d/%d tiletype: %d, veinmat: %d, designation: 0x%x ... DIGGING!\n", cx,cy,cz, tt, veinmat, des.whole);
stack <Vertex> flood;
stack <DFHack::DFCoord> flood;
flood.push(xy);
while( !flood.empty() )
{
Vertex current = flood.top();
while( !flood.empty() )
{
DFHack::DFCoord current = flood.top();
flood.pop();
int16_t vmat2 = MCache->materialAt(current);
tt = MCache->tiletypeAt(current);
if(!DFHack::isWallTerrain(tt))
continue;
if(vmat2!=veinmat)
continue;
// found a good tile, dig+unset material
DFHack::t_designation des = MCache->designationAt(current);
DFHack::t_designation des_minus;
DFHack::t_designation des_plus;
@ -392,7 +138,7 @@ int main (int argc, char* argv[])
des_minus = MCache->designationAt(current-1);
vmat_minus = MCache->materialAt(current-1);
}
if(MCache->testCoord(current+1))
{
above = 1;
@ -405,30 +151,30 @@ int main (int argc, char* argv[])
MCache->clearMaterialAt(current);
if(current.x < tx_max - 2)
{
flood.push(Vertex(current.x + 1, current.y, current.z));
flood.push(DFHack::DFCoord(current.x + 1, current.y, current.z));
if(current.y < ty_max - 2)
{
flood.push(Vertex(current.x + 1, current.y + 1,current.z));
flood.push(Vertex(current.x, current.y + 1,current.z));
flood.push(DFHack::DFCoord(current.x + 1, current.y + 1,current.z));
flood.push(DFHack::DFCoord(current.x, current.y + 1,current.z));
}
if(current.y > 1)
{
flood.push(Vertex(current.x + 1, current.y - 1,current.z));
flood.push(Vertex(current.x, current.y - 1,current.z));
flood.push(DFHack::DFCoord(current.x + 1, current.y - 1,current.z));
flood.push(DFHack::DFCoord(current.x, current.y - 1,current.z));
}
}
if(current.x > 1)
{
flood.push(Vertex(current.x - 1, current.y,current.z));
flood.push(DFHack::DFCoord(current.x - 1, current.y,current.z));
if(current.y < ty_max - 2)
{
flood.push(Vertex(current.x - 1, current.y + 1,current.z));
flood.push(Vertex(current.x, current.y + 1,current.z));
flood.push(DFHack::DFCoord(current.x - 1, current.y + 1,current.z));
flood.push(DFHack::DFCoord(current.x, current.y + 1,current.z));
}
if(current.y > 1)
{
flood.push(Vertex(current.x - 1, current.y - 1,current.z));
flood.push(Vertex(current.x, current.y - 1,current.z));
flood.push(DFHack::DFCoord(current.x - 1, current.y - 1,current.z));
flood.push(DFHack::DFCoord(current.x, current.y - 1,current.z));
}
}
if(updown)
@ -436,25 +182,25 @@ int main (int argc, char* argv[])
if(current.z > 0 && below && vmat_minus == vmat2)
{
flood.push(current-1);
if(des_minus.bits.dig == DFHack::designation_d_stair)
des_minus.bits.dig = DFHack::designation_ud_stair;
else
des_minus.bits.dig = DFHack::designation_u_stair;
MCache->setDesignationAt(current-1,des_minus);
des.bits.dig = DFHack::designation_d_stair;
}
if(current.z < z_max - 1 && above && vmat_plus == vmat2)
{
flood.push(current+ 1);
if(des_plus.bits.dig == DFHack::designation_u_stair)
des_plus.bits.dig = DFHack::designation_ud_stair;
else
des_plus.bits.dig = DFHack::designation_d_stair;
MCache->setDesignationAt(current+1,des_plus);
if(des.bits.dig == DFHack::designation_d_stair)
des.bits.dig = DFHack::designation_ud_stair;
else

@ -413,15 +413,13 @@ void do_features(Context* DF, mapblock40d * block, uint32_t blockX, uint32_t blo
if(!Maps)
return;
vector<DFHack::t_feature> global_features;
std::map <DFHack::planecoord, std::vector<DFHack::t_feature *> > local_features;
std::map <DFHack::DFCoord, std::vector<DFHack::t_feature *> > local_features;
if(!Maps->ReadGlobalFeatures(global_features))
return;
if(!Maps->ReadLocalFeatures(local_features))
return;
planecoord pc;
pc.dim.x = blockX;
pc.dim.y = blockY;
DFCoord pc(blockX, blockY);
int16_t idx =block->global_feature;
if(idx != -1)
{