diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt index 72df7272a..26befdb34 100644 --- a/data/CMakeLists.txt +++ b/data/CMakeLists.txt @@ -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 "*" diff --git a/data/blueprints/library/dreamfort.csv b/data/blueprints/library/dreamfort.csv index ec1a05c51..ff0b8b4fc 100644 --- a/data/blueprints/library/dreamfort.csv +++ b/data/blueprints/library/dreamfort.csv @@ -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. diff --git a/data/examples/professions/Chef b/data/professions/Chef similarity index 92% rename from data/examples/professions/Chef rename to data/professions/Chef index 1f777c81a..218e08301 100644 --- a/data/examples/professions/Chef +++ b/data/professions/Chef @@ -1,4 +1,4 @@ -NAME Chef +NAME library/Chef BUTCHER TANNER COOK diff --git a/data/examples/professions/Craftsdwarf b/data/professions/Craftsdwarf similarity index 92% rename from data/examples/professions/Craftsdwarf rename to data/professions/Craftsdwarf index 29ed1ad0d..8c9707f17 100644 --- a/data/examples/professions/Craftsdwarf +++ b/data/professions/Craftsdwarf @@ -1,4 +1,4 @@ -NAME Craftsdwarf +NAME library/Craftsdwarf WOOD_CRAFT STONE_CRAFT BONE_CARVE diff --git a/data/examples/professions/Doctor b/data/professions/Doctor similarity index 93% rename from data/examples/professions/Doctor rename to data/professions/Doctor index 893708947..14959f599 100644 --- a/data/examples/professions/Doctor +++ b/data/professions/Doctor @@ -1,4 +1,4 @@ -NAME Doctor +NAME library/Doctor ANIMALCARE DIAGNOSE SURGERY diff --git a/data/examples/professions/Farmer b/data/professions/Farmer similarity index 83% rename from data/examples/professions/Farmer rename to data/professions/Farmer index 149b3c368..0b2801f4c 100644 --- a/data/examples/professions/Farmer +++ b/data/professions/Farmer @@ -1,4 +1,4 @@ -NAME Farmer +NAME library/Farmer PLANT MILLER BREWER diff --git a/data/examples/professions/Fisherdwarf b/data/professions/Fisherdwarf similarity index 90% rename from data/examples/professions/Fisherdwarf rename to data/professions/Fisherdwarf index 3c369e61d..1b5d7a1a8 100644 --- a/data/examples/professions/Fisherdwarf +++ b/data/professions/Fisherdwarf @@ -1,4 +1,4 @@ -NAME Fisherdwarf +NAME library/Fisherdwarf FISH CLEAN_FISH DISSECT_FISH diff --git a/data/examples/professions/Hauler b/data/professions/Hauler similarity index 92% rename from data/examples/professions/Hauler rename to data/professions/Hauler index a108b1bfd..4fd8b89f8 100644 --- a/data/examples/professions/Hauler +++ b/data/professions/Hauler @@ -1,4 +1,4 @@ -NAME Hauler +NAME library/Hauler FEED_WATER_CIVILIANS SIEGEOPERATE MECHANIC diff --git a/data/examples/professions/Laborer b/data/professions/Laborer similarity index 92% rename from data/examples/professions/Laborer rename to data/professions/Laborer index bca22a302..ccd688428 100644 --- a/data/examples/professions/Laborer +++ b/data/professions/Laborer @@ -1,4 +1,4 @@ -NAME Laborer +NAME library/Laborer SOAP_MAKER BURN_WOOD POTASH_MAKING diff --git a/data/examples/professions/Marksdwarf b/data/professions/Marksdwarf similarity index 89% rename from data/examples/professions/Marksdwarf rename to data/professions/Marksdwarf index 583afd08e..f34d67cd2 100644 --- a/data/examples/professions/Marksdwarf +++ b/data/professions/Marksdwarf @@ -1,4 +1,4 @@ -NAME Marksdwarf +NAME library/Marksdwarf MECHANIC HAUL_STONE HAUL_WOOD diff --git a/data/examples/professions/Mason b/data/professions/Mason similarity index 92% rename from data/examples/professions/Mason rename to data/professions/Mason index 5f996f448..1977d2df5 100644 --- a/data/examples/professions/Mason +++ b/data/professions/Mason @@ -1,4 +1,4 @@ -NAME Mason +NAME library/Mason MASON CUT_GEM ENCRUST_GEM diff --git a/data/examples/professions/Meleedwarf b/data/professions/Meleedwarf similarity index 90% rename from data/examples/professions/Meleedwarf rename to data/professions/Meleedwarf index 8eac5ffd6..6a8338fea 100644 --- a/data/examples/professions/Meleedwarf +++ b/data/professions/Meleedwarf @@ -1,4 +1,4 @@ -NAME Meleedwarf +NAME library/Meleedwarf RECOVER_WOUNDED MECHANIC HAUL_STONE diff --git a/data/examples/professions/Migrant b/data/professions/Migrant similarity index 92% rename from data/examples/professions/Migrant rename to data/professions/Migrant index 59fd70405..23a3eeddb 100644 --- a/data/examples/professions/Migrant +++ b/data/professions/Migrant @@ -1,4 +1,4 @@ -NAME Migrant +NAME library/Migrant FEED_WATER_CIVILIANS SIEGEOPERATE MECHANIC diff --git a/data/examples/professions/Miner b/data/professions/Miner similarity index 66% rename from data/examples/professions/Miner rename to data/professions/Miner index 7be84512d..3170969d9 100644 --- a/data/examples/professions/Miner +++ b/data/professions/Miner @@ -1,4 +1,4 @@ -NAME Miner +NAME library/Miner MINE DETAIL RECOVER_WOUNDED diff --git a/data/examples/professions/Outdoorsdwarf b/data/professions/Outdoorsdwarf similarity index 92% rename from data/examples/professions/Outdoorsdwarf rename to data/professions/Outdoorsdwarf index a3f696419..31dbd2ad8 100644 --- a/data/examples/professions/Outdoorsdwarf +++ b/data/professions/Outdoorsdwarf @@ -1,4 +1,4 @@ -NAME Outdoorsdwarf +NAME library/Outdoorsdwarf CARPENTER BOWYER CUTWOOD diff --git a/data/examples/professions/Smith b/data/professions/Smith similarity index 92% rename from data/examples/professions/Smith rename to data/professions/Smith index f5fe0f982..7809d80e1 100644 --- a/data/examples/professions/Smith +++ b/data/professions/Smith @@ -1,4 +1,4 @@ -NAME Smith +NAME library/Smith FORGE_WEAPON FORGE_ARMOR FORGE_FURNITURE diff --git a/data/examples/professions/StartManager b/data/professions/StartManager similarity index 96% rename from data/examples/professions/StartManager rename to data/professions/StartManager index 751d75cc9..a70c705bf 100644 --- a/data/examples/professions/StartManager +++ b/data/professions/StartManager @@ -1,4 +1,4 @@ -NAME StartManager +NAME library/StartManager CUTWOOD ANIMALCARE DIAGNOSE diff --git a/data/examples/professions/Tailor b/data/professions/Tailor similarity index 91% rename from data/examples/professions/Tailor rename to data/professions/Tailor index 74ac03a93..f7986553a 100644 --- a/data/examples/professions/Tailor +++ b/data/professions/Tailor @@ -1,4 +1,4 @@ -NAME Tailor +NAME library/Tailor DYER LEATHER WEAVER diff --git a/docs/Plugins.rst b/docs/Plugins.rst index c73bfab3a..8acddfc6d 100644 --- a/docs/Plugins.rst +++ b/docs/Plugins.rst @@ -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: diff --git a/docs/changelog.txt b/docs/changelog.txt index ccc94701c..29e0d8e22 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -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. diff --git a/docs/guides/examples-guide.rst b/docs/guides/examples-guide.rst index 58446506e..b699b8204 100644 --- a/docs/guides/examples-guide.rst +++ b/docs/guides/examples-guide.rst @@ -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/ ` 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 diff --git a/plugins/listcolumn.h b/plugins/listcolumn.h index 08d48bd58..a9a7dc23c 100644 --- a/plugins/listcolumn.h +++ b/plugins/listcolumn.h @@ -1,3 +1,5 @@ +#pragma once + #include "uicommon.h" using df::global::enabler; diff --git a/plugins/manipulator.cpp b/plugins/manipulator.cpp index 4604cd7ea..2d3f3bc0a 100644 --- a/plugins/manipulator.cpp +++ b/plugins/manipulator.cpp @@ -652,10 +652,12 @@ namespace unit_ops { struct ProfessionTemplate { std::string name; + std::string displayName; + bool library; bool mask; std::vector 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 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 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 elem(name, i);