Add a few utility functions to the lua api.

develop
Alexander Gavrilov 2012-10-20 17:06:33 +04:00
parent 687dc7105f
commit 2b1d856214
9 changed files with 244 additions and 63 deletions

@ -334,20 +334,21 @@ ul.auto-toc {
<li><a class="reference internal" href="#build" id="id7">Build</a></li> <li><a class="reference internal" href="#build" id="id7">Build</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#windows" id="id8">Windows</a><ul> <li><a class="reference internal" href="#mac-os-x" id="id8">Mac OS X</a></li>
<li><a class="reference internal" href="#id1" id="id9">How to get the code</a></li> <li><a class="reference internal" href="#windows" id="id9">Windows</a><ul>
<li><a class="reference internal" href="#id2" id="id10">Dependencies</a></li> <li><a class="reference internal" href="#id1" id="id10">How to get the code</a></li>
<li><a class="reference internal" href="#id3" id="id11">Build</a></li> <li><a class="reference internal" href="#id2" id="id11">Dependencies</a></li>
<li><a class="reference internal" href="#id3" id="id12">Build</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#build-types" id="id12">Build types</a></li> <li><a class="reference internal" href="#build-types" id="id13">Build types</a></li>
<li><a class="reference internal" href="#using-the-library-as-a-developer" id="id13">Using the library as a developer</a><ul> <li><a class="reference internal" href="#using-the-library-as-a-developer" id="id14">Using the library as a developer</a><ul>
<li><a class="reference internal" href="#df-data-structure-definitions" id="id14">DF data structure definitions</a></li> <li><a class="reference internal" href="#df-data-structure-definitions" id="id15">DF data structure definitions</a></li>
<li><a class="reference internal" href="#remote-access-interface" id="id15">Remote access interface</a></li> <li><a class="reference internal" href="#remote-access-interface" id="id16">Remote access interface</a></li>
<li><a class="reference internal" href="#contributing-to-dfhack" id="id16">Contributing to DFHack</a><ul> <li><a class="reference internal" href="#contributing-to-dfhack" id="id17">Contributing to DFHack</a><ul>
<li><a class="reference internal" href="#coding-style" id="id17">Coding style</a></li> <li><a class="reference internal" href="#coding-style" id="id18">Coding style</a></li>
<li><a class="reference internal" href="#how-to-get-new-code-into-dfhack" id="id18">How to get new code into DFHack</a></li> <li><a class="reference internal" href="#how-to-get-new-code-into-dfhack" id="id19">How to get new code into DFHack</a></li>
<li><a class="reference internal" href="#memory-research" id="id19">Memory research</a></li> <li><a class="reference internal" href="#memory-research" id="id20">Memory research</a></li>
</ul> </ul>
</li> </li>
</ul> </ul>
@ -403,11 +404,66 @@ extra options.</p>
program.</p> program.</p>
</div> </div>
</div> </div>
<div class="section" id="mac-os-x">
<h1><a class="toc-backref" href="#id8">Mac OS X</a></h1>
<ol class="arabic">
<li><p class="first">Download and unpack a copy of the latest DF</p>
</li>
<li><p class="first">Install Xcode from Mac App Store</p>
</li>
<li><p class="first">Open Xcode, go to Preferences &gt; Downloads, and install the Command Line Tools.</p>
</li>
<li><p class="first">Install MacPorts.</p>
</li>
<li><p class="first">Install dependencies from MacPorts:</p>
<ul>
<li><p class="first"><tt class="docutils literal">sudo port install gcc45 +universal cmake +universal <span class="pre">git-core</span> +universal</tt></p>
<p>This will take some time—maybe hours, depending on your machine.</p>
</li>
<li><p class="first">At some point during this process, it may ask you to install a Java environment; let it do so.</p>
</li>
</ul>
</li>
<li><p class="first">Install perl dependencies</p>
<blockquote>
<ol class="arabic">
<li><p class="first"><tt class="docutils literal">sudo cpan</tt></p>
<p>If this is the first time you've run cpan, you will need to go through the setup
process. Just stick with the defaults for everything and you'll be fine.</p>
</li>
<li><p class="first"><tt class="docutils literal">install <span class="pre">XML::LibXML</span></tt></p>
</li>
<li><p class="first"><tt class="docutils literal">install <span class="pre">XML::LibXSLT</span></tt></p>
</li>
</ol>
</blockquote>
</li>
<li><p class="first">Get the dfhack source:</p>
<pre class="literal-block">
git clone https://github.com/danaris/dfhack.git
cd dfhack
git submodule init
git submodule update
</pre>
</li>
<li><p class="first">Build dfhack:</p>
<pre class="literal-block">
mkdir build-osx
cd build-osx
export CC=/opt/local/bin/gcc-mp-4.5
export CXX=/opt/local/bin/g++-mp-4.5
cmake .. -DCMAKE_BUILD_TYPE:string=Release -DCMAKE_INSTALL_PREFIX=/path/to/DF/directory
make
make install
</pre>
</li>
</ol>
</div>
<div class="section" id="windows"> <div class="section" id="windows">
<h1><a class="toc-backref" href="#id8">Windows</a></h1> <h1><a class="toc-backref" href="#id9">Windows</a></h1>
<p>On Windows, DFHack replaces the SDL library distributed with DF.</p> <p>On Windows, DFHack replaces the SDL library distributed with DF.</p>
<div class="section" id="id1"> <div class="section" id="id1">
<h2><a class="toc-backref" href="#id9">How to get the code</a></h2> <h2><a class="toc-backref" href="#id10">How to get the code</a></h2>
<p>DFHack doesn't have any kind of system of code snapshots in place, so you will have to get code from the github repository using git. <p>DFHack doesn't have any kind of system of code snapshots in place, so you will have to get code from the github repository using git.
You will need some sort of Windows port of git, or a GUI. Some examples:</p> You will need some sort of Windows port of git, or a GUI. Some examples:</p>
<blockquote> <blockquote>
@ -428,7 +484,7 @@ git submodule update
<p>If you want to get really involved with the development, create an account on github, make a clone there and then use that as your remote repository instead. Detailed instructions are beyond the scope of this document. If you need help, join us on IRC (#dfhack channel on freenode).</p> <p>If you want to get really involved with the development, create an account on github, make a clone there and then use that as your remote repository instead. Detailed instructions are beyond the scope of this document. If you need help, join us on IRC (#dfhack channel on freenode).</p>
</div> </div>
<div class="section" id="id2"> <div class="section" id="id2">
<h2><a class="toc-backref" href="#id10">Dependencies</a></h2> <h2><a class="toc-backref" href="#id11">Dependencies</a></h2>
<p>First, you need <tt class="docutils literal">cmake</tt>. Get the win32 installer version from the official <p>First, 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> 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. Make sure you let it add its binary folder <p>It has the usual installer wizard. Make sure you let it add its binary folder
@ -445,7 +501,7 @@ Grab it from Microsoft's site.</p>
<p>If you already have a different version of perl (for example the one from cygwin), you can run into some trouble. Either remove the other perl install from PATH, or install libxml and libxslt for it instead. Strawberry perl works though and has all the required packages.</p> <p>If you already have a different version of perl (for example the one from cygwin), you can run into some trouble. Either remove the other perl install from PATH, or install libxml and libxslt for it instead. Strawberry perl works though and has all the required packages.</p>
</div> </div>
<div class="section" id="id3"> <div class="section" id="id3">
<h2><a class="toc-backref" href="#id11">Build</a></h2> <h2><a class="toc-backref" href="#id12">Build</a></h2>
<p>There are several different batch files in the <tt class="docutils literal">build</tt> folder along with a script that's used for picking the DF path.</p> <p>There are several different batch files in the <tt class="docutils literal">build</tt> folder along with a script that's used for picking the DF path.</p>
<p>First, run set_df_path.vbs and point the dialog that pops up at your DF folder that you want to use for development. <p>First, run set_df_path.vbs and point the dialog that pops up at your DF folder that you want to use for development.
Next, run one of the scripts with <tt class="docutils literal">generate</tt> prefix. These create the MSVC solution file(s):</p> Next, run one of the scripts with <tt class="docutils literal">generate</tt> prefix. These create the MSVC solution file(s):</p>
@ -467,7 +523,7 @@ So pick either Release or RelWithDebInfo build and build the INSTALL target.</p>
</div> </div>
</div> </div>
<div class="section" id="build-types"> <div class="section" id="build-types">
<h1><a class="toc-backref" href="#id12">Build types</a></h1> <h1><a class="toc-backref" href="#id13">Build types</a></h1>
<p><tt class="docutils literal">cmake</tt> allows you to pick a build type by changing this <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> variable: <tt class="docutils literal">CMAKE_BUILD_TYPE</tt></p>
<pre class="literal-block"> <pre class="literal-block">
@ -479,7 +535,7 @@ cmake .. -DCMAKE_BUILD_TYPE:string=BUILD_TYPE
'RelWithDebInfo'. 'Debug' is not available on Windows.</p> 'RelWithDebInfo'. 'Debug' is not available on Windows.</p>
</div> </div>
<div class="section" id="using-the-library-as-a-developer"> <div class="section" id="using-the-library-as-a-developer">
<h1><a class="toc-backref" href="#id13">Using the library as a developer</a></h1> <h1><a class="toc-backref" href="#id14">Using the library as a developer</a></h1>
<p>Currently, the most direct way to use the library is to write a plugin that can be loaded by it. <p>Currently, the most direct way to use the library is to write a plugin that can be loaded by it.
All the plugins can be found in the 'plugins' folder. There's no in-depth documentation All the plugins can be found in the 'plugins' folder. There's no in-depth documentation
on how to write one yet, but it should be easy enough to copy one and just follow the pattern.</p> on how to write one yet, but it should be easy enough to copy one and just follow the pattern.</p>
@ -497,29 +553,29 @@ The main license is zlib/libpng, some bits are MIT licensed, and some are BSD li
<p>Feel free to add your own extensions and plugins. Contributing back to <p>Feel free to add your own extensions and plugins. Contributing back to
the dfhack repository is welcome and the right thing to do :)</p> the dfhack repository is welcome and the right thing to do :)</p>
<div class="section" id="df-data-structure-definitions"> <div class="section" id="df-data-structure-definitions">
<h2><a class="toc-backref" href="#id14">DF data structure definitions</a></h2> <h2><a class="toc-backref" href="#id15">DF data structure definitions</a></h2>
<p>DFHack uses information about the game data structures, represented via xml files in the library/xml/ submodule.</p> <p>DFHack uses information about the game data structures, represented via xml files in the library/xml/ submodule.</p>
<p>Data structure layouts are described in files following the df.*.xml name pattern. This information is transformed by a perl script into C++ headers describing the structures, and associated metadata for the Lua wrapper. These headers and data are then compiled into the DFHack libraries, thus necessitating a compatibility break every time layouts change; in return it significantly boosts the efficiency and capabilities of DFHack code.</p> <p>Data structure layouts are described in files following the df.*.xml name pattern. This information is transformed by a perl script into C++ headers describing the structures, and associated metadata for the Lua wrapper. These headers and data are then compiled into the DFHack libraries, thus necessitating a compatibility break every time layouts change; in return it significantly boosts the efficiency and capabilities of DFHack code.</p>
<p>Global object addresses are stored in symbols.xml, which is copied to the dfhack release package and loaded as data at runtime.</p> <p>Global object addresses are stored in symbols.xml, which is copied to the dfhack release package and loaded as data at runtime.</p>
</div> </div>
<div class="section" id="remote-access-interface"> <div class="section" id="remote-access-interface">
<h2><a class="toc-backref" href="#id15">Remote access interface</a></h2> <h2><a class="toc-backref" href="#id16">Remote access interface</a></h2>
<p>DFHack supports remote access by exchanging Google protobuf messages via a TCP socket. Both the core and plugins can define remotely accessible methods. The <tt class="docutils literal"><span class="pre">dfhack-run</span></tt> command uses this interface to invoke ordinary console commands.</p> <p>DFHack supports remote access by exchanging Google protobuf messages via a TCP socket. Both the core and plugins can define remotely accessible methods. The <tt class="docutils literal"><span class="pre">dfhack-run</span></tt> command uses this interface to invoke ordinary console commands.</p>
<p>Currently the supported set of requests is limited, because the developers don't know what exactly is most useful.</p> <p>Currently the supported set of requests is limited, because the developers don't know what exactly is most useful.</p>
<p>Protocol client implementations exist for Java and C#.</p> <p>Protocol client implementations exist for Java and C#.</p>
</div> </div>
<div class="section" id="contributing-to-dfhack"> <div class="section" id="contributing-to-dfhack">
<h2><a class="toc-backref" href="#id16">Contributing to DFHack</a></h2> <h2><a class="toc-backref" href="#id17">Contributing to DFHack</a></h2>
<p>Several things should be kept in mind when contributing to DFHack.</p> <p>Several things should be kept in mind when contributing to DFHack.</p>
<div class="section" id="coding-style"> <div class="section" id="coding-style">
<h3><a class="toc-backref" href="#id17">Coding style</a></h3> <h3><a class="toc-backref" href="#id18">Coding style</a></h3>
<p>DFhack uses ANSI formatting and four spaces as indentation. Line <p>DFhack uses ANSI formatting and four spaces as indentation. Line
endings are UNIX. The files use UTF-8 encoding. Code not following this 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 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> I'll make <em>you</em> fix it ;)</p>
</div> </div>
<div class="section" id="how-to-get-new-code-into-dfhack"> <div class="section" id="how-to-get-new-code-into-dfhack">
<h3><a class="toc-backref" href="#id18">How to get new code into DFHack</a></h3> <h3><a class="toc-backref" href="#id19">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 <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 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> are any problems. I'll fix them if they are minor.</p>
@ -529,7 +585,7 @@ this is also a good place to dump new ideas and/or bugs that need
fixing.</p> fixing.</p>
</div> </div>
<div class="section" id="memory-research"> <div class="section" id="memory-research">
<h3><a class="toc-backref" href="#id19">Memory research</a></h3> <h3><a class="toc-backref" href="#id20">Memory research</a></h3>
<p>If you want to do memory research, you'll need some tools and some knowledge. <p>If you want to do memory research, you'll need some tools and some knowledge.
In general, you'll need a good memory viewer and optionally something In general, you'll need a good memory viewer and optionally something
to look at machine code without getting crazy :)</p> to look at machine code without getting crazy :)</p>

