[manipulator] add the professions library (#2234)

* move professions out of the examples folder

* install professions into professions/library

* guard unguarded header from multiple inclusion

* load and display library professions

* update changelog

* move example professions docs from examples guide

* update dreamfort documentation

* note that professions folder has changed

* Fix bad merge
develop
Myk 2022-07-06 07:21:26 -07:00 committed by GitHub
parent e0d37a31ae
commit 9f44fd3f72
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 183 additions and 164 deletions

@ -7,6 +7,9 @@ install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/orders/
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/examples/
DESTINATION "${DFHACK_DATA_DESTINATION}/examples")
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/professions/
DESTINATION dfhack-config/professions/library)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/blueprints/
DESTINATION blueprints
FILES_MATCHING PATTERN "*"

@ -29,9 +29,9 @@
"Dreamfort works best at an embark site that is flat and has at least one soil layer. New players should avoid embarks with aquifers if they are not prepared to deal with them. Bring picks for mining, an axe for woodcutting, and an anvil for a forge. Bring a few blocks to speed up initial workshop construction as well. That's all you really need, but see the example embark profile in the online spreadsheets for a more complete setup."
""
"Other DFHack commands also work very well with Dreamfort, such as autofarm, autonestbox, prioritize, seedwatch, tailor, and, of course, buildingplan. An init file that gets everything configured for you is distributed with DFHack as hack/examples/init/onMapLoad_dreamfort.init."
Put that file in your Dwarf Fortress directory -- the same directory that has dfhack.init.
Put that file in your dfhack-config/init/ directory -- the same directory that has dfhack.init.
""
"Also copy the files in hack/examples/professions/ to professions/. We'll be using these files later. See https://docs.dfhack.org/en/stable/docs/guides/examples-guide.html for more information, including suggestions on how many dwarves of each profession you are likely to need at each stage of fort maturity."
"Also check out https://docs.dfhack.org/en/stable/docs/Plugins.html#professions for more information on the default labor professions that are distributed with DFHack, including suggestions on how many dwarves of each profession you are likely to need at each stage of fort maturity."
""
"Once you have your starting surface workshops up and running, you might want to configure buildingplan (in its global settings, accessible from any building placement screen, e.g.: b-a-G) to only use blocks for constructions so it won't use your precious wood, boulders, and bars to build floors and walls. If you bring at least 7 blocks with you on embark, you can even set this in your onMapLoad.init file like this:"
on-new-fortress buildingplan set boulders false; buildingplan set logs false
@ -49,9 +49,7 @@ interactively."
"Here is the recommended order for Dreamfort commands. You can copy/paste the command lines directly into the DFHack terminal, or, if you prefer, you can run the blueprints in the UI with gui/quickfort. See the walkthroughs (the ""help"" blueprints) for context and details. Also remember to read the messages the blueprints print out after you run them so you don't miss any important manual steps."
""
-- Preparation (before you embark!) --
Copy hack/examples/init/onMapLoad_dreamfort.init to your DF directory
Optionally copy the premade profession definitions from hack/examples/professions/ to the professions/ directory
Optionally copy the premade Dreamfort embark profile from the online spreadsheets to the data/init/embark_profiles.txt file
Copy hack/examples/init/onMapLoad_dreamfort.init to your dfhack-config/init directory inside your DF installation
""
-- Set settings and preload initial orders --
quickfort run library/dreamfort.csv -n /setup,# Run before making any manual adjustments to settings! Run the /setup_help blueprint for details on what this blueprint does.

Can't render this file because it has a wrong number of fields in line 55.

@ -1,4 +1,4 @@
NAME Chef
NAME library/Chef
BUTCHER
TANNER
COOK

@ -1,4 +1,4 @@
NAME Craftsdwarf
NAME library/Craftsdwarf
WOOD_CRAFT
STONE_CRAFT
BONE_CARVE

@ -1,4 +1,4 @@
NAME Doctor
NAME library/Doctor
ANIMALCARE
DIAGNOSE
SURGERY

@ -1,4 +1,4 @@
NAME Farmer
NAME library/Farmer
PLANT
MILLER
BREWER

