From ffe2365550b6c96a079261168caba806a36d3be2 Mon Sep 17 00:00:00 2001 From: DFHack-Urist via GitHub Actions <63161697+DFHack-Urist@users.noreply.github.com> Date: Wed, 21 Sep 2022 07:42:18 +0000 Subject: [PATCH 01/73] Auto-update submodules scripts: master --- scripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts b/scripts index 484988bb3..8c03de45b 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 484988bb3d64f7aed9442af3b226faa77d8fd00d +Subproject commit 8c03de45ba8e772239224b49af2617fc714fbaa9 From 39acd3e9925f199672a98dcab6c94fa724b74eca Mon Sep 17 00:00:00 2001 From: myk002 Date: Wed, 21 Sep 2022 08:59:01 -0700 Subject: [PATCH 02/73] don't display overlay on trade goods screen so it doesn't overlap the trade value label --- plugins/overlay.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/overlay.cpp b/plugins/overlay.cpp index 30a5546a4..1a0cc7c02 100644 --- a/plugins/overlay.cpp +++ b/plugins/overlay.cpp @@ -70,7 +70,6 @@ #include "df/viewscreen_topicmeetingst.h" #include "df/viewscreen_topicmeeting_takerequestsst.h" #include "df/viewscreen_tradeagreementst.h" -#include "df/viewscreen_tradegoodsst.h" #include "df/viewscreen_tradelistst.h" #include "df/viewscreen_treasurelistst.h" #include "df/viewscreen_unitlist_page.h" @@ -211,7 +210,6 @@ IMPLEMENT_HOOKS(topicmeeting_fill_land_holder_positions) IMPLEMENT_HOOKS(topicmeeting) IMPLEMENT_HOOKS(topicmeeting_takerequests) IMPLEMENT_HOOKS(tradeagreement) -IMPLEMENT_HOOKS(tradegoods) IMPLEMENT_HOOKS(tradelist) IMPLEMENT_HOOKS(treasurelist) IMPLEMENT_HOOKS(unitlist) @@ -310,7 +308,6 @@ DFhackCExport command_result plugin_enable(color_ostream &, bool enable) { INTERPOSE_HOOKS_FAILED(topicmeeting) || INTERPOSE_HOOKS_FAILED(topicmeeting_takerequests) || INTERPOSE_HOOKS_FAILED(tradeagreement) || - INTERPOSE_HOOKS_FAILED(tradegoods) || INTERPOSE_HOOKS_FAILED(tradelist) || INTERPOSE_HOOKS_FAILED(treasurelist) || INTERPOSE_HOOKS_FAILED(unitlist) || From 9fb037574dd7a6de5c1324e499d7f94dc8b95ceb Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Wed, 21 Sep 2022 06:58:42 -0700 Subject: [PATCH 03/73] add readthedocs configuration --- .readthedocs.requirements.txt | 1 + .readthedocs.yaml | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 .readthedocs.requirements.txt create mode 100644 .readthedocs.yaml diff --git a/.readthedocs.requirements.txt b/.readthedocs.requirements.txt new file mode 100644 index 000000000..122610498 --- /dev/null +++ b/.readthedocs.requirements.txt @@ -0,0 +1 @@ +sphinx<4.4.0 diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 000000000..f3637b24b --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,17 @@ +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +version: 2 + +build: + os: ubuntu-20.04 + tools: + python: "3" + +sphinx: + configuration: conf.py + +python: + install: + - requirements: .readthedocs.requirements.txt From 2ef2ec66b6f48bec4a1aa8c90591be0d28cd7ac9 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Wed, 21 Sep 2022 09:42:42 -0700 Subject: [PATCH 04/73] update min sphinx version to 3.4.3 it might be able to go lower, but sphinx 1.8.6 is too low (it doesn't support the calls we make to generate the genindex entries) --- conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf.py b/conf.py index 68d11f0f9..0170a872b 100644 --- a/conf.py +++ b/conf.py @@ -138,7 +138,7 @@ generate_tag_indices() # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. -needs_sphinx = '1.8' +needs_sphinx = '3.4.3' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom From 2a13664b36feab52c451cf3082b292c5c0871d8e Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Wed, 21 Sep 2022 10:03:51 -0700 Subject: [PATCH 05/73] rename yaml to yml --- .readthedocs.yaml => .readthedocs.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .readthedocs.yaml => .readthedocs.yml (100%) diff --git a/.readthedocs.yaml b/.readthedocs.yml similarity index 100% rename from .readthedocs.yaml rename to .readthedocs.yml From a1c57ccafd6c6abf520889cb54761c6facc83326 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Wed, 21 Sep 2022 10:07:20 -0700 Subject: [PATCH 06/73] pin the sphinx version exactly at 4.4.0 --- .readthedocs.requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.readthedocs.requirements.txt b/.readthedocs.requirements.txt index 122610498..1f028de41 100644 --- a/.readthedocs.requirements.txt +++ b/.readthedocs.requirements.txt @@ -1 +1 @@ -sphinx<4.4.0 +sphinx==4.4.0 From 35152bf02250061dee89136f786ee91c1a3a9600 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Tue, 20 Sep 2022 22:51:44 -0700 Subject: [PATCH 07/73] create genindex entries for all tools and commands --- docs/sphinx_extensions/dfhack/tool_docs.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/docs/sphinx_extensions/dfhack/tool_docs.py b/docs/sphinx_extensions/dfhack/tool_docs.py index c7883e14c..6f5df5568 100644 --- a/docs/sphinx_extensions/dfhack/tool_docs.py +++ b/docs/sphinx_extensions/dfhack/tool_docs.py @@ -8,14 +8,18 @@ import os from typing import List, Optional, Type import docutils.nodes as nodes +from docutils.nodes import Node import docutils.parsers.rst.directives as rst_directives import sphinx import sphinx.addnodes as addnodes import sphinx.directives +from sphinx.util.docutils import SphinxDirective +from sphinx.util.nodes import process_index_entry import dfhack.util + logger = sphinx.util.logging.getLogger(__name__) @@ -46,6 +50,17 @@ def make_summary(builder: sphinx.builders.Builder, summary: str) -> nodes.paragr para += nodes.inline(text=summary) return para +def make_index(directive: SphinxDirective, name: str, summary: str) -> List[Node]: + targetid = 'index-%s' % directive.env.new_serialno('index') + targetnode = nodes.target('', '', ids=[targetid]) + directive.state.document.note_explicit_target(targetnode) + indexnode = addnodes.index() + indexnode['entries'] = [] + indexnode['inline'] = False + directive.set_source_info(indexnode) + entry_text = 'single: {}; {}'.format(name, summary) + indexnode['entries'].extend(process_index_entry(entry_text, targetnode['ids'][0])) + return [indexnode, targetnode] _KEYBINDS = {} _KEYBINDS_RENDERED = set() # commands whose keybindings have been rendered @@ -160,6 +175,7 @@ class DFHackToolDirective(DFHackToolDirectiveBase): ret_nodes = [tag_paragraph] if 'no-command' in self.options: + ret_nodes += make_index(self, self.get_name_or_docname() + ' (plugin)', self.options.get('summary', '')) ret_nodes += [make_summary(self.env.app.builder, self.options.get('summary', ''))] return ret_nodes @@ -177,11 +193,13 @@ class DFHackCommandDirective(DFHackToolDirectiveBase): def render_content(self) -> List[nodes.Node]: command = self.get_name_or_docname() - return [ - self.make_labeled_paragraph('Command', command, content_class=nodes.literal), + ret_nodes = [self.make_labeled_paragraph('Command', command, content_class=nodes.literal)] + ret_nodes += make_index(self, command, self.options.get('summary', '')) + ret_nodes += [ make_summary(self.env.app.builder, self.options.get('summary', '')), *render_dfhack_keybind(command, builder=self.env.app.builder), ] + return ret_nodes def register(app): From 682ed29c0cef0601ff85c7216714937a6ca8c0ab Mon Sep 17 00:00:00 2001 From: myk002 Date: Wed, 21 Sep 2022 10:36:46 -0700 Subject: [PATCH 08/73] replace deprecated support page with a redirect configured on the readthedocs web admin page --- docs/Support.rst | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 docs/Support.rst diff --git a/docs/Support.rst b/docs/Support.rst deleted file mode 100644 index af8bd583c..000000000 --- a/docs/Support.rst +++ /dev/null @@ -1,3 +0,0 @@ -:orphan: - -Please continue to the new `support` page. From e36f6ea8441d8a80a50e99f38d67b8f27225e717 Mon Sep 17 00:00:00 2001 From: myk002 Date: Wed, 21 Sep 2022 10:40:08 -0700 Subject: [PATCH 09/73] also build pdf format --- .readthedocs.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index f3637b24b..88ee132ec 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -10,8 +10,11 @@ build: python: "3" sphinx: - configuration: conf.py + configuration: conf.py + +formats: + - pdf python: - install: - - requirements: .readthedocs.requirements.txt + install: + - requirements: .readthedocs.requirements.txt From ee51e830ad01f428c757e3738d8434e9d65c9b2f Mon Sep 17 00:00:00 2001 From: myk002 Date: Wed, 21 Sep 2022 10:40:17 -0700 Subject: [PATCH 10/73] update wording in Tools docs --- docs/Tools.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/Tools.rst b/docs/Tools.rst index 623fc9c1f..89f712568 100644 --- a/docs/Tools.rst +++ b/docs/Tools.rst @@ -30,9 +30,11 @@ guildhalls and temples that you have agreed to. Finding the tool you need ------------------------- -DFHack tools are tagged with categories to make them easier to find. Note that a -tool can belong to more than one category. If you'd like to see the full list of -tools in one flat list, please refer to the `index `. +DFHack tools are tagged with categories to make them easier to find. These +categories are listed in the next few sections. Note that a tool can belong to +more than one category. If you already know what you're looking for, try the +`search` box or Ctrl-F on this page. If you'd like to see the full list of tools +in one flat list, please refer to the `alphabetized index `. DFHack tools by game mode ------------------------- From 2e64464bb8be74dc3cb2cc30ea684f2e50ac1a07 Mon Sep 17 00:00:00 2001 From: myk002 Date: Wed, 21 Sep 2022 10:44:01 -0700 Subject: [PATCH 11/73] reword sentence after title expansion --- docs/Tools.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/Tools.rst b/docs/Tools.rst index 89f712568..aeff179aa 100644 --- a/docs/Tools.rst +++ b/docs/Tools.rst @@ -33,8 +33,8 @@ Finding the tool you need DFHack tools are tagged with categories to make them easier to find. These categories are listed in the next few sections. Note that a tool can belong to more than one category. If you already know what you're looking for, try the -`search` box or Ctrl-F on this page. If you'd like to see the full list of tools -in one flat list, please refer to the `alphabetized index `. +`search` or Ctrl-F on this page. If you'd like to see the full list of tools in +one flat list, please refer to the `alphabetized index `. DFHack tools by game mode ------------------------- From b6dee4b0f189318270cd0f5f9993fb3970379ec9 Mon Sep 17 00:00:00 2001 From: myk002 Date: Wed, 21 Sep 2022 10:45:27 -0700 Subject: [PATCH 12/73] build all formats --- .readthedocs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index 88ee132ec..f1e062683 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -13,7 +13,7 @@ sphinx: configuration: conf.py formats: - - pdf + - all python: install: From 7f31b612aed3725cbdd0ff41e8cd8065ae8b8adf Mon Sep 17 00:00:00 2001 From: myk002 Date: Wed, 21 Sep 2022 10:47:02 -0700 Subject: [PATCH 13/73] readthedocs doesn't like "all", list separately --- .readthedocs.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index f1e062683..1e570e571 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -13,7 +13,9 @@ sphinx: configuration: conf.py formats: - - all + - htmlzip + - pdf + - epub python: install: From 30100bec8fb1650d62af11e48b9757af5ed9f3e3 Mon Sep 17 00:00:00 2001 From: Tachytaenius Date: Thu, 22 Sep 2022 20:23:56 +0100 Subject: [PATCH 14/73] Add link to Tachy Guns and show more code configurations in guide --- docs/guides/modding-guide.rst | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/docs/guides/modding-guide.rst b/docs/guides/modding-guide.rst index fa0510290..cc7d507d5 100644 --- a/docs/guides/modding-guide.rst +++ b/docs/guides/modding-guide.rst @@ -348,6 +348,9 @@ timer:: The structure of a full mod --------------------------- +For reference, `Tachy Guns `__ is a +full mod that conforms to this guide. + Create a folder for mod projects somewhere outside your Dwarf Fortress installation directory (e.g. ``/path/to/mymods/``) and use your mod IDs as the names for the mod folders within it. In the example below, we'll use a mod ID of @@ -425,13 +428,18 @@ Ok, you're all set up! Now, let's take a look at an example moduleA.onLoad() moduleB.onLoad() - -- register your callbacks - repeatUtil.scheduleEvery(modId .. ' every tick', 1, 'ticks', - moduleA.every1Tick) + -- multiple functions in the same repeat callback + repeatUtil.scheduleEvery(modId .. ' every tick', 1, 'ticks', function() + moduleA.every1Tick() + moduleB.every1Tick() + end) + + -- one function per repeat callback (you can put them in the + -- above format if you prefer) repeatUtil.scheduleEvery(modId .. ' 100 frames', 1, 'frames', moduleD.every100Frames) - -- multiple functions in the same callback + -- multiple functions in the same eventful callback eventful.onReactionComplete[modId] = function(reaction, reaction_product, unit, input_items, input_reagents, output_items) @@ -442,7 +450,7 @@ Ok, you're all set up! Now, let's take a look at an example unit, input_items, input_reagents, output_items) end - -- one function per callback (you can put them in the + -- one function per eventful callback (you can put them in the -- above format if you prefer) eventful.onProjItemCheckMovement[modId] = moduleD.onProjItemCheckMovement eventful.onProjUnitCheckMovement[modId] = moduleD.onProjUnitCheckMovement From 6810f9bb903419f3225d2567f6f7260e27492e0e Mon Sep 17 00:00:00 2001 From: Tachytaenius Date: Thu, 22 Sep 2022 20:31:43 +0100 Subject: [PATCH 15/73] Remove empty indented line --- docs/guides/modding-guide.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guides/modding-guide.rst b/docs/guides/modding-guide.rst index cc7d507d5..4b768be58 100644 --- a/docs/guides/modding-guide.rst +++ b/docs/guides/modding-guide.rst @@ -433,7 +433,7 @@ Ok, you're all set up! Now, let's take a look at an example moduleA.every1Tick() moduleB.every1Tick() end) - + -- one function per repeat callback (you can put them in the -- above format if you prefer) repeatUtil.scheduleEvery(modId .. ' 100 frames', 1, 'frames', From 4d662adfe56618919a917e7c7279cc948d7264a4 Mon Sep 17 00:00:00 2001 From: Myk Date: Thu, 22 Sep 2022 17:39:54 -0700 Subject: [PATCH 16/73] Fix marker checking for ruby help text --- library/lua/helpdb.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/lua/helpdb.lua b/library/lua/helpdb.lua index e5359b323..655b4143b 100644 --- a/library/lua/helpdb.lua +++ b/library/lua/helpdb.lua @@ -275,7 +275,7 @@ local function make_script_entry(old_entry, entry_name, kwargs) local is_rb = source_path:endswith('.rb') update_entry(entry, lines, {begin_marker=(is_rb and SCRIPT_DOC_BEGIN_RUBY or SCRIPT_DOC_BEGIN), - end_marker=(is_rb and SCRIPT_DOC_BEGIN_RUBY or SCRIPT_DOC_END), + end_marker=(is_rb and SCRIPT_DOC_END_RUBY or SCRIPT_DOC_END), first_line_is_short_help=(is_rb and '#' or '%-%-')}) return entry end From b07f3b5b6c3143d27643c2b8106644fd93a54ccf Mon Sep 17 00:00:00 2001 From: Myk Date: Thu, 22 Sep 2022 17:43:56 -0700 Subject: [PATCH 17/73] stub help formatted same as real help --- library/lua/helpdb.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/lua/helpdb.lua b/library/lua/helpdb.lua index 655b4143b..dc9eb1738 100644 --- a/library/lua/helpdb.lua +++ b/library/lua/helpdb.lua @@ -120,7 +120,7 @@ No help available. ]] local function make_default_entry(entry_name, help_source, kwargs) local default_long_help = DEFAULT_HELP_TEMPLATE:format( - entry_name, ('*'):rep(#entry_name)) + entry_name, ('='):rep(#entry_name)) return { help_source=help_source, short_help='No help available.', From fae26b2375304265449f174b16e8ffc5917ffecc Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 23 Sep 2022 08:34:22 -0700 Subject: [PATCH 18/73] replace die's underline with tombstones easter egg suggested by thurin : ) --- library/lua/helpdb.lua | 2 + test/library/helpdb.lua | 116 +++++++++++++++++++--------------------- 2 files changed, 57 insertions(+), 61 deletions(-) diff --git a/library/lua/helpdb.lua b/library/lua/helpdb.lua index dc9eb1738..c39d3ba80 100644 --- a/library/lua/helpdb.lua +++ b/library/lua/helpdb.lua @@ -321,6 +321,8 @@ local function scan_builtins(old_db) HELP_SOURCES.RENDERED or HELP_SOURCES.STUB, {entry_types=entry_types}) end + -- easter egg: replace underline for 'die' help with tombstones + textdb.die.long_help = textdb.die.long_help:gsub('=', string.char(239)) end -- scan for enableable plugins and plugin-provided commands and add their help diff --git a/test/library/helpdb.lua b/test/library/helpdb.lua index 7a223bcaa..067f35532 100644 --- a/test/library/helpdb.lua +++ b/test/library/helpdb.lua @@ -42,10 +42,7 @@ local files = { ['hack/docs/docs/Tags.txt']=[[ * fort: Tools that are useful while in fort mode. -* armok: Tools that give you complete control over - an aspect of the game or provide access to - information that the game intentionally keeps - hidden. +* armok: Tools that give you complete control over an aspect of the game or provide access to information that the game intentionally keeps hidden. * map: Tools that interact with the game map. @@ -55,68 +52,65 @@ local files = { ]], ['hack/docs/docs/tools/hascommands.txt']=[[ hascommands -*********** +=========== -**Tags:** fort | armok | units +Tags: fort | armok | units -Documented a plugin that -has commands. + Documented a plugin that has commands. -**Command:** "boxbinders" +Command: "boxbinders" -Documented boxbinders. + Documented boxbinders. -**Command:** "bindboxers" +Command: "bindboxers" -Documented bindboxers. + Documented bindboxers. Documented full help. ]], ['hack/docs/docs/tools/samename.txt']=[[ samename -******** +======== -**Tags:** fort | armok -| units +Tags: fort | armok | units -**Command:** "samename" +Command: "samename" -Documented samename. + Documented samename. Documented full help. ]], ['hack/docs/docs/tools/nocommand.txt']=[[ nocommand -********* +========= -**Tags:** fort | armok | -units +Tags: fort | armok | units -Documented nocommand. + Documented nocommand. Documented full help. ]], ['hack/docs/docs/tools/basic.txt']=[[ basic -***** +===== -**Tags:** map +Tags: map -**Command:** "basic" +Command: "basic" -Documented basic. + Documented basic. Documented full help. ]], ['hack/docs/docs/tools/subdir/scriptname.txt']=[[ subdir/scriptname -***************** +================= -**Tags:** map +Tags: map -**Command:** "subdir/scriptname" +Command: "subdir/scriptname" -Documented subdir/scriptname. + Documented subdir/scriptname. Documented full help. ]], @@ -126,11 +120,11 @@ Documented full help. basic ===== -**Tags:** map +Tags: map -**Command:** "basic" +Command: "basic" -in-file basic. + in-file basic. Documented full help. ]====] @@ -142,11 +136,11 @@ script contents subdir/scriptname ================= -**Tags:** map +Tags: map -**Command:** "subdir/scriptname" +Command: "subdir/scriptname" -in-file scriptname. + in-file scriptname. Documented full help. ]====] @@ -158,11 +152,11 @@ script contents inscript_docs ============= -**Tags:** map | badtag +Tags: map | badtag -**Command:** "inscript_docs" +Command: "inscript_docs" -in-file inscript_docs. + in-file inscript_docs. Documented full help. ]====] @@ -182,11 +176,11 @@ script contents basic ===== -**Tags:** map +Tags: map -**Command:** "basic" +Command: "basic" -in-file basic (other). + in-file basic (other). Documented full help. ]====] @@ -198,11 +192,11 @@ script contents subdir/scriptname ================= -**Tags:** map +Tags: map -**Command:** "subdir/scriptname" +Command: "subdir/scriptname" -in-file scriptname (other). + in-file scriptname (other). Documented full help. ]====] @@ -214,11 +208,11 @@ script contents inscript_docs ============= -**Tags:** map +Tags: map -**Command:** "inscript_docs" +Command: "inscript_docs" -in-file inscript_docs (other). + in-file inscript_docs (other). Documented full help. ]====] @@ -400,15 +394,15 @@ end function test.get_entry_long_help() local expected = [[ basic -***** +===== -**Tags:** map +Tags: map -**Command:** +Command: "basic" -Documented -basic. + Documented + basic. Documented full help. @@ -432,34 +426,34 @@ full help. -- plugins/commands that have no doc files get the default template expect.eq([[ls -** +== No help available. ]], h.get_entry_long_help('ls')) expect.eq([[nodocs_hascommands -****************** +================== No help available. ]], h.get_entry_long_help('nodocs_hascommands')) expect.eq([[nodocs_hascommands -****************** +================== No help available. ]], h.get_entry_long_help('nodoc_command')) expect.eq([[Nodocs samename. This command has the same name as its host plugin but no rst docs.]], h.get_entry_long_help('nodocs_samename')) expect.eq([[nodocs_nocommand -**************** +================ No help available. ]], h.get_entry_long_help('nodocs_nocommand')) expect.eq([[nodocs_script -************* +============= No help available. ]], h.get_entry_long_help('nodocs_script')) expect.eq([[inscript_short_only -******************* +=================== No help available. ]], h.get_entry_long_help('inscript_short_only')) @@ -468,11 +462,11 @@ No help available. expect.eq([[inscript_docs ============= -**Tags:** map | badtag +Tags: map | badtag -**Command:** "inscript_docs" +Command: "inscript_docs" -in-file inscript_docs. + in-file inscript_docs. Documented full help.]], h.get_entry_long_help('inscript_docs')) end From 7c498e66119890bbb3188c245d1e098048532e72 Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 23 Sep 2022 08:39:40 -0700 Subject: [PATCH 19/73] add note about regenerating dwarfmonitor.json --- docs/changelog.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index c3f8996c3..895f7db72 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -36,7 +36,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## New Plugins - `autonestbox`: split off from `zone` into its own plugin. Note that to enable, the command has changed from ``autonestbox start`` to ``enable autonestbox``. - `autobutcher`: split off from `zone` into its own plugin. Note that to enable, the command has changed from ``autobutcher start`` to ``enable autobutcher``. -- `overlay`: display a "DFHack" button in the lower left corner that you can click to start the new GUI command launcher. +- `overlay`: display a "DFHack" button in the lower left corner that you can click to start the new GUI command launcher. The `dwarfmonitor` weather display had to be moved to make room for the button. If you are seeing the weather indicator rendered over the overlay button, please remove the ``dfhack-config/dwarfmonitor.json`` file to fix the weather indicator display offset. ## New Tweaks From 618a191c8756d469d916498977100542860b8649 Mon Sep 17 00:00:00 2001 From: myk002 Date: Wed, 21 Sep 2022 12:54:12 -0700 Subject: [PATCH 20/73] fix directive use for reveal.rst --- docs/plugins/reveal.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/plugins/reveal.rst b/docs/plugins/reveal.rst index 19066076b..bbcc07b6b 100644 --- a/docs/plugins/reveal.rst +++ b/docs/plugins/reveal.rst @@ -7,19 +7,19 @@ reveal :summary: Reveals the map. :tags: adventure fort armok inspection map -.. dfhack-tool:: unreveal +.. dfhack-command:: unreveal :summary: Hides previously hidden tiles again. -.. dfhack-tool:: revforget +.. dfhack-command:: revforget :summary: Discard records about what was visible before revealing the map. -.. dfhack-tool:: revtoggle +.. dfhack-command:: revtoggle :summary: Switch between reveal and unreveal. -.. dfhack-tool:: revflood +.. dfhack-command:: revflood :summary: Hide everything, then reveal tiles with a path to the cursor. -.. dfhack-tool:: nopause +.. dfhack-command:: nopause :summary: Disable pausing. This reveals all z-layers in fort mode. It also works in adventure mode, but any From 4913637b620a45e2aa97157e5866d90df64104ad Mon Sep 17 00:00:00 2001 From: myk002 Date: Wed, 21 Sep 2022 12:54:28 -0700 Subject: [PATCH 21/73] genindex label "alphabetical" -> "annotated" --- docs/Tools.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Tools.rst b/docs/Tools.rst index aeff179aa..e694ba897 100644 --- a/docs/Tools.rst +++ b/docs/Tools.rst @@ -34,7 +34,7 @@ DFHack tools are tagged with categories to make them easier to find. These categories are listed in the next few sections. Note that a tool can belong to more than one category. If you already know what you're looking for, try the `search` or Ctrl-F on this page. If you'd like to see the full list of tools in -one flat list, please refer to the `alphabetized index `. +one flat list, please refer to the `annotated index `. DFHack tools by game mode ------------------------- From 278b7528ac60d9c838f56981d1f2c2c2f3b77bf7 Mon Sep 17 00:00:00 2001 From: myk002 Date: Wed, 21 Sep 2022 17:53:51 -0700 Subject: [PATCH 22/73] implement basic domain index structure --- conf.py | 59 ++------------------ docs/Core.rst | 2 +- docs/Memory-research.rst | 2 +- docs/Tags.rst | 54 +++++++++--------- docs/sphinx_extensions/dfhack/tool_docs.py | 64 ++++++++++++++++++++-- library/lua/helpdb.lua | 2 +- 6 files changed, 94 insertions(+), 89 deletions(-) diff --git a/conf.py b/conf.py index 0170a872b..01c358153 100644 --- a/conf.py +++ b/conf.py @@ -58,9 +58,6 @@ def doc_dir(dirname, files, prefix): def doc_all_dirs(): """Collect the commands and paths to include in our docs.""" tools = [] - # TODO: as we scan the docs, parse out the tags and short descriptions and - # build a map for use in generating the tags pages and links in the tool - # doc footers for root, _, files in os.walk('docs/builtins'): tools.extend(doc_dir(root, files, os.path.relpath(root, 'docs/builtins'))) for root, _, files in os.walk('docs/plugins'): @@ -69,59 +66,16 @@ def doc_all_dirs(): tools.extend(doc_dir(root, files, os.path.relpath(root, 'scripts/docs'))) return tuple(tools) -DOC_ALL_DIRS = doc_all_dirs() - - -def get_tags(): - groups = {} - group_re = re.compile(r'"([^"]+)"') - tag_re = re.compile(r'- `tag/([^`]+)`: (.*)') - with open('docs/Tags.rst') as f: - lines = f.readlines() - for line in lines: - line = line.strip() - m = re.match(group_re, line) - if m: - group = m.group(1) - groups[group] = [] - continue - m = re.match(tag_re, line) - if m: - tag = m.group(1) - desc = m.group(2) - groups[group].append((tag, desc)) - return groups - - -def generate_tag_indices(): - os.makedirs('docs/tags', mode=0o755, exist_ok=True) - tag_groups = get_tags() - for tag_group in tag_groups: - with write_file_if_changed(('docs/tags/by{group}.rst').format(group=tag_group)) as topidx: - for tag_tuple in tag_groups[tag_group]: - tag = tag_tuple[0] - with write_file_if_changed(('docs/tags/{name}.rst').format(name=tag)) as tagidx: - tagidx.write('TODO: add links to the tools that have this tag') - topidx.write(('.. _tag/{name}:\n\n').format(name=tag)) - topidx.write(('{name}\n').format(name=tag)) - topidx.write(('{underline}\n').format(underline='*'*len(tag))) - topidx.write(('{desc}\n\n').format(desc=tag_tuple[1])) - topidx.write(('.. include:: /docs/tags/{name}.rst\n\n').format(name=tag)) - def write_tool_docs(): """ Creates a file for each tool with the ".. include::" directives to pull in - the original documentation. Then we generate a label and useful info in the - footer. + the original documentation. """ - for k in DOC_ALL_DIRS: + for k in doc_all_dirs(): header = ':orphan:\n' label = ('.. _{name}:\n\n').format(name=k[0]) include = ('.. include:: /{path}\n\n').format(path=k[1]) - # TODO: generate a footer with links to tools that share at least one - # tag with this tool. Just the tool names, strung across the bottom of - # the page in one long wrapped line, similar to how the wiki does it os.makedirs(os.path.join('docs/tools', os.path.dirname(k[0])), mode=0o755, exist_ok=True) with write_file_if_changed('docs/tools/{}.rst'.format(k[0])) as outfile: @@ -131,9 +85,8 @@ def write_tool_docs(): outfile.write(include) -# Actually call the docs generator and run test write_tool_docs() -generate_tag_indices() + # -- General configuration ------------------------------------------------ @@ -315,11 +268,9 @@ html_sidebars = { ] } -# If false, no module index is generated. -html_domain_indices = False - -# If false, no genindex.html is generated. +# generate indices html_use_index = True +html_domain_indices = True # don't link to rst sources in the generated pages html_show_sourcelink = False diff --git a/docs/Core.rst b/docs/Core.rst index e03a7fcba..012236d59 100644 --- a/docs/Core.rst +++ b/docs/Core.rst @@ -185,7 +185,7 @@ where ``*`` can be any string, including the empty string. A world being loaded can mean a fortress, an adventurer, or legends mode. These files are best used for non-persistent commands, such as setting -a `tag/bugfix` script to run on `repeat`. +a `bugfix-tag-index` script to run on `repeat`. .. _onMapLoad.init: diff --git a/docs/Memory-research.rst b/docs/Memory-research.rst index d9c0833e3..c4c7aeb63 100644 --- a/docs/Memory-research.rst +++ b/docs/Memory-research.rst @@ -63,7 +63,7 @@ are not built by default, but can be built by setting the ``BUILD_DEVEL`` Scripts ~~~~~~~ -Several `development tools ` can be useful for memory research. +Several `development tools ` can be useful for memory research. These include (but are not limited to): - `devel/dump-offsets` diff --git a/docs/Tags.rst b/docs/Tags.rst index 9f3906d58..14a12f411 100644 --- a/docs/Tags.rst +++ b/docs/Tags.rst @@ -13,36 +13,36 @@ for the tag assignment spreadsheet. "when" tags ----------- -- `tag/adventure`: Tools that are useful while in adventure mode. Note that some tools only tagged with "fort" might also work in adventure mode, but not always in expected ways. Feel free to experiment, though! -- `tag/dfhack`: Tools that you use to run DFHack commands or interact with the DFHack library. This tag also includes tools that help you manage the DF game itself (e.g. settings, saving, etc.) -- `tag/embark`: Tools that are useful while on the fort embark screen or while creating an adventurer. -- `tag/fort`: Tools that are useful while in fort mode. -- `tag/legends`: Tools that are useful while in legends mode. +- `adventure-tag-index`: Tools that are useful while in adventure mode. Note that some tools only tagged with "fort" might also work in adventure mode, but not always in expected ways. Feel free to experiment, though! +- `dfhack-tag-index`: Tools that you use to run DFHack commands or interact with the DFHack library. This tag also includes tools that help you manage the DF game itself (e.g. settings, saving, etc.) +- `embark-tag-index`: Tools that are useful while on the fort embark screen or while creating an adventurer. +- `fort-tag-index`: Tools that are useful while in fort mode. +- `legends-tag-index`: Tools that are useful while in legends mode. "why" tags ---------- -- `tag/armok`: Tools that give you complete control over an aspect of the game or provide access to information that the game intentionally keeps hidden. -- `tag/auto`: Tools that run in the background and automatically manage routine, toilsome aspects of your fortress. -- `tag/bugfix`: Tools that fix specific bugs, either permanently or on-demand. -- `tag/design`: Tools that help you design your fort. -- `tag/dev`: Tools that are useful when developing scripts or mods. -- `tag/fps`: Tools that help you manage FPS drop. -- `tag/gameplay`: Tools that introduce new gameplay elements. -- `tag/inspection`: Tools that let you view information that is otherwise difficult to find. -- `tag/productivity`: Tools that help you do things that you could do manually, but using the tool is better and faster. +- `armok-tag-index`: Tools that give you complete control over an aspect of the game or provide access to information that the game intentionally keeps hidden. +- `auto-tag-index`: Tools that run in the background and automatically manage routine, toilsome aspects of your fortress. +- `bugfix-tag-index`: Tools that fix specific bugs, either permanently or on-demand. +- `design-tag-index`: Tools that help you design your fort. +- `dev-tag-index`: Tools that are useful when developing scripts or mods. +- `fps-tag-index`: Tools that help you manage FPS drop. +- `gameplay-tag-index`: Tools that introduce new gameplay elements. +- `inspection-tag-index`: Tools that let you view information that is otherwise difficult to find. +- `productivity-tag-index`: Tools that help you do things that you could do manually, but using the tool is better and faster. "what" tags ----------- -- `tag/animals`: Tools that interact with animals. -- `tag/buildings`: Tools that interact with buildings and furniture. -- `tag/graphics`: Tools that interact with game graphics. -- `tag/interface`: Tools that interact with or extend the DF user interface. -- `tag/items`: Tools that interact with in-game items. -- `tag/jobs`: Tools that interact with jobs. -- `tag/labors`: Tools that deal with labor assignment. -- `tag/map`: Tools that interact with the game map. -- `tag/military`: Tools that interact with the military. -- `tag/plants`: Tools that interact with trees, shrubs, and crops. -- `tag/stockpiles`: Tools that interact wtih stockpiles. -- `tag/units`: Tools that interact with units. -- `tag/workorders`: Tools that interact with workorders. +- `animals-tag-index`: Tools that interact with animals. +- `buildings-tag-index`: Tools that interact with buildings and furniture. +- `graphics-tag-index`: Tools that interact with game graphics. +- `interface-tag-index`: Tools that interact with or extend the DF user interface. +- `items-tag-index`: Tools that interact with in-game items. +- `jobs-tag-index`: Tools that interact with jobs. +- `labors-tag-index`: Tools that deal with labor assignment. +- `map-tag-index`: Tools that interact with the game map. +- `military-tag-index`: Tools that interact with the military. +- `plants-tag-index`: Tools that interact with trees, shrubs, and crops. +- `stockpiles-tag-index`: Tools that interact wtih stockpiles. +- `units-tag-index`: Tools that interact with units. +- `workorders-tag-index`: Tools that interact with workorders. diff --git a/docs/sphinx_extensions/dfhack/tool_docs.py b/docs/sphinx_extensions/dfhack/tool_docs.py index 6f5df5568..cff47de79 100644 --- a/docs/sphinx_extensions/dfhack/tool_docs.py +++ b/docs/sphinx_extensions/dfhack/tool_docs.py @@ -5,7 +5,8 @@ import logging import os -from typing import List, Optional, Type +import re +from typing import Iterable, List, Optional, Tuple, Type import docutils.nodes as nodes from docutils.nodes import Node @@ -13,13 +14,13 @@ import docutils.parsers.rst.directives as rst_directives import sphinx import sphinx.addnodes as addnodes import sphinx.directives +from sphinx.domains import Domain, Index, IndexEntry from sphinx.util.docutils import SphinxDirective from sphinx.util.nodes import process_index_entry import dfhack.util - logger = sphinx.util.logging.getLogger(__name__) @@ -165,7 +166,7 @@ class DFHackToolDirective(DFHackToolDirectiveBase): addnodes.pending_xref(tag, nodes.inline(text=tag), **{ 'reftype': 'ref', 'refdomain': 'std', - 'reftarget': 'tag/' + tag, + 'reftarget': tag + '-tag-index', 'refexplicit': False, 'refwarn': True, }), @@ -202,6 +203,56 @@ class DFHackCommandDirective(DFHackToolDirectiveBase): return ret_nodes +def get_tags(): + groups = {} + group_re = re.compile(r'"([^"]+)"') + tag_re = re.compile(r'- `([^`]+)-tag-index`: (.*)') + with open('docs/Tags.rst') as f: + lines = f.readlines() + for line in lines: + line = line.strip() + m = re.match(group_re, line) + if m: + group = m.group(1) + groups[group] = [] + continue + m = re.match(tag_re, line) + if m: + tag = m.group(1) + desc = m.group(2) + groups[group].append((tag, desc)) + return groups + + +def generate_tag_index(self, docnames: Optional[Iterable[str]] = None) -> Tuple[List[Tuple[str, List[IndexEntry]]], bool]: + return [('A', [['name', 0, '', '', '', '', '']])], False + + +def init_tag_indices(app): + os.makedirs('docs/tags', mode=0o755, exist_ok=True) + tag_groups = get_tags() + for tag_group in tag_groups: + with dfhack.util.write_file_if_changed(('docs/tags/by{group}.rst').format(group=tag_group)) as topidx: + for tag_tuple in tag_groups[tag_group]: + tag, desc = tag_tuple[0], tag_tuple[1] + topidx.write(('- `{name} <{name}-tag-index>`\n').format(name=tag)) + topidx.write((' {desc}\n').format(desc=desc)) + + domain_class = type(tag+'Domain', (Domain, ), { + 'name': tag, + 'label': 'Container domain for tag: ' + tag, + }) + index_class = type(tag+'Index', (Index, ), { + 'name': 'tag-index', + 'localname': tag + ' tag index', + 'shortname': tag, + 'desc': desc, + 'generate': generate_tag_index, + }) + app.add_domain(domain_class) + app.add_index_to_domain(tag, index_class) + + def register(app): app.add_directive('dfhack-tool', DFHackToolDirective) app.add_directive('dfhack-command', DFHackCommandDirective) @@ -212,11 +263,14 @@ def register(app): def setup(app): app.connect('builder-inited', register) + init_tag_indices(app) + # TODO: re-enable once detection is corrected # app.connect('build-finished', lambda *_: check_missing_keybinds()) + # TODO: implement parallel builds so we can set these back to True return { 'version': '0.1', - 'parallel_read_safe': True, - 'parallel_write_safe': True, + 'parallel_read_safe': False, + 'parallel_write_safe': False, } diff --git a/library/lua/helpdb.lua b/library/lua/helpdb.lua index c39d3ba80..ac6adb55d 100644 --- a/library/lua/helpdb.lua +++ b/library/lua/helpdb.lua @@ -396,7 +396,7 @@ local function initialize_tags() desc = desc .. ' ' .. line tag_index[tag].description = desc else - _,_,tag,desc = line:find('^%* (%w+): (.+)') + _,_,tag,desc = line:find('^%* (%w+)[^:]*: (.+)') if not tag then goto continue end tag_index[tag] = {description=desc} in_desc = true From a1d3fe77b5d3265823cd55659c9479e5ea33bb83 Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 23 Sep 2022 08:10:37 -0700 Subject: [PATCH 23/73] add a bit more index infrastructure --- docs/sphinx_extensions/dfhack/tool_docs.py | 27 +++++++++++++++------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/docs/sphinx_extensions/dfhack/tool_docs.py b/docs/sphinx_extensions/dfhack/tool_docs.py index cff47de79..152a65280 100644 --- a/docs/sphinx_extensions/dfhack/tool_docs.py +++ b/docs/sphinx_extensions/dfhack/tool_docs.py @@ -6,7 +6,7 @@ import logging import os import re -from typing import Iterable, List, Optional, Tuple, Type +from typing import Dict, Iterable, List, Optional, Tuple, Type import docutils.nodes as nodes from docutils.nodes import Node @@ -167,10 +167,12 @@ class DFHackToolDirective(DFHackToolDirectiveBase): 'reftype': 'ref', 'refdomain': 'std', 'reftarget': tag + '-tag-index', - 'refexplicit': False, + 'refexplicit': True, 'refwarn': True, }), nodes.inline(text=' | '), + indexdata = (self.env.docname) + self.env.domaindata[tag]['objects'].append(indexdata) ] tag_paragraph.pop() @@ -224,8 +226,15 @@ def get_tags(): return groups -def generate_tag_index(self, docnames: Optional[Iterable[str]] = None) -> Tuple[List[Tuple[str, List[IndexEntry]]], bool]: - return [('A', [['name', 0, '', '', '', '', '']])], False +def tag_domain_get_objects(self): + for obj in self.data['objects']: + yield(obj) + +def tag_domain_merge_domaindata(self, docnames: List[str], otherdata: Dict) -> None: + self.data['objects'].extend(otherdata['objects']) + +def tag_index_generate(self, docnames: Optional[Iterable[str]] = None) -> Tuple[List[Tuple[str, List[IndexEntry]]], bool]: + return [('G', [['gui/blueprint', 0, 'docs/tools/gui/blueprint', 'gui-blueprint', '', '', '']])], False def init_tag_indices(app): @@ -241,13 +250,16 @@ def init_tag_indices(app): domain_class = type(tag+'Domain', (Domain, ), { 'name': tag, 'label': 'Container domain for tag: ' + tag, + 'initial_data': {'objects': []}, + 'merge_domaindata': tag_domain_merge_domaindata, + 'get_objects': tag_domain_get_objects, }) index_class = type(tag+'Index', (Index, ), { 'name': 'tag-index', 'localname': tag + ' tag index', 'shortname': tag, 'desc': desc, - 'generate': generate_tag_index, + 'generate': tag_index_generate, }) app.add_domain(domain_class) app.add_index_to_domain(tag, index_class) @@ -268,9 +280,8 @@ def setup(app): # TODO: re-enable once detection is corrected # app.connect('build-finished', lambda *_: check_missing_keybinds()) - # TODO: implement parallel builds so we can set these back to True return { 'version': '0.1', - 'parallel_read_safe': False, - 'parallel_write_safe': False, + 'parallel_read_safe': True, + 'parallel_write_safe': True, } From a92e5d1f74e7017b0bc4b11cc8b5681d7a01e3f6 Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 23 Sep 2022 09:32:08 -0700 Subject: [PATCH 24/73] populate, merge, and generate real tag indices --- docs/sphinx_extensions/dfhack/tool_docs.py | 24 +++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/docs/sphinx_extensions/dfhack/tool_docs.py b/docs/sphinx_extensions/dfhack/tool_docs.py index 152a65280..d32f7c0b3 100644 --- a/docs/sphinx_extensions/dfhack/tool_docs.py +++ b/docs/sphinx_extensions/dfhack/tool_docs.py @@ -3,6 +3,7 @@ # https://www.sphinx-doc.org/en/master/development/tutorials/recipe.html # https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#rst-directives +from collections import defaultdict import logging import os import re @@ -171,9 +172,10 @@ class DFHackToolDirective(DFHackToolDirectiveBase): 'refwarn': True, }), nodes.inline(text=' | '), - indexdata = (self.env.docname) - self.env.domaindata[tag]['objects'].append(indexdata) ] + name = self.get_name_or_docname() + indexdata = (name, self.options.get('summary', ''), '', self.env.docname, '', 0) + self.env.domaindata[tag]['objects'].append(indexdata) tag_paragraph.pop() ret_nodes = [tag_paragraph] @@ -231,10 +233,22 @@ def tag_domain_get_objects(self): yield(obj) def tag_domain_merge_domaindata(self, docnames: List[str], otherdata: Dict) -> None: - self.data['objects'].extend(otherdata['objects']) + seen = set() + objs = self.data['objects'] + for obj in objs: + seen.add(obj[0]) + for obj in otherdata['objects']: + if obj[0] not in seen: + objs.append(obj) + objs.sort() def tag_index_generate(self, docnames: Optional[Iterable[str]] = None) -> Tuple[List[Tuple[str, List[IndexEntry]]], bool]: - return [('G', [['gui/blueprint', 0, 'docs/tools/gui/blueprint', 'gui-blueprint', '', '', '']])], False + content = defaultdict(list) + for name, desc, _, docname, _, _ in self.domain.data['objects']: + first_letter = name[0].lower() + content[first_letter].append( + IndexEntry(name, 0, docname, '', '', '', desc)) + return (sorted(content.items()), False) def init_tag_indices(app): @@ -256,7 +270,7 @@ def init_tag_indices(app): }) index_class = type(tag+'Index', (Index, ), { 'name': 'tag-index', - 'localname': tag + ' tag index', + 'localname': '"' + tag + '" tag index', 'shortname': tag, 'desc': desc, 'generate': tag_index_generate, From 1b9cd830093fdf1a2fe541f01cd341ca7df65e82 Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 23 Sep 2022 10:10:28 -0700 Subject: [PATCH 25/73] use a domain index instead of the genindex --- conf.py | 4 +- docs/Tools.rst | 2 +- docs/sphinx_extensions/dfhack/tool_docs.py | 65 +++++++++------------- 3 files changed, 30 insertions(+), 41 deletions(-) diff --git a/conf.py b/conf.py index 01c358153..2742e18f0 100644 --- a/conf.py +++ b/conf.py @@ -268,8 +268,8 @@ html_sidebars = { ] } -# generate indices -html_use_index = True +# generate domain indices but not the (unused) genindex +html_use_index = False html_domain_indices = True # don't link to rst sources in the generated pages diff --git a/docs/Tools.rst b/docs/Tools.rst index e694ba897..20ceea769 100644 --- a/docs/Tools.rst +++ b/docs/Tools.rst @@ -34,7 +34,7 @@ DFHack tools are tagged with categories to make them easier to find. These categories are listed in the next few sections. Note that a tool can belong to more than one category. If you already know what you're looking for, try the `search` or Ctrl-F on this page. If you'd like to see the full list of tools in -one flat list, please refer to the `annotated index `. +one flat list, please refer to the `annotated index `. DFHack tools by game mode ------------------------- diff --git a/docs/sphinx_extensions/dfhack/tool_docs.py b/docs/sphinx_extensions/dfhack/tool_docs.py index d32f7c0b3..412a332b8 100644 --- a/docs/sphinx_extensions/dfhack/tool_docs.py +++ b/docs/sphinx_extensions/dfhack/tool_docs.py @@ -52,18 +52,6 @@ def make_summary(builder: sphinx.builders.Builder, summary: str) -> nodes.paragr para += nodes.inline(text=summary) return para -def make_index(directive: SphinxDirective, name: str, summary: str) -> List[Node]: - targetid = 'index-%s' % directive.env.new_serialno('index') - targetnode = nodes.target('', '', ids=[targetid]) - directive.state.document.note_explicit_target(targetnode) - indexnode = addnodes.index() - indexnode['entries'] = [] - indexnode['inline'] = False - directive.set_source_info(indexnode) - entry_text = 'single: {}; {}'.format(name, summary) - indexnode['entries'].extend(process_index_entry(entry_text, targetnode['ids'][0])) - return [indexnode, targetnode] - _KEYBINDS = {} _KEYBINDS_RENDERED = set() # commands whose keybindings have been rendered @@ -137,6 +125,10 @@ class DFHackToolDirectiveBase(sphinx.directives.ObjectDescription): else: return parts[-1] + def add_index_entry(self, name, tag) -> None: + indexdata = (name, self.options.get('summary', ''), '', self.env.docname, '', 0) + self.env.domaindata[tag]['objects'].append(indexdata) + @staticmethod def wrap_box(*children: List[nodes.Node]) -> nodes.Admonition: return nodes.topic('', *children, classes=['dfhack-tool-summary']) @@ -173,14 +165,12 @@ class DFHackToolDirective(DFHackToolDirectiveBase): }), nodes.inline(text=' | '), ] - name = self.get_name_or_docname() - indexdata = (name, self.options.get('summary', ''), '', self.env.docname, '', 0) - self.env.domaindata[tag]['objects'].append(indexdata) + self.add_index_entry(self.get_name_or_docname(), tag) tag_paragraph.pop() ret_nodes = [tag_paragraph] if 'no-command' in self.options: - ret_nodes += make_index(self, self.get_name_or_docname() + ' (plugin)', self.options.get('summary', '')) + self.add_index_entry(self.get_name_or_docname() + ' (plugin)', 'all') ret_nodes += [make_summary(self.env.app.builder, self.options.get('summary', ''))] return ret_nodes @@ -198,13 +188,12 @@ class DFHackCommandDirective(DFHackToolDirectiveBase): def render_content(self) -> List[nodes.Node]: command = self.get_name_or_docname() - ret_nodes = [self.make_labeled_paragraph('Command', command, content_class=nodes.literal)] - ret_nodes += make_index(self, command, self.options.get('summary', '')) - ret_nodes += [ + self.add_index_entry(command, 'all') + return [ + self.make_labeled_paragraph('Command', command, content_class=nodes.literal), make_summary(self.env.app.builder, self.options.get('summary', '')), *render_dfhack_keybind(command, builder=self.env.app.builder), ] - return ret_nodes def get_tags(): @@ -250,6 +239,22 @@ def tag_index_generate(self, docnames: Optional[Iterable[str]] = None) -> Tuple[ IndexEntry(name, 0, docname, '', '', '', desc)) return (sorted(content.items()), False) +def register_index(app, tag, title): + domain_class = type(tag+'Domain', (Domain, ), { + 'name': tag, + 'label': 'Container domain for tag: ' + tag, + 'initial_data': {'objects': []}, + 'merge_domaindata': tag_domain_merge_domaindata, + 'get_objects': tag_domain_get_objects, + }) + index_class = type(tag+'Index', (Index, ), { + 'name': 'tag-index', + 'localname': title, + 'shortname': tag, + 'generate': tag_index_generate, + }) + app.add_domain(domain_class) + app.add_index_to_domain(tag, index_class) def init_tag_indices(app): os.makedirs('docs/tags', mode=0o755, exist_ok=True) @@ -260,35 +265,19 @@ def init_tag_indices(app): tag, desc = tag_tuple[0], tag_tuple[1] topidx.write(('- `{name} <{name}-tag-index>`\n').format(name=tag)) topidx.write((' {desc}\n').format(desc=desc)) - - domain_class = type(tag+'Domain', (Domain, ), { - 'name': tag, - 'label': 'Container domain for tag: ' + tag, - 'initial_data': {'objects': []}, - 'merge_domaindata': tag_domain_merge_domaindata, - 'get_objects': tag_domain_get_objects, - }) - index_class = type(tag+'Index', (Index, ), { - 'name': 'tag-index', - 'localname': '"' + tag + '" tag index', - 'shortname': tag, - 'desc': desc, - 'generate': tag_index_generate, - }) - app.add_domain(domain_class) - app.add_index_to_domain(tag, index_class) + register_index(app, tag, '"%s" tag index' % tag) def register(app): app.add_directive('dfhack-tool', DFHackToolDirective) app.add_directive('dfhack-command', DFHackCommandDirective) - _KEYBINDS.update(scan_all_keybinds(os.path.join(dfhack.util.DFHACK_ROOT, 'data', 'init'))) def setup(app): app.connect('builder-inited', register) + register_index(app, 'all', 'Index of DFHack tools') init_tag_indices(app) # TODO: re-enable once detection is corrected From 5869ba64c8b77edaacfc2eba84afe9bcb6e4730d Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 23 Sep 2022 10:21:53 -0700 Subject: [PATCH 26/73] add tag description to the tag index page this is a terrible hack that only works because sphinx doesn't sanitize its input for the html builder. we set the title to '%s