@ -72,24 +72,39 @@ Mac OS X
3. Open Xcode, go to Preferences > Downloads, and install the Command Line Tools. 3. Open Xcode, go to Preferences > Downloads, and install the Command Line Tools.
4. Install MacPorts. 4. Install MacPorts.
5. Install dependencies from MacPorts: 5. Install dependencies from MacPorts:
* sudo port install gcc45 +universal cmake +universal git-core +universal (This will take some time—maybe hours, depending on your machine.)
* At some point during this process, it may ask you to install a Java environment; let it do so. * ``sudo port install gcc45 +universal cmake +universal git-core +universal``
This will take some time—maybe hours, depending on your machine.
* At some point during this process, it may ask you to install a Java environment; let it do so.
6. Install perl dependencies 6. Install perl dependencies
1. sudo cpan (If this is the first time you've run cpan, you will need to go through the setup process. Just stick with the defaults for everything and you'll be fine.)
2. install XML::LibXML 1. ``sudo cpan``
3. install XML::LibXSLT
7. Get the dfhack source If this is the first time you've run cpan, you will need to go through the setup
1. git clone https://github.com/danaris/dfhack.git process. Just stick with the defaults for everything and you'll be fine.
2. cd dfhack
3. git submodule init 2. ``install XML::LibXML``
4. git submodule update 3. ``install XML::LibXSLT``
8. mkdir build-osx
9. cd build-osx 7. Get the dfhack source::
10. export CC=/opt/local/bin/gcc-mp-4.5
11. export CXX=/opt/local/bin/g++-mp-4.5 git clone https://github.com/danaris/dfhack.git
12. cmake .. -DCMAKE_BUILD_TYPE:string=Release -DCMAKE_INSTALL_PREFIX=/path/to/DF/directory cd dfhack
13. make git submodule init
14. make install git submodule update
8. Build dfhack::
mkdir build-osx
cd build-osx
export CC=/opt/local/bin/gcc-mp-4.5
export CXX=/opt/local/bin/g++-mp-4.5
cmake .. -DCMAKE_BUILD_TYPE:string=Release -DCMAKE_INSTALL_PREFIX=/path/to/DF/directory
make
make install
======= =======
Windows Windows

