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 a11cee938..758a54fb5 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -37,6 +37,9 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - `embark-assistant`: fixed order of factors when calculating min temperature - `embark-assistant`: improved performance of surveying +## Misc Improvements +- `buildingplan`: set global settings from the ``DFHack#`` prompt: e.g. ``buildingplan set boulders false`` + # 0.47.04-r4 ## Fixes diff --git a/docs/guides/quickfort-user-guide.rst b/docs/guides/quickfort-user-guide.rst index 9819c8088..d51e84ffc 100644 --- a/docs/guides/quickfort-user-guide.rst +++ b/docs/guides/quickfort-user-guide.rst @@ -1020,9 +1020,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 8d17d5dbc..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 @@ -911,26 +911,87 @@ 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 bool setSetting(std::string name, bool value); + +static bool isTrue(std::string val) +{ + val = toLower(val); + return val == "on" || val == "true" || val == "y" || val == "yes" + || val == "1"; +} + 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.print("buildingplan version: %s\n", PLUGIN_VERSION); + } + else if (parameters.size() >= 2 && cmd == "debug") + { + show_debugging = isTrue(parameters[1]); + out.print("buildingplan debugging: %s\n", + show_debugging ? "enabled" : "disabled"); + } + else if (cmd == "set") { - if (parameters.size() == 1 && toLower(parameters[0])[0] == 'v') + if (!is_enabled) { - out << "Building Plan" << endl << "Version: " << PLUGIN_VERSION << endl; + out.printerr( + "ERROR: buildingplan must be enabled before you can" + " read or set buildingplan global settings."); + return CR_FAILURE; } - else if (parameters.size() == 2 && toLower(parameters[0]) == "debug") + + if (!DFHack::Core::getInstance().isMapLoaded()) { - show_debugging = (toLower(parameters[1]) == "on"); - out << "Debugging " << ((show_debugging) ? "enabled" : "disabled") << 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.print("active settings:\n"); + + for (auto & setting : planner.getGlobalSettings()) + { + out.print(" %s = %s\n", setting.first.c_str(), + setting.second ? "true" : "false"); + } + + 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(parameters[2]); + if (!setSetting(setting, val)) + { + out.printerr("ERROR: invalid parameter: '%s'\n", + parameters[1].c_str()); + } + } + else + { + out.printerr("ERROR: invalid syntax"); } } return CR_OK; } -DFHACK_PLUGIN_IS_ENABLED(is_enabled); - DFhackCExport command_result plugin_enable(color_ostream &out, bool enable) { if (!gps) @@ -1040,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 {