Merge branch 'develop' into dev-embarktools-pr

develop
lethosor 2014-06-10 12:08:43 -04:00
commit 088eff05e5
22 changed files with 2083 additions and 264 deletions

@ -7,6 +7,7 @@ DFHack future
- support for multiple raw/init.d/*.lua init scripts in one save. - support for multiple raw/init.d/*.lua init scripts in one save.
- eventful now has a more friendly way of making custom sidebars - eventful now has a more friendly way of making custom sidebars
- new plugin: building-hacks. Allows to add custom functionality and/or animations to buildings. - new plugin: building-hacks. Allows to add custom functionality and/or animations to buildings.
- on Linux and OSX the console now supports moving the cursor back and forward by a whole word.
New scripts: New scripts:
- gui/mod-manager: allows installing/uninstalling mods into df from df/mods directory. - gui/mod-manager: allows installing/uninstalling mods into df from df/mods directory.
@ -28,6 +29,7 @@ DFHack future
New plugins: New plugins:
- rendermax: replace the renderer with something else. Most interesting is "rendermax light"- a lighting engine for df. - rendermax: replace the renderer with something else. Most interesting is "rendermax light"- a lighting engine for df.
- stockflow (by eswald): queues manager jobs of the configured type based on the state of a stockpile.
Misc improvements: Misc improvements:
- digfort: improved csv parsing, add start() comment handling - digfort: improved csv parsing, add start() comment handling

@ -484,110 +484,114 @@ access DF memory and allow for easier development of new tools.</p>
<li><a class="reference internal" href="#ssense-stonesense" id="id101">ssense / stonesense</a></li> <li><a class="reference internal" href="#ssense-stonesense" id="id101">ssense / stonesense</a></li>
<li><a class="reference internal" href="#mapexport" id="id102">mapexport</a></li> <li><a class="reference internal" href="#mapexport" id="id102">mapexport</a></li>
<li><a class="reference internal" href="#dwarfexport" id="id103">dwarfexport</a></li> <li><a class="reference internal" href="#dwarfexport" id="id103">dwarfexport</a></li>
<li><a class="reference internal" href="#exportlegends" id="id104">exportlegends</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#job-management" id="id104">Job management</a><ul> <li><a class="reference internal" href="#job-management" id="id105">Job management</a><ul>
<li><a class="reference internal" href="#job" id="id105">job</a></li> <li><a class="reference internal" href="#job" id="id106">job</a></li>
<li><a class="reference internal" href="#job-material" id="id106">job-material</a></li> <li><a class="reference internal" href="#job-material" id="id107">job-material</a></li>
<li><a class="reference internal" href="#job-duplicate" id="id107">job-duplicate</a></li> <li><a class="reference internal" href="#job-duplicate" id="id108">job-duplicate</a></li>
<li><a class="reference internal" href="#workflow" id="id108">workflow</a><ul> <li><a class="reference internal" href="#stockflow" id="id109">stockflow</a></li>
<li><a class="reference internal" href="#function" id="id109">Function</a></li> <li><a class="reference internal" href="#workflow" id="id110">workflow</a><ul>
<li><a class="reference internal" href="#constraint-format" id="id110">Constraint format</a></li> <li><a class="reference internal" href="#function" id="id111">Function</a></li>
<li><a class="reference internal" href="#constraint-examples" id="id111">Constraint examples</a></li> <li><a class="reference internal" href="#constraint-format" id="id112">Constraint format</a></li>
<li><a class="reference internal" href="#constraint-examples" id="id113">Constraint examples</a></li>
</ul> </ul>
</li> </li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#fortress-activity-management" id="id112">Fortress activity management</a><ul> <li><a class="reference internal" href="#fortress-activity-management" id="id114">Fortress activity management</a><ul>
<li><a class="reference internal" href="#seedwatch" id="id113">seedwatch</a></li> <li><a class="reference internal" href="#seedwatch" id="id115">seedwatch</a></li>
<li><a class="reference internal" href="#zone" id="id114">zone</a><ul> <li><a class="reference internal" href="#zone" id="id116">zone</a><ul>
<li><a class="reference internal" href="#usage-with-single-units" id="id115">Usage with single units</a></li> <li><a class="reference internal" href="#usage-with-single-units" id="id117">Usage with single units</a></li>
<li><a class="reference internal" href="#usage-with-filters" id="id116">Usage with filters</a></li> <li><a class="reference internal" href="#usage-with-filters" id="id118">Usage with filters</a></li>
<li><a class="reference internal" href="#mass-renaming" id="id117">Mass-renaming</a></li> <li><a class="reference internal" href="#mass-renaming" id="id119">Mass-renaming</a></li>
<li><a class="reference internal" href="#cage-zones" id="id118">Cage zones</a></li> <li><a class="reference internal" href="#cage-zones" id="id120">Cage zones</a></li>
<li><a class="reference internal" href="#examples" id="id119">Examples</a></li> <li><a class="reference internal" href="#examples" id="id121">Examples</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#autonestbox" id="id120">autonestbox</a></li> <li><a class="reference internal" href="#autonestbox" id="id122">autonestbox</a></li>
<li><a class="reference internal" href="#autobutcher" id="id121">autobutcher</a></li> <li><a class="reference internal" href="#autobutcher" id="id123">autobutcher</a></li>
<li><a class="reference internal" href="#autochop" id="id122">autochop</a></li> <li><a class="reference internal" href="#autochop" id="id124">autochop</a></li>
<li><a class="reference internal" href="#autolabor" id="id123">autolabor</a></li> <li><a class="reference internal" href="#autolabor" id="id125">autolabor</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#other" id="id124">Other</a><ul> <li><a class="reference internal" href="#other" id="id126">Other</a><ul>
<li><a class="reference internal" href="#catsplosion" id="id125">catsplosion</a></li> <li><a class="reference internal" href="#catsplosion" id="id127">catsplosion</a></li>
<li><a class="reference internal" href="#dfusion" id="id126">dfusion</a></li> <li><a class="reference internal" href="#dfusion" id="id128">dfusion</a></li>
<li><a class="reference internal" href="#misery" id="id127">misery</a></li> <li><a class="reference internal" href="#misery" id="id129">misery</a></li>
<li><a class="reference internal" href="#strangemood" id="id128">strangemood</a></li> <li><a class="reference internal" href="#strangemood" id="id130">strangemood</a></li>
<li><a class="reference internal" href="#log-region" id="id131">log-region</a></li>
</ul> </ul>
</li> </li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#scripts" id="id129">Scripts</a><ul> <li><a class="reference internal" href="#scripts" id="id132">Scripts</a><ul>
<li><a class="reference internal" href="#fix" id="id130">fix/*</a></li> <li><a class="reference internal" href="#fix" id="id133">fix/*</a></li>
<li><a class="reference internal" href="#gui" id="id131">gui/*</a></li> <li><a class="reference internal" href="#gui" id="id134">gui/*</a></li>
<li><a class="reference internal" href="#binpatch" id="id132">binpatch</a></li> <li><a class="reference internal" href="#binpatch" id="id135">binpatch</a></li>
<li><a class="reference internal" href="#quicksave" id="id133">quicksave</a></li> <li><a class="reference internal" href="#quicksave" id="id136">quicksave</a></li>
<li><a class="reference internal" href="#setfps" id="id134">setfps</a></li> <li><a class="reference internal" href="#setfps" id="id137">setfps</a></li>
<li><a class="reference internal" href="#siren" id="id135">siren</a></li> <li><a class="reference internal" href="#siren" id="id138">siren</a></li>
<li><a class="reference internal" href="#growcrops" id="id136">growcrops</a></li> <li><a class="reference internal" href="#growcrops" id="id139">growcrops</a></li>
<li><a class="reference internal" href="#removebadthoughts" id="id137">removebadthoughts</a></li> <li><a class="reference internal" href="#removebadthoughts" id="id140">removebadthoughts</a></li>
<li><a class="reference internal" href="#exterminate" id="id138">exterminate</a></li> <li><a class="reference internal" href="#exterminate" id="id141">exterminate</a></li>
<li><a class="reference internal" href="#source" id="id139">source</a></li> <li><a class="reference internal" href="#source" id="id142">source</a></li>
<li><a class="reference internal" href="#masspit" id="id140">masspit</a></li> <li><a class="reference internal" href="#masspit" id="id143">masspit</a></li>
<li><a class="reference internal" href="#digfort" id="id141">digfort</a></li> <li><a class="reference internal" href="#digfort" id="id144">digfort</a></li>
<li><a class="reference internal" href="#invasion-now" id="id142">invasion-now</a></li> <li><a class="reference internal" href="#invasion-now" id="id145">invasion-now</a></li>
<li><a class="reference internal" href="#digmat" id="id143">digmat</a></li> <li><a class="reference internal" href="#digmat" id="id146">digmat</a></li>
<li><a class="reference internal" href="#superdwarf" id="id144">superdwarf</a></li> <li><a class="reference internal" href="#superdwarf" id="id147">superdwarf</a></li>
<li><a class="reference internal" href="#drainaquifer" id="id145">drainaquifer</a></li> <li><a class="reference internal" href="#drainaquifer" id="id148">drainaquifer</a></li>
<li><a class="reference internal" href="#deathcause" id="id146">deathcause</a></li> <li><a class="reference internal" href="#deathcause" id="id149">deathcause</a></li>
<li><a class="reference internal" href="#lua" id="id147">lua</a></li> <li><a class="reference internal" href="#lua" id="id150">lua</a></li>
<li><a class="reference internal" href="#embark" id="id148">embark</a></li> <li><a class="reference internal" href="#embark" id="id151">embark</a></li>
<li><a class="reference internal" href="#lever" id="id149">lever</a></li> <li><a class="reference internal" href="#lever" id="id152">lever</a></li>
<li><a class="reference internal" href="#stripcaged" id="id150">stripcaged</a></li> <li><a class="reference internal" href="#stripcaged" id="id153">stripcaged</a></li>
<li><a class="reference internal" href="#undump-buildings" id="id151">undump-buildings</a></li> <li><a class="reference internal" href="#undump-buildings" id="id154">undump-buildings</a></li>
<li><a class="reference internal" href="#create-items" id="id152">create-items</a></li> <li><a class="reference internal" href="#create-items" id="id155">create-items</a></li>
<li><a class="reference internal" href="#locate-ore" id="id153">locate-ore</a></li> <li><a class="reference internal" href="#locate-ore" id="id156">locate-ore</a></li>
<li><a class="reference internal" href="#soundsense-season" id="id154">soundsense-season</a></li> <li><a class="reference internal" href="#soundsense-season" id="id157">soundsense-season</a></li>
<li><a class="reference internal" href="#multicmd" id="id155">multicmd</a></li> <li><a class="reference internal" href="#multicmd" id="id158">multicmd</a></li>
<li><a class="reference internal" href="#dfstatus" id="id159">dfstatus</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#in-game-interface-tools" id="id156">In-game interface tools</a><ul> <li><a class="reference internal" href="#in-game-interface-tools" id="id160">In-game interface tools</a><ul>
<li><a class="reference internal" href="#dwarf-manipulator" id="id157">Dwarf Manipulator</a></li> <li><a class="reference internal" href="#dwarf-manipulator" id="id161">Dwarf Manipulator</a></li>
<li><a class="reference internal" href="#search" id="id158">Search</a></li> <li><a class="reference internal" href="#search" id="id162">Search</a></li>
<li><a class="reference internal" href="#automaterial" id="id159">AutoMaterial</a></li> <li><a class="reference internal" href="#automaterial" id="id163">AutoMaterial</a></li>
<li><a class="reference internal" href="#gui-liquids" id="id160">gui/liquids</a></li> <li><a class="reference internal" href="#gui-liquids" id="id164">gui/liquids</a></li>
<li><a class="reference internal" href="#gui-mechanisms" id="id161">gui/mechanisms</a></li> <li><a class="reference internal" href="#gui-mechanisms" id="id165">gui/mechanisms</a></li>
<li><a class="reference internal" href="#gui-rename" id="id162">gui/rename</a></li> <li><a class="reference internal" href="#gui-rename" id="id166">gui/rename</a></li>
<li><a class="reference internal" href="#gui-room-list" id="id163">gui/room-list</a></li> <li><a class="reference internal" href="#gui-room-list" id="id167">gui/room-list</a></li>
<li><a class="reference internal" href="#gui-choose-weapons" id="id164">gui/choose-weapons</a></li> <li><a class="reference internal" href="#gui-choose-weapons" id="id168">gui/choose-weapons</a></li>
<li><a class="reference internal" href="#gui-clone-uniform" id="id165">gui/clone-uniform</a></li> <li><a class="reference internal" href="#gui-clone-uniform" id="id169">gui/clone-uniform</a></li>
<li><a class="reference internal" href="#gui-guide-path" id="id166">gui/guide-path</a></li> <li><a class="reference internal" href="#gui-guide-path" id="id170">gui/guide-path</a></li>
<li><a class="reference internal" href="#gui-workshop-job" id="id167">gui/workshop-job</a></li> <li><a class="reference internal" href="#gui-workshop-job" id="id171">gui/workshop-job</a></li>
<li><a class="reference internal" href="#gui-workflow" id="id168">gui/workflow</a></li> <li><a class="reference internal" href="#gui-workflow" id="id172">gui/workflow</a></li>
<li><a class="reference internal" href="#gui-assign-rack" id="id169">gui/assign-rack</a></li> <li><a class="reference internal" href="#gui-assign-rack" id="id173">gui/assign-rack</a></li>
<li><a class="reference internal" href="#gui-advfort" id="id170">gui/advfort</a></li> <li><a class="reference internal" href="#gui-advfort" id="id174">gui/advfort</a></li>
<li><a class="reference internal" href="#gui-companion-order" id="id171">gui/companion-order</a></li> <li><a class="reference internal" href="#gui-companion-order" id="id175">gui/companion-order</a></li>
<li><a class="reference internal" href="#gui-gm-editor" id="id172">gui/gm-editor</a></li> <li><a class="reference internal" href="#gui-gm-editor" id="id176">gui/gm-editor</a></li>
<li><a class="reference internal" href="#gui-mod-manager" id="id173">gui/mod-manager</a></li> <li><a class="reference internal" href="#gui-mod-manager" id="id177">gui/mod-manager</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#behavior-mods" id="id174">Behavior Mods</a><ul> <li><a class="reference internal" href="#behavior-mods" id="id178">Behavior Mods</a><ul>
<li><a class="reference internal" href="#siege-engine" id="id175">Siege Engine</a><ul> <li><a class="reference internal" href="#siege-engine" id="id179">Siege Engine</a><ul>
<li><a class="reference internal" href="#rationale" id="id176">Rationale</a></li> <li><a class="reference internal" href="#rationale" id="id180">Rationale</a></li>
<li><a class="reference internal" href="#configuration-ui" id="id177">Configuration UI</a></li> <li><a class="reference internal" href="#configuration-ui" id="id181">Configuration UI</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#power-meter" id="id178">Power Meter</a></li> <li><a class="reference internal" href="#power-meter" id="id182">Power Meter</a></li>
<li><a class="reference internal" href="#steam-engine" id="id179">Steam Engine</a><ul> <li><a class="reference internal" href="#steam-engine" id="id183">Steam Engine</a><ul>
<li><a class="reference internal" href="#id1" id="id180">Rationale</a></li> <li><a class="reference internal" href="#id1" id="id184">Rationale</a></li>
<li><a class="reference internal" href="#construction" id="id181">Construction</a></li> <li><a class="reference internal" href="#construction" id="id185">Construction</a></li>
<li><a class="reference internal" href="#operation" id="id182">Operation</a></li> <li><a class="reference internal" href="#operation" id="id186">Operation</a></li>
<li><a class="reference internal" href="#explosions" id="id183">Explosions</a></li> <li><a class="reference internal" href="#explosions" id="id187">Explosions</a></li>
<li><a class="reference internal" href="#save-files" id="id184">Save files</a></li> <li><a class="reference internal" href="#save-files" id="id188">Save files</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#add-spatter" id="id185">Add Spatter</a></li> <li><a class="reference internal" href="#add-spatter" id="id189">Add Spatter</a></li>
</ul> </ul>
</li> </li>
</ul> </ul>
@ -2354,11 +2358,28 @@ with visualizers.</p>
<h3><a class="toc-backref" href="#id103">dwarfexport</a></h3> <h3><a class="toc-backref" href="#id103">dwarfexport</a></h3>
<p>Export dwarves to RuneSmith-compatible XML.</p> <p>Export dwarves to RuneSmith-compatible XML.</p>
</div> </div>
<div class="section" id="exportlegends">
<h3><a class="toc-backref" href="#id104">exportlegends</a></h3>
<p>Exports data from legends mode; allowing a set-and-forget export of large worlds.</p>
<p>Options:</p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">maps:</th><td class="field-body">Exports all fifteen detailed maps</td>
</tr>
<tr class="field"><th class="field-name">all:</th><td class="field-body">first exports the world/gen info, then the XML, then all detailed maps</td>
</tr>
</tbody>
</table>
</blockquote>
</div>
</div> </div>
<div class="section" id="job-management"> <div class="section" id="job-management">
<h2><a class="toc-backref" href="#id104">Job management</a></h2> <h2><a class="toc-backref" href="#id105">Job management</a></h2>
<div class="section" id="job"> <div class="section" id="job">
<h3><a class="toc-backref" href="#id105">job</a></h3> <h3><a class="toc-backref" href="#id106">job</a></h3>
<p>Command for general job query and manipulation.</p> <p>Command for general job query and manipulation.</p>
<dl class="docutils"> <dl class="docutils">
<dt>Options:</dt> <dt>Options:</dt>
@ -2377,7 +2398,7 @@ in a workshop, or the unit/jobs screen.</dd>
</dl> </dl>
</div> </div>
<div class="section" id="job-material"> <div class="section" id="job-material">
<h3><a class="toc-backref" href="#id106">job-material</a></h3> <h3><a class="toc-backref" href="#id107">job-material</a></h3>
<p>Alter the material of the selected job.</p> <p>Alter the material of the selected job.</p>
<p>Invoked as:</p> <p>Invoked as:</p>
<pre class="literal-block"> <pre class="literal-block">
@ -2395,7 +2416,7 @@ over the first available choice with the matching material.</li>
</blockquote> </blockquote>
</div> </div>
<div class="section" id="job-duplicate"> <div class="section" id="job-duplicate">
<h3><a class="toc-backref" href="#id107">job-duplicate</a></h3> <h3><a class="toc-backref" href="#id108">job-duplicate</a></h3>
<dl class="docutils"> <dl class="docutils">
<dt>Duplicate the selected job in a workshop:</dt> <dt>Duplicate the selected job in a workshop:</dt>
<dd><ul class="first last simple"> <dd><ul class="first last simple">
@ -2405,8 +2426,36 @@ instantly duplicates the job.</li>
</dd> </dd>
</dl> </dl>
</div> </div>
<div class="section" id="stockflow">
<h3><a class="toc-backref" href="#id109">stockflow</a></h3>
<p>Allows the fortress bookkeeper to queue jobs through the manager.</p>
<p>Usage:</p>
<blockquote>
<dl class="docutils">
<dt><tt class="docutils literal">stockflow enable</tt></dt>
<dd>Enable the plugin.</dd>
<dt><tt class="docutils literal">stockflow disable</tt></dt>
<dd>Disable the plugin.</dd>
<dt><tt class="docutils literal">stockflow list</tt></dt>
<dd>List any work order settings for your stockpiles.</dd>
<dt><tt class="docutils literal">stockflow status</tt></dt>
<dd>Display whether the plugin is enabled.</dd>
</dl>
</blockquote>
<dl class="docutils">
<dt>While enabled, the 'q' menu of each stockpile will have two new options:</dt>
<dd><ul class="first last simple">
<li>j: Select a job to order, from an interface like the manager's screen.</li>
<li>J: Cycle between several options for how many such jobs to order.</li>
</ul>
</dd>
</dl>
<p>Whenever the bookkeeper updates stockpile records, new work orders will
be placed on the manager's queue for each such selection, reduced by the
number of identical orders already in the queue.</p>
</div>
<div class="section" id="workflow"> <div class="section" id="workflow">
<h3><a class="toc-backref" href="#id108">workflow</a></h3> <h3><a class="toc-backref" href="#id110">workflow</a></h3>
<p>Manage control of repeat jobs.</p> <p>Manage control of repeat jobs.</p>
<p>Usage:</p> <p>Usage:</p>
<blockquote> <blockquote>
@ -2438,7 +2487,7 @@ this list can be copied to a file, and then reloaded using the
</dl> </dl>
</blockquote> </blockquote>
<div class="section" id="function"> <div class="section" id="function">
<h4><a class="toc-backref" href="#id109">Function</a></h4> <h4><a class="toc-backref" href="#id111">Function</a></h4>
<p>When the plugin is enabled, it protects all repeat jobs from removal. <p>When the plugin is enabled, it protects all repeat jobs from removal.
If they do disappear due to any cause, they are immediately re-added to their If they do disappear due to any cause, they are immediately re-added to their
workshop and suspended.</p> workshop and suspended.</p>
@ -2451,7 +2500,7 @@ the frequency of jobs being toggled.</p>
in the game UI.</p> in the game UI.</p>
</div> </div>
<div class="section" id="constraint-format"> <div class="section" id="constraint-format">
<h4><a class="toc-backref" href="#id110">Constraint format</a></h4> <h4><a class="toc-backref" href="#id112">Constraint format</a></h4>
<p>The contstraint spec consists of 4 parts, separated with '/' characters:</p> <p>The contstraint spec consists of 4 parts, separated with '/' characters:</p>
<pre class="literal-block"> <pre class="literal-block">
ITEM[:SUBTYPE]/[GENERIC_MAT,...]/[SPECIFIC_MAT:...]/[LOCAL,&lt;quality&gt;] ITEM[:SUBTYPE]/[GENERIC_MAT,...]/[SPECIFIC_MAT:...]/[LOCAL,&lt;quality&gt;]
@ -2480,7 +2529,7 @@ be used to ignore imported items or items below a certain quality.</p>
</ul> </ul>
</div> </div>
<div class="section" id="constraint-examples"> <div class="section" id="constraint-examples">
<h4><a class="toc-backref" href="#id111">Constraint examples</a></h4> <h4><a class="toc-backref" href="#id113">Constraint examples</a></h4>
<p>Keep metal bolts within 900-1000, and wood/bone within 150-200.</p> <p>Keep metal bolts within 900-1000, and wood/bone within 150-200.</p>
<pre class="literal-block"> <pre class="literal-block">
workflow amount AMMO:ITEM_AMMO_BOLTS/METAL 1000 100 workflow amount AMMO:ITEM_AMMO_BOLTS/METAL 1000 100
@ -2529,15 +2578,15 @@ workflow count CRAFTS///LOCAL,EXCEPTIONAL 100 90
</div> </div>
</div> </div>
<div class="section" id="fortress-activity-management"> <div class="section" id="fortress-activity-management">
<h2><a class="toc-backref" href="#id112">Fortress activity management</a></h2> <h2><a class="toc-backref" href="#id114">Fortress activity management</a></h2>
<div class="section" id="seedwatch"> <div class="section" id="seedwatch">
<h3><a class="toc-backref" href="#id113">seedwatch</a></h3> <h3><a class="toc-backref" href="#id115">seedwatch</a></h3>
<p>Tool for turning cooking of seeds and plants on/off depending on how much you <p>Tool for turning cooking of seeds and plants on/off depending on how much you
have of them.</p> have of them.</p>
<p>See 'seedwatch help' for detailed description.</p> <p>See 'seedwatch help' for detailed description.</p>
</div> </div>
<div class="section" id="zone"> <div class="section" id="zone">
<h3><a class="toc-backref" href="#id114">zone</a></h3> <h3><a class="toc-backref" href="#id116">zone</a></h3>
<p>Helps a bit with managing activity zones (pens, pastures and pits) and cages.</p> <p>Helps a bit with managing activity zones (pens, pastures and pits) and cages.</p>
<p>Options:</p> <p>Options:</p>
<blockquote> <blockquote>
@ -2636,7 +2685,7 @@ for war/hunt). Negatable.</td>
</table> </table>
</blockquote> </blockquote>
<div class="section" id="usage-with-single-units"> <div class="section" id="usage-with-single-units">
<h4><a class="toc-backref" href="#id115">Usage with single units</a></h4> <h4><a class="toc-backref" href="#id117">Usage with single units</a></h4>
<p>One convenient way to use the zone tool is to bind the command 'zone assign' to <p>One convenient way to use the zone tool is to bind the command 'zone assign' to
a hotkey, maybe also the command 'zone set'. Place the in-game cursor over a hotkey, maybe also the command 'zone set'. Place the in-game cursor over
a pen/pasture or pit, use 'zone set' to mark it. Then you can select units a pen/pasture or pit, use 'zone set' to mark it. Then you can select units
@ -2645,7 +2694,7 @@ and use 'zone assign' to assign them to their new home. Allows pitting your
own dwarves, by the way.</p> own dwarves, by the way.</p>
</div> </div>
<div class="section" id="usage-with-filters"> <div class="section" id="usage-with-filters">
<h4><a class="toc-backref" href="#id116">Usage with filters</a></h4> <h4><a class="toc-backref" href="#id118">Usage with filters</a></h4>
<p>All filters can be used together with the 'assign' command.</p> <p>All filters can be used together with the 'assign' command.</p>
<p>Restrictions: It's not possible to assign units who are inside built cages <p>Restrictions: It's not possible to assign units who are inside built cages
or chained because in most cases that won't be desirable anyways. or chained because in most cases that won't be desirable anyways.
@ -2663,14 +2712,14 @@ are not properly added to your own stocks; slaughtering them should work).</p>
<p>Most filters can be negated (e.g. 'not grazer' -&gt; race is not a grazer).</p> <p>Most filters can be negated (e.g. 'not grazer' -&gt; race is not a grazer).</p>
</div> </div>
<div class="section" id="mass-renaming"> <div class="section" id="mass-renaming">
<h4><a class="toc-backref" href="#id117">Mass-renaming</a></h4> <h4><a class="toc-backref" href="#id119">Mass-renaming</a></h4>
<p>Using the 'nick' command you can set the same nickname for multiple units. <p>Using the 'nick' command you can set the same nickname for multiple units.
If used without 'assign', 'all' or 'count' it will rename all units in the If used without 'assign', 'all' or 'count' it will rename all units in the
current default target zone. Combined with 'assign', 'all' or 'count' (and current default target zone. Combined with 'assign', 'all' or 'count' (and
further optional filters) it will rename units matching the filter conditions.</p> further optional filters) it will rename units matching the filter conditions.</p>
</div> </div>
<div class="section" id="cage-zones"> <div class="section" id="cage-zones">
<h4><a class="toc-backref" href="#id118">Cage zones</a></h4> <h4><a class="toc-backref" href="#id120">Cage zones</a></h4>
<p>Using the 'tocages' command you can assign units to a set of cages, for example <p>Using the 'tocages' command you can assign units to a set of cages, for example
a room next to your butcher shop(s). They will be spread evenly among available a room next to your butcher shop(s). They will be spread evenly among available
cages to optimize hauling to and butchering from them. For this to work you need cages to optimize hauling to and butchering from them. For this to work you need
@ -2681,7 +2730,7 @@ would make no sense, but can be used together with 'nick' or 'remnick' and all
the usual filters.</p> the usual filters.</p>
</div> </div>
<div class="section" id="examples"> <div class="section" id="examples">
<h4><a class="toc-backref" href="#id119">Examples</a></h4> <h4><a class="toc-backref" href="#id121">Examples</a></h4>
<dl class="docutils"> <dl class="docutils">
<dt><tt class="docutils literal">zone assign all own ALPACA minage 3 maxage 10</tt></dt> <dt><tt class="docutils literal">zone assign all own ALPACA minage 3 maxage 10</tt></dt>
<dd>Assign all own alpacas who are between 3 and 10 years old to the selected <dd>Assign all own alpacas who are between 3 and 10 years old to the selected
@ -2707,7 +2756,7 @@ on the current default zone.</dd>
</div> </div>
</div> </div>
<div class="section" id="autonestbox"> <div class="section" id="autonestbox">
<h3><a class="toc-backref" href="#id120">autonestbox</a></h3> <h3><a class="toc-backref" href="#id122">autonestbox</a></h3>
<p>Assigns unpastured female egg-layers to nestbox zones. Requires that you create <p>Assigns unpastured female egg-layers to nestbox zones. Requires that you create
pen/pasture zones above nestboxes. If the pen is bigger than 1x1 the nestbox pen/pasture zones above nestboxes. If the pen is bigger than 1x1 the nestbox
must be in the top left corner. Only 1 unit will be assigned per pen, regardless must be in the top left corner. Only 1 unit will be assigned per pen, regardless
@ -2736,7 +2785,7 @@ frames between runs.</td>
</blockquote> </blockquote>
</div> </div>
<div class="section" id="autobutcher"> <div class="section" id="autobutcher">
<h3><a class="toc-backref" href="#id121">autobutcher</a></h3> <h3><a class="toc-backref" href="#id123">autobutcher</a></h3>
<p>Assigns lifestock for slaughter once it reaches a specific count. Requires that <p>Assigns lifestock for slaughter once it reaches a specific count. Requires that
you add the target race(s) to a watch list. Only tame units will be processed.</p> you add the target race(s) to a watch list. Only tame units will be processed.</p>
<p>Named units will be completely ignored (to protect specific animals from <p>Named units will be completely ignored (to protect specific animals from
@ -2844,7 +2893,7 @@ autobutcher.bat
</pre> </pre>
</div> </div>
<div class="section" id="autochop"> <div class="section" id="autochop">
<h3><a class="toc-backref" href="#id122">autochop</a></h3> <h3><a class="toc-backref" href="#id124">autochop</a></h3>
<p>Automatically manage tree cutting designation to keep available logs withing given <p>Automatically manage tree cutting designation to keep available logs withing given
quotas.</p> quotas.</p>
<p>Open the dashboard by running:</p> <p>Open the dashboard by running:</p>
@ -2862,7 +2911,7 @@ enable getplants
menu.</p> menu.</p>
</div> </div>
<div class="section" id="autolabor"> <div class="section" id="autolabor">
<h3><a class="toc-backref" href="#id123">autolabor</a></h3> <h3><a class="toc-backref" href="#id125">autolabor</a></h3>
<p>Automatically manage dwarf labors.</p> <p>Automatically manage dwarf labors.</p>
<p>When enabled, autolabor periodically checks your dwarves and enables or <p>When enabled, autolabor periodically checks your dwarves and enables or
disables labors. It tries to keep as many dwarves as possible busy but disables labors. It tries to keep as many dwarves as possible busy but
@ -2877,14 +2926,14 @@ while it is enabled.</p>
</div> </div>
</div> </div>
<div class="section" id="other"> <div class="section" id="other">
<h2><a class="toc-backref" href="#id124">Other</a></h2> <h2><a class="toc-backref" href="#id126">Other</a></h2>
<div class="section" id="catsplosion"> <div class="section" id="catsplosion">
<h3><a class="toc-backref" href="#id125">catsplosion</a></h3> <h3><a class="toc-backref" href="#id127">catsplosion</a></h3>
<p>Makes cats just <em>multiply</em>. It is not a good idea to run this more than once or <p>Makes cats just <em>multiply</em>. It is not a good idea to run this more than once or
twice.</p> twice.</p>
</div> </div>
<div class="section" id="dfusion"> <div class="section" id="dfusion">
<h3><a class="toc-backref" href="#id126">dfusion</a></h3> <h3><a class="toc-backref" href="#id128">dfusion</a></h3>
<dl class="docutils"> <dl class="docutils">
<dt>This is the DFusion lua plugin system by Warmist, running as a DFHack plugin. There are two parts to this plugin: an interactive script that shows a text based menu and lua modules. Some of the functionality of is intentionaly left out of the menu:</dt> <dt>This is the DFusion lua plugin system by Warmist, running as a DFHack plugin. There are two parts to this plugin: an interactive script that shows a text based menu and lua modules. Some of the functionality of is intentionaly left out of the menu:</dt>
<dd><table class="first last docutils field-list" frame="void" rules="none"> <dd><table class="first last docutils field-list" frame="void" rules="none">
@ -2909,7 +2958,7 @@ twice.</p>
</div> </div>
</div> </div>
<div class="section" id="misery"> <div class="section" id="misery">
<h3><a class="toc-backref" href="#id127">misery</a></h3> <h3><a class="toc-backref" href="#id129">misery</a></h3>
<p>When enabled, every new negative dwarven thought will be multiplied by a factor (2 by default).</p> <p>When enabled, every new negative dwarven thought will be multiplied by a factor (2 by default).</p>
<p>Usage:</p> <p>Usage:</p>
<table class="docutils field-list" frame="void" rules="none"> <table class="docutils field-list" frame="void" rules="none">
@ -2931,7 +2980,7 @@ twice.</p>
</table> </table>
</div> </div>
<div class="section" id="strangemood"> <div class="section" id="strangemood">
<h3><a class="toc-backref" href="#id128">strangemood</a></h3> <h3><a class="toc-backref" href="#id130">strangemood</a></h3>
<p>Creates a strange mood job the same way the game itself normally does it.</p> <p>Creates a strange mood job the same way the game itself normally does it.</p>
<p>Options:</p> <p>Options:</p>
<blockquote> <blockquote>
@ -2954,10 +3003,14 @@ Valid values are &quot;miner&quot;, &quot;carpenter&quot;, &quot;engraver&quot;,
</blockquote> </blockquote>
<p>Known limitations: if the selected unit is currently performing a job, the mood will not be started.</p> <p>Known limitations: if the selected unit is currently performing a job, the mood will not be started.</p>
</div> </div>
<div class="section" id="log-region">
<h3><a class="toc-backref" href="#id131">log-region</a></h3>
<p>When enabled in dfhack.init, each time a fort is loaded identifying information will be written to the gamelog. Assists in parsing the file if you switch between forts, and adds information for story-building.</p>
</div>
</div> </div>
</div> </div>
<div class="section" id="scripts"> <div class="section" id="scripts">
<h1><a class="toc-backref" href="#id129">Scripts</a></h1> <h1><a class="toc-backref" href="#id132">Scripts</a></h1>
<p>Lua or ruby scripts placed in the hack/scripts/ directory are considered for <p>Lua or ruby scripts placed in the hack/scripts/ directory are considered for
execution as if they were native DFHack commands. They are listed at the end execution as if they were native DFHack commands. They are listed at the end
of the 'ls' command output.</p> of the 'ls' command output.</p>
@ -2966,7 +3019,7 @@ only be listed by ls if called as 'ls -a'. This is intended as a way to hide
scripts that are obscure, developer-oriented, or should be used as keybindings.</p> scripts that are obscure, developer-oriented, or should be used as keybindings.</p>
<p>Some notable scripts:</p> <p>Some notable scripts:</p>
<div class="section" id="fix"> <div class="section" id="fix">
<h2><a class="toc-backref" href="#id130">fix/*</a></h2> <h2><a class="toc-backref" href="#id133">fix/*</a></h2>
<p>Scripts in this subdirectory fix various bugs and issues, some of them obscure.</p> <p>Scripts in this subdirectory fix various bugs and issues, some of them obscure.</p>
<ul> <ul>
<li><p class="first">fix/dead-units</p> <li><p class="first">fix/dead-units</p>
@ -3003,12 +3056,12 @@ hopefully avoid jamming it again, and unsuspends them.</p>
</ul> </ul>
</div> </div>
<div class="section" id="gui"> <div class="section" id="gui">
<h2><a class="toc-backref" href="#id131">gui/*</a></h2> <h2><a class="toc-backref" href="#id134">gui/*</a></h2>
<p>Scripts that implement dialogs inserted into the main game window are put in this <p>Scripts that implement dialogs inserted into the main game window are put in this
directory.</p> directory.</p>
</div> </div>
<div class="section" id="binpatch"> <div class="section" id="binpatch">
<h2><a class="toc-backref" href="#id132">binpatch</a></h2> <h2><a class="toc-backref" href="#id135">binpatch</a></h2>
<p>Checks, applies or removes binary patches directly in memory at runtime:</p> <p>Checks, applies or removes binary patches directly in memory at runtime:</p>
<pre class="literal-block"> <pre class="literal-block">
binpatch check/apply/remove &lt;patchname&gt; binpatch check/apply/remove &lt;patchname&gt;
@ -3018,17 +3071,17 @@ script uses <tt class="docutils literal"><span class="pre">hack/patches/&lt;df-v
the version appropriate for the currently loaded executable.</p> the version appropriate for the currently loaded executable.</p>
</div> </div>
<div class="section" id="quicksave"> <div class="section" id="quicksave">
<h2><a class="toc-backref" href="#id133">quicksave</a></h2> <h2><a class="toc-backref" href="#id136">quicksave</a></h2>
<p>If called in dwarf mode, makes DF immediately auto-save the game by setting a flag <p>If called in dwarf mode, makes DF immediately auto-save the game by setting a flag
normally used in seasonal auto-save.</p> normally used in seasonal auto-save.</p>
</div> </div>
<div class="section" id="setfps"> <div class="section" id="setfps">
<h2><a class="toc-backref" href="#id134">setfps</a></h2> <h2><a class="toc-backref" href="#id137">setfps</a></h2>
<p>Run <tt class="docutils literal">setfps &lt;number&gt;</tt> to set the FPS cap at runtime, in case you want to watch <p>Run <tt class="docutils literal">setfps &lt;number&gt;</tt> to set the FPS cap at runtime, in case you want to watch
combat in slow motion or something :)</p> combat in slow motion or something :)</p>
</div> </div>
<div class="section" id="siren"> <div class="section" id="siren">
<h2><a class="toc-backref" href="#id135">siren</a></h2> <h2><a class="toc-backref" href="#id138">siren</a></h2>
<p>Wakes up sleeping units, cancels breaks and stops parties either everywhere, <p>Wakes up sleeping units, cancels breaks and stops parties either everywhere,
or in the burrows given as arguments. In return, adds bad thoughts about or in the burrows given as arguments. In return, adds bad thoughts about
noise, tiredness and lack of protection. Also, the units with interrupted noise, tiredness and lack of protection. Also, the units with interrupted
@ -3036,7 +3089,7 @@ breaks will go on break again a lot sooner. The script is intended for
emergencies, e.g. when a siege appears, and all your military is partying.</p> emergencies, e.g. when a siege appears, and all your military is partying.</p>
</div> </div>
<div class="section" id="growcrops"> <div class="section" id="growcrops">
<h2><a class="toc-backref" href="#id136">growcrops</a></h2> <h2><a class="toc-backref" href="#id139">growcrops</a></h2>
<p>Instantly grow seeds inside farming plots.</p> <p>Instantly grow seeds inside farming plots.</p>
<p>With no argument, this command list the various seed types currently in <p>With no argument, this command list the various seed types currently in
use in your farming plots. use in your farming plots.
@ -3048,7 +3101,7 @@ growcrops plump 40
</pre> </pre>
</div> </div>
<div class="section" id="removebadthoughts"> <div class="section" id="removebadthoughts">
<h2><a class="toc-backref" href="#id137">removebadthoughts</a></h2> <h2><a class="toc-backref" href="#id140">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>The script can target a single creature, when used with the <tt class="docutils literal">him</tt> argument, <p>The script can target a single creature, when used with the <tt class="docutils literal">him</tt> argument,
@ -3062,7 +3115,7 @@ but in the short term your dwarves will get much more joyful.</p>
quickly after you unpause.</p> quickly after you unpause.</p>
</div> </div>
<div class="section" id="exterminate"> <div class="section" id="exterminate">
<h2><a class="toc-backref" href="#id138">exterminate</a></h2> <h2><a class="toc-backref" href="#id141">exterminate</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 and count eligible targets.</p> <p>With no argument, lists the available races and count eligible targets.</p>
<p>With the special argument <tt class="docutils literal">him</tt>, targets only the selected creature.</p> <p>With the special argument <tt class="docutils literal">him</tt>, targets only the selected creature.</p>
@ -3094,7 +3147,7 @@ exterminate elve magma
</pre> </pre>
</div> </div>
<div class="section" id="source"> <div class="section" id="source">
<h2><a class="toc-backref" href="#id139">source</a></h2> <h2><a class="toc-backref" href="#id142">source</a></h2>
<p>Create an infinite magma or water source or drain on a tile.</p> <p>Create an infinite magma or water source or drain on a tile.</p>
<p>This script registers a map tile as a liquid source, and every 12 game ticks <p>This script registers a map tile as a liquid source, and every 12 game ticks
that tile receives or remove 1 new unit of flow based on the configuration.</p> that tile receives or remove 1 new unit of flow based on the configuration.</p>
@ -3116,14 +3169,14 @@ source add water 0 - water drain
</pre> </pre>
</div> </div>
<div class="section" id="masspit"> <div class="section" id="masspit">
<h2><a class="toc-backref" href="#id140">masspit</a></h2> <h2><a class="toc-backref" href="#id143">masspit</a></h2>
<p>Designate all creatures in cages on top of a pit/pond activity zone for pitting. <p>Designate all creatures in cages on top of a pit/pond activity zone for pitting.
Works best with an animal stockpile on top of the zone.</p> Works best with an animal stockpile on top of the zone.</p>
<p>Works with a zone number as argument (eg <tt class="docutils literal">Activity Zone #6</tt> -&gt; <tt class="docutils literal">masspit 6</tt>) <p>Works with a zone number as argument (eg <tt class="docutils literal">Activity Zone #6</tt> -&gt; <tt class="docutils literal">masspit 6</tt>)
or with the game cursor on top of the area.</p> or with the game cursor on top of the area.</p>
</div> </div>
<div class="section" id="digfort"> <div class="section" id="digfort">
<h2><a class="toc-backref" href="#id141">digfort</a></h2> <h2><a class="toc-backref" href="#id144">digfort</a></h2>
<p>A script to designate an area for digging according to a plan in csv format.</p> <p>A script to designate an area for digging according to a plan in csv format.</p>
<p>This script, inspired from quickfort, can designate an area for digging. <p>This script, inspired from quickfort, can designate an area for digging.
Your plan should be stored in a .csv file like this:</p> Your plan should be stored in a .csv file like this:</p>
@ -3145,7 +3198,7 @@ as an offset for the pattern: instead of starting at the cursor, it will start
Dwarf Fortress.exe is found).</p> Dwarf Fortress.exe is found).</p>
</div> </div>
<div class="section" id="invasion-now"> <div class="section" id="invasion-now">
<h2><a class="toc-backref" href="#id142">invasion-now</a></h2> <h2><a class="toc-backref" href="#id145">invasion-now</a></h2>
<p>Triggers an invasion, or several in the near future.</p> <p>Triggers an invasion, or several in the near future.</p>
<p><cite>invasion-now civName</cite> trigger an invasion from the civilization with the id civName, starting in about ten ticks</p> <p><cite>invasion-now civName</cite> trigger an invasion from the civilization with the id civName, starting in about ten ticks</p>
<p><cite>invasion-now civName start</cite> trigger an invasion from civName in a number of ticks between 10*start and 11*start-1 (inclusive)</p> <p><cite>invasion-now civName start</cite> trigger an invasion from civName in a number of ticks between 10*start and 11*start-1 (inclusive)</p>
@ -3153,7 +3206,7 @@ Dwarf Fortress.exe is found).</p>
<p>Probably fails if the start time of a triggered invasion is later than the start of the next year.</p> <p>Probably fails if the start time of a triggered invasion is later than the start of the next year.</p>
</div> </div>
<div class="section" id="digmat"> <div class="section" id="digmat">
<h2><a class="toc-backref" href="#id143">digmat</a></h2> <h2><a class="toc-backref" href="#id146">digmat</a></h2>
<p>Designates a tile for digging. Monitors the tile, and when it is dug out, add <p>Designates a tile for digging. Monitors the tile, and when it is dug out, add
surrounding discovered tiles of the same material for digging. Similar to 'digv', surrounding discovered tiles of the same material for digging. Similar to 'digv',
but less cheaty. Works for stone layers, soil layers, veins, etc.</p> but less cheaty. Works for stone layers, soil layers, veins, etc.</p>
@ -3162,7 +3215,7 @@ same designation for future digging (eg dig up/downstairs). When digging stairs,
also designate tiles on z-1 and z+1 when they are discovered.</p> also designate tiles on z-1 and z+1 when they are discovered.</p>
</div> </div>
<div class="section" id="superdwarf"> <div class="section" id="superdwarf">
<h2><a class="toc-backref" href="#id144">superdwarf</a></h2> <h2><a class="toc-backref" href="#id147">superdwarf</a></h2>
<p>Similar to fastdwarf, per-creature.</p> <p>Similar to fastdwarf, per-creature.</p>
<p>To make any creature superfast, target it ingame using 'v' and:</p> <p>To make any creature superfast, target it ingame using 'v' and:</p>
<pre class="literal-block"> <pre class="literal-block">
@ -3172,17 +3225,17 @@ superdwarf add
<p>This plugin also shortens the 'sleeping' and 'on break' periods of targets.</p> <p>This plugin also shortens the 'sleeping' and 'on break' periods of targets.</p>
</div> </div>
<div class="section" id="drainaquifer"> <div class="section" id="drainaquifer">
<h2><a class="toc-backref" href="#id145">drainaquifer</a></h2> <h2><a class="toc-backref" href="#id148">drainaquifer</a></h2>
<p>Remove all 'aquifer' tag from the map blocks. Irreversible.</p> <p>Remove all 'aquifer' tag from the map blocks. Irreversible.</p>
</div> </div>
<div class="section" id="deathcause"> <div class="section" id="deathcause">
<h2><a class="toc-backref" href="#id146">deathcause</a></h2> <h2><a class="toc-backref" href="#id149">deathcause</a></h2>
<p>Focus a body part ingame, and this script will display the cause of death of <p>Focus a body part ingame, and this script will display the cause of death of
the creature. the creature.
Also works when selecting units from the 'u'nitlist viewscreen.</p> Also works when selecting units from the 'u'nitlist viewscreen.</p>
</div> </div>
<div class="section" id="lua"> <div class="section" id="lua">
<h2><a class="toc-backref" href="#id147">lua</a></h2> <h2><a class="toc-backref" href="#id150">lua</a></h2>
<p>There are the following ways to invoke this command:</p> <p>There are the following ways to invoke this command:</p>
<ol class="arabic"> <ol class="arabic">
<li><p class="first"><tt class="docutils literal">lua</tt> (without any parameters)</p> <li><p class="first"><tt class="docutils literal">lua</tt> (without any parameters)</p>
@ -3201,11 +3254,11 @@ directory. If the filename is not supplied, it loads &quot;dfhack.lua&quot;.</p>
</ol> </ol>
</div> </div>
<div class="section" id="embark"> <div class="section" id="embark">
<h2><a class="toc-backref" href="#id148">embark</a></h2> <h2><a class="toc-backref" href="#id151">embark</a></h2>
<p>Allows to embark anywhere. Currently windows only.</p> <p>Allows to embark anywhere. Currently windows only.</p>
</div> </div>
<div class="section" id="lever"> <div class="section" id="lever">
<h2><a class="toc-backref" href="#id149">lever</a></h2> <h2><a class="toc-backref" href="#id152">lever</a></h2>
<p>Allow manipulation of in-game levers from the dfhack console.</p> <p>Allow manipulation of in-game levers from the dfhack console.</p>
<p>Can list levers, including state and links, with:</p> <p>Can list levers, including state and links, with:</p>
<pre class="literal-block"> <pre class="literal-block">
@ -3219,7 +3272,7 @@ lever pull 42 --now
</pre> </pre>
</div> </div>
<div class="section" id="stripcaged"> <div class="section" id="stripcaged">
<h2><a class="toc-backref" href="#id150">stripcaged</a></h2> <h2><a class="toc-backref" href="#id153">stripcaged</a></h2>
<p>For dumping items inside cages. Will mark selected items for dumping, then <p>For dumping items inside cages. Will mark selected items for dumping, then
a dwarf may come and actually dump it. See also <tt class="docutils literal">autodump</tt>.</p> a dwarf may come and actually dump it. See also <tt class="docutils literal">autodump</tt>.</p>
<p>With the <tt class="docutils literal">items</tt> argument, only dumps items laying in the cage, excluding <p>With the <tt class="docutils literal">items</tt> argument, only dumps items laying in the cage, excluding
@ -3237,11 +3290,11 @@ stripcaged weapons 25321 34228
</pre> </pre>
</div> </div>
<div class="section" id="undump-buildings"> <div class="section" id="undump-buildings">
<h2><a class="toc-backref" href="#id151">undump-buildings</a></h2> <h2><a class="toc-backref" href="#id154">undump-buildings</a></h2>
<p>Undesignates building base materials for dumping.</p> <p>Undesignates building base materials for dumping.</p>
</div> </div>
<div class="section" id="create-items"> <div class="section" id="create-items">
<h2><a class="toc-backref" href="#id152">create-items</a></h2> <h2><a class="toc-backref" href="#id155">create-items</a></h2>
<p>Spawn arbitrary items under the cursor.</p> <p>Spawn arbitrary items under the cursor.</p>
<p>The first argument gives the item category, the second gives the material, <p>The first argument gives the item category, the second gives the material,
and the optionnal third gives the number of items to create (defaults to 20).</p> and the optionnal third gives the number of items to create (defaults to 20).</p>
@ -3263,7 +3316,7 @@ create-items bar adamantine
</pre> </pre>
</div> </div>
<div class="section" id="locate-ore"> <div class="section" id="locate-ore">
<h2><a class="toc-backref" href="#id153">locate-ore</a></h2> <h2><a class="toc-backref" href="#id156">locate-ore</a></h2>
<p>Scan the map for metal ores.</p> <p>Scan the map for metal ores.</p>
<p>Finds and designate for digging one tile of a specific metal ore. <p>Finds and designate for digging one tile of a specific metal ore.
Only works for native metal ores, does not handle reaction stuff (eg STEEL).</p> Only works for native metal ores, does not handle reaction stuff (eg STEEL).</p>
@ -3276,7 +3329,7 @@ locate-ore iron</dd>
</dl> </dl>
</div> </div>
<div class="section" id="soundsense-season"> <div class="section" id="soundsense-season">
<h2><a class="toc-backref" href="#id154">soundsense-season</a></h2> <h2><a class="toc-backref" href="#id157">soundsense-season</a></h2>
<p>It is a well known issue that Soundsense cannot detect the correct <p>It is a well known issue that Soundsense cannot detect the correct
current season when a savegame is loaded and has to play random current season when a savegame is loaded and has to play random
season music until a season switch occurs.</p> season music until a season switch occurs.</p>
@ -3285,7 +3338,7 @@ to gamelog.txt on every map load to fix this. For best results
call the script from <tt class="docutils literal">dfhack.init</tt>.</p> call the script from <tt class="docutils literal">dfhack.init</tt>.</p>
</div> </div>
<div class="section" id="multicmd"> <div class="section" id="multicmd">
<h2><a class="toc-backref" href="#id155">multicmd</a></h2> <h2><a class="toc-backref" href="#id158">multicmd</a></h2>
<p>Run multiple dfhack commands. The argument is split around the <p>Run multiple dfhack commands. The argument is split around the
character ; and all parts are run sequencially as independent character ; and all parts are run sequencially as independent
dfhack commands. Useful for hotkeys.</p> dfhack commands. Useful for hotkeys.</p>
@ -3294,9 +3347,13 @@ dfhack commands. Useful for hotkeys.</p>
<dd>multicmd locate-ore iron ; digv</dd> <dd>multicmd locate-ore iron ; digv</dd>
</dl> </dl>
</div> </div>
<div class="section" id="dfstatus">
<h2><a class="toc-backref" href="#id159">dfstatus</a></h2>
<p>Show a quick overview of critical stock quantities, including food, dirnks, wood, and various bars.</p>
</div>
</div> </div>
<div class="section" id="in-game-interface-tools"> <div class="section" id="in-game-interface-tools">
<h1><a class="toc-backref" href="#id156">In-game interface tools</a></h1> <h1><a class="toc-backref" href="#id160">In-game interface tools</a></h1>
<p>These tools work by displaying dialogs or overlays in the game window, and <p>These tools work by displaying dialogs or overlays in the game window, and
are mostly implemented by lua scripts.</p> are mostly implemented by lua scripts.</p>
<div class="note"> <div class="note">
@ -3311,7 +3368,7 @@ guideline because it arguably just fixes small usability bugs in the game UI.</p
you must enable the plugins which provide them.</p> you must enable the plugins which provide them.</p>
</div> </div>
<div class="section" id="dwarf-manipulator"> <div class="section" id="dwarf-manipulator">
<h2><a class="toc-backref" href="#id157">Dwarf Manipulator</a></h2> <h2><a class="toc-backref" href="#id161">Dwarf Manipulator</a></h2>
<p>Implemented by the 'manipulator' plugin.</p> <p>Implemented by the 'manipulator' plugin.</p>
<p>To activate, open the unit screen and press 'l'.</p> <p>To activate, open the unit screen and press 'l'.</p>
<img alt="images/manipulator.png" src="images/manipulator.png" /> <img alt="images/manipulator.png" src="images/manipulator.png" />
@ -3350,7 +3407,7 @@ cursor onto that cell instead of toggling it.</li>
directly to the main dwarf mode screen.</p> directly to the main dwarf mode screen.</p>
</div> </div>
<div class="section" id="search"> <div class="section" id="search">
<h2><a class="toc-backref" href="#id158">Search</a></h2> <h2><a class="toc-backref" href="#id162">Search</a></h2>
<p>Implemented by the 'search' plugin.</p> <p>Implemented by the 'search' plugin.</p>
<p>The search plugin adds search to the Stocks, Animals, Trading, Stockpile, <p>The search plugin adds search to the Stocks, Animals, Trading, Stockpile,
Noble (assignment candidates), Military (position candidates), Burrows Noble (assignment candidates), Military (position candidates), Burrows
@ -3381,7 +3438,7 @@ only fat or tallow by forbidding fats, then searching for fat/tallow, and
using Permit Fats again while the list is filtered.</p> using Permit Fats again while the list is filtered.</p>
</div> </div>
<div class="section" id="automaterial"> <div class="section" id="automaterial">
<h2><a class="toc-backref" href="#id159">AutoMaterial</a></h2> <h2><a class="toc-backref" href="#id163">AutoMaterial</a></h2>
<p>Implemented by the 'automaterial' plugin.</p> <p>Implemented by the 'automaterial' plugin.</p>
<p>This makes building constructions (walls, floors, fortifications, etc) a little bit <p>This makes building constructions (walls, floors, fortifications, etc) a little bit
easier by saving you from having to trawl through long lists of materials each time easier by saving you from having to trawl through long lists of materials each time
@ -3409,7 +3466,7 @@ materials, it returns you back to this screen. If you use this along with severa
enabled materials, you should be able to place complex constructions more conveniently.</p> enabled materials, you should be able to place complex constructions more conveniently.</p>
</div> </div>
<div class="section" id="gui-liquids"> <div class="section" id="gui-liquids">
<h2><a class="toc-backref" href="#id160">gui/liquids</a></h2> <h2><a class="toc-backref" href="#id164">gui/liquids</a></h2>
<p>To use, bind to a key (the example config uses Alt-L) and activate in the 'k' mode.</p> <p>To use, bind to a key (the example config uses Alt-L) and activate in the 'k' mode.</p>
<img alt="images/liquids.png" src="images/liquids.png" /> <img alt="images/liquids.png" src="images/liquids.png" />
<p>This script is a gui front-end to the liquids plugin and works similar to it, <p>This script is a gui front-end to the liquids plugin and works similar to it,
@ -3429,7 +3486,7 @@ rivers power water wheels even when full and technically not flowing.</p>
<p>After setting up the desired operations using the described keys, use <tt class="docutils literal">Enter</tt> to apply them.</p> <p>After setting up the desired operations using the described keys, use <tt class="docutils literal">Enter</tt> to apply them.</p>
</div> </div>
<div class="section" id="gui-mechanisms"> <div class="section" id="gui-mechanisms">
<h2><a class="toc-backref" href="#id161">gui/mechanisms</a></h2> <h2><a class="toc-backref" href="#id165">gui/mechanisms</a></h2>
<p>To use, bind to a key (the example config uses Ctrl-M) and activate in the 'q' mode.</p> <p>To use, bind to a key (the example config uses Ctrl-M) and activate in the 'q' mode.</p>
<img alt="images/mechanisms.png" src="images/mechanisms.png" /> <img alt="images/mechanisms.png" src="images/mechanisms.png" />
<p>Lists mechanisms connected to the building, and their links. Navigating the list centers <p>Lists mechanisms connected to the building, and their links. Navigating the list centers
@ -3439,7 +3496,7 @@ focus on the current one. Shift-Enter has an effect equivalent to pressing Enter
re-entering the mechanisms ui.</p> re-entering the mechanisms ui.</p>
</div> </div>
<div class="section" id="gui-rename"> <div class="section" id="gui-rename">
<h2><a class="toc-backref" href="#id162">gui/rename</a></h2> <h2><a class="toc-backref" href="#id166">gui/rename</a></h2>
<p>Backed by the rename plugin, this script allows entering the desired name <p>Backed by the rename plugin, this script allows entering the desired name
via a simple dialog in the game ui.</p> via a simple dialog in the game ui.</p>
<ul> <ul>
@ -3462,7 +3519,7 @@ their species string.</p>
unit profession change to Ctrl-Shift-T.</p> unit profession change to Ctrl-Shift-T.</p>
</div> </div>
<div class="section" id="gui-room-list"> <div class="section" id="gui-room-list">
<h2><a class="toc-backref" href="#id163">gui/room-list</a></h2> <h2><a class="toc-backref" href="#id167">gui/room-list</a></h2>
<p>To use, bind to a key (the example config uses Alt-R) and activate in the 'q' mode, <p>To use, bind to a key (the example config uses Alt-R) and activate in the 'q' mode,
either immediately or after opening the assign owner page.</p> either immediately or after opening the assign owner page.</p>
<img alt="images/room-list.png" src="images/room-list.png" /> <img alt="images/room-list.png" src="images/room-list.png" />
@ -3470,7 +3527,7 @@ either immediately or after opening the assign owner page.</p>
list, and allows unassigning them.</p> list, and allows unassigning them.</p>
</div> </div>
<div class="section" id="gui-choose-weapons"> <div class="section" id="gui-choose-weapons">
<h2><a class="toc-backref" href="#id164">gui/choose-weapons</a></h2> <h2><a class="toc-backref" href="#id168">gui/choose-weapons</a></h2>
<p>Bind to a key (the example config uses Ctrl-W), and activate in the Equip-&gt;View/Customize <p>Bind to a key (the example config uses Ctrl-W), and activate in the Equip-&gt;View/Customize
page of the military screen.</p> page of the military screen.</p>
<p>Depending on the cursor location, it rewrites all 'individual choice weapon' entries <p>Depending on the cursor location, it rewrites all 'individual choice weapon' entries
@ -3481,14 +3538,14 @@ only that entry, and does it even if it is not 'individual choice'.</p>
and may lead to inappropriate weapons being selected.</p> and may lead to inappropriate weapons being selected.</p>
</div> </div>
<div class="section" id="gui-clone-uniform"> <div class="section" id="gui-clone-uniform">
<h2><a class="toc-backref" href="#id165">gui/clone-uniform</a></h2> <h2><a class="toc-backref" href="#id169">gui/clone-uniform</a></h2>
<p>Bind to a key (the example config uses Ctrl-C), and activate in the Uniforms <p>Bind to a key (the example config uses Ctrl-C), and activate in the Uniforms
page of the military screen with the cursor in the leftmost list.</p> page of the military screen with the cursor in the leftmost list.</p>
<p>When invoked, the script duplicates the currently selected uniform template, <p>When invoked, the script duplicates the currently selected uniform template,
and selects the newly created copy.</p> and selects the newly created copy.</p>
</div> </div>
<div class="section" id="gui-guide-path"> <div class="section" id="gui-guide-path">
<h2><a class="toc-backref" href="#id166">gui/guide-path</a></h2> <h2><a class="toc-backref" href="#id170">gui/guide-path</a></h2>
<p>Bind to a key (the example config uses Alt-P), and activate in the Hauling menu with <p>Bind to a key (the example config uses Alt-P), and activate in the Hauling menu with
the cursor over a Guide order.</p> the cursor over a Guide order.</p>
<img alt="images/guide-path.png" src="images/guide-path.png" /> <img alt="images/guide-path.png" src="images/guide-path.png" />
@ -3496,7 +3553,7 @@ the cursor over a Guide order.</p>
computes it when the order is executed for the first time.</p> computes it when the order is executed for the first time.</p>
</div> </div>
<div class="section" id="gui-workshop-job"> <div class="section" id="gui-workshop-job">
<h2><a class="toc-backref" href="#id167">gui/workshop-job</a></h2> <h2><a class="toc-backref" href="#id171">gui/workshop-job</a></h2>
<p>Bind to a key (the example config uses Alt-A), and activate with a job selected in <p>Bind to a key (the example config uses Alt-A), and activate with a job selected in
a workshop in the 'q' mode.</p> a workshop in the 'q' mode.</p>
<img alt="images/workshop-job.png" src="images/workshop-job.png" /> <img alt="images/workshop-job.png" src="images/workshop-job.png" />
@ -3532,7 +3589,7 @@ and then try to change the input item type, now it won't let you select <em>plan
you have to unset the material first.</p> you have to unset the material first.</p>
</div> </div>
<div class="section" id="gui-workflow"> <div class="section" id="gui-workflow">
<h2><a class="toc-backref" href="#id168">gui/workflow</a></h2> <h2><a class="toc-backref" href="#id172">gui/workflow</a></h2>
<p>Bind to a key (the example config uses Alt-W), and activate with a job selected <p>Bind to a key (the example config uses Alt-W), and activate with a job selected
in a workshop in the 'q' mode.</p> in a workshop in the 'q' mode.</p>
<img alt="images/workflow.png" src="images/workflow.png" /> <img alt="images/workflow.png" src="images/workflow.png" />
@ -3579,7 +3636,7 @@ the current stock value. The bright green dashed line is the target
limit (maximum) and the dark green line is that minus the gap (minimum).</p> limit (maximum) and the dark green line is that minus the gap (minimum).</p>
</div> </div>
<div class="section" id="gui-assign-rack"> <div class="section" id="gui-assign-rack">
<h2><a class="toc-backref" href="#id169">gui/assign-rack</a></h2> <h2><a class="toc-backref" href="#id173">gui/assign-rack</a></h2>
<p>Bind to a key (the example config uses P), and activate when viewing a weapon <p>Bind to a key (the example config uses P), and activate when viewing a weapon
rack in the 'q' mode.</p> rack in the 'q' mode.</p>
<img alt="images/assign-rack.png" src="images/assign-rack.png" /> <img alt="images/assign-rack.png" src="images/assign-rack.png" />
@ -3603,7 +3660,7 @@ the intended user. In order to aid in the choice, it shows the number
of currently assigned racks for every valid squad.</p> of currently assigned racks for every valid squad.</p>
</div> </div>
<div class="section" id="gui-advfort"> <div class="section" id="gui-advfort">
<h2><a class="toc-backref" href="#id170">gui/advfort</a></h2> <h2><a class="toc-backref" href="#id174">gui/advfort</a></h2>
<p>This script allows to perform jobs in adventure mode. For more complete help <p>This script allows to perform jobs in adventure mode. For more complete help
press '?' while script is running. It's most confortable to use this as a press '?' while script is running. It's most confortable to use this as a
keybinding. (e.g. keybinding set Ctrl-T gui/advfort). Possible arguments:</p> keybinding. (e.g. keybinding set Ctrl-T gui/advfort). Possible arguments:</p>
@ -3622,7 +3679,7 @@ implies -a</li>
</div> </div>
</div> </div>
<div class="section" id="gui-companion-order"> <div class="section" id="gui-companion-order">
<h2><a class="toc-backref" href="#id171">gui/companion-order</a></h2> <h2><a class="toc-backref" href="#id175">gui/companion-order</a></h2>
<p>A script to issue orders for companions. Select companions with lower case chars, issue orders with upper <p>A script to issue orders for companions. Select companions with lower case chars, issue orders with upper
case. Must be in look or talk mode to issue command on tile.</p> case. Must be in look or talk mode to issue command on tile.</p>
<img alt="images/companion-order.png" src="images/companion-order.png" /> <img alt="images/companion-order.png" src="images/companion-order.png" />
@ -3638,7 +3695,7 @@ case. Must be in look or talk mode to issue command on tile.</p>
</ul> </ul>
</div> </div>
<div class="section" id="gui-gm-editor"> <div class="section" id="gui-gm-editor">
<h2><a class="toc-backref" href="#id172">gui/gm-editor</a></h2> <h2><a class="toc-backref" href="#id176">gui/gm-editor</a></h2>
<p>There are three ways to open this editor:</p> <p>There are three ways to open this editor:</p>
<ul class="simple"> <ul class="simple">
<li>using gui/gm-editor command/keybinding - opens editor on what is selected <li>using gui/gm-editor command/keybinding - opens editor on what is selected
@ -3653,14 +3710,14 @@ the same as version above.</li>
in-game help.</p> in-game help.</p>
</div> </div>
<div class="section" id="gui-mod-manager"> <div class="section" id="gui-mod-manager">
<h2><a class="toc-backref" href="#id173">gui/mod-manager</a></h2> <h2><a class="toc-backref" href="#id177">gui/mod-manager</a></h2>
<p>A way to simply install and remove small mods. It looks for specially formated mods in <p>A way to simply install and remove small mods. It looks for specially formatted mods in
df subfolder 'mods'. Mods are not included, for example mods see: <a class="reference external" href="https://github.com/warmist/df-mini-mods">github mini mod repository</a></p> df subfolder 'mods'. Mods are not included, for example mods see: <a class="reference external" href="https://github.com/warmist/df-mini-mods">github mini mod repository</a></p>
<img alt="images/mod-manager.png" src="images/mod-manager.png" /> <img alt="images/mod-manager.png" src="images/mod-manager.png" />
</div> </div>
</div> </div>
<div class="section" id="behavior-mods"> <div class="section" id="behavior-mods">
<h1><a class="toc-backref" href="#id174">Behavior Mods</a></h1> <h1><a class="toc-backref" href="#id178">Behavior Mods</a></h1>
<p>These plugins, when activated via configuration UI or by detecting certain <p>These plugins, when activated via configuration UI or by detecting certain
structures in RAWs, modify the game engine behavior concerning the target structures in RAWs, modify the game engine behavior concerning the target
objects to add features not otherwise present.</p> objects to add features not otherwise present.</p>
@ -3671,20 +3728,20 @@ technical challenge, and do not represent any long-term plans to produce more
similar modifications of the game.</p> similar modifications of the game.</p>
</div> </div>
<div class="section" id="siege-engine"> <div class="section" id="siege-engine">
<h2><a class="toc-backref" href="#id175">Siege Engine</a></h2> <h2><a class="toc-backref" href="#id179">Siege Engine</a></h2>
<p>The siege-engine plugin enables siege engines to be linked to stockpiles, and <p>The siege-engine plugin enables siege engines to be linked to stockpiles, and
aimed at an arbitrary rectangular area across Z levels, instead of the original aimed at an arbitrary rectangular area across Z levels, instead of the original
four directions. Also, catapults can be ordered to load arbitrary objects, not four directions. Also, catapults can be ordered to load arbitrary objects, not
just stones.</p> just stones.</p>
<div class="section" id="rationale"> <div class="section" id="rationale">
<h3><a class="toc-backref" href="#id176">Rationale</a></h3> <h3><a class="toc-backref" href="#id180">Rationale</a></h3>
<p>Siege engines are a very interesting feature, but sadly almost useless in the current state <p>Siege engines are a very interesting feature, but sadly almost useless in the current state
because they haven't been updated since 2D and can only aim in four directions. This is an because they haven't been updated since 2D and can only aim in four directions. This is an
attempt to bring them more up to date until Toady has time to work on it. Actual improvements, attempt to bring them more up to date until Toady has time to work on it. Actual improvements,
e.g. like making siegers bring their own, are something only Toady can do.</p> e.g. like making siegers bring their own, are something only Toady can do.</p>
</div> </div>
<div class="section" id="configuration-ui"> <div class="section" id="configuration-ui">
<h3><a class="toc-backref" href="#id177">Configuration UI</a></h3> <h3><a class="toc-backref" href="#id181">Configuration UI</a></h3>
<p>The configuration front-end to the plugin is implemented by the gui/siege-engine <p>The configuration front-end to the plugin is implemented by the gui/siege-engine
script. Bind it to a key (the example config uses Alt-A) and activate after selecting script. Bind it to a key (the example config uses Alt-A) and activate after selecting
a siege engine in 'q' mode.</p> a siege engine in 'q' mode.</p>
@ -3707,7 +3764,7 @@ menu.</p>
</div> </div>
</div> </div>
<div class="section" id="power-meter"> <div class="section" id="power-meter">
<h2><a class="toc-backref" href="#id178">Power Meter</a></h2> <h2><a class="toc-backref" href="#id182">Power Meter</a></h2>
<p>The power-meter plugin implements a modified pressure plate that detects power being <p>The power-meter plugin implements a modified pressure plate that detects power being
supplied to gear boxes built in the four adjacent N/S/W/E tiles.</p> supplied to gear boxes built in the four adjacent N/S/W/E tiles.</p>
<p>The configuration front-end is implemented by the gui/power-meter script. Bind it to a <p>The configuration front-end is implemented by the gui/power-meter script. Bind it to a
@ -3718,11 +3775,11 @@ in the build menu.</p>
configuration page, but configures parameters relevant to the modded power meter building.</p> configuration page, but configures parameters relevant to the modded power meter building.</p>
</div> </div>
<div class="section" id="steam-engine"> <div class="section" id="steam-engine">
<h2><a class="toc-backref" href="#id179">Steam Engine</a></h2> <h2><a class="toc-backref" href="#id183">Steam Engine</a></h2>
<p>The steam-engine plugin detects custom workshops with STEAM_ENGINE in <p>The steam-engine plugin detects custom workshops with STEAM_ENGINE in
their token, and turns them into real steam engines.</p> their token, and turns them into real steam engines.</p>
<div class="section" id="id1"> <div class="section" id="id1">
<h3><a class="toc-backref" href="#id180">Rationale</a></h3> <h3><a class="toc-backref" href="#id184">Rationale</a></h3>
<p>The vanilla game contains only water wheels and windmills as sources of <p>The vanilla game contains only water wheels and windmills as sources of
power, but windmills give relatively little power, and water wheels require power, but windmills give relatively little power, and water wheels require
flowing water, which must either be a real river and thus immovable and flowing water, which must either be a real river and thus immovable and
@ -3733,7 +3790,7 @@ it can be done just by combining existing features of the game engine
in a new way with some glue code and a bit of custom logic.</p> in a new way with some glue code and a bit of custom logic.</p>
</div> </div>
<div class="section" id="construction"> <div class="section" id="construction">
<h3><a class="toc-backref" href="#id181">Construction</a></h3> <h3><a class="toc-backref" href="#id185">Construction</a></h3>
<p>The workshop needs water as its input, which it takes via a <p>The workshop needs water as its input, which it takes via a
passable floor tile below it, like usual magma workshops do. passable floor tile below it, like usual magma workshops do.
The magma version also needs magma.</p> The magma version also needs magma.</p>
@ -3757,7 +3814,7 @@ short axles that can be built later than both of the engines.</p>
</div> </div>
</div> </div>
<div class="section" id="operation"> <div class="section" id="operation">
<h3><a class="toc-backref" href="#id182">Operation</a></h3> <h3><a class="toc-backref" href="#id186">Operation</a></h3>
<p>In order to operate the engine, queue the Stoke Boiler job (optionally <p>In order to operate the engine, queue the Stoke Boiler job (optionally
on repeat). A furnace operator will come, possibly bringing a bar of fuel, on repeat). A furnace operator will come, possibly bringing a bar of fuel,
and perform it. As a result, a &quot;boiling water&quot; item will appear and perform it. As a result, a &quot;boiling water&quot; item will appear
@ -3788,7 +3845,7 @@ decrease it by further 4%, and also decrease the whole steam
use rate by 10%.</p> use rate by 10%.</p>
</div> </div>
<div class="section" id="explosions"> <div class="section" id="explosions">
<h3><a class="toc-backref" href="#id183">Explosions</a></h3> <h3><a class="toc-backref" href="#id187">Explosions</a></h3>
<p>The engine must be constructed using barrel, pipe and piston <p>The engine must be constructed using barrel, pipe and piston
from fire-safe, or in the magma version magma-safe metals.</p> from fire-safe, or in the magma version magma-safe metals.</p>
<p>During operation weak parts get gradually worn out, and <p>During operation weak parts get gradually worn out, and
@ -3797,7 +3854,7 @@ toppled during operation by a building destroyer, or a
tantruming dwarf.</p> tantruming dwarf.</p>
</div> </div>
<div class="section" id="save-files"> <div class="section" id="save-files">
<h3><a class="toc-backref" href="#id184">Save files</a></h3> <h3><a class="toc-backref" href="#id188">Save files</a></h3>
<p>It should be safe to load and view engine-using fortresses <p>It should be safe to load and view engine-using fortresses
from a DF version without DFHack installed, except that in such from a DF version without DFHack installed, except that in such
case the engines won't work. However actually making modifications case the engines won't work. However actually making modifications
@ -3808,7 +3865,7 @@ being generated.</p>
</div> </div>
</div> </div>
<div class="section" id="add-spatter"> <div class="section" id="add-spatter">
<h2><a class="toc-backref" href="#id185">Add Spatter</a></h2> <h2><a class="toc-backref" href="#id189">Add Spatter</a></h2>
<p>This plugin makes reactions with names starting with <tt class="docutils literal">SPATTER_ADD_</tt> <p>This plugin makes reactions with names starting with <tt class="docutils literal">SPATTER_ADD_</tt>
produce contaminants on the items instead of improvements. The produced produce contaminants on the items instead of improvements. The produced
contaminants are immune to being washed away by water or destroyed by contaminants are immune to being washed away by water or destroyed by

@ -1577,6 +1577,29 @@ Duplicate the selected job in a workshop:
* In 'q' mode, when a job is highlighted within a workshop or furnace building, * In 'q' mode, when a job is highlighted within a workshop or furnace building,
instantly duplicates the job. instantly duplicates the job.
stockflow
---------
Allows the fortress bookkeeper to queue jobs through the manager.
Usage:
``stockflow enable``
Enable the plugin.
``stockflow disable``
Disable the plugin.
``stockflow list``
List any work order settings for your stockpiles.
``stockflow status``
Display whether the plugin is enabled.
While enabled, the 'q' menu of each stockpile will have two new options:
* j: Select a job to order, from an interface like the manager's screen.
* J: Cycle between several options for how many such jobs to order.
Whenever the bookkeeper updates stockpile records, new work orders will
be placed on the manager's queue for each such selection, reduced by the
number of identical orders already in the queue.
workflow workflow
-------- --------
Manage control of repeat jobs. Manage control of repeat jobs.
@ -2962,7 +2985,7 @@ in-game help.
gui/mod-manager gui/mod-manager
=============== ===============
A way to simply install and remove small mods. It looks for specially formated mods in A way to simply install and remove small mods. It looks for specially formatted mods in
df subfolder 'mods'. Mods are not included, for example mods see: `github mini mod repository <https://github.com/warmist/df-mini-mods>`_ df subfolder 'mods'. Mods are not included, for example mods see: `github mini mod repository <https://github.com/warmist/df-mini-mods>`_
.. image:: images/mod-manager.png .. image:: images/mod-manager.png

@ -192,6 +192,9 @@ enable automaterial
# Auto Syndrome # Auto Syndrome
#autoSyndrome enable #autoSyndrome enable
# allow the fortress bookkeeper to queue jobs through the manager
stockflow enable
########### ###########
# Scripts # # Scripts #
########### ###########

@ -305,6 +305,33 @@ namespace DFHack
} }
/// beep. maybe? /// beep. maybe?
//void beep (void); //void beep (void);
void back_word()
{
if (raw_cursor == 0)
return;
raw_cursor--;
while (raw_cursor > 0 && !isalnum(raw_buffer[raw_cursor]))
raw_cursor--;
while (raw_cursor > 0 && isalnum(raw_buffer[raw_cursor]))
raw_cursor--;
if (!isalnum(raw_buffer[raw_cursor]) && raw_cursor != 0)
raw_cursor++;
prompt_refresh();
}
void forward_word()
{
int len = raw_buffer.size();
if (raw_cursor == len)
return;
raw_cursor++;
while (raw_cursor <= len && !isalnum(raw_buffer[raw_cursor]))
raw_cursor++;
while (raw_cursor <= len && isalnum(raw_buffer[raw_cursor]))
raw_cursor++;
if (raw_cursor > len)
raw_cursor = len;
prompt_refresh();
}
/// A simple line edit (raw mode) /// A simple line edit (raw mode)
int lineedit(const std::string& prompt, std::string& output, recursive_mutex * lock, CommandHistory & ch) int lineedit(const std::string& prompt, std::string& output, recursive_mutex * lock, CommandHistory & ch)
{ {
@ -478,14 +505,27 @@ namespace DFHack
break; break;
case 27: // escape sequence case 27: // escape sequence
lock->unlock(); lock->unlock();
if(!read_char(seq[0]) || !read_char(seq[1])) if (!read_char(seq[0]))
{ {
lock->lock(); lock->lock();
return -2; return -2;
} }
lock->lock(); lock->lock();
if(seq[0] == '[') if (seq[0] == 'b')
{ {
back_word();
}
else if (seq[0] == 'f')
{
forward_word();
}
else if(seq[0] == '[')
{
if (!read_char(seq[1]))
{
lock->lock();
return -2;
}
if (seq[1] == 'D') if (seq[1] == 'D')
{ {
left_arrow: left_arrow:
@ -545,6 +585,7 @@ namespace DFHack
else if (seq[1] > '0' && seq[1] < '7') else if (seq[1] > '0' && seq[1] < '7')
{ {
// extended escape // extended escape
unsigned char seq3[3];
lock->unlock(); lock->unlock();
if(!read_char(seq2)) if(!read_char(seq2))
{ {
@ -561,6 +602,24 @@ namespace DFHack
prompt_refresh(); prompt_refresh();
} }
} }
if (!read_char(seq3[0]) || !read_char(seq3[1]))
{
lock->lock();
return -2;
}
if (seq2 == ';')
{
// Format: esc [ n ; n DIRECTION
// Ignore first character (second "n")
if (seq3[1] == 'C')
{
forward_word();
}
else if (seq3[1] == 'D')
{
back_word();
}
}
} }
} }
break; break;

@ -307,6 +307,33 @@ namespace DFHack
} }
/// beep. maybe? /// beep. maybe?
//void beep (void); //void beep (void);
void back_word()
{
if (raw_cursor == 0)
return;
raw_cursor--;
while (raw_cursor > 0 && !isalnum(raw_buffer[raw_cursor]))
raw_cursor--;
while (raw_cursor > 0 && isalnum(raw_buffer[raw_cursor]))
raw_cursor--;
if (!isalnum(raw_buffer[raw_cursor]) && raw_cursor != 0)
raw_cursor++;
prompt_refresh();
}
void forward_word()
{
int len = raw_buffer.size();
if (raw_cursor == len)
return;
raw_cursor++;
while (raw_cursor <= len && !isalnum(raw_buffer[raw_cursor]))
raw_cursor++;
while (raw_cursor <= len && isalnum(raw_buffer[raw_cursor]))
raw_cursor++;
if (raw_cursor > len)
raw_cursor = len;
prompt_refresh();
}
/// A simple line edit (raw mode) /// A simple line edit (raw mode)
int lineedit(const std::string& prompt, std::string& output, recursive_mutex * lock, CommandHistory & ch) int lineedit(const std::string& prompt, std::string& output, recursive_mutex * lock, CommandHistory & ch)
{ {
@ -480,14 +507,27 @@ namespace DFHack
break; break;
case 27: // escape sequence case 27: // escape sequence
lock->unlock(); lock->unlock();
if(!read_char(seq[0]) || !read_char(seq[1])) if (!read_char(seq[0]))
{ {
lock->lock(); lock->lock();
return -2; return -2;
} }
lock->lock(); lock->lock();
if(seq[0] == '[') if (seq[0] == 'b')
{ {
back_word();
}
else if (seq[0] == 'f')
{
forward_word();
}
else if(seq[0] == '[')
{
if (!read_char(seq[1]))
{
lock->lock();
return -2;
}
if (seq[1] == 'D') if (seq[1] == 'D')
{ {
left_arrow: left_arrow:
@ -547,6 +587,7 @@ namespace DFHack
else if (seq[1] > '0' && seq[1] < '7') else if (seq[1] > '0' && seq[1] < '7')
{ {
// extended escape // extended escape
unsigned char seq3[3];
lock->unlock(); lock->unlock();
if(!read_char(seq2)) if(!read_char(seq2))
{ {
@ -563,6 +604,24 @@ namespace DFHack
prompt_refresh(); prompt_refresh();
} }
} }
if (!read_char(seq3[0]) || !read_char(seq3[1]))
{
lock->lock();
return -2;
}
if (seq2 == ';')
{
// Format: esc [ n ; n DIRECTION
// Ignore first character (second "n")
if (seq3[1] == 'C')
{
forward_word();
}
else if (seq3[1] == 'D')
{
back_word();
}
}
} }
} }
break; break;

@ -42,12 +42,16 @@ namespace DFHack
struct my_hack : df::someclass { struct my_hack : df::someclass {
typedef df::someclass interpose_base; typedef df::someclass interpose_base;
DEFINE_VMETHOD_INTERPOSE(void, foo, (int arg)) { // You may define additional methods here, but NOT non-static fields
DEFINE_VMETHOD_INTERPOSE(int, foo, (int arg)) {
// If needed by the code, claim the suspend lock. // If needed by the code, claim the suspend lock.
// DO NOT USE THE USUAL CoreSuspender, OR IT WILL DEADLOCK! // DO NOT USE THE USUAL CoreSuspender, OR IT WILL DEADLOCK!
// CoreSuspendClaimer suspend; // CoreSuspendClaimer suspend;
... ...
INTERPOSE_NEXT(foo)(arg) // call the original ... this->field ... // access fields of the df::someclass object
...
int orig_retval = INTERPOSE_NEXT(foo)(arg); // call the original method
... ...
} }
}; };

@ -234,6 +234,8 @@ ITEMDEF_VECTORS
#undef ITEM #undef ITEM
default: default:
if (items[1] == "NONE")
return true;
break; break;
} }

@ -1 +1 @@
Subproject commit e0407d8bbbc965dbb62826d481f27940972ffd66 Subproject commit 851f52d5e9eae6fc81adadd10e53bd2cc42bfd21

@ -42,6 +42,7 @@ using namespace MapExtras;
using namespace DFHack::Random; using namespace DFHack::Random;
using df::global::world; using df::global::world;
using df::global::gametype;
command_result cmd_3dveins(color_ostream &out, std::vector <std::string> & parameters); command_result cmd_3dveins(color_ostream &out, std::vector <std::string> & parameters);
@ -1573,6 +1574,12 @@ command_result cmd_3dveins(color_ostream &con, std::vector<std::string> & parame
return CR_FAILURE; return CR_FAILURE;
} }
if (*gametype != game_type::DWARF_MAIN && *gametype != game_type::DWARF_RECLAIM)
{
con.printerr("Must be used in fortress mode!\n");
return CR_FAILURE;
}
VeinGenerator generator(con); VeinGenerator generator(con);
con.print("Collecting statistics...\n"); con.print("Collecting statistics...\n");

@ -114,6 +114,7 @@ if (BUILD_SUPPORTED)
DFHACK_PLUGIN(rename rename.cpp LINK_LIBRARIES lua PROTOBUFS rename) DFHACK_PLUGIN(rename rename.cpp LINK_LIBRARIES lua PROTOBUFS rename)
DFHACK_PLUGIN(jobutils jobutils.cpp) DFHACK_PLUGIN(jobutils jobutils.cpp)
DFHACK_PLUGIN(workflow workflow.cpp LINK_LIBRARIES lua) DFHACK_PLUGIN(workflow workflow.cpp LINK_LIBRARIES lua)
DFHACK_PLUGIN(stockflow stockflow.cpp LINK_LIBRARIES lua)
DFHACK_PLUGIN(showmood showmood.cpp) DFHACK_PLUGIN(showmood showmood.cpp)
DFHACK_PLUGIN(fixveins fixveins.cpp) DFHACK_PLUGIN(fixveins fixveins.cpp)
DFHACK_PLUGIN(fixpositions fixpositions.cpp) DFHACK_PLUGIN(fixpositions fixpositions.cpp)

@ -502,7 +502,7 @@ static command_result autotrade_cmd(color_ostream &out, vector <string> & parame
{ {
if (parameters.size() == 1 && toLower(parameters[0])[0] == 'v') if (parameters.size() == 1 && toLower(parameters[0])[0] == 'v')
{ {
out << "Building Plan" << endl << "Version: " << PLUGIN_VERSION << endl; out << "Autotrade" << endl << "Version: " << PLUGIN_VERSION << endl;
} }
} }

@ -7,6 +7,7 @@
#include <ColorText.h> #include <ColorText.h>
#include <modules/Screen.h> #include <modules/Screen.h>
#include <modules/Gui.h>
#include <set> #include <set>
#include <list> #include <list>
@ -55,9 +56,14 @@ public:
df::global::gps->display_frames=show_fps; df::global::gps->display_frames=show_fps;
} }
void add_response(color_value v,std::string s) void add_response(color_value v, std::string s)
{ {
responses.push_back(std::make_pair(v,s)); std::stringstream ss(s);
std::string part;
while (std::getline(ss, part))
{
responses.push_back(std::make_pair(v, part + '\n'));
}
} }
protected: protected:
std::list<std::pair<color_value,std::string> > responses; std::list<std::pair<color_value,std::string> > responses;
@ -166,16 +172,24 @@ void viewscreen_commandpromptst::feed(std::set<df::interface_key> *events)
DFHACK_PLUGIN("command-prompt"); DFHACK_PLUGIN("command-prompt");
command_result show_prompt(color_ostream &out, std::vector <std::string> & parameters) command_result show_prompt(color_ostream &out, std::vector <std::string> & parameters)
{ {
if (Gui::getCurFocus() == "dfhack/commandprompt")
{
Screen::dismiss(Gui::getCurViewscreen(true));
}
std::string params; std::string params;
for(size_t i=0;i<parameters.size();i++) for(size_t i=0;i<parameters.size();i++)
params+=parameters[i]+" "; params+=parameters[i]+" ";
Screen::show(new viewscreen_commandpromptst(params)); Screen::show(new viewscreen_commandpromptst(params));
return CR_OK; return CR_OK;
} }
bool hotkey_allow_all(df::viewscreen *top)
{
return true;
}
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
"command-prompt","Shows a command prompt on window.",show_prompt,false, "command-prompt","Shows a command prompt on window.",show_prompt,hotkey_allow_all,
"command-prompt [entry] - shows a cmd prompt in df window. Entry is used for default prefix (e.g. ':lua')" "command-prompt [entry] - shows a cmd prompt in df window. Entry is used for default prefix (e.g. ':lua')"
)); ));
return CR_OK; return CR_OK;

@ -26,8 +26,10 @@
#include "df/reaction_product_itemst.h" #include "df/reaction_product_itemst.h"
#include "df/tool_uses.h" #include "df/tool_uses.h"
using namespace std; using std::string;
using std::vector;
using namespace DFHack; using namespace DFHack;
using namespace df::enums;
using df::global::world; using df::global::world;
using df::global::ui; using df::global::ui;
@ -71,8 +73,8 @@ bool makeItem (df::reaction_product_itemst *prod, df::unit *unit, bool second_it
vector<df::item *> out_items; vector<df::item *> out_items;
vector<df::reaction_reagent *> in_reag; vector<df::reaction_reagent *> in_reag;
vector<df::item *> in_items; vector<df::item *> in_items;
bool is_gloves = (prod->item_type == df::item_type::GLOVES); bool is_gloves = (prod->item_type == item_type::GLOVES);
bool is_shoes = (prod->item_type == df::item_type::SHOES); bool is_shoes = (prod->item_type == item_type::SHOES);
df::item *container = NULL; df::item *container = NULL;
df::building *building = NULL; df::building *building = NULL;
@ -81,9 +83,9 @@ bool makeItem (df::reaction_product_itemst *prod, df::unit *unit, bool second_it
if (dest_building != -1) if (dest_building != -1)
building = df::building::find(dest_building); building = df::building::find(dest_building);
prod->produce(unit, &out_items, &in_reag, &in_items, 1, df::job_skill::NONE, prod->produce(unit, &out_items, &in_reag, &in_items, 1, job_skill::NONE,
df::historical_entity::find(unit->civ_id), df::historical_entity::find(unit->civ_id),
((*gametype == df::game_type::DWARF_MAIN) || (*gametype == df::game_type::DWARF_RECLAIM)) ? df::world_site::find(ui->site_id) : NULL); ((*gametype == game_type::DWARF_MAIN) || (*gametype == game_type::DWARF_RECLAIM)) ? df::world_site::find(ui->site_id) : NULL);
if (!out_items.size()) if (!out_items.size())
return false; return false;
// if we asked to make shoes and we got twice as many as we asked, then we're okay // if we asked to make shoes and we got twice as many as we asked, then we're okay
@ -130,7 +132,7 @@ bool makeItem (df::reaction_product_itemst *prod, df::unit *unit, bool second_it
command_result df_createitem (color_ostream &out, vector <string> & parameters) command_result df_createitem (color_ostream &out, vector <string> & parameters)
{ {
string item_str, material_str; string item_str, material_str;
df::item_type item_type = df::item_type::NONE; df::item_type item_type = item_type::NONE;
int16_t item_subtype = -1; int16_t item_subtype = -1;
int16_t mat_type = -1; int16_t mat_type = -1;
int32_t mat_index = -1; int32_t mat_index = -1;
@ -156,23 +158,23 @@ command_result df_createitem (color_ostream &out, vector <string> & parameters)
} }
switch (item->getType()) switch (item->getType())
{ {
case df::item_type::FLASK: case item_type::FLASK:
case df::item_type::BARREL: case item_type::BARREL:
case df::item_type::BUCKET: case item_type::BUCKET:
case df::item_type::ANIMALTRAP: case item_type::ANIMALTRAP:
case df::item_type::BOX: case item_type::BOX:
case df::item_type::BIN: case item_type::BIN:
case df::item_type::BACKPACK: case item_type::BACKPACK:
case df::item_type::QUIVER: case item_type::QUIVER:
break; break;
case df::item_type::TOOL: case item_type::TOOL:
if (item->hasToolUse(df::tool_uses::LIQUID_CONTAINER)) if (item->hasToolUse(tool_uses::LIQUID_CONTAINER))
break; break;
if (item->hasToolUse(df::tool_uses::FOOD_STORAGE)) if (item->hasToolUse(tool_uses::FOOD_STORAGE))
break; break;
if (item->hasToolUse(df::tool_uses::SMALL_OBJECT_STORAGE)) if (item->hasToolUse(tool_uses::SMALL_OBJECT_STORAGE))
break; break;
if (item->hasToolUse(df::tool_uses::TRACK_CART)) if (item->hasToolUse(tool_uses::TRACK_CART))
break; break;
default: default:
out.printerr("The selected item cannot be used for item storage!\n"); out.printerr("The selected item cannot be used for item storage!\n");
@ -195,22 +197,22 @@ command_result df_createitem (color_ostream &out, vector <string> & parameters)
} }
switch (building->getType()) switch (building->getType())
{ {
case df::building_type::Coffin: case building_type::Coffin:
case df::building_type::Furnace: case building_type::Furnace:
case df::building_type::TradeDepot: case building_type::TradeDepot:
case df::building_type::Shop: case building_type::Shop:
case df::building_type::Box: case building_type::Box:
case df::building_type::Weaponrack: case building_type::Weaponrack:
case df::building_type::Armorstand: case building_type::Armorstand:
case df::building_type::Workshop: case building_type::Workshop:
case df::building_type::Cabinet: case building_type::Cabinet:
case df::building_type::SiegeEngine: case building_type::SiegeEngine:
case df::building_type::Trap: case building_type::Trap:
case df::building_type::AnimalTrap: case building_type::AnimalTrap:
case df::building_type::Cage: case building_type::Cage:
case df::building_type::Wagon: case building_type::Wagon:
case df::building_type::NestBox: case building_type::NestBox:
case df::building_type::Hive: case building_type::Hive:
break; break;
default: default:
out.printerr("The selected building cannot be used for item storage!\n"); out.printerr("The selected building cannot be used for item storage!\n");
@ -252,28 +254,31 @@ command_result df_createitem (color_ostream &out, vector <string> & parameters)
MaterialInfo material; MaterialInfo material;
vector<string> tokens; vector<string> tokens;
if (!item.find(item_str)) if (item.find(item_str))
{ {
out.printerr("Unrecognized item type!\n"); item_type = item.type;
item_subtype = item.subtype;
}
if (item_type == item_type::NONE)
{
out.printerr("You must specify a valid item type to create!\n");
return CR_FAILURE; return CR_FAILURE;
} }
item_type = item.type;
item_subtype = item.subtype;
switch (item.type) switch (item.type)
{ {
case df::item_type::INSTRUMENT: case item_type::INSTRUMENT:
case df::item_type::TOY: case item_type::TOY:
case df::item_type::WEAPON: case item_type::WEAPON:
case df::item_type::ARMOR: case item_type::ARMOR:
case df::item_type::SHOES: case item_type::SHOES:
case df::item_type::SHIELD: case item_type::SHIELD:
case df::item_type::HELM: case item_type::HELM:
case df::item_type::GLOVES: case item_type::GLOVES:
case df::item_type::AMMO: case item_type::AMMO:
case df::item_type::PANTS: case item_type::PANTS:
case df::item_type::SIEGEAMMO: case item_type::SIEGEAMMO:
case df::item_type::TRAPCOMP: case item_type::TRAPCOMP:
case df::item_type::TOOL: case item_type::TOOL:
if (item_subtype == -1) if (item_subtype == -1)
{ {
out.printerr("You must specify a subtype!\n"); out.printerr("You must specify a subtype!\n");
@ -289,12 +294,12 @@ command_result df_createitem (color_ostream &out, vector <string> & parameters)
mat_index = material.index; mat_index = material.index;
break; break;
case df::item_type::REMAINS: case item_type::REMAINS:
case df::item_type::FISH: case item_type::FISH:
case df::item_type::FISH_RAW: case item_type::FISH_RAW:
case df::item_type::VERMIN: case item_type::VERMIN:
case df::item_type::PET: case item_type::PET:
case df::item_type::EGG: case item_type::EGG:
split_string(&tokens, material_str, ":"); split_string(&tokens, material_str, ":");
if (tokens.size() != 2) if (tokens.size() != 2)
{ {
@ -331,9 +336,9 @@ command_result df_createitem (color_ostream &out, vector <string> & parameters)
} }
break; break;
case df::item_type::CORPSE: case item_type::CORPSE:
case df::item_type::CORPSEPIECE: case item_type::CORPSEPIECE:
case df::item_type::FOOD: case item_type::FOOD:
out.printerr("Cannot create that type of item!\n"); out.printerr("Cannot create that type of item!\n");
return CR_FAILURE; return CR_FAILURE;
break; break;
@ -376,16 +381,16 @@ command_result df_createitem (color_ostream &out, vector <string> & parameters)
prod->count = count; prod->count = count;
switch (item_type) switch (item_type)
{ {
case df::item_type::BAR: case item_type::BAR:
case df::item_type::POWDER_MISC: case item_type::POWDER_MISC:
case df::item_type::LIQUID_MISC: case item_type::LIQUID_MISC:
case df::item_type::DRINK: case item_type::DRINK:
prod->product_dimension = 150; prod->product_dimension = 150;
break; break;
case df::item_type::THREAD: case item_type::THREAD:
prod->product_dimension = 15000; prod->product_dimension = 15000;
break; break;
case df::item_type::CLOTH: case item_type::CLOTH:
prod->product_dimension = 10000; prod->product_dimension = 10000;
break; break;
default: default:

File diff suppressed because it is too large Load Diff

@ -28,7 +28,7 @@ using namespace df::enums::ui_sidebar_mode;
DFHACK_PLUGIN("mousequery"); DFHACK_PLUGIN("mousequery");
#define PLUGIN_VERSION 0.17 #define PLUGIN_VERSION 0.18
static int32_t last_clicked_x, last_clicked_y, last_clicked_z; static int32_t last_clicked_x, last_clicked_y, last_clicked_z;
static int32_t last_pos_x, last_pos_y, last_pos_z; static int32_t last_pos_x, last_pos_y, last_pos_z;
@ -539,6 +539,13 @@ struct mousequery_hook : public df::viewscreen_dwarfmodest
if (mx < 1 || mx > right_margin - 2 || my < 1 || my > gps->dimy - 2) if (mx < 1 || mx > right_margin - 2 || my < 1 || my > gps->dimy - 2)
mpos_valid = false; mpos_valid = false;
// Check if in lever binding mode
if (Gui::getFocusString(Core::getTopViewscreen()) ==
"dwarfmode/QueryBuilding/Some/Lever/AddJob")
{
return;
}
if (mpos_valid) if (mpos_valid)
{ {
if (mpos.x != last_move_pos.x || mpos.y != last_move_pos.y || mpos.z != last_move_pos.z) if (mpos.x != last_move_pos.x || mpos.y != last_move_pos.y || mpos.z != last_move_pos.z)

@ -449,22 +449,22 @@ command_result revflood(color_ostream &out, vector<string> & params)
} }
if(sides) if(sides)
{ {
flood.push(foo(DFCoord(current.x + 1, current.y ,current.z),0)); flood.push(foo(DFCoord(current.x + 1, current.y ,current.z),false));
flood.push(foo(DFCoord(current.x + 1, current.y + 1 ,current.z),0)); flood.push(foo(DFCoord(current.x + 1, current.y + 1 ,current.z),false));
flood.push(foo(DFCoord(current.x, current.y + 1 ,current.z),0)); flood.push(foo(DFCoord(current.x, current.y + 1 ,current.z),false));
flood.push(foo(DFCoord(current.x - 1, current.y + 1 ,current.z),0)); flood.push(foo(DFCoord(current.x - 1, current.y + 1 ,current.z),false));
flood.push(foo(DFCoord(current.x - 1, current.y ,current.z),0)); flood.push(foo(DFCoord(current.x - 1, current.y ,current.z),false));
flood.push(foo(DFCoord(current.x - 1, current.y - 1 ,current.z),0)); flood.push(foo(DFCoord(current.x - 1, current.y - 1 ,current.z),false));
flood.push(foo(DFCoord(current.x, current.y - 1 ,current.z),0)); flood.push(foo(DFCoord(current.x, current.y - 1 ,current.z),false));
flood.push(foo(DFCoord(current.x + 1, current.y - 1 ,current.z),0)); flood.push(foo(DFCoord(current.x + 1, current.y - 1 ,current.z),false));
} }
if(above) if(above)
{ {
flood.push(foo(DFCoord(current.x, current.y ,current.z + 1),1)); flood.push(foo(DFCoord(current.x, current.y ,current.z + 1),true));
} }
if(below) if(below)
{ {
flood.push(foo(DFCoord(current.x, current.y ,current.z - 1),0)); flood.push(foo(DFCoord(current.x, current.y ,current.z - 1),false));
} }
} }
MCache->WriteAll(); MCache->WriteAll();

@ -210,9 +210,17 @@ module DFHack
out.last << wl.words[name.words[1]].forms[name.parts_of_speech[1]] if name.words[1] >= 0 out.last << wl.words[name.words[1]].forms[name.parts_of_speech[1]] if name.words[1] >= 0
end end
if name.words[5] >= 0 if name.words[5] >= 0
out << 'the ' out << 'the'
out.last.capitalize! if out.length == 1 out.last.capitalize! if out.length == 1
(2..5).each { |i| out.last << wl.words[name.words[i]].forms[name.parts_of_speech[i]] if name.words[i] >= 0 } out << wl.words[name.words[2]].forms[name.parts_of_speech[2]] if name.words[2] >= 0
out << wl.words[name.words[3]].forms[name.parts_of_speech[3]] if name.words[3] >= 0
if name.words[4] >= 0
out << wl.words[name.words[4]].forms[name.parts_of_speech[4]]
out.last << '-'
else
out << ''
end
out.last << wl.words[name.words[5]].forms[name.parts_of_speech[5]]
end end
if name.words[6] >= 0 if name.words[6] >= 0
out << 'of' out << 'of'

@ -180,6 +180,10 @@ public:
{ {
// Query typing mode // Query typing mode
if (input->empty())
{
return false;
}
df::interface_key last_token = *input->rbegin(); df::interface_key last_token = *input->rbegin();
if (last_token >= interface_key::STRING_A032 && last_token <= interface_key::STRING_A126) if (last_token >= interface_key::STRING_A032 && last_token <= interface_key::STRING_A126)
{ {

@ -0,0 +1,393 @@
/*
* Stockflow plugin.
* For best effect, place "stockflow enable" in your dfhack.init configuration,
* or set AUTOENABLE to true.
*/
#include "uicommon.h"
#include "LuaTools.h"
#include "df/building_stockpilest.h"
#include "df/job.h"
#include "df/viewscreen_dwarfmodest.h"
#include "modules/Gui.h"
#include "modules/Maps.h"
#include "modules/World.h"
using namespace DFHack;
using namespace std;
using df::global::world;
using df::global::ui;
using df::building_stockpilest;
DFHACK_PLUGIN("stockflow");
#define AUTOENABLE false
#ifdef DFHACK_PLUGIN_IS_ENABLED
DFHACK_PLUGIN_IS_ENABLED(enabled);
#else
bool enabled = false;
#endif
const char *tagline = "Allows the fortress bookkeeper to queue jobs through the manager.";
const char *usage = (
" stockflow enable\n"
" Enable the plugin.\n"
" stockflow disable\n"
" Disable the plugin.\n"
" stockflow list\n"
" List any work order settings for your stockpiles.\n"
" stockflow status\n"
" Display whether the plugin is enabled.\n"
"\n"
"While enabled, the 'q' menu of each stockpile will have two new options:\n"
" j: Select a job to order, from an interface like the manager's screen.\n"
" J: Cycle between several options for how many such jobs to order.\n"
"\n"
"Whenever the bookkeeper updates stockpile records, new work orders will\n"
"be placed on the manager's queue for each such selection, reduced by the\n"
"number of identical orders already in the queue.\n"
);
/*
* Lua interface.
* Currently calls out to Lua functions, but never back in.
*/
class LuaHelper {
public:
void cycle(color_ostream &out) {
bool found = false;
for (df::job_list_link* link = &df::global::world->job_list; link != NULL; link = link->next) {
if (link->item == NULL) continue;
if (link->item->job_type == job_type::UpdateStockpileRecords) {
found = true;
break;
}
}
if (found && !bookkeeping) {
command_method("start_bookkeeping", out);
bookkeeping = true;
} else if (bookkeeping && !found) {
command_method("finish_bookkeeping", out);
bookkeeping = false;
}
}
void init() {
stockpile_id = -1;
initialized = false;
bookkeeping = false;
}
bool reset(color_ostream &out, bool load) {
stockpile_id = -1;
bookkeeping = false;
if (load) {
return initialized = command_method("initialize_world", out);
} else if (initialized) {
initialized = false;
return command_method("clear_caches", out);
}
return true;
}
bool command_method(const char *method, color_ostream &out) {
// Calls a lua function with no parameters.
// Suspension is required for "stockflow enable" from the command line,
// but may be overkill for other situations.
CoreSuspender suspend;
auto L = Lua::Core::State;
Lua::StackUnwinder top(L);
if (!lua_checkstack(L, 1))
return false;
if (!Lua::PushModulePublic(out, L, "plugins.stockflow", method))
return false;
if (!Lua::SafeCall(out, L, 0, 0))
return false;
return true;
}
bool stockpile_method(const char *method, building_stockpilest *sp) {
// Combines the select_order and toggle_trigger method calls,
// because they share the same signature.
CoreSuspendClaimer suspend;
auto L = Lua::Core::State;
color_ostream_proxy out(Core::getInstance().getConsole());
Lua::StackUnwinder top(L);
if (!lua_checkstack(L, 2))
return false;
if (!Lua::PushModulePublic(out, L, "plugins.stockflow", method))
return false;
Lua::Push(L, sp);
if (!Lua::SafeCall(out, L, 1, 0))
return false;
// Invalidate the string cache.
stockpile_id = -1;
return true;
}
bool collect_settings(building_stockpilest *sp) {
// Find strings representing the job to order, and the trigger condition.
// There might be a memory leak here; C++ is odd like that.
auto L = Lua::Core::State;
color_ostream_proxy out(Core::getInstance().getConsole());
CoreSuspendClaimer suspend;
Lua::StackUnwinder top(L);
if (!lua_checkstack(L, 2))
return false;
if (!Lua::PushModulePublic(out, L, "plugins.stockflow", "stockpile_settings"))
return false;
Lua::Push(L, sp);
if (!Lua::SafeCall(out, L, 1, 2))
return false;
if (!lua_isstring(L, -1))
return false;
current_trigger = lua_tostring(L, -1);
lua_pop(L, 1);
if (!lua_isstring(L, -1))
return false;
current_job = lua_tostring(L, -1);
lua_pop(L, 1);
stockpile_id = sp->id;
return true;
}
void draw(building_stockpilest *sp) {
if (sp->id != stockpile_id) {
if (!collect_settings(sp)) {
Core::printerr("Stockflow job collection failed!\n");
return;
}
}
auto dims = Gui::getDwarfmodeViewDims();
int left_margin = dims.menu_x1 + 1;
int x = left_margin;
int y = 14;
OutputHotkeyString(x, y, current_job, "j", true, left_margin, COLOR_WHITE, COLOR_LIGHTRED);
if (*current_trigger)
OutputHotkeyString(x, y, current_trigger, " J", true, left_margin, COLOR_WHITE, COLOR_LIGHTRED);
}
private:
long stockpile_id;
bool initialized;
bool bookkeeping;
const char *current_job;
const char *current_trigger;
};
static LuaHelper helper;
#define DELTA_TICKS 600
DFhackCExport command_result plugin_onupdate(color_ostream &out) {
if (!enabled)
return CR_OK;
if (!Maps::IsValid())
return CR_OK;
static decltype(world->frame_counter) last_frame_count = 0;
if (DFHack::World::ReadPauseState())
return CR_OK;
if (world->frame_counter - last_frame_count < DELTA_TICKS)
return CR_OK;
last_frame_count = world->frame_counter;
helper.cycle(out);
return CR_OK;
}
/*
* Interface hooks
*/
struct stockflow_hook : public df::viewscreen_dwarfmodest {
typedef df::viewscreen_dwarfmodest interpose_base;
bool handleInput(set<df::interface_key> *input) {
building_stockpilest *sp = get_selected_stockpile();
if (!sp)
return false;
if (input->count(interface_key::CUSTOM_J)) {
// Select a new order for this stockpile.
if (!helper.stockpile_method("select_order", sp)) {
Core::printerr("Stockflow order selection failed!\n");
}
return true;
} else if (input->count(interface_key::CUSTOM_SHIFT_J)) {
// Toggle the order trigger for this stockpile.
if (!helper.stockpile_method("toggle_trigger", sp)) {
Core::printerr("Stockflow trigger toggle failed!\n");
}
return true;
}
return false;
}
DEFINE_VMETHOD_INTERPOSE(void, feed, (set<df::interface_key> *input)) {
if (!handleInput(input))
INTERPOSE_NEXT(feed)(input);
}
DEFINE_VMETHOD_INTERPOSE(void, render, ()) {
INTERPOSE_NEXT(render)();
building_stockpilest *sp = get_selected_stockpile();
if (sp)
helper.draw(sp);
}
};
IMPLEMENT_VMETHOD_INTERPOSE(stockflow_hook, feed);
IMPLEMENT_VMETHOD_INTERPOSE(stockflow_hook, render);
static bool apply_hooks(color_ostream &out, bool enabling) {
if (enabling && !gps) {
out.printerr("Stockflow needs graphics.\n");
return false;
}
if (!INTERPOSE_HOOK(stockflow_hook, feed).apply(enabling) || !INTERPOSE_HOOK(stockflow_hook, render).apply(enabling)) {
out.printerr("Could not %s stockflow hooks!\n", enabling? "insert": "remove");
return false;
}
if (!helper.reset(out, enabling && Maps::IsValid())) {
out.printerr("Could not reset stockflow world data!\n");
return false;
}
return true;
}
static command_result stockflow_cmd(color_ostream &out, vector <string> & parameters) {
bool desired = enabled;
if (parameters.size() == 1) {
if (parameters[0] == "enable" || parameters[0] == "on" || parameters[0] == "1") {
desired = true;
} else if (parameters[0] == "disable" || parameters[0] == "off" || parameters[0] == "0") {
desired = false;
} else if (parameters[0] == "usage" || parameters[0] == "help" || parameters[0] == "?") {
out.print("%s: %s\nUsage:\n%s", name, tagline, usage);
return CR_OK;
} else if (parameters[0] == "list") {
if (!enabled) {
out.printerr("Stockflow is not currently enabled.\n");
return CR_FAILURE;
}
if (!Maps::IsValid()) {
out.printerr("You haven't loaded a map yet.\n");
return CR_FAILURE;
}
// Tell Lua to list any saved stockpile orders.
return helper.command_method("list_orders", out)? CR_OK: CR_FAILURE;
} else if (parameters[0] != "status") {
return CR_WRONG_USAGE;
}
} else if (parameters.size() > 1) {
return CR_WRONG_USAGE;
}
if (desired != enabled) {
if (!apply_hooks(out, desired)) {
return CR_FAILURE;
}
}
out.print("Stockflow is %s %s.\n", (desired == enabled)? "currently": "now", desired? "enabled": "disabled");
enabled = desired;
return CR_OK;
}
DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_change_event event) {
if (event == DFHack::SC_MAP_LOADED) {
if (!helper.reset(out, enabled)) {
out.printerr("Could not load stockflow world data!\n");
return CR_FAILURE;
}
} else if (event == DFHack::SC_MAP_UNLOADED) {
if (!helper.reset(out, false)) {
out.printerr("Could not unload stockflow world data!\n");
return CR_FAILURE;
}
}
return CR_OK;
}
DFhackCExport command_result plugin_enable(color_ostream& out, bool enable) {
/* Accept the "enable stockflow"/"disable stockflow" syntax, where available. */
/* Same as "stockflow enable"/"stockflow disable" except without the status line. */
if (enable != enabled) {
if (!apply_hooks(out, enable)) {
return CR_FAILURE;
}
enabled = enable;
}
return CR_OK;
}
DFhackCExport command_result plugin_init(color_ostream &out, std::vector <PluginCommand> &commands) {
helper.init();
if (AUTOENABLE) {
if (!apply_hooks(out, true)) {
return CR_FAILURE;
}
enabled = true;
}
commands.push_back(PluginCommand(name, tagline, stockflow_cmd, false, usage));
return CR_OK;
}
DFhackCExport command_result plugin_shutdown(color_ostream &out) {
return plugin_enable(out, false);
}