@ -1110,6 +1110,13 @@ above operations accordingly. If enabled, pauses and zooms to position.</p>
if there are any jobs with <tt class="docutils literal">first_id &lt;= id &lt; job_next_id</tt>, if there are any jobs with <tt class="docutils literal">first_id &lt;= id &lt; job_next_id</tt>,
a lua list containing them.</p> a lua list containing them.</p>
</li> </li>
<li><p class="first"><tt class="docutils literal">dfhack.job.isSuitableItem(job_item, item_type, item_subtype)</tt></p>
<p>Does basic sanity checks to verify if the suggested item type matches
the flags in the job item.</p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.job.isSuitableMaterial(job_item, mat_type, mat_index)</tt></p>
<p>Likewise, if replacing material.</p>
</li>
</ul> </ul>
</div> </div>
<div class="section" id="units-module"> <div class="section" id="units-module">
@ -1250,6 +1257,15 @@ Returns <em>false</em> in case of error.</p>
<li><p class="first"><tt class="docutils literal">dfhack.items.makeProjectile(item)</tt></p> <li><p class="first"><tt class="docutils literal">dfhack.items.makeProjectile(item)</tt></p>
<p>Turns the item into a projectile, and returns the new object, or <em>nil</em> if impossible.</p> <p>Turns the item into a projectile, and returns the new object, or <em>nil</em> if impossible.</p>
</li> </li>
<li><p class="first"><tt class="docutils literal">dfhack.items.isCasteMaterial(item_type)</tt></p>
<p>Returns <em>true</em> if this item type uses a creature/caste pair as its material.</p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.items.getSubtypeCount(item_type)</tt></p>
<p>Returns the number of raw-defined subtypes of the given item type, or <em>-1</em> if not applicable.</p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.items.getSubtypeDef(item_type, subtype)</tt></p>
<p>Returns the raw definition for the given item type and subtype, or <em>nil</em> if invalid.</p>
</li>
</ul> </ul>
</div> </div>
<div class="section" id="maps-module"> <div class="section" id="maps-module">
@ -1264,7 +1280,7 @@ Returns <em>false</em> in case of error.</p>
<li><p class="first"><tt class="docutils literal">dfhack.maps.getBlock(x,y,z)</tt></p> <li><p class="first"><tt class="docutils literal">dfhack.maps.getBlock(x,y,z)</tt></p>
<p>Returns a map block object for given x,y,z in local block coordinates.</p> <p>Returns a map block object for given x,y,z in local block coordinates.</p>
</li> </li>
<li><p class="first"><tt class="docutils literal">dfhack.maps.isValidTilePos(coords)</tt>, or isValidTilePos(x,y,z)``</p> <li><p class="first"><tt class="docutils literal">dfhack.maps.isValidTilePos(coords)</tt>, or <tt class="docutils literal">isValidTilePos(x,y,z)</tt></p>
<p>Checks if the given df::coord or x,y,z in local tile coordinates are valid.</p> <p>Checks if the given df::coord or x,y,z in local tile coordinates are valid.</p>
</li> </li>
<li><p class="first"><tt class="docutils literal">dfhack.maps.getTileBlock(coords)</tt>, or <tt class="docutils literal">getTileBlock(x,y,z)</tt></p> <li><p class="first"><tt class="docutils literal">dfhack.maps.getTileBlock(coords)</tt>, or <tt class="docutils literal">getTileBlock(x,y,z)</tt></p>
@ -1273,6 +1289,12 @@ Returns <em>false</em> in case of error.</p>
<li><p class="first"><tt class="docutils literal">dfhack.maps.ensureTileBlock(coords)</tt>, or <tt class="docutils literal">ensureTileBlock(x,y,z)</tt></p> <li><p class="first"><tt class="docutils literal">dfhack.maps.ensureTileBlock(coords)</tt>, or <tt class="docutils literal">ensureTileBlock(x,y,z)</tt></p>
<p>Like <tt class="docutils literal">getTileBlock</tt>, but if the block is not allocated, try creating it.</p> <p>Like <tt class="docutils literal">getTileBlock</tt>, but if the block is not allocated, try creating it.</p>
</li> </li>
<li><p class="first"><tt class="docutils literal">dfhack.maps.getTileType(coords)</tt>, or <tt class="docutils literal">getTileType(x,y,z)</tt></p>
<p>Returns the tile type at the given coordinates, or <em>nil</em> if invalid.</p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.maps.getTileFlags(coords)</tt>, or <tt class="docutils literal">getTileFlags(x,y,z)</tt></p>
<p>Returns designation and occupancy references for the given coordinates, or <em>nil, nil</em> if invalid.</p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.maps.getRegionBiome(region_coord2d)</tt>, or <tt class="docutils literal">getRegionBiome(x,y)</tt></p> <li><p class="first"><tt class="docutils literal">dfhack.maps.getRegionBiome(region_coord2d)</tt>, or <tt class="docutils literal">getRegionBiome(x,y)</tt></p>
<p>Returns the biome info struct for the given global map region.</p> <p>Returns the biome info struct for the given global map region.</p>
</li> </li>
@ -1838,6 +1860,15 @@ coordinates), returns <em>nil</em>.</p>
<li><p class="first"><tt class="docutils literal">xyz2pos(x,y,z)</tt></p> <li><p class="first"><tt class="docutils literal">xyz2pos(x,y,z)</tt></p>
<p>Returns a table with x, y and z as fields.</p> <p>Returns a table with x, y and z as fields.</p>
</li> </li>
<li><p class="first"><tt class="docutils literal">same_xyz(a,b)</tt></p>
<p>Checks if <tt class="docutils literal">a</tt> and <tt class="docutils literal">b</tt> have the same x, y and z fields.</p>
</li>
<li><p class="first"><tt class="docutils literal">get_path_xyz(path,i)</tt></p>
<p>Returns <tt class="docutils literal">path.x[i], path.y[i], path.z[i]</tt>.</p>
</li>
<li><p class="first"><tt class="docutils literal">pos2xy(obj)</tt>, <tt class="docutils literal">xy2pos(x,y)</tt>, <tt class="docutils literal">same_xy(a,b)</tt>, <tt class="docutils literal">get_path_xy(a,b)</tt></p>
<p>Same as above, but for 2D coordinates.</p>
</li>
<li><p class="first"><tt class="docutils literal"><span class="pre">safe_index(obj,index...)</span></tt></p> <li><p class="first"><tt class="docutils literal"><span class="pre">safe_index(obj,index...)</span></tt></p>
<p>Walks a sequence of dereferences, which may be represented by numbers or strings. <p>Walks a sequence of dereferences, which may be represented by numbers or strings.
Returns <em>nil</em> if any of obj or indices is <em>nil</em>, or a numeric index is out of array bounds.</p> Returns <em>nil</em> if any of obj or indices is <em>nil</em>, or a numeric index is out of array bounds.</p>