@ -1,4 +1,4 @@
NAME Fisherdwarf
NAME library/Fisherdwarf
FISH
CLEAN_FISH
DISSECT_FISH

@ -1,4 +1,4 @@
NAME Hauler
NAME library/Hauler
FEED_WATER_CIVILIANS
SIEGEOPERATE
MECHANIC

@ -1,4 +1,4 @@
NAME Laborer
NAME library/Laborer
SOAP_MAKER
BURN_WOOD
POTASH_MAKING

@ -1,4 +1,4 @@
NAME Marksdwarf
NAME library/Marksdwarf
MECHANIC
HAUL_STONE
HAUL_WOOD

@ -1,4 +1,4 @@
NAME Mason
NAME library/Mason
MASON
CUT_GEM
ENCRUST_GEM

@ -1,4 +1,4 @@
NAME Meleedwarf
NAME library/Meleedwarf
RECOVER_WOUNDED
MECHANIC
HAUL_STONE

@ -1,4 +1,4 @@
NAME Migrant
NAME library/Migrant
FEED_WATER_CIVILIANS
SIEGEOPERATE
MECHANIC

@ -1,4 +1,4 @@
NAME Miner
NAME library/Miner
MINE
DETAIL
RECOVER_WOUNDED

@ -1,4 +1,4 @@
NAME Outdoorsdwarf
NAME library/Outdoorsdwarf
CARPENTER
BOWYER
CUTWOOD

@ -1,4 +1,4 @@
NAME Smith
NAME library/Smith
FORGE_WEAPON
FORGE_ARMOR
FORGE_FURNITURE

@ -1,4 +1,4 @@
NAME StartManager
NAME library/StartManager
CUTWOOD
ANIMALCARE
DIAGNOSE

@ -1,4 +1,4 @@
NAME Tailor
NAME library/Tailor
DYER
LEATHER
WEAVER