@ -126,7 +126,7 @@ int getCreatedMetalBars (int32_t idx)
return 0; return 0;
} }
void selectWord (const df::world_raws::T_language::T_word_table &table, int32_t &word, df::enum_field<df::part_of_speech,int16_t> &part, int mode) void selectWord (const df::language_word_table &table, int32_t &word, df::enum_field<df::part_of_speech,int16_t> &part, int mode)
{ {
if (table.parts[mode].size()) if (table.parts[mode].size())
{ {
@ -142,7 +142,7 @@ void selectWord (const df::world_raws::T_language::T_word_table &table, int32_t
} }
} }
void generateName(df::language_name &output, int language, int mode, const df::world_raws::T_language::T_word_table &table1, const df::world_raws::T_language::T_word_table &table2) void generateName(df::language_name &output, int language, int mode, const df::language_word_table &table1, const df::language_word_table &table2)
{ {
for (int i = 0; i < 100; i++) for (int i = 0; i < 100; i++)
{ {

@ -1,8 +1,29 @@
-- a graphical mod manager for df
local gui=require 'gui' local gui=require 'gui'
local widgets=require 'gui.widgets' local widgets=require 'gui.widgets'
local entity_file=dfhack.getDFPath().."/raw/objects/entity_default.txt" local entity_file=dfhack.getDFPath().."/raw/objects/entity_default.txt"
local init_file=dfhack.getDFPath().."/raw/init.lua" local init_file=dfhack.getDFPath().."/raw/init.lua"
local mod_dir=dfhack.getDFPath().."/hack/mods"
--[[ mod format: lua script that defines:
name - a name that is displayed in list
author - mod author, also displayed
description - mod description
OPTIONAL:
raws_list - a list (table) of file names that need to be copied over to df raws
patch_entity - a chunk of text to patch entity TODO: add settings to which entities to add
patch_init - a chunk of lua to add to lua init
patch_dofile - a list (table) of files to add to lua init as "dofile"
patch_files - a table of files to patch:
filename - a filename (in raws folder) to patch
patch - what to add
after - a string after which to insert
MORE OPTIONAL:
guard - a token that is used in raw files to find editions and remove them on uninstall
guard_init - a token for lua file
[pre|post]_(un)install - callback functions. Can trigger more complicated behavior
]]
function fileExists(filename) function fileExists(filename)
local file=io.open(filename,"rb") local file=io.open(filename,"rb")
if file==nil then if file==nil then
@ -12,6 +33,10 @@ function fileExists(filename)
return true return true
end end
end end
if not fileExists(init_file) then
local initFile=io.open(initFileName,"a")
initFile:close()
end
function copyFile(from,to) --oh so primitive function copyFile(from,to) --oh so primitive
local filefrom=io.open(from,"rb") local filefrom=io.open(from,"rb")
local fileto=io.open(to,"w+b") local fileto=io.open(to,"w+b")
@ -27,6 +52,16 @@ function patchInit(initFileName,patch_guard,code)
code,patch_guard[2])) code,patch_guard[2]))
initFile:close() initFile:close()
end end
function patchDofile( initFileName,patch_guard,dofile_list )
local initFile=io.open(initFileName,"a")
initFile:write(patch_guard[1].."\n")
for _,v in ipairs(dofile_list) do
local fixed_path=mod_dir:gsub("\\","/")
initFile:write(string.format("dofile('%s/%s')\n",fixed_path,v))
end
initFile:write(patch_guard[2].."\n")
initFile:close()
end
function patchFile(file_name,patch_guard,after_string,code) function patchFile(file_name,patch_guard,after_string,code)
local input_lines=patch_guard[1].."\n"..code.."\n"..patch_guard[2] local input_lines=patch_guard[1].."\n"..code.."\n"..patch_guard[2]
@ -109,15 +144,19 @@ manager=defclass(manager,gui.FramedScreen)
function manager:init(args) function manager:init(args)
self.mods={} self.mods={}
local mods=self.mods local mods=self.mods
local mlist=dfhack.internal.getDir("mods") local mlist=dfhack.internal.getDir(mod_dir)
if #mlist==0 then
qerror("Mod directory not found! Are you sure it is in:"..mod_dir)
end
for k,v in ipairs(mlist) do for k,v in ipairs(mlist) do
if v~="." and v~=".." then if v~="." and v~=".." then
local f,modData=pcall(dofile,"mods/".. v .. "/init.lua") local f,modData=pcall(dofile,mod_dir.."/".. v .. "/init.lua")
if f then if f then
mods[modData.name]=modData mods[modData.name]=modData
modData.guard=modData.guard or {">>"..modData.name.." patch","<<End "..modData.name.." patch"} modData.guard=modData.guard or {">>"..modData.name.." patch","<<End "..modData.name.." patch"}
modData.guard_init={"--"..modData.guard[1],"--"..modData.guard[2]} modData.guard_init={"--"..modData.guard[1],"--"..modData.guard[2]}
modData.path=dfhack.getDFPath()..'/mods/'..v..'/' modData.path=mod_dir.."/"..v..'/'
end end
end end
end end
@ -254,7 +293,9 @@ function manager:install(trgMod,force)
if trgMod.patch_init then if trgMod.patch_init then
patchInit(init_file,trgMod.guard_init,trgMod.patch_init) patchInit(init_file,trgMod.guard_init,trgMod.patch_init)
end end
if trgMod.patch_dofile then
patchDofile(init_file,trgMod.guard_init,trgMod.patch_dofile)
end
trgMod.installed=true trgMod.installed=true
if trgMod.post_install then if trgMod.post_install then
@ -281,9 +322,10 @@ function manager:uninstall(trgMod)
unPatchFile(dfhack.getDFPath().."/raw/objects/"..v.filename,trgMod.guard) unPatchFile(dfhack.getDFPath().."/raw/objects/"..v.filename,trgMod.guard)
end end
end end
if trgMod.patch_init then if trgMod.patch_init or trgMod.patch_dofile then
unPatchFile(init_file,trgMod.guard_init) unPatchFile(init_file,trgMod.guard_init)
end end
trgMod.installed=false trgMod.installed=false
if trgMod.post_uninstall then if trgMod.post_uninstall then
trgMod.post_uninstall(args) trgMod.post_uninstall(args)