@ -1043,6 +1043,18 @@ Items module
Turns the item into a projectile, and returns the new object, or *nil* if impossible. Turns the item into a projectile, and returns the new object, or *nil* if impossible.
* ``dfhack.items.isCasteMaterial(item_type)``
Returns *true* if this item type uses a creature/caste pair as its material.
* ``dfhack.items.getSubtypeCount(item_type)``
Returns the number of raw-defined subtypes of the given item type, or *-1* if not applicable.
* ``dfhack.items.getSubtypeDef(item_type, subtype)``
Returns the raw definition for the given item type and subtype, or *nil* if invalid.
Maps module Maps module
----------- -----------
@ -1059,7 +1071,7 @@ Maps module
Returns a map block object for given x,y,z in local block coordinates. Returns a map block object for given x,y,z in local block coordinates.
* ``dfhack.maps.isValidTilePos(coords)``, or isValidTilePos(x,y,z)`` * ``dfhack.maps.isValidTilePos(coords)``, or ``isValidTilePos(x,y,z)``
Checks if the given df::coord or x,y,z in local tile coordinates are valid. Checks if the given df::coord or x,y,z in local tile coordinates are valid.
@ -1071,6 +1083,14 @@ Maps module
Like ``getTileBlock``, but if the block is not allocated, try creating it. Like ``getTileBlock``, but if the block is not allocated, try creating it.
* ``dfhack.maps.getTileType(coords)``, or ``getTileType(x,y,z)``
Returns the tile type at the given coordinates, or *nil* if invalid.
* ``dfhack.maps.getTileFlags(coords)``, or ``getTileFlags(x,y,z)``
Returns designation and occupancy references for the given coordinates, or *nil, nil* if invalid.
* ``dfhack.maps.getRegionBiome(region_coord2d)``, or ``getRegionBiome(x,y)`` * ``dfhack.maps.getRegionBiome(region_coord2d)``, or ``getRegionBiome(x,y)``
Returns the biome info struct for the given global map region. Returns the biome info struct for the given global map region.