%s

' % (tag, desc) so the final html looks like

adventure

...

this may not play nice with the pdf builder.. --- docs/sphinx_extensions/dfhack/tool_docs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sphinx_extensions/dfhack/tool_docs.py b/docs/sphinx_extensions/dfhack/tool_docs.py index 412a332b8..fef6ca15a 100644 --- a/docs/sphinx_extensions/dfhack/tool_docs.py +++ b/docs/sphinx_extensions/dfhack/tool_docs.py @@ -265,7 +265,7 @@ def init_tag_indices(app): tag, desc = tag_tuple[0], tag_tuple[1] topidx.write(('- `{name} <{name}-tag-index>`\n').format(name=tag)) topidx.write((' {desc}\n').format(desc=desc)) - register_index(app, tag, '"%s" tag index' % tag) + register_index(app, tag, '%s

%s

' % (tag, desc)) def register(app): From 52011bde7bef90ac550070a1dbe01378d4950b6e Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 23 Sep 2022 11:13:49 -0700 Subject: [PATCH 27/73] share tag list between tool and commands so all relevant tag index entries get generated --- docs/sphinx_extensions/dfhack/tool_docs.py | 29 ++++++++++++++++------ 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/docs/sphinx_extensions/dfhack/tool_docs.py b/docs/sphinx_extensions/dfhack/tool_docs.py index fef6ca15a..e9aa6e888 100644 --- a/docs/sphinx_extensions/dfhack/tool_docs.py +++ b/docs/sphinx_extensions/dfhack/tool_docs.py @@ -125,9 +125,13 @@ class DFHackToolDirectiveBase(sphinx.directives.ObjectDescription): else: return parts[-1] - def add_index_entry(self, name, tag) -> None: - indexdata = (name, self.options.get('summary', ''), '', self.env.docname, '', 0) - self.env.domaindata[tag]['objects'].append(indexdata) + def add_index_entries(self, name) -> None: + docname = self.env.docname + tags = self.env.domaindata['tag-repo']['doctags'][docname] + indexdata = (name, self.options.get('summary', ''), '', docname, '', 0) + self.env.domaindata['all']['objects'].append(indexdata) + for tag in tags: + self.env.domaindata[tag]['objects'].append(indexdata) @staticmethod def wrap_box(*children: List[nodes.Node]) -> nodes.Admonition: @@ -154,7 +158,9 @@ class DFHackToolDirective(DFHackToolDirectiveBase): def render_content(self) -> List[nodes.Node]: tag_paragraph = self.make_labeled_paragraph('Tags') - for tag in self.options.get('tags', []): + tags = self.options.get('tags', []) + self.env.domaindata['tag-repo']['doctags'][self.env.docname] = tags + for tag in tags: tag_paragraph += [ addnodes.pending_xref(tag, nodes.inline(text=tag), **{ 'reftype': 'ref', @@ -165,12 +171,11 @@ class DFHackToolDirective(DFHackToolDirectiveBase): }), nodes.inline(text=' | '), ] - self.add_index_entry(self.get_name_or_docname(), tag) tag_paragraph.pop() ret_nodes = [tag_paragraph] if 'no-command' in self.options: - self.add_index_entry(self.get_name_or_docname() + ' (plugin)', 'all') + self.add_index_entries(self.get_name_or_docname() + ' (plugin)') ret_nodes += [make_summary(self.env.app.builder, self.options.get('summary', ''))] return ret_nodes @@ -188,7 +193,7 @@ class DFHackCommandDirective(DFHackToolDirectiveBase): def render_content(self) -> List[nodes.Node]: command = self.get_name_or_docname() - self.add_index_entry(command, 'all') + self.add_index_entries(command) return [ self.make_labeled_paragraph('Command', command, content_class=nodes.literal), make_summary(self.env.app.builder, self.options.get('summary', '')), @@ -196,6 +201,15 @@ class DFHackCommandDirective(DFHackToolDirectiveBase): ] +class TagRepoDomain(Domain): + name = 'tag-repo' + label = 'Holds tag associations per document' + initial_data = {'doctags': {}} + + def merge_domaindata(self, docnames: List[str], otherdata: Dict) -> None: + self.data['doctags'].update(otherdata['doctags']) + + def get_tags(): groups = {} group_re = re.compile(r'"([^"]+)"') @@ -277,6 +291,7 @@ def register(app): def setup(app): app.connect('builder-inited', register) + app.add_domain(TagRepoDomain) register_index(app, 'all', 'Index of DFHack tools') init_tag_indices(app) From 1cd5e8657a759e64e98b7e4348a0e753686a2419 Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 23 Sep 2022 11:33:14 -0700 Subject: [PATCH 28/73] link directly to the tool page title instead of the top of the page this is especially important on mobile where the top of the page is taken up with the sidebar boilerplate --- docs/sphinx_extensions/dfhack/tool_docs.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/docs/sphinx_extensions/dfhack/tool_docs.py b/docs/sphinx_extensions/dfhack/tool_docs.py index e9aa6e888..e7302c3cd 100644 --- a/docs/sphinx_extensions/dfhack/tool_docs.py +++ b/docs/sphinx_extensions/dfhack/tool_docs.py @@ -115,20 +115,23 @@ class DFHackToolDirectiveBase(sphinx.directives.ObjectDescription): required_arguments = 0 optional_arguments = 1 + def get_tool_name_from_docname(self): + parts = self.env.docname.split('/') + if 'tools' in parts: + return '/'.join(parts[parts.index('tools') + 1:]) + else: + return parts[-1] + def get_name_or_docname(self): if self.arguments: return self.arguments[0] - else: - parts = self.env.docname.split('/') - if 'tools' in parts: - return '/'.join(parts[parts.index('tools') + 1:]) - else: - return parts[-1] + return self.get_tool_name_from_docname() def add_index_entries(self, name) -> None: docname = self.env.docname + anchor = self.get_tool_name_from_docname().replace('/', '-') tags = self.env.domaindata['tag-repo']['doctags'][docname] - indexdata = (name, self.options.get('summary', ''), '', docname, '', 0) + indexdata = (name, self.options.get('summary', ''), '', docname, anchor, 0) self.env.domaindata['all']['objects'].append(indexdata) for tag in tags: self.env.domaindata[tag]['objects'].append(indexdata) @@ -247,10 +250,10 @@ def tag_domain_merge_domaindata(self, docnames: List[str], otherdata: Dict) -> N def tag_index_generate(self, docnames: Optional[Iterable[str]] = None) -> Tuple[List[Tuple[str, List[IndexEntry]]], bool]: content = defaultdict(list) - for name, desc, _, docname, _, _ in self.domain.data['objects']: + for name, desc, _, docname, anchor, _ in self.domain.data['objects']: first_letter = name[0].lower() content[first_letter].append( - IndexEntry(name, 0, docname, '', '', '', desc)) + IndexEntry(name, 0, docname, anchor, '', '', desc)) return (sorted(content.items()), False) def register_index(app, tag, title): From 98b6ad4954ef2b51782488b5744020d449185c50 Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 23 Sep 2022 12:34:50 -0700 Subject: [PATCH 29/73] fix index titles on pdf --- docs/Tags.rst | 54 +++++++++++----------- docs/sphinx_extensions/dfhack/tool_docs.py | 16 +++++-- 2 files changed, 40 insertions(+), 30 deletions(-) diff --git a/docs/Tags.rst b/docs/Tags.rst index 14a12f411..45bfeb9b3 100644 --- a/docs/Tags.rst +++ b/docs/Tags.rst @@ -13,36 +13,36 @@ for the tag assignment spreadsheet. "when" tags ----------- -- `adventure-tag-index`: Tools that are useful while in adventure mode. Note that some tools only tagged with "fort" might also work in adventure mode, but not always in expected ways. Feel free to experiment, though! -- `dfhack-tag-index`: Tools that you use to run DFHack commands or interact with the DFHack library. This tag also includes tools that help you manage the DF game itself (e.g. settings, saving, etc.) -- `embark-tag-index`: Tools that are useful while on the fort embark screen or while creating an adventurer. -- `fort-tag-index`: Tools that are useful while in fort mode. -- `legends-tag-index`: Tools that are useful while in legends mode. +- `adventure `: Tools that are useful while in adventure mode. Note that some tools only tagged with "fort" might also work in adventure mode, but not always in expected ways. Feel free to experiment, though! +- `dfhack `: Tools that you use to run DFHack commands or interact with the DFHack library. This tag also includes tools that help you manage the DF game itself (e.g. settings, saving, etc.) +- `embark `: Tools that are useful while on the fort embark screen or while creating an adventurer. +- `fort `: Tools that are useful while in fort mode. +- `legends `: Tools that are useful while in legends mode. "why" tags ---------- -- `armok-tag-index`: Tools that give you complete control over an aspect of the game or provide access to information that the game intentionally keeps hidden. -- `auto-tag-index`: Tools that run in the background and automatically manage routine, toilsome aspects of your fortress. -- `bugfix-tag-index`: Tools that fix specific bugs, either permanently or on-demand. -- `design-tag-index`: Tools that help you design your fort. -- `dev-tag-index`: Tools that are useful when developing scripts or mods. -- `fps-tag-index`: Tools that help you manage FPS drop. -- `gameplay-tag-index`: Tools that introduce new gameplay elements. -- `inspection-tag-index`: Tools that let you view information that is otherwise difficult to find. -- `productivity-tag-index`: Tools that help you do things that you could do manually, but using the tool is better and faster. +- `armok `: Tools that give you complete control over an aspect of the game or provide access to information that the game intentionally keeps hidden. +- `auto `: Tools that run in the background and automatically manage routine, toilsome aspects of your fortress. +- `bugfix `: Tools that fix specific bugs, either permanently or on-demand. +- `design `: Tools that help you design your fort. +- `dev `: Tools that are useful when developing scripts or mods. +- `fps `: Tools that help you manage FPS drop. +- `gameplay `: Tools that introduce new gameplay elements. +- `inspection `: Tools that let you view information that is otherwise difficult to find. +- `productivity `: Tools that help you do things that you could do manually, but using the tool is better and faster. "what" tags ----------- -- `animals-tag-index`: Tools that interact with animals. -- `buildings-tag-index`: Tools that interact with buildings and furniture. -- `graphics-tag-index`: Tools that interact with game graphics. -- `interface-tag-index`: Tools that interact with or extend the DF user interface. -- `items-tag-index`: Tools that interact with in-game items. -- `jobs-tag-index`: Tools that interact with jobs. -- `labors-tag-index`: Tools that deal with labor assignment. -- `map-tag-index`: Tools that interact with the game map. -- `military-tag-index`: Tools that interact with the military. -- `plants-tag-index`: Tools that interact with trees, shrubs, and crops. -- `stockpiles-tag-index`: Tools that interact wtih stockpiles. -- `units-tag-index`: Tools that interact with units. -- `workorders-tag-index`: Tools that interact with workorders. +- `animals `: Tools that interact with animals. +- `buildings `: Tools that interact with buildings and furniture. +- `graphics `: Tools that interact with game graphics. +- `interface `: Tools that interact with or extend the DF user interface. +- `items `: Tools that interact with in-game items. +- `jobs `: Tools that interact with jobs. +- `labors `: Tools that deal with labor assignment. +- `map `: Tools that interact with the game map. +- `military `: Tools that interact with the military. +- `plants `: Tools that interact with trees, shrubs, and crops. +- `stockpiles `: Tools that interact wtih stockpiles. +- `units `: Tools that interact with units. +- `workorders `: Tools that interact with workorders. diff --git a/docs/sphinx_extensions/dfhack/tool_docs.py b/docs/sphinx_extensions/dfhack/tool_docs.py index e7302c3cd..581cee26e 100644 --- a/docs/sphinx_extensions/dfhack/tool_docs.py +++ b/docs/sphinx_extensions/dfhack/tool_docs.py @@ -216,7 +216,7 @@ class TagRepoDomain(Domain): def get_tags(): groups = {} group_re = re.compile(r'"([^"]+)"') - tag_re = re.compile(r'- `([^`]+)-tag-index`: (.*)') + tag_re = re.compile(r'- `([^ ]+) <[^>]+>`: (.*)') with open('docs/Tags.rst') as f: lines = f.readlines() for line in lines: @@ -282,15 +282,25 @@ def init_tag_indices(app): tag, desc = tag_tuple[0], tag_tuple[1] topidx.write(('- `{name} <{name}-tag-index>`\n').format(name=tag)) topidx.write((' {desc}\n').format(desc=desc)) - register_index(app, tag, '%s

%s

' % (tag, desc)) + register_index(app, tag, desc) +def update_index_titles(app): + for domain in app.env.domains.values(): + for index in domain.indices: + if index.shortname == 'all': + continue + if app.builder.format == 'html': + index.localname = '"%s" tag index

%s

' % (index.shortname, index.localname) + else: + index.localname = '%s tag index - %s' % (index.shortname, index.localname) + def register(app): app.add_directive('dfhack-tool', DFHackToolDirective) app.add_directive('dfhack-command', DFHackCommandDirective) + update_index_titles(app) _KEYBINDS.update(scan_all_keybinds(os.path.join(dfhack.util.DFHACK_ROOT, 'data', 'init'))) - def setup(app): app.connect('builder-inited', register) From 4ae1b7fb747245df0358cc85a0778641ab536ea4 Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 23 Sep 2022 12:51:50 -0700 Subject: [PATCH 30/73] fix anchor text transformation --- docs/sphinx_extensions/dfhack/tool_docs.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/sphinx_extensions/dfhack/tool_docs.py b/docs/sphinx_extensions/dfhack/tool_docs.py index 581cee26e..62569a4d1 100644 --- a/docs/sphinx_extensions/dfhack/tool_docs.py +++ b/docs/sphinx_extensions/dfhack/tool_docs.py @@ -110,6 +110,14 @@ def check_missing_keybinds(): logger.warning('Undocumented keybindings for command: %s', missing_command) +_anchor_pattern = re.compile(r'^\d+') + +def to_anchor(name: str) -> str: + name = name.lower() + name = name.replace('/', '-') + name = re.sub(_anchor_pattern, '', name) + return name + class DFHackToolDirectiveBase(sphinx.directives.ObjectDescription): has_content = False required_arguments = 0 @@ -129,7 +137,7 @@ class DFHackToolDirectiveBase(sphinx.directives.ObjectDescription): def add_index_entries(self, name) -> None: docname = self.env.docname - anchor = self.get_tool_name_from_docname().replace('/', '-') + anchor = to_anchor(self.get_tool_name_from_docname()) tags = self.env.domaindata['tag-repo']['doctags'][docname] indexdata = (name, self.options.get('summary', ''), '', docname, anchor, 0) self.env.domaindata['all']['objects'].append(indexdata) @@ -293,7 +301,7 @@ def update_index_titles(app): if app.builder.format == 'html': index.localname = '"%s" tag index

%s

' % (index.shortname, index.localname) else: - index.localname = '%s tag index - %s' % (index.shortname, index.localname) + index.localname = '"%s" tag index - %s' % (index.shortname, index.localname) def register(app): app.add_directive('dfhack-tool', DFHackToolDirective) From 50f0d1137215d4505c837a732fe6548f8bf64c55 Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 23 Sep 2022 13:19:13 -0700 Subject: [PATCH 31/73] include tool desc in the index for all formats --- docs/sphinx_extensions/dfhack/tool_docs.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/sphinx_extensions/dfhack/tool_docs.py b/docs/sphinx_extensions/dfhack/tool_docs.py index 62569a4d1..18532c9d5 100644 --- a/docs/sphinx_extensions/dfhack/tool_docs.py +++ b/docs/sphinx_extensions/dfhack/tool_docs.py @@ -260,8 +260,11 @@ def tag_index_generate(self, docnames: Optional[Iterable[str]] = None) -> Tuple[ content = defaultdict(list) for name, desc, _, docname, anchor, _ in self.domain.data['objects']: first_letter = name[0].lower() + extra, descr = desc, '' + if self.domain.env.app.builder.format == 'html': + extra, descr = '', desc content[first_letter].append( - IndexEntry(name, 0, docname, anchor, '', '', desc)) + IndexEntry(name, 0, docname, anchor, extra, '', descr)) return (sorted(content.items()), False) def register_index(app, tag, title): From 6b219f342dda546496a948625dd22bfeae0c876f Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 23 Sep 2022 14:09:15 -0700 Subject: [PATCH 32/73] add a TOC of all tools so the pdf picks them up --- docs/Tools.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/Tools.rst b/docs/Tools.rst index 20ceea769..401276d7f 100644 --- a/docs/Tools.rst +++ b/docs/Tools.rst @@ -50,3 +50,14 @@ DFHack tools by what they affect -------------------------------- .. include:: tags/bywhat.rst + +All DFHack tools alphabetically +------------------------------- + +.. toctree:: + :glob: + :maxdepth: 1 + :titlesonly: + + tools/* + tools/*/* From 8546b2963cd7970878ae8b5f1f38f19afd114fdc Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 23 Sep 2022 15:58:31 -0700 Subject: [PATCH 33/73] tool docs are no longer toc-orphaned --- conf.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/conf.py b/conf.py index 2742e18f0..661b0daea 100644 --- a/conf.py +++ b/conf.py @@ -73,13 +73,11 @@ def write_tool_docs(): the original documentation. """ for k in doc_all_dirs(): - header = ':orphan:\n' label = ('.. _{name}:\n\n').format(name=k[0]) include = ('.. include:: /{path}\n\n').format(path=k[1]) os.makedirs(os.path.join('docs/tools', os.path.dirname(k[0])), mode=0o755, exist_ok=True) with write_file_if_changed('docs/tools/{}.rst'.format(k[0])) as outfile: - outfile.write(header) if k[0] != 'search': outfile.write(label) outfile.write(include) From b1801d25ca4285646cb7c6e647ea88614241ebfb Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 23 Sep 2022 15:59:25 -0700 Subject: [PATCH 34/73] update scripts ref --- scripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts b/scripts index 8c03de45b..a1374b572 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 8c03de45ba8e772239224b49af2617fc714fbaa9 +Subproject commit a1374b5726b3dd682ac41d21701f186e748c0974 From d0f9b1d324bfeb52e605153ef462e76f04a56849 Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 23 Sep 2022 16:01:33 -0700 Subject: [PATCH 35/73] update scripts ref --- scripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts b/scripts index a1374b572..f318f56f7 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit a1374b5726b3dd682ac41d21701f186e748c0974 +Subproject commit f318f56f75aa40f2bd91c1cd32c3b426f7821db4 From c4ebd195e8185b81aa6080b0d7e1fd939726ac0a Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 23 Sep 2022 16:02:26 -0700 Subject: [PATCH 36/73] update scripts ref --- scripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts b/scripts index f318f56f7..00fb32809 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit f318f56f75aa40f2bd91c1cd32c3b426f7821db4 +Subproject commit 00fb328091d2950257aa576b223ca22aa621332b From 9eaf3acb256b97220d8b06fff0586e261917d6ff Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 23 Sep 2022 16:09:46 -0700 Subject: [PATCH 37/73] ensure readthedocs checks out submodules --- .readthedocs.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index 1e570e571..e66d3da1b 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -9,13 +9,13 @@ build: tools: python: "3" +submodules: + include: all + sphinx: configuration: conf.py -formats: - - htmlzip - - pdf - - epub +formats: all python: install: From 65500e60690ce803366a6d820b87859dbb018bed Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 23 Sep 2022 16:21:47 -0700 Subject: [PATCH 38/73] update scripts ref --- scripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts b/scripts index 00fb32809..f02f2eb92 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 00fb328091d2950257aa576b223ca22aa621332b +Subproject commit f02f2eb9231c94385750fd318dfb85eed47be66f From e6336e769a2625ee55c9435f2be5c773f758dc37 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sun, 4 Sep 2022 23:08:56 -0400 Subject: [PATCH 39/73] Units::teleport(): set idle_area --- docs/changelog.txt | 1 + library/modules/Units.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/changelog.txt b/docs/changelog.txt index 895f7db72..813dfee77 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -80,6 +80,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - Removed ``Windows`` module (C++-only) - unused. - ``Constructions`` module (C++-only): removed ``t_construction``, ``isValid()``, ``getCount()``, ``getConstruction()``, and ``copyConstruction()``. Access ``world.constructions`` directly instead. - ``Gui::getSelectedItem()``, ``Gui::getAnyItem()``: added support for the artifacts screen +- ``Units::teleport()``: now sets ``unit.idle_area`` ## Lua - History: added ``dfhack.getCommandHistory(history_id, history_filename)`` and ``dfhack.addCommandToHistory(history_id, history_filename, command)`` so gui scripts can access a commandline history without requiring a terminal. diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index 8e9f624ea..32b9f28e5 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -174,6 +174,7 @@ bool Units::teleport(df::unit *unit, df::coord target_pos) // move unit to destination unit->pos = target_pos; + unit->idle_area = target_pos; // move unit's riders (including babies) to destination if (unit->flags1.bits.ridden) From c1b9ffc7ca7cef93ebaa0554f39a1fb40d10ef77 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 24 Sep 2022 13:31:18 -0400 Subject: [PATCH 40/73] Clarify changelog Based on clarification from Doublestrafe and Quietust --- docs/changelog.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index 813dfee77..b7d822801 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -80,7 +80,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - Removed ``Windows`` module (C++-only) - unused. - ``Constructions`` module (C++-only): removed ``t_construction``, ``isValid()``, ``getCount()``, ``getConstruction()``, and ``copyConstruction()``. Access ``world.constructions`` directly instead. - ``Gui::getSelectedItem()``, ``Gui::getAnyItem()``: added support for the artifacts screen -- ``Units::teleport()``: now sets ``unit.idle_area`` +- ``Units::teleport()``: now sets ``unit.idle_area`` to discourage units from walking back to their original location (or teleporting back, if using `fastdwarf`) ## Lua - History: added ``dfhack.getCommandHistory(history_id, history_filename)`` and ``dfhack.addCommandToHistory(history_id, history_filename, command)`` so gui scripts can access a commandline history without requiring a terminal. From e9eeb5fda03b24bd9455963a8d2c40b7ac201ccd Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 24 Sep 2022 13:59:04 -0400 Subject: [PATCH 41/73] tool_docs: don't assume cwd is dfhack root hopefully fixes the CI docs build in dfhack/scripts --- docs/sphinx_extensions/dfhack/tool_docs.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/sphinx_extensions/dfhack/tool_docs.py b/docs/sphinx_extensions/dfhack/tool_docs.py index 18532c9d5..836bab217 100644 --- a/docs/sphinx_extensions/dfhack/tool_docs.py +++ b/docs/sphinx_extensions/dfhack/tool_docs.py @@ -225,7 +225,7 @@ def get_tags(): groups = {} group_re = re.compile(r'"([^"]+)"') tag_re = re.compile(r'- `([^ ]+) <[^>]+>`: (.*)') - with open('docs/Tags.rst') as f: + with open(os.path.join(dfhack.util.DOCS_ROOT, 'Tags.rst')) as f: lines = f.readlines() for line in lines: line = line.strip() @@ -285,10 +285,11 @@ def register_index(app, tag, title): app.add_index_to_domain(tag, index_class) def init_tag_indices(app): - os.makedirs('docs/tags', mode=0o755, exist_ok=True) + os.makedirs(os.path.join(dfhack.util.DOCS_ROOT, 'tags'), mode=0o755, exist_ok=True) tag_groups = get_tags() for tag_group in tag_groups: - with dfhack.util.write_file_if_changed(('docs/tags/by{group}.rst').format(group=tag_group)) as topidx: + group_file_path = os.path.join(dfhack.util.DOCS_ROOT, 'tags', 'by{group}.rst'.format(group=tag_group)) + with dfhack.util.write_file_if_changed(group_file_path) as topidx: for tag_tuple in tag_groups[tag_group]: tag, desc = tag_tuple[0], tag_tuple[1] topidx.write(('- `{name} <{name}-tag-index>`\n').format(name=tag)) From ea7326a1c852db60c575e504c45a2eee861243cd Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 24 Sep 2022 20:47:16 -0700 Subject: [PATCH 42/73] add more job types to the example prioritize list --- data/examples/init/onMapLoad_dreamfort.init | 26 +++++++++++++++------ 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/data/examples/init/onMapLoad_dreamfort.init b/data/examples/init/onMapLoad_dreamfort.init index 05d32134f..619349986 100644 --- a/data/examples/init/onMapLoad_dreamfort.init +++ b/data/examples/init/onMapLoad_dreamfort.init @@ -1,6 +1,7 @@ # This dfhack config file automates common tasks for your forts. # It was written for the Dreamfort set of quickfort blueprints, but the -# configuration here is useful for any fort! Feed free to edit or override +# configuration here is useful for any fort! Copy this file to your +# dfhack-config/init directory to use. Feed free to edit or override # to your liking. # Uncomment this next line if you want buildingplan (and quickfort) to use only @@ -48,13 +49,24 @@ seedwatch all 30 # ensures important tasks get assigned to workers. # otherwise these job types can get ignored in busy forts. -prioritize -a StoreItemInVehicle StoreItemInBag StoreItemInBarrel PullLever -prioritize -a StoreItemInLocation StoreItemInHospital -prioritize -a DestroyBuilding RemoveConstruction RecoverWounded DumpItem -prioritize -a CleanSelf SlaughterAnimal PrepareRawFish ExtractFromRawFish -prioritize -a TradeAtDepot BringItemToDepot CleanTrap ManageWorkOrders +# +# take care of rottables before they rot prioritize -a --haul-labor=Food,Body StoreItemInStockpile prioritize -a --reaction-name=TAN_A_HIDE CustomReaction +prioritize -a PrepareRawFish +# +# organize items efficiently so new items can be brought to the stockpiles +prioritize -a StoreItemInVehicle StoreItemInBag StoreItemInBarrel +prioritize -a StoreItemInLocation StoreItemInHospital StoreItemInBin +# +# when these things come up, get them done ASAP +prioritize -a ManageWorkOrders TradeAtDepot BringItemToDepot CleanTrap +prioritize -a DestroyBuilding RemoveConstruction RecoverWounded DumpItem +prioritize -a PullLever CleanSelf SlaughterAnimal CollectSand +prioritize -a PenLargeAnimal PenSmallAnimal PitLargeAnimal PitSmallAnimal +prioritize -a TameAnimal TrainAnimal TrainHuntingAnimal TrainWarAnimal +prioritize -a FellTree FireBallista FireCatapult OperatePump +prioritize -a MakeArmor MakeWeapon # autobutcher settings are saved in the savegame, so we only need to set them once. # this way, any custom settings you set during gameplay are not overwritten @@ -78,7 +90,7 @@ on-new-fortress autobutcher target 50 50 14 2 BIRD_GOOSE on-new-fortress autobutcher target 2 2 4 2 ALPACA SHEEP LLAMA # pigs give milk and meat and are zero-maintenance. on-new-fortress autobutcher target 5 5 6 2 PIG -# butcher all unprofitable animals +# immediately butcher all unprofitable animals on-new-fortress autobutcher target 0 0 0 0 HORSE YAK DONKEY WATER_BUFFALO GOAT CAVY BIRD_DUCK BIRD_GUINEAFOWL # watch for new animals on-new-fortress autobutcher autowatch From 07d3e70b8a1a3b24799aa2e2f5942dba4341b0f4 Mon Sep 17 00:00:00 2001 From: DFHack-Urist via GitHub Actions <63161697+DFHack-Urist@users.noreply.github.com> Date: Sun, 25 Sep 2022 07:19:50 +0000 Subject: [PATCH 43/73] Auto-update submodules scripts: master --- scripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts b/scripts index f02f2eb92..a5b542eef 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit f02f2eb9231c94385750fd318dfb85eed47be66f +Subproject commit a5b542eef784fc86618c824052f60ecf2582833f From cb80f7dd756aa434bff836a37c4088edfdcfc2af Mon Sep 17 00:00:00 2001 From: myk002 Date: Sun, 25 Sep 2022 16:04:36 -0700 Subject: [PATCH 44/73] don't cache dup civzones when scanning buildings --- docs/changelog.txt | 1 + library/modules/Buildings.cpp | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index b7d822801..52e906486 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -49,6 +49,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - `dig-now`: Fix direction of smoothed walls when adjacent to a door or floodgate - ``job.removeJob()``: ensure jobs are removed from the world list when they are canceled - `quickfort`: `Dreamfort ` blueprint set: declare the hospital zone before building the coffer; otherwise DF fails to stock the hospital with materials +- ``dfhack.buildings.findCivzonesAt``: no longer return duplicate civzones after loading a save with existing civzones ## Misc Improvements - Init scripts: ``dfhack.init`` and other init scripts have moved to ``dfhack-config/init/``. If you have customized your ``dfhack.init`` file and want to keep your changes, please move the part that you have customized to the new location at ``dfhack-config/init/dfhack.init``. If you do not have changes that you want to keep, do not copy anything, and the new defaults will be used automatically. diff --git a/library/modules/Buildings.cpp b/library/modules/Buildings.cpp index dd8d5f0e9..1918771ae 100644 --- a/library/modules/Buildings.cpp +++ b/library/modules/Buildings.cpp @@ -308,9 +308,8 @@ df::building *Buildings::findAtTile(df::coord pos) static unordered_map corner1; static unordered_map corner2; -static void cacheBuilding(df::building *building) { +static void cacheBuilding(df::building *building, bool is_civzone) { int32_t id = building->id; - bool is_civzone = !building->isSettingOccupancy(); df::coord p1(min(building->x1, building->x2), min(building->y1,building->y2), building->z); df::coord p2(max(building->x1, building->x2), max(building->y1,building->y2), building->z); @@ -344,7 +343,7 @@ static void cacheNewCivzones() { auto &vec = world->buildings.other[buildings_other_id::ANY_ZONE]; int32_t idx = df::building::binsearch_index(vec, id); if (idx > -1) - cacheBuilding(vec[idx]); + cacheBuilding(vec[idx], true); } nextCivzone = nextBuildingId; } @@ -1311,8 +1310,9 @@ void Buildings::updateBuildings(color_ostream&, void* ptr) if (building) { - if (!corner1.count(id)) - cacheBuilding(building); + bool is_civzone = !building->isSettingOccupancy(); + if (!corner1.count(id) && !is_civzone) + cacheBuilding(building, false); } else if (corner1.count(id)) { From fce4c9aa97b71ba1dd8ae32d8552e2313a6ac422 Mon Sep 17 00:00:00 2001 From: DFHack-Urist via GitHub Actions <63161697+DFHack-Urist@users.noreply.github.com> Date: Mon, 26 Sep 2022 07:36:25 +0000 Subject: [PATCH 45/73] Auto-update submodules scripts: master --- scripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts b/scripts index a5b542eef..086409c42 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit a5b542eef784fc86618c824052f60ecf2582833f +Subproject commit 086409c42cdf83e1be8631345b192bb60012939e From b744d1a8e5cbe4144a9331467d880fc20e007c10 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Mon, 26 Sep 2022 22:08:55 -0700 Subject: [PATCH 46/73] add medical jobs to the priority list as per discussion on reddit https://www.reddit.com/r/dwarffortress/comments/xj00e9/science_job_priority/ --- data/examples/init/onMapLoad_dreamfort.init | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/data/examples/init/onMapLoad_dreamfort.init b/data/examples/init/onMapLoad_dreamfort.init index 619349986..e23b28285 100644 --- a/data/examples/init/onMapLoad_dreamfort.init +++ b/data/examples/init/onMapLoad_dreamfort.init @@ -55,18 +55,25 @@ prioritize -a --haul-labor=Food,Body StoreItemInStockpile prioritize -a --reaction-name=TAN_A_HIDE CustomReaction prioritize -a PrepareRawFish # +# ensure medical, hygiene, and hospice tasks get done +prioritize -a CleanSelf RecoverWounded ApplyCast BringCrutch CleanPatient +prioritize -a DiagnosePatient DressWound GiveFood GiveWater ImmobilizeBreak +prioritize -a PlaceInTraction SetBone Surgery Suture +# # organize items efficiently so new items can be brought to the stockpiles prioritize -a StoreItemInVehicle StoreItemInBag StoreItemInBarrel prioritize -a StoreItemInLocation StoreItemInHospital StoreItemInBin # -# when these things come up, get them done ASAP -prioritize -a ManageWorkOrders TradeAtDepot BringItemToDepot CleanTrap -prioritize -a DestroyBuilding RemoveConstruction RecoverWounded DumpItem -prioritize -a PullLever CleanSelf SlaughterAnimal CollectSand -prioritize -a PenLargeAnimal PenSmallAnimal PitLargeAnimal PitSmallAnimal +# ensure prisoners and animals are tended to quickly +prioritize -a --haul-labor=Animals StoreItemInStockpile prioritize -a TameAnimal TrainAnimal TrainHuntingAnimal TrainWarAnimal +prioritize -a PenLargeAnimal PitLargeAnimal SlaughterAnimal +# +# when these things come up, get them done ASAP +prioritize -a ManageWorkOrders TradeAtDepot BringItemToDepot +prioritize -a DestroyBuilding RemoveConstruction DumpItem PullLever prioritize -a FellTree FireBallista FireCatapult OperatePump -prioritize -a MakeArmor MakeWeapon +prioritize -a CollectSand MakeArmor MakeWeapon # autobutcher settings are saved in the savegame, so we only need to set them once. # this way, any custom settings you set during gameplay are not overwritten From 2cf23e2b3489715e5b59f2fa019823040d73a822 Mon Sep 17 00:00:00 2001 From: DFHack-Urist via GitHub Actions <63161697+DFHack-Urist@users.noreply.github.com> Date: Tue, 27 Sep 2022 07:41:21 +0000 Subject: [PATCH 47/73] Auto-update submodules scripts: master --- scripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts b/scripts index 086409c42..4f568fc83 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 086409c42cdf83e1be8631345b192bb60012939e +Subproject commit 4f568fc8331d62bc6646055c1252bba19b3a526d From a0cc040d9c62539aa21787291c9585d07c97aede Mon Sep 17 00:00:00 2001 From: myk002 Date: Wed, 28 Sep 2022 12:15:25 -0700 Subject: [PATCH 48/73] use new prioritize defaults --- data/examples/init/onMapLoad_dreamfort.init | 26 +-------------------- 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/data/examples/init/onMapLoad_dreamfort.init b/data/examples/init/onMapLoad_dreamfort.init index e23b28285..fe2b1d54e 100644 --- a/data/examples/init/onMapLoad_dreamfort.init +++ b/data/examples/init/onMapLoad_dreamfort.init @@ -49,31 +49,7 @@ seedwatch all 30 # ensures important tasks get assigned to workers. # otherwise these job types can get ignored in busy forts. -# -# take care of rottables before they rot -prioritize -a --haul-labor=Food,Body StoreItemInStockpile -prioritize -a --reaction-name=TAN_A_HIDE CustomReaction -prioritize -a PrepareRawFish -# -# ensure medical, hygiene, and hospice tasks get done -prioritize -a CleanSelf RecoverWounded ApplyCast BringCrutch CleanPatient -prioritize -a DiagnosePatient DressWound GiveFood GiveWater ImmobilizeBreak -prioritize -a PlaceInTraction SetBone Surgery Suture -# -# organize items efficiently so new items can be brought to the stockpiles -prioritize -a StoreItemInVehicle StoreItemInBag StoreItemInBarrel -prioritize -a StoreItemInLocation StoreItemInHospital StoreItemInBin -# -# ensure prisoners and animals are tended to quickly -prioritize -a --haul-labor=Animals StoreItemInStockpile -prioritize -a TameAnimal TrainAnimal TrainHuntingAnimal TrainWarAnimal -prioritize -a PenLargeAnimal PitLargeAnimal SlaughterAnimal -# -# when these things come up, get them done ASAP -prioritize -a ManageWorkOrders TradeAtDepot BringItemToDepot -prioritize -a DestroyBuilding RemoveConstruction DumpItem PullLever -prioritize -a FellTree FireBallista FireCatapult OperatePump -prioritize -a CollectSand MakeArmor MakeWeapon +prioritize -aq defaults # autobutcher settings are saved in the savegame, so we only need to set them once. # this way, any custom settings you set during gameplay are not overwritten From b6acf7a9286b3dd9809cbd72ea318f270ebe4cdf Mon Sep 17 00:00:00 2001 From: myk002 Date: Wed, 28 Sep 2022 12:45:57 -0700 Subject: [PATCH 49/73] address feedback on the docs --- docs/plugins/3dveins.rst | 8 ++++---- docs/plugins/add-spatter.rst | 3 +++ docs/plugins/autohauler.rst | 4 ++-- docs/plugins/autolabor.rst | 9 +++++---- docs/plugins/autonestbox.rst | 14 +++++++------- 5 files changed, 21 insertions(+), 17 deletions(-) diff --git a/docs/plugins/3dveins.rst b/docs/plugins/3dveins.rst index f71a14343..96fbcf836 100644 --- a/docs/plugins/3dveins.rst +++ b/docs/plugins/3dveins.rst @@ -25,10 +25,10 @@ Example 3dveins -New veins are generated using 3D Perlin noise in order to produce a layout that -flows smoothly between z-levels. The vein distribution is based on the world -seed, so running the command for the second time should produce no change. It is -best to run it just once immediately after embark. +New veins are generated using natural-looking 3D Perlin noise in order to +produce a layout that flows smoothly between z-levels. The vein distribution is +based on the world seed, so running the command for the second time should +produce no change. It is best to run it just once immediately after embark. This command is intended as only a cosmetic change, so it takes care to exactly preserve the mineral counts reported by ``prospect all``. The amounts of layer diff --git a/docs/plugins/add-spatter.rst b/docs/plugins/add-spatter.rst index 873bd761f..1ce32fcbe 100644 --- a/docs/plugins/add-spatter.rst +++ b/docs/plugins/add-spatter.rst @@ -12,3 +12,6 @@ names starting with ``SPATTER_ADD_``, so there are no commands to run to use it. These reactions will then produce contaminants on items instead of improvements. The contaminants are immune to being washed away by water or destroyed by `clean`. + +You must have a mod installed that adds the appropriate tokens in order for this +plugin to do anything. diff --git a/docs/plugins/autohauler.rst b/docs/plugins/autohauler.rst index a71d3ed02..08c84327a 100644 --- a/docs/plugins/autohauler.rst +++ b/docs/plugins/autohauler.rst @@ -5,7 +5,7 @@ autohauler :summary: Automatically manage hauling labors. :tags: fort auto labors -Similar to `autolabor`, but instead of managing all labors, ``autohauler`` only +Similar to `autolabor`, but instead of managing all labors, autohauler only addresses hauling labors, leaving the assignment of skilled labors entirely up to you. You can use the in-game `manipulator` UI or an external tool like Dwarf Therapist to do so. @@ -19,7 +19,7 @@ assignment, with most skilled labors only being assigned to just a few dwarves and almost every non-military dwarf having at least one skilled labor assigned. Autohauler allows a skill to be used as a flag to exempt a dwarf from -``autohauler``'s effects. By default, this is the unused ALCHEMIST labor, but it +autohauler's effects. By default, this is the unused ALCHEMIST labor, but it can be changed by the user. Usage diff --git a/docs/plugins/autolabor.rst b/docs/plugins/autolabor.rst index ed39c2666..861655ab4 100644 --- a/docs/plugins/autolabor.rst +++ b/docs/plugins/autolabor.rst @@ -45,10 +45,11 @@ and manager. Hunting is never assigned without a butchery, and fishing is never assigned without a fishery. -For each labor, a preference order is calculated based on skill, biased against -masters of other trades and excluding those who can't do the job. The labor is -then added to the best dwarves for that labor, then to additional -dwarfs that meet any of these conditions: +For each labor, a preference order is calculated based on skill, excluding those +who can't do the job. Dwarves who are masters of particular skills are +deprioritized in the preference list for other skills. The labor is then added +to the best dwarves for that labor, then to additional dwarfs that +meet any of these conditions: * The dwarf is idle and there are no idle dwarves assigned to this labor * The dwarf has non-zero skill associated with the labor diff --git a/docs/plugins/autonestbox.rst b/docs/plugins/autonestbox.rst index 9d5683f2b..27074fe1c 100644 --- a/docs/plugins/autonestbox.rst +++ b/docs/plugins/autonestbox.rst @@ -5,13 +5,13 @@ autonestbox :summary: Auto-assign egg-laying female pets to nestbox zones. :tags: fort auto animals -To use this feature, you must create 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 of the size. Egg layers who are also -grazers will be ignored, since confining them to a 1x1 pasture is not a good -idea. Only tame and domesticated own units are processed since pasturing -half-trained wild egg layers could destroy your neat nestbox zones when they -revert to wild. +To use this feature, you must create pen/pasture zones on the same tiles as +built 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 of the size. Egg +layers who are also grazers will be ignored, since confining them to a 1x1 +pasture is not a good idea. Only tame and domesticated own units are processed +since pasturing half-trained wild egg layers could destroy your neat nestbox +zones when they revert to wild. Note that the age of the units is not checked, so you might get some egg-laying kids assigned to the nestbox zones. Most birds grow up quite fast, though, so From 9a2cb5ea4492783d4b8cb52c49fea92dad402838 Mon Sep 17 00:00:00 2001 From: myk002 Date: Wed, 28 Sep 2022 14:49:03 -0700 Subject: [PATCH 50/73] fix ALL the typos done by copying everything into Google docs and running spellcheck --- docs/Compile.rst | 8 ++-- docs/Documentation.rst | 2 +- docs/Introduction.rst | 4 +- docs/Lua API.rst | 58 ++++++++++++------------- docs/NEWS.rst | 2 +- docs/Structures-intro.rst | 2 +- docs/Tags.rst | 2 +- docs/guides/modding-guide.rst | 10 ++--- docs/guides/quickfort-alias-guide.rst | 6 +-- docs/guides/quickfort-library-guide.rst | 2 +- docs/guides/quickfort-user-guide.rst | 10 ++--- docs/plugins/autobutcher.rst | 4 +- docs/plugins/autolabor.rst | 6 +-- docs/plugins/automaterial.rst | 4 +- docs/plugins/burrows.rst | 2 +- docs/plugins/changelayer.rst | 2 +- docs/plugins/changevein.rst | 2 +- docs/plugins/command-prompt.rst | 2 +- docs/plugins/cursecheck.rst | 2 +- docs/plugins/debug.rst | 8 ++-- docs/plugins/dwarfmonitor.rst | 2 +- docs/plugins/dwarfvet.rst | 12 ++--- docs/plugins/embark-tools.rst | 2 +- docs/plugins/fix-unit-occupancy.rst | 4 +- docs/plugins/forceequip.rst | 2 +- docs/plugins/labormanager.rst | 4 +- docs/plugins/lair.rst | 2 +- docs/plugins/manipulator.rst | 2 +- docs/plugins/map-render.rst | 2 +- docs/plugins/power-meter.rst | 2 +- docs/plugins/regrass.rst | 2 +- docs/plugins/rendermax.rst | 2 +- docs/plugins/resume.rst | 2 +- docs/plugins/search.rst | 2 +- docs/plugins/seedwatch.rst | 2 +- docs/plugins/stocks.rst | 2 +- docs/plugins/tiletypes.rst | 2 +- docs/plugins/tubefill.rst | 2 +- docs/plugins/tweak.rst | 2 +- docs/plugins/workflow.rst | 2 +- docs/plugins/zone.rst | 4 +- 41 files changed, 98 insertions(+), 98 deletions(-) diff --git a/docs/Compile.rst b/docs/Compile.rst index 0f3880816..ae23a1b73 100644 --- a/docs/Compile.rst +++ b/docs/Compile.rst @@ -289,7 +289,7 @@ DF, which causes DF to use your system libstdc++ instead:: rm libs/libstdc++.so.6 Note that distributing binaries compiled with newer GCC versions may result in -the opposite compatibily issue: users with *older* GCC versions may encounter +the opposite compatibility issue: users with *older* GCC versions may encounter similar errors. This is why DFHack distributes both GCC 4.8 and GCC 7 builds. If you are planning on distributing binaries to other users, we recommend using an older GCC (but still at least 4.8) version if possible. @@ -314,7 +314,7 @@ Notes for GCC 8+ or OS X 10.10+ users If none of these situations apply to you, skip to `osx-setup`. -If you have issues building on OS X 10.10 (Yosemite) or above, try definining +If you have issues building on OS X 10.10 (Yosemite) or above, try defining the following environment variable:: export MACOSX_DEPLOYMENT_TARGET=10.9 @@ -503,7 +503,7 @@ in their name. If this redirect doesn't occur, just copy, paste, and enter the download link again and you should see the options. You need to get: Visual C++ Build Tools for Visual Studio 2015 with Update 3. Click the download button next to it and a dropdown of download formats will appear. -Select the DVD format to download an ISO file. When the donwload is complete, +Select the DVD format to download an ISO file. When the download is complete, click on the ISO file and a folder will popup with the following contents: * packages (folder) @@ -561,7 +561,7 @@ Additional dependencies: installing with the Chocolatey Package Manager ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The remainder of dependencies - Git, CMake, StrawberryPerl, and Python - can be -most easily installed using the Chocolatey Package Manger. Chocolatey is a +most easily installed using the Chocolatey Package Manager. Chocolatey is a \*nix-style package manager for Windows. It's fast, small (8-20MB on disk) and very capable. Think "``apt-get`` for Windows." diff --git a/docs/Documentation.rst b/docs/Documentation.rst index 13ae58dca..6ac5ef382 100644 --- a/docs/Documentation.rst +++ b/docs/Documentation.rst @@ -76,7 +76,7 @@ replaced with the corresponding title and linked: e.g. ```autolabor``` => `autolabor`. Scripts and plugins have link targets that match their names created for you automatically. -If you want to link to a heading in your own page, you can specifiy it like this:: +If you want to link to a heading in your own page, you can specify it like this:: `Heading text exactly as written`_ diff --git a/docs/Introduction.rst b/docs/Introduction.rst index d90983d8c..798a9c3c8 100644 --- a/docs/Introduction.rst +++ b/docs/Introduction.rst @@ -28,7 +28,7 @@ or for coexistence in a single DF install, even with incompatible components. For developers, DFHack unites the various ways tools access DF memory and allows easier development of new tools. As an open-source project under -`various open-source licences `, contributions are welcome. +`various open-source licenses `, contributions are welcome. .. contents:: Contents @@ -54,7 +54,7 @@ used by the DFHack console. to be used this way. * Commands can also run at startup via `init files `, - on in batches at other times with the `script` command. + or in batches at other times with the `script` command. * Finally, some commands are persistent once enabled, and will sit in the background managing or changing some aspect of the game if you `enable` them. diff --git a/docs/Lua API.rst b/docs/Lua API.rst index 64ccdd595..4aa8d78cb 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -740,7 +740,7 @@ Functions: * ``dfhack.matinfo.decode(type,index)`` - Looks up material info for the given number pair; if not found, returs *nil*. + Looks up material info for the given number pair; if not found, returns *nil*. * ``....decode(matinfo)``, ``....decode(item)``, ``....decode(obj)`` @@ -1099,7 +1099,7 @@ Other * ``dfhack.gui.getDepthAt(x, y)`` Returns the distance from the z-level of the tile at map coordinates (x, y) to - the closest ground z-level below. Defaults to 0, unless overriden by plugins. + the closest ground z-level below. Defaults to 0, unless overridden by plugins. Job module ---------- @@ -1869,7 +1869,7 @@ Among them are: - ``full_rectangle = true`` For buildings like stockpiles or farm plots that can normally - accomodate individual tile exclusion, forces an error if any + accommodate individual tile exclusion, forces an error if any tiles within the specified width*height are obstructed. - ``items = { item, item ... }``, or ``filters = { {...}, {...}... }`` @@ -2169,7 +2169,7 @@ Supported callbacks and fields are: Called when keyboard or mouse events are available. If any keys are pressed, the keys argument is a table mapping them to *true*. - Note that this refers to logical keybingings computed from real keys via + Note that this refers to logical keybindings computed from real keys via options; if multiple interpretations exist, the table will contain multiple keys. The table also may contain special keys: @@ -2494,7 +2494,7 @@ Core context specific functions: unit of time used, and may be one of ``'frames'`` (raw FPS), ``'ticks'`` (unpaused FPS), ``'days'``, ``'months'``, ``'years'`` (in-game time). All timers other than - ``'frames'`` are cancelled when the world is unloaded, + ``'frames'`` are canceled when the world is unloaded, and cannot be queued until it is loaded again. Returns the timer id, or *nil* if unsuccessful due to world being unloaded. @@ -2677,7 +2677,7 @@ environment by the mandatory init file dfhack.lua: .. _lua-string: -String class extentions +String class extensions ----------------------- DFHack extends Lua's basic string class to include a number of convenience @@ -2698,7 +2698,7 @@ functions. These are invoked just like standard string functions, e.g.:: * ``string:split([delimiter[, plain]])`` Split a string by the given delimiter. If no delimiter is specified, space - (``' '``) is used. The delimter is treated as a pattern unless a ``plain`` is + (``' '``) is used. The delimiter is treated as a pattern unless a ``plain`` is specified and set to ``true``. To treat multiple successive delimiter characters as a single delimiter, e.g. to avoid getting empty string elements, pass a pattern like ``' +'``. Be aware that passing patterns that match empty @@ -2975,10 +2975,10 @@ parameters. (e.g. combining the previous two examples into ``-abcdparam``) Long options focus on clarity. They are usually entire words, or several words - combined with hypens (``-``) or underscores (``_``). If they take an argument, - the argument can be separated from the option name by a space or an equals - sign (``=``). For example, the following two commandlines are equivalent: - ``yourscript --style pretty`` and ``yourscript --style=pretty``. + combined with hyphens (``-``) or underscores (``_``). If they take an + argument, the argument can be separated from the option name by a space or an + equals sign (``=``). For example, the following two commandlines are + equivalent: ``yourscript --style pretty`` and ``yourscript --style=pretty``. Another reason to use long options is if they represent an esoteric parameter that you don't expect to be commonly used and that you don't want to "waste" a @@ -3172,7 +3172,7 @@ create profiler objects which can be used to profile and generate report. * ``profiler.newProfiler([variant[, sampling_frequency]])`` - Returns an profile object with ``variant`` either ``'time'`` or ``'call'``. + Returns a profile object with ``variant`` either ``'time'`` or ``'call'``. ``'time'`` variant takes optional ``sampling_frequency`` parameter to select lua instruction counts between samples. Default is ``'time'`` variant with ``10*1000`` frequency. @@ -3257,7 +3257,7 @@ Implements a trivial single-inheritance class system. The main difference is that attributes are processed as a separate initialization step, before any ``init`` methods are called. They - also make the directy relation between instance fields and constructor + also make the direct relation between instance fields and constructor arguments more explicit. * ``new_obj = Class{ foo = arg, bar = arg, ... }`` @@ -3267,8 +3267,8 @@ Implements a trivial single-inheritance class system. 1. An empty instance table is created, and its metatable set. 2. The ``preinit`` methods are called via ``invoke_before`` (see below) - with the table used as argument to the class. These methods are intended - for validating and tweaking that argument table. + with the table used as the argument to the class. These methods are + intended for validating and tweaking that argument table. 3. Declared ATTRS are initialized from the argument table or their default values. 4. The ``init`` methods are called via ``invoke_after`` with the argument table. This is the main constructor method. @@ -3339,7 +3339,7 @@ A module for reading custom tokens added to the raws by mods. Where ``typeInstance`` is a unit, entity, item, job, projectile, building, plant, or interaction instance. Gets ``typeDefinition`` and then returns the same as ``getToken(typeDefinition, token)``. - For units, it gets the token from the race or caste instead if appplicable. For plants growth items, + For units, it gets the token from the race or caste instead if applicable. For plants growth items, it gets the token from the plant or plant growth instead if applicable. For plants it does the same but with growth number -1. @@ -3661,7 +3661,7 @@ It also always has the following fields: These fields are computed by the layout process: -:frame_parent_rect: The ViewRect represeting the client area of the parent view. +:frame_parent_rect: The ViewRect representing the client area of the parent view. :frame_rect: The ``mkdims`` rect of the outer frame in parent-local coordinates. :frame_body: The ViewRect representing the body part of the View's own frame. @@ -3897,13 +3897,13 @@ Base of all the widgets. Inherits from View and has the following attributes: :r: gap between the right edges of the frame and the parent. :b: gap between the bottom edges of the frame and the parent. :w: maximum width of the frame. - :h: maximum heigth of the frame. + :h: maximum height of the frame. :xalign: X alignment of the frame. :yalign: Y alignment of the frame. First the ``l,t,r,b`` fields restrict the available area for placing the frame. If ``w`` and ``h`` are not specified or - larger then the computed area, it becomes the frame. Otherwise + larger than the computed area, it becomes the frame. Otherwise the smaller frame is placed within the are based on the ``xalign/yalign`` fields. If the align hints are omitted, they are assumed to be 0, 1, or 0.5 based on which of the ``l/r/t/b`` @@ -4437,7 +4437,7 @@ Functions .. note:: this is the only mandatory field. :fix_impassible: - if true make impassible tiles impassible to liquids too + if true make impassable tiles impassable to liquids too :consume: how much machine power is needed to work. Disables reactions if not supplied enough and ``needs_power==1`` @@ -4461,7 +4461,7 @@ Functions :canBeRoomSubset: a flag if this building can be counted in room. 1 means it can, 0 means it can't and -1 default building behaviour :auto_gears: - a flag that automatically fills up gears and animate. It looks over building definition for gear icons and maps them. + a flag that automatically fills up gears and animations. It looks over the building definition for gear icons and maps them. Animate table also might contain: @@ -4472,7 +4472,7 @@ Functions ``getPower(building)`` returns two number - produced and consumed power if building can be modified and returns nothing otherwise -``setPower(building,produced,consumed)`` sets current productiona and consumption for a building. +``setPower(building,produced,consumed)`` sets current power production and consumption for a building. Examples -------- @@ -4506,7 +4506,7 @@ Native functions provided by the `buildingplan` plugin: * ``bool isPlanModeEnabled(df::building_type type, int16_t subtype, int32_t custom)`` returns whether the buildingplan UI is enabled for the specified building type. * ``bool isPlannedBuilding(df::building *bld)`` returns whether the given building is managed by buildingplan. * ``void addPlannedBuilding(df::building *bld)`` suspends the building jobs and adds the building to the monitor list. -* ``void doCycle()`` runs a check for whether buildlings in the monitor list can be assigned items and unsuspended. This method runs automatically twice a game day, so you only need to call it directly if you want buildingplan to do a check right now. +* ``void doCycle()`` runs a check for whether buildings in the monitor list can be assigned items and unsuspended. This method runs automatically twice a game day, so you only need to call it directly if you want buildingplan to do a check right now. * ``void scheduleCycle()`` schedules a cycle to be run during the next non-paused game frame. Can be called multiple times while the game is paused and only one cycle will be scheduled. burrows @@ -4740,7 +4740,7 @@ List of events 1. ``onReactionCompleting(reaction,reaction_product,unit,input_items,input_reagents,output_items,call_native)`` - Is called once per reaction product, before reaction had a chance to call native code for item creation. + Is called once per reaction product, before the reaction has a chance to call native code for item creation. Setting ``call_native.value=false`` cancels further processing: no items are created and ``onReactionComplete`` is not called. 2. ``onReactionComplete(reaction,reaction_product,unit,input_items,input_reagents,output_items)`` @@ -4796,7 +4796,7 @@ These events are straight from EventManager module. Each of them first needs to 4. ``onJobCompleted(job)`` - Gets called when job is finished. The job that is passed to this function is a copy. Requires a frequency of 0 in order to distinguish between workshop jobs that were cancelled by the user and workshop jobs that completed successfully. + Gets called when job is finished. The job that is passed to this function is a copy. Requires a frequency of 0 in order to distinguish between workshop jobs that were canceled by the user and workshop jobs that completed successfully. 5. ``onUnitDeath(unit_id)`` @@ -4855,7 +4855,7 @@ Functions 5. ``registerSidebar(shop_name,callback)`` - Enable callback when sidebar for ``shop_name`` is drawn. Usefull for custom workshop views e.g. using gui.dwarfmode lib. Also accepts a ``class`` instead of function + Enable callback when sidebar for ``shop_name`` is drawn. Useful for custom workshop views e.g. using gui.dwarfmode lib. Also accepts a ``class`` instead of function as callback. Best used with ``gui.dwarfmode`` class ``WorkshopOverlay``. Examples @@ -4898,7 +4898,7 @@ luasocket ========= A way to access csocket from lua. The usage is made similar to luasocket in vanilla lua distributions. Currently -only subset of functions exist and only tcp mode is implemented. +only a subset of the functions exist and only tcp mode is implemented. .. contents:: :local: @@ -4977,7 +4977,7 @@ Functions - ``render_map_rect(x,y,z,w,h)`` - returns a table with w*h*4 entries of rendered tiles. The format is same as ``df.global.gps.screen`` (tile,foreground,bright,background). + returns a table with w*h*4 entries of rendered tiles. The format is the same as ``df.global.gps.screen`` (tile,foreground,bright,background). .. _pathable-api: @@ -5094,7 +5094,7 @@ Scripts :local: Any files with the ``.lua`` extension placed into the :file:`hack/scripts` folder -are automatically made avaiable as DFHack commands. The command corresponding to +are automatically made available as DFHack commands. The command corresponding to a script is simply the script's filename, relative to the scripts folder, with the extension omitted. For example: diff --git a/docs/NEWS.rst b/docs/NEWS.rst index fb33aebf9..13d5e38de 100644 --- a/docs/NEWS.rst +++ b/docs/NEWS.rst @@ -22,6 +22,6 @@ See `dev-changelog` for a list of changes grouped by development releases. Older Changelogs ================ -Are kept in a seperate file: `History` +Are kept in a separate file: `History` .. that's ``docs/History.rst``, if you're reading the raw text. diff --git a/docs/Structures-intro.rst b/docs/Structures-intro.rst index 48aa571c8..9d304949f 100644 --- a/docs/Structures-intro.rst +++ b/docs/Structures-intro.rst @@ -18,7 +18,7 @@ layout changes, and will need to be recompiled for every new DF version. Addresses of DF global objects and vtables are stored in a separate file, :file:`symbols.xml`. Since these are only absolute addresses, they do not need -to be compiled in to DFHack code, and are instead loaded at runtime. This makes +to be compiled into DFHack code, and are instead loaded at runtime. This makes fixes and additions to global addresses possible without recompiling DFHack. In an installed copy of DFHack, this file can be found at the root of the ``hack`` folder. diff --git a/docs/Tags.rst b/docs/Tags.rst index 45bfeb9b3..2ee18de48 100644 --- a/docs/Tags.rst +++ b/docs/Tags.rst @@ -43,6 +43,6 @@ for the tag assignment spreadsheet. - `map `: Tools that interact with the game map. - `military `: Tools that interact with the military. - `plants `: Tools that interact with trees, shrubs, and crops. -- `stockpiles `: Tools that interact wtih stockpiles. +- `stockpiles `: Tools that interact with stockpiles. - `units `: Tools that interact with units. - `workorders `: Tools that interact with workorders. diff --git a/docs/guides/modding-guide.rst b/docs/guides/modding-guide.rst index 4b768be58..da33a5a9d 100644 --- a/docs/guides/modding-guide.rst +++ b/docs/guides/modding-guide.rst @@ -129,7 +129,7 @@ provides two libraries for this, ``repeat-util`` and `eventful `. ``repeat-util`` is used to run a function once per a configurable number of frames (paused or unpaused), ticks (unpaused), in-game days, months, or years. If you need to be aware the instant something happens, you'll need to run a -check once a tick. Be careful not to do this gratuitiously, though, since +check once a tick. Be careful not to do this gratuitously, though, since running that often can slow down the game! ``eventful``, on the other hand, is much more performance-friendly since it will @@ -176,10 +176,10 @@ you can react to with ``eventful``. Now, you may have noticed that you won't be able to register multiple callbacks with a single key named after your mod. You can, of course, call all the -functions you want from a single registed callback. Alternately, you can create -multiple callbacks using different keys, using your mod ID as a key name prefix. -If you do register multiple callbacks, though, there are no guarantees about the -call order. +functions you want from a single registered callback. Alternately, you can +create multiple callbacks using different keys, using your mod ID as a key name +prefix. If you do register multiple callbacks, though, there are no guarantees +about the call order. Custom raw tokens ----------------- diff --git a/docs/guides/quickfort-alias-guide.rst b/docs/guides/quickfort-alias-guide.rst index 50e5d7650..a89e6f338 100644 --- a/docs/guides/quickfort-alias-guide.rst +++ b/docs/guides/quickfort-alias-guide.rst @@ -80,7 +80,7 @@ sequence, potentially with other aliases. If the alias is the only text in the cell, the alias name is matched and its expansion is used. If the alias has other keys before or after it, the alias name must be surrounded in curly brackets (:kbd:`{` and :kbd:`}`). An alias can be surrounded in curly brackets -even if it is the only text in the cell, it just isn't necesary. For example, +even if it is the only text in the cell, it just isn't necessary. For example, the following blueprint uses the ``aliasname`` alias by itself in the first two rows and uses it as part of a longer sequence in the third row:: @@ -454,7 +454,7 @@ be used for either the ``quantum_enable`` or ``route_enable`` sub-aliases. Experienced Dwarf Fortress players may be wondering how the same aliases can work in both contexts since the keys for entering the configuration screen differ. Fear not! There is some sub-alias magic at work here. If you define -your own stockpile configuraiton aliases, you can use the magic yourself by +your own stockpile configuration aliases, you can use the magic yourself by building your aliases on the ``*prefix`` aliases described later in this guide. @@ -652,7 +652,7 @@ sheetprefix enablesheet disablesheet Then, for each item category, there are aliases that manipulate interesting subsets of that category: -* Exclusive aliases forbid everthing within a category and then enable only +* Exclusive aliases forbid everything within a category and then enable only the named item type (or named class of items) * ``forbid*`` aliases forbid the named type and leave the rest of the stockpile untouched. diff --git a/docs/guides/quickfort-library-guide.rst b/docs/guides/quickfort-library-guide.rst index 86c82ac60..157bb10a1 100644 --- a/docs/guides/quickfort-library-guide.rst +++ b/docs/guides/quickfort-library-guide.rst @@ -198,7 +198,7 @@ Light aquifer tap ~~~~~~~~~~~~~~~~~ The aquifer tap helps you create a safe, everlasting source of fresh water from -a light aquifer. See the step-by-step guide, including informaton on how to +a light aquifer. See the step-by-step guide, including information on how to create a drainage system so your dwarves don't drown when digging the tap, by running ``quickfort run library/aquifer_tap.csv -n /help``. diff --git a/docs/guides/quickfort-user-guide.rst b/docs/guides/quickfort-user-guide.rst index 693ab033c..71a80818c 100644 --- a/docs/guides/quickfort-user-guide.rst +++ b/docs/guides/quickfort-user-guide.rst @@ -245,7 +245,7 @@ If there weren't an alias named ``booze`` then the literal characters spell those aliases correctly! You can save a lot of time and effort by using aliases instead of adding all -key seqences directly to your blueprints. For more details, check out the +key sequences directly to your blueprints. For more details, check out the `quickfort-alias-guide`. You can also see examples of aliases being used in the query blueprints in the :source:`DFHack blueprint library `. You can create @@ -683,7 +683,7 @@ three vertical tiles like this:: ` end here ` # # # # # -Then to carve the cross, you'd do a horizonal segment:: +Then to carve the cross, you'd do a horizontal segment:: ` ` ` # start here ` end here # @@ -740,7 +740,7 @@ Or you could use the aliases to specify tile by tile:: # # # # The aliases can also be used to designate a solid block of track. This is -epecially useful for obliterating low-quality engravings so you can re-smooth +especially useful for obliterating low-quality engravings so you can re-smooth and re-engrave with higher quality. For example, you could use the following sequence of blueprints to ensure a 10x10 floor area contains only masterwork engravings:: @@ -1157,7 +1157,7 @@ blueprint:: "#meta label(help) message(This is the help text for the blueprint set contained in this file. - First, make sure that you embark in...) blueprint set walkthough" + First, make sure that you embark in...) blueprint set walkthrough" could more naturally be written as a ``#notes`` blueprint:: @@ -1739,7 +1739,7 @@ priorities `. Use dig priorities to control ramp creation. We can `ensure `__ -the bottom level is carved out before the layer above is channelled by assigning +the bottom level is carved out before the layer above is channeled by assigning the channel designations lower priorities (the ``h5``\s in the third layer -- scroll down). diff --git a/docs/plugins/autobutcher.rst b/docs/plugins/autobutcher.rst index 83c99271a..f288f9073 100644 --- a/docs/plugins/autobutcher.rst +++ b/docs/plugins/autobutcher.rst @@ -6,7 +6,7 @@ autobutcher :tags: fort auto fps animals This plugin monitors how many pets you have of each gender and age and assigns -excess lifestock for slaughter. It requires that you add the target race(s) to a +excess livestock for slaughter. It requires that you add the target race(s) to a watch list. Units will be ignored if they are: * Untamed @@ -44,7 +44,7 @@ Usage - fa = number of female adults - ma = number of female adults If you specify ``all``, then this command will set the counts for all races - on your current watchlist (including the races which are currenly set to + on your current watchlist (including the races which are currently set to 'unwatched') and sets the new default for future watch commands. If you specify ``new``, then this command just sets the new default counts for future watch commands without changing your current watchlist. Otherwise, diff --git a/docs/plugins/autolabor.rst b/docs/plugins/autolabor.rst index 861655ab4..b39884957 100644 --- a/docs/plugins/autolabor.rst +++ b/docs/plugins/autolabor.rst @@ -11,7 +11,7 @@ dwarves to specialize in specific skills. Autolabor frequently checks how many jobs of each type are available and sets labors proportionally in order to get them all done quickly. Labors with equipment -- mining, hunting, and woodcutting -- which are abandoned if labors -change mid-job, are handled slightly differently to minimise churn. +change mid-job, are handled slightly differently to minimize churn. Dwarves on active military duty or dwarves assigned to burrows are left untouched by autolabor. @@ -39,7 +39,7 @@ and filling ponds. Other jobs are automatically assigned as described above. Each of these settings can be adjusted. Jobs are rarely assigned to nobles with responsibilities for meeting diplomats -or merchants, never to the chief medical dwarf, and less often to the bookeeper +or merchants, never to the chief medical dwarf, and less often to the bookkeeper and manager. Hunting is never assigned without a butchery, and fishing is never assigned @@ -63,7 +63,7 @@ Examples ``autolabor MINE 5`` Keep at least 5 dwarves with mining enabled. ``autolabor CUT_GEM 1 1`` - Keep exactly 1 dwarf with gemcutting enabled. + Keep exactly 1 dwarf with gem cutting enabled. ``autolabor COOK 1 1 3`` Keep 1 dwarf with cooking enabled, selected only from the top 3. ``autolabor FEED_WATER_CIVILIANS haulers`` diff --git a/docs/plugins/automaterial.rst b/docs/plugins/automaterial.rst index 068664638..ac1b3a1da 100644 --- a/docs/plugins/automaterial.rst +++ b/docs/plugins/automaterial.rst @@ -48,6 +48,6 @@ construction menu after selecting materials, it returns you back to this screen. If you use this along with several autoselect enabled materials, you should be able to place complex constructions more conveniently. -The ``automaterial`` plugin also enables extra contruction placement modes, such -as designating areas larger than 10x10 and allowing you to designate hollow +The ``automaterial`` plugin also enables extra construction placement modes, +such as designating areas larger than 10x10 and allowing you to designate hollow rectangles instead of the default filled ones. diff --git a/docs/plugins/burrows.rst b/docs/plugins/burrows.rst index 50d736b95..fb3876e97 100644 --- a/docs/plugins/burrows.rst +++ b/docs/plugins/burrows.rst @@ -34,7 +34,7 @@ Usage ``burrow remove-units target-burrow [ ...]`` Remove units in source burrows from the target. ``burrow set-tiles target-burrow [ ...]`` - Clear target burrow tiles and adds tiles from the names source burrows. + Clear target burrow tiles and add tiles from the names source burrows. ``burrow add-tiles target-burrow [ ...]`` Add tiles from the source burrows to the target. ``burrow remove-tiles target-burrow [ ...]`` diff --git a/docs/plugins/changelayer.rst b/docs/plugins/changelayer.rst index f9467315f..f986a1e3d 100644 --- a/docs/plugins/changelayer.rst +++ b/docs/plugins/changelayer.rst @@ -35,7 +35,7 @@ Examples ``changelayer GRANITE`` Convert the layer at the cursor position into granite. ``changelayer SILTY_CLAY force`` - Convert teh layer at the cursor position into clay, even if it's stone. + Convert the layer at the cursor position into clay, even if it's stone. ``changelayer MARBLE all_biomes all_layers`` Convert all layers of all biomes which are not soil into marble. diff --git a/docs/plugins/changevein.rst b/docs/plugins/changevein.rst index f033a4a6a..4e4512bb1 100644 --- a/docs/plugins/changevein.rst +++ b/docs/plugins/changevein.rst @@ -5,7 +5,7 @@ changevein :summary: Change the material of a mineral inclusion. :tags: fort armok map -You can change a vein to any incorganic material RAW id. Note that this command +You can change a vein to any inorganic material RAW id. Note that this command only affects tiles within the current 16x16 block - for large veins and clusters, you will need to use this command multiple times. diff --git a/docs/plugins/command-prompt.rst b/docs/plugins/command-prompt.rst index 7ccad6c71..c4b464a80 100644 --- a/docs/plugins/command-prompt.rst +++ b/docs/plugins/command-prompt.rst @@ -13,7 +13,7 @@ Usage command-prompt [entry] If called with parameters, it starts with that text in the command edit area. -This is most useful for developers, who can set a keybinding to open a laungage +This is most useful for developers, who can set a keybinding to open a language interpreter for lua or Ruby by starting with the `:lua ` or `:rb ` portions of the command already filled in. diff --git a/docs/plugins/cursecheck.rst b/docs/plugins/cursecheck.rst index 2d623241c..94012919b 100644 --- a/docs/plugins/cursecheck.rst +++ b/docs/plugins/cursecheck.rst @@ -33,7 +33,7 @@ Examples - ``cursecheck detail all`` Give detailed info about all cursed creatures including deceased ones. - ``cursecheck nick`` - Give a nickname all living/active cursed creatures. + Give a nickname to all living/active cursed creatures. .. note:: diff --git a/docs/plugins/debug.rst b/docs/plugins/debug.rst index 0e184595f..0c5a587fb 100644 --- a/docs/plugins/debug.rst +++ b/docs/plugins/debug.rst @@ -42,13 +42,13 @@ Usage ----- ``debugfilter category [] []`` - List available debug plugin and category names. If filters aren't givenm + List available debug plugin and category names. If filters aren't given then all plugins/categories are matched. This command is a good way to test regex parameters before you pass them to ``set``. ``debugfilter filter []`` List active and passive debug print level changes. The optional ``id`` - parameter is the id listed as first column in the filter list. If ``id`` is - given, then the command shows extended information for the given filter + parameter is the id listed as the first column in the filter list. If ``id`` + is given, then the command shows extended information for the given filter only. ``debugfilter set [] [] []`` Create a new debug filter to set category verbosity levels. This filter @@ -61,7 +61,7 @@ Usage ``debugfilter disable [ ...]`` Disable a space separated list of filters but keep it in the filter list. ``debugfilter enable [ ...]`` - Enable a space sperate list of filters. + Enable a space separated list of filters. ``debugfilter header [enable] | [disable] [ ...]`` Control which header metadata is shown along with each log message. Run it without parameters to see the list of configurable elements. Include an diff --git a/docs/plugins/dwarfmonitor.rst b/docs/plugins/dwarfmonitor.rst index bfdbd13b5..79472ae58 100644 --- a/docs/plugins/dwarfmonitor.rst +++ b/docs/plugins/dwarfmonitor.rst @@ -87,7 +87,7 @@ Some widgets support additional options: * ``cursor`` widget: * ``format``: Specifies the format. ``X``, ``x``, ``Y``, and ``y`` are - replaced with the corresponding cursor cordinates, while all other + replaced with the corresponding cursor coordinates, while all other characters are unmodified. * ``show_invalid``: If set to ``true``, the mouse coordinates will both be displayed as ``-1`` when the cursor is outside of the DF window; otherwise, diff --git a/docs/plugins/dwarfvet.rst b/docs/plugins/dwarfvet.rst index e7ddf73d6..fa165250d 100644 --- a/docs/plugins/dwarfvet.rst +++ b/docs/plugins/dwarfvet.rst @@ -5,12 +5,12 @@ dwarfvet :summary: Allows animals to be treated at animal hospitals. :tags: fort gameplay animals -Annoyed your dragons become useless after a minor injury? Well, with dwarfvet, -injured animals will be treated at an animal hospital, which is simply a hospital -that is also an animal training zone. Dwarfs with the Animal Caretaker labor -enabled will come to the hospital to treat animals. Normal medical skills are -used (and trained), but no experience is given to the Animal Caretaker skill -itself. +Annoyed that your dragons become useless after a minor injury? Well, with +dwarfvet, injured animals will be treated at an animal hospital, which is simply +a hospital that is also an animal training zone. Dwarfs with the Animal +Caretaker labor enabled will come to the hospital to treat animals. Normal +medical skills are used (and trained), but no experience is given to the Animal +Caretaker skill itself. Usage ----- diff --git a/docs/plugins/embark-tools.rst b/docs/plugins/embark-tools.rst index 64db27953..781d66e90 100644 --- a/docs/plugins/embark-tools.rst +++ b/docs/plugins/embark-tools.rst @@ -14,7 +14,7 @@ Usage embark-tools enable|disable all embark-tools enable|disable [ ...] -Avaliable tools are: +Available tools are: ``anywhere`` Allows embarking anywhere (including sites, mountain-only biomes, and diff --git a/docs/plugins/fix-unit-occupancy.rst b/docs/plugins/fix-unit-occupancy.rst index 991c77314..0559d4a2f 100644 --- a/docs/plugins/fix-unit-occupancy.rst +++ b/docs/plugins/fix-unit-occupancy.rst @@ -18,7 +18,7 @@ Usage fix-unit-occupancy interval When run without arguments (or with just the ``here`` or ``-n`` parameters), -the fix just runs once. You can also have it run periodically by enbling the +the fix just runs once. You can also have it run periodically by enabling the plugin. Examples @@ -35,7 +35,7 @@ Options ``here`` Only operate on the tile at the cursor. ``-n`` - Report issues, but do not any write changes to the map. + Report issues, but do not write any changes to the map. ``interval `` Set how often the plugin will check for and fix issues when it is enabled. The default is 1200 ticks, or 1 game day. diff --git a/docs/plugins/forceequip.rst b/docs/plugins/forceequip.rst index a32af524b..26ab378ee 100644 --- a/docs/plugins/forceequip.rst +++ b/docs/plugins/forceequip.rst @@ -64,7 +64,7 @@ Examples ``forceequip v bp QQQ`` List the bodyparts of the selected unit. ``forceequip bp LH`` - Equips an appopriate item onto the unit's left hand. + Equips an appropriate item onto the unit's left hand. ``forceequip m bp LH`` Equips ALL appropriate items onto the unit's left hand. The unit may end up wearing a dozen left-handed mittens. Use with caution, and remember that diff --git a/docs/plugins/labormanager.rst b/docs/plugins/labormanager.rst index 5c3632b6a..e3443280d 100644 --- a/docs/plugins/labormanager.rst +++ b/docs/plugins/labormanager.rst @@ -37,7 +37,7 @@ explicitly disable it, even if you save and reload your game. The default priorities for each labor vary (some labors are higher priority by default than others). The way the plugin works is that, once it determines how -many jobs of each labor is needed, it then sorts them by adjusted priority. +many jobs of each labor are needed, it then sorts them by adjusted priority. (Labors other than hauling have a bias added to them based on how long it's been since they were last used to prevent job starvation.) The labor with the highest priority is selected, the "best fit" dwarf for that labor is assigned to that @@ -112,7 +112,7 @@ Advanced usage ``labormanager priority `` Set the priority value for labor to . ``labormanager max `` - Set maximum number of dwarves that can be assigned to a labor. + Set the maximum number of dwarves that can be assigned to a labor. ``labormanager max none`` Unrestrict the number of dwarves that can be assigned to a labor. ``labormanager max disable`` diff --git a/docs/plugins/lair.rst b/docs/plugins/lair.rst index ed2816818..9bded57ab 100644 --- a/docs/plugins/lair.rst +++ b/docs/plugins/lair.rst @@ -11,7 +11,7 @@ Usage ----- ``lair`` - Mark the map as monster lair. + Mark the map as a monster lair. ``lair reset`` Mark the map as ordinary (not lair). diff --git a/docs/plugins/manipulator.rst b/docs/plugins/manipulator.rst index 3dc7f35b7..f333f3be0 100644 --- a/docs/plugins/manipulator.rst +++ b/docs/plugins/manipulator.rst @@ -102,7 +102,7 @@ and how many you are likely to need in a mature fort. These are just approximations. Your playstyle may demand more or fewer of each profession. - ``Chef`` (needed: 0, 3) - Buchery, Tanning, and Cooking. It is important to focus just a few dwarves + Butchery, Tanning, and Cooking. It is important to focus just a few dwarves on cooking since well-crafted meals make dwarves very happy. They are also an excellent trade good. - ``Craftsdwarf`` (needed: 0, 4-6) diff --git a/docs/plugins/map-render.rst b/docs/plugins/map-render.rst index efe3ed0c6..935fc1010 100644 --- a/docs/plugins/map-render.rst +++ b/docs/plugins/map-render.rst @@ -2,7 +2,7 @@ map-render ========== .. dfhack-tool:: - :summary: Provides a Lua API for rerendering portions of the map. + :summary: Provides a Lua API for re-rendering portions of the map. :tags: dev graphics :no-command: diff --git a/docs/plugins/power-meter.rst b/docs/plugins/power-meter.rst index 5e608ca46..701a656b5 100644 --- a/docs/plugins/power-meter.rst +++ b/docs/plugins/power-meter.rst @@ -2,7 +2,7 @@ power-meter =========== .. dfhack-tool:: - :summary: Allow presure plates to measure power. + :summary: Allow pressure plates to measure power. :tags: fort gameplay buildings :no-command: diff --git a/docs/plugins/regrass.rst b/docs/plugins/regrass.rst index 1a3fc7ed9..5512a428b 100644 --- a/docs/plugins/regrass.rst +++ b/docs/plugins/regrass.rst @@ -2,7 +2,7 @@ regrass ======= .. dfhack-tool:: - :summary: Regrows all the grass. + :summary: Regrow all the grass. :tags: adventure fort armok animals map Use this command if your grazers have eaten everything down to the dirt. diff --git a/docs/plugins/rendermax.rst b/docs/plugins/rendermax.rst index 747b74642..ee909fd9a 100644 --- a/docs/plugins/rendermax.rst +++ b/docs/plugins/rendermax.rst @@ -12,7 +12,7 @@ Usage ----- ``rendermax light`` - Light the map tiles realisitically. Outside tiles are light during the day + Light the map tiles realistically. Outside tiles are light during the day and dark at night. Inside tiles are always dark unless a nearby unit is lighting it up, as if they were carrying torches. ``rendermax light sun |cycle`` diff --git a/docs/plugins/resume.rst b/docs/plugins/resume.rst index d6e0b81cb..af3fe161d 100644 --- a/docs/plugins/resume.rst +++ b/docs/plugins/resume.rst @@ -12,7 +12,7 @@ resume When enabled, this plugin will display a colored 'X' over suspended buildings. When run as a command, it can resume all suspended building jobs, allowing you to quickly recover if a bunch of jobs were suspended due to the workers getting -scared off by wildlife or items temporarily blocking buildling sites. +scared off by wildlife or items temporarily blocking building sites. Usage ----- diff --git a/docs/plugins/search.rst b/docs/plugins/search.rst index c489b4c40..e588e3196 100644 --- a/docs/plugins/search.rst +++ b/docs/plugins/search.rst @@ -9,7 +9,7 @@ search :no-command: Search options are added to the Stocks, Animals, Trading, Stockpile, Noble -aassignment candidates), Military (position candidates), Burrows (unit list), +assignment candidates), Military (position candidates), Burrows (unit list), Rooms, Announcements, Job List, and Unit List screens all get hotkeys that allow you to dynamically filter the displayed lists. diff --git a/docs/plugins/seedwatch.rst b/docs/plugins/seedwatch.rst index c471f467d..b41f3a977 100644 --- a/docs/plugins/seedwatch.rst +++ b/docs/plugins/seedwatch.rst @@ -21,7 +21,7 @@ Usage Start managing seed and plant cooking. By default, no types are watched. You have to add them with further ``seedwatch`` commands. ``seedwatch `` - Adds the specifiied type to the watchlist (if it's not already there) and + Adds the specified type to the watchlist (if it's not already there) and sets the target number of seeds to the specified number. You can pass the keyword ``all`` instead of a specific type to set the target for all types. ``seedwatch `` diff --git a/docs/plugins/stocks.rst b/docs/plugins/stocks.rst index d8fae9579..03eb3a72c 100644 --- a/docs/plugins/stocks.rst +++ b/docs/plugins/stocks.rst @@ -21,4 +21,4 @@ Usage stocks show Running ``stocks show`` will bring you to the fortress-wide stock management -screen from whereever you are. +screen from wherever you are. diff --git a/docs/plugins/tiletypes.rst b/docs/plugins/tiletypes.rst index 44fba00df..7b93dd6de 100644 --- a/docs/plugins/tiletypes.rst +++ b/docs/plugins/tiletypes.rst @@ -58,7 +58,7 @@ Examples ``tiletypes-command filter material STONE ; f shape WALL ; paint shape FLOOR`` Turn all stone walls into floors, preserving the material. ``tiletypes-command p any ; p s wall ; p sp normal`` - Clear the paint specificaiton and set it to unsmoothed walls. + Clear the paint specification and set it to unsmoothed walls. ``tiletypes-command f any ; p stone marble ; p sh wall ; p sp normal ; r 10 10`` Prepare to paint a 10x10 area of marble walls, ready for harvesting for flux. diff --git a/docs/plugins/tubefill.rst b/docs/plugins/tubefill.rst index 1085897c8..80282f6d9 100644 --- a/docs/plugins/tubefill.rst +++ b/docs/plugins/tubefill.rst @@ -2,7 +2,7 @@ tubefill ======== .. dfhack-tool:: - :summary: Replentishes mined-out adamantine. + :summary: Replenishes mined-out adamantine. :tags: fort armok map Veins that were originally hollow will be left alone. diff --git a/docs/plugins/tweak.rst b/docs/plugins/tweak.rst index bb125fc0d..aa1ad578b 100644 --- a/docs/plugins/tweak.rst +++ b/docs/plugins/tweak.rst @@ -66,7 +66,7 @@ Commands that persist until disabled or DF quits: ``civ-view-agreement`` Fixes overlapping text on the "view agreement" screen. ``condition-material`` - Fixes a crash in the work order contition material list (:bug:`9905`). + Fixes a crash in the work order condition material list (:bug:`9905`). ``craft-age-wear`` Fixes crafted items not wearing out over time (:bug:`6003`). With this tweak, items made from cloth and leather will gain a level of wear every 20 diff --git a/docs/plugins/workflow.rst b/docs/plugins/workflow.rst index 9013ba189..f085a40da 100644 --- a/docs/plugins/workflow.rst +++ b/docs/plugins/workflow.rst @@ -122,7 +122,7 @@ The constraint spec consists of 4 parts, separated with ``/`` characters:: ITEM[:SUBTYPE]/[GENERIC_MAT,...]/[SPECIFIC_MAT:...]/[LOCAL,] The first part is mandatory and specifies the item type and subtype, using the -raw tokens for items (the same syntax used custom reaction inputs). For more +raw tokens for items (the same syntax used for custom reaction inputs). For more information, see :wiki:`this wiki page `. The subsequent parts are optional: diff --git a/docs/plugins/zone.rst b/docs/plugins/zone.rst index 93b244399..0f77e1d3e 100644 --- a/docs/plugins/zone.rst +++ b/docs/plugins/zone.rst @@ -74,8 +74,8 @@ Filters :all: Process all units. :count : Process only up to n units. :unassigned: Not assigned to zone, chain or built cage. -:minage : Minimum age. Must be followed by number. -:maxage : Maximum age. Must be followed by number. +:minage : Minimum age. Must be followed by a number. +:maxage : Maximum age. Must be followed by a number. :not: Negates the next filter keyword. All of the keywords documented below are negatable. :race: Must be followed by a race RAW ID (e.g. BIRD_TURKEY, ALPACA, From 663916b86bbc22ed4885352591c6da32de20c487 Mon Sep 17 00:00:00 2001 From: myk002 Date: Wed, 28 Sep 2022 14:56:20 -0700 Subject: [PATCH 51/73] update wording for autolabor --- docs/plugins/autolabor.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/plugins/autolabor.rst b/docs/plugins/autolabor.rst index b39884957..63b830dfe 100644 --- a/docs/plugins/autolabor.rst +++ b/docs/plugins/autolabor.rst @@ -46,10 +46,9 @@ Hunting is never assigned without a butchery, and fishing is never assigned without a fishery. For each labor, a preference order is calculated based on skill, excluding those -who can't do the job. Dwarves who are masters of particular skills are -deprioritized in the preference list for other skills. The labor is then added -to the best dwarves for that labor, then to additional dwarfs that -meet any of these conditions: +who can't do the job. Dwarves who are masters of a skill are deprioritized for +other skills. The labor is then added to the best dwarves for that +labor, then to additional dwarfs that meet any of these conditions: * The dwarf is idle and there are no idle dwarves assigned to this labor * The dwarf has non-zero skill associated with the labor From dbeaff7c16e92710b34ee4a5eca2e5f65228dab1 Mon Sep 17 00:00:00 2001 From: DFHack-Urist via GitHub Actions <63161697+DFHack-Urist@users.noreply.github.com> Date: Wed, 28 Sep 2022 21:57:33 +0000 Subject: [PATCH 52/73] Auto-update submodules scripts: master --- scripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts b/scripts index 4f568fc83..3da6fa744 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 4f568fc8331d62bc6646055c1252bba19b3a526d +Subproject commit 3da6fa7444ad537e92a6ad2e1cfad964990c87fd From 95bbdcd93474d1b55816edb2da93a2a543e1749d Mon Sep 17 00:00:00 2001 From: DFHack-Urist via GitHub Actions <63161697+DFHack-Urist@users.noreply.github.com> Date: Thu, 29 Sep 2022 07:37:17 +0000 Subject: [PATCH 53/73] Auto-update submodules scripts: master --- scripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts b/scripts index 3da6fa744..cfb11e1d0 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 3da6fa7444ad537e92a6ad2e1cfad964990c87fd +Subproject commit cfb11e1d0cee48f29b4a8323acc7a32787a8ddda From 8a381ee520d7fa4e17005fc43c1be4403e633141 Mon Sep 17 00:00:00 2001 From: DFHack-Urist via GitHub Actions <63161697+DFHack-Urist@users.noreply.github.com> Date: Fri, 30 Sep 2022 07:42:02 +0000 Subject: [PATCH 54/73] Auto-update submodules scripts: master --- scripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts b/scripts index cfb11e1d0..19c0d1d8b 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit cfb11e1d0cee48f29b4a8323acc7a32787a8ddda +Subproject commit 19c0d1d8b131446c27513eb85bd27d48e8ea214e From 3f6e92eda49579a7fa12b589d7a794448c5dc5bd Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 30 Sep 2022 11:58:22 -0700 Subject: [PATCH 55/73] finalize 0.47.05-r7 release --- CMakeLists.txt | 2 +- docs/changelog.txt | 16 ++++++++++++++-- library/xml | 2 +- scripts | 2 +- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8aa57d574..2e6f5c835 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -192,7 +192,7 @@ endif() # set up versioning. set(DF_VERSION "0.47.05") -set(DFHACK_RELEASE "r6") +set(DFHACK_RELEASE "r7") set(DFHACK_PRERELEASE FALSE) set(DFHACK_VERSION "${DF_VERSION}-${DFHACK_RELEASE}") diff --git a/docs/changelog.txt b/docs/changelog.txt index 52e906486..72fb5906c 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -33,13 +33,25 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: # Future +## New Plugins + +## Fixes + +## Misc Improvements + +## Documentation + +## API + +## Lua + +# 0.47.05-r7 + ## New Plugins - `autonestbox`: split off from `zone` into its own plugin. Note that to enable, the command has changed from ``autonestbox start`` to ``enable autonestbox``. - `autobutcher`: split off from `zone` into its own plugin. Note that to enable, the command has changed from ``autobutcher start`` to ``enable autobutcher``. - `overlay`: display a "DFHack" button in the lower left corner that you can click to start the new GUI command launcher. The `dwarfmonitor` weather display had to be moved to make room for the button. If you are seeing the weather indicator rendered over the overlay button, please remove the ``dfhack-config/dwarfmonitor.json`` file to fix the weather indicator display offset. -## New Tweaks - ## New Internal Commands - `tags`: new built-in command to list the tool category tags and their definitions. tags associated with each tool are visible in the tool help and in the output of `ls`. diff --git a/library/xml b/library/xml index f5fab13fb..f5019a5c6 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit f5fab13fb652dd953e9d59e8deca032b26131208 +Subproject commit f5019a5c6f19ef05a28bd974c3e8668b78e6e2a4 diff --git a/scripts b/scripts index 19c0d1d8b..04836f16f 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 19c0d1d8b131446c27513eb85bd27d48e8ea214e +Subproject commit 04836f16f9705bfbb1438fc0870b3e41b6539f75 From 8e9f3e902f889f38764fb5e86950d12fac2badd5 Mon Sep 17 00:00:00 2001 From: Myk Date: Sat, 1 Oct 2022 16:59:33 -0700 Subject: [PATCH 56/73] Update quickfort-user-guide.rst Fix typo --- docs/guides/quickfort-user-guide.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guides/quickfort-user-guide.rst b/docs/guides/quickfort-user-guide.rst index 71a80818c..6f606c43a 100644 --- a/docs/guides/quickfort-user-guide.rst +++ b/docs/guides/quickfort-user-guide.rst @@ -190,8 +190,8 @@ dug-out area:: Cw Cw Cw # # # # # # -Note my generosity -- in addition to the bed (:kbd:`b`) I've built a chest -(:kbd:`c`) here for the dwarf as well. You must use the full series of keys +Note my generosity -- in addition to the bed (:kbd:`b`) I've built a container +(:kbd:`h`) here for the dwarf as well. You must use the full series of keys needed to build something in each cell, e.g. :kbd:`C`:kbd:`w` indicates we should enter DF's constructions submenu (:kbd:`C`) and select walls (:kbd:`w`). From 55d2c20307f3faf293362cc12ef808d92b0fe6bd Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 21:37:36 +0000 Subject: [PATCH 57/73] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/python-jsonschema/check-jsonschema: 0.18.2 → 0.18.3](https://github.com/python-jsonschema/check-jsonschema/compare/0.18.2...0.18.3) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 25f043624..00e01ea22 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,7 +20,7 @@ repos: args: ['--fix=lf'] - id: trailing-whitespace - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.18.2 + rev: 0.18.3 hooks: - id: check-github-workflows - repo: https://github.com/Lucas-C/pre-commit-hooks From 739792a59e0978bf39995c543d3bc33cb85d0a69 Mon Sep 17 00:00:00 2001 From: DFHack-Urist via GitHub Actions <63161697+DFHack-Urist@users.noreply.github.com> Date: Tue, 4 Oct 2022 07:30:12 +0000 Subject: [PATCH 58/73] Auto-update submodules library/xml: master scripts: master --- library/xml | 2 +- scripts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/xml b/library/xml index f5019a5c6..f2b59b8d5 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit f5019a5c6f19ef05a28bd974c3e8668b78e6e2a4 +Subproject commit f2b59b8d5036cca90a88245d0d7c8b2a713f60ee diff --git a/scripts b/scripts index 04836f16f..41bfa9005 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 04836f16f9705bfbb1438fc0870b3e41b6539f75 +Subproject commit 41bfa9005ec78094388518d40e7aaa43f7d35890 From dc535004e9670db733f6d65f89f20215750c29c4 Mon Sep 17 00:00:00 2001 From: myk002 Date: Wed, 5 Oct 2022 12:51:30 -0700 Subject: [PATCH 59/73] better formatting for ls output for tags --- docs/changelog.txt | 1 + library/lua/helpdb.lua | 6 ++++-- test/library/helpdb.lua | 8 ++++---- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index 72fb5906c..d00f4c246 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -38,6 +38,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## Fixes ## Misc Improvements +- `ls`: indent tag listings and wrap them in the right column for better readability ## Documentation diff --git a/library/lua/helpdb.lua b/library/lua/helpdb.lua index ac6adb55d..d07445399 100644 --- a/library/lua/helpdb.lua +++ b/library/lua/helpdb.lua @@ -726,13 +726,15 @@ end local function list_entries(skip_tags, include, exclude) local entries = search_entries(include, exclude) for _,entry in ipairs(entries) do - print_columns(entry, get_entry_short_help(entry)) + local short_help = get_entry_short_help(entry) if not skip_tags then local tags = set_to_sorted_list(get_entry_tags(entry)) if #tags > 0 then - print((' tags: %s'):format(table.concat(tags, ', '))) + local taglist = table.concat(tags, ', ') + short_help = short_help .. NEWLINE .. 'tags: ' .. taglist end end + print_columns(entry, short_help) end if #entries == 0 then print('No matches.') diff --git a/test/library/helpdb.lua b/test/library/helpdb.lua index 067f35532..efa9e93d5 100644 --- a/test/library/helpdb.lua +++ b/test/library/helpdb.lua @@ -637,7 +637,7 @@ function test.ls() expect.eq(5, mock_print.call_count) expect.eq('inscript_docs in-file short description for inscript_docs.', mock_print.call_args[1][1]) - expect.eq(' tags: map', mock_print.call_args[2][1]) + expect.eq(' tags: map', mock_print.call_args[2][1]) expect.eq('nodoc_command cpp description.', mock_print.call_args[3][1]) expect.eq('nodocs_samename Nodocs samename.', @@ -652,15 +652,15 @@ function test.ls() expect.eq(6, mock_print.call_count) expect.eq('bindboxers Bind your boxers.', mock_print.call_args[1][1]) - expect.eq(' tags: armok, fort, units', + expect.eq(' tags: armok, fort, units', mock_print.call_args[2][1]) expect.eq('boxbinders Box your binders.', mock_print.call_args[3][1]) - expect.eq(' tags: armok, fort, units', + expect.eq(' tags: armok, fort, units', mock_print.call_args[4][1]) expect.eq('samename Samename.', mock_print.call_args[5][1]) - expect.eq(' tags: armok, fort, units', + expect.eq(' tags: armok, fort, units', mock_print.call_args[6][1]) end) From 9817106c30ee63527c22e00833692c5b009dc7d0 Mon Sep 17 00:00:00 2001 From: myk002 Date: Wed, 5 Oct 2022 13:30:14 -0700 Subject: [PATCH 60/73] add --exclude option for ls --- docs/Lua API.rst | 11 ++++-- docs/builtins/ls.rst | 2 ++ docs/changelog.txt | 1 + library/Core.cpp | 13 +++++-- library/lua/helpdb.lua | 60 ++++++++++++++++++++++++------- test/library/helpdb.lua | 78 ++++++++++++++++++++++++++++++++++------- 6 files changed, 136 insertions(+), 29 deletions(-) diff --git a/docs/Lua API.rst b/docs/Lua API.rst index 4aa8d78cb..d8a76dd28 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -3150,8 +3150,8 @@ Each entry has several properties associated with it: alphabetized by their last path component, with populated path components coming before null path components (e.g. ``autobutcher`` will immediately follow ``gui/autobutcher``). - The optional ``include`` and ``exclude`` filter params are maps with the - following elements: + The optional ``include`` and ``exclude`` filter params are maps (or lists of + maps) with the following elements: :str: if a string, filters by the given substring. if a table of strings, includes entry names that match any of the given substrings. @@ -3160,6 +3160,13 @@ Each entry has several properties associated with it: :entry_type: if a string, matches entries of the given type. if a table of strings, includes entries that match any of the given types. + Elements in a map are ANDed together (e.g. if both ``str`` and ``tag`` are + specified, the match is on any of the ``str`` elements AND any of the ``tag`` + elements). + + If lists of filters are passed instead of a single map, the maps are ORed + (that is, the match succeeds if any of the filters match). + If ``include`` is ``nil`` or empty, then all entries are included. If ``exclude`` is ``nil`` or empty, then no entries are filtered out. diff --git a/docs/builtins/ls.rst b/docs/builtins/ls.rst index 7305a0256..cd6bc4126 100644 --- a/docs/builtins/ls.rst +++ b/docs/builtins/ls.rst @@ -40,3 +40,5 @@ Options Don't print out the tags associated with each command. ``--dev`` Include commands intended for developers and modders. +``--exclude [,...]`` + Exclude commands that match any of the given strings. diff --git a/docs/changelog.txt b/docs/changelog.txt index d00f4c246..fb11def8e 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -39,6 +39,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## Misc Improvements - `ls`: indent tag listings and wrap them in the right column for better readability +- `ls`: new ``--exclude`` option for hiding matched scripts from the output. this can be especially useful for modders who don't want their mod scripts to be included in ``ls`` output. ## Documentation diff --git a/library/Core.cpp b/library/Core.cpp index 87f78f56c..73336b2e7 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -622,12 +622,18 @@ void ls_helper(color_ostream &con, const vector ¶ms) { vector filter; bool skip_tags = false; bool show_dev_commands = false; + string exclude_strs = ""; + bool in_exclude = false; for (auto str : params) { - if (str == "--notags") + if (in_exclude) + exclude_strs = str; + else if (str == "--notags") skip_tags = true; else if (str == "--dev") show_dev_commands = true; + else if (str == "--exclude") + in_exclude = true; else filter.push_back(str); } @@ -636,7 +642,7 @@ void ls_helper(color_ostream &con, const vector ¶ms) { auto L = Lua::Core::State; Lua::StackUnwinder top(L); - if (!lua_checkstack(L, 4) || + if (!lua_checkstack(L, 5) || !Lua::PushModulePublic(con, L, "helpdb", "ls")) { con.printerr("Failed to load helpdb Lua code\n"); return; @@ -645,8 +651,9 @@ void ls_helper(color_ostream &con, const vector ¶ms) { Lua::PushVector(L, filter); Lua::Push(L, skip_tags); Lua::Push(L, show_dev_commands); + Lua::Push(L, exclude_strs); - if (!Lua::SafeCall(con, L, 3, 0)) { + if (!Lua::SafeCall(con, L, 4, 0)) { con.printerr("Failed Lua call to helpdb.ls.\n"); } } diff --git a/library/lua/helpdb.lua b/library/lua/helpdb.lua index d07445399..5af41c929 100644 --- a/library/lua/helpdb.lua +++ b/library/lua/helpdb.lua @@ -14,6 +14,8 @@ local _ENV = mkmodule('helpdb') +local argparse = require('argparse') + local MAX_STALE_MS = 60000 -- paths @@ -588,6 +590,8 @@ function sort_by_basename(a, b) return false end +-- returns true if all filter elements are matched (i.e. any of the tags AND +-- any of the strings AND any of the entry_types) local function matches(entry_name, filter) if filter.tag then local matched = false @@ -630,9 +634,18 @@ local function matches(entry_name, filter) return true end +local function matches_any(entry_name, filters) + for _,filter in ipairs(filters) do + if matches(entry_name, filter) then + return true + end + end + return false +end + -- normalizes the lists in the filter and returns nil if no filter elements are -- populated -local function normalize_filter(f) +local function normalize_filter_map(f) if not f then return nil end local filter = {} filter.str = normalize_string_list(f.str) @@ -644,11 +657,21 @@ local function normalize_filter(f) return filter end +local function normalize_filter_list(fs) + if not fs then return nil end + local filter_list = {} + for _,f in ipairs(#fs > 0 and fs or {fs}) do + table.insert(filter_list, normalize_filter_map(f)) + end + if #filter_list == 0 then return nil end + return filter_list +end + -- returns a list of entry names, alphabetized by their last path component, -- with populated path components coming before null path components (e.g. -- autobutcher will immediately follow gui/autobutcher). --- the optional include and exclude filter params are maps with the following --- elements: +-- the optional include and exclude filter params are maps (or lists of maps) +-- with the following elements: -- str - if a string, filters by the given substring. if a table of strings, -- includes entry names that match any of the given substrings. -- tag - if a string, filters by the given tag name. if a table of strings, @@ -658,14 +681,18 @@ end -- types are: "builtin", "plugin", "command". note that many plugin -- commands have the same name as the plugin, so those entries will -- match both "plugin" and "command" types. +-- filter elements in a map are ANDed together (e.g. if both str and tag are +-- specified, the match is on any of the str elements AND any of the tag +-- elements). If lists of maps are passed, the maps are ORed (that is, the match +-- succeeds if any of the filters match). function search_entries(include, exclude) ensure_db() - include = normalize_filter(include) - exclude = normalize_filter(exclude) + include = normalize_filter_list(include) + exclude = normalize_filter_list(exclude) local entries = {} for entry in pairs(entrydb) do - if (not include or matches(entry, include)) and - (not exclude or not matches(entry, exclude)) then + if (not include or matches_any(entry, include)) and + (not exclude or not matches_any(entry, exclude)) then table.insert(entries, entry) end end @@ -743,21 +770,30 @@ end -- wraps the list_entries() API to provide a more convenient interface for Core -- to implement the 'ls' builtin command. --- filter_str - if a tag name, will filter by that tag. otherwise, will filter --- as a substring +-- filter_str - if a tag name (or a list of tag names), will filter by that +-- tag/those tags. otherwise, will filter as a substring/list of +-- substrings -- skip_tags - whether to skip printing tag info -- show_dev_commands - if true, will include scripts in the modtools/ and -- devel/ directories. otherwise those scripts will be -- excluded -function ls(filter_str, skip_tags, show_dev_commands) +-- exclude_strs - comma-separated list of strings. entries are excluded if +-- they match any of the strings. +function ls(filter_str, skip_tags, show_dev_commands, exclude_strs) local include = {entry_type={ENTRY_TYPES.COMMAND}} if is_tag(filter_str) then include.tag = filter_str else include.str = filter_str end - list_entries(skip_tags, include, - show_dev_commands and {} or {tag='dev'}) + local excludes = {} + if exclude_strs and #exclude_strs > 0 then + table.insert(excludes, {str=argparse.stringList(exclude_strs)}) + end + if not show_dev_commands then + table.insert(excludes, {tag='dev'}) + end + list_entries(skip_tags, include, excludes) end local function list_tags() diff --git a/test/library/helpdb.lua b/test/library/helpdb.lua index efa9e93d5..1f1e58ba9 100644 --- a/test/library/helpdb.lua +++ b/test/library/helpdb.lua @@ -36,6 +36,7 @@ local mock_script_db = { inscript_docs=true, inscript_short_only=true, nodocs_script=true, + dev_script=true, } local files = { @@ -48,6 +49,8 @@ local files = { * units: Tools that interact with units. +* dev: Dev tools. + * nomembers: Nothing is tagged with this. ]], ['hack/docs/docs/tools/hascommands.txt']=[[ @@ -113,6 +116,20 @@ Command: "subdir/scriptname" Documented subdir/scriptname. Documented full help. + ]], + ['hack/docs/docs/tools/dev_script.txt']=[[ +dev_script +========== + +Tags: dev + +Command: "dev_script" + + Short desc. + +Full help. +]====] +script contents ]], ['scripts/scriptpath/basic.lua']=[[ -- in-file short description for basic @@ -216,6 +233,9 @@ Command: "inscript_docs" Documented full help. ]====] +script contents + ]], + ['other/scriptpath/dev_script.lua']=[[ script contents ]], } @@ -495,7 +515,7 @@ function test.is_tag() end function test.get_tags() - expect.table_eq({'armok', 'fort', 'map', 'nomembers', 'units'}, + expect.table_eq({'armok', 'dev', 'fort', 'map', 'nomembers', 'units'}, h.get_tags()) end @@ -534,8 +554,8 @@ end function test.search_entries() -- all entries, in alphabetical order by last path component local expected = {'?', 'alias', 'basic', 'bindboxers', 'boxbinders', - 'clear', 'cls', 'die', 'dir', 'disable', 'devel/dump-rpc', 'enable', - 'fpause', 'hascommands', 'help', 'hide', 'inscript_docs', + 'clear', 'cls', 'dev_script', 'die', 'dir', 'disable', 'devel/dump-rpc', + 'enable', 'fpause', 'hascommands', 'help', 'hide', 'inscript_docs', 'inscript_short_only', 'keybinding', 'kill-lua', 'load', 'ls', 'man', 'nocommand', 'nodoc_command', 'nodocs_hascommands', 'nodocs_nocommand', 'nodocs_samename', 'nodocs_script', 'plug', 'reload', 'samename', @@ -555,19 +575,26 @@ function test.search_entries() expect.table_eq(expected, h.search_entries({str='script', entry_type='builtin'})) - expected = {'inscript_docs', 'inscript_short_only','nodocs_script', - 'subdir/scriptname'} + expected = {'dev_script', 'inscript_docs', 'inscript_short_only', + 'nodocs_script', 'subdir/scriptname'} expect.table_eq(expected, h.search_entries({str='script'}, {entry_type='builtin'})) expected = {'bindboxers', 'boxbinders'} expect.table_eq(expected, h.search_entries({str='box'})) + + expected = {'bindboxers', 'boxbinders', 'inscript_docs', + 'inscript_short_only', 'nodocs_script', 'subdir/scriptname'} + expect.table_eq(expected, h.search_entries({{str='script'}, {str='box'}}, + {{entry_type='builtin'}, + {tag='dev'}}), + 'multiple filters for include and exclude') end function test.get_commands() local expected = {'?', 'alias', 'basic', 'bindboxers', 'boxbinders', - 'clear', 'cls', 'die', 'dir', 'disable', 'devel/dump-rpc', 'enable', - 'fpause', 'help', 'hide', 'inscript_docs', 'inscript_short_only', + 'clear', 'cls', 'dev_script', 'die', 'dir', 'disable', 'devel/dump-rpc', + 'enable', 'fpause', 'help', 'hide', 'inscript_docs', 'inscript_short_only', 'keybinding', 'kill-lua', 'load', 'ls', 'man', 'nodoc_command', 'nodocs_samename', 'nodocs_script', 'plug', 'reload', 'samename', 'script', 'subdir/scriptname', 'sc-script', 'show', 'tags', 'type', @@ -598,21 +625,23 @@ function test.tags() local mock_print = mock.func() mock.patch(h, 'print', mock_print, function() h.tags() - expect.eq(7, mock_print.call_count) + expect.eq(8, mock_print.call_count) expect.eq('armok Tools that give you complete control over an aspect of the', mock_print.call_args[1][1]) expect.eq(' game or provide access to information that the game', mock_print.call_args[2][1]) expect.eq(' intentionally keeps hidden.', mock_print.call_args[3][1]) - expect.eq('fort Tools that are useful while in fort mode.', + expect.eq('dev Dev tools.', mock_print.call_args[4][1]) - expect.eq('map Tools that interact with the game map.', + expect.eq('fort Tools that are useful while in fort mode.', mock_print.call_args[5][1]) - expect.eq('nomembers Nothing is tagged with this.', + expect.eq('map Tools that interact with the game map.', mock_print.call_args[6][1]) - expect.eq('units Tools that interact with units.', + expect.eq('nomembers Nothing is tagged with this.', mock_print.call_args[7][1]) + expect.eq('units Tools that interact with units.', + mock_print.call_args[8][1]) end) end @@ -670,4 +699,29 @@ function test.ls() expect.eq(1, mock_print.call_count) expect.eq('No matches.', mock_print.call_args[1][1]) end) + + -- test skipping tags and excluding strings + mock_print = mock.func() + mock.patch(h, 'print', mock_print, function() + h.ls('armok', true, false, 'boxer,binder') + expect.eq(1, mock_print.call_count) + expect.eq('samename Samename.', mock_print.call_args[1][1]) + end) + + -- test excluding dev scripts + mock_print = mock.func() + mock.patch(h, 'print', mock_print, function() + h.ls('_script', true, false, 'inscript,nodocs') + expect.eq(1, mock_print.call_count) + expect.eq('No matches.', mock_print.call_args[1][1]) + end) + + -- test including dev scripts + mock_print = mock.func() + mock.patch(h, 'print', mock_print, function() + h.ls('_script', true, true, 'inscript,nodocs') + expect.eq(1, mock_print.call_count) + expect.eq('dev_script Short desc.', + mock_print.call_args[1][1]) + end) end From 33816b8bc215dcf7b11c9c6ea1cc98f9e80ce0e0 Mon Sep 17 00:00:00 2001 From: myk002 Date: Wed, 5 Oct 2022 14:01:09 -0700 Subject: [PATCH 61/73] optionally process only the cur z-level and below --- docs/changelog.txt | 1 + docs/plugins/dig.rst | 12 ++++++++---- plugins/dig.cpp | 31 ++++++++++++------------------- 3 files changed, 21 insertions(+), 23 deletions(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index fb11def8e..eba15cfb4 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -40,6 +40,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## Misc Improvements - `ls`: indent tag listings and wrap them in the right column for better readability - `ls`: new ``--exclude`` option for hiding matched scripts from the output. this can be especially useful for modders who don't want their mod scripts to be included in ``ls`` output. +- `digtype`: new ``-z`` option for digtype to restrict designations to the current z-level and down ## Documentation diff --git a/docs/plugins/dig.rst b/docs/plugins/dig.rst index 4384ade65..a10db97df 100644 --- a/docs/plugins/dig.rst +++ b/docs/plugins/dig.rst @@ -25,7 +25,7 @@ dig :summary: Designate circles. .. dfhack-command:: digtype - :summary: Designate all vein tiles of the selected type. + :summary: Designate all vein tiles of the same type as the selected tile. .. dfhack-command:: digexp :summary: Designate dig patterns for exploratory mining. @@ -50,9 +50,9 @@ Usage Designate circles. The diameter is the number of tiles across the center of the circle that you want to dig. See the `digcircle`_ section below for options. -``digtype [] [-p]`` - Designate all vein tiles of the selected type. See the `digtype`_ section - below for options. +``digtype [] [-p] [-z]`` + Designate all vein tiles of the same type as the selected tile. See the + `digtype`_ section below for options. ``digexp [] [] [-p]`` Designate dig patterns for exploratory mining. See the `digexp`_ section below for options. @@ -143,6 +143,10 @@ Designation options: ``clear`` Clear any designations. +You can also pass a ``-z`` option, which restricts designations to the current +z-level and down. This is useful when you don't want to designate tiles on the +same z-levels as your carefully dug fort above. + digexp ------ diff --git a/plugins/dig.cpp b/plugins/dig.cpp index ddc2cd97e..945bf3613 100644 --- a/plugins/dig.cpp +++ b/plugins/dig.cpp @@ -35,6 +35,7 @@ command_result digtype (color_ostream &out, vector & parameters); DFHACK_PLUGIN("dig"); REQUIRE_GLOBAL(ui_sidebar_menus); REQUIRE_GLOBAL(world); +REQUIRE_GLOBAL(window_z); DFhackCExport command_result plugin_init ( color_ostream &out, std::vector &commands) { @@ -1417,16 +1418,18 @@ command_result digtype (color_ostream &out, vector & parameters) //mostly copy-pasted from digv int32_t priority = parse_priority(out, parameters); CoreSuspender suspend; - if ( parameters.size() > 1 ) + + if (!Maps::IsValid()) { - out.printerr("Too many parameters.\n"); + out.printerr("Map is not available!\n"); return CR_FAILURE; } - int32_t targetDigType; - if ( parameters.size() == 1 ) - { - string parameter = parameters[0]; + uint32_t xMax,yMax,zMax; + Maps::getSize(xMax,yMax,zMax); + + int32_t targetDigType = -1; + for (string parameter : parameters) { if ( parameter == "clear" ) targetDigType = tile_dig_designation::No; else if ( parameter == "dig" ) @@ -1441,26 +1444,16 @@ command_result digtype (color_ostream &out, vector & parameters) targetDigType = tile_dig_designation::DownStair; else if ( parameter == "up" ) targetDigType = tile_dig_designation::UpStair; + else if ( parameter == "-z" ) + zMax = *window_z + 1; else { - out.printerr("Invalid parameter.\n"); + out.printerr("Invalid parameter: '%s'.\n", parameter.c_str()); return CR_FAILURE; } } - else - { - targetDigType = -1; - } - - if (!Maps::IsValid()) - { - out.printerr("Map is not available!\n"); - return CR_FAILURE; - } int32_t cx, cy, cz; - uint32_t xMax,yMax,zMax; - Maps::getSize(xMax,yMax,zMax); uint32_t tileXMax = xMax * 16; uint32_t tileYMax = yMax * 16; Gui::getCursorCoords(cx,cy,cz); From 24232e894a17e6b6d293ec8413d37929d266a311 Mon Sep 17 00:00:00 2001 From: myk002 Date: Thu, 6 Oct 2022 11:13:16 -0700 Subject: [PATCH 62/73] create Scrollbar widget and integrate with List --- docs/Lua API.rst | 41 ++++++++--- docs/changelog.txt | 2 + library/lua/gui/widgets.lua | 138 +++++++++++++++++++++++++++++++++--- 3 files changed, 165 insertions(+), 16 deletions(-) diff --git a/docs/Lua API.rst b/docs/Lua API.rst index d8a76dd28..b9c09c673 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -4032,6 +4032,38 @@ following keyboard hotkeys: - Ctrl-Left/Right arrow: move the cursor one word to the left or right. - Alt-Left/Right arrow: move the cursor to the beginning/end of the text. +Scrollbar class +--------------- + +This Widget subclass implements mouse-interactive scrollbars whose bar sizes +represent the amount of content currently visible in an associated display +widget (like a `Label class`_ or a `List class`_). By default they are styled +like scrollbars used in the vanilla DF help screens, but they are configurable. + +Scrollbars have the following attributes: + +:fg: Specifies the pen for the scroll icons and the active part of the bar. Default is ``COLOR_LIGHTGREEN``. +:bg: Specifies the pen for the background part of the scrollbar. Default is ``COLOR_CYAN``. +:on_scroll: A callback called when the scrollbar is scrolled. It will be called with a single string parameter with a value of "up_large", "down_large", "up_small", or "down_small". + +The Scrollbar widget implements the following methods: + +* ``scrollbar:update(top_elem, elems_per_page, num_elems)`` + + Updates the info about the widget that the scrollbar is paired with. + The ``top_elem`` param is the (one-based) index of the first visible element. + The ``elems_per_page`` param is the maximum number of elements that can be + shown at one time. The ``num_elems`` param is the total number of elements + that the paried widget can scroll through. The scrollbar will adjust its + scrollbar size and position accordingly. + +Clicking on the arrows at the top or the bottom of a scrollbar will scroll an +associated widget by a small amount. Clicking on the unfilled portion of the +scrollbar above or below the filled area will scroll by a larger amount in that +direction. The amount of scrolling done in each case in determined by the +associated widget, and after scrolling is complete, the associated widget must +call ``scrollbar:update()`` with updated new display info. + Label class ----------- @@ -4056,13 +4088,7 @@ It has the following attributes: icons next to the text in an additional column (``frame_inset`` is adjusted to have ``.r`` or ``.l`` greater than ``0``), ``nil`` same as ``'right'`` but changes ``frame_inset`` only if a scroll icon is actually necessary (if ``getTextHeight()`` is greater than ``frame_body.height``). Default is ``nil``. -:scrollbar_fg: Specifies the pen for the scroll icons and the active part of the bar. Default is ``COLOR_LIGHTGREEN`` (the same as the native DF help screens). -:scrollbar_bg: Specifies the pen for the background part of the scrollbar. Default is ``COLOR_CYAN`` (the same as the native DF help screens). - -If the scrollbar is shown, it will react to mouse clicks on the scrollbar itself. -Clicking on the arrows at the top or the bottom will scroll by one line, and -clicking on the unfilled portion of the scrollbar will scroll by a half page in -that direction. +:scrollbar: The table of attributes to pass to the `Scrollbar class`_. The text itself is represented as a complex structure, and passed to the object via the ``text`` argument of the constructor, or via @@ -4283,7 +4309,6 @@ Every list item may be specified either as a string, or as a lua table with the following fields: :text: Specifies the label text in the same format as the Label text. -:caption, [1]: Deprecated legacy aliases for **text**. :text_*: Reserved for internal use. :key: Specifies a keybinding that acts as a shortcut for the specified item. :icon: Specifies an icon string, or a pen to paint a single character. May be a callback. diff --git a/docs/changelog.txt b/docs/changelog.txt index eba15cfb4..b1d5300a9 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -41,12 +41,14 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - `ls`: indent tag listings and wrap them in the right column for better readability - `ls`: new ``--exclude`` option for hiding matched scripts from the output. this can be especially useful for modders who don't want their mod scripts to be included in ``ls`` output. - `digtype`: new ``-z`` option for digtype to restrict designations to the current z-level and down +- UX: List widgets now have mouse-interactive scrollbars ## Documentation ## API ## Lua +- ``widgets.Scrollbar``: new scrollbar widget that can be paired with an associated scrollable widget. Integrated with ``widgets.Label`` and ``widgets.List``. # 0.47.05-r7 diff --git a/library/lua/gui/widgets.lua b/library/lua/gui/widgets.lua index 7076570b9..20aff7aa4 100644 --- a/library/lua/gui/widgets.lua +++ b/library/lua/gui/widgets.lua @@ -359,6 +359,96 @@ function EditField:onInput(keys) return self.modal end +--------------- +-- Scrollbar -- +--------------- + +Scrollbar = defclass(Scrollbar, Widget) + +Scrollbar.ATTRS{ + fg = COLOR_LIGHTGREEN, + bg = COLOR_CYAN, + on_scroll = DEFAULT_NIL, +} + +function Scrollbar:preinit(init_table) + init_table.frame = init_table.frame or {} + init_table.frame.w = init_table.frame.w or 1 +end + +function Scrollbar:init() + self:update(1, 1, 1) +end + +-- calculate and cache the number of tiles of empty space above the top of the +-- scrollbar and the number of tiles the scrollbar should occupy to represent +-- the percentage of text that is on the screen. +-- if elems_per_page or num_elems are not specified, the last values passed to +-- Scrollbar:update() are used. +function Scrollbar:update(top_elem, elems_per_page, num_elems) + if not top_elem then error('must specify index of new top element') end + elems_per_page = elems_per_page or self.elems_per_page + num_elems = num_elems or self.num_elems + + local frame_height = self.frame_body and self.frame_body.height or 3 + local scrollbar_body_height = frame_height - 2 + local height = math.max(1, math.floor( + (math.min(elems_per_page, num_elems) * scrollbar_body_height) / + num_elems)) + + local max_pos = scrollbar_body_height - height + local pos = math.ceil(((top_elem-1) * max_pos) / + (num_elems - elems_per_page)) + + self.top_elem = top_elem + self.elems_per_page, self.num_elems = elems_per_page, num_elems + self.bar_offset, self.bar_height = pos, height +end + +local UP_ARROW_CHAR = string.char(24) +local DOWN_ARROW_CHAR = string.char(25) +local NO_ARROW_CHAR = string.char(32) +local BAR_CHAR = string.char(7) +local BAR_BG_CHAR = string.char(179) + +function Scrollbar:onRenderBody(dc) + -- don't draw if all elements are visible + if self.elems_per_page >= self.num_elems then return end + -- render up arrow if we're not at the top + dc:seek(0, 0):char( + self.top_elem == 1 and NO_ARROW_CHAR or UP_ARROW_CHAR, self.fg, self.bg) + -- render scrollbar body + local starty = self.bar_offset + 1 + local endy = self.bar_offset + self.bar_height + for y=1,dc.height-2 do + dc:seek(0, y) + if y >= starty and y <= endy then + dc:char(BAR_CHAR, self.fg) + else + dc:char(BAR_BG_CHAR, self.bg) + end + end + -- render down arrow if we're not at the bottom + local last_visible_el = self.top_elem + self.elems_per_page - 1 + dc:seek(0, dc.height-1):char( + last_visible_el >= self.num_elems and NO_ARROW_CHAR or DOWN_ARROW_CHAR, + self.fg, self.bg) +end + +function Scrollbar:onInput(keys) + if not keys._MOUSE_L_DOWN or not self.on_scroll then return false end + local _,y = self:getMousePos() + if not y then return false end + local scroll = nil + if y == 0 then scroll = 'up_small' + elseif y == self.frame_body.height - 1 then scroll = 'down_small' + elseif y <= self.bar_offset then scroll = 'up_large' + elseif y > self.bar_offset + self.bar_height then scroll = 'down_large' + end + if scroll then self.on_scroll(scroll) end + return true +end + ----------- -- Label -- ----------- @@ -610,12 +700,6 @@ local function get_scrollbar_pos_and_height(label) return pos, height end -local UP_ARROW_CHAR = string.char(24) -local DOWN_ARROW_CHAR = string.char(25) -local NO_ARROW_CHAR = string.char(32) -local BAR_CHAR = string.char(7) -local BAR_BG_CHAR = string.char(179) - function Label:render_scrollbar(dc, x, y1, y2) -- render up arrow if we're not at the top dc:seek(x, y1):char( @@ -953,6 +1037,11 @@ List.ATTRS{ function List:init(info) self.page_top = 1 self.page_size = 1 + self.scrollbar = Scrollbar{ + frame={r=0}, + on_scroll=self:callback('on_scrollbar')} + + self:addviews{self.scrollbar} if info.choices then self:setChoices(info.choices, info.selected) @@ -1017,13 +1106,17 @@ function List:postComputeFrame(body) self:moveCursor(0) end +local function update_list_scrollbar(list) + self.scrollbar:update(list.page_top, list.page_size, #list.choices) +end + function List:moveCursor(delta, force_cb) - local page = math.max(1, self.page_size) local cnt = #self.choices if cnt < 1 then self.page_top = 1 self.selected = 1 + update_list_scrollbar(self) if force_cb and self.on_select then self.on_select(nil,nil) end @@ -1046,14 +1139,40 @@ function List:moveCursor(delta, force_cb) end end + local buffer = 1 + math.min(4, math.floor(self.page_size/10)) + self.selected = 1 + off % cnt - self.page_top = 1 + page * math.floor((self.selected-1) / page) + if (self.selected - buffer) < self.page_top then + self.page_top = math.max(1, self.selected - buffer) + elseif (self.selected + buffer + 1) > (self.page_top + self.page_size) then + local max_page_top = cnt - self.page_size + 1 + self.page_top = math.max(1, + math.min(max_page_top, self.selected - self.page_size + buffer + 1)) + end + update_list_scrollbar(self) if (force_cb or delta ~= 0) and self.on_select then self.on_select(self:getSelected()) end end +function List:on_scrollbar(scroll_spec) + local v = 0 + if scroll_spec == 'down_large' then + v = math.floor(self.page_size / 2) + elseif scroll_spec == 'up_large' then + v = -math.floor(self.page_size / 2) + elseif scroll_spec == 'down_small' then + v = 1 + elseif scroll_spec == 'up_small' then + v = -1 + end + + local max_page_top = math.max(1, #self.choices - self.page_size + 1) + self.page_top = math.max(1, math.min(max_page_top, self.page_top + v)) + update_list_scrollbar(self) +end + function List:onRenderBody(dc) local choices = self.choices local top = self.page_top @@ -1122,6 +1241,9 @@ function List:submit2() end function List:onInput(keys) + if self:inputToSubviews(keys) then + return true + end if self.on_submit and keys.SELECT then self:submit() return true From 5722d6914b2ee080890ce44b095806d11b7223d8 Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 7 Oct 2022 12:45:43 -0700 Subject: [PATCH 63/73] transition Label to use the new generic Scrollbar --- docs/Lua API.rst | 8 +- library/lua/gui/widgets.lua | 171 ++++++++--------------------- test/library/gui/widgets.Label.lua | 64 ----------- 3 files changed, 49 insertions(+), 194 deletions(-) diff --git a/docs/Lua API.rst b/docs/Lua API.rst index b9c09c673..ddb00c61a 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -4084,11 +4084,6 @@ It has the following attributes: keys to the number of lines to scroll as positive or negative integers or one of the keywords supported by the ``scroll`` method. The default is up/down arrows scrolling by one line and page up/down scrolling by one page. -:show_scrollbar: Controls scrollbar display: ``false`` for no scrollbar, ``'right'`` or ``'left'`` for - icons next to the text in an additional column (``frame_inset`` is adjusted to have ``.r`` or ``.l`` greater than ``0``), - ``nil`` same as ``'right'`` but changes ``frame_inset`` only if a scroll icon is actually necessary - (if ``getTextHeight()`` is greater than ``frame_body.height``). Default is ``nil``. -:scrollbar: The table of attributes to pass to the `Scrollbar class`_. The text itself is represented as a complex structure, and passed to the object via the ``text`` argument of the constructor, or via @@ -4181,7 +4176,8 @@ The Label widget implements the following methods: This method takes the number of lines to scroll as positive or negative integers or one of the following keywords: ``+page``, ``-page``, - ``+halfpage``, or ``-halfpage``. + ``+halfpage``, or ``-halfpage``. It returns the number of lines that were + actually scrolled (negative for scrolling up). WrappedLabel class ------------------ diff --git a/library/lua/gui/widgets.lua b/library/lua/gui/widgets.lua index 20aff7aa4..3ac9d3c8b 100644 --- a/library/lua/gui/widgets.lua +++ b/library/lua/gui/widgets.lua @@ -636,12 +636,15 @@ Label.ATTRS{ on_click = DEFAULT_NIL, on_rclick = DEFAULT_NIL, scroll_keys = STANDARDSCROLL, - show_scrollbar = DEFAULT_NIL, -- DEFAULT_NIL, 'right', 'left', false - scrollbar_fg = COLOR_LIGHTGREEN, - scrollbar_bg = COLOR_CYAN } function Label:init(args) + self.scrollbar = Scrollbar{ + frame={r=0}, + on_scroll=self:callback('on_scrollbar')} + + self:addviews{self.scrollbar} + -- use existing saved text if no explicit text was specified. this avoids -- overwriting pre-formatted text that subclasses may have already set self:setText(args.text or self.text) @@ -650,6 +653,12 @@ function Label:init(args) end end +local function update_label_scrollbar(label) + local body_height = label.frame_body and label.frame_body.height or 1 + label.scrollbar:update(label.start_line_num, body_height, + label:getTextHeight()) +end + function Label:setText(text) self.start_line_num = 1 self.text = text @@ -659,81 +668,8 @@ function Label:setText(text) self.frame = self.frame or {} self.frame.h = self:getTextHeight() end -end -function Label:update_scroll_inset() - if self.show_scrollbar == nil then - self._show_scrollbar = self:getTextHeight() > self.frame_body.height and 'right' or false - else - self._show_scrollbar = self.show_scrollbar - end - if self._show_scrollbar then - -- here self._show_scrollbar can only be either - -- 'left' or any true value which we interpret as right - local l,t,r,b = gui.parse_inset(self.frame_inset) - if self._show_scrollbar == 'left' and l <= 0 then - l = 1 - elseif r <= 0 then - r = 1 - end - self.frame_inset = {l=l,t=t,r=r,b=b} - end -end - --- the position is the number of tiles of empty space above the top of the --- scrollbar, and the height is the number of tiles the scrollbar should occupy --- to represent the percentage of text that is on the screen. -local function get_scrollbar_pos_and_height(label) - local first_visible_line = label.start_line_num - local text_height = label:getTextHeight() - local last_visible_line = first_visible_line + label.frame_body.height - 1 - local scrollbar_body_height = label.frame_body.height - 2 - local displayed_lines = last_visible_line - first_visible_line - - local height = math.floor(((displayed_lines-1) * scrollbar_body_height) / - text_height) - - local max_pos = scrollbar_body_height - height - local pos = math.ceil(((first_visible_line-1) * max_pos) / - (text_height - label.frame_body.height)) - - return pos, height -end - -function Label:render_scrollbar(dc, x, y1, y2) - -- render up arrow if we're not at the top - dc:seek(x, y1):char( - self.start_line_num == 1 and NO_ARROW_CHAR or UP_ARROW_CHAR, - self.scrollbar_fg, self.scrollbar_bg) - -- render scrollbar body - local pos, height = get_scrollbar_pos_and_height(self) - local starty = y1 + pos + 1 - local endy = y1 + pos + height - for y=y1+1,y2-1 do - if y >= starty and y <= endy then - dc:seek(x, y):char(BAR_CHAR, self.scrollbar_fg) - else - dc:seek(x, y):char(BAR_BG_CHAR, self.scrollbar_bg) - end - end - -- render down arrow if we're not at the bottom - local last_visible_line = self.start_line_num + self.frame_body.height - 1 - dc:seek(x, y2):char( - last_visible_line >= self:getTextHeight() and - NO_ARROW_CHAR or DOWN_ARROW_CHAR, - self.scrollbar_fg, self.scrollbar_bg) -end - -function Label:computeFrame(parent_rect) - local frame_rect,body_rect = Label.super.computeFrame(self, parent_rect) - - self.frame_rect = frame_rect - self.frame_body = parent_rect:viewport(body_rect or frame_rect) - - self:update_scroll_inset() -- frame_body is now set - - -- recalc with updated frame_inset - return Label.super.computeFrame(self, parent_rect) + update_label_scrollbar(self) end function Label:preUpdateLayout() @@ -743,6 +679,10 @@ function Label:preUpdateLayout() end end +function Label:postUpdateLayout() + update_label_scrollbar(self) +end + function Label:itemById(id) if self.text_ids then return self.text_ids[id] @@ -766,44 +706,19 @@ function Label:onRenderBody(dc) render_text(self,dc,0,0,text_pen,self.text_dpen,is_disabled(self)) end -function Label:onRenderFrame(dc, rect) - if self._show_scrollbar then - local x = self._show_scrollbar == 'left' - and self.frame_body.x1-dc.x1-1 - or self.frame_body.x2-dc.x1+1 - self:render_scrollbar(dc, - x, - self.frame_body.y1-dc.y1, - self.frame_body.y2-dc.y1 - ) - end -end - -function Label:click_scrollbar() - if not self._show_scrollbar then return end - local rect = self.frame_body - local x, y = dscreen.getMousePos() - - if self._show_scrollbar == 'left' and x ~= rect.x1-1 or x ~= rect.x2+1 then - return - end - if y < rect.y1 or y > rect.y2 then - return +function Label:on_scrollbar(scroll_spec) + local v = 0 + if scroll_spec == 'down_large' then + v = '+halfpage' + elseif scroll_spec == 'up_large' then + v = '-halfpage' + elseif scroll_spec == 'down_small' then + v = 1 + elseif scroll_spec == 'up_small' then + v = -1 end - if y == rect.y1 then - return -1 - elseif y == rect.y2 then - return 1 - else - local pos, height = get_scrollbar_pos_and_height(self) - if y <= rect.y1 + pos then - return '-halfpage' - elseif y > rect.y1 + pos + height then - return '+halfpage' - end - end - return nil + self:scroll(v) end function Label:scroll(nlines) @@ -824,24 +739,28 @@ function Label:scroll(nlines) local n = self.start_line_num + nlines n = math.min(n, self:getTextHeight() - self.frame_body.height + 1) n = math.max(n, 1) + nlines = n - self.start_line_num self.start_line_num = n + update_label_scrollbar(self) return nlines end function Label:onInput(keys) if is_disabled(self) then return false end - if keys._MOUSE_L_DOWN then - if not self:scroll(self:click_scrollbar()) and - self:getMousePos() and self.on_click then - self:on_click() - end + if self:inputToSubviews(keys) then + return true + end + if keys._MOUSE_L_DOWN and self:getMousePos() and self.on_click then + self:on_click() + return true end if keys._MOUSE_R_DOWN and self:getMousePos() and self.on_rclick then self:on_rclick() + return true end for k,v in pairs(self.scroll_keys) do - if keys[k] then - self:scroll(v) + if keys[k] and 0 ~= self:scroll(v) then + return true end end return check_text_keys(self, keys) @@ -871,7 +790,7 @@ end -- we can't set the text in init() since we may not yet have a frame that we -- can get wrapping bounds from. function WrappedLabel:postComputeFrame() - local wrapped_text = self:getWrappedText(self.frame_body.width) + local wrapped_text = self:getWrappedText(self.frame_body.width-1) if not wrapped_text then return end local text = {} for _,line in ipairs(wrapped_text:split(NEWLINE)) do @@ -1107,7 +1026,11 @@ function List:postComputeFrame(body) end local function update_list_scrollbar(list) - self.scrollbar:update(list.page_top, list.page_size, #list.choices) + list.scrollbar:update(list.page_top, list.page_size, #list.choices) +end + +function List:postUpdateLayout() + update_list_scrollbar(self) end function List:moveCursor(delta, force_cb) @@ -1159,9 +1082,9 @@ end function List:on_scrollbar(scroll_spec) local v = 0 if scroll_spec == 'down_large' then - v = math.floor(self.page_size / 2) + v = math.ceil(self.page_size / 2) elseif scroll_spec == 'up_large' then - v = -math.floor(self.page_size / 2) + v = -math.ceil(self.page_size / 2) elseif scroll_spec == 'down_small' then v = 1 elseif scroll_spec == 'up_small' then diff --git a/test/library/gui/widgets.Label.lua b/test/library/gui/widgets.Label.lua index c43b5e886..4693d3d0d 100644 --- a/test/library/gui/widgets.Label.lua +++ b/test/library/gui/widgets.Label.lua @@ -11,70 +11,6 @@ fs.ATTRS = { focus_path = 'test-framed-screen', } -function test.correct_frame_body_with_scroll_icons() - local t = {} - for i = 1, 12 do - t[#t+1] = tostring(i) - t[#t+1] = NEWLINE - end - - function fs:init() - self:addviews{ - widgets.Label{ - view_id = 'text', - frame_inset = 0, - text = t, - }, - } - end - - local o = fs{} - expect.eq(o.subviews.text.frame_body.width, 9, "Label's frame_body.x2 and .width should be one smaller because of show_scrollbar.") -end - -function test.correct_frame_body_with_few_text_lines() - local t = {} - for i = 1, 10 do - t[#t+1] = tostring(i) - t[#t+1] = NEWLINE - end - - function fs:init() - self:addviews{ - widgets.Label{ - view_id = 'text', - frame_inset = 0, - text = t, - }, - } - end - - local o = fs{} - expect.eq(o.subviews.text.frame_body.width, 10, "Label's frame_body.x2 and .width should not change with show_scrollbar = false.") -end - -function test.correct_frame_body_without_show_scrollbar() - local t = {} - for i = 1, 12 do - t[#t+1] = tostring(i) - t[#t+1] = NEWLINE - end - - function fs:init() - self:addviews{ - widgets.Label{ - view_id = 'text', - frame_inset = 0, - text = t, - show_scrollbar = false, - }, - } - end - - local o = fs{} - expect.eq(o.subviews.text.frame_body.width, 10, "Label's frame_body.x2 and .width should not change with show_scrollbar = false.") -end - function test.scroll() local t = {} for i = 1, 12 do From 2bff70a2905c211133e2150885f43aed47ffbc78 Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 7 Oct 2022 13:14:52 -0700 Subject: [PATCH 64/73] add unit tests for widgets.Scrollbar --- library/lua/gui/widgets.lua | 5 +- test/library/gui/widgets.Scrollbar.lua | 93 ++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 test/library/gui/widgets.Scrollbar.lua diff --git a/library/lua/gui/widgets.lua b/library/lua/gui/widgets.lua index 3ac9d3c8b..2eaf80577 100644 --- a/library/lua/gui/widgets.lua +++ b/library/lua/gui/widgets.lua @@ -397,8 +397,9 @@ function Scrollbar:update(top_elem, elems_per_page, num_elems) num_elems)) local max_pos = scrollbar_body_height - height - local pos = math.ceil(((top_elem-1) * max_pos) / - (num_elems - elems_per_page)) + local pos = (num_elems == elems_per_page) and 0 or + math.ceil(((top_elem-1) * max_pos) / + (num_elems - elems_per_page)) self.top_elem = top_elem self.elems_per_page, self.num_elems = elems_per_page, num_elems diff --git a/test/library/gui/widgets.Scrollbar.lua b/test/library/gui/widgets.Scrollbar.lua new file mode 100644 index 000000000..dbe033ba4 --- /dev/null +++ b/test/library/gui/widgets.Scrollbar.lua @@ -0,0 +1,93 @@ +local gui = require('gui') +local widgets = require('gui.widgets') + +function test.update() + local s = widgets.Scrollbar{} + s.frame_body = {height=100} -- give us some space to work with + + -- initial defaults + expect.eq(1, s.top_elem) + expect.eq(1, s.elems_per_page) + expect.eq(1, s.num_elems) + expect.eq(0, s.bar_offset) + expect.eq(1, s.bar_height) + + -- top_elem, elems_per_page, num_elems + s:update(1, 10, 0) + expect.eq(1, s.top_elem) + expect.eq(10, s.elems_per_page) + expect.eq(0, s.num_elems) + expect.eq(0, s.bar_offset) + expect.eq(1, s.bar_height) + + -- first 10 of 50 shown + s:update(1, 10, 50) + expect.eq(1, s.top_elem) + expect.eq(10, s.elems_per_page) + expect.eq(50, s.num_elems) + expect.eq(0, s.bar_offset) + expect.eq(19, s.bar_height) + + -- bottom 10 of 50 shown + s:update(41, 10, 50) + expect.eq(41, s.top_elem) + expect.eq(10, s.elems_per_page) + expect.eq(50, s.num_elems) + expect.eq(79, s.bar_offset) + expect.eq(19, s.bar_height) + + -- ~middle 10 of 50 shown + s:update(23, 10, 50) + expect.eq(23, s.top_elem) + expect.eq(10, s.elems_per_page) + expect.eq(50, s.num_elems) + expect.eq(44, s.bar_offset) + expect.eq(19, s.bar_height) +end + +function test.onInput() + local spec = nil + local mock_on_scroll = function(scroll_spec) spec = scroll_spec end + local s = widgets.Scrollbar{on_scroll=mock_on_scroll} + s.frame_body = {height=100} -- give us some space to work with + local y = nil + s.getMousePos = function() return 0, y end + + -- put scrollbar somewhere in the middle so we can click above and below it + s:update(23, 10, 50) + + expect.false_(s:onInput{}, 'no mouse down') + expect.false_(s:onInput{_MOUSE_L_DOWN=true}, 'no y coord') + + spec, y = nil, 0 + expect.true_(s:onInput{_MOUSE_L_DOWN=true}) + expect.eq('up_small', spec, 'on up arrow') + + spec, y = nil, 1 + expect.true_(s:onInput{_MOUSE_L_DOWN=true}) + expect.eq('up_large', spec, 'on body above bar') + + spec, y = nil, 44 + expect.true_(s:onInput{_MOUSE_L_DOWN=true}) + expect.eq('up_large', spec, 'on body just above bar') + + spec, y = nil, 45 + expect.true_(s:onInput{_MOUSE_L_DOWN=true}) + expect.nil_(spec, 'on top of bar') + + spec, y = nil, 63 + expect.true_(s:onInput{_MOUSE_L_DOWN=true}) + expect.nil_(spec, 'on bottom of bar') + + spec, y = nil, 64 + expect.true_(s:onInput{_MOUSE_L_DOWN=true}) + expect.eq('down_large', spec, 'on body just below bar') + + spec, y = nil, 98 + expect.true_(s:onInput{_MOUSE_L_DOWN=true}) + expect.eq('down_large', spec, 'on body below bar') + + spec, y = nil, 99 + expect.true_(s:onInput{_MOUSE_L_DOWN=true}) + expect.eq('down_small', spec, 'on down arrow') +end From 35eb4e08dd53133abc14fdb189bfc9dd8fa848b7 Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 7 Oct 2022 15:40:05 -0700 Subject: [PATCH 65/73] hold down the mouse button to continue scrolling --- docs/Lua API.rst | 12 +++++++++++ docs/changelog.txt | 1 + library/lua/gui/widgets.lua | 41 ++++++++++++++++++++++++++++++------- 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/docs/Lua API.rst b/docs/Lua API.rst index ddb00c61a..8960cb15c 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -4064,6 +4064,18 @@ direction. The amount of scrolling done in each case in determined by the associated widget, and after scrolling is complete, the associated widget must call ``scrollbar:update()`` with updated new display info. +You can hold down the mouse button to scroll multiple times, just like in a +normal browser scrollbar. The speed of scroll events when the mouse button is +held down is controlled by two global variables: + +:``SCROLL_INITIAL_DELAY_MS``: The delay before the second scroll event. +:``SCROLL_DELAY_MS``: The delay between further scroll events. + +The defaults are 300 and 20, respectively, but they can be overridden by the +user in their :file:`dfhack-config/init/dfhack.init` file, for example:: + + :lua require('gui.widgets').SCROLL_DELAY_MS = 100 + Label class ----------- diff --git a/docs/changelog.txt b/docs/changelog.txt index b1d5300a9..1669ea9dd 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -42,6 +42,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - `ls`: new ``--exclude`` option for hiding matched scripts from the output. this can be especially useful for modders who don't want their mod scripts to be included in ``ls`` output. - `digtype`: new ``-z`` option for digtype to restrict designations to the current z-level and down - UX: List widgets now have mouse-interactive scrollbars +- UX: You can now hold down the mouse button on a scrollbar to make it scroll multiple times. ## Documentation diff --git a/library/lua/gui/widgets.lua b/library/lua/gui/widgets.lua index 2eaf80577..e5b7e9bfd 100644 --- a/library/lua/gui/widgets.lua +++ b/library/lua/gui/widgets.lua @@ -363,6 +363,11 @@ end -- Scrollbar -- --------------- +-- these can be overridden by the user, e.g.: +-- require('gui.widgets').SCROLL_DELAY_MS = 100 +SCROLL_INITIAL_DELAY_MS = 300 +SCROLL_DELAY_MS = 20 + Scrollbar = defclass(Scrollbar, Widget) Scrollbar.ATTRS{ @@ -377,6 +382,9 @@ function Scrollbar:preinit(init_table) end function Scrollbar:init() + self.last_scroll_ms = 0 + self.is_first_click = false + self.scroll_spec = nil self:update(1, 1, 1) end @@ -434,19 +442,38 @@ function Scrollbar:onRenderBody(dc) dc:seek(0, dc.height-1):char( last_visible_el >= self.num_elems and NO_ARROW_CHAR or DOWN_ARROW_CHAR, self.fg, self.bg) + -- manage state for continuous scrolling + if self.last_scroll_ms == 0 or not self.on_scroll then return end + if df.global.enabler.mouse_lbut_down == 0 then + self.last_scroll_ms = 0 + self.scroll_spec = nil + return + end + local now = dfhack.getTickCount() + local delay = self.is_first_click and + SCROLL_INITIAL_DELAY_MS or SCROLL_DELAY_MS + if now - self.last_scroll_ms >= delay then + self.is_first_click = false + self.on_scroll(self.scroll_spec) + self.last_scroll_ms = now + end end function Scrollbar:onInput(keys) if not keys._MOUSE_L_DOWN or not self.on_scroll then return false end local _,y = self:getMousePos() if not y then return false end - local scroll = nil - if y == 0 then scroll = 'up_small' - elseif y == self.frame_body.height - 1 then scroll = 'down_small' - elseif y <= self.bar_offset then scroll = 'up_large' - elseif y > self.bar_offset + self.bar_height then scroll = 'down_large' - end - if scroll then self.on_scroll(scroll) end + local scroll_spec = nil + if y == 0 then scroll_spec = 'up_small' + elseif y == self.frame_body.height - 1 then scroll_spec = 'down_small' + elseif y <= self.bar_offset then scroll_spec = 'up_large' + elseif y > self.bar_offset + self.bar_height then scroll_spec = 'down_large' + end + self.scroll_spec = scroll_spec + if scroll_spec then self.on_scroll(scroll_spec) end + -- reset continuous scroll state + self.is_first_click = true + self.last_scroll_ms = dfhack.getTickCount() return true end From ba36e72b3328e3cb00aebe6590d96f66234896ec Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 7 Oct 2022 16:27:19 -0700 Subject: [PATCH 66/73] support click and drag for scrollbars --- docs/changelog.txt | 1 + library/lua/gui/widgets.lua | 31 ++++++++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index 1669ea9dd..f9b7accc5 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -43,6 +43,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - `digtype`: new ``-z`` option for digtype to restrict designations to the current z-level and down - UX: List widgets now have mouse-interactive scrollbars - UX: You can now hold down the mouse button on a scrollbar to make it scroll multiple times. +- UX: You can now drag the scrollbar to scroll to a specific spot ## Documentation diff --git a/library/lua/gui/widgets.lua b/library/lua/gui/widgets.lua index e5b7e9bfd..f63b708cf 100644 --- a/library/lua/gui/widgets.lua +++ b/library/lua/gui/widgets.lua @@ -385,6 +385,7 @@ function Scrollbar:init() self.last_scroll_ms = 0 self.is_first_click = false self.scroll_spec = nil + self.is_dragging = false -- index of the scrollbar tile that we're dragging self:update(1, 1, 1) end @@ -414,6 +415,22 @@ function Scrollbar:update(top_elem, elems_per_page, num_elems) self.bar_offset, self.bar_height = pos, height end +local function scrollbar_do_drag(scrollbar) + local x,y = dfhack.screen.getMousePos() + x,y = scrollbar.frame_body:localXY(x,y) + local bar_idx = y - scrollbar.bar_offset + local delta = bar_idx - scrollbar.is_dragging + if delta < -2 then + scrollbar.on_scroll('up_large') + elseif delta < 0 then + scrollbar.on_scroll('up_small') + elseif delta > 2 then + scrollbar.on_scroll('down_large') + elseif delta > 0 then + scrollbar.on_scroll('down_small') + end +end + local UP_ARROW_CHAR = string.char(24) local DOWN_ARROW_CHAR = string.char(25) local NO_ARROW_CHAR = string.char(32) @@ -442,13 +459,18 @@ function Scrollbar:onRenderBody(dc) dc:seek(0, dc.height-1):char( last_visible_el >= self.num_elems and NO_ARROW_CHAR or DOWN_ARROW_CHAR, self.fg, self.bg) - -- manage state for continuous scrolling - if self.last_scroll_ms == 0 or not self.on_scroll then return end + if not self.on_scroll then return end + -- manage state for dragging and continuous scrolling + if self.is_dragging then + scrollbar_do_drag(self) + end if df.global.enabler.mouse_lbut_down == 0 then self.last_scroll_ms = 0 + self.is_dragging = false self.scroll_spec = nil return end + if self.last_scroll_ms == 0 then return end local now = dfhack.getTickCount() local delay = self.is_first_click and SCROLL_INITIAL_DELAY_MS or SCROLL_DELAY_MS @@ -468,9 +490,12 @@ function Scrollbar:onInput(keys) elseif y == self.frame_body.height - 1 then scroll_spec = 'down_small' elseif y <= self.bar_offset then scroll_spec = 'up_large' elseif y > self.bar_offset + self.bar_height then scroll_spec = 'down_large' + else + self.is_dragging = y - self.bar_offset + return true end self.scroll_spec = scroll_spec - if scroll_spec then self.on_scroll(scroll_spec) end + self.on_scroll(scroll_spec) -- reset continuous scroll state self.is_first_click = true self.last_scroll_ms = dfhack.getTickCount() From 31efd4177f05f328c108c127acf74d0977227231 Mon Sep 17 00:00:00 2001 From: DFHack-Urist via GitHub Actions <63161697+DFHack-Urist@users.noreply.github.com> Date: Fri, 7 Oct 2022 23:33:28 +0000 Subject: [PATCH 67/73] Auto-update submodules scripts: master --- scripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts b/scripts index 41bfa9005..f38299b76 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 41bfa9005ec78094388518d40e7aaa43f7d35890 +Subproject commit f38299b764f3947a2ebf2bc112b82467bd47b19b From 9a0f9f210b2e2604c8fe7739350af1bbafd1d7c4 Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 7 Oct 2022 16:38:44 -0700 Subject: [PATCH 68/73] update docs for clicking and dragging scrollbars --- docs/Lua API.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/Lua API.rst b/docs/Lua API.rst index 8960cb15c..c2b84f0f0 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -4064,9 +4064,11 @@ direction. The amount of scrolling done in each case in determined by the associated widget, and after scrolling is complete, the associated widget must call ``scrollbar:update()`` with updated new display info. -You can hold down the mouse button to scroll multiple times, just like in a -normal browser scrollbar. The speed of scroll events when the mouse button is -held down is controlled by two global variables: +You can click and drag the scrollbar to scroll to a specific spot, or you can +click and hold on the end arrows or in the unfilled portion of the scrollbar to +scroll multiple times, just like in a normal browser scrollbar. The speed of +scroll events when the mouse button is held down is controlled by two global +variables: :``SCROLL_INITIAL_DELAY_MS``: The delay before the second scroll event. :``SCROLL_DELAY_MS``: The delay between further scroll events. From 0dad512b5a1fcd40d93539260602fb3caf309955 Mon Sep 17 00:00:00 2001 From: DFHack-Urist via GitHub Actions <63161697+DFHack-Urist@users.noreply.github.com> Date: Sat, 8 Oct 2022 07:22:44 +0000 Subject: [PATCH 69/73] Auto-update submodules scripts: master --- scripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts b/scripts index f38299b76..3c27569e6 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit f38299b764f3947a2ebf2bc112b82467bd47b19b +Subproject commit 3c27569e6834151abe4586dc0437d4efad3c7dcd From d650ba23777726899b56e2a4ebc29c790a56de5b Mon Sep 17 00:00:00 2001 From: myk002 Date: Mon, 10 Oct 2022 16:42:32 -0700 Subject: [PATCH 70/73] ensure scrollbar can never get ahead of the cursor --- library/lua/gui/widgets.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/lua/gui/widgets.lua b/library/lua/gui/widgets.lua index f63b708cf..eb8d92244 100644 --- a/library/lua/gui/widgets.lua +++ b/library/lua/gui/widgets.lua @@ -420,11 +420,11 @@ local function scrollbar_do_drag(scrollbar) x,y = scrollbar.frame_body:localXY(x,y) local bar_idx = y - scrollbar.bar_offset local delta = bar_idx - scrollbar.is_dragging - if delta < -2 then + if delta < -scrollbar.bar_height then scrollbar.on_scroll('up_large') elseif delta < 0 then scrollbar.on_scroll('up_small') - elseif delta > 2 then + elseif delta > scrollbar.bar_height then scrollbar.on_scroll('down_large') elseif delta > 0 then scrollbar.on_scroll('down_small') From cc61d4a82aad31277c7ba663644357d8e88bdc69 Mon Sep 17 00:00:00 2001 From: myk002 Date: Mon, 10 Oct 2022 17:03:57 -0700 Subject: [PATCH 71/73] use rendered help instead of hard-coded --- plugins/blueprint.cpp | 37 ++++++++++++------------------------- plugins/lua/blueprint.lua | 31 ------------------------------- 2 files changed, 12 insertions(+), 56 deletions(-) diff --git a/plugins/blueprint.cpp b/plugins/blueprint.cpp index 3a0cb60b4..7919c4c5c 100644 --- a/plugins/blueprint.cpp +++ b/plugins/blueprint.cpp @@ -1187,23 +1187,11 @@ static bool get_options(color_ostream &out, return true; } -static void print_help(color_ostream &out) { - auto L = Lua::Core::State; - Lua::StackUnwinder top(L); - - if (!lua_checkstack(L, 1) || - !Lua::PushModulePublic(out, L, "plugins.blueprint", "print_help") || - !Lua::SafeCall(out, L, 0, 0)) - { - out.printerr("Failed to load blueprint Lua code\n"); - } -} - // returns whether blueprint generation was successful. populates files with the // names of the files that were generated -static bool do_blueprint(color_ostream &out, - const vector ¶meters, - vector &files) { +static command_result do_blueprint(color_ostream &out, + const vector ¶meters, + vector &files) { CoreSuspender suspend; if (parameters.size() >= 1 && parameters[0] == "gui") { @@ -1221,13 +1209,12 @@ static bool do_blueprint(color_ostream &out, blueprint_options options; if (!get_options(out, options, parameters) || options.help) { - print_help(out); - return options.help; + return CR_WRONG_USAGE; } if (!Maps::IsValid()) { out.printerr("Map is not available!\n"); - return false; + return CR_FAILURE; } // start coordinates can come from either the commandline or the map cursor @@ -1236,13 +1223,13 @@ static bool do_blueprint(color_ostream &out, if (!Gui::getCursorCoords(start)) { out.printerr("Can't get cursor coords! Make sure you specify the" " --cursor parameter or have an active cursor in DF.\n"); - return false; + return CR_FAILURE; } } if (!Maps::isValidTilePos(start)) { out.printerr("Invalid start position: %d,%d,%d\n", start.x, start.y, start.z); - return false; + return CR_FAILURE; } // end coords are one beyond the last processed coordinate. note that @@ -1265,7 +1252,7 @@ static bool do_blueprint(color_ostream &out, bool ok = do_transform(out, start, end, options, files); cache(NULL); - return ok; + return ok ? CR_OK : CR_FAILURE; } // entrypoint when called from Lua. returns the names of the generated files @@ -1284,7 +1271,7 @@ static int run(lua_State *L) { color_ostream *out = Lua::GetOutput(L); if (!out) out = &Core::getInstance().getConsole(); - if (do_blueprint(*out, argv, files)) { + if (CR_OK == do_blueprint(*out, argv, files)) { Lua::PushVector(L, files); return 1; } @@ -1294,13 +1281,13 @@ static int run(lua_State *L) { command_result blueprint(color_ostream &out, vector ¶meters) { vector files; - if (do_blueprint(out, parameters, files)) { + command_result cr = do_blueprint(out, parameters, files); + if (cr == CR_OK) { out.print("Generated blueprint file(s):\n"); for (string &fname : files) out.print(" %s\n", fname.c_str()); - return CR_OK; } - return CR_FAILURE; + return cr; } DFHACK_PLUGIN_LUA_COMMANDS { diff --git a/plugins/lua/blueprint.lua b/plugins/lua/blueprint.lua index 7b0076e14..4cc866650 100644 --- a/plugins/lua/blueprint.lua +++ b/plugins/lua/blueprint.lua @@ -3,37 +3,6 @@ local _ENV = mkmodule('plugins.blueprint') local argparse = require('argparse') local utils = require('utils') --- the info here is very basic and minimal, so hopefully we won't need to change --- it when features are added and the full blueprint docs in Plugins.rst are --- updated. -local help_text = [=[ - -blueprint -========= - -Records the structure of a portion of your fortress in quickfort blueprints. - -Usage: - - blueprint [] [ []] [] - blueprint gui [ []] [] - -Examples: - -blueprint gui - Runs gui/blueprint, the interactive blueprint frontend, where all - configuration can be set visually and interactively. - -blueprint 30 40 bedrooms - Generates blueprints for an area 30 tiles wide by 40 tiles tall, starting - from the active cursor on the current z-level. Output files are written to - the "blueprints" directory. - -See the online DFHack documentation for more examples and details. -]=] - -function print_help() print(help_text) end - local valid_phase_list = { 'dig', 'carve', From 8f024216b833301706685dc0954f0ad90ca7fc63 Mon Sep 17 00:00:00 2001 From: DFHack-Urist via GitHub Actions <63161697+DFHack-Urist@users.noreply.github.com> Date: Tue, 11 Oct 2022 07:40:53 +0000 Subject: [PATCH 72/73] Auto-update submodules scripts: master --- scripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts b/scripts index 3c27569e6..937cf27f9 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 3c27569e6834151abe4586dc0437d4efad3c7dcd +Subproject commit 937cf27f9b41301be6df0fe1d75d77b6f089f688 From 598f2c4b120d53b79dbd376b806120ede4bdf15d Mon Sep 17 00:00:00 2001 From: myk002 Date: Wed, 12 Oct 2022 10:10:53 -0700 Subject: [PATCH 73/73] support --smooth option for blueprints --- docs/plugins/blueprint.rst | 4 ++++ plugins/blueprint.cpp | 37 ++++++++++++++++++++++++++++++++++--- plugins/lua/blueprint.lua | 1 + test/plugins/blueprint.lua | 6 ++++++ 4 files changed, 45 insertions(+), 3 deletions(-) diff --git a/docs/plugins/blueprint.rst b/docs/plugins/blueprint.rst index 9d7d7ef8d..b999c0e99 100644 --- a/docs/plugins/blueprint.rst +++ b/docs/plugins/blueprint.rst @@ -103,6 +103,10 @@ Options to surround the parameter string in double quotes: ``"-s10,10,central stairs"`` or ``--playback-start "10,10,central stairs"`` or ``"--playback-start=10,10,central stairs"``. +``--smooth`` + Record all smooth tiles in the ``smooth`` phase. If this parameter is not + specified, only tiles that will later be carved into fortifications or + engraved will be smoothed. ``-t``, ``--splitby `` Split blueprints into multiple files. See the `Splitting output into multiple files`_ section below for details. If not specified, defaults to diff --git a/plugins/blueprint.cpp b/plugins/blueprint.cpp index 7919c4c5c..20aa1aa99 100644 --- a/plugins/blueprint.cpp +++ b/plugins/blueprint.cpp @@ -76,6 +76,8 @@ struct blueprint_options { // base name to use for generated files string name; + // whether to capture all smoothed tiles + bool smooth = false; // whether to capture engravings and smooth the tiles that will be engraved bool engrave = false; @@ -103,6 +105,7 @@ static const struct_field_info blueprint_options_fields[] = { { struct_field_info::PRIMITIVE, "height", offsetof(blueprint_options, height), &df::identity_traits::identity, 0, 0 }, { struct_field_info::PRIMITIVE, "depth", offsetof(blueprint_options, depth), &df::identity_traits::identity, 0, 0 }, { struct_field_info::PRIMITIVE, "name", offsetof(blueprint_options, name), df::identity_traits::get(), 0, 0 }, + { struct_field_info::PRIMITIVE, "smooth", offsetof(blueprint_options, smooth), &df::identity_traits::identity, 0, 0 }, { struct_field_info::PRIMITIVE, "engrave", offsetof(blueprint_options, engrave), &df::identity_traits::identity, 0, 0 }, { struct_field_info::PRIMITIVE, "auto_phase", offsetof(blueprint_options, auto_phase), &df::identity_traits::identity, 0, 0 }, { struct_field_info::PRIMITIVE, "dig", offsetof(blueprint_options, dig), &df::identity_traits::identity, 0, 0 }, @@ -219,8 +222,8 @@ static const char * get_tile_smooth_minimal(const df::coord &pos, return NULL; } -static const char * get_tile_smooth(const df::coord &pos, - const tile_context &tc) { +static const char * get_tile_smooth_with_engravings(const df::coord &pos, + const tile_context &tc) { const char * smooth_minimal = get_tile_smooth_minimal(pos, tc); if (smooth_minimal) return smooth_minimal; @@ -244,6 +247,30 @@ static const char * get_tile_smooth(const df::coord &pos, return NULL; } +static const char * get_tile_smooth_all(const df::coord &pos, + const tile_context &tc) { + const char * smooth_minimal = get_tile_smooth_minimal(pos, tc); + if (smooth_minimal) + return smooth_minimal; + + df::tiletype *tt = Maps::getTileType(pos); + if (!tt) + return NULL; + + switch (tileShape(*tt)) + { + case tiletype_shape::FLOOR: + case tiletype_shape::WALL: + if (tileSpecial(*tt) == tiletype_special::SMOOTH) + return "s"; + break; + default: + break; + } + + return NULL; +} + static const char * get_track_str(const char *prefix, df::tiletype tt) { TileDirection tdir = tileDirection(tt); @@ -1096,9 +1123,13 @@ static bool do_transform(color_ostream &out, vector processors; + get_tile_fn* smooth_get_tile_fn = get_tile_smooth_minimal; + if (opts.engrave) smooth_get_tile_fn = get_tile_smooth_with_engravings; + if (opts.smooth) smooth_get_tile_fn = get_tile_smooth_all; + add_processor(processors, opts, "dig", "dig", opts.dig, get_tile_dig); add_processor(processors, opts, "dig", "smooth", opts.carve, - opts.engrave ? get_tile_smooth : get_tile_smooth_minimal); + smooth_get_tile_fn); add_processor(processors, opts, "dig", "carve", opts.carve, opts.engrave ? get_tile_carve : get_tile_carve_minimal); add_processor(processors, opts, "build", "build", opts.build, diff --git a/plugins/lua/blueprint.lua b/plugins/lua/blueprint.lua index 4cc866650..5c73be7c0 100644 --- a/plugins/lua/blueprint.lua +++ b/plugins/lua/blueprint.lua @@ -123,6 +123,7 @@ local function process_args(opts, args) {'h', 'help', handler=function() opts.help = true end}, {'s', 'playback-start', hasArg=true, handler=function(optarg) parse_start(opts, optarg) end}, + {nil, 'smooth', handler=function() opts.smooth = true end}, {'t', 'splitby', hasArg=true, handler=function(optarg) parse_split_strategy(opts, optarg) end}, }) diff --git a/test/plugins/blueprint.lua b/test/plugins/blueprint.lua index 27a2634b4..a19d519b8 100644 --- a/test/plugins/blueprint.lua +++ b/test/plugins/blueprint.lua @@ -35,6 +35,12 @@ function test.parse_gui_commandline() name='blueprint', engrave=true,}, opts) + opts = {} + b.parse_gui_commandline(opts, {'--smooth'}) + expect.table_eq({auto_phase=true, format='minimal', split_strategy='none', + name='blueprint', smooth=true,}, + opts) + opts = {} b.parse_gui_commandline(opts, {'--engrave'}) expect.table_eq({auto_phase=true, format='minimal', split_strategy='none',