@ -3096,8 +3096,121 @@ To apply a profession, either highlight a single dwarf or select multiple with
:kbd:`x`, and press :kbd:`p` to select the profession to apply. All labors for
the selected dwarves will be reset to the labors of the chosen profession.
Professions are saved as human-readable text files in the "professions" folder
within the DF folder, and can be edited or deleted there.
Professions are saved as human-readable text files in the
``dfhack-config/professions`` folder within the DF folder, and can be edited or
deleted there.
The professions library
~~~~~~~~~~~~~~~~~~~~~~~
The manipulator plugin comes with a library of professions that you can assign
to your dwarves.
If you'd rather use Dwarf Therapist to manage your labors, it is easy to import
these professions to DT and use them there. Simply assign the professions you
want to import to a dwarf. Once you have assigned a profession to at least one
dwarf, you can select "Import Professions from DF" in the DT "File" menu. The
professions will then be available for use in DT.
In the charts below, the "At Start" and "Max" columns indicate the approximate
number of dwarves of each profession that you are likely to need at the start of
the game 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.
============= ======== ===== =================================================
Profession At Start Max Description
============= ======== ===== =================================================
Chef 0 3 Buchery, 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 0 4-6 All labors used at Craftsdwarf's workshops,
Glassmaker's workshops, and kilns.
Doctor 0 2-4 The full suite of medical labors, plus Animal
Caretaking for those using the dwarfvet plugin.
Farmer 1 4 Food- and animal product-related labors. This
profession also has the ``Alchemist`` labor
enabled since they need to focus on food-related
jobs, though you might want to disable
``Alchemist`` for your first farmer until there
are actual farming duties to perform.
Fisherdwarf 0 0-1 Fishing and fish cleaning. If you assign this
profession to any dwarf, be prepared to be
inundated with fish. Fisherdwarves *never stop
fishing*. Be sure to also run ``prioritize -a
PrepareRawFish ExtractFromRawFish`` or else
caught fish will just be left to rot.
Hauler 0 >20 All hauling labors plus Siege Operating, Mechanic
(so haulers can assist in reloading traps) and
Architecture (so haulers can help build massive
windmill farms and pump stacks). As you
accumulate enough Haulers, you can turn off
hauling labors for other dwarves so they can
focus on their skilled tasks. You may also want
to restrict your Mechanic's workshops to only
skilled mechanics so your haulers don't make
low-quality mechanisms.
Laborer 0 10-12 All labors that don't improve quality with skill,
such as Soapmaking and furnace labors.
Marksdwarf 0 10-30 Similar to Hauler. See the description for
Meleedwarf below for more details.
Mason 2 2-4 Masonry and Gem Cutting/Encrusting. In the early
game, you may need to run "`prioritize`
ConstructBuilding" to get your masons to build
wells and bridges if they are too busy crafting
stone furniture.
Meleedwarf 0 20-50 Similar to Hauler, but without most civilian
labors. This profession is separate from Hauler
so you can find your military dwarves easily.
Meleedwarves and Marksdwarves have Mechanics and
hauling labors enabled so you can temporarily
deactivate your military after sieges and allow
your military dwarves to help clean up.
Migrant 0 0 You can assign this profession to new migrants
temporarily while you sort them into professions.
Like Marksdwarf and Meleedwarf, the purpose of
this profession is so you can find your new
dwarves more easily.
Miner 2 2-10 Mining and Engraving. This profession also has
the ``Alchemist`` labor enabled, which disables
hauling for those using the `autohauler` plugin.
Once the need for Miners tapers off in the late
game, dwarves with this profession make good
military dwarves, wielding their picks as
weapons.
Outdoorsdwarf 1 2-4 Carpentry, Bowyery, Woodcutting, Animal Training,
Trapping, Plant Gathering, Beekeeping, and Siege
Engineering.
Smith 0 2-4 Smithing labors. You may want to specialize your
Smiths to focus on a single smithing skill to
maximize equipment quality.
StartManager 1 0 All skills not covered by the other starting
professions (Miner, Mason, Outdoorsdwarf, and
Farmer), plus a few overlapping skills to
assist in critical tasks at the beginning of the
game. Individual labors should be turned off as
migrants are assigned more specialized
professions that cover them, and the StartManager
dwarf can eventually convert to some other
profession.
Tailor 0 2 Textile industry labors: Dying, Leatherworking,
Weaving, and Clothesmaking.
============= ======== ===== =================================================
A note on autohauler
~~~~~~~~~~~~~~~~~~~~
These profession definitions are designed to work well with or without the
`autohauler` plugin (which helps to keep your dwarves focused on skilled labors
instead of constantly being distracted by hauling). If you do want to use
autohauler, adding the following lines to your ``onMapLoad.init`` file will
configure it to let the professions manage the "Feed water to civilians" and
"Recover wounded" labors instead of enabling those labors for all hauling
dwarves::
on-new-fortress enable autohauler
on-new-fortress autohauler FEED_WATER_CIVILIANS allow
on-new-fortress autohauler RECOVER_WOUNDED allow
.. _mousequery:

@ -41,8 +41,10 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
- ``job.removeJob()``: ensure jobs are removed from the world list when they are canceled
## Misc Improvements
- ``materials.ItemTraitsDialog``: added a default ``on_select``-handler which toggles the traits.
- `manipulator`: add a library of useful default professions
- `manipulator`: move professions configuration from ``professions/`` to ``dfhack-config/professions/`` to keep it together with other dfhack configuration. If you have saved professions that you would like to keep, please manually move them to the new folder.
- ``materials.ItemTraitsDialog``: added a default ``on_select``-handler which toggles the traits.
- `orders`: added useful library of manager orders. see them with ``orders list`` and import them with, for example, ``orders import library/basic``
- `prospect`: add new ``--show`` option to give the player control over which report sections are shown. e.g. ``prospect all --show ores`` will just show information on ores.