@ -2494,20 +2494,21 @@ growcrops plump 40
<h2><a class="toc-backref" href="#id118">removebadthoughts</a></h2> <h2><a class="toc-backref" href="#id118">removebadthoughts</a></h2>
<p>This script remove negative thoughts from your dwarves. Very useful against <p>This script remove negative thoughts from your dwarves. Very useful against
tantrum spirals.</p> tantrum spirals.</p>
<p>With a selected unit in 'v' mode, will clear this unit's mind, otherwise <p>The script can target a single creature, when used with the <tt class="docutils literal">him</tt> argument,
clear all your fort's units minds.</p> or the whole fort population, with <tt class="docutils literal">all</tt>.</p>
<p>To show every bad thought present without actually removing them, run the
script with the <tt class="docutils literal"><span class="pre">-n</span></tt> or <tt class="docutils literal"><span class="pre">--dry-run</span></tt> argument. This can give a quick
hint on what bothers your dwarves the most.</p>
<p>Individual dwarf happiness may not increase right after this command is run, <p>Individual dwarf happiness may not increase right after this command is run,
but in the short term your dwarves will get much more joyful. but in the short term your dwarves will get much more joyful.</p>
The thoughts are set to be very old, and the game will remove them soon when <p>Internals: the thoughts are set to be very old, so that the game remove them
you unpause.</p> quickly after you unpause.</p>
<p>With the optional <tt class="docutils literal"><span class="pre">-v</span></tt> parameter, the script will dump the negative thoughts
it removed.</p>
</div> </div>
<div class="section" id="slayrace"> <div class="section" id="slayrace">
<h2><a class="toc-backref" href="#id119">slayrace</a></h2> <h2><a class="toc-backref" href="#id119">slayrace</a></h2>
<p>Kills any unit of a given race.</p> <p>Kills any unit of a given race.</p>
<p>With no argument, lists the available races.</p> <p>With no argument, lists the available races.</p>
<p>With the special argument 'him', targets only the selected creature.</p> <p>With the special argument <tt class="docutils literal">him</tt>, targets only the selected creature.</p>
<p>Any non-dead non-caged unit of the specified race gets its <tt class="docutils literal">blood_count</tt> <p>Any non-dead non-caged unit of the specified race gets its <tt class="docutils literal">blood_count</tt>
set to 0, which means immediate death at the next game tick. For creatures set to 0, which means immediate death at the next game tick. For creatures
such as vampires, also set animal.vanish_countdown to 2.</p> such as vampires, also set animal.vanish_countdown to 2.</p>

