From 339d5ce26bf6604a602a41dccb34f247b54992fe Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Tue, 3 Nov 2020 19:09:58 -0800 Subject: [PATCH 1/8] set buildingplan global settings from prompt allow buildingplan settings to be set from the DFHack# prompt. For example, if a player knows they'll always want to build with blocks, they could add the following two lines to onMapLoad.init: buildingplan set boulders false buildingplan set logs false --- plugins/buildingplan.cpp | 65 +++++++++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 8 deletions(-) diff --git a/plugins/buildingplan.cpp b/plugins/buildingplan.cpp index 8d17d5dbc..b6bef39bf 100644 --- a/plugins/buildingplan.cpp +++ b/plugins/buildingplan.cpp @@ -911,26 +911,75 @@ IMPLEMENT_VMETHOD_INTERPOSE(buildingplan_query_hook, render); IMPLEMENT_VMETHOD_INTERPOSE(buildingplan_place_hook, render); IMPLEMENT_VMETHOD_INTERPOSE(buildingplan_room_hook, render); +DFHACK_PLUGIN_IS_ENABLED(is_enabled); + +static void setSetting(std::string name, bool value); + +static bool isTrue(std::string val) +{ + return val == "on" || val == "true" || val == "y" || val == "yes"; +} + static command_result buildingplan_cmd(color_ostream &out, vector & parameters) { - if (!parameters.empty()) + if (parameters.empty()) + return CR_OK; + + std::string cmd = toLower(parameters[0]); + + if (cmd.size() >= 1 && cmd[0] == 'v') + { + out << "buildingplan version: " << PLUGIN_VERSION << endl; + } + else if (parameters.size() >= 2 && cmd == "debug") { - if (parameters.size() == 1 && toLower(parameters[0])[0] == 'v') + show_debugging = isTrue(toLower(parameters[1])); + out << "buildingplan debugging: " << + ((show_debugging) ? "enabled" : "disabled") << endl; + } + else if (cmd == "set") + { + if (!is_enabled) { - out << "Building Plan" << endl << "Version: " << PLUGIN_VERSION << endl; + out << "ERROR: buildingplan must be enabled before you can read or " + << "set buildingplan global settings." << endl; + return CR_FAILURE; } - else if (parameters.size() == 2 && toLower(parameters[0]) == "debug") + + if (!DFHack::Core::getInstance().isMapLoaded()) + { + out << "ERROR: A map must be loaded before you can read or set " + << "buildingplan global settings. Try adding your " + << "'buildingplan set' commands to the onMapLoad.init file." + << endl; + return CR_FAILURE; + } + + if (parameters.size() == 1) + { + // display current settings + out << "active settings:" << endl; + for (auto & setting : planner.getGlobalSettings()) + { + out << " " << setting.first << " = " + << (setting.second ? "true" : "false") << endl; + } + + out << " quickfort_mode = " + << (quickfort_mode ? "true" : "false") << endl; + } + else if (parameters.size() == 3) { - show_debugging = (toLower(parameters[1]) == "on"); - out << "Debugging " << ((show_debugging) ? "enabled" : "disabled") << endl; + // set a setting + std::string setting = toLower(parameters[1]); + bool val = isTrue(toLower(parameters[2])); + setSetting(setting, val); } } return CR_OK; } -DFHACK_PLUGIN_IS_ENABLED(is_enabled); - DFhackCExport command_result plugin_enable(color_ostream &out, bool enable) { if (!gps) From 96b117d369b599c93014dd710b24a0b77a197b1f Mon Sep 17 00:00:00 2001 From: myk002 Date: Mon, 11 Jan 2021 14:37:57 -0800 Subject: [PATCH 2/8] update plugin docs and changelog --- docs/Plugins.rst | 46 +++++++++++++++++++++++++++++++++++++++++----- docs/changelog.txt | 3 +++ 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/docs/Plugins.rst b/docs/Plugins.rst index f8fcd569d..8adf91c05 100644 --- a/docs/Plugins.rst +++ b/docs/Plugins.rst @@ -723,11 +723,11 @@ While placing a building, you can set filters for what materials you want the bu out of, what quality you want the component items to be, and whether you want the items to be decorated. -If a building type takes more than one item to construct, use -:kbd:`Ctrl`:kbd:`Left` and :kbd:`Ctrl`:kbd:`Right` to select the item that you -want to set filters for. Any filters that you set will be used for all buildings -of the selected type from that point onward (until you set a new filter or clear -the current one). +If a building type takes more than one item to construct, use :kbd:`Ctrl`:kbd:`Left` and +:kbd:`Ctrl`:kbd:`Right` to select the item that you want to set filters for. Any filters that +you set will be used for all buildings of the selected type placed from that point onward +(until you set a new filter or clear the current one). Buildings placed before the filters +were changed will keep the filter values that were set when the building was placed. For example, you can be sure that all your constructed walls are the same color by setting a filter to accept only certain types of stone. @@ -745,6 +745,42 @@ Note that Quickfort mode is only for compatibility with the legacy Python Quickf DFHack `quickfort` script does not need Quickfort mode to be enabled. The `quickfort` script will successfully integrate with buildingplan as long as the buildingplan plugin is enabled. +Global settings +--------------- + +The buildingplan plugin has several global settings that can be set from the UI (:kbd:`G` +from any building placement screen, for example: :kbd:`b`:kbd:`a`:kbd:`G`). These settings +can also be set from the ``DFHack#`` prompt once a map is loaded (or from your +``onMapLoad.init`` file) with the syntax:: + + buildingplan set + +The available settings are: + ++----------------+---------+---------------------------------------+ +| Setting | Default | Description | ++================+=========+=======================================+ +| blocks | true | Allow blocks, boulders, logs, or bars | ++----------------+---------+ to be matched for generic "building | +| boulders | true | material" items | ++----------------+---------+ | +| logs | true | | ++----------------+---------+ | +| bars | false | | ++----------------+---------+---------------------------------------+ +| quickfort_mode | false | Enable compatibility mode for the | +| | | legacy Python Quickfort (not required | +| | | for DFHack quickfort) | ++----------------+---------+---------------------------------------+ + +For example, to ensure you only use blocks when a "building material" item is required, you +could add this to your ``onMapLoad.init`` file:: + + on-new-fortress buildingplan set boulders false; buildingplan set logs false + +You only need to set the settings for new fortresses since your current filter settings +are saved with your game. + .. _confirm: confirm diff --git a/docs/changelog.txt b/docs/changelog.txt index fdc7c13e7..1c5f45525 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -36,6 +36,9 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## Fixes - `embark-assistant`: fixed order of factors when calculating min temperature +## Misc Improvements +- `buildingplan`: set global settings from the ``DFHack#`` prompt: e.g. ``buildingplan set boulders false`` + # 0.47.04-r4 ## Fixes From b5b7319a23ecbddbec57e40804587e09eab9e898 Mon Sep 17 00:00:00 2001 From: myk002 Date: Mon, 11 Jan 2021 15:58:16 -0800 Subject: [PATCH 3/8] add documentation for #ignore blueprints --- docs/guides/quickfort-user-guide.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/guides/quickfort-user-guide.rst b/docs/guides/quickfort-user-guide.rst index 0deedc192..9819c8088 100644 --- a/docs/guides/quickfort-user-guide.rst +++ b/docs/guides/quickfort-user-guide.rst @@ -842,6 +842,8 @@ Blueprint mode Description meta Link sequences of blueprints together notes Display long messages, such as help text or blueprint walkthroughs +ignore Hide a section from quickfort, useful for scratch space or + personal notes ============== =========== .. _quickfort-meta: @@ -1000,6 +1002,14 @@ The quotes around the ``#meta`` modeline allow newlines in a single cell's text. Each line of the ``#notes`` "blueprint", however, is in a separate cell, allowing for much easier viewing and editing. +Ignore blueprints +````````````````` + +If you don't want some data to be visible to quickfort at all, use an +``#ignore`` blueprint. All lines until the next modeline in the file or sheet +will be completely ignored. This can be useful for personal notes, scratch +space, or temporarily "commented out" blueprints. + Buildingplan integration ------------------------ From c300cae2f9ba931e217f21cbc6b45d5b4a6dc5c2 Mon Sep 17 00:00:00 2001 From: bseiller Date: Mon, 18 Jan 2021 19:38:57 +0100 Subject: [PATCH 4/8] removing 2 dead stores to speed up survey::survey_mid_level_tile - survey.cpp: removing layer_bottom and layer_top, which are never read, but slow down survey_mid_level_tile significantly because entries are added quite often into the tree map structure - survey.h: removing now obsolete include for map --- plugins/embark-assistant/survey.cpp | 3 --- plugins/embark-assistant/survey.h | 1 - 2 files changed, 4 deletions(-) diff --git a/plugins/embark-assistant/survey.cpp b/plugins/embark-assistant/survey.cpp index e0deb5e58..7a7ab334a 100644 --- a/plugins/embark-assistant/survey.cpp +++ b/plugins/embark-assistant/survey.cpp @@ -996,7 +996,6 @@ void embark_assist::survey::survey_mid_level_tile(embark_assist::defs::geo_data base_z = elevation - 1; features = details->features[i][k]; - std::map layer_bottom, layer_top; mlt->at(i).at(k).adamantine_level = -1; mlt->at(i).at(k).magma_level = -1; @@ -1027,8 +1026,6 @@ void embark_assist::survey::survey_mid_level_tile(embark_assist::defs::geo_data feature->min_z != -30000) { auto layer = world_data->underground_regions[feature->layer]; - layer_bottom[layer->layer_depth] = feature->min_z; - layer_top[layer->layer_depth] = feature->max_z; base_z = std::min((int)base_z, (int)feature->min_z); if (layer->type == df::world_underground_region::MagmaSea) { diff --git a/plugins/embark-assistant/survey.h b/plugins/embark-assistant/survey.h index 14cc8a468..fa7fa7628 100644 --- a/plugins/embark-assistant/survey.h +++ b/plugins/embark-assistant/survey.h @@ -1,5 +1,4 @@ #pragma once -#include #include "DataDefs.h" #include "df/coord2d.h" From 4a7546c03a40a73953b9e1348a85f3bccefcb9e3 Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 21 Jan 2021 00:16:44 -0500 Subject: [PATCH 5/8] Update scripts --- scripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts b/scripts index 9d11d91e1..ebe6f5d59 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 9d11d91e1991bedc3108f97c0b79389c88206594 +Subproject commit ebe6f5d599bfafb614a791b637413e976c8870a5 From ed3c48e64b6cffdeefd91331dcf1e2ec48b69c5e Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 21 Jan 2021 23:55:01 -0500 Subject: [PATCH 6/8] Update changelog and authors (#1755) --- docs/Authors.rst | 1 + docs/changelog.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/Authors.rst b/docs/Authors.rst index 83ce58ef0..b9edfa3d5 100644 --- a/docs/Authors.rst +++ b/docs/Authors.rst @@ -24,6 +24,7 @@ Bearskie Bearskie belal jimhester Ben Lubar BenLubar Ben Rosser TC01 +Benjamin Seiller bseiller RedDwarfStepper billw2012 billw2012 BrickViking brickviking brndd brndd burneddi diff --git a/docs/changelog.txt b/docs/changelog.txt index fdc7c13e7..a11cee938 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -35,6 +35,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## Fixes - `embark-assistant`: fixed order of factors when calculating min temperature +- `embark-assistant`: improved performance of surveying # 0.47.04-r4 From ad39bb3c3348c432f7edc7c2de5cd023a9d0c452 Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 22 Jan 2021 12:48:36 -0800 Subject: [PATCH 7/8] address review comments --- docs/guides/quickfort-user-guide.rst | 8 ++-- plugins/buildingplan.cpp | 58 +++++++++++++++++----------- 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/docs/guides/quickfort-user-guide.rst b/docs/guides/quickfort-user-guide.rst index 0deedc192..66dc980aa 100644 --- a/docs/guides/quickfort-user-guide.rst +++ b/docs/guides/quickfort-user-guide.rst @@ -1010,9 +1010,11 @@ job but can't find the materials. As long as the `buildingplan` plugin is enabled, quickfort will use it to manage construction. The buildingplan plugin also has an "enabled" setting for each -building type, but that setting only applies to the buildingplan user interface; -quickfort will use buildingplan to manage everything designated in a ``#build`` -blueprint regardless of the buildingplan UI settings. +building type, but that setting only applies to the buildingplan user interface. +In addition, buildingplan has a "quickfort_mode" setting for compatibility with +legacy Python Quickfort. This setting has no effect on DFHack Quickfort, which +will use buildingplan to manage everything designated in a ``#build`` blueprint +regardless of the buildingplan UI settings. However, quickfort *does* use buildingplan's filters for each building type. For example, you can use the buildingplan UI to set the type of stone you want your diff --git a/plugins/buildingplan.cpp b/plugins/buildingplan.cpp index b6bef39bf..14c3a1918 100644 --- a/plugins/buildingplan.cpp +++ b/plugins/buildingplan.cpp @@ -17,7 +17,7 @@ #include "buildingplan-lib.h" DFHACK_PLUGIN("buildingplan"); -#define PLUGIN_VERSION 2.0 +#define PLUGIN_VERSION "2.0" REQUIRE_GLOBAL(ui); REQUIRE_GLOBAL(ui_build_selector); REQUIRE_GLOBAL(world); // used in buildingplan library @@ -913,11 +913,13 @@ IMPLEMENT_VMETHOD_INTERPOSE(buildingplan_room_hook, render); DFHACK_PLUGIN_IS_ENABLED(is_enabled); -static void setSetting(std::string name, bool value); +static bool setSetting(std::string name, bool value); static bool isTrue(std::string val) { - return val == "on" || val == "true" || val == "y" || val == "yes"; + val = toLower(val); + return val == "on" || val == "true" || val == "y" || val == "yes" + || val == "1"; } static command_result buildingplan_cmd(color_ostream &out, vector & parameters) @@ -929,51 +931,61 @@ static command_result buildingplan_cmd(color_ostream &out, vector & par if (cmd.size() >= 1 && cmd[0] == 'v') { - out << "buildingplan version: " << PLUGIN_VERSION << endl; + out.print("buildingplan version: %s\n", PLUGIN_VERSION); } else if (parameters.size() >= 2 && cmd == "debug") { - show_debugging = isTrue(toLower(parameters[1])); - out << "buildingplan debugging: " << - ((show_debugging) ? "enabled" : "disabled") << endl; + show_debugging = isTrue(parameters[1]); + out.print("buildingplan debugging: %s\n", + show_debugging ? "enabled" : "disabled"); } else if (cmd == "set") { if (!is_enabled) { - out << "ERROR: buildingplan must be enabled before you can read or " - << "set buildingplan global settings." << endl; + out.printerr( + "ERROR: buildingplan must be enabled before you can" + " read or set buildingplan global settings."); return CR_FAILURE; } if (!DFHack::Core::getInstance().isMapLoaded()) { - out << "ERROR: A map must be loaded before you can read or set " - << "buildingplan global settings. Try adding your " - << "'buildingplan set' commands to the onMapLoad.init file." - << endl; + out.printerr( + "ERROR: A map must be loaded before you can read or set" + "buildingplan global settings. Try adding your" + "'buildingplan set' commands to the onMapLoad.init" "file."); return CR_FAILURE; } if (parameters.size() == 1) { // display current settings - out << "active settings:" << endl; + out.print("active settings:\n"); + for (auto & setting : planner.getGlobalSettings()) { - out << " " << setting.first << " = " - << (setting.second ? "true" : "false") << endl; + out.print(" %s = %s\n", setting.first.c_str(), + setting.second ? "true" : "false"); } - out << " quickfort_mode = " - << (quickfort_mode ? "true" : "false") << endl; + out.print(" quickfort_mode = %s\n", + quickfort_mode ? "true" : "false"); } else if (parameters.size() == 3) { // set a setting std::string setting = toLower(parameters[1]); - bool val = isTrue(toLower(parameters[2])); - setSetting(setting, val); + bool val = isTrue(parameters[2]); + if (!setSetting(setting, val)) + { + out.printerr("ERROR: invalid parameter: '%s'\n", + parameters[1].c_str()); + } + } + else + { + out.printerr("ERROR: invalid syntax"); } } @@ -1089,14 +1101,14 @@ static void scheduleCycle() { cycle_requested = true; } -static void setSetting(std::string name, bool value) { +static bool setSetting(std::string name, bool value) { if (name == "quickfort_mode") { debug("setting quickfort_mode %d -> %d", quickfort_mode, value); quickfort_mode = value; - return; + return true; } - planner.setGlobalSetting(name, value); + return planner.setGlobalSetting(name, value); } DFHACK_PLUGIN_LUA_FUNCTIONS { From d01e61c6583262fc01fcc47efdffc4547526a396 Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 22 Jan 2021 21:05:20 -0500 Subject: [PATCH 8/8] Fix some error message formatting and add some cross-links to docs Followup to #1747 --- docs/Plugins.rst | 8 ++++++++ docs/guides/quickfort-user-guide.rst | 27 ++++++++++++++------------- plugins/buildingplan.cpp | 4 ++-- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/docs/Plugins.rst b/docs/Plugins.rst index 8adf91c05..544a40844 100644 --- a/docs/Plugins.rst +++ b/docs/Plugins.rst @@ -716,6 +716,8 @@ to always have one or two doors/beds/tables/chairs/etc available, and place as many as you like. The plugins then take over and fulfill the orders, with minimal space dedicated to stockpiles. +.. _buildingplan-filters: + Item filtering -------------- @@ -745,6 +747,8 @@ Note that Quickfort mode is only for compatibility with the legacy Python Quickf DFHack `quickfort` script does not need Quickfort mode to be enabled. The `quickfort` script will successfully integrate with buildingplan as long as the buildingplan plugin is enabled. +.. _buildingplan-settings: + Global settings --------------- @@ -755,6 +759,10 @@ can also be set from the ``DFHack#`` prompt once a map is loaded (or from your buildingplan set +and displayed with:: + + buildingplan set + The available settings are: +----------------+---------+---------------------------------------+ diff --git a/docs/guides/quickfort-user-guide.rst b/docs/guides/quickfort-user-guide.rst index d51e84ffc..8be74ac51 100644 --- a/docs/guides/quickfort-user-guide.rst +++ b/docs/guides/quickfort-user-guide.rst @@ -1019,21 +1019,22 @@ prevents a building designation from being canceled when a dwarf picks up the job but can't find the materials. As long as the `buildingplan` plugin is enabled, quickfort will use it to manage -construction. The buildingplan plugin also has an "enabled" setting for each -building type, but that setting only applies to the buildingplan user interface. -In addition, buildingplan has a "quickfort_mode" setting for compatibility with -legacy Python Quickfort. This setting has no effect on DFHack Quickfort, which -will use buildingplan to manage everything designated in a ``#build`` blueprint +construction. The buildingplan plugin has an `"enabled" setting +` for each building type, but those settings only apply +to buildings created through the buildingplan user interface. In addition, +buildingplan has a "quickfort_mode" setting for compatibility with legacy Python +Quickfort. This setting has no effect on DFHack Quickfort, which will use +buildingplan to manage everything designated in a ``#build`` blueprint regardless of the buildingplan UI settings. -However, quickfort *does* use buildingplan's filters for each building type. For -example, you can use the buildingplan UI to set the type of stone you want your -walls made out of. Or you can specify that all buildingplan-managed tables must -be of Masterful quality. The current filter settings are saved with planned -buildings when the ``#build`` blueprint is run. This means you can set the -filters the way you want for one blueprint, run the blueprint, and then freely -change them again for the next blueprint, even if the first set of buildings -haven't been built yet. +However, quickfort *does* use `buildingplan's filters ` +for each building type. For example, you can use the buildingplan UI to set the +type of stone you want your walls made out of. Or you can specify that all +buildingplan-managed tables must be of Masterful quality. The current filter +settings are saved with planned buildings when the ``#build`` blueprint is run. +This means you can set the filters the way you want for one blueprint, run the +blueprint, and then freely change them again for the next blueprint, even if the +first set of buildings haven't been built yet. Note that buildings are still constructed immediately if you already have the materials. However, with buildingplan you now have the freedom to apply diff --git a/plugins/buildingplan.cpp b/plugins/buildingplan.cpp index 14c3a1918..e68f9ca4b 100644 --- a/plugins/buildingplan.cpp +++ b/plugins/buildingplan.cpp @@ -954,7 +954,7 @@ static command_result buildingplan_cmd(color_ostream &out, vector & par out.printerr( "ERROR: A map must be loaded before you can read or set" "buildingplan global settings. Try adding your" - "'buildingplan set' commands to the onMapLoad.init" "file."); + "'buildingplan set' commands to the onMapLoad.init file.\n"); return CR_FAILURE; } @@ -985,7 +985,7 @@ static command_result buildingplan_cmd(color_ostream &out, vector & par } else { - out.printerr("ERROR: invalid syntax"); + out.printerr("ERROR: invalid syntax\n"); } }