@ -47,125 +47,3 @@ it is useful (and customizable) for any fort. It includes the following config:
fortress is first started, so any later changes you make to autobutcher
settings won't be overridden.
- Enables `automelt`, `tailor`, `zone`, `nestboxes`, and `autonestbox`.
The ``professions/`` subfolder
------------------------------
The :source:`professions/ <data/examples/professions>` subfolder contains
professions, or sets of related labors, that you can assign to your dwarves with
the DFHack `manipulator` plugin. Copy them into the ``professions/``
subdirectory under the main Dwarf Fortress folder (you may have to create this
subdirectory) and assign them to your dwarves in the manipulator UI, accessible
from the ``units`` screen via the :kbd:`l` hotkey. Make sure that the
``manipulator`` plugin is enabled in your ``dfhack.init`` file! You can assign a
profession to a dwarf by selecting the dwarf in the ``manipulator`` UI and
hitting :kbd:`p`. The list of professions that you copied into the
``professions/`` folder will show up for you to choose from. This is very useful
for assigning roles to new migrants to ensure that all the tasks in your fort
have adequate numbers of dwarves attending to them.
If you'd rather use Dwarf Therapist to manage your labors, it is easy to import
these professions to DT and use them there. Simply assign the professions you
want to import to a dwarf. Once you have assigned a profession to at least one
dwarf, you can select "Import Professions from DF" in the DT "File" menu. The
professions will then be available for use in DT.
In the charts below, the "At Start" and "Max" columns indicate the approximate
number of dwarves of each profession that you are likely to need at the start of
the game and how many you are likely to need in a mature fort.
============= ======== ===== =================================================
Profession At Start Max Description
============= ======== ===== =================================================
Chef 0 3 Buchery, 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 0 4-6 All labors used at Craftsdwarf's workshops,
Glassmaker's workshops, and kilns.
Doctor 0 2-4 The full suite of medical labors, plus Animal
Caretaking for those using the dwarfvet plugin.
Farmer 1 4 Food- and animal product-related labors. This
profession also has the ``Alchemist`` labor
enabled since they need to focus on food-related
jobs, though you might want to disable
``Alchemist`` for your first farmer until there
are actual farming duties to perform.
Fisherdwarf 0 0-1 Fishing and fish cleaning. If you assign this
profession to any dwarf, be prepared to be
inundated with fish. Fisherdwarves *never stop
fishing*. Be sure to also run ``prioritize -a
PrepareRawFish ExtractFromRawFish`` (or use the
``onMapLoad_dreamfort.init`` file above) or else
caught fish will just be left to rot.
Hauler 0 >20 All hauling labors plus Siege Operating, Mechanic
(so haulers can assist in reloading traps) and
Architecture (so haulers can help build massive
windmill farms and pump stacks). As you
accumulate enough Haulers, you can turn off
hauling labors for other dwarves so they can
focus on their skilled tasks. You may also want
to restrict your Mechanic's workshops to only
skilled mechanics so your haulers don't make
low-quality mechanisms.
Laborer 0 10-12 All labors that don't improve quality with skill,
such as Soapmaking and furnace labors.
Marksdwarf 0 10-30 Similar to Hauler. See the description for
Meleedwarf below for more details.
Mason 2 2-4 Masonry, Gem Cutting/Encrusting, and
Architecture. In the early game, you may need to
run "`prioritize` ConstructBuilding" to get your
masons to build wells and bridges if they are too
busy crafting stone furniture.
Meleedwarf 0 20-50 Similar to Hauler, but without most civilian
labors. This profession is separate from Hauler
so you can find your military dwarves easily.
Meleedwarves and Marksdwarves have Mechanics and
hauling labors enabled so you can temporarily
deactivate your military after sieges and allow
your military dwarves to help clean up.
Migrant 0 0 You can assign this profession to new migrants
temporarily while you sort them into professions.
Like Marksdwarf and Meleedwarf, the purpose of
this profession is so you can find your new
dwarves more easily.
Miner 2 2-10 Mining and Engraving. This profession also has
the ``Alchemist`` labor enabled, which disables
hauling for those using the `autohauler` plugin.
Once the need for Miners tapers off in the late
game, dwarves with this profession make good
military dwarves, wielding their picks as
weapons.
Outdoorsdwarf 1 2-4 Carpentry, Bowyery, Woodcutting, Animal Training,
Trapping, Plant Gathering, Beekeeping, and Siege
Engineering.
Smith 0 2-4 Smithing labors. You may want to specialize your
Smiths to focus on a single smithing skill to
maximize equipment quality.
StartManager 1 0 All skills not covered by the other starting
professions (Miner, Mason, Outdoorsdwarf, and
Farmer), plus a few overlapping skills to
assist in critical tasks at the beginning of the
game. Individual labors should be turned off as
migrants are assigned more specialized
professions that cover them, and the StartManager
dwarf can eventually convert to some other
profession.
Tailor 0 2 Textile industry labors: Dying, Leatherworking,
Weaving, and Clothesmaking.
============= ======== ===== =================================================
A note on autohauler
~~~~~~~~~~~~~~~~~~~~
These profession definitions are designed to work well with or without the
`autohauler` plugin (which helps to keep your dwarves focused on skilled labors
instead of constantly being distracted by hauling). If you do want to use
autohauler, adding the following lines to your ``onMapLoad.init`` file will
configure it to let the professions manage the "Feed water to civilians" and
"Recover wounded" labors instead of enabling those labors for all hauling
dwarves::
on-new-fortress enable autohauler
on-new-fortress autohauler FEED_WATER_CIVILIANS allow
on-new-fortress autohauler RECOVER_WOUNDED allow