@ -82,6 +82,7 @@ distribution.
#include "df/flow_info.h" #include "df/flow_info.h"
#include "df/unit_misc_trait.h" #include "df/unit_misc_trait.h"
#include "df/proj_itemst.h" #include "df/proj_itemst.h"
#include "df/itemdef.h"
#include <lua.h> #include <lua.h>
#include <lauxlib.h> #include <lauxlib.h>
@ -937,6 +938,9 @@ static const LuaWrapper::FunctionReg dfhack_items_module[] = {
WRAPM(Items, setOwner), WRAPM(Items, setOwner),
WRAPM(Items, getContainer), WRAPM(Items, getContainer),
WRAPM(Items, getDescription), WRAPM(Items, getDescription),
WRAPM(Items, isCasteMaterial),
WRAPM(Items, getSubtypeCount),
WRAPM(Items, getSubtypeDef),
WRAPN(moveToGround, items_moveToGround), WRAPN(moveToGround, items_moveToGround),
WRAPN(moveToContainer, items_moveToContainer), WRAPN(moveToContainer, items_moveToContainer),
WRAPN(moveToBuilding, items_moveToBuilding), WRAPN(moveToBuilding, items_moveToBuilding),
@ -1018,6 +1022,25 @@ static int maps_ensureTileBlock(lua_State *L)
return 1; return 1;
} }
static int maps_getTileType(lua_State *L)
{
auto pos = CheckCoordXYZ(L, 1, true);
auto ptype = Maps::getTileType(pos);
if (ptype)
lua_pushinteger(L, *ptype);
else
lua_pushnil(L);
return 1;
}
static int maps_getTileFlags(lua_State *L)
{
auto pos = CheckCoordXYZ(L, 1, true);
Lua::PushDFObject(L, Maps::getTileDesignation(pos));
Lua::PushDFObject(L, Maps::getTileOccupancy(pos));
return 2;
}
static int maps_getRegionBiome(lua_State *L) static int maps_getRegionBiome(lua_State *L)
{ {
auto pos = CheckCoordXY(L, 1, true); auto pos = CheckCoordXY(L, 1, true);
@ -1035,6 +1058,8 @@ static const luaL_Reg dfhack_maps_funcs[] = {
{ "isValidTilePos", maps_isValidTilePos }, { "isValidTilePos", maps_isValidTilePos },
{ "getTileBlock", maps_getTileBlock }, { "getTileBlock", maps_getTileBlock },
{ "ensureTileBlock", maps_ensureTileBlock }, { "ensureTileBlock", maps_ensureTileBlock },
{ "getTileType", maps_getTileType },
{ "getTileFlags", maps_getTileFlags },
{ "getRegionBiome", maps_getRegionBiome }, { "getRegionBiome", maps_getRegionBiome },
{ "getTileBiomeRgn", maps_getTileBiomeRgn }, { "getTileBiomeRgn", maps_getTileBiomeRgn },
{ NULL, NULL } { NULL, NULL }

@ -123,6 +123,10 @@ struct dfh_item
namespace Items namespace Items
{ {
DFHACK_EXPORT bool isCasteMaterial(df::item_type itype);
DFHACK_EXPORT int getSubtypeCount(df::item_type itype);
DFHACK_EXPORT df::itemdef *getSubtypeDef(df::item_type itype, int subtype);
/// Look for a particular item by ID /// Look for a particular item by ID
DFHACK_EXPORT df::item * findItemByID(int32_t id); DFHACK_EXPORT df::item * findItemByID(int32_t id);

@ -109,30 +109,47 @@ using df::global::proj_next_id;
ITEM(PANTS, pants, itemdef_pantsst) \ ITEM(PANTS, pants, itemdef_pantsst) \
ITEM(FOOD, food, itemdef_foodst) ITEM(FOOD, food, itemdef_foodst)
bool ItemTypeInfo::decode(df::item_type type_, int16_t subtype_) int Items::getSubtypeCount(df::item_type itype)
{ {
using namespace df::enums::item_type; using namespace df::enums::item_type;
type = type_;
subtype = subtype_;
custom = NULL;
df::world_raws::T_itemdefs &defs = df::global::world->raws.itemdefs; df::world_raws::T_itemdefs &defs = df::global::world->raws.itemdefs;
switch (type_) { switch (itype) {
case NONE: #define ITEM(type,vec,tclass) \
return false; case type: \
return defs.vec.size();
ITEMDEF_VECTORS
#undef ITEM
default:
return -1;
}
}
df::itemdef *Items::getSubtypeDef(df::item_type itype, int subtype)
{
using namespace df::enums::item_type;
df::world_raws::T_itemdefs &defs = df::global::world->raws.itemdefs;
switch (itype) {
#define ITEM(type,vec,tclass) \ #define ITEM(type,vec,tclass) \
case type: \ case type: \
custom = vector_get(defs.vec, subtype); \ return vector_get(defs.vec, subtype);
break;
ITEMDEF_VECTORS ITEMDEF_VECTORS
#undef ITEM #undef ITEM
default: default:
break; return NULL;
} }
}
bool ItemTypeInfo::decode(df::item_type type_, int16_t subtype_)
{
type = type_;
subtype = subtype_;
custom = Items::getSubtypeDef(type_, subtype_);
return isValid(); return isValid();
} }
@ -171,6 +188,10 @@ ITEMDEF_VECTORS
break; break;
} }
const char *name = ENUM_ATTR(item_type, caption, type);
if (name)
return name;
return toLower(ENUM_KEY_STR(item_type, type)); return toLower(ENUM_KEY_STR(item_type, type));
} }
@ -219,6 +240,11 @@ ITEMDEF_VECTORS
return (subtype >= 0); return (subtype >= 0);
} }
bool Items::isCasteMaterial(df::item_type itype)
{
return ENUM_ATTR(item_type, is_caste_mat, itype);
}
bool ItemTypeInfo::matches(const df::job_item &item, MaterialInfo *mat) bool ItemTypeInfo::matches(const df::job_item &item, MaterialInfo *mat)
{ {
using namespace df::enums::item_type; using namespace df::enums::item_type;
@ -226,6 +252,9 @@ bool ItemTypeInfo::matches(const df::job_item &item, MaterialInfo *mat)
if (!isValid()) if (!isValid())
return mat ? mat->matches(item) : false; return mat ? mat->matches(item) : false;
if (Items::isCasteMaterial(type) && mat && !mat->isNone())
return false;
df::job_item_flags1 ok1, mask1, item_ok1, item_mask1; df::job_item_flags1 ok1, mask1, item_ok1, item_mask1;
df::job_item_flags2 ok2, mask2, item_ok2, item_mask2; df::job_item_flags2 ok2, mask2, item_ok2, item_mask2;
df::job_item_flags3 ok3, mask3, item_ok3, item_mask3; df::job_item_flags3 ok3, mask3, item_ok3, item_mask3;

@ -1 +1 @@
Subproject commit aec106cdc32083bbcc6d6dd27d9e069f5525ea92 Subproject commit 0ed2d1dc5547737fbb838568fc66671098f2c11a