@ -1,3 +1,5 @@
#pragma once
#include "uicommon.h"
using df::global::enabler;

@ -652,10 +652,12 @@ namespace unit_ops {
struct ProfessionTemplate
{
std::string name;
std::string displayName;
bool library;
bool mask;
std::vector<df::unit_labor> labors;
bool load(string directory, string file)
bool load(string directory, string file, bool isLibrary)
{
cerr << "Attempt to load " << file << endl;
std::ifstream infile(directory + "/" + file);
@ -663,14 +665,25 @@ struct ProfessionTemplate
return false;
}
library = isLibrary;
std::string line;
name = file; // If no name is given we default to the filename
displayName = name;
mask = false;
while (std::getline(infile, line)) {
if (strcmp(line.substr(0,5).c_str(),"NAME ")==0)
{
auto nextInd = line.find(' ');
name = line.substr(nextInd + 1);
displayName = line.substr(nextInd + 1);
name = displayName;
size_t slashpos = name.find_first_of("\\/");
while (name.npos != slashpos) {
name = name.substr(slashpos + 1);
slashpos = name.find_first_of("\\/");
}
if (name == "")
name = file;
continue;
}
if (line == "MASK")
@ -745,7 +758,8 @@ struct ProfessionTemplate
}
};
static std::string professions_folder = Filesystem::getcwd() + "/professions";
static std::string professions_folder = "dfhack-config/professions";
static std::string professions_library_folder = "dfhack-config/professions/library";
class ProfessionTemplateManager
{
public:
@ -760,27 +774,21 @@ public:
}
void load()
{
vector <string> files;
cerr << "Attempting to load professions: " << professions_folder.c_str() << endl;
if (!Filesystem::isdir(professions_folder) && !Filesystem::mkdir(professions_folder))
{
cerr << professions_folder << ": Does not exist and cannot be created" << endl;
return;
}
Filesystem::listdir(professions_folder, files);
std::sort(files.begin(), files.end());
for(size_t i = 0; i < files.size(); i++)
{
if (files[i] == "." || files[i] == "..")
continue;
_load(professions_folder, false);
_load(professions_library_folder, true);
ProfessionTemplate t;
if (t.load(professions_folder, files[i]))
{
templates.push_back(t);
}
}
// sort alphabetically by display name, with user data above library data
std::sort(templates.begin(), templates.end(),
[](const ProfessionTemplate &a, const ProfessionTemplate &b) {
return (a.library == b.library && a.displayName < b.displayName)
|| (b.library && !a.library);
});
}
void save_from_unit(UnitInfo *unit)
{
@ -792,6 +800,21 @@ public:
t.save(professions_folder);
reload();
}
private:
void _load(const std::string &path, bool library) {
vector<string> files;
Filesystem::listdir(path, files);
for (auto &fname : files) {
if (Filesystem::isdir(path + "/" + fname))
continue;
ProfessionTemplate t;
if (t.load(path, fname, library)) {
templates.push_back(t);
}
}
}
};
static ProfessionTemplateManager manager;
@ -992,7 +1015,7 @@ public:
manager.reload();
for (size_t i = 0; i < manager.templates.size(); i++) {
std::string name = manager.templates[i].name;
std::string name = manager.templates[i].displayName;
if (manager.templates[i].mask)
name += " (mask)";
ListEntry<size_t> elem(name, i);