From 9d4d0b195a3fbf3c1e672deb0be87c81b9d0cd66 Mon Sep 17 00:00:00 2001 From: PatrikLundell Date: Wed, 22 Jan 2020 17:33:39 +0100 Subject: [PATCH 001/547] Added switches for farm seeds and plant counts --- docs/changelog.txt | 5 ++ plugins/getplants.cpp | 198 +++++++++++++++++++++++++++++++++++------- 2 files changed, 172 insertions(+), 31 deletions(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index 5c1b37561..41b371a8e 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -35,6 +35,11 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ======== IMPORTANT: rename this, and add a new "future" section, BEFORE ======== ======== making a new DFHack release! ======== ================================================================================ +# Future + +## Misc Improvements +- `getplants`: added switches for designations for farming seeds and for max number designated per plant + # 0.44.12-r3 ## New Plugins diff --git a/plugins/getplants.cpp b/plugins/getplants.cpp index ebd64d8d1..11717b36b 100644 --- a/plugins/getplants.cpp +++ b/plugins/getplants.cpp @@ -38,16 +38,53 @@ enum class selectability { Unselected }; -//selectability selectablePlant(color_ostream &out, const df::plant_raw *plant) -selectability selectablePlant(const df::plant_raw *plant) +// Determination of whether seeds can be collected is somewhat messy: +// - Growths of type SEEDS are collected only if they are edible either raw or cooked. +// - Growths of type PLANT_GROWTH are collected provided the STOCKPILE_PLANT_GROWTH +// flag is set. +// The two points above were determined through examination of the DF code, while the ones +// below were determined through examination of the behavior of bugged, working, and +// RAW manipulated shrubs on embarks. +// - If seeds are defined as explicit growths, they are the source of seeds, overriding +// the default STRUCTURAL part as the source. +// - If a growth has the reaction that extracts seeds as a side effect of other +// processing (brewing, eating raw, etc.), this overrides the STRUCTURAL part as the +// source of seeds. However, for some reason it does not produce seeds from eating +// raw growths unless the structural part is collected (at least for shrubs: other +// processing was not examined). +// - If a growth has a (non vanilla) reaction that produces seeds, seeds are produced, +// provided there is something (such as a workshop order) that triggers it. +// The code below is satisfied with detection of a seed producing reaction, and does not +// detect the bugged case where a seed extraction process is defined but doesn't get +// triggered. Such a process can be triggered either as a side effect of other +// processing, or as a workshop reaction, and it would be overkill for this code to +// try to determine if a workshop reaction exists and has been permitted for the played +// race. +// There are two bugged cases of this in the current vanilla RAWs: +// Both Red Spinach and Elephant-Head Amaranth have the seed extraction reaction +// explicitly specified for the structural part, but no other use for it. This causes +// these parts to be collected (a valid reaction is defined), but remain unusable. This +// is one ofthe issues in bug 9640 on the bug tracker (the others cases are detected and +// result in the plants not being usable for farming or even collectable at all). + +//selectability selectablePlant(color_ostream &out, const df::plant_raw *plant, bool farming) +selectability selectablePlant(const df::plant_raw *plant, bool farming) { const DFHack::MaterialInfo basic_mat = DFHack::MaterialInfo(plant->material_defs.type_basic_mat, plant->material_defs.idx_basic_mat); bool outOfSeason = false; + selectability result = selectability::Nonselectable; if (plant->flags.is_set(plant_raw_flags::TREE)) { // out.print("%s is a selectable tree\n", plant->id.c_str()); - return selectability::Selectable; + if (farming) + { + return selectability::Nonselectable; + } + else + { + return selectability::Selectable; + } } else if (plant->flags.is_set(plant_raw_flags::GRASS)) { @@ -55,11 +92,26 @@ selectability selectablePlant(const df::plant_raw *plant) return selectability::Grass; } + if (farming && plant->material_defs.type_seed == -1) + { + return selectability::Nonselectable; + } + if (basic_mat.material->flags.is_set(material_flags::EDIBLE_RAW) || basic_mat.material->flags.is_set(material_flags::EDIBLE_COOKED)) { // out.print("%s is edible\n", plant->id.c_str()); - return selectability::Selectable; + if (farming) + { + if (basic_mat.material->flags.is_set(material_flags::EDIBLE_RAW)) + { + result = selectability::Selectable; + } + } + else + { + return selectability::Selectable; + } } if (plant->flags.is_set(plant_raw_flags::THREAD) || @@ -69,14 +121,28 @@ selectability selectablePlant(const df::plant_raw *plant) plant->flags.is_set(plant_raw_flags::EXTRACT_STILL_VIAL)) { // out.print("%s is thread/mill/extract\n", plant->id.c_str()); - return selectability::Selectable; + if (farming) + { + result = selectability::Selectable; + } + else + { + return selectability::Selectable; + } } if (basic_mat.material->reaction_product.id.size() > 0 || basic_mat.material->reaction_class.size() > 0) { // out.print("%s has a reaction\n", plant->id.c_str()); - return selectability::Selectable; + if (farming) + { + result = selectability::Selectable; + } + else + { + return selectability::Selectable; + } } for (size_t i = 0; i < plant->growths.size(); i++) @@ -91,16 +157,37 @@ selectability selectablePlant(const df::plant_raw *plant) (plant->growths[i]->item_type == df::item_type::PLANT_GROWTH && growth_mat.material->flags.is_set(material_flags::LEAF_MAT))) // Will change name to STOCKPILE_PLANT_GROWTH any day now... { + bool seedSource = plant->growths[i]->item_type == df::item_type::SEEDS; + + if (plant->growths[i]->item_type == df::item_type::PLANT_GROWTH) + { + for (size_t k = 0; growth_mat.material->reaction_product.material.mat_type.size(); k++) + { + if (growth_mat.material->reaction_product.material.mat_type[k] == plant->material_defs.type_seed && + growth_mat.material->reaction_product.material.mat_index[k] == plant->material_defs.idx_seed) + { + seedSource = true; + break; + } + } + } + if (*cur_year_tick >= plant->growths[i]->timing_1 && (plant->growths[i]->timing_2 == -1 || *cur_year_tick <= plant->growths[i]->timing_2)) { // out.print("%s has an edible seed or a stockpile growth\n", plant->id.c_str()); - return selectability::Selectable; + if (!farming || seedSource) + { + return selectability::Selectable; + } } else { - outOfSeason = true; + if (!farming || seedSource) + { + outOfSeason = true; + } } } } @@ -133,7 +220,7 @@ selectability selectablePlant(const df::plant_raw *plant) else { // out.printerr("%s cannot be gathered\n", plant->id.c_str()); - return selectability::Nonselectable; + return result; } } @@ -143,8 +230,8 @@ command_result df_getplants (color_ostream &out, vector & parameters) std::vector plantSelections; std::vector collectionCount; set plantNames; - bool deselect = false, exclude = false, treesonly = false, shrubsonly = false, all = false, verbose = false; - + bool deselect = false, exclude = false, treesonly = false, shrubsonly = false, all = false, verbose = false, farming = false; + size_t maxCount = 999999; int count = 0; plantSelections.resize(world->raws.plants.all.size()); @@ -160,20 +247,43 @@ command_result df_getplants (color_ostream &out, vector & parameters) for (size_t i = 0; i < parameters.size(); i++) { - if(parameters[i] == "help" || parameters[i] == "?") + if (parameters[i] == "help" || parameters[i] == "?") return CR_WRONG_USAGE; - else if(parameters[i] == "-t") + else if (parameters[i] == "-t") treesonly = true; - else if(parameters[i] == "-s") + else if (parameters[i] == "-s") shrubsonly = true; - else if(parameters[i] == "-c") + else if (parameters[i] == "-c") deselect = true; - else if(parameters[i] == "-x") + else if (parameters[i] == "-x") exclude = true; - else if(parameters[i] == "-a") + else if (parameters[i] == "-a") all = true; - else if(parameters[i] == "-v") + else if (parameters[i] == "-v") verbose = true; + else if (parameters[i] == "-f") + farming = true; + else if (parameters[i] == "-n") + { + if (parameters.size() > i + 1) + { + maxCount = atoi(parameters[i + 1].c_str()); + if (maxCount >= 1) + { + i++; // We've consumed the next parameter, so we need to progress the iterator. + } + else + { + out.printerr("-n requires a positive integer parameter!\n"); + return CR_WRONG_USAGE; + } + } + else + { + out.printerr("-n requires a positive integer parameter!\n"); + return CR_WRONG_USAGE; + } + } else plantNames.insert(parameters[i]); } @@ -182,6 +292,11 @@ command_result df_getplants (color_ostream &out, vector & parameters) out.printerr("Cannot specify both -t and -s at the same time!\n"); return CR_WRONG_USAGE; } + if (treesonly && farming) + { + out.printerr("Cannot specify both -t and -f at the same time!\n"); + return CR_WRONG_USAGE; + } if (all && exclude) { out.printerr("Cannot specify both -a and -x at the same time!\n"); @@ -200,14 +315,14 @@ command_result df_getplants (color_ostream &out, vector & parameters) df::plant_raw *plant = world->raws.plants.all[i]; if (all) { -// plantSelections[i] = selectablePlant(out, plant); - plantSelections[i] = selectablePlant(plant); +// plantSelections[i] = selectablePlant(out, plant, farming); + plantSelections[i] = selectablePlant(plant, farming); } else if (plantNames.find(plant->id) != plantNames.end()) { plantNames.erase(plant->id); -// plantSelections[i] = selectablePlant(out, plant); - plantSelections[i] = selectablePlant(plant); +// plantSelections[i] = selectablePlant(out, plant, farming); + plantSelections[i] = selectablePlant(plant, farming); switch (plantSelections[i]) { case selectability::Grass: @@ -215,7 +330,14 @@ command_result df_getplants (color_ostream &out, vector & parameters) break; case selectability::Nonselectable: - out.printerr("%s does not have any parts that can be gathered\n", plant->id.c_str()); + if (farming) + { + out.printerr("%s does not have any parts that can be gathered for seeds for farming\n", plant->id.c_str()); + } + else + { + out.printerr("%s does not have any parts that can be gathered\n", plant->id.c_str()); + } break; case selectability::OutOfSeason: @@ -255,8 +377,8 @@ command_result df_getplants (color_ostream &out, vector & parameters) for (size_t i = 0; i < world->raws.plants.all.size(); i++) { df::plant_raw *plant = world->raws.plants.all[i]; -// switch (selectablePlant(out, plant)) - switch (selectablePlant(plant)) +// switch (selectablePlant(out, plant, farming)) + switch (selectablePlant(plant, farming)) { case selectability::Grass: case selectability::Nonselectable: @@ -264,13 +386,21 @@ command_result df_getplants (color_ostream &out, vector & parameters) case selectability::OutOfSeason: { - out.print("* (shrub) %s - %s is out of season\n", plant->id.c_str(), plant->name.c_str()); + if (!treesonly) + { + out.print("* (shrub) %s - %s is out of season\n", plant->id.c_str(), plant->name.c_str()); + } break; } case selectability::Selectable: { - out.print("* (%s) %s - %s\n", plant->flags.is_set(plant_raw_flags::TREE) ? "tree" : "shrub", plant->id.c_str(), plant->name.c_str()); + if ((treesonly && plant->flags.is_set(plant_raw_flags::TREE)) || + (shrubsonly && !plant->flags.is_set(plant_raw_flags::TREE)) || + (!treesonly && !shrubsonly)) // 'farming' weeds out trees when determining selectability, so no need to test that explicitly + { + out.print("* (%s) %s - %s\n", plant->flags.is_set(plant_raw_flags::TREE) ? "tree" : "shrub", plant->id.c_str(), plant->name.c_str()); + } break; } @@ -311,6 +441,8 @@ command_result df_getplants (color_ostream &out, vector & parameters) continue; if (cur->designation[x][y].bits.hidden) continue; + if (collectionCount[plant->material] >= maxCount) + continue; if (deselect && Designations::unmarkPlant(plant)) { collectionCount[plant->material]++; @@ -350,12 +482,16 @@ DFhackCExport command_result plugin_init ( color_ostream &out, vector Date: Wed, 22 Jan 2020 19:41:06 +0100 Subject: [PATCH 002/547] Updated getplants documentation --- docs/Plugins.rst | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/docs/Plugins.rst b/docs/Plugins.rst index ac1f7dae8..d8d8bb85e 100644 --- a/docs/Plugins.rst +++ b/docs/Plugins.rst @@ -2298,16 +2298,19 @@ by spaces. Options: -:``-t``: Select trees only (exclude shrubs) -:``-s``: Select shrubs only (exclude trees) -:``-c``: Clear designations instead of setting them -:``-x``: Apply selected action to all plants except those specified (invert +:``-t``: Tree: Select trees only (exclude shrubs) +:``-s``: Shrub: Select shrubs only (exclude trees) +:``-f``: Farming: Designate only shrubs that yield seeds for farming. Implies -s +:``-c``: Clear: Clear designations instead of setting them +:``-x``: eXcept: Apply selected action to all plants except those specified (invert selection) -:``-a``: Select every type of plant (obeys ``-t``/``-s``) -:``-v``: Lists the number of (un)designations per plant +:``-a``: All: Select every type of plant (obeys ``-t``/``-s``/``-f``) +:``-v``: Verbose: Lists the number of (un)designations per plant +:``-n *``: Number: Designate up to * (an integer number) plants of each species -Specifying both ``-t`` and ``-s`` will have no effect. If no plant IDs are specified, -all valid plant IDs will be listed. +Specifying both ``-t`` and ``-s`` or ``-f`` will have no effect. If no plant IDs are +specified, all valid plant IDs will be listed, with ``-t``, ``-s``, and ``-f`` +restricting the list to trees, shrubs, and farmable shrubs, respectively. .. note:: @@ -2317,7 +2320,13 @@ all valid plant IDs will be listed. This leads to some shrubs being designated when they shouldn't be, causing a plant gatherer to walk there and do nothing (except clearing the designation). See :issue:`1479` for details. - + + The implementation another known deficiency: it's incapable of detecting that + RAW definitions that specify a seed extraction reaction for the structural part + but has no other use for it cannot actually yield any seeds, as the part is + never used (parts of bug tracker report 6940, e.g. Red Spinach), even though DF + collects it, unless there's a workshop reaction to do it (which there isn't + in vanilla). .. _infiniteSky: From c6bbf39c6c906a1600b9597f96da2760d6be7dd4 Mon Sep 17 00:00:00 2001 From: PatrikLundell Date: Sat, 25 Jan 2020 12:43:02 +0100 Subject: [PATCH 003/547] Issue #1262. Added Items::getTitle and used in stocks --- docs/changelog.txt | 8 ++++ library/include/modules/Items.h | 5 ++ library/modules/Items.cpp | 81 +++++++++++++++++++++++++++++++++ plugins/stocks.cpp | 14 ++++-- 4 files changed, 105 insertions(+), 3 deletions(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index 5c1b37561..9e4bef7a0 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -35,6 +35,14 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ======== IMPORTANT: rename this, and add a new "future" section, BEFORE ======== ======== making a new DFHack release! ======== ================================================================================ +# Future + +## Fixes +- `stocks`: fixed display of titles by using the new ``Items::`getTitle`` operation before the original one, issue 1262 + +## API +- Added ``Items::`getTitle`` to get titles of "books". Catches titles buried in improvements, unlike getDescription. + # 0.44.12-r3 ## New Plugins diff --git a/library/include/modules/Items.h b/library/include/modules/Items.h index 776e935eb..e232bc953 100644 --- a/library/include/modules/Items.h +++ b/library/include/modules/Items.h @@ -159,6 +159,11 @@ DFHACK_EXPORT df::unit *getHolderUnit(df::item *item); /// Returns the true position of the item. DFHACK_EXPORT df::coord getPosition(df::item *item); +/// Returns the title of a codex or "tool", either as the codex title or as the title of the +/// first page or writing it has that has a non blank title. An empty string is returned if +/// no title is found (which is the casee for everything that isn't a "book"). +DFHACK_EXPORT std::string getTitle(df::item *item); + /// Returns the description string of the item. DFHACK_EXPORT std::string getDescription(df::item *item, int type = 0, bool decorate = false); diff --git a/library/modules/Items.cpp b/library/modules/Items.cpp index a1b4ace4d..f102bcc78 100644 --- a/library/modules/Items.cpp +++ b/library/modules/Items.cpp @@ -59,6 +59,8 @@ using namespace std; #include "df/general_ref_unit_holderst.h" #include "df/historical_entity.h" #include "df/item.h" +#include "df/item_bookst.h" +#include "df/item_toolst.h" #include "df/item_type.h" #include "df/itemdef_ammost.h" #include "df/itemdef_armorst.h" @@ -74,6 +76,9 @@ using namespace std; #include "df/itemdef_toyst.h" #include "df/itemdef_trapcompst.h" #include "df/itemdef_weaponst.h" +#include "df/itemimprovement.h" +#include "df/itemimprovement_pagesst.h" +#include "df/itemimprovement_writingst.h" #include "df/job_item.h" #include "df/mandate.h" #include "df/map_block.h" @@ -90,6 +95,7 @@ using namespace std; #include "df/viewscreen_itemst.h" #include "df/world.h" #include "df/world_site.h" +#include "df/written_content.h" using namespace DFHack; using namespace df::enums; @@ -681,6 +687,81 @@ static void addQuality(std::string &tmp, int quality) } } +// It's not impossible the functionality of this operation is provided by one of the unmapped item functions. +std::string Items::getTitle(df::item *item) +{ + CHECK_NULL_POINTER(item); + + std::string tmp; + + if (item->getType() == df::item_type::BOOK) + { + if (virtual_cast(item)->title != "") + { + return virtual_cast(item)->title; + } + else + { + for (size_t i = 0; i < virtual_cast(item)->improvements.size(); i++) + { + if (virtual_cast(item)->improvements[i]->getType() == df::improvement_type::PAGES) + { + for (size_t k = 0; k < virtual_cast(virtual_cast(item)->improvements[i])->contents.size(); k++) + { + df::written_content *contents = world->written_contents.all[virtual_cast(virtual_cast(item)->improvements[i])->contents[k]]; + if (contents->title != "") + { + return contents->title; + } + } + } + else if (virtual_cast(item)->improvements[i]->getType() == df::improvement_type::WRITING) + { + for (size_t k = 0; k < virtual_cast(virtual_cast(item)->improvements[i])->contents.size(); k++) + { + df::written_content *contents = world->written_contents.all[virtual_cast(virtual_cast(item)->improvements[i])->contents[k]]; + if (contents->title != "") + { + return contents->title; + } + } + } + } + } + } + else if (item->getType() == df::item_type::TOOL && + virtual_cast(item)->hasToolUse(df::tool_uses::CONTAIN_WRITING)) + { + for (size_t i = 0; i < virtual_cast(item)->improvements.size(); i++) + { + if (virtual_cast(item)->improvements[i]->getType() == df::improvement_type::PAGES) + { + for (size_t k = 0; k < virtual_cast(virtual_cast(item)->improvements[i])->contents.size(); k++) + { + df::written_content *contents = world->written_contents.all[virtual_cast(virtual_cast(item)->improvements[i])->contents[k]]; + if (contents->title != "") + { + return contents->title; + } + } + } + else if (virtual_cast(item)->improvements[i]->getType() == df::improvement_type::WRITING) + { + for (size_t k = 0; k < virtual_cast(virtual_cast(item)->improvements[i])->contents.size(); k++) + { + df::written_content *contents = world->written_contents.all[virtual_cast(virtual_cast(item)->improvements[i])->contents[k]]; + if (contents->title != "") + { + return contents->title; + } + } + } + } + } + + return ""; +} + std::string Items::getDescription(df::item *item, int type, bool decorate) { CHECK_NULL_POINTER(item); diff --git a/plugins/stocks.cpp b/plugins/stocks.cpp index b5831d159..e44cbb431 100644 --- a/plugins/stocks.cpp +++ b/plugins/stocks.cpp @@ -30,7 +30,7 @@ #include "df/ui_advmode.h" DFHACK_PLUGIN("stocks"); -#define PLUGIN_VERSION 0.12 +#define PLUGIN_VERSION 0.13 REQUIRE_GLOBAL(world); @@ -248,7 +248,11 @@ static string get_keywords(df::item *item) static string get_item_label(df::item *item, bool trim = false) { - auto label = Items::getDescription(item, 0, false); + auto label = Items::getTitle(item); + if (label == "") + { + label = Items::getDescription(item, 0, false); + } if (trim && item->getType() == item_type::BIN) { auto pos = label.find("<#"); @@ -562,7 +566,11 @@ class StockListColumn : public ListColumn if (!ListColumn::showEntry(entry, search_tokens)) return false; - string item_name = toLower(Items::getDescription(entry->elem->entries[0], 0, false)); + string item_name = toLower(Items::getTitle(entry->elem->entries[0])); + if (item_name == "") + { + item_name = toLower(Items::getDescription(entry->elem->entries[0], 0, false)); + } if ((match_start || match_end) && raw_search.size() > item_name.size()) return false; From 876ac6c056a0a9f0ce91ea2a06fe46efa8f01953 Mon Sep 17 00:00:00 2001 From: PatrikLundell Date: Sat, 25 Jan 2020 21:46:10 +0100 Subject: [PATCH 004/547] Renamed to getBookTitle, cut down on virtual_cast --- library/include/modules/Items.h | 2 +- library/modules/Items.cpp | 56 ++++++++++++++++++--------------- plugins/stocks.cpp | 4 +-- 3 files changed, 34 insertions(+), 28 deletions(-) diff --git a/library/include/modules/Items.h b/library/include/modules/Items.h index e232bc953..838104bfe 100644 --- a/library/include/modules/Items.h +++ b/library/include/modules/Items.h @@ -162,7 +162,7 @@ DFHACK_EXPORT df::coord getPosition(df::item *item); /// Returns the title of a codex or "tool", either as the codex title or as the title of the /// first page or writing it has that has a non blank title. An empty string is returned if /// no title is found (which is the casee for everything that isn't a "book"). -DFHACK_EXPORT std::string getTitle(df::item *item); +DFHACK_EXPORT std::string getBookTitle(df::item *item); /// Returns the description string of the item. DFHACK_EXPORT std::string getDescription(df::item *item, int type = 0, bool decorate = false); diff --git a/library/modules/Items.cpp b/library/modules/Items.cpp index f102bcc78..14700f9e7 100644 --- a/library/modules/Items.cpp +++ b/library/modules/Items.cpp @@ -688,7 +688,7 @@ static void addQuality(std::string &tmp, int quality) } // It's not impossible the functionality of this operation is provided by one of the unmapped item functions. -std::string Items::getTitle(df::item *item) +std::string Items::getBookTitle(df::item *item) { CHECK_NULL_POINTER(item); @@ -696,30 +696,32 @@ std::string Items::getTitle(df::item *item) if (item->getType() == df::item_type::BOOK) { - if (virtual_cast(item)->title != "") + auto book = virtual_cast(item); + + if (book->title != "") { - return virtual_cast(item)->title; + return book->title; } else { - for (size_t i = 0; i < virtual_cast(item)->improvements.size(); i++) + for (size_t i = 0; i < book->improvements.size(); i++) { - if (virtual_cast(item)->improvements[i]->getType() == df::improvement_type::PAGES) + if (auto page = virtual_cast(book->improvements[i])) { - for (size_t k = 0; k < virtual_cast(virtual_cast(item)->improvements[i])->contents.size(); k++) + for (size_t k = 0; k < page->contents.size(); k++) { - df::written_content *contents = world->written_contents.all[virtual_cast(virtual_cast(item)->improvements[i])->contents[k]]; + df::written_content *contents = world->written_contents.all[page->contents[k]]; if (contents->title != "") { return contents->title; } } } - else if (virtual_cast(item)->improvements[i]->getType() == df::improvement_type::WRITING) + else if (auto writing = virtual_cast(book->improvements[i])) { - for (size_t k = 0; k < virtual_cast(virtual_cast(item)->improvements[i])->contents.size(); k++) + for (size_t k = 0; k < writing->contents.size(); k++) { - df::written_content *contents = world->written_contents.all[virtual_cast(virtual_cast(item)->improvements[i])->contents[k]]; + df::written_content *contents = world->written_contents.all[writing->contents[k]]; if (contents->title != "") { return contents->title; @@ -729,30 +731,34 @@ std::string Items::getTitle(df::item *item) } } } - else if (item->getType() == df::item_type::TOOL && - virtual_cast(item)->hasToolUse(df::tool_uses::CONTAIN_WRITING)) + else if (item->getType() == df::item_type::TOOL) { - for (size_t i = 0; i < virtual_cast(item)->improvements.size(); i++) + auto book = virtual_cast(item); + + if (book->hasToolUse(df::tool_uses::CONTAIN_WRITING)) { - if (virtual_cast(item)->improvements[i]->getType() == df::improvement_type::PAGES) + for (size_t i = 0; i < book->improvements.size(); i++) { - for (size_t k = 0; k < virtual_cast(virtual_cast(item)->improvements[i])->contents.size(); k++) + if (auto page = virtual_cast(book->improvements[i])) { - df::written_content *contents = world->written_contents.all[virtual_cast(virtual_cast(item)->improvements[i])->contents[k]]; - if (contents->title != "") + for (size_t k = 0; k < page->contents.size(); k++) { - return contents->title; + df::written_content *contents = world->written_contents.all[page->contents[k]]; + if (contents->title != "") + { + return contents->title; + } } } - } - else if (virtual_cast(item)->improvements[i]->getType() == df::improvement_type::WRITING) - { - for (size_t k = 0; k < virtual_cast(virtual_cast(item)->improvements[i])->contents.size(); k++) + else if (auto writing = virtual_cast(book->improvements[i])) { - df::written_content *contents = world->written_contents.all[virtual_cast(virtual_cast(item)->improvements[i])->contents[k]]; - if (contents->title != "") + for (size_t k = 0; k < writing->contents.size(); k++) { - return contents->title; + df::written_content *contents = world->written_contents.all[writing->contents[k]]; + if (contents->title != "") + { + return contents->title; + } } } } diff --git a/plugins/stocks.cpp b/plugins/stocks.cpp index e44cbb431..4439d820a 100644 --- a/plugins/stocks.cpp +++ b/plugins/stocks.cpp @@ -248,7 +248,7 @@ static string get_keywords(df::item *item) static string get_item_label(df::item *item, bool trim = false) { - auto label = Items::getTitle(item); + auto label = Items::getBookTitle(item); if (label == "") { label = Items::getDescription(item, 0, false); @@ -566,7 +566,7 @@ class StockListColumn : public ListColumn if (!ListColumn::showEntry(entry, search_tokens)) return false; - string item_name = toLower(Items::getTitle(entry->elem->entries[0])); + string item_name = toLower(Items::getBookTitle(entry->elem->entries[0])); if (item_name == "") { item_name = toLower(Items::getDescription(entry->elem->entries[0], 0, false)); From 121497a466df789cac5a6d9ecf206538c01d0cb7 Mon Sep 17 00:00:00 2001 From: PatrikLundell Date: Sun, 26 Jan 2020 11:47:47 +0100 Subject: [PATCH 005/547] Propagated getBookTitle to Lua --- docs/Lua API.rst | 6 ++++++ docs/changelog.txt | 4 ++-- library/LuaApi.cpp | 1 + library/include/modules/Items.h | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/docs/Lua API.rst b/docs/Lua API.rst index a4130096b..d7e94b92a 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -1292,6 +1292,12 @@ Items module Returns true *x,y,z* of the item, or *nil* if invalid; may be not equal to item.pos if in inventory. +* ``dfhack.items.getBookTitle(item)`` + + Returns the title of the "book" item, or an empty string if the item isn't a "book" or it doesn't + have a title. A "book" is a codex or a tool item that has page or writings improvements, such as + scrolls and quires. + * ``dfhack.items.getDescription(item, type[, decorate])`` Returns the string description of the item, as produced by the ``getItemDescription`` diff --git a/docs/changelog.txt b/docs/changelog.txt index 9e4bef7a0..36ac237be 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -38,10 +38,10 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: # Future ## Fixes -- `stocks`: fixed display of titles by using the new ``Items::`getTitle`` operation before the original one, issue 1262 +- `stocks`: fixed display of titles by using the new ``Items::getBookTitle`` operation before the original one ## API -- Added ``Items::`getTitle`` to get titles of "books". Catches titles buried in improvements, unlike getDescription. +- Added ``Items::getBookTitle`` to get titles of "books". Catches titles buried in improvements, unlike getDescription. # 0.44.12-r3 diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 7c3ef965d..1d127930e 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -1766,6 +1766,7 @@ static const LuaWrapper::FunctionReg dfhack_items_module[] = { WRAPM(Items, getContainer), WRAPM(Items, getHolderBuilding), WRAPM(Items, getHolderUnit), + WRAPM(Items, getBookTitle), WRAPM(Items, getDescription), WRAPM(Items, isCasteMaterial), WRAPM(Items, getSubtypeCount), diff --git a/library/include/modules/Items.h b/library/include/modules/Items.h index 838104bfe..33feea222 100644 --- a/library/include/modules/Items.h +++ b/library/include/modules/Items.h @@ -161,7 +161,7 @@ DFHACK_EXPORT df::coord getPosition(df::item *item); /// Returns the title of a codex or "tool", either as the codex title or as the title of the /// first page or writing it has that has a non blank title. An empty string is returned if -/// no title is found (which is the casee for everything that isn't a "book"). +/// no title is found (which is the case for everything that isn't a "book"). DFHACK_EXPORT std::string getBookTitle(df::item *item); /// Returns the description string of the item. From c859076a3fd663f8ff004dd78d212eaed20a16a4 Mon Sep 17 00:00:00 2001 From: PatrikLundell Date: Fri, 7 Feb 2020 20:49:56 +0100 Subject: [PATCH 006/547] Adjusted to int-> enum defs, fixed bug --- plugins/embark-assistant/survey.cpp | 54 ++++++++++++++++++----------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/plugins/embark-assistant/survey.cpp b/plugins/embark-assistant/survey.cpp index a2fb648f2..94e4bd832 100644 --- a/plugins/embark-assistant/survey.cpp +++ b/plugins/embark-assistant/survey.cpp @@ -1909,12 +1909,12 @@ uint8_t embark_assist::survey::translate_ew_edge(embark_assist::defs::world_tile df::world_region_type east_region_type; if (own_edge) { - effective_edge = world_data->region_details[0]->edges.biome_x[i][k]; + effective_edge = world_data->region_details[0]->edges.biome_y[i][k]; east_region_type = embark_assist::survey::region_type_of(survey_results, x, y, i, k); west_region_type = embark_assist::survey::region_type_of(survey_results, x, y, i - 1, k); } else { - effective_edge = world_data->region_details[0]->edges.biome_x[i + 1][k]; + effective_edge = world_data->region_details[0]->edges.biome_y[i + 1][k]; west_region_type = embark_assist::survey::region_type_of(survey_results, x, y, i, k); east_region_type = embark_assist::survey::region_type_of(survey_results, x, y, i + 1, k); } @@ -1995,14 +1995,18 @@ void embark_assist::survey::survey_region_sites(embark_assist::defs::site_lists break; case df::world_site_type::Monument: - if (site->subtype_info->lair_type != -1 || - site->subtype_info->is_monument == 0) { // Not Tomb, which is visible already - } - else if (site->subtype_info->lair_type == -1) { - site_list->push_back({ (uint8_t)site->rgn_min_x , (uint8_t)site->rgn_min_y, 'V' }); // Vault - } - else { + switch (site->subtype_info->monument_type) { + case df::monument_type::NONE: + case df::monument_type::TOMB: + break; // NONE shouldn't appear, and Tombs are visible already + + case df::monument_type::VAULT: + site_list->push_back({ (uint8_t)site->rgn_min_x , (uint8_t)site->rgn_min_y, 'V' }); + break; + + default: site_list->push_back({ (uint8_t)site->rgn_min_x , (uint8_t)site->rgn_min_y, 'M' }); // Any other Monument type. Pyramid? + break; } break; @@ -2011,19 +2015,27 @@ void embark_assist::survey::survey_region_sites(embark_assist::defs::site_lists break; case df::world_site_type::LairShrine: - if (site->subtype_info->lair_type == 0 || - site->subtype_info->lair_type == 1 || - site->subtype_info->lair_type == 4) { // Only Rocs seen. Mountain lair? - site_list->push_back({ (uint8_t)site->rgn_min_x , (uint8_t)site->rgn_min_y, 'l' }); // Lair - } - else if (site->subtype_info->lair_type == 2) { - site_list->push_back({ (uint8_t)site->rgn_min_x , (uint8_t)site->rgn_min_y, 'L' }); // Labyrinth - } - else if (site->subtype_info->lair_type == 3) { - site_list->push_back({ (uint8_t)site->rgn_min_x , (uint8_t)site->rgn_min_y, 'S' }); // Shrine - } - else { + switch (site->subtype_info->lair_type) { + case df::lair_type::NONE: + break; + + case df::lair_type::SIMPLE_MOUND: + case df::lair_type::SIMPLE_BURROW: + case df::lair_type::WILDERNESS_LOCATION: + site_list->push_back({ (uint8_t)site->rgn_min_x , (uint8_t)site->rgn_min_y, 'l' }); + break; + + case df::lair_type::LABYRINTH: + site_list->push_back({ (uint8_t)site->rgn_min_x , (uint8_t)site->rgn_min_y, 'L' }); + break; + + case df::lair_type::SHRINE: + site_list->push_back({ (uint8_t)site->rgn_min_x , (uint8_t)site->rgn_min_y, 'S' }); + break; + + default: site_list->push_back({ (uint8_t)site->rgn_min_x , (uint8_t)site->rgn_min_y, '?' }); // Can these exist? + break; } break; From 63a26b987de676d2cdf81974ac9a393abcfbcf8e Mon Sep 17 00:00:00 2001 From: PatrikLundell Date: Wed, 1 Apr 2020 11:16:24 +0200 Subject: [PATCH 007/547] Fix issue #1528 --- library/modules/Translation.cpp | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/library/modules/Translation.cpp b/library/modules/Translation.cpp index d836e6122..e05154b44 100644 --- a/library/modules/Translation.cpp +++ b/library/modules/Translation.cpp @@ -180,14 +180,11 @@ string Translation::TranslateName(const df::language_name * name, bool inEnglish word.append(*world->raws.language.translations[name->language]->words[name->words[1]]); addNameWord(out, word); } - if (name->words[5] >= 0) - { - word.clear(); - for (int i = 2; i <= 5; i++) - if (name->words[i] >= 0) - word.append(*world->raws.language.translations[name->language]->words[name->words[i]]); - addNameWord(out, word); - } + word.clear(); + for (int i = 2; i <= 5; i++) + if (name->words[i] >= 0) + word.append(*world->raws.language.translations[name->language]->words[name->words[i]]); + addNameWord(out, word); if (name->words[6] >= 0) { word.clear(); @@ -206,18 +203,17 @@ string Translation::TranslateName(const df::language_name * name, bool inEnglish word.append(world->raws.language.words[name->words[1]]->forms[name->parts_of_speech[1]]); addNameWord(out, word); } - if (name->words[5] >= 0) + if (name->words[2] >= 0 || name->words[3] >= 0 || name->words[4] >= 0 || name->words[5] >= 0) { if (out.length() > 0) out.append(" the"); else out.append("The"); - - for (int i = 2; i <= 5; i++) - { - if (name->words[i] >= 0) - addNameWord(out, world->raws.language.words[name->words[i]]->forms[name->parts_of_speech[i]]); - } + } + for (int i = 2; i <= 5; i++) + { + if (name->words[i] >= 0) + addNameWord(out, world->raws.language.words[name->words[i]]->forms[name->parts_of_speech[i]]); } if (name->words[6] >= 0) { From 897e78b174d62d5782317b1a6ebc0e1c0fab4749 Mon Sep 17 00:00:00 2001 From: ymber Date: Wed, 1 Apr 2020 15:09:51 +0100 Subject: [PATCH 008/547] Activate autodump in default config --- dfhack.init-example | 1 + 1 file changed, 1 insertion(+) diff --git a/dfhack.init-example b/dfhack.init-example index d8cf832c7..0fd445fff 100644 --- a/dfhack.init-example +++ b/dfhack.init-example @@ -245,6 +245,7 @@ enable \ dwarfmonitor \ mousequery \ autogems \ + autodump \ automelt \ autotrade \ buildingplan \ From a0e2abe20a1906f5449be6d931e7b53f1b4f7e21 Mon Sep 17 00:00:00 2001 From: PatrikLundell Date: Sat, 4 Apr 2020 14:00:26 +0200 Subject: [PATCH 009/547] Units update need coordination with structure identity --- library/modules/Units.cpp | 32 ++++++++++++------- .../remotefortressreader.cpp | 2 +- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index 3ac235203..07c3a7acf 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -58,6 +58,7 @@ using namespace std; #include "df/entity_position_assignment.h" #include "df/entity_raw.h" #include "df/entity_raw_flags.h" +#include "df/identity_type.h" #include "df/game_mode.h" #include "df/histfig_entity_link_positionst.h" #include "df/historical_entity.h" @@ -200,13 +201,23 @@ void Units::setNickname(df::unit *unit, std::string nick) if (auto identity = getFigureIdentity(figure)) { - auto id_hfig = df::historical_figure::find(identity->histfig_id); + df::historical_figure *id_hfig = NULL; + + switch (identity->type) { + case df::identity_type::Hiding_Curse: + case df::identity_type::Identity: + case df::identity_type::False_Identity: + break; // We want the nickname to end up in the identity + + case df::identity_type::Unk_1: // Guess, but that's how it worked in the past + case df::identity_type::Demon_Alias: + case df::identity_type::Unk_4: // Pure guess, as this is a new case, still unseen + id_hfig = df::historical_figure::find(identity->histfig_nemesis_id); + break; + } if (id_hfig) { - // Even DF doesn't do this bit, because it's apparently - // only used for demons masquerading as gods, so you - // can't ever change their nickname in-game. Translation::setNickname(&id_hfig->name, nick); } else @@ -247,7 +258,7 @@ bool Units::isHidingCurse(df::unit *unit) if (!unit->job.hunt_target) { auto identity = Units::getIdentity(unit); - if (identity && identity->unk_4c == 0) + if (identity && identity->type == df::identity_type::Hiding_Curse) return true; } @@ -722,12 +733,11 @@ double Units::getAge(df::unit *unit, bool true_age) double birth_time = unit->birth_year + unit->birth_time/year_ticks; double cur_time = *cur_year + *cur_year_tick / year_ticks; - if (!true_age && unit->curse_year >= 0) - { - if (auto identity = getIdentity(unit)) - { - if (identity->histfig_id < 0) - birth_time = identity->birth_year + identity->birth_second/year_ticks; + if (!true_age) { + if (auto identity = getIdentity(unit)) { + if (identity->birth_year != -1) { + birth_time = identity->birth_year + identity->birth_second / year_ticks; + } } } diff --git a/plugins/remotefortressreader/remotefortressreader.cpp b/plugins/remotefortressreader/remotefortressreader.cpp index f63ae5b2c..6ab401027 100644 --- a/plugins/remotefortressreader/remotefortressreader.cpp +++ b/plugins/remotefortressreader/remotefortressreader.cpp @@ -1701,7 +1701,7 @@ static command_result GetUnitListInside(color_ostream &stream, const BlockReques { if (auto identity = Units::getIdentity(unit)) { - if (identity->histfig_id < 0) + if (identity->histfig_nemesis_id < 0) birth_time = identity->birth_year * year_ticks + identity->birth_second; } } From f4dc5e827782f9e20ca62aacc472d706d656de18 Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 6 Apr 2020 19:57:20 -0400 Subject: [PATCH 010/547] Add an initial build workflow --- .github/workflows/build.yml | 43 +++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..1b8a6f715 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,43 @@ +name: Build and test + +on: [push, pull_request] + +jobs: + setup: + runs-on: ubuntu-18.04 + steps: + - name: Install dependencies + run: | + sudo apt install \ + libsdl-image1.2-dev \ + libsdl-ttf2.0-dev \ + libsdl1.2-dev \ + libxml-libxml-perl \ + libxml-libxslt-perl \ + lua5.3 \ + ninja-build \ + zlib1g-dev + sudo pip3 install --system sphinx + - name: Clone DFHack + uses: actions/checkout@v1 + - name: Set up environment + run: | + export DF_VERSION=$(sh travis/get-df-version.sh) + export DF_FOLDER="$HOME/DF/$DF_VERSION/df_linux" + - name: Download DF + run: | + sh travis/download-df.sh + - name: Git information + run: | + sh travis/git-info.sh + docs: + needs: [setup] + runs-on: ubuntu-18.04 + steps: + - name: Build docs + run: | + sphinx-build -qW -j3 . docs/html + - uses: actions/upload-artifact@master + with: + name: docs + path: docs/html From 6c9e3909fd62484d1dd75c834f49faa4baa777fd Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 6 Apr 2020 20:00:10 -0400 Subject: [PATCH 011/547] Run apt-get update first --- .github/workflows/build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1b8a6f715..1f3a66451 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,7 +8,8 @@ jobs: steps: - name: Install dependencies run: | - sudo apt install \ + sudo apt-get update + sudo apt-get install \ libsdl-image1.2-dev \ libsdl-ttf2.0-dev \ libsdl1.2-dev \ From 55988e3fc4042af34408f362772c09d9a88b21f9 Mon Sep 17 00:00:00 2001 From: PatrikLundell Date: Wed, 8 Apr 2020 08:45:40 +0200 Subject: [PATCH 012/547] adapted to updated structures, remote Using units for age --- library/modules/Units.cpp | 2 +- .../remotefortressreader/remotefortressreader.cpp | 15 +-------------- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index 07c3a7acf..fa7007574 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -210,7 +210,7 @@ void Units::setNickname(df::unit *unit, std::string nick) break; // We want the nickname to end up in the identity case df::identity_type::Unk_1: // Guess, but that's how it worked in the past - case df::identity_type::Demon_Alias: + case df::identity_type::True_Name: case df::identity_type::Unk_4: // Pure guess, as this is a new case, still unseen id_hfig = df::historical_figure::find(identity->histfig_nemesis_id); break; diff --git a/plugins/remotefortressreader/remotefortressreader.cpp b/plugins/remotefortressreader/remotefortressreader.cpp index 6ab401027..686c32211 100644 --- a/plugins/remotefortressreader/remotefortressreader.cpp +++ b/plugins/remotefortressreader/remotefortressreader.cpp @@ -1693,20 +1693,7 @@ static command_result GetUnitListInside(color_ostream &stream, const BlockReques using df::global::cur_year; using df::global::cur_year_tick; - int year_ticks = 403200; - int birth_time = unit->birth_year * year_ticks + unit->birth_time; - int cur_time = *cur_year * year_ticks + *cur_year_tick; - - if (unit->curse_year >= 0) - { - if (auto identity = Units::getIdentity(unit)) - { - if (identity->histfig_nemesis_id < 0) - birth_time = identity->birth_year * year_ticks + identity->birth_second; - } - } - - send_unit->set_age(cur_time - birth_time); + send_unit->set_age(Units::getAge(unit, false)); ConvertDfColor(Units::getProfessionColor(unit), send_unit->mutable_profession_color()); send_unit->set_flags1(unit->flags1.whole); From 125f4b129bba54448f14031ef510d6e35a4cffc2 Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 9 Apr 2020 00:02:07 -0400 Subject: [PATCH 013/547] Add ref_target attribute to primitive field references --- library/LuaTypes.cpp | 11 +++++++++++ library/LuaWrapper.cpp | 10 ++++++++-- library/include/LuaWrapper.h | 11 ++--------- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/library/LuaTypes.cpp b/library/LuaTypes.cpp index 306538f51..4e90265ce 100644 --- a/library/LuaTypes.cpp +++ b/library/LuaTypes.cpp @@ -536,6 +536,7 @@ static void field_reference(lua_State *state, const struct_field_info *field, vo case struct_field_info::PRIMITIVE: case struct_field_info::SUBSTRUCT: push_object_internal(state, field->type, ptr); + get_object_ref_header(state, -1)->field_info = field; return; case struct_field_info::POINTER: @@ -706,6 +707,16 @@ static type_identity *find_primitive_field(lua_State *state, int field, const ch */ static int meta_primitive_index(lua_State *state) { + const char *attr = lua_tostring(state, -1); + if (attr == std::string("ref_target")) { + const struct_field_info *field_info = get_object_ref_header(state, 1)->field_info; + if (field_info && field_info->extra && field_info->extra->ref_target) { + LookupInTable(state, field_info->extra->ref_target, &DFHACK_TYPEID_TABLE_TOKEN); + } else { + lua_pushnil(state); + } + return 1; + } uint8_t *ptr = get_object_addr(state, 1, 2, "read"); auto type = find_primitive_field(state, 2, "read", &ptr); if (!type) diff --git a/library/LuaWrapper.cpp b/library/LuaWrapper.cpp index 497addd5c..05c4db789 100644 --- a/library/LuaWrapper.cpp +++ b/library/LuaWrapper.cpp @@ -170,18 +170,24 @@ void LuaWrapper::push_object_ref(lua_State *state, void *ptr) // stack: [metatable] auto ref = (DFRefHeader*)lua_newuserdata(state, sizeof(DFRefHeader)); ref->ptr = ptr; + ref->field_info = NULL; lua_swap(state); lua_setmetatable(state, -2); // stack: [userdata] } -void *LuaWrapper::get_object_ref(lua_State *state, int val_index) +DFRefHeader *LuaWrapper::get_object_ref_header(lua_State *state, int val_index) { assert(!lua_islightuserdata(state, val_index)); auto ref = (DFRefHeader*)lua_touserdata(state, val_index); - return ref->ptr; + return ref; +} + +void *LuaWrapper::get_object_ref(lua_State *state, int val_index) +{ + return get_object_ref_header(state, val_index)->ptr; } /** diff --git a/library/include/LuaWrapper.h b/library/include/LuaWrapper.h index 4cbf9d34f..b23e1f912 100644 --- a/library/include/LuaWrapper.h +++ b/library/include/LuaWrapper.h @@ -126,6 +126,7 @@ namespace LuaWrapper { */ struct DFRefHeader { void *ptr; + const struct_field_info *field_info; }; /** @@ -133,15 +134,7 @@ namespace LuaWrapper { */ void push_object_ref(lua_State *state, void *ptr); DFHACK_EXPORT void *get_object_ref(lua_State *state, int val_index); - - /* - * The system might be extended to carry some simple - * objects inline inside the reference buffer. - */ - inline bool is_self_contained(DFRefHeader *ptr) { - void **pp = &ptr->ptr; - return **(void****)pp == (pp + 1); - } + DFHACK_EXPORT DFRefHeader *get_object_ref_header(lua_State *state, int val_index); /** * Report an error while accessing a field (index = field name). From d72c3956608aa00afcc1a3115df3b6f664333545 Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 10 Apr 2020 23:33:06 -0400 Subject: [PATCH 014/547] Merge into one job --- .github/workflows/build.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1f3a66451..96a623457 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,7 +3,7 @@ name: Build and test on: [push, pull_request] jobs: - setup: + main: runs-on: ubuntu-18.04 steps: - name: Install dependencies @@ -31,10 +31,6 @@ jobs: - name: Git information run: | sh travis/git-info.sh - docs: - needs: [setup] - runs-on: ubuntu-18.04 - steps: - name: Build docs run: | sphinx-build -qW -j3 . docs/html From 385aa0877d2e1c72319e93160739877b09213c0e Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 10 Apr 2020 23:38:32 -0400 Subject: [PATCH 015/547] Checkout submodules too --- .github/workflows/build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 96a623457..10a653932 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,6 +21,8 @@ jobs: sudo pip3 install --system sphinx - name: Clone DFHack uses: actions/checkout@v1 + with: + submodules: true - name: Set up environment run: | export DF_VERSION=$(sh travis/get-df-version.sh) From daad14ee66dd46f19e81d860992fd56c14f4c09b Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 10 Apr 2020 23:46:19 -0400 Subject: [PATCH 016/547] Implement linting checks --- .github/workflows/build.yml | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 10a653932..4db414bd1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,7 +3,7 @@ name: Build and test on: [push, pull_request] jobs: - main: + build: runs-on: ubuntu-18.04 steps: - name: Install dependencies @@ -36,7 +36,32 @@ jobs: - name: Build docs run: | sphinx-build -qW -j3 . docs/html - - uses: actions/upload-artifact@master + - name: Upload docs + uses: actions/upload-artifact@master with: name: docs path: docs/html + lint: + runs-on: ubuntu-18.04 + steps: + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install \ + lua5.3 \ + ruby + - name: Check whitespace + run: | + python travis/lint.py + - name: Check Authors.rst + run: | + python travis/authors-rst.py + - name: Check for missing documentation + run: | + python travis/script-docs.py + - name: Check Lua syntax + run: | + python travis/script-syntax.py --ext=lua --cmd="luac5.3 -p" + - name: Check Ruby syntax + run: | + python travis/script-syntax.py --ext=rb --cmd="ruby -c" From 9a7c07b42bc32827d21cbc1ed2080eb0d56a4811 Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 10 Apr 2020 23:47:47 -0400 Subject: [PATCH 017/547] Clone the repo --- .github/workflows/build.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4db414bd1..dad202209 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -50,6 +50,10 @@ jobs: sudo apt-get install \ lua5.3 \ ruby + - name: Clone DFHack + uses: actions/checkout@v1 + with: + submodules: true - name: Check whitespace run: | python travis/lint.py From 1ebad37c2cb33bf97c6f9ec7c8fec08a64333f48 Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 10 Apr 2020 23:53:12 -0400 Subject: [PATCH 018/547] Attempt to fix DF installation --- .github/workflows/build.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dad202209..6594dcb85 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,10 +25,11 @@ jobs: submodules: true - name: Set up environment run: | - export DF_VERSION=$(sh travis/get-df-version.sh) - export DF_FOLDER="$HOME/DF/$DF_VERSION/df_linux" + echo 'export DF_VERSION=$(sh travis/get-df-version.sh)' >> "$HOME/.dfhackrc" + echo 'export DF_FOLDER="$HOME/DF/$DF_VERSION/df_linux"' >> "$HOME/.dfhackrc" - name: Download DF run: | + source "$HOME/.dfhackrc" sh travis/download-df.sh - name: Git information run: | From 0d4572e40a41f3ca152473762c1653c1a93a57e1 Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 10 Apr 2020 23:56:28 -0400 Subject: [PATCH 019/547] Build DFHack --- .github/workflows/build.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6594dcb85..5b28ab101 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -42,6 +42,18 @@ jobs: with: name: docs path: docs/html + - name: Build DFHack + run: | + source "$HOME/.dfhackrc" + mkdir build-ci + cd build-ci + cmake .. \ + -G Ninja \ + -DDFHACK_BUILD_ARCH=64 \ + -DBUILD_DOCS:BOOL=ON \ + -DBUILD_TESTS:BOOL=ON \ + -DCMAKE_INSTALL_PREFIX="$DF_FOLDER" + ninja install lint: runs-on: ubuntu-18.04 steps: From d2ba91e2cd3caf61d95896d835a101e0b3d05c99 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 11 Apr 2020 00:10:28 -0400 Subject: [PATCH 020/547] Run tests --- .github/workflows/build.yml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5b28ab101..aa179eb91 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -38,7 +38,7 @@ jobs: run: | sphinx-build -qW -j3 . docs/html - name: Upload docs - uses: actions/upload-artifact@master + uses: actions/upload-artifact@v1 with: name: docs path: docs/html @@ -54,6 +54,20 @@ jobs: -DBUILD_TESTS:BOOL=ON \ -DCMAKE_INSTALL_PREFIX="$DF_FOLDER" ninja install + - name: Run tests + run: | + cd .. + mv "$DF_FOLDER"/dfhack.init-example "$DF_FOLDER"/dfhack.init + python travis/run-tests.py --headless --keep-status "$DF_FOLDER" + python travis/check-rpc.py "$DF_FOLDER/dfhack-rpc.txt" + mkdir -p artifacts + cp "$DF_FOLDER/test_status.json" "$DF_FOLDER"/*.log artifacts + - name: Upload test artifacts + uses: actions/upload-artifact@v1 + if: success() || failure() + with: + name: test-artifacts + path: artifacts lint: runs-on: ubuntu-18.04 steps: From 19f84603cd56dce355020944e49f92e8c737f015 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 11 Apr 2020 00:18:01 -0400 Subject: [PATCH 021/547] Fix test environment --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index aa179eb91..b5283258f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -56,6 +56,7 @@ jobs: ninja install - name: Run tests run: | + source "$HOME/.dfhackrc" cd .. mv "$DF_FOLDER"/dfhack.init-example "$DF_FOLDER"/dfhack.init python travis/run-tests.py --headless --keep-status "$DF_FOLDER" From 35dbf6cf5f46216e87ef902f9dfeb30c9ecd751c Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 11 Apr 2020 00:31:15 -0400 Subject: [PATCH 022/547] Avoid changing working directory --- .github/workflows/build.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b5283258f..1b4ac36b7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -45,19 +45,18 @@ jobs: - name: Build DFHack run: | source "$HOME/.dfhackrc" - mkdir build-ci - cd build-ci - cmake .. \ + cmake \ + -S . \ + -B build-ci \ -G Ninja \ -DDFHACK_BUILD_ARCH=64 \ -DBUILD_DOCS:BOOL=ON \ -DBUILD_TESTS:BOOL=ON \ -DCMAKE_INSTALL_PREFIX="$DF_FOLDER" - ninja install + ninja -C build-ci install - name: Run tests run: | source "$HOME/.dfhackrc" - cd .. mv "$DF_FOLDER"/dfhack.init-example "$DF_FOLDER"/dfhack.init python travis/run-tests.py --headless --keep-status "$DF_FOLDER" python travis/check-rpc.py "$DF_FOLDER/dfhack-rpc.txt" From ab81b1f06d9ac86adbccd6c957d439b67f52dee0 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 11 Apr 2020 00:40:25 -0400 Subject: [PATCH 023/547] Avoid running travis commands when starting DF --- .github/workflows/build.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1b4ac36b7..afa907958 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,11 +25,11 @@ jobs: submodules: true - name: Set up environment run: | - echo 'export DF_VERSION=$(sh travis/get-df-version.sh)' >> "$HOME/.dfhackrc" - echo 'export DF_FOLDER="$HOME/DF/$DF_VERSION/df_linux"' >> "$HOME/.dfhackrc" + echo export DF_VERSION="$(sh travis/get-df-version.sh)" >> "$HOME/.df-env" + echo export DF_FOLDER="$HOME/DF/$DF_VERSION/df_linux" >> "$HOME/.df-env" - name: Download DF run: | - source "$HOME/.dfhackrc" + source "$HOME/.df-env" sh travis/download-df.sh - name: Git information run: | @@ -44,7 +44,7 @@ jobs: path: docs/html - name: Build DFHack run: | - source "$HOME/.dfhackrc" + source "$HOME/.df-env" cmake \ -S . \ -B build-ci \ @@ -56,7 +56,7 @@ jobs: ninja -C build-ci install - name: Run tests run: | - source "$HOME/.dfhackrc" + source "$HOME/.df-env" mv "$DF_FOLDER"/dfhack.init-example "$DF_FOLDER"/dfhack.init python travis/run-tests.py --headless --keep-status "$DF_FOLDER" python travis/check-rpc.py "$DF_FOLDER/dfhack-rpc.txt" From 023575071a165d7541d2956287421bafbbd1c351 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 11 Apr 2020 00:49:16 -0400 Subject: [PATCH 024/547] Run tests with TERM=dumb --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index afa907958..2d158dc7c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -57,6 +57,7 @@ jobs: - name: Run tests run: | source "$HOME/.df-env" + export TERM=dumb mv "$DF_FOLDER"/dfhack.init-example "$DF_FOLDER"/dfhack.init python travis/run-tests.py --headless --keep-status "$DF_FOLDER" python travis/check-rpc.py "$DF_FOLDER/dfhack-rpc.txt" From 8b7989e93f69021f7d4b37aefb6b6c907e87995b Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 11 Apr 2020 01:17:43 -0400 Subject: [PATCH 025/547] Try with TERM=xterm to get test output logged to console It's currently going to stderr.log only --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2d158dc7c..0c5c857f5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -57,7 +57,7 @@ jobs: - name: Run tests run: | source "$HOME/.df-env" - export TERM=dumb + export TERM=xterm mv "$DF_FOLDER"/dfhack.init-example "$DF_FOLDER"/dfhack.init python travis/run-tests.py --headless --keep-status "$DF_FOLDER" python travis/check-rpc.py "$DF_FOLDER/dfhack-rpc.txt" From 9e9e71cad7f43a224c069adf2cd327e48fa3f175 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 11 Apr 2020 01:31:41 -0400 Subject: [PATCH 026/547] Fix spacing in error message --- conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf.py b/conf.py index bfd69d828..2f47d5644 100644 --- a/conf.py +++ b/conf.py @@ -174,7 +174,7 @@ def all_keybinds_documented(): plugin_binds = set(re.findall(':dfhack-keybind:`(.*?)`', f.read())) undocumented_binds = configured_binds - script_commands - plugin_binds if undocumented_binds: - raise ValueError('The following DFHack commands have undocumented' + raise ValueError('The following DFHack commands have undocumented ' 'keybindings: {}'.format(sorted(undocumented_binds))) From 148b5495cc589d2a4ddd6c0be67ae7f3dea3ad92 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 11 Apr 2020 01:32:05 -0400 Subject: [PATCH 027/547] Fall back to dfout_C if set before stderr.log --- library/Console-posix.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/library/Console-posix.cpp b/library/Console-posix.cpp index 6fb1cbff3..76b5a8cb2 100644 --- a/library/Console-posix.cpp +++ b/library/Console-posix.cpp @@ -903,7 +903,10 @@ void Console::add_text(color_value color, const std::string &text) if (inited) d->print_text(color, text); else - fwrite(text.data(), 1, text.size(), stderr); + { + FILE *out = d->dfout_C ? d->dfout_C : stderr; + fwrite(text.data(), 1, text.size(), out); + } } int Console::get_columns(void) From 44be99388e487998661a851ffdd72cb7fd4bb3f0 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 11 Apr 2020 01:43:06 -0400 Subject: [PATCH 028/547] Revert "Fall back to dfout_C if set before stderr.log" Makes stuff go to stdout.log instead This reverts commit 148b5495cc589d2a4ddd6c0be67ae7f3dea3ad92. --- library/Console-posix.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/library/Console-posix.cpp b/library/Console-posix.cpp index 76b5a8cb2..6fb1cbff3 100644 --- a/library/Console-posix.cpp +++ b/library/Console-posix.cpp @@ -903,10 +903,7 @@ void Console::add_text(color_value color, const std::string &text) if (inited) d->print_text(color, text); else - { - FILE *out = d->dfout_C ? d->dfout_C : stderr; - fwrite(text.data(), 1, text.size(), out); - } + fwrite(text.data(), 1, text.size(), stderr); } int Console::get_columns(void) From cdc82bd7dbfb85f9294adcb62cb55da26b4bb29f Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 11 Apr 2020 01:49:53 -0400 Subject: [PATCH 029/547] Run tests within `script` --- .github/workflows/build.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0c5c857f5..bc8101b8f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -57,9 +57,8 @@ jobs: - name: Run tests run: | source "$HOME/.df-env" - export TERM=xterm mv "$DF_FOLDER"/dfhack.init-example "$DF_FOLDER"/dfhack.init - python travis/run-tests.py --headless --keep-status "$DF_FOLDER" + script -qe -c "python travis/run-tests.py --headless --keep-status \"$DF_FOLDER\"" python travis/check-rpc.py "$DF_FOLDER/dfhack-rpc.txt" mkdir -p artifacts cp "$DF_FOLDER/test_status.json" "$DF_FOLDER"/*.log artifacts From 6bbda95dd4fc3519fd65c773849d4bdada3352f3 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 11 Apr 2020 01:58:06 -0400 Subject: [PATCH 030/547] Add TERM=dumb back --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bc8101b8f..bb1791a67 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -57,6 +57,7 @@ jobs: - name: Run tests run: | source "$HOME/.df-env" + export TERM=dumb mv "$DF_FOLDER"/dfhack.init-example "$DF_FOLDER"/dfhack.init script -qe -c "python travis/run-tests.py --headless --keep-status \"$DF_FOLDER\"" python travis/check-rpc.py "$DF_FOLDER/dfhack-rpc.txt" From b3db62742c0ca150aa442bda7e81b5a99db35fb0 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 11 Apr 2020 02:15:57 -0400 Subject: [PATCH 031/547] Rename workflow to match Travis, update badge --- .github/workflows/build.yml | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bb1791a67..deab07958 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,4 @@ -name: Build and test +name: Build on: [push, pull_request] diff --git a/README.md b/README.md index fd95e1e5e..a0499a333 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # DFHack Readme -[![Build Status](https://travis-ci.org/DFHack/dfhack.svg?branch=develop)](https://travis-ci.org/DFHack/dfhack) +[![Build Status](https://github.com/DFHack/dfhack/workflows/Build/badge.svg)](https://github.com/DFHack/dfhack/actions?query=workflow%3ABuild) [![Documentation Status](https://readthedocs.org/projects/dfhack/badge)](https://dfhack.readthedocs.org) [![License](https://img.shields.io/badge/license-ZLib-blue.svg)](https://en.wikipedia.org/wiki/Zlib_License) From dbdd98829f46f6e9e98196a94dbfed20844bded8 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 11 Apr 2020 02:22:12 -0400 Subject: [PATCH 032/547] Add check for PR base branch --- .github/workflows/build.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index deab07958..a585b6e80 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -97,3 +97,13 @@ jobs: - name: Check Ruby syntax run: | python travis/script-syntax.py --ext=rb --cmd="ruby -c" + check-pr: + runs-on: ubuntu-latest + steps: + - name: Check that PR is based on develop branch + if: github.event_name == 'pull_request' + env: + BASE_BRANCH: ${{ github.base_ref }} + run: | + echo "PR base branch: $BASE_BRANCH" + test "$BASE_BRANCH" = develop From dc598d501a799e043b6d5c04ab8e075091d58542 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 11 Apr 2020 02:24:40 -0400 Subject: [PATCH 033/547] Limit entire check-pr job to PRs only --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a585b6e80..f737a1539 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -99,9 +99,9 @@ jobs: python travis/script-syntax.py --ext=rb --cmd="ruby -c" check-pr: runs-on: ubuntu-latest + if: github.event_name == 'pull_request' steps: - name: Check that PR is based on develop branch - if: github.event_name == 'pull_request' env: BASE_BRANCH: ${{ github.base_ref }} run: | From dbff3355ba92d2ba944b5093ec0e781cec9719c8 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 11 Apr 2020 02:32:07 -0400 Subject: [PATCH 034/547] Remove .travis.yml --- .travis.yml | 64 ----------------------------------------------------- 1 file changed, 64 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index c096552bc..000000000 --- a/.travis.yml +++ /dev/null @@ -1,64 +0,0 @@ -sudo: false -language: cpp -cache: - pip: true - directories: - - $HOME/DF-travis - - $HOME/lua53 -addons: - apt: - packages: &default_packages - - libsdl-image1.2-dev - - libsdl-ttf2.0-dev - - libsdl1.2-dev - - libxml-libxml-perl - - libxml-libxslt-perl - - ninja-build - - zlib1g-dev -matrix: - include: - - env: GCC_VERSION=4.8 - addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - *default_packages - - gcc-4.8 - - g++-4.8 -before_install: -- export DF_VERSION=$(sh travis/get-df-version.sh) -- export DF_FOLDER="$HOME/DF-travis/$DF_VERSION/df_linux" -- pip install --user "sphinx==1.4" "requests[security]" -- sh travis/build-lua.sh -- sh travis/download-df.sh -script: -- export PATH="$PATH:$HOME/lua53/bin" -- git tag tmp-travis-build -- sh travis/git-info.sh -- sphinx-build -qW -j3 . docs/html -- python travis/pr-check-base.py -- python travis/lint.py -- python travis/authors-rst.py -- python travis/script-docs.py -- python travis/script-syntax.py --ext=lua --cmd="luac5.3 -p" -- python travis/script-syntax.py --ext=rb --cmd="ruby -c" -- mkdir build-travis -- cd build-travis -- cmake .. -G Ninja -DCMAKE_C_COMPILER=gcc-$GCC_VERSION -DCMAKE_CXX_COMPILER=g++-$GCC_VERSION -DDFHACK_BUILD_ARCH=64 -DBUILD_DOCS:BOOL=ON -DBUILD_TESTS:BOOL=ON -DCMAKE_INSTALL_PREFIX="$DF_FOLDER" -- ninja -j3 install -- mv "$DF_FOLDER"/dfhack.init-example "$DF_FOLDER"/dfhack.init -- cd .. -- python travis/run-tests.py --headless --keep-status "$DF_FOLDER" -- python travis/check-rpc.py "$DF_FOLDER/dfhack-rpc.txt" -- cat "$DF_FOLDER/test_status.json" -before_cache: -- cat "$DF_FOLDER/stderr.log" -- rm -rf "$DF_FOLDER" -notifications: - email: false - irc: - channels: - - "chat.freenode.net#dfhack" - on_success: change - on_failure: always From ba12e0c6d4446248683f0fa6ae3fc8709898e34d Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 11 Apr 2020 02:33:50 -0400 Subject: [PATCH 035/547] Remove obsolete travis scripts --- .github/workflows/build.yml | 3 --- travis/build-lua.sh | 54 ------------------------------------- travis/git-info.sh | 2 -- travis/pr-check-base.py | 18 ------------- 4 files changed, 77 deletions(-) delete mode 100644 travis/build-lua.sh delete mode 100644 travis/git-info.sh delete mode 100644 travis/pr-check-base.py diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f737a1539..17af62cb1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,9 +31,6 @@ jobs: run: | source "$HOME/.df-env" sh travis/download-df.sh - - name: Git information - run: | - sh travis/git-info.sh - name: Build docs run: | sphinx-build -qW -j3 . docs/html diff --git a/travis/build-lua.sh b/travis/build-lua.sh deleted file mode 100644 index e29d7ce87..000000000 --- a/travis/build-lua.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/sh - -set -e - -LUA_ROOT="$HOME/lua53" -LUA_URL="http://www.lua.org/ftp/lua-5.3.3.tar.gz" -LUA_TAR=$(basename "$LUA_URL") -LUA_DIR="$LUA_ROOT/${LUA_TAR%.tar.*}" -LUA_SHA1="a0341bc3d1415b814cc738b2ec01ae56045d64ef" - -echo LUA_ROOT $LUA_ROOT -echo LUA_TAR $LUA_TAR -echo LUA_DIR $LUA_DIR - -sha1() { - python -c 'import hashlib, sys; print(hashlib.sha1(open(sys.argv[1],"rb").read()).hexdigest())' "$1" -} - -download() { - echo "Downloading $LUA_URL" - wget -O "$LUA_ROOT/$LUA_TAR" "$LUA_URL" - tar xvf "$LUA_ROOT/$LUA_TAR" -} - -build() { - cd "$LUA_DIR/src" - make generic -} - -main() { - mkdir -p "$LUA_ROOT" - cd "$LUA_ROOT" - mkdir -p bin - - if [ "$(sha1 "$LUA_ROOT/$LUA_TAR" 2>/dev/null)" != "$LUA_SHA1" ]; then - download - build - else - echo "Already downloaded" - - if [ -x "$LUA_DIR/src/luac" ]; then - echo "Already built" - else - build - fi - fi - - echo "Linking" - ln -sf "$LUA_DIR/src/lua" "$LUA_ROOT/bin/lua5.3" - ln -sf "$LUA_DIR/src/luac" "$LUA_ROOT/bin/luac5.3" - echo "Done" -} - -main diff --git a/travis/git-info.sh b/travis/git-info.sh deleted file mode 100644 index 333d13bc1..000000000 --- a/travis/git-info.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -git log --pretty="commit %h (parents: %p): %s" -1 diff --git a/travis/pr-check-base.py b/travis/pr-check-base.py deleted file mode 100644 index 47605b051..000000000 --- a/travis/pr-check-base.py +++ /dev/null @@ -1,18 +0,0 @@ -import os, sys -repo = os.environ.get('TRAVIS_REPO_SLUG', 'dfhack/dfhack').lower() -branch = os.environ.get('TRAVIS_BRANCH', 'master') -try: - pr_id = int(os.environ.get('TRAVIS_PULL_REQUEST', 'false')) -except ValueError: - print('Not a pull request') - sys.exit(0) -print('Pull request %s#%i' % (repo, pr_id)) -if repo != 'dfhack/dfhack': - print('Not in dfhack/dfhack') - sys.exit(0) -if branch != 'develop': - print('Not based on develop branch') - sys.exit(1) -else: - print('Ok') - sys.exit(0) From 362e49c0bc9c0c5cde28e1e9ff3a0ae427e27dd8 Mon Sep 17 00:00:00 2001 From: Nilsolm Date: Sun, 12 Apr 2020 11:02:26 +0200 Subject: [PATCH 036/547] autogems: check bin content in linked stockpiles --- plugins/autogems.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/plugins/autogems.cpp b/plugins/autogems.cpp index 4121b562f..f22d20d30 100644 --- a/plugins/autogems.cpp +++ b/plugins/autogems.cpp @@ -167,6 +167,16 @@ void create_jobs() { stockpiled.insert(item->id); piled[item->getMaterialIndex()] += 1; } + else if (item->flags.bits.container) { + std::vector binneditems; + Items::getContainedItems(item, &binneditems); + for (df::item *it : binneditems) { + if (valid_gem(it)) { + stockpiled.insert(it->id); + piled[it->getMaterialIndex()] += 1; + } + } + } } // Decrement current jobs from all linked workshops, not just this one. From f7630a52707b9d8e5e4d0ae82ed98244c71a7b8b Mon Sep 17 00:00:00 2001 From: Nilsolm Date: Sun, 12 Apr 2020 11:03:28 +0200 Subject: [PATCH 037/547] update changelog --- docs/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog.txt b/docs/changelog.txt index d2404c951..ba75f09fb 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: # Future ## Fixes +- `autogems`: fixed an issue with binned gems being ignored in linked stockpiles - `tweak` embark-profile-name: fixed handling of the native shift+space key ## Misc Improvements From c97adb91735becad845d8af630e62c19c8e94d03 Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 15 Apr 2020 01:09:16 -0400 Subject: [PATCH 038/547] Update changelog (#1528, #1530) --- docs/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog.txt b/docs/changelog.txt index ba75f09fb..11734d9f7 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: # Future ## Fixes +- Fixed translation of certain types of in-game names - `autogems`: fixed an issue with binned gems being ignored in linked stockpiles - `tweak` embark-profile-name: fixed handling of the native shift+space key From 79387647d39a326fa3c82e620e7c435b4f7c2002 Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 15 Apr 2020 01:09:29 -0400 Subject: [PATCH 039/547] Update scripts --- scripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts b/scripts index 8618cd0b0..b3ce8fa65 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 8618cd0b0a17935fe07f329b249726cda61f5bdf +Subproject commit b3ce8fa650f86c7a1dbd5329d72c3d73dd76d05d From 36df6eac8b649f7787c54d95c93b42280a7f6d81 Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 15 Apr 2020 01:15:09 -0400 Subject: [PATCH 040/547] Restrict status badge to push events only --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a0499a333..e4bfefb38 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # DFHack Readme -[![Build Status](https://github.com/DFHack/dfhack/workflows/Build/badge.svg)](https://github.com/DFHack/dfhack/actions?query=workflow%3ABuild) +[![Build Status](https://github.com/DFHack/dfhack/workflows/Build/badge.svg?event=push)](https://github.com/DFHack/dfhack/actions?query=workflow%3ABuild) [![Documentation Status](https://readthedocs.org/projects/dfhack/badge)](https://dfhack.readthedocs.org) [![License](https://img.shields.io/badge/license-ZLib-blue.svg)](https://en.wikipedia.org/wiki/Zlib_License) From f4f2aa0d5ef0814adce64af3f8339207e9c97aef Mon Sep 17 00:00:00 2001 From: PatrikLundell Date: Wed, 15 Apr 2020 10:18:37 +0200 Subject: [PATCH 041/547] removed underscores, adapted to structure (re)naming --- library/modules/Items.cpp | 2 +- library/modules/Job.cpp | 4 ++-- library/modules/Units.cpp | 8 ++++---- plugins/orders.cpp | 6 +++--- plugins/stocks.cpp | 10 +++++----- plugins/workflow.cpp | 4 ++-- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/library/modules/Items.cpp b/library/modules/Items.cpp index 4939aa9dd..4b6010718 100644 --- a/library/modules/Items.cpp +++ b/library/modules/Items.cpp @@ -658,7 +658,7 @@ df::coord Items::getPosition(df::item *item) switch (ref->type) { case specific_ref_type::VERMIN_ESCAPED_PET: - return ref->data.VERMIN_ESCAPED_PET->pos; + return ref->data.vermin->pos; default: break; diff --git a/library/modules/Job.cpp b/library/modules/Job.cpp index d0487941f..0aa01af95 100644 --- a/library/modules/Job.cpp +++ b/library/modules/Job.cpp @@ -311,7 +311,7 @@ void DFHack::Job::disconnectJobItem(df::job *job, df::job_item_ref *ref) { auto ref = item->specific_refs[refIndex]; if (ref->type == df::specific_ref_type::JOB) { - if (ref->data.JOB == job) { + if (ref->data.job == job) { vector_erase_at(item->specific_refs, refIndex); delete ref; } else { @@ -579,7 +579,7 @@ bool DFHack::Job::attachJobItem(df::job *job, df::item *item, auto item_link = new df::specific_ref(); item_link->type = specific_ref_type::JOB; - item_link->data.JOB = job; + item_link->data.job = job; item->specific_refs.push_back(item_link); auto job_link = new df::job_item_ref(); diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index fa7007574..313d6ee9f 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -204,13 +204,13 @@ void Units::setNickname(df::unit *unit, std::string nick) df::historical_figure *id_hfig = NULL; switch (identity->type) { - case df::identity_type::Hiding_Curse: + case df::identity_type::HidingCurse: case df::identity_type::Identity: - case df::identity_type::False_Identity: + case df::identity_type::FalseIdentity: break; // We want the nickname to end up in the identity case df::identity_type::Unk_1: // Guess, but that's how it worked in the past - case df::identity_type::True_Name: + case df::identity_type::TrueName: case df::identity_type::Unk_4: // Pure guess, as this is a new case, still unseen id_hfig = df::historical_figure::find(identity->histfig_nemesis_id); break; @@ -258,7 +258,7 @@ bool Units::isHidingCurse(df::unit *unit) if (!unit->job.hunt_target) { auto identity = Units::getIdentity(unit); - if (identity && identity->type == df::identity_type::Hiding_Curse) + if (identity && identity->type == df::identity_type::HidingCurse) return true; } diff --git a/plugins/orders.cpp b/plugins/orders.cpp index f600b0cd0..045c07a1f 100644 --- a/plugins/orders.cpp +++ b/plugins/orders.cpp @@ -798,13 +798,13 @@ static command_result orders_clear_command(color_ostream & out) { delete condition; } - if (order->anon_1) + if (order->items) { - for (auto anon_1 : *order->anon_1) + for (auto anon_1 : *order->items) { delete anon_1; } - delete order->anon_1; + delete order->items; } delete order; diff --git a/plugins/stocks.cpp b/plugins/stocks.cpp index d9ec97c0d..af49dcb2a 100644 --- a/plugins/stocks.cpp +++ b/plugins/stocks.cpp @@ -179,8 +179,8 @@ static map items_in_cages; static df::job *get_item_job(df::item *item) { auto ref = Items::getSpecificRef(item, specific_ref_type::JOB); - if (ref && ref->data.JOB) - return ref->data.JOB; + if (ref && ref->data.job) + return ref->data.job; return nullptr; } @@ -1008,12 +1008,12 @@ private: if (item->flags.bits.in_job) { auto ref = Items::getSpecificRef(item, specific_ref_type::JOB); - if (ref && ref->data.JOB) + if (ref && ref->data.job) { - if (ref->data.JOB->job_type == job_type::Eat || ref->data.JOB->job_type == job_type::Drink) + if (ref->data.job->job_type == job_type::Eat || ref->data.job->job_type == job_type::Drink) return pos; - auto unit = Job::getWorker(ref->data.JOB); + auto unit = Job::getWorker(ref->data.job); if (unit) return unit->pos; } diff --git a/plugins/workflow.cpp b/plugins/workflow.cpp index 3e31d14ab..600a8bef1 100644 --- a/plugins/workflow.cpp +++ b/plugins/workflow.cpp @@ -1151,10 +1151,10 @@ static bool itemInRealJob(df::item *item) return false; auto ref = Items::getSpecificRef(item, specific_ref_type::JOB); - if (!ref || !ref->data.JOB) + if (!ref || !ref->data.job) return true; - return ENUM_ATTR(job_type, type, ref->data.JOB->job_type) + return ENUM_ATTR(job_type, type, ref->data.job->job_type) != job_type_class::Hauling; } From b5c6fd26e2632286a8d9dc8a4fb3cdea33f10be6 Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 15 Apr 2020 17:33:58 -0400 Subject: [PATCH 042/547] Update changelog (#1531) --- docs/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog.txt b/docs/changelog.txt index 11734d9f7..47f891cb5 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -45,6 +45,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - `tweak` embark-profile-name: fixed handling of the native shift+space key ## Misc Improvements +- ``dfhack.init-example``: enabled `autodump` - `manipulator`: added intrigue to displayed skills - `search`: added support for the fortress mode justice screen From 253b15aeb98581b7cc61013be88db464f3c5a3d7 Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Wed, 15 Apr 2020 19:03:40 -0500 Subject: [PATCH 043/547] update structures --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index f185d0b22..96a8df43d 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit f185d0b22acb1daf36b3a017f7a30b48994ee42c +Subproject commit 96a8df43d1c4508800c209701ce39ca972579e3b From 8427f518c941f8e5734e98f2ff56648522f1281b Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Wed, 15 Apr 2020 20:05:15 -0500 Subject: [PATCH 044/547] match capitalization changes I made to df-structures in specific_ref --- library/modules/Items.cpp | 2 +- library/modules/Job.cpp | 4 ++-- plugins/orders.cpp | 8 ++++---- plugins/stocks.cpp | 10 +++++----- plugins/workflow.cpp | 4 ++-- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/library/modules/Items.cpp b/library/modules/Items.cpp index 4939aa9dd..4b6010718 100644 --- a/library/modules/Items.cpp +++ b/library/modules/Items.cpp @@ -658,7 +658,7 @@ df::coord Items::getPosition(df::item *item) switch (ref->type) { case specific_ref_type::VERMIN_ESCAPED_PET: - return ref->data.VERMIN_ESCAPED_PET->pos; + return ref->data.vermin->pos; default: break; diff --git a/library/modules/Job.cpp b/library/modules/Job.cpp index d0487941f..0aa01af95 100644 --- a/library/modules/Job.cpp +++ b/library/modules/Job.cpp @@ -311,7 +311,7 @@ void DFHack::Job::disconnectJobItem(df::job *job, df::job_item_ref *ref) { auto ref = item->specific_refs[refIndex]; if (ref->type == df::specific_ref_type::JOB) { - if (ref->data.JOB == job) { + if (ref->data.job == job) { vector_erase_at(item->specific_refs, refIndex); delete ref; } else { @@ -579,7 +579,7 @@ bool DFHack::Job::attachJobItem(df::job *job, df::item *item, auto item_link = new df::specific_ref(); item_link->type = specific_ref_type::JOB; - item_link->data.JOB = job; + item_link->data.job = job; item->specific_refs.push_back(item_link); auto job_link = new df::job_item_ref(); diff --git a/plugins/orders.cpp b/plugins/orders.cpp index f600b0cd0..6c6888c0e 100644 --- a/plugins/orders.cpp +++ b/plugins/orders.cpp @@ -798,13 +798,13 @@ static command_result orders_clear_command(color_ostream & out) { delete condition; } - if (order->anon_1) + if (order->items) { - for (auto anon_1 : *order->anon_1) + for (auto item : *order->items) { - delete anon_1; + delete item; } - delete order->anon_1; + delete order->items; } delete order; diff --git a/plugins/stocks.cpp b/plugins/stocks.cpp index d9ec97c0d..af49dcb2a 100644 --- a/plugins/stocks.cpp +++ b/plugins/stocks.cpp @@ -179,8 +179,8 @@ static map items_in_cages; static df::job *get_item_job(df::item *item) { auto ref = Items::getSpecificRef(item, specific_ref_type::JOB); - if (ref && ref->data.JOB) - return ref->data.JOB; + if (ref && ref->data.job) + return ref->data.job; return nullptr; } @@ -1008,12 +1008,12 @@ private: if (item->flags.bits.in_job) { auto ref = Items::getSpecificRef(item, specific_ref_type::JOB); - if (ref && ref->data.JOB) + if (ref && ref->data.job) { - if (ref->data.JOB->job_type == job_type::Eat || ref->data.JOB->job_type == job_type::Drink) + if (ref->data.job->job_type == job_type::Eat || ref->data.job->job_type == job_type::Drink) return pos; - auto unit = Job::getWorker(ref->data.JOB); + auto unit = Job::getWorker(ref->data.job); if (unit) return unit->pos; } diff --git a/plugins/workflow.cpp b/plugins/workflow.cpp index 3e31d14ab..600a8bef1 100644 --- a/plugins/workflow.cpp +++ b/plugins/workflow.cpp @@ -1151,10 +1151,10 @@ static bool itemInRealJob(df::item *item) return false; auto ref = Items::getSpecificRef(item, specific_ref_type::JOB); - if (!ref || !ref->data.JOB) + if (!ref || !ref->data.job) return true; - return ENUM_ATTR(job_type, type, ref->data.JOB->job_type) + return ENUM_ATTR(job_type, type, ref->data.job->job_type) != job_type_class::Hauling; } From c8ff8d0d8efa7a7c69658a30d18255a73c2955c8 Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Fri, 17 Apr 2020 11:52:16 -0500 Subject: [PATCH 045/547] update scripts and structures --- library/xml | 2 +- scripts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/xml b/library/xml index 96a8df43d..816497911 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 96a8df43d1c4508800c209701ce39ca972579e3b +Subproject commit 81649791116754a789aae85222797c4df3945b08 diff --git a/scripts b/scripts index b3ce8fa65..c6bb439ad 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit b3ce8fa650f86c7a1dbd5329d72c3d73dd76d05d +Subproject commit c6bb439ad18455fff85cdfab480689a1c94f56fe From 54d4b68f3cdef054b55849a248a8bcdaac8033df Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Sat, 18 Apr 2020 20:39:57 -0500 Subject: [PATCH 046/547] don't crash if the path to an instance-vector contains a null pointer --- library/DataStatics.cpp | 5 +++-- library/xml | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/library/DataStatics.cpp b/library/DataStatics.cpp index 61b7b6378..275cae584 100644 --- a/library/DataStatics.cpp +++ b/library/DataStatics.cpp @@ -12,10 +12,11 @@ namespace { template - inline T &_toref(T &r) { return r; } + inline T *_toptr(T &r) { return &r; } template - inline T &_toref(T *&p) { return *p; } + inline T *_toptr(T *&p) { return p; } } +#define _fieldptr(ptr, fn) (ptr) ? _toptr((ptr)->fn) : NULL #define INIT_GLOBAL_FUNCTION_PREFIX \ DFHack::VersionInfo *global_table_ = DFHack::Core::getInstance().vinfo.get(); \ diff --git a/library/xml b/library/xml index 816497911..d9a31fa45 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 81649791116754a789aae85222797c4df3945b08 +Subproject commit d9a31fa45228a7507b975dbbddbf00c7905644ea From d3a007489c5248b758627d019d1a6c4f4a53fd34 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sun, 19 Apr 2020 12:16:48 -0400 Subject: [PATCH 047/547] Fix ZLIB_ROOT in newer CMake versions --- CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index e40c932a0..f8dd5dc86 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,12 @@ if("${CMAKE_GENERATOR}" STREQUAL Ninja) endif() endif() +if(NOT("${CMAKE_VERSION}" VERSION_LESS 3.12)) + # make ZLIB_ROOT work in CMake >= 3.12 + # https://cmake.org/cmake/help/git-stage/policy/CMP0074.html + cmake_policy(SET CMP0074 NEW) +endif() + # Set up build types if(CMAKE_CONFIGURATION_TYPES) set(CMAKE_CONFIGURATION_TYPES "Release;RelWithDebInfo" CACHE STRING "List of supported configuration types" FORCE) From 2f1e057bc7efc215702cf14d0448dfaeaf1574e0 Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Sun, 19 Apr 2020 22:03:03 -0500 Subject: [PATCH 048/547] check-structures-sanity: report known void* types with a better message --- plugins/devel/check-structures-sanity/dispatch.cpp | 5 +++++ plugins/devel/check-structures-sanity/types.cpp | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/devel/check-structures-sanity/dispatch.cpp b/plugins/devel/check-structures-sanity/dispatch.cpp index fcc6b0b8e..f6342d03c 100644 --- a/plugins/devel/check-structures-sanity/dispatch.cpp +++ b/plugins/devel/check-structures-sanity/dispatch.cpp @@ -67,6 +67,11 @@ bool Checker::queue_item(const QueueItem & item, CheckedStructure cs) auto offset = uintptr_t(item.ptr) - uintptr_t(prev->first); if (!prev->second.second.has_type_at_offset(cs, offset)) { + if (offset == 0 && cs.identity == df::identity_traits::get()) + { + FAIL("unknown pointer is " << prev->second.second.identity->getFullName() << ", previously seen at " << prev->second.first); + return false; + } // TODO FAIL("TODO: handle merging structures: " << item.path << " overlaps " << prev->second.first << " (backward)"); return false; diff --git a/plugins/devel/check-structures-sanity/types.cpp b/plugins/devel/check-structures-sanity/types.cpp index 9e565215a..86d691f1d 100644 --- a/plugins/devel/check-structures-sanity/types.cpp +++ b/plugins/devel/check-structures-sanity/types.cpp @@ -129,7 +129,6 @@ bool CheckedStructure::has_type_at_offset(const CheckedStructure & type, size_t auto st = dynamic_cast(identity); if (!st) { - UNEXPECTED; return false; } From 66314806b137a86a0ff7627b08251ab9ce4d0d6f Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Sun, 19 Apr 2020 22:03:13 -0500 Subject: [PATCH 049/547] update structures --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index d9a31fa45..ce91eb750 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit d9a31fa45228a7507b975dbbddbf00c7905644ea +Subproject commit ce91eb750026e97b0044e88043f36fe4ff5218c0 From 9a10ea9fe5cec8b84a68f0846012f4cf4fca470a Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 22 Apr 2020 02:13:24 -0400 Subject: [PATCH 050/547] Update submodules --- library/xml | 2 +- scripts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/xml b/library/xml index ce91eb750..353caa341 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit ce91eb750026e97b0044e88043f36fe4ff5218c0 +Subproject commit 353caa3413f728938821c8aaccebb389a322bfef diff --git a/scripts b/scripts index c6bb439ad..1468a773e 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit c6bb439ad18455fff85cdfab480689a1c94f56fe +Subproject commit 1468a773e4b56716d94c28cc90a6988739d0c561 From f371ae6da86e3bf770b2a2412f10e12eccf99c63 Mon Sep 17 00:00:00 2001 From: PatrikLundell Date: Wed, 22 Apr 2020 12:38:37 +0200 Subject: [PATCH 051/547] adapted to histfig_nemesis_id->union --- library/modules/Units.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index 313d6ee9f..dc76c6802 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -212,7 +212,7 @@ void Units::setNickname(df::unit *unit, std::string nick) case df::identity_type::Unk_1: // Guess, but that's how it worked in the past case df::identity_type::TrueName: case df::identity_type::Unk_4: // Pure guess, as this is a new case, still unseen - id_hfig = df::historical_figure::find(identity->histfig_nemesis_id); + id_hfig = df::historical_figure::find(identity->figure.historical); break; } From 21be5cf061c65ef9d0ec7e9e8c1ab99adc97fa77 Mon Sep 17 00:00:00 2001 From: PatrikLundell Date: Wed, 22 Apr 2020 15:32:49 +0200 Subject: [PATCH 052/547] adapted to structures --- library/modules/Units.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index dc76c6802..c4b9e60fa 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -212,7 +212,7 @@ void Units::setNickname(df::unit *unit, std::string nick) case df::identity_type::Unk_1: // Guess, but that's how it worked in the past case df::identity_type::TrueName: case df::identity_type::Unk_4: // Pure guess, as this is a new case, still unseen - id_hfig = df::historical_figure::find(identity->figure.historical); + id_hfig = df::historical_figure::find(identity->histfig_id); break; } From 75c8bf1a59e49f8f64371b11a528eb086edfd685 Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 22 Apr 2020 22:05:48 -0400 Subject: [PATCH 053/547] Indent more --- plugins/remotefortressreader/remotefortressreader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/remotefortressreader/remotefortressreader.cpp b/plugins/remotefortressreader/remotefortressreader.cpp index 686c32211..e94c3f832 100644 --- a/plugins/remotefortressreader/remotefortressreader.cpp +++ b/plugins/remotefortressreader/remotefortressreader.cpp @@ -1693,7 +1693,7 @@ static command_result GetUnitListInside(color_ostream &stream, const BlockReques using df::global::cur_year; using df::global::cur_year_tick; - send_unit->set_age(Units::getAge(unit, false)); + send_unit->set_age(Units::getAge(unit, false)); ConvertDfColor(Units::getProfessionColor(unit), send_unit->mutable_profession_color()); send_unit->set_flags1(unit->flags1.whole); From 0272fd57f8cf662537f1896beca31e2c0041bba8 Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 22 Apr 2020 22:16:24 -0400 Subject: [PATCH 054/547] Update submodules --- library/xml | 2 +- scripts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/xml b/library/xml index 353caa341..eb99251b8 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 353caa3413f728938821c8aaccebb389a322bfef +Subproject commit eb99251b8f5e0a07788e1a3704bc9859323fdbc4 diff --git a/scripts b/scripts index 1468a773e..068ae1342 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 1468a773e4b56716d94c28cc90a6988739d0c561 +Subproject commit 068ae13427c7bad0c084c21a1ac83eec91395efa From c5513c3ca1fa194b459b103bae2bd4d103c31454 Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 23 Apr 2020 01:11:29 -0400 Subject: [PATCH 055/547] Update xml --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index eb99251b8..3e83ae5fc 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit eb99251b8f5e0a07788e1a3704bc9859323fdbc4 +Subproject commit 3e83ae5fc53ae6ff2e4e76ac0fa83af39cd6794d From 84f13b643b38c87f77b9c3c9ed0599e30c1b442a Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Thu, 23 Apr 2020 15:34:26 -0500 Subject: [PATCH 056/547] update structures --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index 3e83ae5fc..275f5c519 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 3e83ae5fc53ae6ff2e4e76ac0fa83af39cd6794d +Subproject commit 275f5c5199cc4f6293dac1cfeb17ffdebee4312a From 27e42ed25dd426182237eaa242291d1d4df89368 Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 23 Apr 2020 23:10:30 -0400 Subject: [PATCH 057/547] Update xml --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index 275f5c519..a106b5e98 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 275f5c5199cc4f6293dac1cfeb17ffdebee4312a +Subproject commit a106b5e98381184004fa9dfff44072239755e554 From c6ed0a24584c2c279828e26cb89c7082b2483660 Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 24 Apr 2020 21:15:04 -0400 Subject: [PATCH 058/547] Update xml, scripts, authors --- docs/Authors.rst | 1 + library/xml | 2 +- scripts | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/Authors.rst b/docs/Authors.rst index 72d61de06..6821a84b0 100644 --- a/docs/Authors.rst +++ b/docs/Authors.rst @@ -117,6 +117,7 @@ Priit Laes plaes Putnam Putnam3145 Quietust quietust _Q Raidau Raidau +Ralph Bisschops ralpha Ramblurr Ramblurr rampaging-poet Raoul van Putten diff --git a/library/xml b/library/xml index a106b5e98..3a1e2159a 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit a106b5e98381184004fa9dfff44072239755e554 +Subproject commit 3a1e2159a55ea46622b8bcfab35333b3674405fd diff --git a/scripts b/scripts index 068ae1342..73f89fe3d 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 068ae13427c7bad0c084c21a1ac83eec91395efa +Subproject commit 73f89fe3d48e52d9d860462df02d488b73de0953 From 7bdf958518d2892ee89a7173224a069c4a2190d8 Mon Sep 17 00:00:00 2001 From: Ben Rosser Date: Fri, 24 Apr 2020 21:18:46 -0400 Subject: [PATCH 059/547] Fix protobuf compilation with GCC 10 on Fedora Fixes #1506 --- depends/protobuf/google/protobuf/message.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/depends/protobuf/google/protobuf/message.cc b/depends/protobuf/google/protobuf/message.cc index 91e6878e8..37db6a485 100644 --- a/depends/protobuf/google/protobuf/message.cc +++ b/depends/protobuf/google/protobuf/message.cc @@ -32,6 +32,7 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. +#include #include #include From 55a82e43c6838849417723780be4f09f048d6b0b Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 24 Apr 2020 23:50:35 -0400 Subject: [PATCH 060/547] Update xml, fix stockpiles build --- library/xml | 2 +- plugins/stockpiles/StockpileSerializer.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/xml b/library/xml index 3a1e2159a..e42376086 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 3a1e2159a55ea46622b8bcfab35333b3674405fd +Subproject commit e42376086e04fe6db338eadefb00511dcccf1d7b diff --git a/plugins/stockpiles/StockpileSerializer.cpp b/plugins/stockpiles/StockpileSerializer.cpp index cdeced990..e5873988f 100644 --- a/plugins/stockpiles/StockpileSerializer.cpp +++ b/plugins/stockpiles/StockpileSerializer.cpp @@ -417,7 +417,7 @@ void StockpileSerializer::serialize_list_itemdef ( FuncWriteExport add_value, s { const df::itemdef *a = items.at ( i ); // skip procedurally generated items - if ( a->base_flags.is_set ( 0 ) ) continue; + if ( a->base_flags.is_set ( df::itemdef_flags::GENERATED ) ) continue; ItemTypeInfo ii; if ( !ii.decode ( type, i ) ) continue; add_value ( ii.getToken() ); From 405af5a20b131f8bc0a098c56b02fca6cd2811f1 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 25 Apr 2020 02:01:21 -0400 Subject: [PATCH 061/547] Update structures --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index e42376086..a7dae6083 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit e42376086e04fe6db338eadefb00511dcccf1d7b +Subproject commit a7dae6083d295821afe2ba91073d9b7547395b45 From 1546d9ec1a3c5673dfa49795bb8a956bf17c3b2d Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 25 Apr 2020 02:41:27 -0400 Subject: [PATCH 062/547] Tweak docs from #1484 --- docs/Plugins.rst | 4 ++-- plugins/getplants.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/Plugins.rst b/docs/Plugins.rst index 9e8911db1..421e5e81b 100644 --- a/docs/Plugins.rst +++ b/docs/Plugins.rst @@ -2322,9 +2322,9 @@ restricting the list to trees, shrubs, and farmable shrubs, respectively. designation). See :issue:`1479` for details. The implementation another known deficiency: it's incapable of detecting that - RAW definitions that specify a seed extraction reaction for the structural part + raw definitions that specify a seed extraction reaction for the structural part but has no other use for it cannot actually yield any seeds, as the part is - never used (parts of bug tracker report 6940, e.g. Red Spinach), even though DF + never used (parts of :bug:`6940`, e.g. Red Spinach), even though DF collects it, unless there's a workshop reaction to do it (which there isn't in vanilla). diff --git a/plugins/getplants.cpp b/plugins/getplants.cpp index 11717b36b..d678a63b0 100644 --- a/plugins/getplants.cpp +++ b/plugins/getplants.cpp @@ -64,7 +64,7 @@ enum class selectability { // Both Red Spinach and Elephant-Head Amaranth have the seed extraction reaction // explicitly specified for the structural part, but no other use for it. This causes // these parts to be collected (a valid reaction is defined), but remain unusable. This -// is one ofthe issues in bug 9640 on the bug tracker (the others cases are detected and +// is one of the issues in bug 9640 on the bug tracker (the others cases are detected and // result in the plants not being usable for farming or even collectable at all). //selectability selectablePlant(color_ostream &out, const df::plant_raw *plant, bool farming) From f008da32f8ef555cb048e76a31434c7b5214c869 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 25 Apr 2020 17:58:09 -0400 Subject: [PATCH 063/547] Update submodules --- library/xml | 2 +- plugins/getplants.cpp | 2 +- scripts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library/xml b/library/xml index a7dae6083..08d81cea7 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit a7dae6083d295821afe2ba91073d9b7547395b45 +Subproject commit 08d81cea7c32fee3fd55deb434d9f43e3b228497 diff --git a/plugins/getplants.cpp b/plugins/getplants.cpp index d678a63b0..d1ee79a04 100644 --- a/plugins/getplants.cpp +++ b/plugins/getplants.cpp @@ -64,7 +64,7 @@ enum class selectability { // Both Red Spinach and Elephant-Head Amaranth have the seed extraction reaction // explicitly specified for the structural part, but no other use for it. This causes // these parts to be collected (a valid reaction is defined), but remain unusable. This -// is one of the issues in bug 9640 on the bug tracker (the others cases are detected and +// is one of the issues in bug 6940 on the bug tracker (the others cases are detected and // result in the plants not being usable for farming or even collectable at all). //selectability selectablePlant(color_ostream &out, const df::plant_raw *plant, bool farming) diff --git a/scripts b/scripts index 73f89fe3d..b5ea085b5 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 73f89fe3d48e52d9d860462df02d488b73de0953 +Subproject commit b5ea085b5cfc9411d7374257db245a0ebefed380 From 02c118335f3f399ea41f9c0129cd13e840abc7c7 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 25 Apr 2020 17:59:50 -0400 Subject: [PATCH 064/547] Restore build-lua.sh for build-env --- travis/build-lua.sh | 54 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 travis/build-lua.sh diff --git a/travis/build-lua.sh b/travis/build-lua.sh new file mode 100644 index 000000000..e29d7ce87 --- /dev/null +++ b/travis/build-lua.sh @@ -0,0 +1,54 @@ +#!/bin/sh + +set -e + +LUA_ROOT="$HOME/lua53" +LUA_URL="http://www.lua.org/ftp/lua-5.3.3.tar.gz" +LUA_TAR=$(basename "$LUA_URL") +LUA_DIR="$LUA_ROOT/${LUA_TAR%.tar.*}" +LUA_SHA1="a0341bc3d1415b814cc738b2ec01ae56045d64ef" + +echo LUA_ROOT $LUA_ROOT +echo LUA_TAR $LUA_TAR +echo LUA_DIR $LUA_DIR + +sha1() { + python -c 'import hashlib, sys; print(hashlib.sha1(open(sys.argv[1],"rb").read()).hexdigest())' "$1" +} + +download() { + echo "Downloading $LUA_URL" + wget -O "$LUA_ROOT/$LUA_TAR" "$LUA_URL" + tar xvf "$LUA_ROOT/$LUA_TAR" +} + +build() { + cd "$LUA_DIR/src" + make generic +} + +main() { + mkdir -p "$LUA_ROOT" + cd "$LUA_ROOT" + mkdir -p bin + + if [ "$(sha1 "$LUA_ROOT/$LUA_TAR" 2>/dev/null)" != "$LUA_SHA1" ]; then + download + build + else + echo "Already downloaded" + + if [ -x "$LUA_DIR/src/luac" ]; then + echo "Already built" + else + build + fi + fi + + echo "Linking" + ln -sf "$LUA_DIR/src/lua" "$LUA_ROOT/bin/lua5.3" + ln -sf "$LUA_DIR/src/luac" "$LUA_ROOT/bin/luac5.3" + echo "Done" +} + +main From 3380f9ccf49e47e551168cfa48b947a4d00f9ded Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 25 Apr 2020 21:03:32 -0400 Subject: [PATCH 065/547] Update changelog --- docs/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog.txt b/docs/changelog.txt index 6ce9f69fd..3a20e1766 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -41,6 +41,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## Fixes - Fixed translation of certain types of in-game names +- Fixed a crash in ``find()`` for some types when no world is loaded - `autogems`: fixed an issue with binned gems being ignored in linked stockpiles - `tweak` embark-profile-name: fixed handling of the native shift+space key From 7a2ef4ff608df930c5cdf7d70e8367330a96997d Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 25 Apr 2020 21:14:27 -0400 Subject: [PATCH 066/547] Update scripts --- scripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts b/scripts index b5ea085b5..b3c2e1402 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit b5ea085b5cfc9411d7374257db245a0ebefed380 +Subproject commit b3c2e14029ebc544ea677738e3d155eaf732ef4c From f76b890cc8434f077285e83ca7ca147c245f0140 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 25 Apr 2020 21:18:33 -0400 Subject: [PATCH 067/547] Ensure that dev changelogs are also sorted, since they are pulled in from multiple files now --- docs/gen_changelog.py | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/gen_changelog.py b/docs/gen_changelog.py index cd27d99d2..8b1a6771e 100644 --- a/docs/gen_changelog.py +++ b/docs/gen_changelog.py @@ -235,6 +235,7 @@ def generate_changelog(all=False): dev_entries[entry.dev_version][entry.section].append(entry) consolidate_changelog(stable_entries) + consolidate_changelog(dev_entries) print_changelog(versions, stable_entries, 'docs/_auto/news.rst') print_changelog(versions, dev_entries, 'docs/_auto/news-dev.rst') From 6bdbf5b0ddaa045a8fc6ff91e91dc30cb3d21e3f Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 25 Apr 2020 21:33:02 -0400 Subject: [PATCH 068/547] Update to 0.47.04-r1, update xml, scripts, changelog version --- CMakeLists.txt | 4 ++-- docs/changelog.txt | 2 ++ library/xml | 2 +- scripts | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f8dd5dc86..5a5e8312b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -180,8 +180,8 @@ endif() # set up versioning. set(DF_VERSION "0.47.04") -set(DFHACK_RELEASE "beta1") -set(DFHACK_PRERELEASE TRUE) +set(DFHACK_RELEASE "r1") +set(DFHACK_PRERELEASE FALSE) set(DFHACK_VERSION "${DF_VERSION}-${DFHACK_RELEASE}") diff --git a/docs/changelog.txt b/docs/changelog.txt index 16105efc2..d3ed3e51c 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -39,6 +39,8 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: # Future +# 0.47.04-r1 + ## Fixes - Fixed translation of certain types of in-game names - Fixed a crash in ``find()`` for some types when no world is loaded diff --git a/library/xml b/library/xml index 08d81cea7..0792fc020 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 08d81cea7c32fee3fd55deb434d9f43e3b228497 +Subproject commit 0792fc0202fb6a04bfdaa262bc36a3b14c8581e5 diff --git a/scripts b/scripts index b3c2e1402..2079b9fb6 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit b3c2e14029ebc544ea677738e3d155eaf732ef4c +Subproject commit 2079b9fb69b8b4db48aa35ec54a96f5cca7cc8ef From 2108c2363dd22adc5bd24cea48217ca61834b04c Mon Sep 17 00:00:00 2001 From: lethosor Date: Tue, 28 Apr 2020 01:21:11 -0400 Subject: [PATCH 069/547] Use strcmp --- library/LuaTypes.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/LuaTypes.cpp b/library/LuaTypes.cpp index 4e90265ce..ebc33b477 100644 --- a/library/LuaTypes.cpp +++ b/library/LuaTypes.cpp @@ -708,7 +708,7 @@ static type_identity *find_primitive_field(lua_State *state, int field, const ch static int meta_primitive_index(lua_State *state) { const char *attr = lua_tostring(state, -1); - if (attr == std::string("ref_target")) { + if (strcmp(attr, "ref_target") == 0) { const struct_field_info *field_info = get_object_ref_header(state, 1)->field_info; if (field_info && field_info->extra && field_info->extra->ref_target) { LookupInTable(state, field_info->extra->ref_target, &DFHACK_TYPEID_TABLE_TOKEN); @@ -717,6 +717,7 @@ static int meta_primitive_index(lua_State *state) } return 1; } + uint8_t *ptr = get_object_addr(state, 1, 2, "read"); auto type = find_primitive_field(state, 2, "read", &ptr); if (!type) From 24cebbda5813450b0196253cc7c26aa773f23622 Mon Sep 17 00:00:00 2001 From: lethosor Date: Tue, 28 Apr 2020 21:38:47 -0400 Subject: [PATCH 070/547] Fix segfault when setting DFHACK_HEADLESS but not PRINT_MODE:TEXT endwin() is unhappy if initscr() wasn't called --- library/Core.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/library/Core.cpp b/library/Core.cpp index c0a1155c7..a9fe9a69a 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -1692,14 +1692,21 @@ bool Core::Init() if (is_headless) { #ifdef LINUX_BUILD - auto endwin = (int(*)(void))dlsym(RTLD_DEFAULT, "endwin"); - if (endwin) + if (is_text_mode) { - endwin(); + auto endwin = (int(*)(void))dlsym(RTLD_DEFAULT, "endwin"); + if (endwin) + { + endwin(); + } + else + { + cerr << "endwin(): bind failed" << endl; + } } else { - cerr << "endwin(): bind failed" << endl; + cerr << "Headless mode requires PRINT_MODE:TEXT" << endl; } #else cerr << "Headless mode not supported on Windows" << endl; From 1dc59d377275f893d568bc5782107ef3ff609806 Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 1 May 2020 22:50:02 -0400 Subject: [PATCH 071/547] Ruby: use core methods for finding selected item and building Similar to c3d566332, the core methods have become more complicated (and are also checked at compile-time). This will give a more consistent experience across scripts. Fixes #1563 --- plugins/ruby/building.rb | 11 +---------- plugins/ruby/item.rb | 36 +----------------------------------- plugins/ruby/ruby.cpp | 16 ++++++++++++++++ 3 files changed, 18 insertions(+), 45 deletions(-) diff --git a/plugins/ruby/building.rb b/plugins/ruby/building.rb index 7a85e9314..dae1d455b 100644 --- a/plugins/ruby/building.rb +++ b/plugins/ruby/building.rb @@ -2,16 +2,7 @@ module DFHack class << self def building_find(what=:selected, y=nil, z=nil) if what == :selected - case ui.main.mode - when :LookAround - k = ui_look_list.items[ui_look_cursor] - k.building if k.type == :Building - when :BuildingItems, :QueryBuilding - world.selected_building - when :Zones, :ZonesPenInfo, :ZonesPitInfo, :ZonesHospitalInfo - ui_sidebar_menus.zone.selected - end - + return world.buildings.all.binsearch(df.get_selected_building_id) elsif what.kind_of?(Integer) # search by building.id return world.buildings.all.binsearch(what) if not z diff --git a/plugins/ruby/item.rb b/plugins/ruby/item.rb index 394e545c6..59477c382 100644 --- a/plugins/ruby/item.rb +++ b/plugins/ruby/item.rb @@ -4,41 +4,7 @@ module DFHack # arg similar to unit.rb/unit_find; no arg = 'k' menu def item_find(what=:selected, y=nil, z=nil) if what == :selected - case curview._rtti_classname - when :viewscreen_itemst - if ref = curview.entry_ref[curview.cursor_pos] - ref.item_tg if ref.kind_of?(GeneralRefItem) - else - # not a container - curview.item - end - when :viewscreen_storesst # z/stocks - if curview.in_group_mode == 0 and curview.in_right_list == 1 - curview.items[curview.item_cursor] - end - else - case ui.main.mode - when :LookAround - k = ui_look_list.items[ui_look_cursor] - case k.type - when :Item - k.item - when :Building - # hilight a constructed bed/coffer - mats = k.building.contained_items.find_all { |i| i.use_mode == 2 } - mats[0].item if mats.length == 1 - end - when :BuildingItems - bld = world.selected_building - bld.contained_items[ui_building_item_cursor].item if bld - when :ViewUnits - u = world.units.active[ui_selected_unit] - u.inventory[ui_look_cursor].item if u and u.pos.z == cursor.z and - ui_unit_view_mode.value == :Inventory and u.inventory[ui_look_cursor] - else - ui.follow_item_tg if ui.follow_item != -1 - end - end + return world.items.all.binsearch(df.get_selected_item_id) elsif what.kind_of?(Integer) # search by id return world.items.all.binsearch(what) if not z diff --git a/plugins/ruby/ruby.cpp b/plugins/ruby/ruby.cpp index 240a67cb2..0209806d1 100644 --- a/plugins/ruby/ruby.cpp +++ b/plugins/ruby/ruby.cpp @@ -9,6 +9,8 @@ #include "modules/Gui.h" #include "df/global_objects.h" +#include "df/building.h" +#include "df/item.h" #include "df/unit.h" #include "tinythread.h" @@ -630,6 +632,18 @@ static VALUE rb_dfget_vtable_ptr(VALUE self, VALUE objptr) return rb_uint2inum(*(uintptr_t*)rb_num2ulong(objptr)); } +static VALUE rb_dfget_selected_building_id(VALUE self) +{ + df::building *b = Gui::getAnyBuilding(Core::getTopViewscreen()); + return rb_int2inum(b ? b->id : -1); +} + +static VALUE rb_dfget_selected_item_id(VALUE self) +{ + df::item *i = Gui::getAnyItem(Core::getTopViewscreen()); + return rb_int2inum(i ? i->id : -1); +} + static VALUE rb_dfget_selected_unit_id(VALUE self) { df::unit *u = Gui::getAnyUnit(Core::getTopViewscreen()); @@ -1147,6 +1161,8 @@ static void ruby_bind_dfhack(void) { rb_define_singleton_method(rb_cDFHack, "get_vtable", RUBY_METHOD_FUNC(rb_dfget_vtable), 1); rb_define_singleton_method(rb_cDFHack, "get_rtti_classname", RUBY_METHOD_FUNC(rb_dfget_rtti_classname), 1); rb_define_singleton_method(rb_cDFHack, "get_vtable_ptr", RUBY_METHOD_FUNC(rb_dfget_vtable_ptr), 1); + rb_define_singleton_method(rb_cDFHack, "get_selected_building_id", RUBY_METHOD_FUNC(rb_dfget_selected_building_id), 0); + rb_define_singleton_method(rb_cDFHack, "get_selected_item_id", RUBY_METHOD_FUNC(rb_dfget_selected_item_id), 0); rb_define_singleton_method(rb_cDFHack, "get_selected_unit_id", RUBY_METHOD_FUNC(rb_dfget_selected_unit_id), 0); rb_define_singleton_method(rb_cDFHack, "dfhack_run", RUBY_METHOD_FUNC(rb_dfhack_run), 1); rb_define_singleton_method(rb_cDFHack, "print_str", RUBY_METHOD_FUNC(rb_dfprint_str), 1); From 217535decbc38709cb0870530cf796a9e438b52f Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 1 May 2020 22:52:35 -0400 Subject: [PATCH 072/547] Update xml --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index 0792fc020..7941e0ffa 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 0792fc0202fb6a04bfdaa262bc36a3b14c8581e5 +Subproject commit 7941e0ffa7e355cd2363367cdfbb3e085ac4a941 From 947d0db182832c931e26b30eb13daba94219a1cc Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Sat, 2 May 2020 01:54:38 -0500 Subject: [PATCH 073/547] update structures --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index 7941e0ffa..0231cce29 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 7941e0ffa7e355cd2363367cdfbb3e085ac4a941 +Subproject commit 0231cce29e6014367c0af122aed4f7ba21292b2b From 1c57aa7bb4f103b482c3dabba9bcfcb0bdb47e90 Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Sat, 2 May 2020 02:01:32 -0500 Subject: [PATCH 074/547] update structures --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index 0231cce29..b4dfab6d0 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 0231cce29e6014367c0af122aed4f7ba21292b2b +Subproject commit b4dfab6d08635da8b01504a289e8cf4e62c859c5 From ec7f97bb7a85a1d317c5fdba602e8bbc43eb44cd Mon Sep 17 00:00:00 2001 From: PatrikLundell Date: Sat, 2 May 2020 17:37:10 +0200 Subject: [PATCH 075/547] adapted to enum value name change --- library/modules/Units.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index c4b9e60fa..43eb9026c 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -209,7 +209,7 @@ void Units::setNickname(df::unit *unit, std::string nick) case df::identity_type::FalseIdentity: break; // We want the nickname to end up in the identity - case df::identity_type::Unk_1: // Guess, but that's how it worked in the past + case df::identity_type::Impersonating: case df::identity_type::TrueName: case df::identity_type::Unk_4: // Pure guess, as this is a new case, still unseen id_hfig = df::historical_figure::find(identity->histfig_id); From fcc49620520bcc48662ed363130c17d662d324e6 Mon Sep 17 00:00:00 2001 From: JapaMala Date: Sat, 2 May 2020 10:58:07 -0700 Subject: [PATCH 076/547] Update stonesense to not crash. --- plugins/stonesense | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/stonesense b/plugins/stonesense index b9fc28836..5b7e7743a 160000 --- a/plugins/stonesense +++ b/plugins/stonesense @@ -1 +1 @@ -Subproject commit b9fc28836f34f7ce1be64de94afd90184a341c7d +Subproject commit 5b7e7743a1372b929acb2ccb75080e139ac11691 From 60853a543df9e5a90f71f9b315e7169211a126b2 Mon Sep 17 00:00:00 2001 From: JapaMala Date: Sat, 2 May 2020 13:28:28 -0700 Subject: [PATCH 077/547] Remove the site realization building type from the remote reader spec. It has no business being there. --- plugins/proto/RemoteFortressReader.proto | 29 +------------------ .../remotefortressreader.cpp | 2 +- 2 files changed, 2 insertions(+), 29 deletions(-) diff --git a/plugins/proto/RemoteFortressReader.proto b/plugins/proto/RemoteFortressReader.proto index a54a0397f..864cdba1a 100644 --- a/plugins/proto/RemoteFortressReader.proto +++ b/plugins/proto/RemoteFortressReader.proto @@ -642,33 +642,6 @@ message WorldMap repeated RegionTile region_tiles = 25; } -enum SiteRealizationBuildingType -{ - cottage_plot = 0; - castle_wall = 1; - castle_tower = 2; - castle_courtyard = 3; - house = 4; - temple = 5; - tomb = 6; - shop_house = 7; - warehouse = 8; - market_square = 9; - pasture = 10; - waste = 11; - courtyard = 12; - well = 13; - vault = 14; - great_tower = 15; - trenches = 16; - tree_house = 17; - hillock_house = 18; - mead_hall = 19; - fortress_entrance = 20; - library = 21; - tavern = 22; -} - message SiteRealizationBuildingWall { optional int32 start_x = 1; @@ -702,7 +675,6 @@ message SiteRealizationBuildingTrenches message SiteRealizationBuilding { optional int32 id = 1; - optional SiteRealizationBuildingType type = 2; optional int32 min_x = 3; optional int32 min_y = 4; optional int32 max_x = 5; @@ -711,6 +683,7 @@ message SiteRealizationBuilding optional SiteRealizationBuildingWall wall_info = 8; optional SiteRealizationBuildingTower tower_info = 9; optional SiteRealizationBuildingTrenches trench_info = 10; + optional int32 type = 11; } message RegionTile diff --git a/plugins/remotefortressreader/remotefortressreader.cpp b/plugins/remotefortressreader/remotefortressreader.cpp index e94c3f832..7e654c727 100644 --- a/plugins/remotefortressreader/remotefortressreader.cpp +++ b/plugins/remotefortressreader/remotefortressreader.cpp @@ -2541,7 +2541,7 @@ static void CopyLocalMap(df::world_data * worldData, df::world_region_details* w out_building->set_id(in_building->id); #if DF_VERSION_INT > 34011 - out_building->set_type((SiteRealizationBuildingType)in_building->type); + out_building->set_type(in_building->type); #endif out_building->set_min_x(in_building->min_x - (site_x * 48)); out_building->set_min_y(in_building->min_y - (site_y * 48)); From 63c7b69b5b5a9503b378185bf56b768e1c740d51 Mon Sep 17 00:00:00 2001 From: JapaMala Date: Sat, 2 May 2020 14:38:55 -0700 Subject: [PATCH 078/547] Change item improvement type to bare ints. --- plugins/proto/RemoteFortressReader.proto | 19 +------------------ plugins/remotefortressreader/item_reader.cpp | 2 +- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/plugins/proto/RemoteFortressReader.proto b/plugins/proto/RemoteFortressReader.proto index 864cdba1a..8255f91cd 100644 --- a/plugins/proto/RemoteFortressReader.proto +++ b/plugins/proto/RemoteFortressReader.proto @@ -963,30 +963,13 @@ message Language repeated ShapeDescriptior shapes = 1; } -enum ImprovementType -{ - ART_IMAGE = 0; - COVERED = 1; - RINGS_HANGING = 2; - BANDS = 3; - SPIKES = 4; - ITEMSPECIFIC = 5; - THREAD = 6; - CLOTH = 7; - SEWN_IMAGE = 8; - PAGES = 9; - ILLUSTRATION = 10; - INSTRUMENT_PIECE = 11; - WRITING = 12; -} - message ItemImprovement { optional MatPair material = 1; - optional ImprovementType type = 2; optional int32 shape = 3; optional int32 specific_type= 4; optional ArtImage image = 5; + optional int32 type = 6; } enum ArtImageElementType diff --git a/plugins/remotefortressreader/item_reader.cpp b/plugins/remotefortressreader/item_reader.cpp index 620e06310..56ec9019b 100644 --- a/plugins/remotefortressreader/item_reader.cpp +++ b/plugins/remotefortressreader/item_reader.cpp @@ -450,7 +450,7 @@ void CopyItem(RemoteFortressReader::Item * NetItem, df::item * DfItem) auto netImp = NetItem->add_improvements(); - netImp->set_type((ImprovementType)impType); + netImp->set_type(impType); auto mat = netImp->mutable_material(); mat->set_mat_type(improvement->mat_type); From 866660169e89599141264ec3f03691bd4597dc79 Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Sun, 3 May 2020 17:53:32 -0500 Subject: [PATCH 079/547] Update joblabormapper.cpp Add no-labor mappings for new jobs 241 through 243. --- plugins/labormanager/joblabormapper.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/labormanager/joblabormapper.cpp b/plugins/labormanager/joblabormapper.cpp index 7c4f80fb7..7b4e77553 100644 --- a/plugins/labormanager/joblabormapper.cpp +++ b/plugins/labormanager/joblabormapper.cpp @@ -896,6 +896,10 @@ JobLaborMapper::JobLaborMapper() job_to_labor_table[df::job_type::PutItemOnDisplay] = jlf_const(df::unit_labor::HAUL_ITEM); job_to_labor_table[df::job_type::StoreItemInLocation] = jlf_no_labor; // StoreItemInLocation + + job_to_labor_table[df::job_type::unk_fake_no_job] = jlf_no_labor; // added for 47.04 - see #1561 + job_to_labor_table[df::job_type::InterrogateSubject] = jlf_no_labor; // added for 47.04 - see #1561 + job_to_labor_table[df::job_type::unk_fake_no_activity] = jlf_no_labor; // added for 47.04 - see #1561 }; df::unit_labor JobLaborMapper::find_job_labor(df::job* j) From 319354f6cd34ad7a68bbbcc90b3c28948322e063 Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Sun, 3 May 2020 18:16:31 -0500 Subject: [PATCH 080/547] Update labormanager.cpp Add entries for jobs 241-243 to the `dwarf_states` vector as well, derp. --- plugins/labormanager/labormanager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/labormanager/labormanager.cpp b/plugins/labormanager/labormanager.cpp index e416dcf63..accb74b38 100644 --- a/plugins/labormanager/labormanager.cpp +++ b/plugins/labormanager/labormanager.cpp @@ -385,6 +385,9 @@ static const dwarf_state dwarf_states[] = { BUSY /* MakeBracelet */, BUSY /* MakeGem */, BUSY /* PutItemOnDisplay */, + BUSY /* unk_fake_no_job */, + BUSY /* InterrogateSubject */, + BUSY /* unk_fake_no_activity */, }; struct labor_info From 2dfd7ea0d0399b603b5461b4fee34c21079bd651 Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Sun, 3 May 2020 18:19:49 -0500 Subject: [PATCH 081/547] Update labormanager.cpp again These should probably be OTHER rather than BUSY. --- plugins/labormanager/labormanager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/labormanager/labormanager.cpp b/plugins/labormanager/labormanager.cpp index accb74b38..fad421104 100644 --- a/plugins/labormanager/labormanager.cpp +++ b/plugins/labormanager/labormanager.cpp @@ -385,9 +385,9 @@ static const dwarf_state dwarf_states[] = { BUSY /* MakeBracelet */, BUSY /* MakeGem */, BUSY /* PutItemOnDisplay */, - BUSY /* unk_fake_no_job */, - BUSY /* InterrogateSubject */, - BUSY /* unk_fake_no_activity */, + OTHER /* unk_fake_no_job */, + OTHER /* InterrogateSubject */, + OTHER /* unk_fake_no_activity */, }; struct labor_info From af33f71aa220a5b42dd640a3233f4ae57d75789b Mon Sep 17 00:00:00 2001 From: lethosor Date: Sun, 3 May 2020 22:54:43 -0400 Subject: [PATCH 082/547] Update changelog Includes #1561/#1566 --- docs/changelog.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/changelog.txt b/docs/changelog.txt index d3ed3e51c..1aa7f916e 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -39,6 +39,13 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: # Future +## Fixes +- Fixed a segfault when attempting to start a headless session with a graphical PRINT_MODE setting +- `labormanager`: fixed handling of new jobs in 0.47 + +## Ruby +- Updated ``item_find`` and ``building_find`` to use centralized logic that works on more screens + # 0.47.04-r1 ## Fixes From be517370a69ab6d8b35ffff58c6c5fc5068257ec Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 4 May 2020 18:38:54 -0400 Subject: [PATCH 083/547] rendermax: move to std::mutex fast_mutex can deadlock on Linux with optimization enabled --- plugins/rendermax/renderer_light.cpp | 4 ++-- plugins/rendermax/renderer_light.hpp | 24 +++++++++++++----------- plugins/rendermax/renderer_opengl.hpp | 22 ++++++++++------------ plugins/rendermax/rendermax.cpp | 24 ++++++++++-------------- 4 files changed, 35 insertions(+), 39 deletions(-) diff --git a/plugins/rendermax/renderer_light.cpp b/plugins/rendermax/renderer_light.cpp index dda928afa..d76889220 100644 --- a/plugins/rendermax/renderer_light.cpp +++ b/plugins/rendermax/renderer_light.cpp @@ -270,7 +270,7 @@ rgbf blend(const rgbf& a,const rgbf& b) void lightingEngineViewscreen::clear() { lightMap.assign(lightMap.size(),rgbf(1,1,1)); - tthread::lock_guard guard(myRenderer->dataMutex); + std::lock_guard guard{myRenderer->dataMutex}; if(lightMap.size()==myRenderer->lightGrid.size()) { std::swap(myRenderer->lightGrid,lightMap); @@ -299,7 +299,7 @@ void lightingEngineViewscreen::calculate() } void lightingEngineViewscreen::updateWindow() { - tthread::lock_guard guard(myRenderer->dataMutex); + std::lock_guard guard{myRenderer->dataMutex}; if(lightMap.size()!=myRenderer->lightGrid.size()) { reinit(); diff --git a/plugins/rendermax/renderer_light.hpp b/plugins/rendermax/renderer_light.hpp index b0fb8c5d5..4e779f3fa 100644 --- a/plugins/rendermax/renderer_light.hpp +++ b/plugins/rendermax/renderer_light.hpp @@ -1,11 +1,14 @@ -#ifndef RENDERER_LIGHT_INCLUDED -#define RENDERER_LIGHT_INCLUDED -#include "renderer_opengl.hpp" -#include "Types.h" -#include -#include +#pragma once + #include +#include +#include +#include #include + +#include "renderer_opengl.hpp" +#include "Types.h" + // we are not using boost so let's cheat: template inline void hash_combine(std::size_t & seed, const T & v) @@ -91,7 +94,7 @@ private: } void reinitLightGrid(int w,int h) { - tthread::lock_guard guard(dataMutex); + std::lock_guard guard{dataMutex}; lightGrid.resize(w*h,rgbf(1,1,1)); } void reinitLightGrid() @@ -100,7 +103,7 @@ private: } public: - tthread::fast_mutex dataMutex; + std::mutex dataMutex; std::vector lightGrid; renderer_light(renderer* parent):renderer_wrap(parent),light_adaptation(1) { @@ -108,12 +111,12 @@ public: } virtual void update_tile(int32_t x, int32_t y) { renderer_wrap::update_tile(x,y); - tthread::lock_guard guard(dataMutex); + std::lock_guard guard{dataMutex}; colorizeTile(x,y); }; virtual void update_all() { renderer_wrap::update_all(); - tthread::lock_guard guard(dataMutex); + std::lock_guard guard{dataMutex}; for (int x = 0; x < df::global::gps->dimx; x++) for (int y = 0; y < df::global::gps->dimy; y++) colorizeTile(x,y); @@ -374,4 +377,3 @@ private: }; rgbf blend(const rgbf& a,const rgbf& b); rgbf blendMax(const rgbf& a,const rgbf& b); -#endif diff --git a/plugins/rendermax/renderer_opengl.hpp b/plugins/rendermax/renderer_opengl.hpp index 76a45918c..a0a920e69 100644 --- a/plugins/rendermax/renderer_opengl.hpp +++ b/plugins/rendermax/renderer_opengl.hpp @@ -1,9 +1,7 @@ //original file from https://github.com/Baughn/Dwarf-Fortress--libgraphics- -#ifndef RENDERER_OPENGL_INCLUDED -#define RENDERER_OPENGL_INCLUDED +#pragma once #include "tinythread.h" -#include "fast_mutex.h" #include "Core.h" #include @@ -15,6 +13,7 @@ #include "df/graphic.h" #include #include +#include using df::renderer; using df::init; @@ -281,7 +280,7 @@ private: } void reinitLightGrid(int w,int h) { - tthread::lock_guard guard(dataMutex); + std::lock_guard guard{dataMutex}; lightGrid.resize(w*h); } void reinitLightGrid() @@ -289,7 +288,7 @@ private: reinitLightGrid(df::global::gps->dimy,df::global::gps->dimx); } public: - tthread::fast_mutex dataMutex; + std::mutex dataMutex; std::vector lightGrid; renderer_test(renderer* parent):renderer_wrap(parent) { @@ -297,14 +296,14 @@ public: } virtual void update_tile(int32_t x, int32_t y) { renderer_wrap::update_tile(x,y); - tthread::lock_guard guard(dataMutex); + std::lock_guard guard{dataMutex}; colorizeTile(x,y); //some sort of mutex or sth? //and then map read }; virtual void update_all() { renderer_wrap::update_all(); - tthread::lock_guard guard(dataMutex); + std::lock_guard guard{dataMutex}; for (int x = 0; x < df::global::gps->dimx; x++) for (int y = 0; y < df::global::gps->dimy; y++) colorizeTile(x,y); @@ -366,7 +365,7 @@ private: } void reinitGrids(int w,int h) { - tthread::lock_guard guard(dataMutex); + std::lock_guard guard{dataMutex}; foreOffset.resize(w*h); foreMult.resize(w*h); backOffset.resize(w*h); @@ -377,7 +376,7 @@ private: reinitGrids(df::global::gps->dimy,df::global::gps->dimx); } public: - tthread::fast_mutex dataMutex; + std::mutex dataMutex; std::vector foreOffset,foreMult; std::vector backOffset,backMult; inline int xyToTile(int x, int y) @@ -390,14 +389,14 @@ public: } virtual void update_tile(int32_t x, int32_t y) { renderer_wrap::update_tile(x,y); - tthread::lock_guard guard(dataMutex); + std::lock_guard guard{dataMutex}; overwriteTile(x,y); //some sort of mutex or sth? //and then map read }; virtual void update_all() { renderer_wrap::update_all(); - tthread::lock_guard guard(dataMutex); + std::lock_guard guard{dataMutex}; for (int x = 0; x < df::global::gps->dimx; x++) for (int y = 0; y < df::global::gps->dimy; y++) overwriteTile(x,y); @@ -414,4 +413,3 @@ public: reinitGrids(w,h); } }; -#endif \ No newline at end of file diff --git a/plugins/rendermax/rendermax.cpp b/plugins/rendermax/rendermax.cpp index be8be07ba..17fd6fa95 100644 --- a/plugins/rendermax/rendermax.cpp +++ b/plugins/rendermax/rendermax.cpp @@ -1,27 +1,23 @@ -#include +#include +#include #include +#include -#include - -#include - -#include "Core.h" #include "Console.h" +#include "Core.h" #include "Export.h" +#include "LuaTools.h" #include "PluginManager.h" +#include "VTableInterpose.h" -#include -#include "df/renderer.h" #include "df/enabler.h" +#include "df/renderer.h" +#include "df/viewscreen_dungeonmodest.h" +#include "df/viewscreen_dwarfmodest.h" #include "renderer_opengl.hpp" #include "renderer_light.hpp" -#include "df/viewscreen_dwarfmodest.h" -#include "df/viewscreen_dungeonmodest.h" - -#include - using df::viewscreen_dungeonmodest; using df::viewscreen_dwarfmodest; @@ -367,7 +363,7 @@ static command_result rendermax(color_ostream &out, vector & parameters cur=blue; renderer_test* r=reinterpret_cast(enabler->renderer); - tthread::lock_guard guard(r->dataMutex); + std::lock_guard guard{r->dataMutex}; int h=gps->dimy; int w=gps->dimx; int cx=w/2; From 1dc2d4b6aafd948518c37709a4979a6458674be3 Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 4 May 2020 18:41:59 -0400 Subject: [PATCH 084/547] Remove tthread::fast_mutex entirely This can deadlock on Linux, per be517370a69ab6d8b35ffff58c6c5fc5068257ec, and rendermax was the only tool that used it --- depends/tthread/fast_mutex.h | 249 ----------------------------------- depends/tthread/tinythread.h | 1 - 2 files changed, 250 deletions(-) delete mode 100644 depends/tthread/fast_mutex.h diff --git a/depends/tthread/fast_mutex.h b/depends/tthread/fast_mutex.h deleted file mode 100644 index a381b2c75..000000000 --- a/depends/tthread/fast_mutex.h +++ /dev/null @@ -1,249 +0,0 @@ -/* -*- mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- -Copyright (c) 2010-2012 Marcus Geelnard - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -*/ - -#ifndef _FAST_MUTEX_H_ -#define _FAST_MUTEX_H_ - -/// @file - -// Which platform are we on? -#if !defined(_TTHREAD_PLATFORM_DEFINED_) - #if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__) - #define _TTHREAD_WIN32_ - #else - #define _TTHREAD_POSIX_ - #endif - #define _TTHREAD_PLATFORM_DEFINED_ -#endif - -// Check if we can support the assembly language level implementation (otherwise -// revert to the system API) -#if (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))) || \ - (defined(_MSC_VER) && (defined(_M_IX86) /*|| defined(_M_X64)*/)) || \ - (defined(__GNUC__) && (defined(__ppc__))) - #define _FAST_MUTEX_ASM_ -#else - #define _FAST_MUTEX_SYS_ -#endif - -#if defined(_TTHREAD_WIN32_) - #define NOMINMAX - #ifndef WIN32_LEAN_AND_MEAN - #define WIN32_LEAN_AND_MEAN - #define __UNDEF_LEAN_AND_MEAN - #endif - #include - #ifdef __UNDEF_LEAN_AND_MEAN - #undef WIN32_LEAN_AND_MEAN - #undef __UNDEF_LEAN_AND_MEAN - #endif -#else - #ifdef _FAST_MUTEX_ASM_ - #include - #else - #include - #endif -#endif - -namespace tthread { - -/// Fast mutex class. -/// This is a mutual exclusion object for synchronizing access to shared -/// memory areas for several threads. It is similar to the tthread::mutex class, -/// but instead of using system level functions, it is implemented as an atomic -/// spin lock with very low CPU overhead. -/// -/// The \c fast_mutex class is NOT compatible with the \c condition_variable -/// class (however, it IS compatible with the \c lock_guard class). It should -/// also be noted that the \c fast_mutex class typically does not provide -/// as accurate thread scheduling as a the standard \c mutex class does. -/// -/// Because of the limitations of the class, it should only be used in -/// situations where the mutex needs to be locked/unlocked very frequently. -/// -/// @note The "fast" version of this class relies on inline assembler language, -/// which is currently only supported for 32/64-bit Intel x86/AMD64 and -/// PowerPC architectures on a limited number of compilers (GNU g++ and MS -/// Visual C++). -/// For other architectures/compilers, system functions are used instead. -class fast_mutex { - public: - /// Constructor. -#if defined(_FAST_MUTEX_ASM_) - fast_mutex() : mLock(0) {} -#else - fast_mutex() - { - #if defined(_TTHREAD_WIN32_) - InitializeCriticalSection(&mHandle); - #elif defined(_TTHREAD_POSIX_) - pthread_mutex_init(&mHandle, NULL); - #endif - } -#endif - -#if !defined(_FAST_MUTEX_ASM_) - /// Destructor. - ~fast_mutex() - { - #if defined(_TTHREAD_WIN32_) - DeleteCriticalSection(&mHandle); - #elif defined(_TTHREAD_POSIX_) - pthread_mutex_destroy(&mHandle); - #endif - } -#endif - - /// Lock the mutex. - /// The method will block the calling thread until a lock on the mutex can - /// be obtained. The mutex remains locked until \c unlock() is called. - /// @see lock_guard - inline void lock() - { -#if defined(_FAST_MUTEX_ASM_) - bool gotLock; - do { - gotLock = try_lock(); - if(!gotLock) - { - #if defined(_TTHREAD_WIN32_) - Sleep(0); - #elif defined(_TTHREAD_POSIX_) - sched_yield(); - #endif - } - } while(!gotLock); -#else - #if defined(_TTHREAD_WIN32_) - EnterCriticalSection(&mHandle); - #elif defined(_TTHREAD_POSIX_) - pthread_mutex_lock(&mHandle); - #endif -#endif - } - - /// Try to lock the mutex. - /// The method will try to lock the mutex. If it fails, the function will - /// return immediately (non-blocking). - /// @return \c true if the lock was acquired, or \c false if the lock could - /// not be acquired. - inline bool try_lock() - { -#if defined(_FAST_MUTEX_ASM_) - int oldLock; - #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) - asm volatile ( - "movl $1,%%eax\n\t" - "xchg %%eax,%0\n\t" - "movl %%eax,%1\n\t" - : "=m" (mLock), "=m" (oldLock) - : - : "%eax", "memory" - ); - #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) - int *ptrLock = &mLock; - __asm { - mov eax,1 - mov ecx,ptrLock - xchg eax,[ecx] - mov oldLock,eax - } - #elif defined(__GNUC__) && (defined(__ppc__)) - int newLock = 1; - asm volatile ( - "\n1:\n\t" - "lwarx %0,0,%1\n\t" - "cmpwi 0,%0,0\n\t" - "bne- 2f\n\t" - "stwcx. %2,0,%1\n\t" - "bne- 1b\n\t" - "isync\n" - "2:\n\t" - : "=&r" (oldLock) - : "r" (&mLock), "r" (newLock) - : "cr0", "memory" - ); - #endif - return (oldLock == 0); -#else - #if defined(_TTHREAD_WIN32_) - return TryEnterCriticalSection(&mHandle) ? true : false; - #elif defined(_TTHREAD_POSIX_) - return (pthread_mutex_trylock(&mHandle) == 0) ? true : false; - #endif -#endif - } - - /// Unlock the mutex. - /// If any threads are waiting for the lock on this mutex, one of them will - /// be unblocked. - inline void unlock() - { -#if defined(_FAST_MUTEX_ASM_) - #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) - asm volatile ( - "movl $0,%%eax\n\t" - "xchg %%eax,%0\n\t" - : "=m" (mLock) - : - : "%eax", "memory" - ); - #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) - int *ptrLock = &mLock; - __asm { - mov eax,0 - mov ecx,ptrLock - xchg eax,[ecx] - } - #elif defined(__GNUC__) && (defined(__ppc__)) - asm volatile ( - "sync\n\t" // Replace with lwsync where possible? - : : : "memory" - ); - mLock = 0; - #endif -#else - #if defined(_TTHREAD_WIN32_) - LeaveCriticalSection(&mHandle); - #elif defined(_TTHREAD_POSIX_) - pthread_mutex_unlock(&mHandle); - #endif -#endif - } - - private: -#if defined(_FAST_MUTEX_ASM_) - int mLock; -#else - #if defined(_TTHREAD_WIN32_) - CRITICAL_SECTION mHandle; - #elif defined(_TTHREAD_POSIX_) - pthread_mutex_t mHandle; - #endif -#endif -}; - -} - -#endif // _FAST_MUTEX_H_ - diff --git a/depends/tthread/tinythread.h b/depends/tthread/tinythread.h index d575bae33..b5ff2f077 100644 --- a/depends/tthread/tinythread.h +++ b/depends/tthread/tinythread.h @@ -46,7 +46,6 @@ freely, subject to the following restrictions: /// @li tthread::recursive_mutex /// @li tthread::condition_variable /// @li tthread::lock_guard -/// @li tthread::fast_mutex /// /// @section misc_sec Miscellaneous /// The following special keywords are available: #thread_local. From f3b3cb1b3316dee9f960c3670f94494ead27fb29 Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 4 May 2020 19:26:49 -0400 Subject: [PATCH 085/547] Remove fast_mutex from CMakeLists --- depends/tthread/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/tthread/CMakeLists.txt b/depends/tthread/CMakeLists.txt index 9e0e85dc5..dfb1d9901 100644 --- a/depends/tthread/CMakeLists.txt +++ b/depends/tthread/CMakeLists.txt @@ -1,5 +1,5 @@ project(dfhack-tinythread) -add_library(dfhack-tinythread STATIC EXCLUDE_FROM_ALL tinythread.cpp tinythread.h fast_mutex.h) +add_library(dfhack-tinythread STATIC EXCLUDE_FROM_ALL tinythread.cpp tinythread.h) if(UNIX) target_link_libraries(dfhack-tinythread pthread) endif() From d0c030c3da62b88d97a05c417fce3d86e80fa7de Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 4 May 2020 19:27:17 -0400 Subject: [PATCH 086/547] Update xml (changelog only) --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index b4dfab6d0..0686cfdfc 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit b4dfab6d08635da8b01504a289e8cf4e62c859c5 +Subproject commit 0686cfdfc18e9f606f2c296b617d5b3ab6b83889 From 31d984e9348f23287f89b50ec661bdb542400f4d Mon Sep 17 00:00:00 2001 From: PatrikLundell Date: Tue, 5 May 2020 10:21:56 +0200 Subject: [PATCH 087/547] Fixed 2 incursion handling bugs --- docs/changelog.txt | 1 + plugins/embark-assistant/survey.cpp | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index 1aa7f916e..5b83825e1 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: ## Fixes - Fixed a segfault when attempting to start a headless session with a graphical PRINT_MODE setting - `labormanager`: fixed handling of new jobs in 0.47 +- `embark-assistant`: fixed a couple of incursion handling bugs. ## Ruby - Updated ``item_find`` and ``building_find`` to use centralized logic that works on more screens diff --git a/plugins/embark-assistant/survey.cpp b/plugins/embark-assistant/survey.cpp index 79c66e4df..20dd9d539 100644 --- a/plugins/embark-assistant/survey.cpp +++ b/plugins/embark-assistant/survey.cpp @@ -2424,7 +2424,7 @@ void embark_assist::survey::survey_embark(embark_assist::defs::mid_level_tiles * } else { process_embark_incursion_mid_level_tile - (translate_ns_edge(survey_results, + (translate_ew_edge(survey_results, true, x, y, @@ -2481,7 +2481,7 @@ void embark_assist::survey::survey_embark(embark_assist::defs::mid_level_tiles * } else { process_embark_incursion_mid_level_tile - (translate_ns_edge(survey_results, + (translate_ew_edge(survey_results, false, x, y, From 1058e40cb0f42820ba1364477537bc9c668fb85f Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Tue, 28 Apr 2020 18:18:28 -0500 Subject: [PATCH 088/547] Enable /bigobj globally on MSVC. This changes the intermediate format used for compiled files from one that can hold up to 65279 (slightly less than 2^16) addressable sections to one that can hold 4294967296 (2^32). Code that uses templates, such as... C++ code... can easily run up against the smaller limit. This does not affect the finished executable, only the intermediate object files. --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a5e8312b..de0c858af 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,6 +89,10 @@ if(MSVC) # a smaller type, and most of the time this is just conversion from 64 to 32 bits # for things like vector sizes, which are never that big anyway. add_definitions("/wd4267") + + # MSVC panics if an object file contains more than 65,279 sections. this + # happens quite frequently with code that uses templates, such as vectors. + add_definitions("/bigobj") endif() # Automatically detect architecture based on Visual Studio generator From 0ffafbde298cc84003ebec0de75013d6baa547e9 Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Sat, 9 May 2020 18:28:19 -0500 Subject: [PATCH 089/547] update structures --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index 0686cfdfc..efc5c2610 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 0686cfdfc18e9f606f2c296b617d5b3ab6b83889 +Subproject commit efc5c2610bd0345e9102279be0a9f154e5862050 From fc10ed3df63f610fa4c3756ae121201f3c7a79f4 Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Mon, 27 Apr 2020 18:26:31 -0500 Subject: [PATCH 090/547] Implementation for df-other-vectors-type in C++. Still needs Lua and Ruby support. --- library/include/BitArray.h | 10 ++++++++++ library/include/DataDefs.h | 1 + 2 files changed, 11 insertions(+) diff --git a/library/include/BitArray.h b/library/include/BitArray.h index cfb859bd0..dfd187363 100644 --- a/library/include/BitArray.h +++ b/library/include/BitArray.h @@ -568,4 +568,14 @@ namespace DFHack root->next = link; } }; + + template + struct DfOtherVectors + { + std::vector & operator[](O other_id) + { + auto vectors = reinterpret_cast *>(this); + return vectors[other_id]; + } + }; } diff --git a/library/include/DataDefs.h b/library/include/DataDefs.h index fd70b7ba8..3b961df20 100644 --- a/library/include/DataDefs.h +++ b/library/include/DataDefs.h @@ -474,6 +474,7 @@ namespace df using DFHack::BitArray; using DFHack::DfArray; using DFHack::DfLinkedList; + using DFHack::DfOtherVectors; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" From 7cf9624de9d25383ba548d49fa180f28409c8202 Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Mon, 27 Apr 2020 18:56:48 -0500 Subject: [PATCH 091/547] add assert to make sure other_id array index is in bounds --- library/include/BitArray.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/include/BitArray.h b/library/include/BitArray.h index dfd187363..5858897a3 100644 --- a/library/include/BitArray.h +++ b/library/include/BitArray.h @@ -574,6 +574,8 @@ namespace DFHack { std::vector & operator[](O other_id) { + CHECK_INVALID_ARGUMENT(size_t(other_id) < sizeof(*this) / sizeof(std::vector)); + auto vectors = reinterpret_cast *>(this); return vectors[other_id]; } From 6c20fe4c804fa97018bb1a4374c0d86470d5e26f Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Tue, 28 Apr 2020 13:55:34 -0500 Subject: [PATCH 092/547] implement df-other-vectors-type for lua --- library/LuaTypes.cpp | 22 ++++++++++++++++++++++ library/include/DataDefs.h | 18 ++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/library/LuaTypes.cpp b/library/LuaTypes.cpp index 306538f51..c46d7ce05 100644 --- a/library/LuaTypes.cpp +++ b/library/LuaTypes.cpp @@ -1422,6 +1422,28 @@ void struct_identity::build_metatable(lua_State *state) SetPtrMethods(state, base+1, base+2); } +void other_vectors_identity::build_metatable(lua_State *state) +{ + int base = lua_gettop(state); + MakeFieldMetatable(state, this, meta_struct_index, meta_struct_newindex); + + EnableMetaField(state, base+2, "_enum"); + + LookupInTable(state, index_enum, &DFHACK_TYPEID_TABLE_TOKEN); + lua_setfield(state, base+1, "_enum"); + + auto keys = &index_enum->getKeys()[-index_enum->getFirstItem()]; + + for (int64_t i = 0; i < index_enum->getLastItem(); i++) + { + lua_getfield(state, base+2, keys[i]); + lua_rawseti(state, base+2, int(i)); + } + + SetStructMethod(state, base+1, base+2, meta_struct_field_reference, "_field"); + SetPtrMethods(state, base+1, base+2); +} + void global_identity::build_metatable(lua_State *state) { int base = lua_gettop(state); diff --git a/library/include/DataDefs.h b/library/include/DataDefs.h index 3b961df20..f4eff8510 100644 --- a/library/include/DataDefs.h +++ b/library/include/DataDefs.h @@ -334,6 +334,23 @@ namespace DFHack virtual identity_type type() { return IDTYPE_UNION; } }; + class DFHACK_EXPORT other_vectors_identity : public struct_identity { + enum_identity *index_enum; + + public: + other_vectors_identity(size_t size, TAllocateFn alloc, + compound_identity *scope_parent, const char *dfhack_name, + struct_identity *parent, const struct_field_info *fields, + enum_identity *index_enum) : + struct_identity(size, alloc, scope_parent, dfhack_name, parent, fields), + index_enum(index_enum) + {} + + enum_identity *getIndexEnum() { return index_enum; } + + virtual void build_metatable(lua_State *state); + }; + #ifdef _MSC_VER typedef void *virtual_ptr; #else @@ -465,6 +482,7 @@ namespace df using DFHack::global_identity; using DFHack::struct_identity; using DFHack::union_identity; + using DFHack::other_vectors_identity; using DFHack::struct_field_info; using DFHack::struct_field_info_extra; using DFHack::bitfield_item_info; From 28c34217d86a77b6eafe26aca1c3ff371cb65ecb Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Tue, 28 Apr 2020 14:26:33 -0500 Subject: [PATCH 093/547] Ruby implementation of df-other-vectors-type --- plugins/ruby/codegen.pl | 8 ++++++++ plugins/ruby/ruby-autogen-defs.rb | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/plugins/ruby/codegen.pl b/plugins/ruby/codegen.pl index 2a12a1bea..535a49694 100755 --- a/plugins/ruby/codegen.pl +++ b/plugins/ruby/codegen.pl @@ -240,6 +240,12 @@ sub render_global_class { } my $rbparent = ($parent ? rb_ucase($parent) : 'MemHack::Compound'); + my $ienum; + if (($type->getAttribute('ld:subtype') or '') eq 'df-other-vectors-type') + { + $rbparent = 'MemHack::OtherVectors'; + $ienum = rb_ucase($type->getAttribute('index-enum')); + } push @lines_rb, "class $rbname < $rbparent"; indent_rb { my $sz = sizeof($type); @@ -249,6 +255,8 @@ sub render_global_class { push @lines_rb, "rtti_classname :$rtti_name\n" if $rtti_name; + push @lines_rb, "ienum $ienum\n" if $ienum; + render_struct_fields($type); my $vms = $type->findnodes('child::virtual-methods')->[0]; diff --git a/plugins/ruby/ruby-autogen-defs.rb b/plugins/ruby/ruby-autogen-defs.rb index 10727894d..c72ffeb2b 100644 --- a/plugins/ruby/ruby-autogen-defs.rb +++ b/plugins/ruby/ruby-autogen-defs.rb @@ -205,6 +205,22 @@ module DFHack end end + class OtherVectors < Compound + class << self + attr_accessor :_enum + def ienum(enum) + @_enum = enum + end + end + + def [](i) + self.send(self.class._enum.sym(i)) + end + def []=(i, v) + self.send((self.class._enum.sym(i).to_s + "=").to_sym, v) + end + end + class Enum # number -> symbol def self.enum From 94d7f3b3475a6b1ff1c773e81395acb88f660ff7 Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 13 May 2020 22:25:42 -0400 Subject: [PATCH 094/547] Update docs on cloning and git stuff --- docs/Compile.rst | 106 ++++++++++++++++++++++++++++-------------- docs/Introduction.rst | 1 + 2 files changed, 71 insertions(+), 36 deletions(-) diff --git a/docs/Compile.rst b/docs/Compile.rst index f30775a03..3e7f9701e 100644 --- a/docs/Compile.rst +++ b/docs/Compile.rst @@ -2,10 +2,16 @@ Compiling DFHack ################ -You don't need to compile DFHack unless you're developing plugins or working on the core. +DFHack builds are available for all supported platforms; see `installing` for +installation instructions. If you are a DFHack end-user, modder, or plan on +writing scripts (not plugins), it is generally recommended (and easier) to use +these builds instead of compiling DFHack from source. -For users, modders, and authors of scripts it's better to download -and `install the latest release instead `. +However, if you are looking to develop plugins, work on the DFHack core, make +complex changes to DF-structures, or anything else that requires compiling +DFHack from source, this document will walk you through the build process. Note +that some steps may be unconventional compared to other projects, so be sure to +pay close attention if this is your first time compiling DFHack. .. contents:: :depth: 2 @@ -14,35 +20,60 @@ and `install the latest release instead `. How to get the code =================== -DFHack doesn't have any kind of system of code snapshots in place, so you will have to -get code from the GitHub repository using Git. How to get Git is described under -the instructions for each platform. - -To get the latest release code (master branch):: +DFHack uses Git for source control; instructions for installing Git can be found +in the platform-specific sections below. The code is hosted on +`GitHub `_, and can be downloaded with:: git clone --recursive https://github.com/DFHack/dfhack cd dfhack -If your version of Git does not support the ``--recursive`` flag, you will need to omit it and run -``git submodule update --init`` after entering the dfhack directory. +If your version of Git does not support the ``--recursive`` flag, you will need +to omit it and run ``git submodule update --init`` after entering the dfhack +directory. -To get the latest development code (develop branch), clone as above and then:: +This will check out the code on the default branch of the GitHub repo, currently +``develop``, which may be unstable. If you want code for the latest stable +release, you can check out the ``master`` branch instead:: - git checkout develop + git checkout master git submodule update -Generally, you should only need to clone DFHack once. - -**Important note regarding submodule update after pulling or changing branches**: - -You must run ``git submodule update`` every time you change branches, such as -when switching between the master and develop branches or vice versa. You also -must run it after pulling any changes to submodules from the DFHack repo. If a -submodule only exists on the newer branch, or if a commit you just pulled -contains a new submodule, you need to run ``git submodule update --init``. -Failure to do this may result in a variety of errors, including ``fatal: -does not exist`` when using Git, errors when building DFHack, and ``not a known -DF version`` when starting DF. +In general, a single DFHack clone is suitable for development - most Git +operations such as switching branches can be done on an existing clone. If you +find yourself cloning DFHack frequently as part of your development process, or +getting stuck on anything else Git-related, feel free to reach out to us for +assistance. + +.. admonition:: A note on submodules + + DFHack uses submodules extensively to manage its subprojects (including the + ``scripts`` folder and DF-structures in ``library/xml``). Failing to keep + submodules in sync when switching between branches can result in build errors + or scripts that don't work. In general, you should always update submodules + whenever you switch between branches in the main DFHack repo with + ``git submodule update``. (If you are working on bleeding-edge DFHack and + have checked out the master branch of some submodules, running ``git pull`` + in those submodules is also an option.) + + Rarely, we add or remove submodules. If there are any changes to the existence + of submodules when you switch between branches, you should run + ``git submodule update --init`` instead (adding ``--init`` to the above + command). + + Some common errors that can arise when failing to update submodules include: + + * ``fatal: does not exist`` when performing Git operations + * Build errors, particularly referring to structures in the ``df::`` namespace + or the ``library/include/df`` folder + * ``Not a known DF version`` when starting DF + * ``Run 'git submodule update --init'`` when running CMake + + Submodules are a particularly confusing feature of Git. The + `Git Book `_ has a + thorough explanation of them (as well as of many other aspects of Git) and + is a recommended resource if you run into any issues. Other DFHack developers + are also able to help with any submodule-related (or Git-related) issues + you may encounter. **More notes**: @@ -51,18 +82,21 @@ DF version`` when starting DF. Contributing to DFHack ====================== -If you want to get involved with the development, create an account on -GitHub, make a clone there and then use that as your remote repository instead. - -We'd love that; join us on IRC_ (#dfhack channel on freenode) for discussion, -and whenever you need help. - -.. _IRC: https://webchat.freenode.net/?channels=dfhack - -(Note: for submodule issues, please see the above instructions first!) - -For lots more details on contributing to DFHack, including pull requests, code format, -and more, please see `contributing-code`. +To contribute to DFHack on GitHub, you will need a GitHub account. Only some +DFHack developers can push directly to the DFHack repositories; we recommend +making a fork of whatever repos you are interested in contributing to, making +changes there, and submitting pull requests. `GitHub's pull request tutorial +`_ +is a good resource for getting started with pull requests (some things to note: +our work mainly happens on the ``develop`` branch, and you will need to use +your own fork, assuming that you don't have write access to the DFHack repos). + +Most development-related discussion happens on IRC or in individual GitHub +issues and pull requests, but there are also other ways to reach out - see +`support` for details. + +For more details on contributing to DFHack, including pull requests, code +format, and more, please see `contributing-code`. Build settings diff --git a/docs/Introduction.rst b/docs/Introduction.rst index 3a36aa538..09e38e52f 100644 --- a/docs/Introduction.rst +++ b/docs/Introduction.rst @@ -87,6 +87,7 @@ the console. .. _troubleshooting: +.. _support: Troubleshooting =============== From df06f31137cfc931dcd37e81263e6a55f8586acf Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 13 May 2020 22:25:56 -0400 Subject: [PATCH 095/547] Update forum thread link --- docs/Introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Introduction.rst b/docs/Introduction.rst index 09e38e52f..22033d528 100644 --- a/docs/Introduction.rst +++ b/docs/Introduction.rst @@ -102,7 +102,7 @@ If the search function in this documentation isn't enough and :wiki:`the DF Wiki <>` hasn't helped, try asking in: - the `#dfhack IRC channel on freenode `_ -- the :forums:`Bay12 DFHack thread <139553>` +- the `Bay12 DFHack thread `_ - the `/r/dwarffortress `_ questions thread - the thread for the mod or Starter Pack you're using (if any) From 7a9be264c6464a482418b92a8578d158c1789a0d Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 13 May 2020 22:46:09 -0400 Subject: [PATCH 096/547] Update Linux GCC docs and some ninja notes --- docs/Compile.rst | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/docs/Compile.rst b/docs/Compile.rst index 3e7f9701e..f61d89e2e 100644 --- a/docs/Compile.rst +++ b/docs/Compile.rst @@ -112,7 +112,8 @@ Generator The ``Ninja`` CMake build generator is the prefered build method on Linux and macOS, instead of ``Unix Makefiles``, which is the default. You can select Ninja by passing ``-G Ninja`` to CMake. Incremental builds using Unix Makefiles can be -much slower than Ninja builds. +much slower than Ninja builds. Note that you will probably need to install +Ninja; see the platform-specific sections for details. :: @@ -178,13 +179,18 @@ DFHack is meant to be installed into an existing DF folder, so get one ready. We assume that any Linux platform will have ``git`` available (though it may need to be installed with your package manager.) -To build DFHack you need GCC version 4.8 or later. GCC 4.8 is easiest to work -with due to avoiding libstdc++ issues (see below), but any version from 4.8 -onwards (including 5.x) will work. +To build DFHack, you need GCC 4.8 or newer. GCC 4.8 has the benefit of avoiding +`libstdc++ compatibility issues `, but can be hard +to obtain on modern distributions, and working around these issues is done +automatically by the ``dfhack`` launcher script. As long as your system-provided +GCC is new enough, it should work. Note that extremely new GCC versions may not +have been used to build DFHack yet, so if you run into issues with these, please +let us know (e.g. by opening a GitHub issue). Before you can build anything, you'll also need ``cmake``. It is advisable to also get ``ccmake`` on distributions that split the cmake package into multiple -parts. +parts. As mentioned above, ``ninja`` is recommended (many distributions call +this package ``ninja-build``). You will need pthread; most systems should have this already. Note that older CMake versions may have trouble detecting pthread, so if you run into @@ -260,29 +266,32 @@ This will show a curses-based interface that lets you set all of the extra options. You can also use a cmake-friendly IDE like KDevelop 4 or the cmake-gui program. +.. _linux-incompatible-libstdcxx: + Incompatible libstdc++ ~~~~~~~~~~~~~~~~~~~~~~ -When compiling dfhack yourself, it builds against your system libstdc++. When -Dwarf Fortress runs, it uses a libstdc++ shipped with the binary, which comes -from GCC 4.8 and is incompatible with code compiled with newer GCC versions. If -you compile DFHack with a GCC version newer than 4.8, you will see an error -message such as:: +When compiling DFHack yourself, it builds against your system libstdc++. When +Dwarf Fortress runs, it uses a libstdc++ shipped in the ``libs`` folder, which +comes from GCC 4.8 and is incompatible with code compiled with newer GCC +versions. As of DFHack 0.42.05-alpha1, the ``dfhack`` launcher script attempts +to fix this by automatically removing the DF-provided libstdc++ on startup. +In rare cases, this may fail and cause errors such as:: ./libs/Dwarf_Fortress: /pathToDF/libs/libstdc++.so.6: version `GLIBCXX_3.4.18' not found (required by ./hack/libdfhack.so) -To fix this you can compile with GCC 4.8 or remove the libstdc++ shipped with +The easiest way to fix this is generally removing the libstdc++ shipped with DF, which causes DF to use your system libstdc++ instead:: cd /path/to/DF/ rm libs/libstdc++.so.6 -Note that distributing binaries compiled with newer GCC versions requires end- -users to delete libstdc++ themselves and have a libstdc++ on their system from -the same GCC version or newer. For this reason, distributing anything compiled -with GCC versions newer than 4.8 is discouraged. In the future we may start -bundling a later libstdc++ as part of the DFHack package, so as to enable -compilation-for-distribution with a GCC newer than 4.8. +Note that distributing binaries compiled with newer GCC versions may result in +the opposite compatibily 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. + Mac OS X ======== From d189b91f4997b35fa691dcf2e809ee0860fcba9e Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 13 May 2020 22:58:32 -0400 Subject: [PATCH 097/547] Update macOS -> OS X, tweak a bit and add more anchors --- docs/Compile.rst | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/docs/Compile.rst b/docs/Compile.rst index f61d89e2e..6ebaa8c1f 100644 --- a/docs/Compile.rst +++ b/docs/Compile.rst @@ -168,6 +168,9 @@ your build folder or by running ``ccmake`` (or another CMake GUI). Most DFHack-specific settings begin with ``BUILD_`` and control which parts of DFHack are built. + +.. _compile-linux: + Linux ===== On Linux, DFHack acts as a library that shadows parts of the SDL API using LD_PRELOAD. @@ -293,13 +296,15 @@ you are planning on distributing binaries to other users, we recommend using an older GCC (but still at least 4.8) version if possible. -Mac OS X -======== -DFHack functions similarly on OS X and Linux, and the majority of the -information above regarding the build process (cmake and ninja) applies here +.. _compile-macos: + +macOS +===== +DFHack functions similarly on macOS and Linux, and the majority of the +information above regarding the build process (CMake and Ninja) applies here as well. -DFHack can officially be built on OS X with GCC 4.8 or 7. Anything newer than 7 +DFHack can officially be built on macOS only with GCC 4.8 or 7. Anything newer than 7 will require you to perform extra steps to get DFHack to run (see `osx-new-gcc-notes`), and your build will likely not be redistributable. @@ -352,7 +357,7 @@ Dependencies and system set-up cleaner, quicker, and smarter. For example, installing MacPort's GCC will install more than twice as many dependencies as Homebrew's will, and all in both 32-bit and 64-bit variants. Homebrew also doesn't require constant use - of sudo. + of ``sudo``. Using `Homebrew `_ (recommended):: @@ -421,9 +426,9 @@ Building export CC=gcc-7 export CXX=g++-7 - etc. + (adjust as needed for different GCC installations) -* Build dfhack:: +* Build DFHack:: mkdir build-osx cd build-osx @@ -433,6 +438,7 @@ Building should be a path to a copy of Dwarf Fortress, of the appropriate version for the DFHack you are building. + .. _compile-windows: Windows @@ -725,9 +731,9 @@ It may be installed in a directory such as ``~/.local/bin/``, so after pip install, find ``sphinx-build`` and ensure its directory is in your local ``$PATH``. -Mac OS X --------- -OS X has Python 2.7 installed by default, but it does not have the pip package manager. +macOS +----- +macOS has Python 2.7 installed by default, but it does not have the pip package manager. You can install Homebrew's Python 3, which includes pip, and then install the latest Sphinx using pip:: @@ -739,11 +745,11 @@ Alternatively, you can simply install Sphinx 1.3.x directly from Homebrew:: brew install sphinx-doc -This will install Sphinx for OS X's system Python 2.7, without needing pip. +This will install Sphinx for macOS's system Python 2.7, without needing pip. Either method works; if you plan to use Python for other purposes, it might best to install Homebrew's Python 3 so that you have the latest Python as well as pip. -If not, just installing sphinx-doc for OS X's system Python 2.7 is fine. +If not, just installing sphinx-doc for macOS's system Python 2.7 is fine. Windows @@ -810,7 +816,7 @@ files alphabetically, so all the files you need should be next to each other. It is recommended that you create a build folder and run CMake to verify that you have downloaded everything at this point, assuming your download machine has CMake installed. This involves running a "generate" batch script on Windows, or -a command starting with ``cmake .. -G Ninja`` on Linux and OS X, following the +a command starting with ``cmake .. -G Ninja`` on Linux and macOS, following the instructions in the sections above. CMake should automatically locate files that you placed in ``CMake/downloads``, and use them instead of attempting to download them. From 7dd4b6d9685cbbbb9dda44129967e34b9b5970e8 Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Thu, 14 May 2020 13:07:11 -0500 Subject: [PATCH 098/547] update structures --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index efc5c2610..cbeed8b52 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit efc5c2610bd0345e9102279be0a9f154e5862050 +Subproject commit cbeed8b52482ce749fc2ff13a9db9733931e7da0 From f20446534bb7f39425e102bd70daec46e328004f Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Thu, 14 May 2020 14:01:05 -0500 Subject: [PATCH 099/547] fix DfOtherVectors computed size --- library/include/BitArray.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/include/BitArray.h b/library/include/BitArray.h index 5858897a3..1f558221a 100644 --- a/library/include/BitArray.h +++ b/library/include/BitArray.h @@ -574,7 +574,7 @@ namespace DFHack { std::vector & operator[](O other_id) { - CHECK_INVALID_ARGUMENT(size_t(other_id) < sizeof(*this) / sizeof(std::vector)); + CHECK_INVALID_ARGUMENT(size_t(other_id) < sizeof(T) / sizeof(std::vector)); auto vectors = reinterpret_cast *>(this); return vectors[other_id]; From 3db490ee9e31c7a0f950f242b8c338a161a63fcc Mon Sep 17 00:00:00 2001 From: Rose Date: Fri, 22 May 2020 08:01:34 -0700 Subject: [PATCH 100/547] Fix a problem where the block coordinates would sometimes not get copied. --- plugins/remotefortressreader/remotefortressreader.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/plugins/remotefortressreader/remotefortressreader.cpp b/plugins/remotefortressreader/remotefortressreader.cpp index e94c3f832..8e9ac8d45 100644 --- a/plugins/remotefortressreader/remotefortressreader.cpp +++ b/plugins/remotefortressreader/remotefortressreader.cpp @@ -949,9 +949,6 @@ static command_result GetGrowthList(color_ostream &stream, const EmptyMessage *i void CopyBlock(df::map_block * DfBlock, RemoteFortressReader::MapBlock * NetBlock, MapExtras::MapCache * MC, DFCoord pos) { - NetBlock->set_map_x(DfBlock->map_pos.x); - NetBlock->set_map_y(DfBlock->map_pos.y); - NetBlock->set_map_z(DfBlock->map_pos.z); MapExtras::Block * block = MC->BlockAtTile(DfBlock->map_pos); @@ -1465,7 +1462,12 @@ static command_result GetBlockList(color_ostream &stream, const BlockRequest *in bool flows = block->flows.size() > 0; RemoteFortressReader::MapBlock *net_block = nullptr; if (tileChanged || desChanged || spatterChanged || firstBlock || itemsChanged || flows) + { net_block = out->add_map_blocks(); + net_block->set_map_x(block->map_pos.x); + net_block->set_map_y(block->map_pos.y); + net_block->set_map_z(block->map_pos.z); + } if (tileChanged) { CopyBlock(block, net_block, &MC, pos); From ad3735421186f56e2097e8324610b9aa77969722 Mon Sep 17 00:00:00 2001 From: Rose Date: Sun, 24 May 2020 15:42:59 -0700 Subject: [PATCH 101/547] Bump version number to make sure the updater works. --- plugins/remotefortressreader/remotefortressreader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/remotefortressreader/remotefortressreader.cpp b/plugins/remotefortressreader/remotefortressreader.cpp index 4ab540a5e..5a8957ddf 100644 --- a/plugins/remotefortressreader/remotefortressreader.cpp +++ b/plugins/remotefortressreader/remotefortressreader.cpp @@ -1,5 +1,5 @@ #include "df_version_int.h" -#define RFR_VERSION "0.20.3" +#define RFR_VERSION "0.21.0" #include #include From 2fc7fa7ac2e56bffa5775e33fc3a3a8cafd6f364 Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 28 May 2020 23:11:08 -0400 Subject: [PATCH 102/547] Update xml, scripts See #1576 --- library/xml | 2 +- scripts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/xml b/library/xml index cbeed8b52..995caf761 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit cbeed8b52482ce749fc2ff13a9db9733931e7da0 +Subproject commit 995caf76159ae84046f723ebb4547f9a9eae372c diff --git a/scripts b/scripts index 2079b9fb6..47d9b3c93 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 2079b9fb69b8b4db48aa35ec54a96f5cca7cc8ef +Subproject commit 47d9b3c9390d21ecc49ddaba477b16071884ee87 From 5d05cfc7ccadbad5dceab045f8e66bb064a2c43c Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Tue, 2 Jun 2020 01:15:33 -0500 Subject: [PATCH 103/547] Fix several functions in the Units module ignoring unit caste. Fixes #1583. --- docs/changelog.txt | 1 + library/modules/Units.cpp | 52 +++++++++++---------------------------- 2 files changed, 15 insertions(+), 38 deletions(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index 1aa7f916e..90492cdfc 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: ## Fixes - Fixed a segfault when attempting to start a headless session with a graphical PRINT_MODE setting - `labormanager`: fixed handling of new jobs in 0.47 +- Fixed ``Units::isEggLayer``, ``Units::isGrazer``, ``Units::isMilkable``, ``Units::isTrainableHunting``, ``Units::isTrainableWar``, and ``Units::isTamable`` ignoring the unit's caste ## Ruby - Updated ``item_find`` and ``building_find`` to use centralized logic that works on more screens diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index c4b9e60fa..422060803 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -636,74 +636,50 @@ bool Units::isEggLayer(df::unit* unit) { CHECK_NULL_POINTER(unit); df::creature_raw *raw = world->raws.creatures.all[unit->race]; - for (auto caste = raw->caste.begin(); caste != raw->caste.end(); ++caste) - { - if ((*caste)->flags.is_set(caste_raw_flags::LAYS_EGGS) - || (*caste)->flags.is_set(caste_raw_flags::LAYS_UNUSUAL_EGGS)) - return true; - } - return false; + df::caste_raw *caste = raw->caste.at(unit->caste); + return caste->flags.is_set(caste_raw_flags::LAYS_EGGS) + || caste->flags.is_set(caste_raw_flags::LAYS_UNUSUAL_EGGS); } bool Units::isGrazer(df::unit* unit) { CHECK_NULL_POINTER(unit); df::creature_raw *raw = world->raws.creatures.all[unit->race]; - for (auto caste = raw->caste.begin(); caste != raw->caste.end(); ++caste) - { - if((*caste)->flags.is_set(caste_raw_flags::GRAZER)) - return true; - } - return false; + df::caste_raw *caste = raw->caste.at(unit->caste); + return caste->flags.is_set(caste_raw_flags::GRAZER); } bool Units::isMilkable(df::unit* unit) { CHECK_NULL_POINTER(unit); df::creature_raw *raw = world->raws.creatures.all[unit->race]; - for (auto caste = raw->caste.begin(); caste != raw->caste.end(); ++caste) - { - if((*caste)->flags.is_set(caste_raw_flags::MILKABLE)) - return true; - } - return false; + df::caste_raw *caste = raw->caste.at(unit->caste); + return caste->flags.is_set(caste_raw_flags::MILKABLE); } bool Units::isTrainableWar(df::unit* unit) { CHECK_NULL_POINTER(unit); df::creature_raw *raw = world->raws.creatures.all[unit->race]; - for (auto caste = raw->caste.begin(); caste != raw->caste.end(); ++caste) - { - if((*caste)->flags.is_set(caste_raw_flags::TRAINABLE_WAR)) - return true; - } - return false; + df::caste_raw *caste = raw->caste.at(unit->caste); + return caste->flags.is_set(caste_raw_flags::TRAINABLE_WAR); } bool Units::isTrainableHunting(df::unit* unit) { CHECK_NULL_POINTER(unit); df::creature_raw *raw = world->raws.creatures.all[unit->race]; - for (auto caste = raw->caste.begin(); caste != raw->caste.end(); ++caste) - { - if((*caste)->flags.is_set(caste_raw_flags::TRAINABLE_HUNTING)) - return true; - } - return false; + df::caste_raw *caste = raw->caste.at(unit->caste); + return caste->flags.is_set(caste_raw_flags::TRAINABLE_HUNTING); } bool Units::isTamable(df::unit* unit) { CHECK_NULL_POINTER(unit); df::creature_raw *raw = world->raws.creatures.all[unit->race]; - for (auto caste = raw->caste.begin(); caste != raw->caste.end(); ++caste) - { - if((*caste)->flags.is_set(caste_raw_flags::PET) || - (*caste)->flags.is_set(caste_raw_flags::PET_EXOTIC)) - return true; - } - return false; + df::caste_raw *caste = raw->caste.at(unit->caste); + return caste->flags.is_set(caste_raw_flags::PET) + || caste->flags.is_set(caste_raw_flags::PET_EXOTIC); } bool Units::isMale(df::unit* unit) From d5b5b81450fca0394e378420c13be64a02828f78 Mon Sep 17 00:00:00 2001 From: PatrikLundell Date: Tue, 2 Jun 2020 15:03:59 +0200 Subject: [PATCH 104/547] changes --- library/modules/Units.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index 43eb9026c..458a09ea3 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -204,14 +204,15 @@ void Units::setNickname(df::unit *unit, std::string nick) df::historical_figure *id_hfig = NULL; switch (identity->type) { + case df::identity_type::None: case df::identity_type::HidingCurse: - case df::identity_type::Identity: case df::identity_type::FalseIdentity: + case df::identity_type::InfiltrationIdentity: + case df::identity_type::Identity: break; // We want the nickname to end up in the identity case df::identity_type::Impersonating: case df::identity_type::TrueName: - case df::identity_type::Unk_4: // Pure guess, as this is a new case, still unseen id_hfig = df::historical_figure::find(identity->histfig_id); break; } From 4a48c356a9b5c2a283a5ba19d068a488ae94861a Mon Sep 17 00:00:00 2001 From: PatrikLundell Date: Tue, 2 Jun 2020 15:58:46 +0200 Subject: [PATCH 105/547] fixed bug with incursion handling along world tile edges --- plugins/embark-assistant/defs.h | 2 ++ plugins/embark-assistant/survey.cpp | 25 +++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/plugins/embark-assistant/defs.h b/plugins/embark-assistant/defs.h index 29c5a063c..13494b91e 100644 --- a/plugins/embark-assistant/defs.h +++ b/plugins/embark-assistant/defs.h @@ -119,6 +119,8 @@ namespace embark_assist { df::world_region_type region_type[16][16]; // Required for incursion override detection. We could store only the // edges, but storing it for every tile allows for a unified fetching // logic. + int8_t north_row_biome_x[16]; // "biome_x" data cached for the northern row for access from the north. + int8_t west_column_biome_y[16]; // "biome_y" data cached for the western row for access from the west. }; struct geo_datum { diff --git a/plugins/embark-assistant/survey.cpp b/plugins/embark-assistant/survey.cpp index 20dd9d539..01ed9ba31 100644 --- a/plugins/embark-assistant/survey.cpp +++ b/plugins/embark-assistant/survey.cpp @@ -1470,6 +1470,8 @@ void embark_assist::survey::survey_mid_level_tile(embark_assist::defs::geo_data tile->north_corner_selection[i] = world_data->region_details[0]->edges.biome_corner[i][0]; tile->west_corner_selection[i] = world_data->region_details[0]->edges.biome_corner[0][i]; + tile->north_row_biome_x[i] = world_data->region_details[0]->edges.biome_x[i][0]; + tile->west_column_biome_y[i] = world_data->region_details[0]->edges.biome_y[0][i]; } for (uint8_t i = 0; i < 16; i++) { @@ -1919,7 +1921,17 @@ uint8_t embark_assist::survey::translate_ns_edge(embark_assist::defs::world_tile north_region_type = embark_assist::survey::region_type_of(survey_results, x, y, i, k - 1); } else { - effective_edge = world_data->region_details[0]->edges.biome_x[i][k + 1]; + if (k < 15) { // We're still within the same world tile + effective_edge = world_data->region_details[0]->edges.biome_x[i][k + 1]; + } + else { // Getting the data from the world tile to the south + if (y + 1 == world_data->world_height) { + return 4; // There's nothing to the south, so we fall back on our own tile. + } + + effective_edge = survey_results->at(x).at(y + 1).north_row_biome_x[i]; + } + north_region_type = embark_assist::survey::region_type_of(survey_results, x, y, i, k); south_region_type = embark_assist::survey::region_type_of(survey_results, x, y, i, k + 1); } @@ -1993,7 +2005,16 @@ uint8_t embark_assist::survey::translate_ew_edge(embark_assist::defs::world_tile west_region_type = embark_assist::survey::region_type_of(survey_results, x, y, i - 1, k); } else { - effective_edge = world_data->region_details[0]->edges.biome_y[i + 1][k]; + if (i < 15) { // We're still within the same world tile + effective_edge = world_data->region_details[0]->edges.biome_y[i + 1][k]; + } + else { // Getting the data from the world tile to the east + if (x + 1 == world_data->world_width) { + return 4; // There's nothing to the east, so we fall back on our own tile. + } + + effective_edge = survey_results->at(x + 1).at(y).west_column_biome_y[k]; + } west_region_type = embark_assist::survey::region_type_of(survey_results, x, y, i, k); east_region_type = embark_assist::survey::region_type_of(survey_results, x, y, i + 1, k); } From d5a491e85238931786e737c82854d0bc53bc8f6a Mon Sep 17 00:00:00 2001 From: PatrikLundell Date: Sun, 7 Jun 2020 08:38:12 +0200 Subject: [PATCH 106/547] fixed parameter bugs --- plugins/embark-assistant/survey.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/embark-assistant/survey.cpp b/plugins/embark-assistant/survey.cpp index 01ed9ba31..2d5dca04d 100644 --- a/plugins/embark-assistant/survey.cpp +++ b/plugins/embark-assistant/survey.cpp @@ -1603,7 +1603,7 @@ df::world_region_type embark_assist::survey::region_type_of(embark_assist::defs: int16_t effective_y = y; int8_t effective_i = i; int8_t effective_k = k; - adjust_coordinates(&effective_x, &effective_y, &effective_i, &effective_i); + adjust_coordinates(&effective_x, &effective_y, &effective_i, &effective_k); if (effective_x < 0 || effective_x >= world_data->world_width || @@ -1659,7 +1659,7 @@ uint8_t embark_assist::survey::translate_corner(embark_assist::defs::world_tile effective_k = k + 1; } - adjust_coordinates(&effective_x, &effective_y, &effective_i, &effective_i); + adjust_coordinates(&effective_x, &effective_y, &effective_i, &effective_k); if (effective_x == world_data->world_width) { if (effective_y == world_data->world_height) { // Only the SE corner of the SE most tile of the world can reference this. From bd216dbc117bdb197fe12febaf1285f5a67c57d7 Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Mon, 15 Jun 2020 23:47:35 -0500 Subject: [PATCH 107/547] update structures --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index 995caf761..b80a661f1 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 995caf76159ae84046f723ebb4547f9a9eae372c +Subproject commit b80a661f1139eb8535e6f76f8a07b697eeb9c9de From 97a20acf1b3bcb83e84e85e0ced0eeb4e33f2269 Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 17 Jun 2020 20:32:30 -0400 Subject: [PATCH 108/547] Add current year to docs copyright message --- conf.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/conf.py b/conf.py index 2f47d5644..c36e4f8aa 100644 --- a/conf.py +++ b/conf.py @@ -15,6 +15,7 @@ serve to show the default. # pylint:disable=redefined-builtin +import datetime from io import open import os import re @@ -222,7 +223,7 @@ master_doc = 'index' # General information about the project. project = 'DFHack' -copyright = '2015, The DFHack Team' +copyright = '2015-%d, The DFHack Team' % datetime.datetime.now().year author = 'The DFHack Team' # The version info for the project you're documenting, acts as replacement for From 861c8c81482e87e7bc07c4faaaa103505f8876f0 Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 17 Jun 2020 20:36:07 -0400 Subject: [PATCH 109/547] Remove -q from docs/build.sh to make -v work --- docs/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/build.sh b/docs/build.sh index 6745db4d5..48e1bfd4a 100755 --- a/docs/build.sh +++ b/docs/build.sh @@ -17,4 +17,4 @@ if [ -z "$JOBS" ]; then JOBS=2 fi -"$sphinx" -a -E -q -b html . ./docs/html -w ./docs/_sphinx-warnings.txt -j "$JOBS" "$@" +"$sphinx" -a -E -b html . ./docs/html -w ./docs/_sphinx-warnings.txt -j "$JOBS" "$@" From 5073bd31c4545e91f78623d7c28b0a61fa813d4a Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Fri, 19 Jun 2020 19:37:44 -0500 Subject: [PATCH 110/547] update structures --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index b80a661f1..bc42fe311 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit b80a661f1139eb8535e6f76f8a07b697eeb9c9de +Subproject commit bc42fe3114a7943850b32231559adf54bb1d0c60 From aee4fcd1a6fd708f706e03bee01d4287e0d656f9 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 20 Jun 2020 12:02:13 -0400 Subject: [PATCH 111/547] Add confirmation for convicting dwarves of crimes Closes #1593 --- docs/changelog.txt | 3 +++ plugins/confirm.cpp | 2 ++ plugins/lua/confirm.lua | 15 +++++++++++++++ 3 files changed, 20 insertions(+) diff --git a/docs/changelog.txt b/docs/changelog.txt index 90492cdfc..c165ff855 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -44,6 +44,9 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - `labormanager`: fixed handling of new jobs in 0.47 - Fixed ``Units::isEggLayer``, ``Units::isGrazer``, ``Units::isMilkable``, ``Units::isTrainableHunting``, ``Units::isTrainableWar``, and ``Units::isTamable`` ignoring the unit's caste +## Misc Improvements +- `confirm`: added a confirmation dialog for convicting dwarves of crimes + ## Ruby - Updated ``item_find`` and ``building_find`` to use centralized logic that works on more screens diff --git a/plugins/confirm.cpp b/plugins/confirm.cpp index c616ac493..07aee4640 100644 --- a/plugins/confirm.cpp +++ b/plugins/confirm.cpp @@ -18,6 +18,7 @@ #include "df/general_ref.h" #include "df/general_ref_contained_in_itemst.h" #include "df/viewscreen_dwarfmodest.h" +#include "df/viewscreen_justicest.h" #include "df/viewscreen_layer_militaryst.h" #include "df/viewscreen_locationsst.h" #include "df/viewscreen_tradegoodsst.h" @@ -479,6 +480,7 @@ DEFINE_CONFIRMATION(uniform_delete, viewscreen_layer_militaryst); DEFINE_CONFIRMATION(note_delete, viewscreen_dwarfmodest); DEFINE_CONFIRMATION(route_delete, viewscreen_dwarfmodest); DEFINE_CONFIRMATION(location_retire, viewscreen_locationsst); +DEFINE_CONFIRMATION(convict, viewscreen_justicest); DFhackCExport command_result plugin_init (color_ostream &out, vector &commands) { diff --git a/plugins/lua/confirm.lua b/plugins/lua/confirm.lua index 4312ab4be..b8a815662 100644 --- a/plugins/lua/confirm.lua +++ b/plugins/lua/confirm.lua @@ -204,6 +204,21 @@ end location_retire.title = "Retire location" location_retire.message = "Are you sure you want to retire this location?" +convict = defconf('convict') +convict.title = "Confirm conviction" +function convict.intercept_key(key) + return key == keys.SELECT and + screen.cur_column == df.viewscreen_justicest.T_cur_column.ConvictChoices +end +function convict.get_message() + name = dfhack.TranslateName(screen.convict_choices[screen.cursor_right].name) + if name == "" then + name = "this creature" + end + return "Are you sure you want to convict " .. name .. "?\n" .. + "This action is irreversible." +end + -- End of confirmation definitions function check() From 7ddc3bb9187f7c9c74859a17ce977467f4151eb6 Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Sat, 20 Jun 2020 23:05:55 -0500 Subject: [PATCH 112/547] fix labor inferences for custom furnaces Also clean up how paved roads are handled (the way it was was stupid) --- plugins/labormanager/joblabormapper.cpp | 40 ++++++++++++++++++++----- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/plugins/labormanager/joblabormapper.cpp b/plugins/labormanager/joblabormapper.cpp index 7b4e77553..54ef9cceb 100644 --- a/plugins/labormanager/joblabormapper.cpp +++ b/plugins/labormanager/joblabormapper.cpp @@ -200,8 +200,6 @@ static df::building* get_building_from_job(df::job* j) static df::unit_labor construction_build_labor(df::building_actual* b) { - if (b->getType() == df::building_type::RoadPaved) - return df::unit_labor::BUILD_ROAD; // Find last item in building with use mode appropriate to the building's constructions state // For screw pumps contained_items[0] = pipe, 1 corkscrew, 2 block // For wells 0 mechanism, 1 rope, 2 bucket, 3 block @@ -313,14 +311,27 @@ public: return workshop_build_labor[ws->type]; } break; + case df::building_type::Furnace: + { + df::building_furnacest* frn = (df::building_furnacest*) bld; + if (frn->design && !frn->design->flags.bits.designed) + return df::unit_labor::ARCHITECT; + if (frn->type == df::furnace_type::Custom) + { + df::building_def* def = df::building_def::find(frn->custom_type); + return def->build_labors[0]; + } + else + // cast to building_actual should be safe here because at this point the building has been designed + return construction_build_labor((df::building_actual*)bld); + } + break; case df::building_type::Construction: return df::unit_labor::BUILD_CONSTRUCTION; - case df::building_type::Furnace: case df::building_type::TradeDepot: case df::building_type::Bridge: case df::building_type::ArcheryTarget: case df::building_type::WaterWheel: - case df::building_type::RoadPaved: case df::building_type::Well: case df::building_type::ScrewPump: case df::building_type::Wagon: @@ -334,6 +345,8 @@ public: return construction_build_labor(b); } break; + case df::building_type::RoadPaved: + return df::unit_labor::BUILD_ROAD; case df::building_type::FarmPlot: return df::unit_labor::PLANT; case df::building_type::Chair: @@ -418,15 +431,26 @@ public: return workshop_build_labor[ws->type]; } break; + case df::building_type::Furnace: + { + df::building_furnacest* frn = (df::building_furnacest*) bld; + if (frn->type == df::furnace_type::Custom) + { + df::building_def* def = df::building_def::find(frn->custom_type); + return def->build_labors[0]; + } + else + // can't destroy a building if doesn't actually exist + return construction_build_labor((df::building_actual*)bld); + } + break; case df::building_type::Construction: return df::unit_labor::REMOVE_CONSTRUCTION; - case df::building_type::Furnace: case df::building_type::TradeDepot: case df::building_type::Wagon: case df::building_type::Bridge: case df::building_type::ScrewPump: case df::building_type::ArcheryTarget: - case df::building_type::RoadPaved: case df::building_type::Shop: case df::building_type::Support: case df::building_type::WaterWheel: @@ -436,7 +460,9 @@ public: auto b = (df::building_actual*) bld; return construction_build_labor(b); } - break; + break; + case df::building_type::RoadPaved: + return df::unit_labor::BUILD_ROAD; case df::building_type::FarmPlot: return df::unit_labor::PLANT; case df::building_type::Trap: From 7b4ae9b6a3b0cd289dfcea61ef34b5d3e9eae57b Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Sat, 20 Jun 2020 23:08:55 -0500 Subject: [PATCH 113/547] update structures --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index bc42fe311..cd0e5ec3c 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit bc42fe3114a7943850b32231559adf54bb1d0c60 +Subproject commit cd0e5ec3c4588310e5d20c6f28ee1deed2cd33f6 From 61a00f78090adbfe7145907ce8817119acdb7940 Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Sat, 20 Jun 2020 23:10:44 -0500 Subject: [PATCH 114/547] stupid whitespace --- plugins/labormanager/joblabormapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/labormanager/joblabormapper.cpp b/plugins/labormanager/joblabormapper.cpp index 54ef9cceb..4a71b40bf 100644 --- a/plugins/labormanager/joblabormapper.cpp +++ b/plugins/labormanager/joblabormapper.cpp @@ -460,7 +460,7 @@ public: auto b = (df::building_actual*) bld; return construction_build_labor(b); } - break; + break; case df::building_type::RoadPaved: return df::unit_labor::BUILD_ROAD; case df::building_type::FarmPlot: From 85855a2d88ed7ee1bd4457084ea0b617006f0663 Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Sun, 21 Jun 2020 16:16:16 -0500 Subject: [PATCH 115/547] update structures --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index cd0e5ec3c..6f7f33ceb 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit cd0e5ec3c4588310e5d20c6f28ee1deed2cd33f6 +Subproject commit 6f7f33cebbbefefa7c6f920b2fc197b56a3e8d1c From e2301ecae7d7c76778430545c32e0e5e452eebe1 Mon Sep 17 00:00:00 2001 From: Quietust Date: Tue, 23 Jun 2020 13:31:27 -0600 Subject: [PATCH 116/547] Update structures, fix reaction_productst::produce() parms --- library/modules/Items.cpp | 4 ++-- library/xml | 2 +- plugins/add-spatter.cpp | 4 ++-- plugins/createitem.cpp | 4 ++-- plugins/diggingInvaders/assignJob.cpp | 4 ++-- plugins/eventful.cpp | 6 +++--- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/library/modules/Items.cpp b/library/modules/Items.cpp index 05f174ddf..0e02043dc 100644 --- a/library/modules/Items.cpp +++ b/library/modules/Items.cpp @@ -1477,9 +1477,9 @@ int32_t Items::createItem(df::item_type item_type, int16_t item_subtype, int16_t df::enums::game_type::game_type type = *df::global::gametype; prod->produce(unit, &out_products, &out_items, &in_reag, &in_items, 1, job_skill::NONE, - df::historical_entity::find(unit->civ_id), 0, + 0, df::historical_entity::find(unit->civ_id), ((type == df::enums::game_type::DWARF_MAIN) || (type == df::enums::game_type::DWARF_RECLAIM)) ? df::world_site::find(df::global::ui->site_id) : NULL, - 0); + NULL); if ( out_items.size() != 1 ) return -1; diff --git a/library/xml b/library/xml index 6f7f33ceb..542d1bd28 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 6f7f33cebbbefefa7c6f920b2fc197b56a3e8d1c +Subproject commit 542d1bd283051186b2d4943c9acb546af1cc7b8b diff --git a/plugins/add-spatter.cpp b/plugins/add-spatter.cpp index 3d2d89dd1..459e28f25 100644 --- a/plugins/add-spatter.cpp +++ b/plugins/add-spatter.cpp @@ -249,7 +249,7 @@ struct product_hook : improvement_product { std::vector *in_reag, std::vector *in_items, int32_t quantity, df::job_skill skill, - df::historical_entity *entity, int32_t unk, df::world_site *site, void* unk2) + int32_t quality, df::historical_entity *entity, df::world_site *site, std::vector *unk2) ) { if (auto product = products[this]) { @@ -295,7 +295,7 @@ struct product_hook : improvement_product { return; } - INTERPOSE_NEXT(produce)(unit, out_products, out_items, in_reag, in_items, quantity, skill, entity, unk, site, unk2); + INTERPOSE_NEXT(produce)(unit, out_products, out_items, in_reag, in_items, quantity, skill, quality, entity, site, unk2); } }; diff --git a/plugins/createitem.cpp b/plugins/createitem.cpp index 939afebc2..4ef1c853c 100644 --- a/plugins/createitem.cpp +++ b/plugins/createitem.cpp @@ -86,8 +86,8 @@ bool makeItem (df::reaction_product_itemst *prod, df::unit *unit, bool second_it building = df::building::find(dest_building); prod->produce(unit, &out_products, &out_items, &in_reag, &in_items, 1, job_skill::NONE, - df::historical_entity::find(unit->civ_id), 0, - (World::isFortressMode()) ? df::world_site::find(ui->site_id) : NULL, 0); + 0, df::historical_entity::find(unit->civ_id), + (World::isFortressMode()) ? df::world_site::find(ui->site_id) : NULL, NULL); if (!out_items.size()) return false; // if we asked to make shoes and we got twice as many as we asked, then we're okay diff --git a/plugins/diggingInvaders/assignJob.cpp b/plugins/diggingInvaders/assignJob.cpp index b253e7833..7e3dfaf8c 100644 --- a/plugins/diggingInvaders/assignJob.cpp +++ b/plugins/diggingInvaders/assignJob.cpp @@ -256,8 +256,8 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map in_reag; vector in_items; prod->produce(firstInvader, &out_products, &out_items, &in_reag, &in_items, 1, df::job_skill::NONE, - df::historical_entity::find(firstInvader->civ_id), 0, - df::world_site::find(df::global::ui->site_id), 0); + 0, df::historical_entity::find(firstInvader->civ_id), + df::world_site::find(df::global::ui->site_id), NULL); if ( out_items.size() != 1 ) { out.print("%s, %d: wrong size: %zu.\n", __FILE__, __LINE__, out_items.size()); diff --git a/plugins/eventful.cpp b/plugins/eventful.cpp index 5d8dfdb59..42cfbdf69 100644 --- a/plugins/eventful.cpp +++ b/plugins/eventful.cpp @@ -287,12 +287,12 @@ struct product_hook : item_product { std::vector *in_reag, std::vector *in_items, int32_t quantity, df::job_skill skill, - df::historical_entity *entity, int32_t unk, df::world_site *site, void* unk2) + int32_t quality, df::historical_entity *entity, df::world_site *site, std::vector *unk2) ) { color_ostream_proxy out(Core::getInstance().getConsole()); auto product = products[this]; if ( !product ) { - INTERPOSE_NEXT(produce)(unit, out_products, out_items, in_reag, in_items, quantity, skill, entity, unk, site, unk2); + INTERPOSE_NEXT(produce)(unit, out_products, out_items, in_reag, in_items, quantity, skill, quality, entity, site, unk2); return; } df::reaction* this_reaction=product->react; @@ -304,7 +304,7 @@ struct product_hook : item_product { size_t out_item_count = out_items->size(); - INTERPOSE_NEXT(produce)(unit, out_products, out_items, in_reag, in_items, quantity, skill, entity, unk, site, unk2); + INTERPOSE_NEXT(produce)(unit, out_products, out_items, in_reag, in_items, quantity, skill, quality, entity, site, unk2); if ( out_items->size() == out_item_count ) return; //if it produced something, call the scripts From 2597aeab0e4dd2a3ab4ba8f368e59e713669d09a Mon Sep 17 00:00:00 2001 From: Quietust Date: Tue, 2 Jun 2020 09:10:25 -0600 Subject: [PATCH 117/547] Add a new tweak, "reaction-gloves" When enabled, custom reactions will begin to produce gloves in sets, based on the number of hands the job performer's race has, and set the Handedness flags accordingly. The "createitem" plugin already contains a simpler workaround (which doesn't check body plan but instead just produces pairs), but it shouldn't trigger when this tweak is enabled (unless you use it on a creature which has been modded to only have "neutral" hands). --- plugins/tweak/tweak.cpp | 6 +++ plugins/tweak/tweaks/reaction-gloves.h | 75 ++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 plugins/tweak/tweaks/reaction-gloves.h diff --git a/plugins/tweak/tweak.cpp b/plugins/tweak/tweak.cpp index 49d96cc74..13e08f174 100644 --- a/plugins/tweak/tweak.cpp +++ b/plugins/tweak/tweak.cpp @@ -59,6 +59,7 @@ #include "df/reaction.h" #include "df/reaction_reagent_itemst.h" #include "df/reaction_reagent_flags.h" +#include "df/reaction_product_itemst.h" #include "df/viewscreen_setupdwarfgamest.h" #include "df/viewscreen_layer_assigntradest.h" #include "df/viewscreen_tradegoodsst.h" @@ -106,6 +107,7 @@ #include "tweaks/stone-status-all.h" #include "tweaks/title-start-rename.h" #include "tweaks/tradereq-pet-gender.h" +#include "tweaks/reaction-gloves.h" using std::set; using std::vector; @@ -250,6 +252,8 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector *out_products, std::vector *out_items, std::vector *in_reag, std::vector *in_items, int32_t quantity, df::job_skill skill, df::historical_entity *entity, int32_t unk_1, df::world_site *site, void *unk_2)) + { + if (item_type != df::item_type::GLOVES) + { + INTERPOSE_NEXT(produce)(unit, out_products, out_items, in_reag, in_items, quantity, skill, entity, unk_1, site, unk_2); + return; + } + + // Examine creator unit's body plan, see how many hands it has + // Count left hands and right hands, as well as "neutral" hands for compatibility + int num_hands = 0, num_left = 0, num_right = 0; + for (int i = 0; i < unit->body.body_plan->body_parts.size(); i++) + { + df::body_part_raw *part = unit->body.body_plan->body_parts[i]; + if (part->flags.is_set(df::body_part_raw_flags::GRASP)) + { + num_hands++; + if (part->flags.is_set(df::body_part_raw_flags::LEFT)) + num_left++; + if (part->flags.is_set(df::body_part_raw_flags::RIGHT)) + num_right++; + } + } + + std::vector out_items_temp; + int old_count = count; + + // If the reaction product's count is set to 1 or 2, set it to the number of hands + // Otherwise, *multiply* it by the number of hands (and multiply the left/right counts accordingly) + if (count <= 2) + count = num_hands; + else + { + num_left *= count; + num_right *= count; + count *= num_hands; + } + + INTERPOSE_NEXT(produce)(unit, out_products, &out_items_temp, in_reag, in_items, quantity, skill, entity, unk_1, site, unk_2); + count = old_count; + + // If the reaction was somehow asked to produce multiple sets (due to excess inputs), multiply the outputs too + num_left *= quantity; + num_right *= quantity; + + // Iterate across the output gloves, set their handedness, then append them to the actual out_items list for DF + for (int i = 0; i < out_items_temp.size(); i++) + { + // Do left gloves first, then right gloves, then "neutral" ones last + // This is important for the "createitem" plugin, which contains similar workaround logic + if (num_left > 0) + { + out_items_temp[i]->setGloveHandedness(1); + --num_left; + } + else if (num_right > 0) + { + out_items_temp[i]->setGloveHandedness(2); + --num_right; + } + out_items->push_back(out_items_temp[i]); + } + } +}; + +IMPLEMENT_VMETHOD_INTERPOSE(reaction_gloves_hook, produce); \ No newline at end of file From c2776c20b97db44b0d18662627d88b69b252c1ed Mon Sep 17 00:00:00 2001 From: Quietust Date: Tue, 2 Jun 2020 09:56:42 -0600 Subject: [PATCH 118/547] Update changelog --- docs/Plugins.rst | 1 + docs/changelog.txt | 3 +++ 2 files changed, 4 insertions(+) diff --git a/docs/Plugins.rst b/docs/Plugins.rst index 421e5e81b..37e568167 100644 --- a/docs/Plugins.rst +++ b/docs/Plugins.rst @@ -332,6 +332,7 @@ Subcommands that persist until disabled or DF quits: :stone-status-all: Adds an option to toggle the economic status of all stones :title-start-rename: Adds a safe rename option to the title screen "Start Playing" menu :tradereq-pet-gender: Displays pet genders on the trade request screen +:reaction-gloves: Fixes reactions to produce gloves in sets with correct handedness .. _fix-armory: diff --git a/docs/changelog.txt b/docs/changelog.txt index c165ff855..c0e9b5440 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -39,6 +39,9 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: # Future +## New Tweaks +- `tweak` reaction-gloves: adds an option to make reactions produce gloves in sets with correct handedness + ## Fixes - Fixed a segfault when attempting to start a headless session with a graphical PRINT_MODE setting - `labormanager`: fixed handling of new jobs in 0.47 From 3dcde1554a1a93b860eb972e60d898e84b24818d Mon Sep 17 00:00:00 2001 From: Quietust Date: Tue, 23 Jun 2020 13:36:00 -0600 Subject: [PATCH 119/547] Update xml, fix reaction_product::produce() parms --- plugins/tweak/tweaks/reaction-gloves.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/plugins/tweak/tweaks/reaction-gloves.h b/plugins/tweak/tweaks/reaction-gloves.h index 6ef3c6ccf..82890239c 100644 --- a/plugins/tweak/tweaks/reaction-gloves.h +++ b/plugins/tweak/tweaks/reaction-gloves.h @@ -7,11 +7,15 @@ struct reaction_gloves_hook : df::reaction_product_itemst { typedef df::reaction_product_itemst interpose_base; - DEFINE_VMETHOD_INTERPOSE(void, produce, (df::unit *unit, std::vector *out_products, std::vector *out_items, std::vector *in_reag, std::vector *in_items, int32_t quantity, df::job_skill skill, df::historical_entity *entity, int32_t unk_1, df::world_site *site, void *unk_2)) + DEFINE_VMETHOD_INTERPOSE(void, produce, (df::unit *unit, + std::vector *out_products, std::vector *out_items, + std::vector *in_reag, std::vector *in_items, + int32_t quantity, df::job_skill skill, int32_t quality, + df::historical_entity *entity, df::world_site *site, std::vector *unk_2)) { if (item_type != df::item_type::GLOVES) { - INTERPOSE_NEXT(produce)(unit, out_products, out_items, in_reag, in_items, quantity, skill, entity, unk_1, site, unk_2); + INTERPOSE_NEXT(produce)(unit, out_products, out_items, in_reag, in_items, quantity, skill, quality, entity, site, unk_2); return; } @@ -45,7 +49,7 @@ struct reaction_gloves_hook : df::reaction_product_itemst { count *= num_hands; } - INTERPOSE_NEXT(produce)(unit, out_products, &out_items_temp, in_reag, in_items, quantity, skill, entity, unk_1, site, unk_2); + INTERPOSE_NEXT(produce)(unit, out_products, &out_items_temp, in_reag, in_items, quantity, skill, quality, entity, site, unk_2); count = old_count; // If the reaction was somehow asked to produce multiple sets (due to excess inputs), multiply the outputs too From ce3cc24228258afd76c8b7193b605eb32bc5db54 Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 24 Jun 2020 00:11:54 -0400 Subject: [PATCH 120/547] Split docs on documentation into a separate file and reorganize/expand a bit --- docs/Compile.rst | 125 +-------------------------- docs/Documentation.rst | 191 +++++++++++++++++++++++++++++++++++++++++ docs/changelog.txt | 12 +-- index.rst | 1 + 4 files changed, 197 insertions(+), 132 deletions(-) create mode 100644 docs/Documentation.rst diff --git a/docs/Compile.rst b/docs/Compile.rst index 6ebaa8c1f..650e762e3 100644 --- a/docs/Compile.rst +++ b/docs/Compile.rst @@ -656,129 +656,8 @@ Then build the ``INSTALL`` target listed under ``CMakePredefinedTargets``. Building the documentation ========================== -DFHack documentation, like the file you are reading now, is created as .rst files, -which are in `reStructuredText (reST) `_ format. -This is a documenation format that has come from the Python community. It is very -similar in concept - and in syntax - to Markdown, as found on GitHub and many other -places. However it is more advanced than Markdown, with more features available when -compiled to HTML, such as automatic tables of contents, cross-linking, special -external links (forum, wiki, etc) and more. The documentation is compiled by a -Python tool, `Sphinx `_. - -The DFHack build process will compile the documentation but this has been disabled -by default. You only need to build the docs if you're changing them, or perhaps -if you want a local HTML copy; otherwise, read them easily online at -`ReadTheDoc's DFHack hosted documentation `_. - -(Note that even if you do want a local copy, it is certainly not necesesary to -compile the documentation in order to read it. Like Markdown, reST documents are -designed to be just as readable in a plain-text editor as they are in HTML format. -The main thing you lose in plain text format is hyperlinking.) - - -Enabling documentation building -------------------------------- -First, make sure you have followed all the necessary steps for your platform as -outlined in the rest of this document. - -To compile documentation with DFHack, add the following flag to your ``cmake`` command:: - - -DBUILD_DOCS:bool=ON - -For example:: - - cmake .. -DCMAKE_BUILD_TYPE:string=Release -DBUILD_DOCS:bool=ON -DCMAKE_INSTALL_PREFIX= - -Alternatively you can use the CMake GUI which allows options to be changed easily. - -On Windows you should either use ``generate-msvc-gui.bat`` and set the option -through the GUI, or else if you want to use an alternate file, such as -``generate-msvc-all.bat``, you will need to edit it to add the flag. -Or you could just run ``cmake`` on the command line like in other platforms. - -Required dependencies ---------------------- -In order to build the documentation, you must have Python with Sphinx -version 1.3.1 or later. Both Python 2.x and 3.x are supported. - -When installing Sphinx from OS package managers, be aware that there is -another program called Sphinx, completely unrelated to documentation management. -Be sure you are installing the right Sphinx; it may be called ``python-sphinx``, -for example. To avoid doubt, ``pip`` can be used instead as detailed below. - - -Linux ------ -Most Linux distributions will include Python as standard. - -Check your package manager to see if Sphinx 1.3.1 or later is available, -but at the time of writing Ubuntu for example only has 1.2.x. - -You can instead install Sphinx with the pip package manager. This may need -to be installed from your OS package manager; this is the case on Ubuntu. -On Ubuntu/Debian, use the following to first install pip:: - - sudo apt-get install python-pip - -Once pip is available, you can then install the Python Sphinx module with:: - - pip install sphinx - -If you run this as a normal user it will install a local copy for your user only. -Run it with sudo if you want a system-wide install. Either is fine for DFHack, -however if installing locally do check that ``sphinx-build`` is in your path. -It may be installed in a directory such as ``~/.local/bin/``, so after pip -install, find ``sphinx-build`` and ensure its directory is in your local ``$PATH``. - - -macOS ------ -macOS has Python 2.7 installed by default, but it does not have the pip package manager. - -You can install Homebrew's Python 3, which includes pip, and then install the -latest Sphinx using pip:: - - brew install python3 - pip3 install sphinx - -Alternatively, you can simply install Sphinx 1.3.x directly from Homebrew:: - - brew install sphinx-doc - -This will install Sphinx for macOS's system Python 2.7, without needing pip. - -Either method works; if you plan to use Python for other purposes, it might best -to install Homebrew's Python 3 so that you have the latest Python as well as pip. -If not, just installing sphinx-doc for macOS's system Python 2.7 is fine. - - -Windows -------- -Use the Chocolatey package manager to install Python and pip, -then use pip to install Sphinx. - -Run the following commands from an elevated (Admin) ``cmd.exe``, after installing -Chocolatey as outlined in the `Windows section `:: - - choco install python pip -y - -Then close that Admin ``cmd.exe``, re-open another Admin ``cmd.exe``, and run:: - - pip install sphinx - -.. _build-changelog: - -Building the changelogs ------------------------ -If you have Python installed, but do not want to build all of the documentation, -you can build the changelogs with the ``docs/gen_changelog.py`` script. - -All changes should be listed in ``changelog.txt``. A description of this file's -format follows: - -.. include:: /docs/changelog.txt - :start-after: ===help - :end-before: ===end +The steps above will not build DFHack's documentation by default. If you are +editing documentation, see `documentation` for details on how to build it. Misc. Notes =========== diff --git a/docs/Documentation.rst b/docs/Documentation.rst new file mode 100644 index 000000000..f7cb9ef92 --- /dev/null +++ b/docs/Documentation.rst @@ -0,0 +1,191 @@ +.. _documentation: + +#################### +DFHack Documentation +#################### + + +DFHack documentation, like the file you are reading now, is created as ``.rst`` files, +which are in `reStructuredText (reST) `_ format. +This is a documentation format common in the Python community. It is very +similar in concept - and in syntax - to Markdown, as found on GitHub and many other +places. However it is more advanced than Markdown, with more features available when +compiled to HTML, such as automatic tables of contents, cross-linking, special +external links (forum, wiki, etc) and more. The documentation is compiled by a +Python tool, `Sphinx `_. + +The DFHack build process will compile the documentation, but this is disabled +by default due to the additional Python and Sphinx requirements. You typically +only need to build the docs if you're changing them, or perhaps +if you want a local HTML copy; otherwise, you can read an +`online version hosted by ReadTheDocs `_. + +(Note that even if you do want a local copy, it is certainly not necessary to +compile the documentation in order to read it. Like Markdown, reST documents are +designed to be just as readable in a plain-text editor as they are in HTML format. +The main thing you lose in plain text format is hyperlinking.) + +.. contents:: + + +Required dependencies +===================== +In order to build the documentation, you must have Python with Sphinx +version 1.3.1 or later. Both Python 2.x and 3.x are supported. + +When installing Sphinx from OS package managers, be aware that there is +another program called Sphinx, completely unrelated to documentation management. +Be sure you are installing the right Sphinx; it may be called ``python-sphinx``, +for example. To avoid doubt, ``pip`` can be used instead as detailed below. + +For more detailed platform-specific instructions, see the sections below: + + +Linux +----- +Most Linux distributions will include Python as standard. + +Check your package manager to see if Sphinx 1.3.1 or later is available, +but at the time of writing Ubuntu for example only has 1.2.x. + +You can instead install Sphinx with the pip package manager. This may need +to be installed from your OS package manager; this is the case on Ubuntu. +On Ubuntu/Debian, use the following to first install pip:: + + sudo apt-get install python-pip + +Once pip is available, you can then install the Python Sphinx module with:: + + pip install sphinx + +If you run this as a normal user it will install a local copy for your user only. +Run it with sudo if you want a system-wide install. Either is fine for DFHack, +however if installing locally do check that ``sphinx-build`` is in your path. +It may be installed in a directory such as ``~/.local/bin/``, so after pip +install, find ``sphinx-build`` and ensure its directory is in your local ``$PATH``. + + +macOS +----- +macOS has Python 2.7 installed by default, but it does not have the pip package manager. + +You can install Homebrew's Python 3, which includes pip, and then install the +latest Sphinx using pip:: + + brew install python3 + pip3 install sphinx + +Alternatively, you can simply install Sphinx 1.3.x directly from Homebrew:: + + brew install sphinx-doc + +This will install Sphinx for macOS's system Python 2.7, without needing pip. + +Either method works; if you plan to use Python for other purposes, it might best +to install Homebrew's Python 3 so that you have the latest Python as well as pip. +If not, just installing sphinx-doc for macOS's system Python 2.7 is fine. + + +Windows +------- +Python for Windows can be downloaded `from python.org `_. +The latest version of Python 3 is recommended, as it includes pip already. + +You can also install Python and pip through the Chocolatey package manager. +After installing Chocolatey as outlined in the `Windows compilation instructions `, +run the following command from an elevated (admin) command prompt (e.g. ``cmd.exe``):: + + choco install python pip -y + +Once you have pip available, you can install Sphinx with the following command:: + + pip install sphinx + +Note that this may require opening a new (admin) command prompt if you just +installed pip from the same command prompt. + + +Building the documentation +========================== + +Once you have installed Sphinx, ``sphinx-build --version`` should report the +version of Sphinx that you have installed. If this works, CMake should also be +able to find Sphinx. + +Using CMake +----------- + +Enabling the ``BUILD_DOCS`` CMake option will cause the documentation to be built +whenever it changes as part of the normal DFHack build process. There are several +ways to do this: + +* When initially running CMake, add ``-DBUILD_DOCS:bool=ON`` to your ``cmake`` + command. For example:: + + cmake .. -DCMAKE_BUILD_TYPE:string=Release -DBUILD_DOCS:bool=ON -DCMAKE_INSTALL_PREFIX= + +* If you have already run CMake, you can simply run it again from your build + folder to update your configuration:: + + cmake .. -DBUILD_DOCS:bool=ON + +* You can edit the ``BUILD_DOCS`` setting in CMakeCache.txt directly + +* You can use the CMake GUI to change ``BUILD_DOCS`` + +* On Windows, if you prefer to use the batch scripts, you can run + ``generate-msvc-gui.bat`` and set ``BUILD_DOCS`` through the GUI. If you are + running another file, such as ``generate-msvc-all.bat``, you will need to edit + it to add the flag. You can also run ``cmake`` on the command line, similar to + other platforms. + +Running Sphinx manually +----------------------- + +You can also build the documentation without going through CMake, which may be +faster. There is a ``docs/build.sh`` script available for Linux and macOS that +will run essentially the same command that CMake runs - see the script for +options. + +To build the documentation with default options, run the following command from +the root DFHack folder:: + + sphinx-build . docs/html + +Sphinx has many options to enable clean builds, parallel builds, logging, and +more - run ``sphinx-build --help`` for details. + +.. _build-changelog: + +Building the changelogs +======================= +If you have Python installed, but do not want to build all of the documentation, +you can build the changelogs with the ``docs/gen_changelog.py`` script. This +script provides additional options, including one to build individual changelogs +for all DFHack versions - run ``python docs/gen_changelog.py --help`` for details. + +Changelog entries are obtained from ``changelog.txt`` files in multiple repos. +This allows changes to be listed in the same repo where they were made. These +changelogs are combined as part of the changelog build process: + +* ``docs/changelog.txt`` for changes in the main ``dfhack`` repo +* ``scripts/changelog.txt`` for changes made to scripts in the ``scripts`` repo +* ``library/xml/changelog.txt`` for changes made in the ``df-structures`` repo + +Building the changelogs generates two files: ``docs/_auto/news.rst`` and +``docs/_auto/news-dev.rst``. These correspond to `changelog` and `dev-changelog` +and contain changes organized by stable and development DFHack releases, +respectively. For example, an entry listed under "0.44.05-alpha1" in +changelog.txt will be listed under that version in the development changelog as +well, but under "0.44.05-r1" in the stable changelog (assuming that is the +closest stable release after 0.44.05-alpha1). An entry listed under a stable +release like "0.44.05-r1" in changelog.txt will be listed under that release in +both the stable changelog and the development changelog. + + +Changelog syntax +---------------- + +.. include:: /docs/changelog.txt + :start-after: ===help + :end-before: ===end diff --git a/docs/changelog.txt b/docs/changelog.txt index c165ff855..7201bfd23 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -1,16 +1,10 @@ === Scroll down for changes ===[[[ -===help +The text below is included in docs/Documentation.rst - see that file for more details on the changelog setup. +This is kept in this file as a quick syntax reference. -Entries in docs/NEWS.rst and docs/NEWS-dev.rst are generated from -docs/changelog.txt. NEWS.rst groups entries by stable releases, and NEWS-dev.rst -groups them by all releases (stable and development). For example, an entry -listed under "0.44.05-alpha1" in changelog.txt will be listed under that in -NEWS-dev.rst as well, but under "0.44.05-r1" in NEWS.rst (assuming that is the -closest stable release after 0.44.05-alpha1). An entry listed under a stable -release in changelog.txt will be listed under that release in both NEWS.rst and -NEWS-dev.rst. +===help changelog.txt uses a syntax similar to RST, with a few special sequences: diff --git a/index.rst b/index.rst index d4bd223c5..855b31a73 100644 --- a/index.rst +++ b/index.rst @@ -62,6 +62,7 @@ For Developers /docs/Compile /docs/NEWS-dev /docs/Lua API + /docs/Documentation /library/xml/SYNTAX /library/xml/how-to-update /docs/Binpatches From 8a7e8f4facf50757f54a049fb18f67b8b81a3837 Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 25 Jun 2020 01:12:18 -0400 Subject: [PATCH 121/547] Update xml --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index 542d1bd28..2ed5fae13 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 542d1bd283051186b2d4943c9acb546af1cc7b8b +Subproject commit 2ed5fae13f721b73b71bc31a062fb66abd1f3920 From ee56d8157f62e5161f6248d9329d30e0c0ab314e Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 27 Jun 2020 00:15:48 -0400 Subject: [PATCH 122/547] Update xml --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index 2ed5fae13..97084e556 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 2ed5fae13f721b73b71bc31a062fb66abd1f3920 +Subproject commit 97084e556119ce4445c3745151180467338a746a From a9f219baf9dda6d8cc300251fc040420e84bbc49 Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Mon, 29 Jun 2020 16:16:44 -0500 Subject: [PATCH 123/547] update for DFHack/df-structures#7dfea1f1d4e453b97d5529785701db46360596ce --- library/modules/Kitchen.cpp | 4 ++-- library/modules/MapCache.cpp | 8 ++++---- library/modules/Materials.cpp | 2 +- library/xml | 2 +- plugins/autochop.cpp | 2 +- plugins/getplants.cpp | 10 +++++----- plugins/stonesense | 2 +- scripts | 2 +- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/library/modules/Kitchen.cpp b/library/modules/Kitchen.cpp index 63372d564..fa4d1dea7 100644 --- a/library/modules/Kitchen.cpp +++ b/library/modules/Kitchen.cpp @@ -95,7 +95,7 @@ void Kitchen::denyPlantSeedCookery(t_materialIndex materialIndex) { ui->kitchen.item_types.push_back(item_type::SEEDS); ui->kitchen.item_subtypes.push_back(organicSubtype); - ui->kitchen.mat_types.push_back(type->material_defs.type_seed); + ui->kitchen.mat_types.push_back(type->material_defs.type[plant_material_def::seed]); ui->kitchen.mat_indices.push_back(materialIndex); ui->kitchen.exc_types.push_back(df::kitchen_exc_type::Cook); } @@ -103,7 +103,7 @@ void Kitchen::denyPlantSeedCookery(t_materialIndex materialIndex) { ui->kitchen.item_types.push_back(item_type::PLANT); ui->kitchen.item_subtypes.push_back(organicSubtype); - ui->kitchen.mat_types.push_back(type->material_defs.type_basic_mat); + ui->kitchen.mat_types.push_back(type->material_defs.type[plant_material_def::basic_mat]); ui->kitchen.mat_indices.push_back(materialIndex); ui->kitchen.exc_types.push_back(df::kitchen_exc_type::Cook); } diff --git a/library/modules/MapCache.cpp b/library/modules/MapCache.cpp index b61ba375e..ce3039ecf 100644 --- a/library/modules/MapCache.cpp +++ b/library/modules/MapCache.cpp @@ -899,8 +899,8 @@ t_matpair MapExtras::BlockInfo::getBaseMaterial(df::tiletype tt, df::coord2d pos { if (auto raw = df::plant_raw::find(plant->material)) { - rv.mat_type = raw->material_defs.type_basic_mat; - rv.mat_index = raw->material_defs.idx_basic_mat; + rv.mat_type = raw->material_defs.type[plant_material_def::basic_mat]; + rv.mat_index = raw->material_defs.idx[plant_material_def::basic_mat]; } } break; @@ -912,8 +912,8 @@ t_matpair MapExtras::BlockInfo::getBaseMaterial(df::tiletype tt, df::coord2d pos rv.mat_type = MaterialInfo::PLANT_BASE; if (auto raw = df::plant_raw::find(grass[x][y])) { - rv.mat_type = raw->material_defs.type_basic_mat; - rv.mat_index = raw->material_defs.idx_basic_mat; + rv.mat_type = raw->material_defs.type[plant_material_def::basic_mat]; + rv.mat_index = raw->material_defs.idx[plant_material_def::basic_mat]; } break; diff --git a/library/modules/Materials.cpp b/library/modules/Materials.cpp index 51d717d05..c341ea99e 100644 --- a/library/modules/Materials.cpp +++ b/library/modules/Materials.cpp @@ -261,7 +261,7 @@ bool MaterialInfo::findPlant(const std::string &token, const std::string &subtok // As a special exception, return the structural material with empty subtoken if (subtoken.empty()) - return decode(p->material_defs.type_basic_mat, p->material_defs.idx_basic_mat); + return decode(p->material_defs.type[plant_material_def::basic_mat], p->material_defs.idx[plant_material_def::basic_mat]); for (size_t j = 0; j < p->material.size(); j++) if (p->material[j]->id == subtoken) diff --git a/library/xml b/library/xml index 97084e556..7dfea1f1d 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 97084e556119ce4445c3745151180467338a746a +Subproject commit 7dfea1f1d4e453b97d5529785701db46360596ce diff --git a/plugins/autochop.cpp b/plugins/autochop.cpp index e7f3874d3..8f2225f72 100644 --- a/plugins/autochop.cpp +++ b/plugins/autochop.cpp @@ -258,7 +258,7 @@ static bool skip_plant(const df::plant * plant, bool *restricted) const df::plant_raw *plant_raw = df::plant_raw::find(plant->material); // Skip fruit trees if set. - if (skip.fruit_trees && plant_raw->material_defs.type_drink != -1) + if (skip.fruit_trees && plant_raw->material_defs.type[plant_material_def::drink] != -1) { if (restricted) *restricted = true; diff --git a/plugins/getplants.cpp b/plugins/getplants.cpp index d1ee79a04..b4b7a493b 100644 --- a/plugins/getplants.cpp +++ b/plugins/getplants.cpp @@ -70,7 +70,7 @@ enum class selectability { //selectability selectablePlant(color_ostream &out, const df::plant_raw *plant, bool farming) selectability selectablePlant(const df::plant_raw *plant, bool farming) { - const DFHack::MaterialInfo basic_mat = DFHack::MaterialInfo(plant->material_defs.type_basic_mat, plant->material_defs.idx_basic_mat); + const DFHack::MaterialInfo basic_mat = DFHack::MaterialInfo(plant->material_defs.type[plant_material_def::basic_mat], plant->material_defs.idx[plant_material_def::basic_mat]); bool outOfSeason = false; selectability result = selectability::Nonselectable; @@ -92,7 +92,7 @@ selectability selectablePlant(const df::plant_raw *plant, bool farming) return selectability::Grass; } - if (farming && plant->material_defs.type_seed == -1) + if (farming && plant->material_defs.type[plant_material_def::seed] == -1) { return selectability::Nonselectable; } @@ -163,8 +163,8 @@ selectability selectablePlant(const df::plant_raw *plant, bool farming) { for (size_t k = 0; growth_mat.material->reaction_product.material.mat_type.size(); k++) { - if (growth_mat.material->reaction_product.material.mat_type[k] == plant->material_defs.type_seed && - growth_mat.material->reaction_product.material.mat_index[k] == plant->material_defs.idx_seed) + if (growth_mat.material->reaction_product.material.mat_type[k] == plant->material_defs.type[plant_material_def::seed] && + growth_mat.material->reaction_product.material.mat_index[k] == plant->material_defs.idx[plant_material_def::seed]) { seedSource = true; break; @@ -193,7 +193,7 @@ selectability selectablePlant(const df::plant_raw *plant, bool farming) } /* else if (plant->growths[i]->behavior.bits.has_seed) // This code designates beans, etc. when DF doesn't, but plant gatherers still fail to collect anything, so it's useless: bug #0006940. { - const DFHack::MaterialInfo seed_mat = DFHack::MaterialInfo(plant->material_defs.type_seed, plant->material_defs.idx_seed); + const DFHack::MaterialInfo seed_mat = DFHack::MaterialInfo(plant->material_defs.type[plant_material_def::seed], plant->material_defs.idx[plant_material_def::seed]); if (seed_mat.material->flags.is_set(material_flags::EDIBLE_RAW) || seed_mat.material->flags.is_set(material_flags::EDIBLE_COOKED)) diff --git a/plugins/stonesense b/plugins/stonesense index 5b7e7743a..bdab71c99 160000 --- a/plugins/stonesense +++ b/plugins/stonesense @@ -1 +1 @@ -Subproject commit 5b7e7743a1372b929acb2ccb75080e139ac11691 +Subproject commit bdab71c99a0a7cc268ca517a0cd3f0a5fb41042a diff --git a/scripts b/scripts index 47d9b3c93..792ae44ab 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 47d9b3c9390d21ecc49ddaba477b16071884ee87 +Subproject commit 792ae44ab14afd3a2b3e850a6fcb463d714b0a44 From d13e5a3f3157b02fd552a90c2722046745626791 Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Mon, 29 Jun 2020 20:20:37 -0500 Subject: [PATCH 124/547] update structures handle renaming of caste_raw::gender --- library/xml | 2 +- plugins/remotefortressreader/remotefortressreader.cpp | 2 +- plugins/tweak/tweaks/tradereq-pet-gender.h | 2 +- scripts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/xml b/library/xml index 7dfea1f1d..b11433eea 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 7dfea1f1d4e453b97d5529785701db46360596ce +Subproject commit b11433eea0a1117edc2a4a51f7a30b01594cb52b diff --git a/plugins/remotefortressreader/remotefortressreader.cpp b/plugins/remotefortressreader/remotefortressreader.cpp index e94c3f832..1a0d045dc 100644 --- a/plugins/remotefortressreader/remotefortressreader.cpp +++ b/plugins/remotefortressreader/remotefortressreader.cpp @@ -2685,7 +2685,7 @@ static command_result GetPartialCreatureRaws(color_ostream &stream, const ListRe send_caste->add_child_name(orig_caste->child_name[0]); send_caste->add_child_name(orig_caste->child_name[1]); - send_caste->set_gender(orig_caste->gender); + send_caste->set_gender(orig_caste->sex); for (size_t partIndex = 0; partIndex < orig_caste->body_info.body_parts.size(); partIndex++) { diff --git a/plugins/tweak/tweaks/tradereq-pet-gender.h b/plugins/tweak/tweaks/tradereq-pet-gender.h index ca786bef2..c62a56f67 100644 --- a/plugins/tweak/tweaks/tradereq-pet-gender.h +++ b/plugins/tweak/tweaks/tradereq-pet-gender.h @@ -20,7 +20,7 @@ struct pet_gender_hook : df::viewscreen_topicmeeting_takerequestsst { vector& castes = entity->resources.animals.pet_castes; for (int i = (good_idx / 17) * 17, y = 4; i < (good_idx / 17) * 17 + 17 && size_t(i) < races.size(); i++, y++) { int x = 30 + 1 + world->raws.creatures.all[races[i]]->caste[castes[i]]->caste_name[0].size(); - bool male = (bool)world->raws.creatures.all[races[i]]->caste[castes[i]]->gender; + bool male = world->raws.creatures.all[races[i]]->caste[castes[i]]->sex == pronoun_type::he; OutputString((i == good_idx) ? COLOR_WHITE : COLOR_GREY, x, y, male ? "\013" : "\014"); } diff --git a/scripts b/scripts index 792ae44ab..91060d6d2 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 792ae44ab14afd3a2b3e850a6fcb463d714b0a44 +Subproject commit 91060d6d2c79196f6b332b9b88492eb0e7ef32da From 0f58d95ea890a7333131547bba95a43e582a3f78 Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 29 Jun 2020 22:02:53 -0400 Subject: [PATCH 125/547] Use workflow commands to set up environment variables https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-environment-variable --- .github/workflows/build.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 17af62cb1..7da428d32 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,11 +25,11 @@ jobs: submodules: true - name: Set up environment run: | - echo export DF_VERSION="$(sh travis/get-df-version.sh)" >> "$HOME/.df-env" - echo export DF_FOLDER="$HOME/DF/$DF_VERSION/df_linux" >> "$HOME/.df-env" + DF_VERSION="$(sh travis/get-df-version.sh)" + echo "::set-env name=DF_VERSION::${DF_VERSION}" + echo "::set-env name=DF_FOLDER::${HOME}/DF/${DF_VERSION}/df_linux" - name: Download DF run: | - source "$HOME/.df-env" sh travis/download-df.sh - name: Build docs run: | @@ -41,7 +41,6 @@ jobs: path: docs/html - name: Build DFHack run: | - source "$HOME/.df-env" cmake \ -S . \ -B build-ci \ @@ -53,7 +52,6 @@ jobs: ninja -C build-ci install - name: Run tests run: | - source "$HOME/.df-env" export TERM=dumb mv "$DF_FOLDER"/dfhack.init-example "$DF_FOLDER"/dfhack.init script -qe -c "python travis/run-tests.py --headless --keep-status \"$DF_FOLDER\"" From c6283ea262f401845c2d0f6e645a7dc18fff79c3 Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 29 Jun 2020 22:04:33 -0400 Subject: [PATCH 126/547] Make download-df.sh fail sooner --- travis/download-df.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/travis/download-df.sh b/travis/download-df.sh index 834aa4da7..6918a596a 100755 --- a/travis/download-df.sh +++ b/travis/download-df.sh @@ -1,5 +1,7 @@ #!/bin/sh +set -e + tardest="df.tar.bz2" which md5sum && alias md5=md5sum From 9def098ef914a9c8e0f7121889b17cf550e879a8 Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Mon, 29 Jun 2020 21:30:22 -0500 Subject: [PATCH 127/547] add enum-attrs to pronoun_type --- library/xml | 2 +- plugins/manipulator.cpp | 4 +++- scripts | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/library/xml b/library/xml index b11433eea..b67b3fa4b 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit b11433eea0a1117edc2a4a51f7a30b01594cb52b +Subproject commit b67b3fa4b02f834dc76a2e1eae21136e0be089f7 diff --git a/plugins/manipulator.cpp b/plugins/manipulator.cpp index e9206dc0f..a013df335 100644 --- a/plugins/manipulator.cpp +++ b/plugins/manipulator.cpp @@ -2032,7 +2032,9 @@ void viewscreen_unitlaborsst::render() int x = 1, y = 3 + num_rows + 2; Screen::Pen white_pen(' ', 15, 0); - Screen::paintString(white_pen, x, y, (cur->unit && cur->unit->sex) ? "\x0b" : "\x0c"); + auto symbol = cur->unit ? ENUM_ATTR(pronoun_type, symbol, cur->unit->sex) : nullptr; + if (symbol) + Screen::paintString(white_pen, x, y, symbol); x += 2; Screen::paintString(white_pen, x, y, cur->transname); x += cur->transname.length(); diff --git a/scripts b/scripts index 91060d6d2..3987d0314 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 91060d6d2c79196f6b332b9b88492eb0e7ef32da +Subproject commit 3987d031469420d64aff23097d9548676f1ab752 From b4a55110e3a9572b32df10c841e7b4d06ad0a9da Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 29 Jun 2020 22:35:23 -0400 Subject: [PATCH 128/547] Also try downloading DF from files.dfhack.org --- travis/download-df.sh | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/travis/download-df.sh b/travis/download-df.sh index 6918a596a..49dcedea7 100755 --- a/travis/download-df.sh +++ b/travis/download-df.sh @@ -4,7 +4,6 @@ set -e tardest="df.tar.bz2" -which md5sum && alias md5=md5sum selfmd5=$(openssl md5 < "$0") echo $selfmd5 @@ -30,7 +29,20 @@ if [ ! -f receipt ]; then patch=$(echo "$DF_VERSION" | cut -d. -f3) url="http://www.bay12games.com/dwarves/df_${minor}_${patch}_linux.tar.bz2" echo Downloading - wget "$url" -O "$tardest" + while read url; do + echo "Attempting download: ${url}" + if wget -v "$url" -O "$tardest"; then + break + fi + done < Date: Mon, 29 Jun 2020 22:35:36 -0400 Subject: [PATCH 129/547] Attempt to cache DF --- .github/workflows/build.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7da428d32..6ad88dc27 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,6 +28,11 @@ jobs: DF_VERSION="$(sh travis/get-df-version.sh)" echo "::set-env name=DF_VERSION::${DF_VERSION}" echo "::set-env name=DF_FOLDER::${HOME}/DF/${DF_VERSION}/df_linux" + - name: Fetch DF cache + uses: actions/cache@v2 + with: + path: ~/DF + key: ${DF_VERSION} - name: Download DF run: | sh travis/download-df.sh From e33a3ffff9f68a61aa39597bb8339d211e5574c6 Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 29 Jun 2020 22:40:58 -0400 Subject: [PATCH 130/547] Fix cache key --- .github/workflows/build.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6ad88dc27..fdea2180e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,15 +24,17 @@ jobs: with: submodules: true - name: Set up environment + id: env_setup run: | DF_VERSION="$(sh travis/get-df-version.sh)" echo "::set-env name=DF_VERSION::${DF_VERSION}" + echo "::set-output name=df_version::${DF_VERSION}" echo "::set-env name=DF_FOLDER::${HOME}/DF/${DF_VERSION}/df_linux" - name: Fetch DF cache uses: actions/cache@v2 with: path: ~/DF - key: ${DF_VERSION} + key: ${{ steps.env_setup.outputs.df_version }} - name: Download DF run: | sh travis/download-df.sh From e26a091b7d02eacb3b0d4855ded6151ebff0fc01 Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 29 Jun 2020 22:52:44 -0400 Subject: [PATCH 131/547] Clean up cached DF --- .github/workflows/build.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fdea2180e..aadb1a15f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -71,6 +71,12 @@ jobs: with: name: test-artifacts path: artifacts + - name: Clean up DF folder + # to prevent DFHack-generated files from ending up in the cache + # (download-df.sh also removes them, this is just to save cache space) + if: success() || failure() + run: | + rm -rf "$DF_FOLDER" lint: runs-on: ubuntu-18.04 steps: From c4aebfdf65acf63293648316144f7da2f11c5f58 Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 29 Jun 2020 22:53:05 -0400 Subject: [PATCH 132/547] Use setup-python --- .github/workflows/build.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index aadb1a15f..4205e5e2a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,6 +6,10 @@ jobs: build: runs-on: ubuntu-18.04 steps: + - name: Set up Python 3 + uses: actions/setup-python@v2 + with: + python-version: 3 - name: Install dependencies run: | sudo apt-get update @@ -18,7 +22,7 @@ jobs: lua5.3 \ ninja-build \ zlib1g-dev - sudo pip3 install --system sphinx + pip install sphinx - name: Clone DFHack uses: actions/checkout@v1 with: From 6b2887d31b0e84b29b1121fabab96b5610e9678e Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 29 Jun 2020 23:00:20 -0400 Subject: [PATCH 133/547] Upgrade to checkout@v2 --- .github/workflows/build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4205e5e2a..612302397 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,8 +24,9 @@ jobs: zlib1g-dev pip install sphinx - name: Clone DFHack - uses: actions/checkout@v1 + uses: actions/checkout@v2 with: + fetch-depth: 0 # unlimited - we need past tags submodules: true - name: Set up environment id: env_setup From e39150ac36934e54b5cdbdbdcb5c17e4f5faacf1 Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 29 Jun 2020 23:05:03 -0400 Subject: [PATCH 134/547] Update authors (dfhack/scripts#157) --- docs/Authors.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Authors.rst b/docs/Authors.rst index 6821a84b0..e816389cd 100644 --- a/docs/Authors.rst +++ b/docs/Authors.rst @@ -25,6 +25,7 @@ belal jimhester Ben Lubar BenLubar Ben Rosser TC01 billw2012 billw2012 +BrickViking brickviking brndd brndd burneddi Bumber Bumber64 Caldfir caldfir From e95edc095c395d4fca41dd3838dba5fccc8013a5 Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 29 Jun 2020 23:58:47 -0400 Subject: [PATCH 135/547] Use workflow commands to annotate linter errors --- travis/lint.py | 83 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 53 insertions(+), 30 deletions(-) diff --git a/travis/lint.py b/travis/lint.py index 7d8df7246..53abc4cbc 100644 --- a/travis/lint.py +++ b/travis/lint.py @@ -18,12 +18,49 @@ def valid_file(filename): not len(list(filter(lambda path: path.replace('\\', '/') in filename.replace('\\', '/'), path_blacklist))) success = True -def error(msg): +def error(msg=None): global success success = False - sys.stderr.write(msg + '\n') + if msg: + sys.stderr.write(msg + '\n') -class LinterError(Exception): pass +def format_lines(lines, total): + if len(lines) == total - 1: + return 'entire file' + if not len(lines): + # should never happen + return 'nowhere' + if len(lines) == 1: + return 'line %i' % lines[0] + s = 'lines ' + range_start = range_end = lines[0] + for i, line in enumerate(lines): + if line > range_end + 1: + if range_start == range_end: + s += ('%i, ' % range_end) + else: + s += ('%i-%i, ' % (range_start, range_end)) + range_start = range_end = line + if i == len(lines) - 1: + s += ('%i' % line) + else: + range_end = line + if i == len(lines) - 1: + s += ('%i-%i, ' % (range_start, range_end)) + return s.rstrip(' ').rstrip(',') + +class LinterError(Exception): + def __init__(self, message, lines, total_lines): + self.message = message + self.lines = lines + self.total_lines = total_lines + + def __str__(self): + return '%s: %s' % (self.message, format_lines(self.lines, self.total_lines)) + + def github_actions_workflow_command(self, filename): + first_line = self.lines[0] if self.lines else 1 + return '::error file=%s,line=%i::%s' % (filename, first_line, self) class Linter(object): ignore = False @@ -33,36 +70,12 @@ class Linter(object): if not self.check_line(line): failures.append(i + 1) if len(failures): - raise LinterError('%s: %s' % (self.msg, self.display_lines(failures, len(lines)))) + raise LinterError(self.msg, failures, len(lines)) def fix(self, lines): for i in range(len(lines)): lines[i] = self.fix_line(lines[i]) - def display_lines(self, lines, total): - if len(lines) == total - 1: - return 'entire file' - if not len(lines): - # should never happen - return 'nowhere' - if len(lines) == 1: - return 'line %i' % lines[0] - s = 'lines ' - range_start = range_end = lines[0] - for i, line in enumerate(lines): - if line > range_end + 1: - if range_start == range_end: - s += ('%i, ' % range_end) - else: - s += ('%i-%i, ' % (range_start, range_end)) - range_start = range_end = line - if i == len(lines) - 1: - s += ('%i' % line) - else: - range_end = line - if i == len(lines) - 1: - s += ('%i-%i, ' % (range_start, range_end)) - return s.rstrip(' ').rstrip(',') class NewlineLinter(Linter): msg = 'Contains DOS-style newlines' @@ -91,6 +104,7 @@ class TabLinter(Linter): linters = [cls() for cls in Linter.__subclasses__() if not cls.ignore] def main(): + is_github_actions = os.environ.get('GITHUB_ACTIONS') root_path = os.path.abspath(sys.argv[1] if len(sys.argv) > 1 else '.') if not os.path.exists(root_path): print('Nonexistent path: %s' % root_path) @@ -112,13 +126,22 @@ def main(): try: lines[i] = line.decode('utf-8') except UnicodeDecodeError: - error('%s:%i: Invalid UTF-8 (other errors will be ignored)' % (rel_path, i + 1)) + msg_params = (rel_path, i + 1, 'Invalid UTF-8 (other errors will be ignored)') + if is_github_actions: + error() + print('::error file=%s,line=%i::%s' % msg_params) + else: + error('%s:%i: %s' % msg_params) lines[i] = '' for linter in linters: try: linter.check(lines) except LinterError as e: - error('%s: %s' % (rel_path, e)) + if is_github_actions: + error() + print(e.github_actions_workflow_command(rel_path)) + else: + error('%s: %s' % (rel_path, e)) if fix: linter.fix(lines) contents = '\n'.join(lines) From fedf68cc7ccd0787ad7231085a9695c29844445d Mon Sep 17 00:00:00 2001 From: lethosor Date: Tue, 30 Jun 2020 00:24:03 -0400 Subject: [PATCH 136/547] Annotate script syntax errors --- .github/workflows/build.yml | 4 ++-- travis/script-syntax.py | 28 +++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 612302397..d60a428bf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -106,10 +106,10 @@ jobs: python travis/script-docs.py - name: Check Lua syntax run: | - python travis/script-syntax.py --ext=lua --cmd="luac5.3 -p" + python travis/script-syntax.py --ext=lua --cmd="luac5.3 -p" --github-actions - name: Check Ruby syntax run: | - python travis/script-syntax.py --ext=rb --cmd="ruby -c" + python travis/script-syntax.py --ext=rb --cmd="ruby -c" --github-actions check-pr: runs-on: ubuntu-latest if: github.event_name == 'pull_request' diff --git a/travis/script-syntax.py b/travis/script-syntax.py index b3a264f04..e33a11f1d 100644 --- a/travis/script-syntax.py +++ b/travis/script-syntax.py @@ -3,6 +3,24 @@ import os import subprocess import sys + +def print_stderr(stderr, args): + if not args.github_actions: + sys.stderr.write(stderr + '\n') + return + + for line in stderr.split('\n'): + parts = list(map(str.strip, line.split(':'))) + # e.g. luac prints "luac:" in front of messages, so find the first part + # containing the actual filename + for i in range(len(parts) - 1): + if parts[i].endswith('.' + args.ext) and parts[i + 1].isdigit(): + print('::error file=%s,line=%s::%s' % (parts[i], parts[i + 1], ':'.join(parts[i + 2:]))) + break + else: + print(line) + + def main(args): root_path = os.path.abspath(args.path) cmd = args.cmd.split(' ') @@ -19,7 +37,13 @@ def main(args): continue full_path = os.path.join(cur, filename) try: - subprocess.check_output(cmd + [full_path]) + p = subprocess.Popen(cmd + [full_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + _, stderr = p.communicate() + stderr = stderr.decode('utf-8', errors='ignore') + if stderr: + print_stderr(stderr, args) + if p.returncode != 0: + err = True except subprocess.CalledProcessError: err = True except IOError: @@ -34,5 +58,7 @@ if __name__ == '__main__': parser.add_argument('--path', default='.', help='Root directory') parser.add_argument('--ext', help='Script extension', required=True) parser.add_argument('--cmd', help='Command', required=True) + parser.add_argument('--github-actions', action='store_true', + help='Enable GitHub Actions workflow command output') args = parser.parse_args() main(args) From c333059316c2455416dbfacd1edf60477eb27a36 Mon Sep 17 00:00:00 2001 From: lethosor Date: Tue, 30 Jun 2020 00:29:30 -0400 Subject: [PATCH 137/547] Switch CI scripts to Python 3 --- .github/workflows/build.yml | 5 +++++ travis/all.py | 1 + travis/authors-rst.py | 1 + travis/check-rpc.py | 1 + travis/lint.py | 1 + travis/run-tests.py | 1 + travis/script-docs.py | 1 + travis/script-syntax.py | 1 + 8 files changed, 12 insertions(+) mode change 100644 => 100755 travis/all.py mode change 100644 => 100755 travis/authors-rst.py mode change 100644 => 100755 travis/check-rpc.py mode change 100644 => 100755 travis/lint.py mode change 100644 => 100755 travis/run-tests.py mode change 100644 => 100755 travis/script-docs.py mode change 100644 => 100755 travis/script-syntax.py diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d60a428bf..37a306abd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -82,9 +82,14 @@ jobs: if: success() || failure() run: | rm -rf "$DF_FOLDER" + lint: runs-on: ubuntu-18.04 steps: + - name: Set up Python 3 + uses: actions/setup-python@v2 + with: + python-version: 3 - name: Install dependencies run: | sudo apt-get update diff --git a/travis/all.py b/travis/all.py old mode 100644 new mode 100755 index 281911e7a..edd2eee18 --- a/travis/all.py +++ b/travis/all.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import argparse, os, sys, time parser = argparse.ArgumentParser() diff --git a/travis/authors-rst.py b/travis/authors-rst.py old mode 100644 new mode 100755 index 2d7274219..e8db817f6 --- a/travis/authors-rst.py +++ b/travis/authors-rst.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 """ Overly-complicated script to check formatting/sorting in Authors.rst """ import re, sys diff --git a/travis/check-rpc.py b/travis/check-rpc.py old mode 100644 new mode 100755 index ecddafa9f..aba3e3811 --- a/travis/check-rpc.py +++ b/travis/check-rpc.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import glob import sys diff --git a/travis/lint.py b/travis/lint.py old mode 100644 new mode 100755 index 53abc4cbc..51117201c --- a/travis/lint.py +++ b/travis/lint.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import re, os, sys valid_extensions = ['c', 'cpp', 'h', 'hpp', 'mm', 'lua', 'rb', 'proto', diff --git a/travis/run-tests.py b/travis/run-tests.py old mode 100644 new mode 100755 index 70ab6cf20..f4c173af2 --- a/travis/run-tests.py +++ b/travis/run-tests.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import argparse import enum import json diff --git a/travis/script-docs.py b/travis/script-docs.py old mode 100644 new mode 100755 index 33b2818c8..04728e101 --- a/travis/script-docs.py +++ b/travis/script-docs.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 from __future__ import print_function from io import open import os diff --git a/travis/script-syntax.py b/travis/script-syntax.py old mode 100644 new mode 100755 index e33a11f1d..1f6eca2eb --- a/travis/script-syntax.py +++ b/travis/script-syntax.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import argparse import os import subprocess From 324bc515408fec1b9d0ca848329e88ac956b51a9 Mon Sep 17 00:00:00 2001 From: lethosor Date: Tue, 30 Jun 2020 00:34:40 -0400 Subject: [PATCH 138/547] Upgrade to checkout@v2 --- .github/workflows/build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 37a306abd..829ab1c14 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -97,9 +97,10 @@ jobs: lua5.3 \ ruby - name: Clone DFHack - uses: actions/checkout@v1 + uses: actions/checkout@v2 with: submodules: true + # don't need tags here - name: Check whitespace run: | python travis/lint.py From 504d2ec65b0d3a5823789519535ed7eb792153f0 Mon Sep 17 00:00:00 2001 From: lethosor Date: Tue, 30 Jun 2020 00:35:01 -0400 Subject: [PATCH 139/547] Stop linter steps from stopping each other --- .github/workflows/build.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 829ab1c14..3533bd1ee 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -105,17 +105,22 @@ jobs: run: | python travis/lint.py - name: Check Authors.rst + if: success() || failure() run: | python travis/authors-rst.py - name: Check for missing documentation + if: success() || failure() run: | python travis/script-docs.py - name: Check Lua syntax + if: success() || failure() run: | python travis/script-syntax.py --ext=lua --cmd="luac5.3 -p" --github-actions - name: Check Ruby syntax + if: success() || failure() run: | python travis/script-syntax.py --ext=rb --cmd="ruby -c" --github-actions + check-pr: runs-on: ubuntu-latest if: github.event_name == 'pull_request' From 1df7c0be122f1751b858b5c78a9992e86bdf16be Mon Sep 17 00:00:00 2001 From: lethosor Date: Tue, 30 Jun 2020 00:41:02 -0400 Subject: [PATCH 140/547] Upgrade Ruby --- .github/workflows/build.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3533bd1ee..fb98bfa0b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -90,12 +90,14 @@ jobs: uses: actions/setup-python@v2 with: python-version: 3 - - name: Install dependencies + - name: Set up Ruby 2.7 + uses: actions/setup-ruby@v1 + with: + ruby-version: 2.7 + - name: Install Lua run: | sudo apt-get update - sudo apt-get install \ - lua5.3 \ - ruby + sudo apt-get install lua5.3 - name: Clone DFHack uses: actions/checkout@v2 with: From 13f411d9fa650cc4ca443f606d2c7119fc5d59bf Mon Sep 17 00:00:00 2001 From: lethosor Date: Tue, 30 Jun 2020 00:44:27 -0400 Subject: [PATCH 141/547] Always print error lines to make GitHub logs more readable --- travis/script-syntax.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/travis/script-syntax.py b/travis/script-syntax.py index 1f6eca2eb..53891f762 100755 --- a/travis/script-syntax.py +++ b/travis/script-syntax.py @@ -18,8 +18,7 @@ def print_stderr(stderr, args): if parts[i].endswith('.' + args.ext) and parts[i + 1].isdigit(): print('::error file=%s,line=%s::%s' % (parts[i], parts[i + 1], ':'.join(parts[i + 2:]))) break - else: - print(line) + print(line) def main(args): From 20993f9a429a2011d1d696d504b8ea1e6fac0375 Mon Sep 17 00:00:00 2001 From: lethosor Date: Tue, 30 Jun 2020 14:03:05 -0400 Subject: [PATCH 142/547] script-docs.py: add support for printing errors in GitHub actions format --- travis/lint.py | 2 +- travis/script-docs.py | 40 +++++++++++++++++++++++++++++----------- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/travis/lint.py b/travis/lint.py index 51117201c..e1db140c2 100755 --- a/travis/lint.py +++ b/travis/lint.py @@ -105,7 +105,7 @@ class TabLinter(Linter): linters = [cls() for cls in Linter.__subclasses__() if not cls.ignore] def main(): - is_github_actions = os.environ.get('GITHUB_ACTIONS') + is_github_actions = bool(os.environ.get('GITHUB_ACTIONS')) root_path = os.path.abspath(sys.argv[1] if len(sys.argv) > 1 else '.') if not os.path.exists(root_path): print('Nonexistent path: %s' % root_path) diff --git a/travis/script-docs.py b/travis/script-docs.py index 04728e101..b2c8063bf 100755 --- a/travis/script-docs.py +++ b/travis/script-docs.py @@ -1,11 +1,10 @@ #!/usr/bin/env python3 -from __future__ import print_function -from io import open import os from os.path import basename, dirname, join, splitext import sys SCRIPT_PATH = sys.argv[1] if len(sys.argv) > 1 else 'scripts' +IS_GITHUB_ACTIONS = bool(os.environ.get('GITHUB_ACTIONS')) def expected_cmd(path): """Get the command from the name of a script.""" @@ -20,42 +19,61 @@ def check_ls(fname, line): line = line.strip() comment = '--' if fname.endswith('.lua') else '#' if '[====[' in line or not line.startswith(comment): - print('Error: no leading comment in ' + fname) + print_error('missing leading comment (requred for `ls`)', fname) return 1 return 0 +def print_error(message, filename, line=None): + if not isinstance(line, int): + line = 1 + print('Error: %s:%i: %s' % (filename, line, message)) + if IS_GITHUB_ACTIONS: + print('::error file=%s,line=%i::%s' % (filename, line, message)) + + def check_file(fname): errors, doclines = 0, [] tok1, tok2 = ('=begin', '=end') if fname.endswith('.rb') else \ ('[====[', ']====]') + doc_start_line = None with open(fname, errors='ignore') as f: lines = f.readlines() + if not lines: + print_error('empty file', fname) + return 1 errors += check_ls(fname, lines[0]) - for l in lines: + for i, l in enumerate(lines): if doclines or l.strip().endswith(tok1): + if not doclines: + doc_start_line = i + 1 doclines.append(l.rstrip()) if l.startswith(tok2): break else: if doclines: - print('Error: docs start but not end: ' + fname) + print_error('docs start but do not end', fname, doc_start_line) else: - print('Error: no documentation in: ' + fname) + print_error('no documentation found', fname) return 1 if not doclines: - print('Error: missing or malformed documentation in: ' + fname) + print_error('missing or malformed documentation', fname) return 1 title, underline = [d for d in doclines if d and '=begin' not in d and '[====[' not in d][:2] - if underline != '=' * len(title): - print('Error: title/underline mismatch:', fname, title, underline) + title_line = doc_start_line + doclines.index(title) + expected_underline = '=' * len(title) + if underline != expected_underline: + print_error('title/underline mismatch: expected {!r}, got {!r}'.format( + expected_underline, underline), + fname, title_line + 1) errors += 1 if title != expected_cmd(fname): - print('Warning: expected script title {}, got {}'.format( - expected_cmd(fname), title)) + print_error('expected script title {!r}, got {!r}'.format( + expected_cmd(fname), title), + fname, title_line) errors += 1 return errors From 142a7aa287daba0b1c652d67b94a6d4577d602de Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 1 Jul 2020 21:58:54 -0400 Subject: [PATCH 143/547] authors-rst.py: add support for printing errors in GitHub actions format --- travis/authors-rst.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/travis/authors-rst.py b/travis/authors-rst.py index e8db817f6..076f7f226 100755 --- a/travis/authors-rst.py +++ b/travis/authors-rst.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 """ Overly-complicated script to check formatting/sorting in Authors.rst """ -import re, sys +import os, re, sys def main(): success = [True] @@ -10,6 +10,8 @@ def main(): for k in kwargs: info += ' %s %s:' % (k, kwargs[k]) print('line %i:%s %s' % (line, info, msg)) + if os.environ.get('GITHUB_ACTIONS'): + print('::error file=docs/Authors.rst,line=%i::%s %s' % (line, info.lstrip(), msg)) success[0] = False with open('docs/Authors.rst', 'rb') as f: lines = list(map(lambda line: line.decode('utf8').replace('\n', ''), f.readlines())) From ae0f57f0e061d769e1189e58a54b4471ff4eb865 Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 1 Jul 2020 23:54:31 -0400 Subject: [PATCH 144/547] Update submodules --- library/xml | 2 +- scripts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/xml b/library/xml index b67b3fa4b..ec0f06754 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit b67b3fa4b02f834dc76a2e1eae21136e0be089f7 +Subproject commit ec0f06754f0e03655611fe29d388f0a3ffad21e4 diff --git a/scripts b/scripts index 3987d0314..e4b5898ac 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 3987d031469420d64aff23097d9548676f1ab752 +Subproject commit e4b5898acb9cae806ef99416e1f9265df3abeeae From 27ee6a30d491773a423693cf4622590cd1c627dc Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 1 Jul 2020 23:56:41 -0400 Subject: [PATCH 145/547] Add additional path to strawberry perl docs From http://www.bay12forums.com/smf/index.php?topic=164123.msg8141934#msg8141934 --- docs/Compile.rst | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/Compile.rst b/docs/Compile.rst index 650e762e3..5bb51a01f 100644 --- a/docs/Compile.rst +++ b/docs/Compile.rst @@ -545,23 +545,25 @@ to your binary search PATH so the tool can be later run from anywhere. Perl / Strawberry Perl ^^^^^^^^^^^^^^^^^^^^^^ -For the code generation parts you'll need Perl 5 with XML::LibXML and XML::LibXSLT. -`Strawberry Perl `_ is recommended as it includes -all of the required packages in a single, easy install. +For the code generation stage of the build process, you'll need Perl 5 with +XML::LibXML and XML::LibXSLT. `Strawberry Perl `_ is +recommended as it includes all of the required packages in a single, easy +install. After install, ensure Perl is in your user's PATH. This can be edited from ``Control Panel -> System -> Advanced System Settings -> Environment Variables``. -The following three directories must be in PATH, in this order: +The following directories must be in your PATH, in this order: * ``\c\bin`` * ``\perl\site\bin`` * ``\perl\bin`` +* ``\perl\vendor\lib\auto\XML\LibXML`` (may only be required on some systems) Be sure to close and re-open any existing ``cmd.exe`` windows after updating your PATH. -If you already have a different version of Perl (for example the one from Cygwin), +If you already have a different version of Perl installed (for example, from Cygwin), you can run into some trouble. Either remove the other Perl install from PATH, or install XML::LibXML and XML::LibXSLT for it using CPAN. From 72ce52e0044263e851dc59cca09dcd22e0324d8a Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Wed, 1 Jul 2020 23:10:13 -0500 Subject: [PATCH 146/547] update structures --- library/modules/Translation.cpp | 11 +---------- library/xml | 2 +- plugins/strangemood.cpp | 8 ++++---- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/library/modules/Translation.cpp b/library/modules/Translation.cpp index e05154b44..282039c02 100644 --- a/library/modules/Translation.cpp +++ b/library/modules/Translation.cpp @@ -69,16 +69,7 @@ bool Translation::copyName(df::language_name * source, df::language_name * targe if (source == target) return true; - target->first_name = source->first_name; - target->nickname = source->nickname; - for (int i = 0; i < 7; i++) - { - target->words[i] = source->words[i]; - target->parts_of_speech[i] = source->parts_of_speech[i]; - } - target->language = source->language; - target->unknown = source->unknown; - target->has_name = source->has_name; + *target = *source; return true; } diff --git a/library/xml b/library/xml index ec0f06754..b439f2287 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit ec0f06754f0e03655611fe29d388f0a3ffad21e4 +Subproject commit b439f22876634725f246703e3ac8a7a0b1a01d63 diff --git a/plugins/strangemood.cpp b/plugins/strangemood.cpp index e8a1046df..f37400cbb 100644 --- a/plugins/strangemood.cpp +++ b/plugins/strangemood.cpp @@ -153,7 +153,7 @@ void selectWord (const df::language_word_table &table, int32_t &word, df::part_o } } -void generateName(df::language_name &output, int language, int mode, const df::language_word_table &table1, const df::language_word_table &table2) +void generateName(df::language_name &output, int language, df::language_name_type mode, const df::language_word_table &table1, const df::language_word_table &table2) { for (int i = 0; i < 100; i++) { @@ -162,7 +162,7 @@ void generateName(df::language_name &output, int language, int mode, const df::l output = df::language_name(); if (language == -1) language = rng.df_trandom(world->raws.language.translations.size()); - output.unknown = mode; + output.type = mode; output.language = language; } output.has_name = 1; @@ -1316,10 +1316,10 @@ command_result df_strangemood (color_ostream &out, vector & parameters) // Generate the artifact's name if (type == mood_type::Fell || type == mood_type::Macabre) - generateName(unit->status.artifact_name, unit->name.language, 1, world->raws.language.word_table[0][2], world->raws.language.word_table[1][2]); + generateName(unit->status.artifact_name, unit->name.language, language_name_type::Artifact, world->raws.language.word_table[0][2], world->raws.language.word_table[1][2]); else { - generateName(unit->status.artifact_name, unit->name.language, 1, world->raws.language.word_table[0][1], world->raws.language.word_table[1][1]); + generateName(unit->status.artifact_name, unit->name.language, language_name_type::Artifact, world->raws.language.word_table[0][1], world->raws.language.word_table[1][1]); if (!rng.df_trandom(100)) unit->status.artifact_name = unit->name; } From 25f1b14a8882ee7cabaaccb31ca8bfe903972543 Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Wed, 1 Jul 2020 23:12:45 -0500 Subject: [PATCH 147/547] update structures --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index b439f2287..2d67b03a1 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit b439f22876634725f246703e3ac8a7a0b1a01d63 +Subproject commit 2d67b03a1c5c701e65fb483b9d6c1d3067f990cb From a04c609980ae5205dc11c7c4748b1b71a0ae4c40 Mon Sep 17 00:00:00 2001 From: PatrikLundell Date: Fri, 3 Jul 2020 13:46:32 +0200 Subject: [PATCH 148/547] fixed getplants, issue #1479 --- plugins/getplants.cpp | 109 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 108 insertions(+), 1 deletion(-) diff --git a/plugins/getplants.cpp b/plugins/getplants.cpp index d1ee79a04..b722776c0 100644 --- a/plugins/getplants.cpp +++ b/plugins/getplants.cpp @@ -9,11 +9,16 @@ #include "TileTypes.h" #include "df/map_block.h" +#include "df/map_block_column.h" #include "df/plant.h" #include "df/plant_growth.h" #include "df/plant_raw.h" #include "df/tile_dig_designation.h" +#include "df/ui.h" #include "df/world.h" +#include "df/world_data.h" +#include "df/world_object_data.h" +#include "df/world_site.h" #include "modules/Designations.h" #include "modules/Maps.h" @@ -27,7 +32,9 @@ using namespace DFHack; using namespace df::enums; DFHACK_PLUGIN("getplants"); +REQUIRE_GLOBAL(ui); REQUIRE_GLOBAL(world); +REQUIRE_GLOBAL(cur_year); REQUIRE_GLOBAL(cur_year_tick); enum class selectability { @@ -224,6 +231,106 @@ selectability selectablePlant(const df::plant_raw *plant, bool farming) } } +// Formula for determination of the variance in plant growth maturation time, determined via disassembly. +// The x and y parameters are in tiles relative to the embark. +bool ripe(int32_t x, int32_t y, int32_t start, int32_t end) { + int32_t time = ((435522653 - (((y + 3) * x + 5) * ((y + 7) * y * 400181475 + 289700012))) & 0x3FFFFFFF) % 2000 + (*cur_year_tick % 403200); + + return time >= start && (end == -1 || time <= end); +} + +// Looks in the picked growths vector to see if a matching growth has been marked as picked. +bool picked(const df::plant *plant, int32_t growth_subtype) { + df::world_data *world_data = world->world_data; + df::world_site *site = df::world_site::find(ui->site_id); + int32_t pos_x = site->global_min_x + plant->pos.x / 48; + int32_t pos_y = site->global_min_y + plant->pos.y / 48; + size_t id = pos_x + pos_y * 16 * world_data->world_width; + df::world_object_data *object_data = df::world_object_data::find(id); + df::map_block_column *column = world->map.map_block_columns[(plant->pos.x / 16) * world->map.x_count_block + (plant->pos.y / 16)]; + + for (size_t i = 0; i < object_data->picked_growths.x.size(); i++) { + if (object_data->picked_growths.x[i] == plant->pos.x && + object_data->picked_growths.y[i] == plant->pos.y && + object_data->picked_growths.z[i] - column->z_base == plant->pos.z && + object_data->picked_growths.subtype[i] == growth_subtype && + object_data->picked_growths.year[i] == *cur_year) { + return true; + } + } + + return false; +} + +bool designate(const df::plant *plant, bool farming) { + df::plant_raw *plant_raw = world->raws.plants.all[plant->material]; + const DFHack::MaterialInfo basic_mat = DFHack::MaterialInfo(plant_raw->material_defs.type_basic_mat, plant_raw->material_defs.idx_basic_mat); + + if (basic_mat.material->flags.is_set(material_flags::EDIBLE_RAW) || + basic_mat.material->flags.is_set(material_flags::EDIBLE_COOKED)) + { + return Designations::markPlant(plant); + } + + if (plant_raw->flags.is_set(plant_raw_flags::THREAD) || + plant_raw->flags.is_set(plant_raw_flags::MILL) || + plant_raw->flags.is_set(plant_raw_flags::EXTRACT_VIAL) || + plant_raw->flags.is_set(plant_raw_flags::EXTRACT_BARREL) || + plant_raw->flags.is_set(plant_raw_flags::EXTRACT_STILL_VIAL)) + { + if (!farming) { + return Designations::markPlant(plant); + } + } + + if (basic_mat.material->reaction_product.id.size() > 0 || + basic_mat.material->reaction_class.size() > 0) + { + if (!farming) { + return Designations::markPlant(plant); + } + } + + for (size_t i = 0; i < plant_raw->growths.size(); i++) + { + if (plant_raw->growths[i]->item_type == df::item_type::SEEDS || // Only trees have seed growths in vanilla, but raws can be modded... + plant_raw->growths[i]->item_type == df::item_type::PLANT_GROWTH) + { + const DFHack::MaterialInfo growth_mat = DFHack::MaterialInfo(plant_raw->growths[i]->mat_type, plant_raw->growths[i]->mat_index); + if ((plant_raw->growths[i]->item_type == df::item_type::SEEDS && + (growth_mat.material->flags.is_set(material_flags::EDIBLE_COOKED) || + growth_mat.material->flags.is_set(material_flags::EDIBLE_RAW))) || + (plant_raw->growths[i]->item_type == df::item_type::PLANT_GROWTH && + growth_mat.material->flags.is_set(material_flags::LEAF_MAT))) // Will change name to STOCKPILE_PLANT_GROWTH any day now... + { + bool seedSource = plant_raw->growths[i]->item_type == df::item_type::SEEDS; + + if (plant_raw->growths[i]->item_type == df::item_type::PLANT_GROWTH) + { + for (size_t k = 0; growth_mat.material->reaction_product.material.mat_type.size(); k++) + { + if (growth_mat.material->reaction_product.material.mat_type[k] == plant_raw->material_defs.type_seed && + growth_mat.material->reaction_product.material.mat_index[k] == plant_raw->material_defs.idx_seed) + { + seedSource = true; + break; + } + } + } + + if ((!farming || seedSource) && + ripe(plant->pos.x, plant->pos.y, plant_raw->growths[i]->timing_1, plant_raw->growths[i]->timing_2) && + !picked(plant, i)) + { + return Designations::markPlant(plant); + } + } + } + } + + return false; +} + command_result df_getplants (color_ostream &out, vector & parameters) { string plantMatStr = ""; @@ -448,7 +555,7 @@ command_result df_getplants (color_ostream &out, vector & parameters) collectionCount[plant->material]++; ++count; } - if (!deselect && Designations::markPlant(plant)) + if (!deselect && designate(plant, farming)) { // out.print("Designated %s at (%i, %i, %i), %d\n", world->raws.plants.all[plant->material]->id.c_str(), plant->pos.x, plant->pos.y, plant->pos.z, (int)i); collectionCount[plant->material]++; From 0a2a16d29c401a7fbf606b9cf842385104c0cb30 Mon Sep 17 00:00:00 2001 From: PatrikLundell Date: Fri, 3 Jul 2020 15:50:18 +0200 Subject: [PATCH 149/547] corrected ripeness calculation --- plugins/getplants.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/getplants.cpp b/plugins/getplants.cpp index b722776c0..db283d808 100644 --- a/plugins/getplants.cpp +++ b/plugins/getplants.cpp @@ -234,7 +234,7 @@ selectability selectablePlant(const df::plant_raw *plant, bool farming) // Formula for determination of the variance in plant growth maturation time, determined via disassembly. // The x and y parameters are in tiles relative to the embark. bool ripe(int32_t x, int32_t y, int32_t start, int32_t end) { - int32_t time = ((435522653 - (((y + 3) * x + 5) * ((y + 7) * y * 400181475 + 289700012))) & 0x3FFFFFFF) % 2000 + (*cur_year_tick % 403200); + int32_t time = (((435522653 - (((y + 3) * x + 5) * ((y + 7) * y * 400181475 + 289700012))) & 0x3FFFFFFF) % 2000 + *cur_year_tick) % 403200; return time >= start && (end == -1 || time <= end); } From 30c8db811dc2c5ee99b857200460b52afaadd8c5 Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 3 Jul 2020 16:50:52 -0400 Subject: [PATCH 150/547] Add note referring to gui/liquids, update scripts (docs) --- docs/Plugins.rst | 6 +++++- scripts | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/Plugins.rst b/docs/Plugins.rst index 421e5e81b..5c855ddd3 100644 --- a/docs/Plugins.rst +++ b/docs/Plugins.rst @@ -2356,11 +2356,15 @@ dfhack command line and can't be used from a hotkey. Settings will be remembered as long as dfhack runs. Intended for use in combination with the command ``liquids-here`` (which can be bound to a hotkey). See also :issue:`80`. -.. note:: +.. warning:: Spawning and deleting liquids can mess up pathing data and temperatures (creating heat traps). You've been warned. +.. note:: + + `gui/liquids` is an in-game UI for this script. + Settings will be remembered until you quit DF. You can call `liquids-here` to execute the last configured action, which is useful in combination with keybindings. diff --git a/scripts b/scripts index e4b5898ac..d265de74d 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit e4b5898acb9cae806ef99416e1f9265df3abeeae +Subproject commit d265de74d4c28460961f8e646b1b574997756ea2 From 9a3747d307e48f053e246c6bf8f23d00a0da1b67 Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 3 Jul 2020 20:42:23 -0400 Subject: [PATCH 151/547] Make sidebar fixed --- conf.py | 1 + docs/styles/dfhack.css | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/conf.py b/conf.py index c36e4f8aa..9f497fb57 100644 --- a/conf.py +++ b/conf.py @@ -297,6 +297,7 @@ html_theme_options = { 'github_repo': 'dfhack', 'github_button': False, 'travis_button': False, + 'fixed_sidebar': True, } # The name for this set of Sphinx documents. If None, it defaults to diff --git a/docs/styles/dfhack.css b/docs/styles/dfhack.css index d12348c31..bfe37720d 100644 --- a/docs/styles/dfhack.css +++ b/docs/styles/dfhack.css @@ -46,3 +46,12 @@ div.body p, div.body dd, div.body li, div.body blockquote { -webkit-hyphens: manual; hyphens: manual; } + +div.sphinxsidebar { + max-height: 100%; + overflow-y: auto; +} + +div.sphinxsidebar h3 > a { + border-bottom: 1px dotted #999; +} From fa910cd74f45f3fd1838dc3c5c8c11b3b3b0a8c3 Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 3 Jul 2020 22:43:21 -0400 Subject: [PATCH 152/547] Include custom CSS separately instead of overriding theme CSS May help with https://github.com/DFHack/dfhack/issues/1578#issuecomment-635512324 --- conf.py | 7 +++++-- docs/styles/dfhack.css | 3 --- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/conf.py b/conf.py index 9f497fb57..b3f2b5848 100644 --- a/conf.py +++ b/conf.py @@ -187,7 +187,7 @@ all_keybinds_documented() # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. -needs_sphinx = '1.3' +needs_sphinx = '1.8' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom @@ -286,7 +286,6 @@ todo_include_todos = False # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'alabaster' -html_style = 'dfhack.css' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the @@ -337,6 +336,10 @@ html_domain_indices = False # If false, no index is generated. html_use_index = False +html_css_files = [ + 'dfhack.css', +] + # -- Options for LaTeX output --------------------------------------------- # Grouping the document tree into LaTeX files. List of tuples diff --git a/docs/styles/dfhack.css b/docs/styles/dfhack.css index bfe37720d..e7a608460 100644 --- a/docs/styles/dfhack.css +++ b/docs/styles/dfhack.css @@ -1,6 +1,3 @@ -/* make sure to sync this with the base theme's css filename */ -@import url("alabaster.css"); - /* Keybinding CSS from the DF wiki; applies to :kbd:`` directives. * Use this directive for all keypresses, to make them look like keys. */ From f32757fa0910c178bf3174c1d9daf03de3a86c49 Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 3 Jul 2020 22:49:48 -0400 Subject: [PATCH 153/547] Update scripts --- plugins/buildingplan-lib.cpp | 1 - scripts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/buildingplan-lib.cpp b/plugins/buildingplan-lib.cpp index 4e7cfd3fd..0c29284db 100644 --- a/plugins/buildingplan-lib.cpp +++ b/plugins/buildingplan-lib.cpp @@ -9,7 +9,6 @@ void debug(const string &msg) color_ostream_proxy out(Core::getInstance().getConsole()); out << "DEBUG (" << PLUGIN_VERSION << "): " << msg << endl; } -#define dbg Core::getInstance().getConsole() void enable_quickfort_fn(pair& pair) { pair.second = true; } diff --git a/scripts b/scripts index d265de74d..e8de92efb 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit d265de74d4c28460961f8e646b1b574997756ea2 +Subproject commit e8de92efb73d5ef4d0b52df000d60d3350f07a37 From f81f77352cbca122cf72c589b2f5d160e0db660a Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 4 Jul 2020 02:15:05 -0400 Subject: [PATCH 154/547] Restructure changelog generation as a Sphinx extension --- conf.py | 10 ++++++---- docs/sphinx_extensions/dfhack/__init__.py | 0 .../dfhack/changelog.py} | 14 ++++++++++++++ 3 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 docs/sphinx_extensions/dfhack/__init__.py rename docs/{gen_changelog.py => sphinx_extensions/dfhack/changelog.py} (97%) diff --git a/conf.py b/conf.py index b3f2b5848..47d1c0c58 100644 --- a/conf.py +++ b/conf.py @@ -22,8 +22,6 @@ import re import shlex # pylint:disable=unused-import import sys -sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'docs')) -from gen_changelog import generate_changelog # -- Support :dfhack-keybind:`command` ------------------------------------ # this is a custom directive that pulls info from dfhack.init-example @@ -180,19 +178,23 @@ def all_keybinds_documented(): # Actually call the docs generator and run test -generate_changelog() write_script_docs() all_keybinds_documented() # -- General configuration ------------------------------------------------ +sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'docs', 'sphinx_extensions')) + # If your documentation needs a minimal Sphinx version, state it here. needs_sphinx = '1.8' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = ['sphinx.ext.extlinks'] +extensions = [ + 'sphinx.ext.extlinks', + 'dfhack.changelog', +] # This config value must be a dictionary of external sites, mapping unique # short alias names to a base URL and a prefix. diff --git a/docs/sphinx_extensions/dfhack/__init__.py b/docs/sphinx_extensions/dfhack/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/docs/gen_changelog.py b/docs/sphinx_extensions/dfhack/changelog.py similarity index 97% rename from docs/gen_changelog.py rename to docs/sphinx_extensions/dfhack/changelog.py index 8b1a6771e..4c0f30427 100644 --- a/docs/gen_changelog.py +++ b/docs/sphinx_extensions/dfhack/changelog.py @@ -283,3 +283,17 @@ if __name__ == '__main__': print('stable missing: ' + description) if description not in content_dev: print('dev missing: ' + description) + + +def sphinx_entrypoint(app, config): + generate_changelog() + + +def setup(app): + app.connect('config-inited', sphinx_entrypoint) + + return { + 'version': '0.1', + 'parallel_read_safe': True, + 'parallel_write_safe': True, + } From b0fe96f6c7c81c800e7cf2e9df148637feeb6392 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 4 Jul 2020 02:35:55 -0400 Subject: [PATCH 155/547] Add gen_changelog.py compatibility shim, fix paths when run under cmake --- docs/gen_changelog.py | 5 +++++ docs/sphinx_extensions/dfhack/changelog.py | 19 ++++++++++--------- docs/sphinx_extensions/dfhack/util.py | 7 +++++++ 3 files changed, 22 insertions(+), 9 deletions(-) create mode 100644 docs/gen_changelog.py create mode 100644 docs/sphinx_extensions/dfhack/util.py diff --git a/docs/gen_changelog.py b/docs/gen_changelog.py new file mode 100644 index 000000000..3b4452f62 --- /dev/null +++ b/docs/gen_changelog.py @@ -0,0 +1,5 @@ +import os, sys +sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'sphinx_extensions')) + +from dfhack.changelog import cli_entrypoint +cli_entrypoint() diff --git a/docs/sphinx_extensions/dfhack/changelog.py b/docs/sphinx_extensions/dfhack/changelog.py index 4c0f30427..99f0ea299 100644 --- a/docs/sphinx_extensions/dfhack/changelog.py +++ b/docs/sphinx_extensions/dfhack/changelog.py @@ -4,11 +4,14 @@ import itertools import os import sys +from dfhack.util import DFHACK_ROOT, DOCS_ROOT + CHANGELOG_PATHS = ( 'docs/changelog.txt', 'scripts/changelog.txt', 'library/xml/changelog.txt', ) +CHANGELOG_PATHS = (os.path.join(DFHACK_ROOT, p) for p in CHANGELOG_PATHS) CHANGELOG_SECTIONS = [ 'New Plugins', @@ -237,8 +240,8 @@ def generate_changelog(all=False): consolidate_changelog(stable_entries) consolidate_changelog(dev_entries) - print_changelog(versions, stable_entries, 'docs/_auto/news.rst') - print_changelog(versions, dev_entries, 'docs/_auto/news-dev.rst') + print_changelog(versions, stable_entries, os.path.join(DOCS_ROOT, '_auto/news.rst')) + print_changelog(versions, dev_entries, os.path.join(DOCS_ROOT, '_auto/news-dev.rst')) if all: for version in versions: @@ -250,16 +253,16 @@ def generate_changelog(all=False): else: version_entries = {version: dev_entries[version]} print_changelog([version], version_entries, - 'docs/_changelogs/%s-github.txt' % version, + os.path.join(DOCS_ROOT, '_changelogs/%s-github.txt' % version), replace=False) print_changelog([version], version_entries, - 'docs/_changelogs/%s-reddit.txt' % version, + os.path.join(DOCS_ROOT, '_changelogs/%s-reddit.txt' % version), replace=False, prefix='> ') return entries -if __name__ == '__main__': +def cli_entrypoint(): import argparse parser = argparse.ArgumentParser() parser.add_argument('-a', '--all', action='store_true', @@ -268,14 +271,12 @@ if __name__ == '__main__': help='Check that all entries are printed') args = parser.parse_args() - os.chdir(os.path.abspath(os.path.dirname(__file__))) - os.chdir('..') entries = generate_changelog(all=args.all) if args.check: - with open('docs/_auto/news.rst') as f: + with open(os.path.join(DOCS_ROOT, '_auto/news.rst')) as f: content_stable = f.read() - with open('docs/_auto/news-dev.rst') as f: + with open(os.path.join(DOCS_ROOT, '_auto/news-dev.rst')) as f: content_dev = f.read() for entry in entries: for description in entry.children: diff --git a/docs/sphinx_extensions/dfhack/util.py b/docs/sphinx_extensions/dfhack/util.py new file mode 100644 index 000000000..71a432da4 --- /dev/null +++ b/docs/sphinx_extensions/dfhack/util.py @@ -0,0 +1,7 @@ +import os + +DFHACK_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) +DOCS_ROOT = os.path.join(DFHACK_ROOT, 'docs') + +if not os.path.isdir(DOCS_ROOT): + raise ReferenceError('docs root not found: %s' % DOCS_ROOT) From b122870b6a0e5b43d962c6c9be810139e0a9aa60 Mon Sep 17 00:00:00 2001 From: lethosor Date: Tue, 7 Jul 2020 01:54:59 -0400 Subject: [PATCH 156/547] Move documentation standards to Documentation.rst --- Contributing.rst | 89 +------------------------------ docs/Documentation.rst | 115 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 104 insertions(+), 100 deletions(-) diff --git a/Contributing.rst b/Contributing.rst index e358e66b3..cb9e87a0e 100644 --- a/Contributing.rst +++ b/Contributing.rst @@ -32,6 +32,7 @@ How to get new code into DFHack (i.e. not the master or develop branch of your fork). * If possible, compile on multiple platforms when changing anything that compiles * It must pass CI - run ``python travis/all.py`` to check this. +* Update documentation when applicable - see `docs-standards` for details. * Update ``changelog.txt`` and ``docs/Authors.rst`` when applicable. See `build-changelog` for more information on the changelog format. * Create a GitHub pull request once finished @@ -126,94 +127,6 @@ know what exactly is most useful. `remotefortressreader` provides a fairly comprehensive interface for visualisers such as :forums:`Armok Vision <146473>`. -Documentation Standards -======================= -DFHack documentation is built with Sphinx_, and configured automatically -through CMake. If you want to build the docs *only*, use this command:: - - sphinx-build . docs/html - -Whether you're adding new code or just fixing old documentation (and there's plenty), -there are a few important standards for completeness and consistent style. Treat -this section as a guide rather than iron law, match the surrounding text, and you'll -be fine. - -Each command should have a short (~54 character) help string, which is shown -by the `ls` command. For scripts, this is a comment on the first line -(the comment marker and whitespace is stripped). For plugins it's the second -argument to ``PluginCommand``. Please make this brief but descriptive! - -Everything should be documented! If it's not clear *where* a particular -thing should be documented, ask on IRC or in the DFHack thread on Bay12 - -as well as getting help, you'll be providing valuable feedback that -makes it easier for future readers! - -Scripts can use a custom autodoc function, based on the Sphinx ``include`` -directive - anything between the tokens is copied into the appropriate scripts -documentation page. For Ruby, we follow the built-in docstring convention -(``=begin`` and ``=end``). For Lua, the tokens are ``[====[`` and ``]====]`` -- ordinary multi-line strings. It is highly encouraged to reuse this string -as the in-console documentation by (eg.) printing it when a ``-help`` argument -is given. - -The docs **must** have a heading which exactly matches the command, underlined -with ``=====`` to the same length. For example, a lua file would have:: - - local helpstr = [====[ - - add-thought - =========== - Adds a thought or emotion to the selected unit. Can be used by other scripts, - or the gui invoked by running ``add-thought gui`` with a unit selected. - - ]====] - - -Where the heading for a section is also the name of a command, the spelling -and case should exactly match the command to enter in the DFHack command line. - -Try to keep lines within 80-100 characters, so it's readable in plain text -in the terminal - Sphinx (our documentation system) will make sure -paragraphs flow. - -If there aren't many options or examples to show, they can go in a paragraph of -text. Use double-backticks to put commands in monospaced font, like this:: - - You can use ``cleanowned scattered x`` to dump tattered or abandoned items. - -If the command takes more than three arguments, format the list as a table -called Usage. The table *only* lists arguments, not full commands. -Input values are specified in angle brackets. Example:: - - Usage: - - :arg1: A simple argument. - :arg2 : Does something based on the input value. - :Very long argument: - Is very specific. - -To demonstrate usage - useful mainly when the syntax is complicated, list the -full command with arguments in monospaced font, then indent the next line and -describe the effect:: - - ``resume all`` - Resumes all suspended constructions. - -If it would be helpful to mention another DFHack command, don't just type the -name - add a hyperlink! Specify the link target in backticks, and it will be -replaced with the corresponding title and linked: eg ```autolabor``` -=> `autolabor`. Link targets should be equivalent to the command -described (without file extension), and placed above the heading of that -section like this:: - - .. _autolabor: - - autolabor - ========= - -Add link targets if you need them, but otherwise plain headings are preferred. -Scripts have link targets created automatically. - Other ways to help ================== DFHack is a software project, but there's a lot more to it than programming. diff --git a/docs/Documentation.rst b/docs/Documentation.rst index f7cb9ef92..2fa32e16c 100644 --- a/docs/Documentation.rst +++ b/docs/Documentation.rst @@ -28,21 +28,118 @@ The main thing you lose in plain text format is hyperlinking.) .. contents:: +.. _docs-standards: + +Documentation standards +======================= + +Whether you're adding new code or just fixing old documentation (and there's plenty), +there are a few important standards for completeness and consistent style. Treat +this section as a guide rather than iron law, match the surrounding text, and you'll +be fine. + +Each command should have a short (~54 character) help string, which is shown +by the `ls` command. For scripts, this is a comment on the first line +(the comment marker and whitespace is stripped). For plugins it's the second +argument to ``PluginCommand``. Please make this brief but descriptive! + +Everything should be documented! If it's not clear *where* a particular +thing should be documented, ask on IRC or in the DFHack thread on Bay12 - +as well as getting help, you'll be providing valuable feedback that +makes it easier for future readers! + +Scripts can use a custom autodoc function, based on the Sphinx ``include`` +directive - anything between the tokens is copied into the appropriate scripts +documentation page. For Ruby, we follow the built-in docstring convention +(``=begin`` and ``=end``). For Lua, the tokens are ``[====[`` and ``]====]`` +- ordinary multi-line strings. It is highly encouraged to reuse this string +as the in-console documentation by (eg.) printing it when a ``-help`` argument +is given. + +The docs **must** have a heading which exactly matches the command, underlined +with ``=====`` to the same length. For example, a lua file would have:: + + local helpstr = [====[ + + add-thought + =========== + Adds a thought or emotion to the selected unit. Can be used by other scripts, + or the gui invoked by running ``add-thought gui`` with a unit selected. + + ]====] + + +Where the heading for a section is also the name of a command, the spelling +and case should exactly match the command to enter in the DFHack command line. + +Try to keep lines within 80-100 characters, so it's readable in plain text +in the terminal - Sphinx (our documentation system) will make sure +paragraphs flow. + +If there aren't many options or examples to show, they can go in a paragraph of +text. Use double-backticks to put commands in monospaced font, like this:: + + You can use ``cleanowned scattered x`` to dump tattered or abandoned items. + +If the command takes more than three arguments, format the list as a table +called Usage. The table *only* lists arguments, not full commands. +Input values are specified in angle brackets. Example:: + + Usage: + + :arg1: A simple argument. + :arg2 : Does something based on the input value. + :Very long argument: + Is very specific. + +To demonstrate usage - useful mainly when the syntax is complicated, list the +full command with arguments in monospaced font, then indent the next line and +describe the effect:: + + ``resume all`` + Resumes all suspended constructions. + +If it would be helpful to mention another DFHack command, don't just type the +name - add a hyperlink! Specify the link target in backticks, and it will be +replaced with the corresponding title and linked: eg ```autolabor``` +=> `autolabor`. Link targets should be equivalent to the command +described (without file extension), and placed above the heading of that +section like this:: + + .. _autolabor: + + autolabor + ========= + +Add link targets if you need them, but otherwise plain headings are preferred. +Scripts have link targets created automatically. + + +Building the documentation +========================== + Required dependencies -===================== +--------------------- In order to build the documentation, you must have Python with Sphinx -version 1.3.1 or later. Both Python 2.x and 3.x are supported. +version 1.8 or later. Both Python 2.x and 3.x are supported. When installing Sphinx from OS package managers, be aware that there is another program called Sphinx, completely unrelated to documentation management. Be sure you are installing the right Sphinx; it may be called ``python-sphinx``, for example. To avoid doubt, ``pip`` can be used instead as detailed below. +Once you have installed Sphinx, ``sphinx-build --version`` should report the +version of Sphinx that you have installed. If this works, CMake should also be +able to find Sphinx. + For more detailed platform-specific instructions, see the sections below: +.. contents:: + :local: + Linux ------ +~~~~~ Most Linux distributions will include Python as standard. Check your package manager to see if Sphinx 1.3.1 or later is available, @@ -66,7 +163,7 @@ install, find ``sphinx-build`` and ensure its directory is in your local ``$PATH macOS ------ +~~~~~ macOS has Python 2.7 installed by default, but it does not have the pip package manager. You can install Homebrew's Python 3, which includes pip, and then install the @@ -87,7 +184,7 @@ If not, just installing sphinx-doc for macOS's system Python 2.7 is fine. Windows -------- +~~~~~~~ Python for Windows can be downloaded `from python.org `_. The latest version of Python 3 is recommended, as it includes pip already. @@ -105,13 +202,6 @@ Note that this may require opening a new (admin) command prompt if you just installed pip from the same command prompt. -Building the documentation -========================== - -Once you have installed Sphinx, ``sphinx-build --version`` should report the -version of Sphinx that you have installed. If this works, CMake should also be -able to find Sphinx. - Using CMake ----------- @@ -155,6 +245,7 @@ the root DFHack folder:: Sphinx has many options to enable clean builds, parallel builds, logging, and more - run ``sphinx-build --help`` for details. + .. _build-changelog: Building the changelogs From 512f425c65cd5394a7e36f7c49b048249ecd450e Mon Sep 17 00:00:00 2001 From: lethosor Date: Tue, 7 Jul 2020 23:49:28 -0400 Subject: [PATCH 157/547] Move Contributing.rst to docs/, add GitHub-specific version in .github/ --- .github/CONTRIBUTING.md | 6 ++++++ Contributing.rst => docs/Contributing.rst | 0 index.rst | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 .github/CONTRIBUTING.md rename Contributing.rst => docs/Contributing.rst (100%) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 000000000..2367db678 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,6 @@ +Thank you for your interest in contributing to DFHack! If you're reading this +document, you're probably viewing it on GitHub. The DFHack docs are hosted +on [ReadTheDocs](https://dfhack.readthedocs.io/) - in particular, contributing +guidelines are [here](https://docs.dfhack.org/en/latest/docs/Contributing.html). +Double-checking the style guidelines before submitting a pull request is +always appreciated. diff --git a/Contributing.rst b/docs/Contributing.rst similarity index 100% rename from Contributing.rst rename to docs/Contributing.rst diff --git a/index.rst b/index.rst index 855b31a73..8c1e9d86d 100644 --- a/index.rst +++ b/index.rst @@ -58,7 +58,7 @@ For Developers .. toctree:: :maxdepth: 1 - /Contributing + /docs/Contributing /docs/Compile /docs/NEWS-dev /docs/Lua API From 7f56faa64a63c043be96c572d8792624cb982807 Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 8 Jul 2020 00:08:47 -0400 Subject: [PATCH 158/547] Tweak Documentation.rst TOC --- docs/Documentation.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/Documentation.rst b/docs/Documentation.rst index 2fa32e16c..cbbf8e153 100644 --- a/docs/Documentation.rst +++ b/docs/Documentation.rst @@ -1,8 +1,8 @@ .. _documentation: -#################### -DFHack Documentation -#################### +########################### +DFHack Documentation System +########################### DFHack documentation, like the file you are reading now, is created as ``.rst`` files, @@ -136,6 +136,7 @@ For more detailed platform-specific instructions, see the sections below: .. contents:: :local: + :backlinks: none Linux From aff2944f28418bb71095daf57159d7146d9e4f62 Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 8 Jul 2020 00:12:05 -0400 Subject: [PATCH 159/547] Add "scripts-" prefix to generated scripts subpage anchors --- conf.py | 2 +- docs/Core.rst | 2 +- docs/Introduction.rst | 2 +- index.rst | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/conf.py b/conf.py index 47d1c0c58..1c5ef9853 100644 --- a/conf.py +++ b/conf.py @@ -151,7 +151,7 @@ def write_script_docs(): 'gui': 'GUI Scripts', 'modtools': 'Scripts for Modders'} for k in head: - title = ('.. _{k}:\n\n{l}\n{t}\n{l}\n\n' + title = ('.. _scripts-{k}:\n\n{l}\n{t}\n{l}\n\n' '.. include:: /scripts/{a}about.txt\n\n' '.. contents::\n\n').format( k=k, t=head[k], diff --git a/docs/Core.rst b/docs/Core.rst index 4e65f4dda..9cad075f4 100644 --- a/docs/Core.rst +++ b/docs/Core.rst @@ -408,7 +408,7 @@ All matching init files will be executed in alphebetical order. 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 `fix ` script to run on `repeat`. +a `fix ` script to run on `repeat`. .. _onUnload.init: diff --git a/docs/Introduction.rst b/docs/Introduction.rst index 22033d528..52675d364 100644 --- a/docs/Introduction.rst +++ b/docs/Introduction.rst @@ -20,7 +20,7 @@ enhancements by default, and more can be enabled. There are also many tools You can even add third-party scripts and plugins to do almost anything! For modders, DFHack makes many things possible. Custom reactions, new -interactions, magic creature abilities, and more can be set through `modtools` +interactions, magic creature abilities, and more can be set through `scripts-modtools` and custom raws. Non-standard DFHack scripts and inits can be stored in the raw directory, making raws or saves fully self-contained for distribution - or for coexistence in a single DF install, even with incompatible components. diff --git a/index.rst b/index.rst index 8c1e9d86d..b3498d432 100644 --- a/index.rst +++ b/index.rst @@ -20,7 +20,7 @@ enhancements by default, and more can be enabled. There are also many tools You can even add third-party scripts and plugins to do almost anything! For modders, DFHack makes many things possible. Custom reactions, new -interactions, magic creature abilities, and more can be set through `modtools` +interactions, magic creature abilities, and more can be set through `scripts-modtools` and custom raws. Non-standard DFHack scripts and inits can be stored in the raw directory, making raws or saves fully self-contained for distribution - or for coexistence in a single DF install, even with incompatible components. From 85003a40c2f89693faed8af9185571e0b9a8194f Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 8 Jul 2020 01:03:58 -0400 Subject: [PATCH 160/547] Split memory research into separate doc and expand --- docs/Binpatches.rst | 2 +- docs/Compile.rst | 2 + docs/Contributing.rst | 20 ------ docs/Memory-research.rst | 149 +++++++++++++++++++++++++++++++++++++++ index.rst | 1 + 5 files changed, 153 insertions(+), 21 deletions(-) create mode 100644 docs/Memory-research.rst diff --git a/docs/Binpatches.rst b/docs/Binpatches.rst index a0fcc6630..40ae8af32 100644 --- a/docs/Binpatches.rst +++ b/docs/Binpatches.rst @@ -24,7 +24,7 @@ There are no binary patches available for Dwarf Fortress versions after 0.34.11. This system is kept for the chance that someone will find it useful, so some hints on how to write your own follow. This will require disassembly and -decent skill in `memory research `. +decent skill in `memory research `. * The patches are expected to be encoded in text format used by IDA. diff --git a/docs/Compile.rst b/docs/Compile.rst index 5bb51a01f..c8c51e88c 100644 --- a/docs/Compile.rst +++ b/docs/Compile.rst @@ -161,6 +161,8 @@ in any case. Note that the scripts in the "build" folder on Windows will set the architecture automatically. +.. _compile-build-options: + Other settings -------------- There are a variety of other settings which you can find in CMakeCache.txt in diff --git a/docs/Contributing.rst b/docs/Contributing.rst index cb9e87a0e..6231b6f04 100644 --- a/docs/Contributing.rst +++ b/docs/Contributing.rst @@ -41,26 +41,6 @@ How to get new code into DFHack * Work on :issue:`reported problems ` will take priority over ideas or suggestions. -.. _contributing-memory-research: - -Memory research ---------------- -If you want to do memory research, you'll need some tools and some knowledge. -In general, you'll need a good memory viewer and optionally something -to look at machine code without getting crazy :) -Using publicly known information and analyzing the game's data is preferred. - -Good Windows tools include: - -* IDA Freeware 7.0 (for non-commercial use, supports 32-bit and 64-bit) -* Cheat Engine - -Good Linux tools: - -* angavrilov's df-structures gui (32-bit only, visit us on IRC for details) -* IDA Freeware 7.0 (see above) -* edb (Evan's Debugger) -* Some of the tools residing in the ``legacy`` dfhack branch. Using the library as a developer ================================ diff --git a/docs/Memory-research.rst b/docs/Memory-research.rst new file mode 100644 index 000000000..08c0c9573 --- /dev/null +++ b/docs/Memory-research.rst @@ -0,0 +1,149 @@ +.. _memory-research: + +############### +Memory research +############### + +There are a variety of tools that can be used to analyze DF memory - some are +listed here. Note that some of these may be old and unmaintained. If you aren't +sure what tool would be best for your purposes, feel free to ask for advice (on +IRC, Bay12, etc.). + +.. contents:: + :local: + + +Cross-platform tools +==================== + +Ghidra +------ + +Ghidra is a cross-platform reverse-engineering framework (written in Java) +available at https://ghidra-sre.org. It supports analyzing both 32-bit and +64-bit executables for all supported DF platforms. There are some custom DFHack +Ghidra scripts available in the `df_misc`_ repo (look for ``.java`` files). + + +IDA Freeware 7.0 +---------------- + +Available from `Hex-Rays `_. +Supports analyzing both 32-bit and 64-bit executables for all supported DF platforms. +Some ``.idc`` scripts for IDA are available in the `df_misc`_ repo. + +.. _df_misc: https://github.com/DFHack/df_misc + + +Hopper +------ + +Runs on macOS and some Linux distributions; available from https://www.hopperapp.com/. +`TWBT `_ uses this to produce some patches. + + +DFHack tools +------------ + +Plugins +~~~~~~~ + +There are a few development plugins useful for low-level memory research. They +are not built by default, but can be built by setting the ``BUILD_DEVEL`` +`CMake option `. These include: + +- ``check-structures-sanity``, which performs sanity checks on the given DF + object. Note that this will crash in several cases, some intentional, so using + this with `GDB ` is recommended. +- ``memview``, which produces a hex dump of a given memory range. It also + highlights valid pointers, and can be configured to work with `sizecheck` + to auto-detect object sizes. +- ``vectors``, which can identify instances of ``std::vector`` in a given memory range. + +Scripts +~~~~~~~ + +Several `development scripts ` can be useful for memory research. +These include (but are not limited to): + +- `devel/dump-offsets` +- `devel/find-offsets` +- `devel/lsmem` +- `devel/sc` (requires `sizecheck`) +- `devel/visualize-structure` +- Generally, any script starting with ``devel/find`` + +.. _sizecheck: + +Sizecheck +~~~~~~~~~ + +Sizecheck is a custom tool that hooks into the memory allocator and inserts a +header indicating the size of every object. The corresponding logic to check for +this header when freeing memory usually works, but is inherently not foolproof. +You should not count on DF being stable when using this. + +DFHack's implementation of sizecheck is currently only tested on Linux, although +it probably also works on macOS. It can be built with the ``BUILD_SIZECHECK`` +`CMake option `, which produces a ``libsizecheck`` +library installed in the ``hack`` folder. You will need to preload this library +manually, by setting ``PRELOAD_LIB`` on Linux (or ``LD_PRELOAD`` if editing +the ``dfhack`` launcher script directly), or by editing the ``dfhack`` +launcher script and adding the library to ``DYLD_INSERT_LIBRARIES`` on macOS. + +There is also an older sizecheck implementation by Mifki available on +`GitHub `__ (``b.cpp`` is the main +sizecheck library, and ``win_patch.cpp`` is used for Windows support). To use +this with other DFHack tools, you will likely need to edit the header's +magic number to match what is used in `devel/sc` (search for a hexadecimal +constant starting with ``0x``). + +Legacy tools +~~~~~~~~~~~~ + +Some very old DFHack tools are available in the `legacy branch on GitHub `_. +No attempt is made to support these. + + +Linux-specific tools +==================== + +.. _linux-gdb: + +GDB +--- + +`GDB `_ is technically cross-platform, but +tends to work best on Linux, and DFHack currently only offers support for using +GDB on 64-bit Linux. To start with GDB, pass ``-g`` to the DFHack launcher +script:: + + ./dfhack -g + +Some basic GDB commands: + +- ``run``: starts DF from the GDB prompt. Any arguments will be passed as + command-line arguments to DF (e.g. `load-save` may be useful). +- ``bt`` will produce a backtrace if DF crashes. + +See the `official GDB documentation `_ +for more details. + + +df-structures GUI +----------------- + +This is a tool written by Angavrilov and available on `GitHub `__. +It only supports 32-bit DF. Some assistance may be available on IRC. + + +EDB (Evan's debugger) +--------------------- + +Available on `GitHub `__. + + +Windows-specific tools +====================== + +Some people have used `Cheat Engine `__ for research in the past. diff --git a/index.rst b/index.rst index b3498d432..4c5b2e6e4 100644 --- a/index.rst +++ b/index.rst @@ -65,4 +65,5 @@ For Developers /docs/Documentation /library/xml/SYNTAX /library/xml/how-to-update + /docs/Memory-research /docs/Binpatches From 24d64175fb7f9c0c4e148841abee69fd905a09e7 Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 8 Jul 2020 02:13:37 -0400 Subject: [PATCH 161/547] Remove top-level links from TOCs --- conf.py | 3 ++- docs/Binpatches.rst | 3 ++- docs/Compile.rst | 5 +++-- docs/Contributing.rst | 4 ++-- docs/Core.rst | 5 +++-- docs/Documentation.rst | 4 ++-- docs/History.rst | 19 +++++++++++-------- docs/Introduction.rst | 3 ++- docs/Lua API.rst | 5 +++-- docs/Memory-research.rst | 4 ++-- docs/NEWS-dev.rst | 5 +++-- docs/NEWS.rst | 9 +++++---- docs/Plugins.rst | 5 +++-- docs/Scripts-removed.rst | 5 +++-- library/xml | 2 +- 15 files changed, 47 insertions(+), 34 deletions(-) diff --git a/conf.py b/conf.py index 1c5ef9853..aebe73bab 100644 --- a/conf.py +++ b/conf.py @@ -153,7 +153,8 @@ def write_script_docs(): for k in head: title = ('.. _scripts-{k}:\n\n{l}\n{t}\n{l}\n\n' '.. include:: /scripts/{a}about.txt\n\n' - '.. contents::\n\n').format( + '.. contents:: Contents\n' + ' :local:\n\n').format( k=k, t=head[k], l=len(head[k])*'#', a=('' if k == 'base' else k + '/') diff --git a/docs/Binpatches.rst b/docs/Binpatches.rst index 40ae8af32..b92190bc8 100644 --- a/docs/Binpatches.rst +++ b/docs/Binpatches.rst @@ -15,7 +15,8 @@ the `binpatch` command. at all possible - that way your work will work for many versions across multiple operating systems. -.. contents:: +.. contents:: Contents + :local: Getting a patch diff --git a/docs/Compile.rst b/docs/Compile.rst index c8c51e88c..26f720076 100644 --- a/docs/Compile.rst +++ b/docs/Compile.rst @@ -13,8 +13,9 @@ DFHack from source, this document will walk you through the build process. Note that some steps may be unconventional compared to other projects, so be sure to pay close attention if this is your first time compiling DFHack. -.. contents:: - :depth: 2 +.. contents:: Contents + :local: + :depth: 1 .. _compile-how-to-get-the-code: diff --git a/docs/Contributing.rst b/docs/Contributing.rst index 6231b6f04..28e4e6e95 100644 --- a/docs/Contributing.rst +++ b/docs/Contributing.rst @@ -2,8 +2,8 @@ How to contribute to DFHack ########################### -.. contents:: - +.. contents:: Contents + :local: .. _contributing-code: diff --git a/docs/Core.rst b/docs/Core.rst index 9cad075f4..8f84c7b54 100644 --- a/docs/Core.rst +++ b/docs/Core.rst @@ -4,8 +4,9 @@ DFHack Core ########### -.. contents:: - :depth: 2 +.. contents:: Contents + :local: + :depth: 2 Command Implementation diff --git a/docs/Documentation.rst b/docs/Documentation.rst index cbbf8e153..8a829c0a8 100644 --- a/docs/Documentation.rst +++ b/docs/Documentation.rst @@ -25,8 +25,8 @@ compile the documentation in order to read it. Like Markdown, reST documents are designed to be just as readable in a plain-text editor as they are in HTML format. The main thing you lose in plain text format is hyperlinking.) -.. contents:: - +.. contents:: Contents + :local: .. _docs-standards: diff --git a/docs/History.rst b/docs/History.rst index 8386c4cab..d382b351e 100644 --- a/docs/History.rst +++ b/docs/History.rst @@ -1,16 +1,19 @@ :orphan: -.. _HISTORY: +.. _History: -######################## -HISTORY - old changelogs -######################## +##################### +Historical changelogs +##################### -This file is where old changelogs live, so the current `changelog` -in ``NEWS.rst`` doesn't get too long. +This file is where old changelogs live, so the `current changelog ` +doesn't get too long. Some of these changelogs are also formatted differently +from current changelogs and would be difficult for the current `changelog +generation system ` to handle. -.. contents:: - :depth: 2 +.. contents:: Contents + :local: + :depth: 1 DFHack 0.43.05-r3 ================= diff --git a/docs/Introduction.rst b/docs/Introduction.rst index 52675d364..dc05c8725 100644 --- a/docs/Introduction.rst +++ b/docs/Introduction.rst @@ -30,7 +30,8 @@ allows easier development of new tools. As an open-source project under `various copyleft licences `, contributions are welcome. -.. contents:: +.. contents:: Contents + :local: .. _installing: diff --git a/docs/Lua API.rst b/docs/Lua API.rst index d7e94b92a..3e0f22116 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -24,8 +24,9 @@ implemented by Lua files located in :file:`hack/lua/*` (:file:`library/lua/*` in the git repo). -.. contents:: - :depth: 3 +.. contents:: Contents + :local: + :depth: 2 ========================= diff --git a/docs/Memory-research.rst b/docs/Memory-research.rst index 08c0c9573..41aa437c8 100644 --- a/docs/Memory-research.rst +++ b/docs/Memory-research.rst @@ -9,8 +9,8 @@ listed here. Note that some of these may be old and unmaintained. If you aren't sure what tool would be best for your purposes, feel free to ask for advice (on IRC, Bay12, etc.). -.. contents:: - :local: +.. contents:: Contents + :local: Cross-platform tools diff --git a/docs/NEWS-dev.rst b/docs/NEWS-dev.rst index 7a9da7cb7..f0c47fe96 100644 --- a/docs/NEWS-dev.rst +++ b/docs/NEWS-dev.rst @@ -13,7 +13,8 @@ which they first appeared. See `build-changelog` for more information. See `changelog` for a list of changes grouped by stable releases. -.. contents:: - :depth: 2 +.. contents:: Contents + :local: + :depth: 1 .. include:: /docs/_auto/news-dev.rst diff --git a/docs/NEWS.rst b/docs/NEWS.rst index 22f9881b9..1283b079a 100644 --- a/docs/NEWS.rst +++ b/docs/NEWS.rst @@ -13,14 +13,15 @@ appeared. See `build-changelog` for more information. See `dev-changelog` for a list of changes grouped by development releases. -.. contents:: - :depth: 2 +.. contents:: Contents + :local: + :depth: 1 .. include:: /docs/_auto/news.rst Older Changelogs ================ -Are kept in a seperate file: `HISTORY` +Are kept in a seperate file: `History` -.. that's ``docs/history.rst``, if you're reading the raw text. +.. that's ``docs/History.rst``, if you're reading the raw text. diff --git a/docs/Plugins.rst b/docs/Plugins.rst index 5c855ddd3..0bd699e14 100644 --- a/docs/Plugins.rst +++ b/docs/Plugins.rst @@ -9,8 +9,9 @@ game subsystems or the entire renderer. Most commands offered by plugins are listed here, hopefully organised in a way you will find useful. -.. contents:: - :depth: 3 +.. contents:: Contents + :local: + :depth: 2 =============================== Data inspection and visualizers diff --git a/docs/Scripts-removed.rst b/docs/Scripts-removed.rst index 4490110ba..5fa3d3ec4 100644 --- a/docs/Scripts-removed.rst +++ b/docs/Scripts-removed.rst @@ -4,8 +4,9 @@ Removed scripts The following scripts were removed for various reasons. -.. contents:: - :depth: 2 +.. contents:: Contents + :local: + :depth: 1 .. _warn-stuck-trees: diff --git a/library/xml b/library/xml index 2d67b03a1..847ec0c2d 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 2d67b03a1c5c701e65fb483b9d6c1d3067f990cb +Subproject commit 847ec0c2d4dc74a887e1f980eeed6f97345c195e From 858e90e6c2d06b8e4b81201273699b18878b056e Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 8 Jul 2020 21:04:23 -0400 Subject: [PATCH 162/547] Move Scripts-removed.rst to Removed.rst and update a bit --- docs/Removed.rst | 17 +++++++++++++++++ docs/Scripts-removed.rst | 15 --------------- index.rst | 2 +- 3 files changed, 18 insertions(+), 16 deletions(-) create mode 100644 docs/Removed.rst delete mode 100644 docs/Scripts-removed.rst diff --git a/docs/Removed.rst b/docs/Removed.rst new file mode 100644 index 000000000..f98915bdd --- /dev/null +++ b/docs/Removed.rst @@ -0,0 +1,17 @@ +############# +Removed tools +############# + +This page lists tools (plugins or scripts) that were previously included in +DFHack but have been removed. It exists primarily so that internal links still +work (e.g. links from the `changelog`). + +.. contents:: Contents + :local: + :depth: 1 + +.. _warn-stuck-trees: + +warn-stuck-trees +================ +The corresponding DF bug, :bug:`9252` was fixed in DF 0.44.01. diff --git a/docs/Scripts-removed.rst b/docs/Scripts-removed.rst deleted file mode 100644 index 5fa3d3ec4..000000000 --- a/docs/Scripts-removed.rst +++ /dev/null @@ -1,15 +0,0 @@ -############### -Removed scripts -############### - -The following scripts were removed for various reasons. - -.. contents:: Contents - :local: - :depth: 1 - -.. _warn-stuck-trees: - -warn-stuck-trees -================ -The corresponding DF bug, :bug:`9252` was fixed in DF 0.44.01. diff --git a/index.rst b/index.rst index 4c5b2e6e4..10424f5fe 100644 --- a/index.rst +++ b/index.rst @@ -50,7 +50,7 @@ Other Contents /docs/Authors /LICENSE /docs/NEWS - /docs/Scripts-removed + /docs/Removed For Developers ============== From 87fd32d330a50b126ec8ea3a15145e982fbd0064 Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 8 Jul 2020 22:52:20 -0400 Subject: [PATCH 163/547] Move general dev info to a separate doc (Dev-intro) --- docs/Contributing.rst | 65 ------------------------------------------ docs/Dev-intro.rst | 66 +++++++++++++++++++++++++++++++++++++++++++ docs/index-dev.rst | 20 +++++++++++++ index.rst | 17 +---------- 4 files changed, 87 insertions(+), 81 deletions(-) create mode 100644 docs/Dev-intro.rst create mode 100644 docs/index-dev.rst diff --git a/docs/Contributing.rst b/docs/Contributing.rst index 28e4e6e95..7ce092a8e 100644 --- a/docs/Contributing.rst +++ b/docs/Contributing.rst @@ -42,71 +42,6 @@ How to get new code into DFHack will take priority over ideas or suggestions. -Using the library as a developer -================================ -Currently, the most direct way to use the library is to write a script or plugin that can be loaded by it. -All the plugins can be found in the 'plugins' folder. There's no in-depth documentation -on how to write one yet, but it should be easy enough to copy one and just follow the pattern. -``plugins/skeleton/skeleton.cpp`` is provided for this purpose. - -Other than through plugins, it is possible to use DFHack via remote access interface, -or by writing scripts in Lua or Ruby. There are plenty of examples in the scripts folder. -The `lua-api` is quite well documented. - -The most important parts of DFHack are the Core, Console, Modules and Plugins. - -* Core acts as the centerpiece of DFHack - it acts as a filter between DF and - SDL and synchronizes the various plugins with DF. -* Console is a thread-safe console that can be used to invoke commands exported by Plugins. -* Modules actually describe the way to access information in DF's memory. You - can get them from the Core. Most modules are split into two parts: high-level - and low-level. High-level is mostly method calls, low-level publicly visible - pointers to DF's data structures. -* Plugins are the tools that use all the other stuff to make things happen. - A plugin can have a list of commands that it exports and an onupdate function - that will be called each DF game tick. - -Rudimentary API documentation can be built using doxygen (see build options -in ``CMakeCache.txt`` or with ``ccmake`` or ``cmake-gui``). The full DFHack -documentation is built with Sphinx_, which runs automatically at compile time. - -.. _Sphinx: http://www.sphinx-doc.org - -DFHack consists of variously licensed code, but invariably weak copyleft. -The main license is zlib/libpng, some bits are MIT licensed, and some are -BSD licensed. See the `license` for more information. - -Feel free to add your own extensions and plugins. Contributing back to -the DFHack repository is welcome and the right thing to do :) - -DF data structure definitions ------------------------------ -DFHack uses information about the game data structures, represented via xml files -in the ``library/xml/`` submodule. - -See https://github.com/DFHack/df-structures, and the documentation linked in the index. - -Data structure layouts are described in files following the ``df.*.xml`` name pattern. -This information is transformed by a perl script into C++ headers describing the -structures, and associated metadata for the Lua wrapper. These headers and data -are then compiled into the DFHack libraries, thus necessitating a compatibility -break every time layouts change; in return it significantly boosts the efficiency -and capabilities of DFHack code. - -Global object addresses are stored in :file:`symbols.xml`, which is copied to the dfhack -release package and loaded as data at runtime. - -Remote access interface ------------------------ -DFHack supports remote access by exchanging Google protobuf messages via a TCP -socket. Both the core and plugins can define remotely accessible methods. The -``dfhack-run`` command uses this interface to invoke ordinary console commands. - -Currently the supported set of requests is limited, because the developers don't -know what exactly is most useful. `remotefortressreader` provides a fairly -comprehensive interface for visualisers such as :forums:`Armok Vision <146473>`. - - Other ways to help ================== DFHack is a software project, but there's a lot more to it than programming. diff --git a/docs/Dev-intro.rst b/docs/Dev-intro.rst new file mode 100644 index 000000000..e43f03659 --- /dev/null +++ b/docs/Dev-intro.rst @@ -0,0 +1,66 @@ +=========================== +DFHack development overview +=========================== + +Currently, the most direct way to use the library is to write a script or plugin that can be loaded by it. +All the plugins can be found in the 'plugins' folder. There's no in-depth documentation +on how to write one yet, but it should be easy enough to copy one and just follow the pattern. +``plugins/skeleton/skeleton.cpp`` is provided for this purpose. + +Other than through plugins, it is possible to use DFHack via remote access interface, +or by writing scripts in Lua or Ruby. There are plenty of examples in the scripts folder. +The `lua-api` is quite well documented. + +The most important parts of DFHack are the Core, Console, Modules and Plugins. + +* Core acts as the centerpiece of DFHack - it acts as a filter between DF and + SDL and synchronizes the various plugins with DF. +* Console is a thread-safe console that can be used to invoke commands exported by Plugins. +* Modules actually describe the way to access information in DF's memory. You + can get them from the Core. Most modules are split into two parts: high-level + and low-level. High-level is mostly method calls, low-level publicly visible + pointers to DF's data structures. +* Plugins are the tools that use all the other stuff to make things happen. + A plugin can have a list of commands that it exports and an onupdate function + that will be called each DF game tick. + +Rudimentary API documentation can be built using doxygen (see build options +in ``CMakeCache.txt`` or with ``ccmake`` or ``cmake-gui``). The full DFHack +documentation is built with Sphinx_, which runs automatically at compile time. + +.. _Sphinx: http://www.sphinx-doc.org + +DFHack consists of variously licensed code, but invariably weak copyleft. +The main license is zlib/libpng, some bits are MIT licensed, and some are +BSD licensed. See the `license` for more information. + +Feel free to add your own extensions and plugins. Contributing back to +the DFHack repository is welcome and the right thing to do :) + +DF data structure definitions +----------------------------- +DFHack uses information about the game data structures, represented via xml files +in the ``library/xml/`` submodule. + +See https://github.com/DFHack/df-structures, and the documentation linked in the index. + +Data structure layouts are described in files following the ``df.*.xml`` name pattern. +This information is transformed by a perl script into C++ headers describing the +structures, and associated metadata for the Lua wrapper. These headers and data +are then compiled into the DFHack libraries, thus necessitating a compatibility +break every time layouts change; in return it significantly boosts the efficiency +and capabilities of DFHack code. + +Global object addresses are stored in :file:`symbols.xml`, which is copied to the dfhack +release package and loaded as data at runtime. + +Remote access interface +----------------------- +DFHack supports remote access by exchanging Google protobuf messages via a TCP +socket. Both the core and plugins can define remotely accessible methods. The +``dfhack-run`` command uses this interface to invoke ordinary console commands. + +Currently the supported set of requests is limited, because the developers don't +know what exactly is most useful. `remotefortressreader` provides a fairly +comprehensive interface for visualisers such as :forums:`Armok Vision <146473>`. + diff --git a/docs/index-dev.rst b/docs/index-dev.rst new file mode 100644 index 000000000..9134ff6b5 --- /dev/null +++ b/docs/index-dev.rst @@ -0,0 +1,20 @@ +======================== +DFHack Development Guide +======================== + +These are pages relevant to people developing for DFHack. + +.. toctree:: + :maxdepth: 1 + + /docs/Dev-intro + /docs/Contributing + /docs/Compile + /docs/NEWS-dev + /docs/Lua API + /docs/Documentation + /library/xml/SYNTAX + /library/xml/how-to-update + /docs/Memory-research + /docs/Binpatches + diff --git a/index.rst b/index.rst index 10424f5fe..df28d0778 100644 --- a/index.rst +++ b/index.rst @@ -40,6 +40,7 @@ User Manual /docs/Core /docs/Plugins /docs/Scripts + /docs/index-dev Other Contents ============== @@ -51,19 +52,3 @@ Other Contents /LICENSE /docs/NEWS /docs/Removed - -For Developers -============== - -.. toctree:: - :maxdepth: 1 - - /docs/Contributing - /docs/Compile - /docs/NEWS-dev - /docs/Lua API - /docs/Documentation - /library/xml/SYNTAX - /library/xml/how-to-update - /docs/Memory-research - /docs/Binpatches From 108e100d2206cd7710d4c2a8074b42d8264a6a58 Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 8 Jul 2020 23:10:55 -0400 Subject: [PATCH 164/547] Move structures overview to Structures-intro.rst and update/elaborate --- docs/Dev-intro.rst | 16 ---------------- docs/Structures-intro.rst | 34 ++++++++++++++++++++++++++++++++++ docs/index-dev.rst | 3 +-- 3 files changed, 35 insertions(+), 18 deletions(-) create mode 100644 docs/Structures-intro.rst diff --git a/docs/Dev-intro.rst b/docs/Dev-intro.rst index e43f03659..6983693e8 100644 --- a/docs/Dev-intro.rst +++ b/docs/Dev-intro.rst @@ -37,22 +37,6 @@ BSD licensed. See the `license` for more information. Feel free to add your own extensions and plugins. Contributing back to the DFHack repository is welcome and the right thing to do :) -DF data structure definitions ------------------------------ -DFHack uses information about the game data structures, represented via xml files -in the ``library/xml/`` submodule. - -See https://github.com/DFHack/df-structures, and the documentation linked in the index. - -Data structure layouts are described in files following the ``df.*.xml`` name pattern. -This information is transformed by a perl script into C++ headers describing the -structures, and associated metadata for the Lua wrapper. These headers and data -are then compiled into the DFHack libraries, thus necessitating a compatibility -break every time layouts change; in return it significantly boosts the efficiency -and capabilities of DFHack code. - -Global object addresses are stored in :file:`symbols.xml`, which is copied to the dfhack -release package and loaded as data at runtime. Remote access interface ----------------------- diff --git a/docs/Structures-intro.rst b/docs/Structures-intro.rst new file mode 100644 index 000000000..c45d03eaf --- /dev/null +++ b/docs/Structures-intro.rst @@ -0,0 +1,34 @@ +=================================== +DF data definitions (DF-structures) +=================================== + +DFHack's information about DF's data structures is stored in XML files in the +`df-structures repository `_. If you +have `obtained a local copy of the DFHack source `, +DF-structures is included as a submodule in ``library/xml``. + +Data structure layouts are described in files named with the ``df.*.xml`` +pattern. This information is transformed by a Perl script (``codegen.pl``) into +C++ headers, as well as metadata for the Lua wrapper. This ultimately allows +DFHack code to access DF data directly, with the same speed and capabilities as +DF itself, which is an advantage over the older out-of-process approach (used +by debuggers and utilities like Dwarf Therapist). The main disadvantage of this +approach is that any compiled code relying on these layouts will break when DF's +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 +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. + +The following pages contain more detailed information about various aspects +of DF-structures: + +.. toctree:: + :titlesonly: + + /library/xml/SYNTAX + /library/xml/how-to-update + diff --git a/docs/index-dev.rst b/docs/index-dev.rst index 9134ff6b5..617c0c0d7 100644 --- a/docs/index-dev.rst +++ b/docs/index-dev.rst @@ -13,8 +13,7 @@ These are pages relevant to people developing for DFHack. /docs/NEWS-dev /docs/Lua API /docs/Documentation - /library/xml/SYNTAX - /library/xml/how-to-update + /docs/Structures-intro /docs/Memory-research /docs/Binpatches From 7e620b09a44b21f4a107925314a410c87262ba1b Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 8 Jul 2020 23:38:18 -0400 Subject: [PATCH 165/547] Update dev-intro Doxygen was removed in 787c54d8a --- docs/Contributing.rst | 2 + docs/Dev-intro.rst | 85 +++++++++++++++++++++++++++++-------------- docs/Lua API.rst | 2 + 3 files changed, 62 insertions(+), 27 deletions(-) diff --git a/docs/Contributing.rst b/docs/Contributing.rst index 7ce092a8e..ab92d0571 100644 --- a/docs/Contributing.rst +++ b/docs/Contributing.rst @@ -1,3 +1,5 @@ +.. _contributing: + ########################### How to contribute to DFHack ########################### diff --git a/docs/Dev-intro.rst b/docs/Dev-intro.rst index 6983693e8..b1961378c 100644 --- a/docs/Dev-intro.rst +++ b/docs/Dev-intro.rst @@ -2,41 +2,72 @@ DFHack development overview =========================== -Currently, the most direct way to use the library is to write a script or plugin that can be loaded by it. -All the plugins can be found in the 'plugins' folder. There's no in-depth documentation -on how to write one yet, but it should be easy enough to copy one and just follow the pattern. -``plugins/skeleton/skeleton.cpp`` is provided for this purpose. +DFHack has various components; this page provides an overview of some. If you +are looking to develop a tool for DFHack, developing a script or plugin is +likely the most straightforward choice. -Other than through plugins, it is possible to use DFHack via remote access interface, -or by writing scripts in Lua or Ruby. There are plenty of examples in the scripts folder. -The `lua-api` is quite well documented. +Other pages that may be relevant include: -The most important parts of DFHack are the Core, Console, Modules and Plugins. +- `contributing` +- `documentation` +- `license` -* Core acts as the centerpiece of DFHack - it acts as a filter between DF and - SDL and synchronizes the various plugins with DF. -* Console is a thread-safe console that can be used to invoke commands exported by Plugins. -* Modules actually describe the way to access information in DF's memory. You - can get them from the Core. Most modules are split into two parts: high-level - and low-level. High-level is mostly method calls, low-level publicly visible - pointers to DF's data structures. -* Plugins are the tools that use all the other stuff to make things happen. - A plugin can have a list of commands that it exports and an onupdate function - that will be called each DF game tick. -Rudimentary API documentation can be built using doxygen (see build options -in ``CMakeCache.txt`` or with ``ccmake`` or ``cmake-gui``). The full DFHack -documentation is built with Sphinx_, which runs automatically at compile time. +.. contents:: Contents + :local: -.. _Sphinx: http://www.sphinx-doc.org -DFHack consists of variously licensed code, but invariably weak copyleft. -The main license is zlib/libpng, some bits are MIT licensed, and some are -BSD licensed. See the `license` for more information. +Plugins +------- -Feel free to add your own extensions and plugins. Contributing back to -the DFHack repository is welcome and the right thing to do :) +DFHack plugins are written in C++ and located in the ``plugins`` folder. +Currently, documentation on how to write plugins is somewhat sparse. There are +templates that you can get use to get started in the ``plugins/skeleton`` +folder, and the source code of existing plugins can also be helpful. +If you want to compile a plugin that you have just added, you will need to add a +call to ``DFHACK_PLUGIN`` in ``plugins/CMakeLists.txt``. + +Plugins have the ability to make one or more commands available to users of the +DFHack console. Examples include `3dveins` (which implements the ``3dveins`` +command) and `reveal` (which implements ``reveal``, ``unreveal``, and several +other commands). + +Plugins can also register handlers to run on every tick, and can interface with +the built-in `enable` and `disable` commands. For the full plugin API, see the +skeleton plugins or ``PluginManager.cpp``. + +Scripts +------- + +DFHack scripts can currently be written in Lua or Ruby. The `Lua API ` +is more complete and currently better-documented, however. Referring to existing +scripts as well as the API documentation can be helpful when developing new +scripts. + +DFHack scripts live in a separate `scripts repository `_. +This can be found in the ``scripts`` submodule if you have +`cloned DFHack `, or the ``hack/scripts`` folder +of an installed copy of DFHack. + +Core +---- + +The DFHack core has a variety of low-level functions. It is responsible for +hooking into DF (via SDL), providing a console, and providing an interface +for plugins and scripts to interact with DF. + +Modules +------- + +A lot of shared code to interact with DF in more complicated ways is exposed by +**modules**. For example, the Units module contains functions for checking +various traits of units, changing nicknames properly, and more. Generally, +code that is useful to multiple plugins and scripts should go in the appropriate +module, if there is one. + +Several modules are also `exposed to Lua `, although +some functions (and some entire modules) are currently only available in C++. Remote access interface ----------------------- diff --git a/docs/Lua API.rst b/docs/Lua API.rst index 3e0f22116..4c7163623 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -802,6 +802,8 @@ Random number generation Dimension may be 1, 2 or 3 (default). +.. _lua-cpp-func-wrappers: + C++ function wrappers ===================== From ba0f8553ed5afde61ea9bec1360a089c7fcebcba Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 8 Jul 2020 23:46:38 -0400 Subject: [PATCH 166/547] Misc updates, links --- docs/Core.rst | 12 +++++++++--- docs/Dev-intro.rst | 22 ++++++++++++++-------- docs/Plugins.rst | 2 ++ docs/Scripts.rst | 2 ++ 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/docs/Core.rst b/docs/Core.rst index 8f84c7b54..6ef1d0575 100644 --- a/docs/Core.rst +++ b/docs/Core.rst @@ -166,10 +166,13 @@ right place to do it. Most such plugins or scripts support the built-in ``enable`` and ``disable`` commands. Calling them at any time without arguments prints a list of enabled and disabled plugins, and shows whether that can be changed -through the same commands. +through the same commands. Passing plugin names to these commands will enable +or disable the specified plugins. For example, to enable the `manipulator` +plugin:: -To enable or disable plugins that support this, use their names as -arguments for the command:: + enable manipulator + +It is also possible to enable or disable multiple plugins at once:: enable manipulator search @@ -272,6 +275,9 @@ something. Usage:: Allows dealing with plugins individually by name, or all at once. +Note that plugins do not maintain their enabled state if they are reloaded, so +you may need to use `enable` to re-enable a plugin after reloading it. + .. _ls: diff --git a/docs/Dev-intro.rst b/docs/Dev-intro.rst index b1961378c..9a08533c0 100644 --- a/docs/Dev-intro.rst +++ b/docs/Dev-intro.rst @@ -37,6 +37,12 @@ Plugins can also register handlers to run on every tick, and can interface with the built-in `enable` and `disable` commands. For the full plugin API, see the skeleton plugins or ``PluginManager.cpp``. +Installed plugins live in the ``hack/plugins`` folder of a DFHack installation, +and the `load` family of commands can be used to load a recompiled plugin +without restarting DF. + +See `plugins-index` for a list of all plugins included in DFHack. + Scripts ------- @@ -45,7 +51,7 @@ is more complete and currently better-documented, however. Referring to existing scripts as well as the API documentation can be helpful when developing new scripts. -DFHack scripts live in a separate `scripts repository `_. +`Scripts included in DFHack ` live in a separate `scripts repository `_. This can be found in the ``scripts`` submodule if you have `cloned DFHack `, or the ``hack/scripts`` folder of an installed copy of DFHack. @@ -53,17 +59,17 @@ of an installed copy of DFHack. Core ---- -The DFHack core has a variety of low-level functions. It is responsible for -hooking into DF (via SDL), providing a console, and providing an interface -for plugins and scripts to interact with DF. +The `DFHack core ` has a variety of low-level functions. It is +responsible for hooking into DF (via SDL), providing a console, and providing an +interface for plugins and scripts to interact with DF. Modules ------- -A lot of shared code to interact with DF in more complicated ways is exposed by -**modules**. For example, the Units module contains functions for checking -various traits of units, changing nicknames properly, and more. Generally, -code that is useful to multiple plugins and scripts should go in the appropriate +A lot of shared code to interact with DF in more complicated ways is contained +in **modules**. For example, the Units module contains functions for checking +various traits of units, changing nicknames properly, and more. Generally, code +that is useful to multiple plugins and scripts should go in the appropriate module, if there is one. Several modules are also `exposed to Lua `, although diff --git a/docs/Plugins.rst b/docs/Plugins.rst index 0bd699e14..0185dbee5 100644 --- a/docs/Plugins.rst +++ b/docs/Plugins.rst @@ -1,3 +1,5 @@ +.. _plugins-index: + ############## DFHack Plugins ############## diff --git a/docs/Scripts.rst b/docs/Scripts.rst index 0e6ef415c..419385582 100644 --- a/docs/Scripts.rst +++ b/docs/Scripts.rst @@ -1,3 +1,5 @@ +.. _scripts-index: + ############## DFHack Scripts ############## From fdb4487a3632e11b37d82efb8caf78fe12631484 Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 10 Jul 2020 02:11:03 -0400 Subject: [PATCH 167/547] Update Linux sphinx installation instructions, define substitution for minumum sphinx version --- conf.py | 7 +++++++ docs/Documentation.rst | 36 +++++++++++++++++++----------------- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/conf.py b/conf.py index aebe73bab..e70d836f1 100644 --- a/conf.py +++ b/conf.py @@ -283,6 +283,13 @@ pygments_style = 'sphinx' # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = False +rst_prolog = """ +.. |sphinx_min_version| replace:: {sphinx_min_version} +.. |dfhack_version| replace:: {dfhack_version} +""".format( + sphinx_min_version=needs_sphinx, + dfhack_version=version, +) # -- Options for HTML output ---------------------------------------------- diff --git a/docs/Documentation.rst b/docs/Documentation.rst index 8a829c0a8..462932b0f 100644 --- a/docs/Documentation.rst +++ b/docs/Documentation.rst @@ -121,7 +121,7 @@ Building the documentation Required dependencies --------------------- In order to build the documentation, you must have Python with Sphinx -version 1.8 or later. Both Python 2.x and 3.x are supported. +version |sphinx_min_version| or later. Both Python 2.x and 3.x are supported. When installing Sphinx from OS package managers, be aware that there is another program called Sphinx, completely unrelated to documentation management. @@ -141,27 +141,29 @@ For more detailed platform-specific instructions, see the sections below: Linux ~~~~~ -Most Linux distributions will include Python as standard. +Most Linux distributions will include Python by default. If not, start by +installing Python (preferably Python 3). On Debian-based distros:: -Check your package manager to see if Sphinx 1.3.1 or later is available, -but at the time of writing Ubuntu for example only has 1.2.x. + sudo apt install python3 -You can instead install Sphinx with the pip package manager. This may need -to be installed from your OS package manager; this is the case on Ubuntu. -On Ubuntu/Debian, use the following to first install pip:: +Check your package manager to see if Sphinx |sphinx_min_version| or later is +available. On Debian-based distros, this package is named ``python3-sphinx``. +If this package is new enough, you can install it directly. If not, or if you +want to use a newer Sphinx version (which may result in faster builds), you +can install Sphinx through the ``pip`` package manager instead. On Debian-based +distros, you can install pip with:: - sudo apt-get install python-pip + sudo apt install python3-pip -Once pip is available, you can then install the Python Sphinx module with:: +Once pip is available, you can then install Sphinx with:: - pip install sphinx - -If you run this as a normal user it will install a local copy for your user only. -Run it with sudo if you want a system-wide install. Either is fine for DFHack, -however if installing locally do check that ``sphinx-build`` is in your path. -It may be installed in a directory such as ``~/.local/bin/``, so after pip -install, find ``sphinx-build`` and ensure its directory is in your local ``$PATH``. + pip3 install sphinx +If you run this as an unpriviliged user, it may install a local copy of Sphinx +for your user only. The ``sphinx-build`` executable will typically end up in +``~/.local/bin/`` in this case. Alternatively, you can install Sphinx +system-wide by running pip with ``sudo``. In any case, you will need the folder +containing ``sphinx-build`` to be in your ``$PATH``. macOS ~~~~~ @@ -173,7 +175,7 @@ latest Sphinx using pip:: brew install python3 pip3 install sphinx -Alternatively, you can simply install Sphinx 1.3.x directly from Homebrew:: +Alternatively, you can simply install Sphinx directly from Homebrew:: brew install sphinx-doc From 9284daaf89c4bbeb9bede091820c2bd28fc947c4 Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 10 Jul 2020 19:59:34 -0400 Subject: [PATCH 168/547] Unset content min-width to improve mobile layout --- docs/styles/dfhack.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/styles/dfhack.css b/docs/styles/dfhack.css index e7a608460..43063cee2 100644 --- a/docs/styles/dfhack.css +++ b/docs/styles/dfhack.css @@ -52,3 +52,7 @@ div.sphinxsidebar { div.sphinxsidebar h3 > a { border-bottom: 1px dotted #999; } + +div.body { + min-width: unset; +} From c30d27cfbd6c560bd922ad01f7a8c94ce2d525f4 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 11 Jul 2020 01:41:38 -0400 Subject: [PATCH 169/547] Silence strangemood warnings --- plugins/strangemood.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/strangemood.cpp b/plugins/strangemood.cpp index f37400cbb..67ccbf719 100644 --- a/plugins/strangemood.cpp +++ b/plugins/strangemood.cpp @@ -314,6 +314,9 @@ void generateName(df::language_name &output, int language, df::language_name_typ if (rng.df_trandom(100)) selectWord(table2, output.words[4], output.parts_of_speech[4], 4); break; + default: + // not handled yet + break; } if (output.words[2] != -1 && output.words[3] != -1 && world->raws.language.words[output.words[3]]->adj_dist < world->raws.language.words[output.words[2]]->adj_dist) From 07a2b4a9d7cfa10ab533815c9d50fc5a10305066 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 11 Jul 2020 02:05:38 -0400 Subject: [PATCH 170/547] Use language_name_type enum item names --- library/xml | 2 +- plugins/strangemood.cpp | 48 ++++++++++++++++++++++++++++++++++------- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/library/xml b/library/xml index 847ec0c2d..b9028b0bb 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 847ec0c2d4dc74a887e1f980eeed6f97345c195e +Subproject commit b9028b0bb9ad40d3ad4dc3f10934bb61aa16629b diff --git a/plugins/strangemood.cpp b/plugins/strangemood.cpp index 67ccbf719..b1b48f1a5 100644 --- a/plugins/strangemood.cpp +++ b/plugins/strangemood.cpp @@ -171,7 +171,9 @@ void generateName(df::language_name &output, int language, df::language_name_typ int r, r2, r3; switch (mode) { - case 0: case 9: case 10: + case language_name_type::Figure: + case language_name_type::FigureNoFirst: + case language_name_type::FigureFirstOnly: if (mode != 9) { int32_t word; df::part_of_speech part; @@ -182,7 +184,8 @@ void generateName(df::language_name &output, int language, df::language_name_typ } if (mode != 10) { - case 4: case 37: // this is not a typo + case language_name_type::Site: + case language_name_type::Unk37: // this is not a typo if (rng.df_trandom(2)) { selectWord(table2, output.words[0], output.parts_of_speech[0], 0); @@ -196,7 +199,9 @@ void generateName(df::language_name &output, int language, df::language_name_typ } break; - case 1: case 13: case 20: + case language_name_type::Artifact: + case language_name_type::Unk13: + case language_name_type::River: r = rng.df_trandom(3); if (r == 0 || r == 1) { @@ -213,7 +218,9 @@ void generateName(df::language_name &output, int language, df::language_name_typ } if (r == 1 || r == 2) { - case 3: case 8: case 11: // this is not a typo either + case language_name_type::Squad: + case language_name_type::LegendaryFigure: + case language_name_type::ArtImage: // this is not a typo either r2 = rng.df_trandom(2); if (r2) selectWord(table1, output.words[5], output.parts_of_speech[5], 2); @@ -256,9 +263,34 @@ void generateName(df::language_name &output, int language, df::language_name_typ output.parts_of_speech[5] = part_of_speech::NounPlural; break; - case 2: case 5: case 6: case 12: case 14: case 15: case 16: case 17: case 18: case 19: - case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: - case 31: case 32: case 33: case 34: case 35: case 36: case 38: case 39: + case language_name_type::Civilization: + case language_name_type::World: + case language_name_type::Region: + case language_name_type::AdventuringGroup: + case language_name_type::SiteGovernment: + case language_name_type::Unk15: + case language_name_type::Vessel: + case language_name_type::MilitaryUnit: + case language_name_type::Religion: + case language_name_type::MountainPeak: + case language_name_type::Temple: + case language_name_type::Keep: + case language_name_type::MeadHall: + case language_name_type::Unk24: + case language_name_type::Unk25: + case language_name_type::Unk26: + case language_name_type::Market: + case language_name_type::Tavern: + case language_name_type::War: + case language_name_type::Battle: + case language_name_type::Siege: + case language_name_type::Road: + case language_name_type::Wall: + case language_name_type::Bridge: + case language_name_type::Tunnel: + case language_name_type::PretentiousEntityPosition: + case language_name_type::Tomb: + case language_name_type::MigratingGroup: selectWord(table1, output.words[5], output.parts_of_speech[5], 2); r3 = rng.df_trandom(3); if (rng.df_trandom(50)) @@ -280,7 +312,7 @@ void generateName(df::language_name &output, int language, df::language_name_typ selectWord(table2, output.words[4], output.parts_of_speech[4], 4); break; - case 7: + case language_name_type::Dungeon: r = rng.df_trandom(3); if (r == 0 || r == 1) { From 1043a4e49b2f848d39f90a17b0c5d0a2b5b638db Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 11 Jul 2020 23:50:51 -0400 Subject: [PATCH 171/547] Update intro, fix bay12 link, shorten index, add quick links section --- docs/Compile.rst | 2 ++ docs/Introduction.rst | 13 +++++++------ index.rst | 38 ++++++++++++++------------------------ 3 files changed, 23 insertions(+), 30 deletions(-) diff --git a/docs/Compile.rst b/docs/Compile.rst index 26f720076..68187e7fa 100644 --- a/docs/Compile.rst +++ b/docs/Compile.rst @@ -1,3 +1,5 @@ +.. _compile: + ################ Compiling DFHack ################ diff --git a/docs/Introduction.rst b/docs/Introduction.rst index dc05c8725..4490086f3 100644 --- a/docs/Introduction.rst +++ b/docs/Introduction.rst @@ -7,14 +7,15 @@ Introduction and Overview DFHack is a Dwarf Fortress memory access library, distributed with a wide variety of useful scripts and plugins. -The project is currently hosted at https://www.github.com/DFHack/dfhack, -and can be downloaded from `the releases page -`_. +The project is currently hosted `on GitHub `_, +and can be downloaded from `the releases page `_ +- see `installing` for installation instructions. This is also where the +`DFHack bug tracker `_ is hosted. -All new releases are announced in :forums:`the bay12 forums thread <139553>`, +All new releases are announced in `the Bay12 forums thread `_, which is also a good place for discussion and questions. -For users, it provides a significant suite of bugfixes and interface +For users, DFHack provides a significant suite of bugfixes and interface enhancements by default, and more can be enabled. There are also many tools (such as `workflow` or `autodump`) which can make life easier. You can even add third-party scripts and plugins to do almost anything! @@ -27,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 copyleft licences `, contributions are welcome. +`various open-source licences `, contributions are welcome. .. contents:: Contents diff --git a/index.rst b/index.rst index df28d0778..d5c7fbc10 100644 --- a/index.rst +++ b/index.rst @@ -2,33 +2,23 @@ Welcome to DFHack's documentation! ################################## -Introduction -============ -DFHack is a Dwarf Fortress memory access library, distributed with -a wide variety of useful scripts and plugins. +DFHack is a memory editing library for `Dwarf Fortress `_ +that provides a unified, cross-platform environment where tools can be developed +to extend the game. The default distribution contains a variety of tools, including +bugfixes, interface improvements, automation tools, modding tools, and more. +There are also a variety of third-party tools available. -The project is currently hosted at https://www.github.com/DFHack/dfhack, -and can be downloaded from `the releases page -`_. +.. _quick-links: -All new releases are announced in :forums:`the bay12 forums thread <139553>`, -which is also a good place for discussion and questions. - -For users, it provides a significant suite of bugfixes and interface -enhancements by default, and more can be enabled. There are also many tools -(such as `workflow` or `autodump`) which can make life easier. -You can even add third-party scripts and plugins to do almost anything! - -For modders, DFHack makes many things possible. Custom reactions, new -interactions, magic creature abilities, and more can be set through `scripts-modtools` -and custom raws. Non-standard DFHack scripts and inits can be stored in the -raw directory, making raws or saves fully self-contained for distribution - -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 copyleft licences `, contributions are welcome. +Quick Links +=========== +* `Downloads `_ +* `Installation guide ` +* `Source code `_ + (**important:** read `compile` before attempting to build from source) +* `Bay 12 forums thread `_ +* `Bug tracker `_ User Manual =========== From 801961bf7853b2747a46ce553529fe73c03a422f Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 11 Jul 2020 23:55:02 -0400 Subject: [PATCH 172/547] Move changelog, license, authors into main TOC tree --- docs/index-about.rst | 13 +++++++++++++ index.rst | 12 +----------- 2 files changed, 14 insertions(+), 11 deletions(-) create mode 100644 docs/index-about.rst diff --git a/docs/index-about.rst b/docs/index-about.rst new file mode 100644 index 000000000..3dba1e5f8 --- /dev/null +++ b/docs/index-about.rst @@ -0,0 +1,13 @@ +============ +About DFHack +============ + +These pages contain information about the general DFHack project. + +.. toctree:: + :maxdepth: 1 + + /docs/NEWS + /docs/Authors + /LICENSE + /docs/Removed diff --git a/index.rst b/index.rst index d5c7fbc10..91c883b51 100644 --- a/index.rst +++ b/index.rst @@ -30,15 +30,5 @@ User Manual /docs/Core /docs/Plugins /docs/Scripts + /docs/index-about /docs/index-dev - -Other Contents -============== - -.. toctree:: - :maxdepth: 1 - - /docs/Authors - /LICENSE - /docs/NEWS - /docs/Removed From 279d3e80f2f3691facae7cea3cc022b59251cd59 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 11 Jul 2020 23:56:15 -0400 Subject: [PATCH 173/547] Add kazimuth to authors --- docs/Authors.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Authors.rst b/docs/Authors.rst index e816389cd..3111b17f0 100644 --- a/docs/Authors.rst +++ b/docs/Authors.rst @@ -57,6 +57,7 @@ Hayati Ayguen hayguen Herwig Hochleitner bendlas Ian S kremlin- IndigoFenix +James Gilles kazimuth James Logsdon jlogsdon Japa JapaMala Jared Adams From a8d34bb64ec6ef6e09c611de7a8bbb14b322f0c3 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sun, 12 Jul 2020 00:30:28 -0400 Subject: [PATCH 174/547] Add explicit home link to sidebar --- conf.py | 2 +- docs/styles/dfhack.css | 2 +- docs/templates/about.html | 6 ++++++ 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 docs/templates/about.html diff --git a/conf.py b/conf.py index e70d836f1..a46039126 100644 --- a/conf.py +++ b/conf.py @@ -212,7 +212,7 @@ extlinks = { } # Add any paths that contain templates here, relative to this directory. -templates_path = [] +templates_path = ["docs/templates"] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: diff --git a/docs/styles/dfhack.css b/docs/styles/dfhack.css index 43063cee2..daedd1120 100644 --- a/docs/styles/dfhack.css +++ b/docs/styles/dfhack.css @@ -49,7 +49,7 @@ div.sphinxsidebar { overflow-y: auto; } -div.sphinxsidebar h3 > a { +div.sphinxsidebar h3.logo-name a { border-bottom: 1px dotted #999; } diff --git a/docs/templates/about.html b/docs/templates/about.html new file mode 100644 index 000000000..48f98859f --- /dev/null +++ b/docs/templates/about.html @@ -0,0 +1,6 @@ + + +

From 1d2b0bb3a522cfeb92c4695d7d4ef5a6a0e9c13b Mon Sep 17 00:00:00 2001 From: Tommy R Date: Mon, 13 Jul 2020 10:04:09 -0700 Subject: [PATCH 175/547] Fix the unquarantine behavior on OSX. - Using print0 but without the parenthesis, find only outputs one filename. - Also added the .framework files to the unquarantine list. --- package/darwin/dfhack | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/darwin/dfhack b/package/darwin/dfhack index 1c2c7a175..5241f1a67 100755 --- a/package/darwin/dfhack +++ b/package/darwin/dfhack @@ -13,7 +13,7 @@ fi # attempt to remove quarantine flag: https://github.com/DFHack/dfhack/issues/1465 if ! test -f hack/quarantine-removed; then - find hack/ libs/ dwarfort.exe -name '*.dylib' -or -name '*.exe' -print0 | xargs -0 xattr -d com.apple.quarantine 2>&1 | grep -iv 'no such xattr' + find hack/ libs/ dwarfort.exe \( -name '*.dylib' -or -name '*.framework' -or -name '*.exe' \) -print0 | xargs -0 xattr -d com.apple.quarantine 2>&1 | grep -iv 'no such xattr' echo "quarantine flag removed on $(date); remove this file to re-run" > hack/quarantine-removed fi From f33f9136c88031e59fbaee3105c8bac1250fe14c Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 13 Jul 2020 19:57:14 -0400 Subject: [PATCH 176/547] Update changelog + authors (#1606) --- docs/Authors.rst | 1 + docs/changelog.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/Authors.rst b/docs/Authors.rst index 3111b17f0..6701b67a0 100644 --- a/docs/Authors.rst +++ b/docs/Authors.rst @@ -161,6 +161,7 @@ Timothy Collett danaris Timur Kelman TymurGubayev Tom Jobbins TheBloke Tom Prince +Tommy R tommy TotallyGatsby TotallyGatsby Travis Hoppe thoppe orthographic-pedant txtsd txtsd diff --git a/docs/changelog.txt b/docs/changelog.txt index 7201bfd23..c6fbe840a 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 - Fixed a segfault when attempting to start a headless session with a graphical PRINT_MODE setting +- Fixed an issue with the macOS launcher failing to un-quarantine some files - `labormanager`: fixed handling of new jobs in 0.47 - Fixed ``Units::isEggLayer``, ``Units::isGrazer``, ``Units::isMilkable``, ``Units::isTrainableHunting``, ``Units::isTrainableWar``, and ``Units::isTamable`` ignoring the unit's caste From ced8f4a55164da36f7b1b7b458eb1f8c789f2e97 Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 13 Jul 2020 20:05:08 -0400 Subject: [PATCH 177/547] Update changelog (#1565) --- docs/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog.txt b/docs/changelog.txt index c6fbe840a..dfda78c0b 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: - Fixed an issue with the macOS launcher failing to un-quarantine some files - `labormanager`: fixed handling of new jobs in 0.47 - Fixed ``Units::isEggLayer``, ``Units::isGrazer``, ``Units::isMilkable``, ``Units::isTrainableHunting``, ``Units::isTrainableWar``, and ``Units::isTamable`` ignoring the unit's caste +- `RemoteFortressReader`: fixed a couple crashes that could result from decoding invalid enum items (``site_realization_building_type`` and ``improvement_type``) ## Misc Improvements - `confirm`: added a confirmation dialog for convicting dwarves of crimes From 89283026ae917883f84da7a16179f207390bc540 Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 13 Jul 2020 20:14:11 -0400 Subject: [PATCH 178/547] Improve changelog error handling a bit when called from sphinx --- docs/sphinx_extensions/dfhack/changelog.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/sphinx_extensions/dfhack/changelog.py b/docs/sphinx_extensions/dfhack/changelog.py index 99f0ea299..6f444d36f 100644 --- a/docs/sphinx_extensions/dfhack/changelog.py +++ b/docs/sphinx_extensions/dfhack/changelog.py @@ -4,6 +4,8 @@ import itertools import os import sys +from sphinx.errors import ExtensionError, SphinxError, SphinxWarning + from dfhack.util import DFHACK_ROOT, DOCS_ROOT CHANGELOG_PATHS = ( @@ -214,7 +216,7 @@ def generate_changelog(all=False): # scan for unrecognized sections for entry in entries: if entry.section not in CHANGELOG_SECTIONS: - raise RuntimeWarning('Unknown section: ' + entry.section) + raise SphinxWarning('Unknown section: ' + entry.section) # ordered versions versions = ['future'] @@ -287,7 +289,12 @@ def cli_entrypoint(): def sphinx_entrypoint(app, config): - generate_changelog() + try: + generate_changelog() + except SphinxError: + raise + except Exception as e: + raise ExtensionError(str(e), e) def setup(app): From df6f3a04557525e5780fb423bf68b4caca4c2316 Mon Sep 17 00:00:00 2001 From: lethosor Date: Tue, 14 Jul 2020 02:31:18 -0400 Subject: [PATCH 179/547] Mark ref_target as a metafield so meta_primitive_newindex fails properly unit:_field('hist_figure_id').ref_target = 4 now fails with "Cannot write field int32_t.ref_target: builtin property or method" instead of "not found" --- library/LuaTypes.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/LuaTypes.cpp b/library/LuaTypes.cpp index 7f0711b20..845d273e3 100644 --- a/library/LuaTypes.cpp +++ b/library/LuaTypes.cpp @@ -1316,6 +1316,8 @@ static void MakePrimitiveMetatable(lua_State *state, type_identity *type) { EnableMetaField(state, base+2, "value", type); AssociateId(state, base+3, 1, "value"); + + EnableMetaField(state, base+2, "ref_target", NULL); } // Add the iteration metamethods From 1f1bb5a055bbf121fbfe1a741200b7aeedac7cf1 Mon Sep 17 00:00:00 2001 From: lethosor Date: Tue, 14 Jul 2020 02:54:33 -0400 Subject: [PATCH 180/547] Update Lua API docs for ref_target field, add tests --- docs/Lua API.rst | 4 +++- test/main.lua | 13 +++++++++++++ test/structures/ref_target.lua | 35 ++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 test/structures/ref_target.lua diff --git a/docs/Lua API.rst b/docs/Lua API.rst index 4c7163623..2cfaff350 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -158,7 +158,9 @@ that don't fit any of the other reference types. Such references can only appear as a value of a pointer field, or as a result of calling the ``_field()`` method. -They behave as structs with one field ``value`` of the right type. +They behave as structs with a ``value`` field of the right type. If the +object's XML definition has a ``ref-target`` attribute, they will also have +a read-only ``ref_target`` field set to the corresponding type object. To make working with numeric buffers easier, they also allow numeric indices. Note that other than excluding negative values diff --git a/test/main.lua b/test/main.lua index 46a91e1ca..83a35d165 100644 --- a/test/main.lua +++ b/test/main.lua @@ -69,6 +69,19 @@ function expect.error(func, ...) return true end end +function expect.error_match(func, matcher, ...) + local ok, err = pcall(func, ...) + if ok then + return false, 'no error raised by function call' + elseif type(matcher) == 'string' then + if not tostring(err):match(matcher) then + return false, ('error "%s" did not match "%s"'):format(err, matcher) + end + elseif not matcher(err) then + return false, ('error "%s" did not satisfy matcher'):format(err) + end + return true +end function expect.pairs_contains(table, key, comment) for k, v in pairs(table) do if k == key then diff --git a/test/structures/ref_target.lua b/test/structures/ref_target.lua new file mode 100644 index 000000000..05818ee06 --- /dev/null +++ b/test/structures/ref_target.lua @@ -0,0 +1,35 @@ +function test.get() + dfhack.with_temp_object(df.unit:new(), function(unit) + expect.eq(unit:_field('hist_figure_id').ref_target, df.historical_figure) + end) +end + +function test.get_nil() + dfhack.with_temp_object(df.coord:new(), function(coord) + expect.nil_(coord:_field('x').ref_target) + end) +end + +function test.get_non_primitive() + dfhack.with_temp_object(df.unit:new(), function(unit) + expect.error_match(function() + return unit:_field('status').ref_target + end, 'not found') + end) +end + +function test.set() + dfhack.with_temp_object(df.unit:new(), function(unit) + expect.error_match(function() + unit:_field('hist_figure_id').ref_target = df.coord + end, 'builtin property or method') + end) +end + +function test.set_non_primitive() + dfhack.with_temp_object(df.unit:new(), function(unit) + expect.error_match(function() + unit:_field('status').ref_target = df.coord + end, 'not found') + end) +end From 9b922c19655c73bdbb79e40c0ded95b335da9413 Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 15 Jul 2020 00:05:36 -0400 Subject: [PATCH 181/547] Update scripts, changelog (#1543) --- docs/changelog.txt | 3 +++ scripts | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index dfda78c0b..9b935698e 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -43,6 +43,9 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## Misc Improvements - `confirm`: added a confirmation dialog for convicting dwarves of crimes +## Lua +- Added a ``ref_target`` field to primitive field references, corresponding to the ``ref-target`` XML attribute + ## Ruby - Updated ``item_find`` and ``building_find`` to use centralized logic that works on more screens diff --git a/scripts b/scripts index e8de92efb..7be22b0d0 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit e8de92efb73d5ef4d0b52df000d60d3350f07a37 +Subproject commit 7be22b0d0d133c6dbadf700126ddeb08b7aa0ac5 From e2334387a905f0dc5f75a25150a50605749b0225 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Wed, 15 Jul 2020 16:57:14 -0700 Subject: [PATCH 182/547] blueprint: write blueprints to blueprints/ subdir to enable writing to a subdir that may not exist, blueprint now automatically creates folder trees. E.g. ``blueprint 30 30 1 rooms/dining dig`` will create the file ``blueprints/rooms/dining-dig.csv``). Previously it would fail if the ``blueprints/rooms/`` directory didn't already exist. --- docs/Authors.rst | 1 + docs/changelog.txt | 2 + plugins/CMakeLists.txt | 3 +- plugins/blueprint.cpp | 87 ++++++++++++++++++++++++++++++------------ 4 files changed, 67 insertions(+), 26 deletions(-) diff --git a/docs/Authors.rst b/docs/Authors.rst index 6701b67a0..3c2777a7d 100644 --- a/docs/Authors.rst +++ b/docs/Authors.rst @@ -100,6 +100,7 @@ Milo Christiansen milochristiansen MithrilTuxedo MithrilTuxedo mizipzor mizipzor moversti moversti +Myk Taylor myk002 napagokc napagokc Neil Little nmlittle Nick Rart nickrart comestible diff --git a/docs/changelog.txt b/docs/changelog.txt index dfda78c0b..e43abd188 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -41,6 +41,8 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - `RemoteFortressReader`: fixed a couple crashes that could result from decoding invalid enum items (``site_realization_building_type`` and ``improvement_type``) ## Misc Improvements +- `blueprint`: now writes blueprints to the ``blueprints/`` subfolder instead of the df root folder +- `blueprint`: now automatically creates folder trees when organizing blueprints into subfolders (e.g. ``blueprint 30 30 1 rooms/dining dig`` will create the file ``blueprints/rooms/dining-dig.csv``); previously it would fail if the ``blueprints/rooms/`` directory didn't already exist - `confirm`: added a confirmation dialog for convicting dwarves of crimes ## Ruby diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 678b7eec2..3dc461ee9 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -93,7 +93,8 @@ if(BUILD_SUPPORTED) dfhack_plugin(automaterial automaterial.cpp) dfhack_plugin(automelt automelt.cpp) dfhack_plugin(autotrade autotrade.cpp) - dfhack_plugin(blueprint blueprint.cpp LINK_LIBRARIES lua) + # stdc++fs required for std::experimental::filesystem; once we move to c++17 this can be removed since it's in the STL there + dfhack_plugin(blueprint blueprint.cpp LINK_LIBRARIES lua stdc++fs) dfhack_plugin(burrows burrows.cpp LINK_LIBRARIES lua) dfhack_plugin(building-hacks building-hacks.cpp LINK_LIBRARIES lua) dfhack_plugin(buildingplan buildingplan.cpp LINK_LIBRARIES buildingplan-lib) diff --git a/plugins/blueprint.cpp b/plugins/blueprint.cpp index 9742b16e7..d7ce19334 100644 --- a/plugins/blueprint.cpp +++ b/plugins/blueprint.cpp @@ -3,6 +3,8 @@ //Translates a region of tiles specified by the cursor and arguments/prompts into a series of blueprint files suitable for digfort/buildingplan/quickfort #include +#include // This is just in c++17, but we're currently compiling with c++11 +#include #include #include @@ -33,6 +35,8 @@ using std::pair; using namespace DFHack; using namespace df::enums; +namespace filesystem = std::experimental::filesystem; + DFHACK_PLUGIN("blueprint"); enum phase {DIG=1, BUILD=2, PLACE=4, QUERY=8}; @@ -62,9 +66,10 @@ command_result help(color_ostream &out) << " defaults to generating all blueprints" << endl << endl << "blueprint translates a portion of your fortress into blueprints suitable for" << endl - << " digfort/fortplan/quickfort. Blueprints are created in the DF folder with names" << endl - << " following a \"name-phase.csv\" pattern. Translation starts at the current" << endl - << " cursor location and includes all tiles in the range specified." << endl; + << " digfort/fortplan/quickfort. Blueprints are created in the \"blueprints\"" << endl + << " subdirectory of the DF folder with names following a \"name-phase.csv\" pattern." << endl + << " Translation starts at the current cursor location and includes all tiles in the" << endl + << " range specified." << endl; return CR_OK; } @@ -557,32 +562,52 @@ string get_tile_query(df::building* b) return " "; } -command_result do_transform(DFCoord start, DFCoord end, string name, uint32_t phases) +void init_stream(ofstream &out, filesystem::path basename, std::string target) +{ + filesystem::path out_path(basename); + out_path += "-"; + out_path += target; + out_path += ".csv"; + out.open(out_path, ofstream::trunc); + out << "#" << target << endl; +} + +command_result do_transform(DFCoord start, DFCoord end, string name, uint32_t phases, std::ostringstream &err) { ofstream dig, build, place, query; + + filesystem::path basename = "blueprints"; + basename /= name; + basename.make_preferred(); + + // create output directory if it doesn't already exist + std::error_code ec; + if (!filesystem::create_directories(basename.parent_path(), ec) && ec) + { + err << "could not create output directory: " << basename.parent_path() + << " (" << ec.message() << ")"; + return CR_FAILURE; + } + if (phases & QUERY) { //query = ofstream((name + "-query.csv").c_str(), ofstream::trunc); - query.open(name+"-query.csv", ofstream::trunc); - query << "#query" << endl; + init_stream(query, basename, "query"); } if (phases & PLACE) { //place = ofstream(name + "-place.csv", ofstream::trunc); - place.open(name+"-place.csv", ofstream::trunc); - place << "#place" << endl; + init_stream(place, basename, "place"); } if (phases & BUILD) { //build = ofstream(name + "-build.csv", ofstream::trunc); - build.open(name+"-build.csv", ofstream::trunc); - build << "#build" << endl; + init_stream(build, basename, "build"); } if (phases & DIG) { //dig = ofstream(name + "-dig.csv", ofstream::trunc); - dig.open(name+"-dig.csv", ofstream::trunc); - dig << "#dig" << endl; + init_stream(dig, basename, "dig"); } if (start.x > end.x) { @@ -675,18 +700,27 @@ command_result blueprint(color_ostream &out, vector ¶meters) } DFCoord start (x, y, z); DFCoord end (x + stoi(parameters[0]), y + stoi(parameters[1]), z + stoi(parameters[2])); - if (parameters.size() == 4) - return do_transform(start, end, parameters[3], DIG | BUILD | PLACE | QUERY); uint32_t option = 0; - if (cmd_option_exists(parameters, "dig")) - option |= DIG; - if (cmd_option_exists(parameters, "build")) - option |= BUILD; - if (cmd_option_exists(parameters, "place")) - option |= PLACE; - if (cmd_option_exists(parameters, "query")) - option |= QUERY; - return do_transform(start, end, parameters[3], option); + if (parameters.size() == 4) + { + option = DIG | BUILD | PLACE | QUERY; + } + else + { + if (cmd_option_exists(parameters, "dig")) + option |= DIG; + if (cmd_option_exists(parameters, "build")) + option |= BUILD; + if (cmd_option_exists(parameters, "place")) + option |= PLACE; + if (cmd_option_exists(parameters, "query")) + option |= QUERY; + } + std::ostringstream err; + DFHack::command_result result = do_transform(start, end, parameters[3], option, err); + if (result != CR_OK) + out.printerr("%s\n", err.str().c_str()); + return result; } static int create(lua_State *L, uint32_t options) { @@ -701,9 +735,12 @@ static int create(lua_State *L, uint32_t options) { luaL_argerror(L, 2, "invalid end position"); string filename(lua_tostring(L, 3)); - lua_pushboolean(L, do_transform(start, end, filename, options)); + std::ostringstream err; + DFHack::command_result result = do_transform(start, end, filename, options, err); + if (result != CR_OK) + luaL_error(L, "%s", err.str().c_str()); + lua_pushboolean(L, result); return 1; - } static int dig(lua_State *L) { From b18847d9516d892bd7a08f3b96152295fa0a47b6 Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 15 Jul 2020 21:08:47 -0400 Subject: [PATCH 183/547] Update scripts --- scripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts b/scripts index 7be22b0d0..4881acf99 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 7be22b0d0d133c6dbadf700126ddeb08b7aa0ac5 +Subproject commit 4881acf99db08455bb1bc5472c301668d578f4db From bca76b8fc6b23c1ca13acbd50930d900a9641592 Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 15 Jul 2020 21:15:07 -0400 Subject: [PATCH 184/547] Remove excess/inconsistent padding from lists containing other lists --- docs/styles/dfhack.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/styles/dfhack.css b/docs/styles/dfhack.css index daedd1120..a25772871 100644 --- a/docs/styles/dfhack.css +++ b/docs/styles/dfhack.css @@ -56,3 +56,8 @@ div.sphinxsidebar h3.logo-name a { div.body { min-width: unset; } + +div.body li > p { + margin-top: 0; + margin-bottom: 0; +} From ef53cac05b270bd6d1cda39ce245cbe822d13b93 Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 15 Jul 2020 21:19:37 -0400 Subject: [PATCH 185/547] Improve chapter levels in the PDF build "Quick links" was "Chapter 1", and everything else was nested under Chapter 2. This changes e.g. "2.6.5 DFHack Lua API" to "6.5: DFHack Lua API" --- conf.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/conf.py b/conf.py index a46039126..d6c40b0a7 100644 --- a/conf.py +++ b/conf.py @@ -359,3 +359,5 @@ latex_documents = [ (master_doc, 'DFHack.tex', 'DFHack Documentation', 'The DFHack Team', 'manual'), ] + +latex_toplevel_sectioning = 'part' From 470456583c2b605f21e9be3c8b3fcc9e79dacab0 Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 15 Jul 2020 21:42:43 -0400 Subject: [PATCH 186/547] Document PDF build process and add a script for it --- .gitignore | 1 + docs/Documentation.rst | 17 +++++++++++++++-- docs/build-pdf.sh | 23 +++++++++++++++++++++++ docs/build.sh | 11 +++++++---- 4 files changed, 46 insertions(+), 6 deletions(-) create mode 100755 docs/build-pdf.sh diff --git a/.gitignore b/.gitignore index db4ed747c..9ff16b94c 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ build/VC2010 # Sphinx generated documentation docs/_* docs/html/ +docs/pdf/ # in-place build build/Makefile diff --git a/docs/Documentation.rst b/docs/Documentation.rst index 462932b0f..37fcc6ee6 100644 --- a/docs/Documentation.rst +++ b/docs/Documentation.rst @@ -236,9 +236,9 @@ Running Sphinx manually ----------------------- You can also build the documentation without going through CMake, which may be -faster. There is a ``docs/build.sh`` script available for Linux and macOS that +faster. There is a ``docs/build.sh`` script provided for Linux and macOS that will run essentially the same command that CMake runs - see the script for -options. +additional options. To build the documentation with default options, run the following command from the root DFHack folder:: @@ -248,6 +248,19 @@ the root DFHack folder:: Sphinx has many options to enable clean builds, parallel builds, logging, and more - run ``sphinx-build --help`` for details. +Building a PDF version +---------------------- + +ReadTheDocs automatically builds a PDF version of the documentation (available +under the "Downloads" section when clicking on the release selector). If you +want to build a PDF version locally, you will need ``pdflatex``, which is part +of a TeX distribution. The following command will then build a PDF, located in +``docs/pdf/latex/DFHack.pdf``, with default options:: + + sphinx-build -M latexpdf . ./docs/pdf + +There is a ``docs/build-pdf.sh`` script provided for Linux and macOS that runs +this command for convenience - see the script for additional options. .. _build-changelog: diff --git a/docs/build-pdf.sh b/docs/build-pdf.sh new file mode 100755 index 000000000..76908b49b --- /dev/null +++ b/docs/build-pdf.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +# usage: +# ./build-pdf.sh +# SPHINX=/path/to/sphinx-build ./build-pdf.sh +# JOBS=3 ./build-pdf.sh ... +# all command-line arguments are passed directly to sphinx-build - run +# ``sphinx-build --help`` for a list, or see +# https://www.sphinx-doc.org/en/master/man/sphinx-build.html + +cd $(dirname "$0") +cd .. + +sphinx=sphinx-build +if [ -n "$SPHINX" ]; then + sphinx=$SPHINX +fi + +if [ -z "$JOBS" ]; then + JOBS=2 +fi + +"$sphinx" -M latexpdf . ./docs/pdf -w ./docs/_sphinx-warnings.txt -j "$JOBS" "$@" diff --git a/docs/build.sh b/docs/build.sh index 48e1bfd4a..95a97e539 100755 --- a/docs/build.sh +++ b/docs/build.sh @@ -1,9 +1,12 @@ #!/bin/sh # usage: -# ./build.sh -# ./build.sh sphinx-executable -# JOBS=3 ./build.sh ... +# ./build.sh +# SPHINX=/path/to/sphinx-build ./build.sh +# JOBS=3 ./build.sh ... +# all command-line arguments are passed directly to sphinx-build - run +# ``sphinx-build --help`` for a list, or see +# https://www.sphinx-doc.org/en/master/man/sphinx-build.html cd $(dirname "$0") cd .. @@ -17,4 +20,4 @@ if [ -z "$JOBS" ]; then JOBS=2 fi -"$sphinx" -a -E -b html . ./docs/html -w ./docs/_sphinx-warnings.txt -j "$JOBS" "$@" +"$sphinx" -a -b html . ./docs/html -w ./docs/_sphinx-warnings.txt -j "$JOBS" "$@" From c19fc1f34903f15e915fa730af6d9ed53f5fc93c Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Wed, 15 Jul 2020 21:35:21 -0700 Subject: [PATCH 187/547] gcc-4.8 compatibility --- library/LuaApi.cpp | 1 + library/include/modules/Filesystem.h | 1 + library/modules/Filesystem.cpp | 31 ++++++++++++++++++++++++++++ plugins/CMakeLists.txt | 3 +-- plugins/blueprint.cpp | 31 ++++++++++++++-------------- 5 files changed, 50 insertions(+), 17 deletions(-) diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 1d127930e..b1dc3de0b 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -2365,6 +2365,7 @@ static const LuaWrapper::FunctionReg dfhack_filesystem_module[] = { WRAPM(Filesystem, getcwd), WRAPM(Filesystem, chdir), WRAPM(Filesystem, mkdir), + WRAPM(Filesystem, mkdir_recursive), WRAPM(Filesystem, rmdir), WRAPM(Filesystem, exists), WRAPM(Filesystem, isfile), diff --git a/library/include/modules/Filesystem.h b/library/include/modules/Filesystem.h index bc7a02337..bc0953d27 100644 --- a/library/include/modules/Filesystem.h +++ b/library/include/modules/Filesystem.h @@ -149,6 +149,7 @@ namespace DFHack { DFHACK_EXPORT bool chdir (std::string path); DFHACK_EXPORT std::string getcwd (); DFHACK_EXPORT bool mkdir (std::string path); + DFHACK_EXPORT bool mkdir_recursive (std::string path); DFHACK_EXPORT bool rmdir (std::string path); DFHACK_EXPORT bool stat (std::string path, STAT_STRUCT &info); DFHACK_EXPORT bool exists (std::string path); diff --git a/library/modules/Filesystem.cpp b/library/modules/Filesystem.cpp index 430e6351e..373b403c8 100644 --- a/library/modules/Filesystem.cpp +++ b/library/modules/Filesystem.cpp @@ -82,6 +82,37 @@ bool Filesystem::mkdir (std::string path) return fail == 0; } +static bool mkdir_recursive_impl (std::string path) +{ + size_t last_slash = path.find_last_of("/"); + if (last_slash != std::string::npos) + { + std::string parent_path = path.substr(0, last_slash); + bool parent_exists = mkdir_recursive_impl(parent_path); + if (!parent_exists) + { + return false; + } + } + return Filesystem::mkdir(path) || errno == EEXIST; +} + +bool Filesystem::mkdir_recursive (std::string path) +{ +#ifdef _WIN32 + // normalize to forward slashes + std::replace(path.begin(), path.end(), '\\', '/'); +#endif + + if (path.size() > PATH_MAX) + { + // path too long + return false; + } + + return mkdir_recursive_impl(path); +} + bool Filesystem::rmdir (std::string path) { int fail; diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 3dc461ee9..678b7eec2 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -93,8 +93,7 @@ if(BUILD_SUPPORTED) dfhack_plugin(automaterial automaterial.cpp) dfhack_plugin(automelt automelt.cpp) dfhack_plugin(autotrade autotrade.cpp) - # stdc++fs required for std::experimental::filesystem; once we move to c++17 this can be removed since it's in the STL there - dfhack_plugin(blueprint blueprint.cpp LINK_LIBRARIES lua stdc++fs) + dfhack_plugin(blueprint blueprint.cpp LINK_LIBRARIES lua) dfhack_plugin(burrows burrows.cpp LINK_LIBRARIES lua) dfhack_plugin(building-hacks building-hacks.cpp LINK_LIBRARIES lua) dfhack_plugin(buildingplan buildingplan.cpp LINK_LIBRARIES buildingplan-lib) diff --git a/plugins/blueprint.cpp b/plugins/blueprint.cpp index d7ce19334..4653b469c 100644 --- a/plugins/blueprint.cpp +++ b/plugins/blueprint.cpp @@ -3,7 +3,6 @@ //Translates a region of tiles specified by the cursor and arguments/prompts into a series of blueprint files suitable for digfort/buildingplan/quickfort #include -#include // This is just in c++17, but we're currently compiling with c++11 #include #include @@ -11,6 +10,7 @@ #include "LuaTools.h" #include "modules/Buildings.h" +#include "modules/Filesystem.h" #include "modules/Gui.h" #include "modules/MapCache.h" @@ -35,8 +35,6 @@ using std::pair; using namespace DFHack; using namespace df::enums; -namespace filesystem = std::experimental::filesystem; - DFHACK_PLUGIN("blueprint"); enum phase {DIG=1, BUILD=2, PLACE=4, QUERY=8}; @@ -562,13 +560,11 @@ string get_tile_query(df::building* b) return " "; } -void init_stream(ofstream &out, filesystem::path basename, std::string target) +void init_stream(ofstream &out, std::string basename, std::string target) { - filesystem::path out_path(basename); - out_path += "-"; - out_path += target; - out_path += ".csv"; - out.open(out_path, ofstream::trunc); + std::ostringstream out_path; + out_path << basename << "-" << target << ".csv"; + out.open(out_path.str(), ofstream::trunc); out << "#" << target << endl; } @@ -576,16 +572,21 @@ command_result do_transform(DFCoord start, DFCoord end, string name, uint32_t ph { ofstream dig, build, place, query; - filesystem::path basename = "blueprints"; - basename /= name; - basename.make_preferred(); + std::string basename = "blueprints/" + name; + +#ifdef _WIN32 + // normalize to forward slashes + std::replace(basename.begin(), basename.end(), '\\', '/'); +#endif + + size_t last_slash = basename.find_last_of("/"); + std::string parent_path = basename.substr(0, last_slash); // create output directory if it doesn't already exist std::error_code ec; - if (!filesystem::create_directories(basename.parent_path(), ec) && ec) + if (!Filesystem::mkdir_recursive(parent_path)) { - err << "could not create output directory: " << basename.parent_path() - << " (" << ec.message() << ")"; + err << "could not create output directory: '" << parent_path << "'"; return CR_FAILURE; } From 1ae341b637375432c94aa29cf828c41a47d0322c Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Wed, 15 Jul 2020 22:02:12 -0700 Subject: [PATCH 188/547] Check that we created a dir before we return true --- library/modules/Filesystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/modules/Filesystem.cpp b/library/modules/Filesystem.cpp index 373b403c8..87001f6dd 100644 --- a/library/modules/Filesystem.cpp +++ b/library/modules/Filesystem.cpp @@ -94,7 +94,7 @@ static bool mkdir_recursive_impl (std::string path) return false; } } - return Filesystem::mkdir(path) || errno == EEXIST; + return (Filesystem::mkdir(path) || errno == EEXIST) && Filesystem::isdir(path); } bool Filesystem::mkdir_recursive (std::string path) From c0d10b9e448d62a5abab4d0b7be648d911e7fc0a Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 16 Jul 2020 01:49:16 -0400 Subject: [PATCH 189/547] Update submodules --- library/xml | 2 +- scripts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/xml b/library/xml index b9028b0bb..2c21bf250 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit b9028b0bb9ad40d3ad4dc3f10934bb61aa16629b +Subproject commit 2c21bf2503751fae87cfd62e9608003b5f0dc1c5 diff --git a/scripts b/scripts index 4881acf99..af749e708 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 4881acf99db08455bb1bc5472c301668d578f4db +Subproject commit af749e7086739a058cd5095a6ee1a60d7e795a7c From bb1fcff410a5af6964fc5d7c3fb2f69dc2bccbcb Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Thu, 16 Jul 2020 08:33:23 -0700 Subject: [PATCH 190/547] use FILENAME_MAX instead of PATH_MAX for compat --- library/modules/Filesystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/modules/Filesystem.cpp b/library/modules/Filesystem.cpp index 87001f6dd..227bb57b6 100644 --- a/library/modules/Filesystem.cpp +++ b/library/modules/Filesystem.cpp @@ -104,7 +104,7 @@ bool Filesystem::mkdir_recursive (std::string path) std::replace(path.begin(), path.end(), '\\', '/'); #endif - if (path.size() > PATH_MAX) + if (path.size() > FILENAME_MAX) { // path too long return false; From 0afbe9d9319c6026025dbdf0ddf86e350699dfbb Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Thu, 16 Jul 2020 08:42:39 -0700 Subject: [PATCH 191/547] include algorithm on windows for std::replace --- library/modules/Filesystem.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/library/modules/Filesystem.cpp b/library/modules/Filesystem.cpp index 227bb57b6..ddc091525 100644 --- a/library/modules/Filesystem.cpp +++ b/library/modules/Filesystem.cpp @@ -45,6 +45,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include #include #include "modules/Filesystem.h" From 6cafd230c5f12a0bb4d0ad0dd4d56ea4b72a270a Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 16 Jul 2020 22:42:36 -0400 Subject: [PATCH 192/547] Link to bug from docs (#1585) --- docs/Plugins.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Plugins.rst b/docs/Plugins.rst index e3c9ec9c1..ee0aa074c 100644 --- a/docs/Plugins.rst +++ b/docs/Plugins.rst @@ -335,7 +335,7 @@ Subcommands that persist until disabled or DF quits: :stone-status-all: Adds an option to toggle the economic status of all stones :title-start-rename: Adds a safe rename option to the title screen "Start Playing" menu :tradereq-pet-gender: Displays pet genders on the trade request screen -:reaction-gloves: Fixes reactions to produce gloves in sets with correct handedness +:reaction-gloves: Fixes reactions to produce gloves in sets with correct handedness (:bug:`6273`) .. _fix-armory: From 56e43a0dde023c5a4595a22b29d800153b31e3c4 Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 16 Jul 2020 23:19:38 -0400 Subject: [PATCH 193/547] Linux: make Process::getPath (and dfhack.getDFPath()) not depend on cwd, for consistency with other platforms --- docs/changelog.txt | 1 + library/Process-linux.cpp | 31 ++++++++++++++++++++++++------- test/core.lua | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 7 deletions(-) create mode 100644 test/core.lua diff --git a/docs/changelog.txt b/docs/changelog.txt index 2bc506565..15a4383ca 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: ## Fixes - Fixed a segfault when attempting to start a headless session with a graphical PRINT_MODE setting - Fixed an issue with the macOS launcher failing to un-quarantine some files +- Linux: fixed ``dfhack.getDFPath()`` (Lua) and ``Process::getPath()`` (C++) to always return the DF root path, even if the working directory has changed - `labormanager`: fixed handling of new jobs in 0.47 - `embark-assistant`: fixed a couple of incursion handling bugs. - Fixed ``Units::isEggLayer``, ``Units::isGrazer``, ``Units::isMilkable``, ``Units::isTrainableHunting``, ``Units::isTrainableWar``, and ``Units::isTamable`` ignoring the unit's caste diff --git a/library/Process-linux.cpp b/library/Process-linux.cpp index a7f09a7f6..45e655948 100644 --- a/library/Process-linux.cpp +++ b/library/Process-linux.cpp @@ -23,11 +23,12 @@ distribution. */ #include "Internal.h" + #include #include -#include #include #include +#include #include #include @@ -180,12 +181,28 @@ uint32_t Process::getTickCount() string Process::getPath() { - const char * cwd_name = "/proc/self/cwd"; - char target_name[1024]; - int target_result; - target_result = readlink(cwd_name, target_name, sizeof(target_name)); - target_name[target_result] = '\0'; - return(string(target_name)); + static string cached_path; + if (cached_path.empty()) + { + const char *exe_name = "/proc/self/exe"; + char exe_path[1024]; + int length = readlink(exe_name, exe_path, sizeof(exe_path)); + if (length > 0) + { + exe_path[length] = '\0'; + string path_string = exe_path; + // DF lives in libs, so move up a folder + cached_path = path_string.substr(0, path_string.find_last_of("/", path_string.find_last_of("/") - 1)); + } + else + { + perror("readlink(/proc/self/exe) failed"); + fprintf(stderr, " length=%i\n", length); + cached_path = "."; + } + fprintf(stderr, "Resolved DF root to %s\n", cached_path.c_str()); + } + return cached_path; } int Process::getPID() diff --git a/test/core.lua b/test/core.lua new file mode 100644 index 000000000..6cde334d4 --- /dev/null +++ b/test/core.lua @@ -0,0 +1,34 @@ +local function clean_path(p) + -- todo: replace with dfhack.filesystem call? + return p:gsub('\\', '/'):gsub('//', '/'):gsub('/$', '') +end + +local fs = dfhack.filesystem +local old_cwd = clean_path(fs.getcwd()) +local function restore_cwd() + fs.chdir(old_cwd) +end + +function test.getDFPath() + expect.eq(clean_path(dfhack.getDFPath()), old_cwd) +end + +function test.getDFPath_chdir() + dfhack.with_finalize(restore_cwd, function() + fs.chdir('data') + expect.eq(clean_path(dfhack.getDFPath()), old_cwd) + expect.ne(clean_path(dfhack.getDFPath()), clean_path(fs.getcwd())) + end) +end + +function test.getHackPath() + expect.eq(clean_path(dfhack.getHackPath()), clean_path(dfhack.getDFPath() .. '/hack/')) +end + +function test.getHackPath_chdir() + dfhack.with_finalize(restore_cwd, function() + fs.chdir('hack') + expect.eq(clean_path(dfhack.getHackPath()), clean_path(old_cwd .. '/hack/')) + expect.eq(clean_path(dfhack.getHackPath()), clean_path(fs.getcwd())) + end) +end From c858f33f61b44a1ee08a4adc2feb14fdaf6036d6 Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 17 Jul 2020 00:00:57 -0400 Subject: [PATCH 194/547] reaction-gloves: fix warnings --- plugins/tweak/tweaks/reaction-gloves.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/tweak/tweaks/reaction-gloves.h b/plugins/tweak/tweaks/reaction-gloves.h index 82890239c..4f55f77b7 100644 --- a/plugins/tweak/tweaks/reaction-gloves.h +++ b/plugins/tweak/tweaks/reaction-gloves.h @@ -22,7 +22,7 @@ struct reaction_gloves_hook : df::reaction_product_itemst { // Examine creator unit's body plan, see how many hands it has // Count left hands and right hands, as well as "neutral" hands for compatibility int num_hands = 0, num_left = 0, num_right = 0; - for (int i = 0; i < unit->body.body_plan->body_parts.size(); i++) + for (size_t i = 0; i < unit->body.body_plan->body_parts.size(); i++) { df::body_part_raw *part = unit->body.body_plan->body_parts[i]; if (part->flags.is_set(df::body_part_raw_flags::GRASP)) @@ -57,7 +57,7 @@ struct reaction_gloves_hook : df::reaction_product_itemst { num_right *= quantity; // Iterate across the output gloves, set their handedness, then append them to the actual out_items list for DF - for (int i = 0; i < out_items_temp.size(); i++) + for (size_t i = 0; i < out_items_temp.size(); i++) { // Do left gloves first, then right gloves, then "neutral" ones last // This is important for the "createitem" plugin, which contains similar workaround logic @@ -76,4 +76,4 @@ struct reaction_gloves_hook : df::reaction_product_itemst { } }; -IMPLEMENT_VMETHOD_INTERPOSE(reaction_gloves_hook, produce); \ No newline at end of file +IMPLEMENT_VMETHOD_INTERPOSE(reaction_gloves_hook, produce); From 0cc6f40bd6bb936665edd4e8f6ca3fb507476796 Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 17 Jul 2020 17:35:09 -0400 Subject: [PATCH 195/547] Update API docs (#1607) --- docs/Lua API.rst | 5 +++++ docs/changelog.txt | 3 +++ 2 files changed, 8 insertions(+) diff --git a/docs/Lua API.rst b/docs/Lua API.rst index 2cfaff350..c62d0f379 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -2093,6 +2093,11 @@ unless otherwise noted. Creates a new directory. Returns ``false`` if unsuccessful, including if ``path`` already exists. +* ``dfhack.filesystem.mkdir_recursive(path)`` + + Creates a new directory, including any intermediate directories that don't exist yet. + Returns ``true`` if the folder was created or already existed, or ``false`` if unsuccessful. + * ``dfhack.filesystem.rmdir(path)`` Removes a directory. Only works if the directory is already empty. diff --git a/docs/changelog.txt b/docs/changelog.txt index 6db43ad64..9d03b1f0a 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -50,6 +50,9 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - `blueprint`: now automatically creates folder trees when organizing blueprints into subfolders (e.g. ``blueprint 30 30 1 rooms/dining dig`` will create the file ``blueprints/rooms/dining-dig.csv``); previously it would fail if the ``blueprints/rooms/`` directory didn't already exist - `confirm`: added a confirmation dialog for convicting dwarves of crimes +## API +- Added ``Filesystem::mkdir_recursive`` + ## Lua - Added a ``ref_target`` field to primitive field references, corresponding to the ``ref-target`` XML attribute From a0c514b117d939a53d4ed9f0cc0f7bca5b4437e1 Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 17 Jul 2020 17:35:33 -0400 Subject: [PATCH 196/547] Update xml --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index 2c21bf250..7822df15e 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 2c21bf2503751fae87cfd62e9608003b5f0dc1c5 +Subproject commit 7822df15ed44ca9e68d7270329ffd54dd7744977 From 128050c68435eb9633aac4af35070f57fd25e55c Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 18 Jul 2020 03:16:52 -0400 Subject: [PATCH 197/547] Move installation docs to a separate document and expand --- docs/Installing.rst | 132 ++++++++++++++++++++++++++++++++++++++++++ docs/Introduction.rst | 46 +++------------ index.rst | 1 + 3 files changed, 142 insertions(+), 37 deletions(-) create mode 100644 docs/Installing.rst diff --git a/docs/Installing.rst b/docs/Installing.rst new file mode 100644 index 000000000..92e5cfa0a --- /dev/null +++ b/docs/Installing.rst @@ -0,0 +1,132 @@ +.. _installing: + +================= +Installing DFHack +================= + +.. contents:: + :local: + + +Requirements +============ + +DFHack supports Windows, Linux, and macOS, and both 64-bit and 32-bit builds +of Dwarf Fortress. + +.. _installing-df-version: + +DFHack releases generally only support the version of Dwarf Fortress that they +are named after. For example, DFHack 0.40.24-r5 only supported DF 0.40.24. +DFHack releases *never* support newer versions of DF, because DFHack requires +data about DF that is only possible to obtain after DF has been released. +Occasionally, DFHack releases will be able to maintain support for older +versions of DF - for example, DFHack 0.34.11-r5 supported both DF 0.34.11 and +0.34.10. For maximum stability, you should usually use the latest versions of +both DF and DFHack. + +Windows +------- + +* DFHack only supports the SDL version of Dwarf Fortress. The "legacy" version + will *not* work with DFHack (the "small" SDL version is acceptable, however). +* Windows XP and older are *not* supported, due in part to a + `Visual C++ 2015 bug `_ + +The Windows build of DFHack should work under Wine on other operating systems, +although this is not tested very often. It is recommended to use the native +build for your operating system instead. + +.. _installing-reqs-linux: + +Linux +----- + +Generally, DFHack should work on any modern Linux distribution. There are +multiple release binaries provided - as of DFHack 0.47.04-r1, there are built +with GCC 7 and GCC 4.8 (as indicated by the ``gcc`` component of their +filenames). Using the newest build that works on your system is recommended. +The GCC 4.8 build is built on Ubuntu 14.04 and targets an older glibc, so it +should work on older distributions. + +In the event that none of the provided binaries work on your distribution, +you may need to `compile DFHack from source `. + +macOS +----- + +OS X 10.6.8 or later is required. + + +.. _downloading: + +Downloading DFHack +================== + +Stable builds of DFHack are available on `GitHub `_. +GitHub has been known to change their layout periodically, but as of July 2020, +downloads are available at the bottom of the release notes for each release, under a section +named "Assets" (which you may have to expand). The name of the file indicates +which DF version, platform, and architecture the build supports - the platform +and architecture (64-bit or 32-bit) **must** match your build of DF. The DF +version should also match your DF version - see `above ` +for details. For example: + +* ``dfhack-0.47.04-r1-Windows-64bit.zip`` supports 64-bit DF on Windows +* ``dfhack-0.47.04-r1-Linux-32bit-gcc-7.tar.bz2`` supports 32-bit DF on Linux + (see `installing-reqs-linux` for details on the GCC version indicator) + +The `DFHack website `_ also provides links to +unstable builds. These files have a different naming scheme, but the same +restrictions apply (e.g. a file named ``Windows64`` is for 64-bit Windows DF). + +.. warning:: + + Do *not* download the source code from GitHub, either from the releases page + or by clicking "Download ZIP" on the repo homepage. This will give you an + incomplete copy of the DFHack source code, which will not work as-is. (If + you want to compile DFHack instead of using a pre-built release, see + `compile` for instructions.) + +Installing DFHack +================= + +When you `download DFHack `, you will end up with a release archive +(a ``.zip`` file on Windows, or a ``.tar.bz2`` file on other platforms). Your +operating system should have built-in utilities capable of extracting files from +these archives. + +The release archives contain several files and folders, including a ``hack`` +folder, a ``dfhack-config`` folder, and a ``dfhack.init-example`` file. All +files from the DFHack archive need to be copied into the root DF folder, which +should already include a ``data`` folder and a ``raw`` folder, among other +things. Some packs and other redistributions of Dwarf Fortress may place DF in +another folder, so ensure that the ``hack`` folder ends up next to the ``data`` +folder. + +.. note:: + + On Windows, installing DFHack will overwrite ``SDL.dll``. This is + intentional and necessary for DFHack to work, so be sure to choose to + overwrite ``SDL.dll`` if prompted. (If you are not prompted, you may be + installing DFHack in the wrong place.) + + +Uninstalling DFHack +=================== + +Uninstalling DFHack essentially involves reversing what you did to install +DFHack. On Windows, replace ``SDL.dll`` with ``SDLreal.dll`` first. Then, you +can remove any files that were part of the DFHack archive. DFHack does not +currently maintain a list of these files, so if you want to completely remove +them, you should consult the DFHack archive that you installed for a full list. +Generally, any files left behind should not negatively affect DF. + +Pre-packaged DFHack installations +================================= + +There are :wiki:`several packs available ` that include +DF, DFHack, and other utilities. If you are new to Dwarf Fortress and DFHack, +these may be easier to set up. Note that these packs are not maintained by the +DFHack team and vary in their release schedules and contents. Some may make +significant configuration changes, and some may not include DFHack at all. diff --git a/docs/Introduction.rst b/docs/Introduction.rst index 4490086f3..7d510422f 100644 --- a/docs/Introduction.rst +++ b/docs/Introduction.rst @@ -35,47 +35,19 @@ allows easier development of new tools. As an open-source project under :local: -.. _installing: - -Installing DFHack -================= -DFHack is available for the SDL version of Dwarf Fortress on Windows, -any modern Linux distribution, and Mac OS X (10.6.8 and later). -It is possible to use Windows DF+DFHack under Wine on Linux or OS X. - -Most releases only support the version of DF mentioned in their title - for -example, DFHack 0.40.24-r2 only supports DF 0.40.24 - but some releases -support earlier DF versions as well. Wherever possible, use the latest version -of DFHack built for the target version of DF. - -Installing DFhack involves copying files from a release archive -into your DF folder, so that: - -* On Windows, ``SDL.dll`` is replaced -* On Linux or OS X, the ``dfhack`` script is placed in the same folder as the ``df`` script - -Uninstalling is basically the same, in reverse: - -* On Windows, replace ``SDL.dll`` with ``SDLreal.dll``, then remove the DFHack files. -* On Linux or OS X, remove the DFHack files. - -New players may wish to :wiki:`get a pack ` -with DFHack preinstalled. - - Getting started =============== -DFHack basically extends DF with something similar to the -console found in many PC games. +See `installing` for details on installing DFHack. -If DFHack is installed correctly, it will automatically pop up a console -window once DF is started as usual on Windows. Linux and Mac OS X require -running the dfhack script from the terminal, and will use that terminal for -the console. +Once DFHack is installed, it extends DF with a console that can be used to run +commands. On Windows, this console will open automatically when DF is started. +On Linux and macOS, you will need to run the ``dfhack`` script from a terminal +(instead of the ``df`` script included with DF), and that terminal will be +used by the DFHack console. -* Basic interaction with dfhack involves entering commands into the console. - To learn what commands are available, you can keep reading this documentation - or skip ahead and use the `ls` and `help` commands. +* Basic interaction with DFHack involves entering commands into the console. To + learn what commands are available, you can keep reading this documentation or + skip ahead and use the `ls` and `help` commands. * Another way to interact with DFHack is to set in-game `keybindings ` for certain commands. Many of the newer and user-friendly tools are designed diff --git a/index.rst b/index.rst index 91c883b51..d0e90b741 100644 --- a/index.rst +++ b/index.rst @@ -27,6 +27,7 @@ User Manual :maxdepth: 2 /docs/Introduction + /docs/Installing /docs/Core /docs/Plugins /docs/Scripts From 88dffd6474a0dffe57fedd69f13736a76a3b146e Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 18 Jul 2020 08:54:24 -0700 Subject: [PATCH 198/547] quickfort files and docs --- .gitignore | 1 + CMakeLists.txt | 1 + data/CMakeLists.txt | 2 + data/blueprints/README.txt | 14 +++ data/blueprints/library/square-dig.csv | 4 + data/quickfort/aliases-common.txt | 135 +++++++++++++++++++++++++ data/quickfort/materials-common.txt | 8 ++ dfhack-config/quickfort/aliases.txt | 30 ++++++ dfhack-config/quickfort/materials.txt | 9 ++ dfhack-config/quickfort/quickfort.txt | 20 ++++ 10 files changed, 224 insertions(+) create mode 100644 data/CMakeLists.txt create mode 100644 data/blueprints/README.txt create mode 100644 data/blueprints/library/square-dig.csv create mode 100644 data/quickfort/aliases-common.txt create mode 100644 data/quickfort/materials-common.txt create mode 100644 dfhack-config/quickfort/aliases.txt create mode 100644 dfhack-config/quickfort/materials.txt create mode 100644 dfhack-config/quickfort/quickfort.txt diff --git a/.gitignore b/.gitignore index 9ff16b94c..4b533ab20 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ build/Makefile build/CMakeCache.txt build/cmake_install.cmake build/CMakeFiles +build/data build/doc build/lua build/bin diff --git a/CMakeLists.txt b/CMakeLists.txt index de0c858af..44d6a02ce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -429,6 +429,7 @@ if(BUILD_PLUGINS) add_subdirectory(plugins) endif() +add_subdirectory(data) add_subdirectory(scripts) find_package(Sphinx QUIET) diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt new file mode 100644 index 000000000..19acb9261 --- /dev/null +++ b/data/CMakeLists.txt @@ -0,0 +1,2 @@ +install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/blueprints/ DESTINATION blueprints) +install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/quickfort/ DESTINATION "${DFHACK_DATA_DESTINATION}/data/quickfort") diff --git a/data/blueprints/README.txt b/data/blueprints/README.txt new file mode 100644 index 000000000..2096476c5 --- /dev/null +++ b/data/blueprints/README.txt @@ -0,0 +1,14 @@ +This directory is for quickfort blueprints. You can apply them to your fortress +map with the DFHack quickfort plugin. See +https://docs.dfhack.org/en/stable/docs/Scripts.html#quickfort for details. + +You can create blueprints by hand or by using any spreadsheet application, +saving them as .xlsx or .csv files. You can also build your plan "for real" in +Dwarf Fortress, and then export your map using the DFHack blueprint for later +replay in a different fort. See +https://docs.dfhack.org/en/stable/docs/Plugins.html#blueprint for more info. + +DFHack blueprints follow the original Quickfort 2.0 syntax. See +https://github.com/joelpt/quickfort for joelpt's excellent documentation. + +There are many ready-to-use examples of blueprints in the library subfolder. diff --git a/data/blueprints/library/square-dig.csv b/data/blueprints/library/square-dig.csv new file mode 100644 index 000000000..328710ddb --- /dev/null +++ b/data/blueprints/library/square-dig.csv @@ -0,0 +1,4 @@ +#dig start(2,2) +d,d,d +d, ,d +d,d,d diff --git a/data/quickfort/aliases-common.txt b/data/quickfort/aliases-common.txt new file mode 100644 index 000000000..b4e19c782 --- /dev/null +++ b/data/quickfort/aliases-common.txt @@ -0,0 +1,135 @@ +# quickfort aliases common baseline configuration file +# +# Defines custom keycode shortcuts for blueprints. Please DO NOT EDIT this file +# directly. Instead, custom aliases should be added to +# dfhack-config/quickfort/aliases.txt. +# +# Syntax: +# aliasname: keystrokes +# +# Special keys: +# {Right}, {Left}, {Up}, {Down}, >, < move the DF cursor +# {/}, {*}, {+}, {-} can be used to navigate some DF menus +# {Enter}, +{Enter}, {ExitMenu} - Enter, Shift+Enter, and Escape, respectively +# {Wait} pauses playback briefly +# +# Special keys can be repeated by adding a number inside the curly braces, for +# example: {Down 5} +# +# Some shorthand: +# & expands to {Enter} +# @ expands to +{Enter} +# ^ expands to {ExitMenu} +# % expands to {Wait} +# +# The aliases in this file were tested in DF 0.47.04 on 2020 Jul 18. + +################################## +# food stockpile adjustments +################################## + +seeds: s{Down}deb{Right}{Down 9}p^ +noseeds: s{Down}dea{Right}{Down 9}f^ +booze: s{Down}deb{Right}{Down 5}p{Down}p^ +food: s{Down}dea{Right}{Down 5}f{Down}f{Down 3}f^ +plants: s{Down}deb{Right}{Down 4}p^ + +################################## +# refuse stockpile adjustments +################################## + +corpses: s{Down 4}deb{Right 2}&{Down 2}&{Left}{Down}p{Down}p^ +bones: s{Down 4}deb{Right}{Down 3}p{Down}p^ +rawhides: s{Down 4}deb{Right 2}{Down}&^ +tannedhides: s{Down 4}deb{Right 2}{Down 53}&^ + +################################## +# stone stockpile adjustments +################################## + +metal: s{Down 5}deb{Right}p^ +nometal: s{Down 5}dea{Right}f^ +bauxite: s{Down 5}deb{Right}{Down 2}{Right}{Down 42}&^ + +# Only use nobauxite on stone piles that you want to accept all "Other Stone" on. +# This alias works by permitting all "Other Stone",then forbidding just bauxite. +# Thus you wouldn't want to use this on a metal-only pile, for example. +nobauxite: s{Down 5}{Right}{Down 2}p{Right}{Down 42}&^ + +################################## +# misc stockpile adjustments +################################## + +# Artifacts-only stockpile, usable on any type of existing pile. +artifacts: sd{Down}d{Down}d{Down}d{Down}d{Down}d{Down}d{Down}d{Down}d{Down}d{Down}d{Down}d{Down}d{Down}d{Down}d{Down}d{Down 4}deu{Right}{Up}f{Right}{Up}&{Left 2}{Down 4}e{Right}{Up}f{Right}{Up}&{Left 2}{Down 4}e{Right}{Up}f{Right}{Up}&{Left 2}{Down 4}e{Right}{Up}f{Right}{Up}&{Left 2}{Down}e{Right}{Up}f{Right}{Up}&{Left 2}^ + +# Bans artifacts on any pile (or rather, allows items of any quality except Artifact quality). +# This should be safe to run on any type of pile. +noartifacts: sd{Down 2}{Right}{Up}fp{Right}{Up}&{Down 2}{Left 2}{Down 4}{Right}{Up}fp{Right}{Up}&{Down 2}{Left 2}{Down 4}{Right}{Up}fp{Right}{Up}&{Down 2}{Left 2}{Down 4}{Right}{Up}fp{Right}{Up}&{Down 2}{Left 2}{Down}{Right}{Up}fp{Right}{Up}&{Down 2}{Left 2}^ + +# Set a finished goods stockpile to crappy low-quality trade goods only. +# Position such a stockpile near fort entrances to (hopefully) let thieves steal low quality junk. +junkgoods: s{Down 10}de{Right 2}&{Down 5}&{Down}&{Down}&{Down}&{Down 8}&{Down 2}&{Down}&{Down}&{Down}&{Down}&{Down}&{Left}{Down}f{Right}{Down}&{Down}&{Left}{Down}f{Down 2}f{Right}&{Down}&^ + +################################## +# farm plots +################################## + +# Sets a farm plot to grow the LAST type of seed in the list of available seeds, for all 4 seasons. +# The last seed is used because it's usually Plump helmet spawn, suitable for post-embark. If you +# only have 1 seed type, that'll be grown. +growlastcropall: a{/}&b{/}&c{/}&d{/}& + +# Like growlastcropall but grows the first one in the list instead. +growfirstcropall: a&b&c&d& + +################################## +# mining tracks +################################## + +# The following aliases make it more convenient to build the various types of mine tracks. +# For example, to build a north/south track 'Track (NS)', you would put trackNS in a cell(s). +trackN: CT{Enter} +trackS: CT{+ 1}{Enter} +trackE: CT{+ 2}{Enter} +trackW: CT{+ 3}{Enter} +trackNS: CT{+ 4}{Enter} +trackNE: CT{+ 5}{Enter} +trackNW: CT{+ 6}{Enter} +trackSE: CT{+ 7}{Enter} +trackSW: CT{+ 8}{Enter} +trackEW: CT{+ 9}{Enter} +trackNSE: CT{+ 10}{Enter} +trackNSW: CT{+ 11}{Enter} +trackNEW: CT{+ 12}{Enter} +trackSEW: CT{+ 13}{Enter} +trackNSEW: CT{+ 14}{Enter} +trackrampN: CT{+ 15}{Enter} +trackrampS: CT{+ 15}{+ 1}{Enter} +trackrampE: CT{+ 15}{+ 2}{Enter} +trackrampW: CT{+ 15}{+ 3}{Enter} +trackrampNS: CT{+ 15}{+ 4}{Enter} +trackrampNE: CT{+ 15}{+ 5}{Enter} +trackrampNW: CT{+ 15}{+ 6}{Enter} +trackrampSE: CT{+ 15}{+ 7}{Enter} +trackrampSW: CT{+ 15}{+ 8}{Enter} +trackrampEW: CT{+ 15}{+ 9}{Enter} +trackrampNSE: CT{+ 15}{+ 10}{Enter} +trackrampNSW: CT{+ 15}{+ 11}{Enter} +trackrampNEW: CT{+ 15}{+ 12}{Enter} +trackrampSEW: CT{+ 15}{+ 13}{Enter} +trackrampNSEW: CT{+ 15}{+ 14}{Enter} + +# Aliases for building track rollers; use e.g. rollerHqqq to make a low-speed horizontal roller +rollerH: Mrs +rollerV: Mr +rollerNS: Mr +rollerSN: Mrss +rollerEW: Mrs +rollerWE: Mrsss + +# Aliases for building track stops that dump in each of the four directions +trackstopN: CSd +trackstopS: CSdd +trackstopE: CSddd +trackstopW: CSdddd diff --git a/data/quickfort/materials-common.txt b/data/quickfort/materials-common.txt new file mode 100644 index 000000000..a9b388bdd --- /dev/null +++ b/data/quickfort/materials-common.txt @@ -0,0 +1,8 @@ +# quickfort materials preference configuration file +# +# Defines forbidden materials and material preferences for build blueprints. +# Please DO NOT EDIT this file directly. Instead, custom materials preferences +# should be added to dfhack-config/quickfort/materials.txt. +# +# Syntax TBD + diff --git a/dfhack-config/quickfort/aliases.txt b/dfhack-config/quickfort/aliases.txt new file mode 100644 index 000000000..52cdb2893 --- /dev/null +++ b/dfhack-config/quickfort/aliases.txt @@ -0,0 +1,30 @@ +# quickfort aliases configuration file +# +# Defines custom keycode shortcuts for blueprints. Definitions in this file take +# precedence over any definitions in the baseline aliases configuration file at +# hack/data/quickfort/aliases-common.txt. See that file for aliases that are +# already defined. +# +# This file can be used to simplify repetitive tasks, such as building minecart +# tracks or adjusting a food stockpile to accept seeds only. Making new aliases +# is just a matter of mimicking the keys used to navigate through the menus and +# select options. +# +# Syntax: +# aliasname: keystrokes +# +# Special keys: +# {Right}, {Left}, {Up}, {Down}, >, < move the DF cursor +# {/}, {*}, {+}, {-} can be used to navigate some DF menus +# {Enter}, +{Enter}, {ExitMenu} - Enter, Shift+Enter, and Escape, respectively +# {Wait} pauses playback briefly +# +# Special keys can be repeated by adding a number inside the curly braces, for +# example: {Down 5} +# +# Some shorthand: +# & expands to {Enter} +# @ expands to +{Enter} +# ^ expands to {ExitMenu} +# % expands to {Wait} + diff --git a/dfhack-config/quickfort/materials.txt b/dfhack-config/quickfort/materials.txt new file mode 100644 index 000000000..5938f16fe --- /dev/null +++ b/dfhack-config/quickfort/materials.txt @@ -0,0 +1,9 @@ +# quickfort materials preference configuration file +# +# Defines forbidden materials and material preferences for build blueprints. +# Settings in this file take precedence over any settings in the baseline +# materials configuration file at hack/data/quickfort/materials-common.txt. See +# that file to view the global defaults. +# +# Syntax TBD + diff --git a/dfhack-config/quickfort/quickfort.txt b/dfhack-config/quickfort/quickfort.txt new file mode 100644 index 000000000..bac02b631 --- /dev/null +++ b/dfhack-config/quickfort/quickfort.txt @@ -0,0 +1,20 @@ +# quickfort main configuration file +# +# Set startup defaults for the quickfort script in this file. Settings can be +# dynamically overridden in the active session with the `quickfort set` command. + +# Directory to search for blueprints. Can be set to an absolute or relative +# path. If set to a relative path, resolves to a directory under the DF folder. +blueprints-dir=blueprints + +# Set to "true" or "false". If true, will designate dig blueprints in marker +# mode. If false, only cells with dig codes prefixed with ``m`` will be +# designated in marker mode. +force-marker-mode=false + +# Allows you to manually select building materials for each +# building/construction when running (or creating orders for) build blueprints. +# Materials in selection dialogs are ordered according to preferences in +# materials.txt. If false, will only prompt for materials that have :labels. +# See https://github.com/joelpt/quickfort#manual-material-selection for details. +force-interactive-build=false From fb3269eee4d4683228ff469c06a629b982863086 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 18 Jul 2020 09:11:33 -0700 Subject: [PATCH 199/547] note that the baseline config is a baseline config --- data/quickfort/materials-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/quickfort/materials-common.txt b/data/quickfort/materials-common.txt index a9b388bdd..256d5deb8 100644 --- a/data/quickfort/materials-common.txt +++ b/data/quickfort/materials-common.txt @@ -1,4 +1,4 @@ -# quickfort materials preference configuration file +# quickfort materials common baseline configuration file # # Defines forbidden materials and material preferences for build blueprints. # Please DO NOT EDIT this file directly. Instead, custom materials preferences From 6921277e8104187d74d7a68be0f4df2b94ecc6ce Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 18 Jul 2020 12:35:04 -0400 Subject: [PATCH 200/547] Add upgrading instructions --- docs/Installing.rst | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/docs/Installing.rst b/docs/Installing.rst index 92e5cfa0a..c0175b820 100644 --- a/docs/Installing.rst +++ b/docs/Installing.rst @@ -97,12 +97,12 @@ operating system should have built-in utilities capable of extracting files from these archives. The release archives contain several files and folders, including a ``hack`` -folder, a ``dfhack-config`` folder, and a ``dfhack.init-example`` file. All -files from the DFHack archive need to be copied into the root DF folder, which -should already include a ``data`` folder and a ``raw`` folder, among other -things. Some packs and other redistributions of Dwarf Fortress may place DF in -another folder, so ensure that the ``hack`` folder ends up next to the ``data`` -folder. +folder, a ``dfhack-config`` folder, and a ``dfhack.init-example`` file. To +install DFHack, copy all of the files from the DFHack archive into the root DF +folder, which should already include a ``data`` folder and a ``raw`` folder, +among other things. Some packs and other redistributions of Dwarf Fortress may +place DF in another folder, so ensure that the ``hack`` folder ends up next to +the ``data`` folder. .. note:: @@ -122,6 +122,26 @@ currently maintain a list of these files, so if you want to completely remove them, you should consult the DFHack archive that you installed for a full list. Generally, any files left behind should not negatively affect DF. + +Upgrading DFHack +================ + +The recommended approach to upgrade DFHack is to uninstall DFHack first, then +install the new version. This will ensure that any files that are only part +of the older DFHack installation do not affect the new DFHack installation +(although this is unlikely to occur). + +It is also possible to overwrite an existing DFHack installation in-place. +To do this, follow the installation instructions above, but overwrite all files +that exist in the new DFHack archive (on Windows, this includes ``SDL.dll`` again). + +.. note:: + + You may wish to make a backup of your ``dfhack-config`` folder first if you + have made changes to it. Some archive managers (e.g. Archive Utility on macOS) + will overwrite the entire folder, removing any files that you have added. + + Pre-packaged DFHack installations ================================= From 044add214710434a6d0fddb30b48209d3ed0f017 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 18 Jul 2020 12:48:20 -0400 Subject: [PATCH 201/547] Reorder .proto comments --- plugins/proto/AdventureControl.proto | 2 +- plugins/proto/DwarfControl.proto | 2 +- plugins/proto/ItemdefInstrument.proto | 2 +- plugins/proto/RemoteFortressReader.proto | 2 +- plugins/proto/isoworldremote.proto | 2 +- plugins/proto/ui_sidebar_mode.proto | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/proto/AdventureControl.proto b/plugins/proto/AdventureControl.proto index 0bbcc8da8..840576c2b 100644 --- a/plugins/proto/AdventureControl.proto +++ b/plugins/proto/AdventureControl.proto @@ -1,6 +1,6 @@ +//Attempts to provide a complete framework for reading everything from a fortress needed for vizualization package AdventureControl; -//Attempts to provide a complete framework for reading everything from a fortress needed for vizualization option optimize_for = LITE_RUNTIME; import "RemoteFortressReader.proto"; diff --git a/plugins/proto/DwarfControl.proto b/plugins/proto/DwarfControl.proto index 9bd63b8d3..ee750f8bc 100644 --- a/plugins/proto/DwarfControl.proto +++ b/plugins/proto/DwarfControl.proto @@ -1,7 +1,7 @@ +//Attempts to provide a complete framework for reading everything from a fortress needed for vizualization syntax = "proto2"; package DwarfControl; -//Attempts to provide a complete framework for reading everything from a fortress needed for vizualization option optimize_for = LITE_RUNTIME; // Plugin: RemoteFortressReader diff --git a/plugins/proto/ItemdefInstrument.proto b/plugins/proto/ItemdefInstrument.proto index 02d4c7a90..0b64eb6d1 100644 --- a/plugins/proto/ItemdefInstrument.proto +++ b/plugins/proto/ItemdefInstrument.proto @@ -1,6 +1,6 @@ +//Attempts to provide a complete framework for reading everything from a fortress needed for vizualization package ItemdefInstrument; -//Attempts to provide a complete framework for reading everything from a fortress needed for vizualization option optimize_for = LITE_RUNTIME; // Plugin: RemoteFortressReader diff --git a/plugins/proto/RemoteFortressReader.proto b/plugins/proto/RemoteFortressReader.proto index 8255f91cd..a128a162f 100644 --- a/plugins/proto/RemoteFortressReader.proto +++ b/plugins/proto/RemoteFortressReader.proto @@ -1,6 +1,6 @@ +//Attempts to provide a complete framework for reading everything from a fortress needed for vizualization package RemoteFortressReader; -//Attempts to provide a complete framework for reading everything from a fortress needed for vizualization option optimize_for = LITE_RUNTIME; // Plugin: RemoteFortressReader diff --git a/plugins/proto/isoworldremote.proto b/plugins/proto/isoworldremote.proto index 23abdab73..c972e98a8 100644 --- a/plugins/proto/isoworldremote.proto +++ b/plugins/proto/isoworldremote.proto @@ -1,6 +1,6 @@ +//Describes a very basic material structure for the map embark package isoworldremote; -//Describes a very basic material structure for the map embark option optimize_for = LITE_RUNTIME; // Plugin: isoworldremote diff --git a/plugins/proto/ui_sidebar_mode.proto b/plugins/proto/ui_sidebar_mode.proto index b07bb1baa..af9dbabd7 100644 --- a/plugins/proto/ui_sidebar_mode.proto +++ b/plugins/proto/ui_sidebar_mode.proto @@ -1,6 +1,6 @@ +//Attempts to provide a complete framework for reading everything from a fortress needed for vizualization package proto.enums.ui_sidebar_mode; -//Attempts to provide a complete framework for reading everything from a fortress needed for vizualization option optimize_for = LITE_RUNTIME; enum ui_sidebar_mode @@ -60,4 +60,4 @@ enum ui_sidebar_mode Hauling = 52; ArenaWeather = 53; ArenaTrees = 54; -} \ No newline at end of file +} From 2026c2b0c3dfc49f9bd01cf0eecef9d054c6d953 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 18 Jul 2020 20:04:22 -0700 Subject: [PATCH 202/547] change settings names to use underscored since dash makes them invalid lua identifiers --- dfhack-config/quickfort/quickfort.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dfhack-config/quickfort/quickfort.txt b/dfhack-config/quickfort/quickfort.txt index bac02b631..683c1da7d 100644 --- a/dfhack-config/quickfort/quickfort.txt +++ b/dfhack-config/quickfort/quickfort.txt @@ -5,16 +5,16 @@ # Directory to search for blueprints. Can be set to an absolute or relative # path. If set to a relative path, resolves to a directory under the DF folder. -blueprints-dir=blueprints +blueprints_dir=blueprints # Set to "true" or "false". If true, will designate dig blueprints in marker # mode. If false, only cells with dig codes prefixed with ``m`` will be # designated in marker mode. -force-marker-mode=false +force_marker_mode=false # Allows you to manually select building materials for each # building/construction when running (or creating orders for) build blueprints. # Materials in selection dialogs are ordered according to preferences in # materials.txt. If false, will only prompt for materials that have :labels. # See https://github.com/joelpt/quickfort#manual-material-selection for details. -force-interactive-build=false +force_interactive_build=false From 1e734938ae01f31acfbc8d2d235e54f432ef7fa1 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sun, 19 Jul 2020 01:00:00 -0400 Subject: [PATCH 203/547] Add isoworldremote to Plugins.rst --- docs/Plugins.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/Plugins.rst b/docs/Plugins.rst index ee0aa074c..7c37ea78c 100644 --- a/docs/Plugins.rst +++ b/docs/Plugins.rst @@ -59,6 +59,11 @@ remotefortressreader An in-development plugin for realtime fortress visualisation. See :forums:`Armok Vision <146473>`. +.. _isoworldremote: + +isoworldremote +============== +A plugin that implements a `remote API ` used by Isoworld. .. _cursecheck: From d88137b1d653f2efcd7407af10e3bd4907d7b86a Mon Sep 17 00:00:00 2001 From: lethosor Date: Sun, 19 Jul 2020 01:13:43 -0400 Subject: [PATCH 204/547] Split remote API info into separate doc, add example tools and clients --- docs/Dev-intro.rst | 9 ++------- docs/Remote.rst | 47 ++++++++++++++++++++++++++++++++++++++++++++++ docs/index-dev.rst | 1 + 3 files changed, 50 insertions(+), 7 deletions(-) create mode 100644 docs/Remote.rst diff --git a/docs/Dev-intro.rst b/docs/Dev-intro.rst index 9a08533c0..2a17313fe 100644 --- a/docs/Dev-intro.rst +++ b/docs/Dev-intro.rst @@ -77,11 +77,6 @@ some functions (and some entire modules) are currently only available in C++. Remote access interface ----------------------- -DFHack supports remote access by exchanging Google protobuf messages via a TCP -socket. Both the core and plugins can define remotely accessible methods. The -``dfhack-run`` command uses this interface to invoke ordinary console commands. - -Currently the supported set of requests is limited, because the developers don't -know what exactly is most useful. `remotefortressreader` provides a fairly -comprehensive interface for visualisers such as :forums:`Armok Vision <146473>`. +DFHack provides a remote access interface that external tools can connect to and +use to interact with DF. See `remote` for more information. diff --git a/docs/Remote.rst b/docs/Remote.rst new file mode 100644 index 000000000..b7c65b032 --- /dev/null +++ b/docs/Remote.rst @@ -0,0 +1,47 @@ +.. _remote: + +======================= +DFHack Remote Interface +======================= + +DFHack provides a remote access interface that external tools can connect to and +use to interact with DF. This is implemented with `Google protobuf`_ messages +exchanged over a TCP socket (which only accepts connections from the local +machine by default). Both the core and plugins can define remotely-accessible +methods (often referred to as **RPC methods**). The RPC methods currently +available are not comprehensive, but can be extended with plugins. + +.. _Google protobuf: https://developers.google.com/protocol-buffers + +.. contents:: + :local: + +Examples +======== + +The `dfhack-run` command uses the RPC interface to invoke DFHack commands +(or Lua functions) externally. + +Plugins that implement RPC methods include: + +- `rename` +- `remotefortressreader` +- `isoworldremote` + +Plugins that use the RPC API include: + +- `stonesense` + +Third-party tools that use the RPC API include: + +- `Armok Vision `_ (:forums:`Bay12 forums thread <146473>`) + +Client libraries +================ + +Some external libraries are available for interacting with the remote interface +from other (non-C++) languages, including: + +- `RemoteClientDF-Net `_ for C# +- `dfhackrpc `_ for Go +- `dfhack-remote `_ for JavaScript diff --git a/docs/index-dev.rst b/docs/index-dev.rst index 617c0c0d7..560137609 100644 --- a/docs/index-dev.rst +++ b/docs/index-dev.rst @@ -15,5 +15,6 @@ These are pages relevant to people developing for DFHack. /docs/Documentation /docs/Structures-intro /docs/Memory-research + /docs/Remote /docs/Binpatches From 16cfd34678a874b6cc2aa6ec9fdb251872d2f0d3 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 18 Jul 2020 22:22:37 -0700 Subject: [PATCH 205/547] recurs-ify default config copying logic I refactored Filesystem::listdir_recursive to support removing the path prefix from the returned files list. There are no current calls that make use of the prefix parameter, so I converted it into a boolean. Current usages will use the new default parameter and will not see any changed behavior. --- data/blueprints/library/square-dig.csv | 2 +- library/Core.cpp | 29 ++++++++++++++++---- library/include/modules/Filesystem.h | 2 +- library/modules/Filesystem.cpp | 38 +++++++++++++++++--------- 4 files changed, 50 insertions(+), 21 deletions(-) diff --git a/data/blueprints/library/square-dig.csv b/data/blueprints/library/square-dig.csv index 328710ddb..548c5c3f2 100644 --- a/data/blueprints/library/square-dig.csv +++ b/data/blueprints/library/square-dig.csv @@ -1,4 +1,4 @@ -#dig start(2,2) +#dig start(2;2) This is a library placeholder for use during quickfort development d,d,d d, ,d d,d,d diff --git a/library/Core.cpp b/library/Core.cpp index a9fe9a69a..20d9c994b 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -1737,18 +1737,35 @@ bool Core::Init() virtual_identity::Init(this); // copy over default config files if necessary - std::vector config_files; - std::vector default_config_files; - if (Filesystem::listdir("dfhack-config", config_files) != 0) + std::map config_files; + std::map default_config_files; + if (Filesystem::listdir_recursive("dfhack-config", config_files, 10, false) != 0) con.printerr("Failed to list directory: dfhack-config"); - else if (Filesystem::listdir("dfhack-config/default", default_config_files) != 0) + else if (Filesystem::listdir_recursive("dfhack-config/default", default_config_files, 10, false) != 0) con.printerr("Failed to list directory: dfhack-config/default"); else { + // ensure all config file directories exist before we start copying files for (auto it = default_config_files.begin(); it != default_config_files.end(); ++it) { - std::string filename = *it; - if (std::find(config_files.begin(), config_files.end(), filename) == config_files.end()) + // skip over files + if (!it->second) + continue; + std::string dirname = "dfhack-config/" + it->first; + if (!Filesystem::mkdir_recursive(dirname)) + { + con.printerr("Failed to create config directory: '%s'\n", dirname.c_str()); + } + } + + // copy files from the default tree that don't already exist in the config tree + for (auto it = default_config_files.begin(); it != default_config_files.end(); ++it) + { + // skip over directories + if (it->second) + continue; + std::string filename = it->first; + if (config_files.find(filename) == config_files.end()) { std::string src_file = std::string("dfhack-config/default/") + filename; if (!Filesystem::isfile(src_file)) diff --git a/library/include/modules/Filesystem.h b/library/include/modules/Filesystem.h index bc0953d27..3252be007 100644 --- a/library/include/modules/Filesystem.h +++ b/library/include/modules/Filesystem.h @@ -161,6 +161,6 @@ namespace DFHack { DFHACK_EXPORT int64_t mtime (std::string path); DFHACK_EXPORT int listdir (std::string dir, std::vector &files); DFHACK_EXPORT int listdir_recursive (std::string dir, std::map &files, - int depth = 10, std::string prefix = ""); + int depth = 10, bool include_prefix = true); } } diff --git a/library/modules/Filesystem.cpp b/library/modules/Filesystem.cpp index ddc091525..c0d0860ad 100644 --- a/library/modules/Filesystem.cpp +++ b/library/modules/Filesystem.cpp @@ -205,34 +205,46 @@ int Filesystem::listdir (std::string dir, std::vector &files) return 0; } -int Filesystem::listdir_recursive (std::string dir, std::map &files, - int depth /* = 10 */, std::string prefix /* = "" */) +// prefix is the top-level dir where we started recursing +// path is the relative path under the prefix; must be empty or end in a '/' +// files is the output list of files and directories (bool == true for dir) +// depth is the remaining dir depth to recurse into. function returns -1 if +// we haven't finished recursing when we run out of depth. +// include_prefix controls whether the directory where we started recursing is +// included in the filenames returned in files. +static int listdir_recursive_impl (std::string prefix, std::string path, + std::map &files, int depth, bool include_prefix) { - int err; if (depth < 0) return -1; - if (prefix == "") - prefix = dir; - std::vector tmp; - err = listdir(dir, tmp); + std::string prefixed_path = prefix + "/" + path; + std::vector curdir_files; + int err = Filesystem::listdir(prefixed_path, curdir_files); if (err) return err; - for (auto file = tmp.begin(); file != tmp.end(); ++file) + for (auto file = curdir_files.begin(); file != curdir_files.end(); ++file) { if (*file == "." || *file == "..") continue; - std::string rel_path = prefix + "/" + *file; - if (isdir(rel_path)) + std::string prefixed_file = prefixed_path + *file; + std::string path_file = path + *file; + if (Filesystem::isdir(prefixed_file)) { - files.insert(std::pair(rel_path, true)); - err = listdir_recursive(dir + "/" + *file, files, depth - 1, rel_path); + files.insert(std::pair(include_prefix ? prefixed_file : path_file, true)); + err = listdir_recursive_impl(prefix, path_file + "/", files, depth - 1, include_prefix); if (err) return err; } else { - files.insert(std::pair(rel_path, false)); + files.insert(std::pair(include_prefix ? prefixed_file : path_file, false)); } } return 0; } + +int Filesystem::listdir_recursive (std::string dir, std::map &files, + int depth /* = 10 */, bool include_prefix /* = true */) +{ + return listdir_recursive_impl(dir, "", files, depth, include_prefix); +} From d0f8ba06a25ed63bc66f9e0fb02440039d20d0cf Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sun, 19 Jul 2020 01:52:57 -0700 Subject: [PATCH 206/547] expose new include_prefix param to Lua --- library/LuaApi.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index b1dc3de0b..c20be4618 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -2406,8 +2406,11 @@ static int filesystem_listdir_recursive(lua_State *L) int depth = 10; if (lua_type(L, 2) == LUA_TNUMBER) depth = lua_tounsigned(L, 2); + bool include_prefix = true; + if (lua_type(L, 3) == LUA_TBOOLEAN) + include_prefix = lua_toboolean(L, 3); std::map files; - int err = DFHack::Filesystem::listdir_recursive(dir, files, depth); + int err = DFHack::Filesystem::listdir_recursive(dir, files, depth, include_prefix); if (err) { lua_pushnil(L); From 6a851537d5ef022447525718fec21038f9c5efe4 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sun, 19 Jul 2020 17:29:56 -0700 Subject: [PATCH 207/547] update changelog --- docs/changelog.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index 9d03b1f0a..5f3510ed9 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -51,7 +51,8 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - `confirm`: added a confirmation dialog for convicting dwarves of crimes ## API -- Added ``Filesystem::mkdir_recursive`` +- Added ``Filesystem::mkdir_recursive`` (returns true if directories to create already exist) +- Extended ``Filesystem::listdir_recursive`` to optionally make returned filenames relative to the start directory ## Lua - Added a ``ref_target`` field to primitive field references, corresponding to the ``ref-target`` XML attribute From b2002199670ce2c2d0f3d55af603ee54190b9d67 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Mon, 20 Jul 2020 23:04:23 -0700 Subject: [PATCH 208/547] support for splitting lua scripts into parts without polluting the output of #DFHack ls --- docs/changelog.txt | 1 + library/Core.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index 5f3510ed9..c949115f1 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -56,6 +56,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## Lua - Added a ``ref_target`` field to primitive field references, corresponding to the ``ref-target`` XML attribute +- Support for splitting scripts into multiple files without polluting the output of '#DFHack ls'. Scripts that end in '-internal.lua' will not be listed, but but they can still be 'require'd from other scripts. ## Ruby - Updated ``item_find`` and ``building_find`` to use centralized logic that works on more screens diff --git a/library/Core.cpp b/library/Core.cpp index 20d9c994b..9192d5772 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -301,7 +301,7 @@ static void listScripts(PluginManager *plug_mgr, std::map &pset, path += '/'; for (size_t i = 0; i < files.size(); i++) { - if (hasEnding(files[i], ".lua")) + if (hasEnding(files[i], ".lua") && !hasEnding(files[i], "-internal.lua")) { string help = getScriptHelp(path + files[i], "--"); string key = prefix + files[i].substr(0, files[i].size()-4); From b34aa86d3c3dd606c22877d9cf95d25204e5d567 Mon Sep 17 00:00:00 2001 From: lethosor Date: Tue, 21 Jul 2020 21:39:37 -0400 Subject: [PATCH 209/547] Document remote server config --- docs/Core.rst | 3 +++ docs/Remote.rst | 25 ++++++++++++++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/docs/Core.rst b/docs/Core.rst index 6ef1d0575..196b12918 100644 --- a/docs/Core.rst +++ b/docs/Core.rst @@ -442,6 +442,8 @@ Other init files directory, will be run when any world or that save is loaded. +.. _env-vars: + Environment variables ===================== @@ -453,6 +455,7 @@ on UNIX-like systems:: - ``DFHACK_PORT``: the port to use for the RPC server (used by ``dfhack-run`` and `remotefortressreader` among others) instead of the default ``5000``. As with the default, if this port cannot be used, the server is not started. + See `remote` for more details. - ``DFHACK_DISABLE_CONSOLE``: if set, the DFHack console is not set up. This is the default behavior if ``PRINT_MODE:TEXT`` is set in ``data/init/init.txt``. diff --git a/docs/Remote.rst b/docs/Remote.rst index b7c65b032..5fa556ef2 100644 --- a/docs/Remote.rst +++ b/docs/Remote.rst @@ -6,9 +6,8 @@ DFHack Remote Interface DFHack provides a remote access interface that external tools can connect to and use to interact with DF. This is implemented with `Google protobuf`_ messages -exchanged over a TCP socket (which only accepts connections from the local -machine by default). Both the core and plugins can define remotely-accessible -methods (often referred to as **RPC methods**). The RPC methods currently +exchanged over a TCP socket. Both the core and plugins can define +remotely-accessible methods, or **RPC methods**. The RPC methods currently available are not comprehensive, but can be extended with plugins. .. _Google protobuf: https://developers.google.com/protocol-buffers @@ -16,6 +15,26 @@ available are not comprehensive, but can be extended with plugins. .. contents:: :local: + +Server configuration +==================== + +DFHack attempts to start a TCP server to listen for remote connections on +startup. If this fails (due to the port being in use, for example), an error +message will be logged to stderr.log. + +The server can be configured by setting options in ``dfhack-config/remote-server.json``: + +- ``allow_remote`` (default: ``false``): if true, allows connections from hosts + other than the local machine. This is insecure and may allow arbitrary code + execution on your machine, so it is disabled by default. +- ``port`` (default: ``5000``): the port that the remote server listens on. + Overriding this will allow the server to work if you have multiple instances + of DF running, or if you have something else running on port 5000. Note that + the ``DFHACK_PORT`` `environment variable ` takes precedence over + this setting and may be more useful for overriding the port temporarily. + + Examples ======== From dfc9f78fa4f2deeb576a7c334b8a75f69dfe01f4 Mon Sep 17 00:00:00 2001 From: lethosor Date: Tue, 21 Jul 2020 23:14:59 -0400 Subject: [PATCH 210/547] Refer to server config docs from dfhack-run --- docs/Core.rst | 10 +++++++++- docs/Remote.rst | 2 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/Core.rst b/docs/Core.rst index 196b12918..c5d5670af 100644 --- a/docs/Core.rst +++ b/docs/Core.rst @@ -82,7 +82,7 @@ dfhack-run If DF and DFHack are already running, calling ``dfhack-run my command`` in an external terminal is equivalent to calling ``my command`` in the -DFHack console. Direct use of the DFhack console is generally easier, +DFHack console. Direct use of the DFHack console is generally easier, but ``dfhack-run`` can be useful in a variety of circumstances: - if the console is unavailable @@ -101,6 +101,14 @@ Examples:: The first (\*nix) example `checks for vampires `; the second (Windows) example uses `kill-lua` to stop a Lua script. +.. note:: + + ``dfhack-run`` attempts to connect to a server on TCP port 5000. If DFHack + was unable to start this server, ``dfhack-run`` will not be able to connect. + This could happen if you have other software listening on port 5000, or if + you have multiple copies of DF running simultaneously. To assign a different + port, see `remote-server-config`. + Built-in Commands ================= diff --git a/docs/Remote.rst b/docs/Remote.rst index 5fa556ef2..24426c819 100644 --- a/docs/Remote.rst +++ b/docs/Remote.rst @@ -16,6 +16,8 @@ available are not comprehensive, but can be extended with plugins. :local: +.. _remote-server-config: + Server configuration ==================== From 4b6325eeabd6311ed30c38199f1e4111df519c19 Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 22 Jul 2020 01:34:51 -0400 Subject: [PATCH 211/547] Add RPC protocol description to docs and reformat From https://gist.github.com/BenLubar/1f51cf570b4c8dca275db9687fa6b9e3 Ref dfhack/dfhack#1574 --- docs/Remote.rst | 166 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 164 insertions(+), 2 deletions(-) diff --git a/docs/Remote.rst b/docs/Remote.rst index 24426c819..689f9978b 100644 --- a/docs/Remote.rst +++ b/docs/Remote.rst @@ -37,8 +37,16 @@ The server can be configured by setting options in ``dfhack-config/remote-server this setting and may be more useful for overriding the port temporarily. +Developing with the remote API +============================== + +At a high level, the core and plugins define RPC methods, and external clients +can call these methods. Each method is assigned an ID internally, which clients +use to call it. These method IDs can be obtained using the special ``BindMethod`` +method, which has an ID of 0. + Examples -======== +-------- The `dfhack-run` command uses the RPC interface to invoke DFHack commands (or Lua functions) externally. @@ -58,7 +66,7 @@ Third-party tools that use the RPC API include: - `Armok Vision `_ (:forums:`Bay12 forums thread <146473>`) Client libraries -================ +---------------- Some external libraries are available for interacting with the remote interface from other (non-C++) languages, including: @@ -66,3 +74,157 @@ from other (non-C++) languages, including: - `RemoteClientDF-Net `_ for C# - `dfhackrpc `_ for Go - `dfhack-remote `_ for JavaScript + + +Protocol description +==================== + +This is a low-level description of the RPC protocol, which may be useful when +developing custom clients. + +Built-in messages +----------------- +These messages have hardcoded IDs; all others must be obtained through ``BindMethod``. + +=== ============ =============================== ======================= +ID Method Input Output +=== ============ =============================== ======================= + 0 BindMethod dfproto.CoreBindRequest dfproto.CoreBindReply + 1 RunCommand dfproto.CoreRunCommandRequest dfproto.EmptyMessage +=== ============ =============================== ======================= + + + +Conversation flow +----------------- + +* Client → Server: `handshake request`_ +* Server → Client: `handshake reply`_ +* Repeated 0 or more times: + * Client → Server: `request`_ + * Server → Client: `text`_ (0 or more times) + * Server → Client: `result`_ or `failure`_ +* Client → Server: `quit`_ + +Raw message types +----------------- + +* All numbers are little-endian +* All strings are ASCII +* A payload size of greater than 64MiB is an error +* See ``RemoteClient.h`` for definitions of constants starting with ``RPC`` + +handshake request +~~~~~~~~~~~~~~~~~ + +.. csv-table:: + :align: left + :header-rows: 1 + + Type, Name, Value + char[8], magic, ``DFHack?\n`` + int32_t, version, 1 + +handshake reply +~~~~~~~~~~~~~~~ + +.. csv-table:: + :align: left + :header-rows: 1 + + Type, Name, Value + char[8], magic, ``DFHack!\n`` + int32_t, version, 1 + +header +~~~~~~ + +**Note:** the two fields of this message are sometimes repurposed. Uses of this +message are represented as ``header(x, y)``, where ``x`` corresponds to the ``id`` +field and ``y`` corresponds to ``size``. + +.. csv-table:: + :align: left + :header-rows: 1 + + Type, Name + int16_t, id + int16_t, (padding - unused) + int32_t, size + +request +~~~~~~~ + +.. list-table:: + :align: left + :header-rows: 1 + :widths: 25 75 + + * - Type + - Description + * - `header`_ + - ``header(id, size)`` + * - buffer + - Protobuf-encoded payload of the input message type of the method specified by ``id``; length of ``size`` bytes + +text +~~~~ + +.. list-table:: + :align: left + :header-rows: 1 + :widths: 25 75 + + * - Type + - Description + * - `header`_ + - ``header(RPC_REPLY_TEXT, size)`` + * - buffer + - Protobuf-encoded payload of type ``dfproto.CoreTextNotification``; length of ``size`` bytes + +result +~~~~~~ + +.. list-table:: + :align: left + :header-rows: 1 + :widths: 25 75 + + * - Type + - Description + * - `header`_ + - ``header(RPC_REPLY_RESULT, size)`` + * - buffer + - Protobuf-encoded payload of the output message type of the oldest incomplete method call; when received, + that method call is considered completed. Length of ``size`` bytes. + +failure +~~~~~~~ + +.. list-table:: + :align: left + :header-rows: 1 + :widths: 25 75 + + * - Type + - Description + * - `header`_ + - ``header(RPC_REPLY_FAIL, command_result)`` + * - command_result + - return code of the command (a constant starting with ``CR_``; see ``RemoteClient.h``) + +quit +~~~~ + +**Note:** the server closes the connection after sending this message. + +.. list-table:: + :align: left + :header-rows: 1 + :widths: 25 75 + :width: 100% + + * - Type + - Description + * - `header`_ + - ``header(RPC_REQUEST_QUIT, 0)`` From eb074b8a493fb971a98df156b95926dca1146dec Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 22 Jul 2020 02:04:02 -0400 Subject: [PATCH 212/547] Link to Wireshark script --- docs/Remote.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/Remote.rst b/docs/Remote.rst index 689f9978b..a40161fee 100644 --- a/docs/Remote.rst +++ b/docs/Remote.rst @@ -82,6 +82,10 @@ Protocol description This is a low-level description of the RPC protocol, which may be useful when developing custom clients. +A WireShark dissector for this protocol is available in the +`df_misc repo `_. + + Built-in messages ----------------- These messages have hardcoded IDs; all others must be obtained through ``BindMethod``. @@ -216,7 +220,7 @@ failure quit ~~~~ -**Note:** the server closes the connection after sending this message. +**Note:** the server closes the connection after receiving this message. .. list-table:: :align: left From 655b3632386f17f34ccaf5ddb223114e9184e623 Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 22 Jul 2020 02:23:29 -0400 Subject: [PATCH 213/547] Fix some spelling errors --- docs/Compile.rst | 2 +- docs/Core.rst | 12 ++++++------ docs/Documentation.rst | 6 +++--- docs/Lua API.rst | 8 ++++---- docs/Plugins.rst | 8 ++++---- plugins/stonesense | 2 +- scripts | 2 +- 7 files changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/Compile.rst b/docs/Compile.rst index 68187e7fa..c98cb939a 100644 --- a/docs/Compile.rst +++ b/docs/Compile.rst @@ -112,7 +112,7 @@ in the platform-specific sections below first, then come back here. Generator --------- -The ``Ninja`` CMake build generator is the prefered build method on Linux and +The ``Ninja`` CMake build generator is the preferred build method on Linux and macOS, instead of ``Unix Makefiles``, which is the default. You can select Ninja by passing ``-G Ninja`` to CMake. Incremental builds using Unix Makefiles can be much slower than Ninja builds. Note that you will probably need to install diff --git a/docs/Core.rst b/docs/Core.rst index c5d5670af..5ef3e6a4d 100644 --- a/docs/Core.rst +++ b/docs/Core.rst @@ -15,12 +15,12 @@ DFHack commands can be implemented in three ways, all of which are used in the same way: :builtin: commands are implemented by the core of DFHack. They manage - other DFhack tools, interpret commands, and control basic + other DFHack tools, interpret commands, and control basic aspects of DF (force pause or quit). :plugins: are stored in ``hack/plugins/`` and must be compiled with the same version of DFHack. They are less flexible than scripts, - but used for complex or ongoing tasks becasue they run faster. + but used for complex or ongoing tasks because they run faster. :scripts: are Ruby or Lua scripts stored in ``hack/scripts/``. Because they don't need to be compiled, scripts are @@ -88,7 +88,7 @@ but ``dfhack-run`` can be useful in a variety of circumstances: - if the console is unavailable - with the init setting ``PRINT_MODE:TEXT`` - - while running an interactive command (eg. `liquids` or `tiletypes`) + - while running an interactive command (e.g. `liquids` or `tiletypes`) - from external programs or scripts - if DF or DFHack are not responding @@ -113,7 +113,7 @@ second (Windows) example uses `kill-lua` to stop a Lua script. Built-in Commands ================= The following commands are provided by the 'core' components -of DFhack, rather than plugins or scripts. +of DFHack, rather than plugins or scripts. .. contents:: :local: @@ -419,7 +419,7 @@ onLoad*.init When a world is loaded, DFHack looks for files of the form ``onLoad*.init``, where ``*`` can be any string, including the empty string. -All matching init files will be executed in alphebetical order. +All matching init files will be executed in alphabetical order. 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 @@ -444,7 +444,7 @@ Other init files * ``onMapLoad*.init`` and ``onMapUnload*.init`` are run when a map, distinct from a world, is loaded. This is good for map-affecting - commands (eg `clean`), or avoiding issues in Legends mode. + commands (e.g. `clean`), or avoiding issues in Legends mode. * Any lua script named ``raw/init.d/*.lua``, in the save or main DF directory, will be run when any world or that save is loaded. diff --git a/docs/Documentation.rst b/docs/Documentation.rst index 37fcc6ee6..067f6bf90 100644 --- a/docs/Documentation.rst +++ b/docs/Documentation.rst @@ -53,7 +53,7 @@ directive - anything between the tokens is copied into the appropriate scripts documentation page. For Ruby, we follow the built-in docstring convention (``=begin`` and ``=end``). For Lua, the tokens are ``[====[`` and ``]====]`` - ordinary multi-line strings. It is highly encouraged to reuse this string -as the in-console documentation by (eg.) printing it when a ``-help`` argument +as the in-console documentation by (e.g.) printing it when a ``-help`` argument is given. The docs **must** have a heading which exactly matches the command, underlined @@ -101,7 +101,7 @@ describe the effect:: If it would be helpful to mention another DFHack command, don't just type the name - add a hyperlink! Specify the link target in backticks, and it will be -replaced with the corresponding title and linked: eg ```autolabor``` +replaced with the corresponding title and linked: e.g. ```autolabor``` => `autolabor`. Link targets should be equivalent to the command described (without file extension), and placed above the heading of that section like this:: @@ -159,7 +159,7 @@ Once pip is available, you can then install Sphinx with:: pip3 install sphinx -If you run this as an unpriviliged user, it may install a local copy of Sphinx +If you run this as an unprivileged user, it may install a local copy of Sphinx for your user only. The ``sphinx-build`` executable will typically end up in ``~/.local/bin/`` in this case. Alternatively, you can install Sphinx system-wide by running pip with ``sudo``. In any case, you will need the folder diff --git a/docs/Lua API.rst b/docs/Lua API.rst index c62d0f379..e9392f9c4 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -42,11 +42,11 @@ to lua code as a tree of objects and functions under the ``df`` global, which also broadly maps to the ``df`` namespace in the headers generated for C++. .. warning:: - The wrapper provides almost raw access to the memory - of the game, so mistakes in manipulating objects are as likely to - crash the game as equivalent plain C++ code would be. - eg. NULL pointer access is safely detected, but dangling pointers aren't. + The wrapper provides almost raw access to the memory of the game, so + mistakes in manipulating objects are as likely to crash the game as + equivalent plain C++ code would be - e.g. null pointer access is safely + detected, but dangling pointers aren't. Objects managed by the wrapper can be broadly classified into the following groups: diff --git a/docs/Plugins.rst b/docs/Plugins.rst index 7c37ea78c..3a4133873 100644 --- a/docs/Plugins.rst +++ b/docs/Plugins.rst @@ -191,7 +191,7 @@ Usage and related commands: :revflood: Hide everything, then reveal tiles with a path to the cursor (useful to make walled-off rooms vanish) :revforget: Discard info about what was visible before revealing the map. - Only useful where (eg) you abandoned with the fort revealed + Only useful where (e.g.) you abandoned with the fort revealed and no longer want the data. .. _showmood: @@ -737,7 +737,7 @@ by moving the view manually. mousequery ========== -Adds mouse controls to the DF interface, eg click-and-drag designations. +Adds mouse controls to the DF interface, e.g. click-and-drag designations. Options: @@ -840,10 +840,10 @@ See `gui/stockpiles` for an in-game interface. :savestock: Saves the currently highlighted stockpile's settings to a file in your Dwarf Fortress folder. This file can be used to copy settings between game saves or - players. eg: ``savestock food_settings.dfstock`` + players. e.g.: ``savestock food_settings.dfstock`` :loadstock: Loads a saved stockpile settings file and applies it to the currently selected - stockpile. eg: ``loadstock food_settings.dfstock`` + stockpile. e.g.: ``loadstock food_settings.dfstock`` To use savestock and loadstock, use the :kbd:`q` command to highlight a stockpile. Then run savestock giving it a descriptive filename. Then, in a different (or diff --git a/plugins/stonesense b/plugins/stonesense index bdab71c99..87e6cf02b 160000 --- a/plugins/stonesense +++ b/plugins/stonesense @@ -1 +1 @@ -Subproject commit bdab71c99a0a7cc268ca517a0cd3f0a5fb41042a +Subproject commit 87e6cf02b914daf6f7811d967db6fadc7ca115fe diff --git a/scripts b/scripts index af749e708..a5e385bb2 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit af749e7086739a058cd5095a6ee1a60d7e795a7c +Subproject commit a5e385bb2a3c72f878be614cb0cc004aafa17f79 From 8541db17cd660bb3a2e6745151be33d5338ac32d Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 22 Jul 2020 02:30:41 -0400 Subject: [PATCH 214/547] Remove :width: table directive (requires docutils 0.15) --- docs/Remote.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/Remote.rst b/docs/Remote.rst index a40161fee..a6f07ebc0 100644 --- a/docs/Remote.rst +++ b/docs/Remote.rst @@ -226,7 +226,6 @@ quit :align: left :header-rows: 1 :widths: 25 75 - :width: 100% * - Type - Description From e17d49220359ca0bd1dfe757532cbb0fb161afb6 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Thu, 23 Jul 2020 21:55:05 -0700 Subject: [PATCH 215/547] address PR review comments on api docs --- docs/changelog.txt | 2 +- library/include/modules/Filesystem.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index 5f3510ed9..58669e321 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -51,7 +51,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - `confirm`: added a confirmation dialog for convicting dwarves of crimes ## API -- Added ``Filesystem::mkdir_recursive`` (returns true if directories to create already exist) +- Added ``Filesystem::mkdir_recursive`` - Extended ``Filesystem::listdir_recursive`` to optionally make returned filenames relative to the start directory ## Lua diff --git a/library/include/modules/Filesystem.h b/library/include/modules/Filesystem.h index 3252be007..c9218ba33 100644 --- a/library/include/modules/Filesystem.h +++ b/library/include/modules/Filesystem.h @@ -149,6 +149,7 @@ namespace DFHack { DFHACK_EXPORT bool chdir (std::string path); DFHACK_EXPORT std::string getcwd (); DFHACK_EXPORT bool mkdir (std::string path); + // returns true on success or if directory already exists DFHACK_EXPORT bool mkdir_recursive (std::string path); DFHACK_EXPORT bool rmdir (std::string path); DFHACK_EXPORT bool stat (std::string path, STAT_STRUCT &info); @@ -160,6 +161,8 @@ namespace DFHack { DFHACK_EXPORT int64_t ctime (std::string path); DFHACK_EXPORT int64_t mtime (std::string path); DFHACK_EXPORT int listdir (std::string dir, std::vector &files); + // set include_prefix to false to prevent dir from being prepended to + // paths returned in files DFHACK_EXPORT int listdir_recursive (std::string dir, std::map &files, int depth = 10, bool include_prefix = true); } From e61f2b74516c208fed05ee3e420e231f15f282a3 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Thu, 23 Jul 2020 22:44:34 -0700 Subject: [PATCH 216/547] update Lua API.rst --- docs/Lua API.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/Lua API.rst b/docs/Lua API.rst index c62d0f379..569dc4c49 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -2116,8 +2116,10 @@ unless otherwise noted. * ``dfhack.filesystem.listdir(path)`` Lists files/directories in a directory. Returns ``{}`` if ``path`` does not exist. + Set include_prefix to false if you don't want the ``path`` string prepended to the + returned filenames. -* ``dfhack.filesystem.listdir_recursive(path [, depth = 10])`` +* ``dfhack.filesystem.listdir_recursive(path [, depth = 10[, include_prefix = true]])`` Lists all files/directories in a directory and its subdirectories. All directories are listed before their contents. Returns a table with subtables of the format:: From cafdc1620b5e57ac744064c448682bd417cabcb4 Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 24 Jul 2020 22:15:35 -0400 Subject: [PATCH 217/547] Improve Lua listdir_recursive error handling Ref #519, #1609 --- library/LuaApi.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index c20be4618..5b731ecc7 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -2404,10 +2404,10 @@ static int filesystem_listdir_recursive(lua_State *L) luaL_checktype(L,1,LUA_TSTRING); std::string dir=lua_tostring(L,1); int depth = 10; - if (lua_type(L, 2) == LUA_TNUMBER) - depth = lua_tounsigned(L, 2); + if (lua_gettop(L) >= 2) + depth = luaL_checkint(L, 2); bool include_prefix = true; - if (lua_type(L, 3) == LUA_TBOOLEAN) + if (lua_gettop(L) >= 3) include_prefix = lua_toboolean(L, 3); std::map files; int err = DFHack::Filesystem::listdir_recursive(dir, files, depth, include_prefix); From fcb14623a71ecd796f46c97a25b06e1fba9bf0c9 Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 24 Jul 2020 22:18:00 -0400 Subject: [PATCH 218/547] Update authors, submodules Ref dfhack/scripts#162 --- docs/Authors.rst | 1 + library/xml | 2 +- scripts | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/Authors.rst b/docs/Authors.rst index 3c2777a7d..55ecbb17c 100644 --- a/docs/Authors.rst +++ b/docs/Authors.rst @@ -43,6 +43,7 @@ Deon DoctorVanGogh DoctorVanGogh Donald Ruegsegger hashaash doomchild doomchild +ElMendukol ElMendukol enjia2000 Eric Wald eswald Erik Youngren Artanis diff --git a/library/xml b/library/xml index 7822df15e..bada2199d 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 7822df15ed44ca9e68d7270329ffd54dd7744977 +Subproject commit bada2199d16bd8e97d15efee7cbe05e5eb6ee6ee diff --git a/scripts b/scripts index a5e385bb2..f028d38e4 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit a5e385bb2a3c72f878be614cb0cc004aafa17f79 +Subproject commit f028d38e4ee9d60b9295a07d23ddb8dcc5197699 From 48d4013bcb8102a683545d3e63797a086bc68f44 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Fri, 24 Jul 2020 22:07:16 -0700 Subject: [PATCH 219/547] don't list subdirectories named 'internal' instead of just specifically for lua files with a '-internal.lua' suffix --- docs/changelog.txt | 2 +- library/Core.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index 19209ca60..949e8fe56 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -56,7 +56,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## Lua - Added a ``ref_target`` field to primitive field references, corresponding to the ``ref-target`` XML attribute -- Support for splitting scripts into multiple files without polluting the output of '#DFHack ls'. Scripts that end in '-internal.lua' will not be listed, but but they can still be 'require'd from other scripts. +- Support for splitting scripts into multiple files without polluting the output of ``#DFHack ls``. Scripts can now add internal files to an ``scripts/internal`` folder. ## Ruby - Updated ``item_find`` and ``building_find`` to use centralized logic that works on more screens diff --git a/library/Core.cpp b/library/Core.cpp index 9192d5772..c6ce9ea48 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -301,7 +301,7 @@ static void listScripts(PluginManager *plug_mgr, std::map &pset, path += '/'; for (size_t i = 0; i < files.size(); i++) { - if (hasEnding(files[i], ".lua") && !hasEnding(files[i], "-internal.lua")) + if (hasEnding(files[i], ".lua")) { string help = getScriptHelp(path + files[i], "--"); string key = prefix + files[i].substr(0, files[i].size()-4); @@ -317,7 +317,7 @@ static void listScripts(PluginManager *plug_mgr, std::map &pset, pset[key] = help; } } - else if (all && !files[i].empty() && files[i][0] != '.') + else if (all && !files[i].empty() && files[i][0] != '.' && files[i] != "internal") { listScripts(plug_mgr, pset, path+files[i]+"/", all, prefix+files[i]+"/"); } From e614e28beb2ae4d2979b4a94fe32ae3b8df79a51 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Fri, 24 Jul 2020 23:40:27 -0700 Subject: [PATCH 220/547] exempt scripts under 'internal' from docstring req --- travis/script-docs.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/travis/script-docs.py b/travis/script-docs.py index b2c8063bf..a102ae35b 100755 --- a/travis/script-docs.py +++ b/travis/script-docs.py @@ -81,7 +81,9 @@ def check_file(fname): def main(): """Check that all DFHack scripts include documentation""" err = 0 - for root, _, files in os.walk(SCRIPT_PATH): + exclude = set(['internal']) + for root, dirs, files in os.walk(SCRIPT_PATH, topdown=True): + dirs[:] = [d for d in dirs if d not in exclude] for f in files: if f[-3:] in {'.rb', 'lua'}: err += check_file(join(root, f)) From 7c921d8c916dce2cc06a1f885198e8f1dca58622 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 25 Jul 2020 13:02:35 -0400 Subject: [PATCH 221/547] Lua listdir_recursive: allow nil to be used for default arguments https://github.com/DFHack/dfhack/pull/1609#issuecomment-663803777 --- library/LuaApi.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 5b731ecc7..25843875d 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -2404,10 +2404,10 @@ static int filesystem_listdir_recursive(lua_State *L) luaL_checktype(L,1,LUA_TSTRING); std::string dir=lua_tostring(L,1); int depth = 10; - if (lua_gettop(L) >= 2) + if (lua_gettop(L) >= 2 && !lua_isnil(L, 2)) depth = luaL_checkint(L, 2); bool include_prefix = true; - if (lua_gettop(L) >= 3) + if (lua_gettop(L) >= 3 && !lua_isnil(L, 3)) include_prefix = lua_toboolean(L, 3); std::map files; int err = DFHack::Filesystem::listdir_recursive(dir, files, depth, include_prefix); From e0b37c8320213920dccda4fc6341ea52a6823481 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 25 Jul 2020 13:03:22 -0400 Subject: [PATCH 222/547] Update scripts (gui/advfort_items) --- scripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts b/scripts index f028d38e4..ad67c79f8 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit f028d38e4ee9d60b9295a07d23ddb8dcc5197699 +Subproject commit ad67c79f8074a491c144144b2825cd05c80a2236 From 0f0306fc848bbdeb60a9c705578a38c0e67c4b99 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 25 Jul 2020 15:20:20 -0400 Subject: [PATCH 223/547] Move to internal changelog section + shorten --- docs/changelog.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index 949e8fe56..8a45ba5b7 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -54,9 +54,11 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - Added ``Filesystem::mkdir_recursive`` - Extended ``Filesystem::listdir_recursive`` to optionally make returned filenames relative to the start directory +## Internals +- Added support for splitting scripts into multiple files in the ``scripts/internal`` folder without polluting the output of `ls` + ## Lua - Added a ``ref_target`` field to primitive field references, corresponding to the ``ref-target`` XML attribute -- Support for splitting scripts into multiple files without polluting the output of ``#DFHack ls``. Scripts can now add internal files to an ``scripts/internal`` folder. ## Ruby - Updated ``item_find`` and ``building_find`` to use centralized logic that works on more screens From 4891b4fd5e98801e414bdf57b4129df2515d4689 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 25 Jul 2020 20:22:52 -0400 Subject: [PATCH 224/547] Fix indexing primitive refs with integers (broken in #1543), add tests Apparently lua_tostring has the side effect of *converting* numbers to strings --- library/LuaTypes.cpp | 19 +++--- test/structures/primitive_refs.lua | 92 ++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 8 deletions(-) create mode 100644 test/structures/primitive_refs.lua diff --git a/library/LuaTypes.cpp b/library/LuaTypes.cpp index 845d273e3..d496ba56f 100644 --- a/library/LuaTypes.cpp +++ b/library/LuaTypes.cpp @@ -707,15 +707,18 @@ static type_identity *find_primitive_field(lua_State *state, int field, const ch */ static int meta_primitive_index(lua_State *state) { - const char *attr = lua_tostring(state, -1); - if (strcmp(attr, "ref_target") == 0) { - const struct_field_info *field_info = get_object_ref_header(state, 1)->field_info; - if (field_info && field_info->extra && field_info->extra->ref_target) { - LookupInTable(state, field_info->extra->ref_target, &DFHACK_TYPEID_TABLE_TOKEN); - } else { - lua_pushnil(state); + if (lua_type(state, -1) == LUA_TSTRING) + { + const char *attr = lua_tostring(state, -1); + if (strcmp(attr, "ref_target") == 0) { + const struct_field_info *field_info = get_object_ref_header(state, 1)->field_info; + if (field_info && field_info->extra && field_info->extra->ref_target) { + LookupInTable(state, field_info->extra->ref_target, &DFHACK_TYPEID_TABLE_TOKEN); + } else { + lua_pushnil(state); + } + return 1; } - return 1; } uint8_t *ptr = get_object_addr(state, 1, 2, "read"); diff --git a/test/structures/primitive_refs.lua b/test/structures/primitive_refs.lua new file mode 100644 index 000000000..9de5bc980 --- /dev/null +++ b/test/structures/primitive_refs.lua @@ -0,0 +1,92 @@ +utils = require('utils') + +function with_temp_ref(...) + local args = {...} + local dtype = 'int32_t' + if type(args[1]) == 'string' then + dtype = table.remove(args, 1) + end + local count = 1 + if type(args[1]) == 'number' then + count = table.remove(args, 1) + end + local func = table.remove(args, 1) + assert(type(func) == 'function') + dfhack.with_temp_object(df.new(dtype, count), func, table.unpack(args)) +end + +function test.zero_initialize() + with_temp_ref(function(x) + expect.eq(x.value, 0) + end) +end + +function test.zero_initialize_array() + with_temp_ref(2, function(x) + expect.eq(x:_displace(1).value, 0) + end) +end + +function test.displace_zero() + with_temp_ref(function(x) + expect.eq(x, x:_displace(0)) + end) +end + +function test.displace_nonzero() + with_temp_ref(2, function(x) + expect.ne(x, x:_displace(1)) + expect.eq(utils.addressof(x) + x:sizeof(), utils.addressof(x:_displace(1))) + end) +end + +function test.displace_negative() + with_temp_ref(2, function(x) + expect.true_(x:_displace(1):_displace(-1).value) + end) +end + +function test.index_read() + with_temp_ref(function(x) + expect.eq(x.value, x[0]) + end) +end + +function test.index_write() + with_temp_ref(function(x) + x[0] = 1 + expect.eq(x.value, 1) + expect.eq(x[0], 1) + x.value = 2 + expect.eq(x.value, 2) + expect.eq(x[0], 2) + end) +end + +function test.index_write_multi() + local len = 3 + with_temp_ref(len, function(x) + for i = 0, len - 1 do + x[i] = i * i + end + for i = 0, len - 1 do + expect.eq(x[i], i * i) + end + end) +end + +function test.index_read_negative() + with_temp_ref(function(x) + expect.error_match(function() + expect.true_(x:_displace(1)[-1]) + end, 'negative index') + end) +end + +function test.index_write_negative() + with_temp_ref(function(x) + expect.error_match(function() + x:_displace(1)[-1] = 7 + end, 'negative index') + end) +end From 4e218c7de30dd859c3c2ca033dd0a5b1b8951df7 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sun, 26 Jul 2020 02:00:13 -0400 Subject: [PATCH 225/547] Update xml --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index bada2199d..389ffde5a 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit bada2199d16bd8e97d15efee7cbe05e5eb6ee6ee +Subproject commit 389ffde5a96b3c8263c0c2a2376e387aa2343fad From f0ad730a3798bbe60c2afa1b3274963adf085425 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sun, 26 Jul 2020 02:11:20 -0400 Subject: [PATCH 226/547] Lua: Fix off-by-one preventing accessing last df-other-vectors item by ID, add tests --- library/LuaTypes.cpp | 2 +- test/structures/other_vectors.lua | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 test/structures/other_vectors.lua diff --git a/library/LuaTypes.cpp b/library/LuaTypes.cpp index d496ba56f..740b3f689 100644 --- a/library/LuaTypes.cpp +++ b/library/LuaTypes.cpp @@ -1451,7 +1451,7 @@ void other_vectors_identity::build_metatable(lua_State *state) auto keys = &index_enum->getKeys()[-index_enum->getFirstItem()]; - for (int64_t i = 0; i < index_enum->getLastItem(); i++) + for (int64_t i = 0; i <= index_enum->getLastItem(); i++) { lua_getfield(state, base+2, keys[i]); lua_rawseti(state, base+2, int(i)); diff --git a/test/structures/other_vectors.lua b/test/structures/other_vectors.lua new file mode 100644 index 000000000..43a50dc2a --- /dev/null +++ b/test/structures/other_vectors.lua @@ -0,0 +1,27 @@ +function test.index_name() + for _, k in ipairs(df.units_other_id) do + expect.eq(df.global.world.units.other[k]._kind, 'container') + end +end + +function test.index_name_bad() + expect.error_match(function() + expect.eq(df.global.world.units.other.SOME_FAKE_NAME, 'container') + end, 'not found.$') +end + +function test.index_id() + for i in ipairs(df.units_other_id) do + expect.eq(df.global.world.units.other[i]._kind, 'container') + end +end + +function test.index_id_bad() + expect.error_match(function() + expect.eq(df.global.world.units.other[df.units_other_id._first_item - 1], 'container') + end, 'Cannot read field') + expect.error_match(function() + expect.eq(df.global.world.units.other[df.units_other_id._last_item + 1], 'container') + end, 'Cannot read field') +end + From 4554ca35f3eef40137d5b264fdfda673eca60be0 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sun, 26 Jul 2020 23:11:04 -0400 Subject: [PATCH 227/547] Ruby: add _indexenum wrapper to OtherVectors for compat with devel/scanitemsother Ref #1558 --- plugins/ruby/ruby-autogen-defs.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/ruby/ruby-autogen-defs.rb b/plugins/ruby/ruby-autogen-defs.rb index c72ffeb2b..162914e32 100644 --- a/plugins/ruby/ruby-autogen-defs.rb +++ b/plugins/ruby/ruby-autogen-defs.rb @@ -213,6 +213,9 @@ module DFHack end end + def _indexenum + self.class._enum + end def [](i) self.send(self.class._enum.sym(i)) end From 569370489adf34bdb5089bd0ab406069943cf9db Mon Sep 17 00:00:00 2001 From: lethosor Date: Sun, 26 Jul 2020 23:16:13 -0400 Subject: [PATCH 228/547] Update submodules (fixes #1576) --- library/xml | 2 +- scripts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/xml b/library/xml index 389ffde5a..d6800389a 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 389ffde5a96b3c8263c0c2a2376e387aa2343fad +Subproject commit d6800389a501d53dcc353d7e82137f5e2a7d08c8 diff --git a/scripts b/scripts index ad67c79f8..3678042e4 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit ad67c79f8074a491c144144b2825cd05c80a2236 +Subproject commit 3678042e41f84669c0faf5984f22cf3742186091 From 289e0df828297b75a96fef2d1132ca7aa7de890e Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 27 Jul 2020 01:12:14 -0400 Subject: [PATCH 229/547] Roll back to actions/checkout v1 v2 uses the wrong commit sometimes: actions/checkout#299 --- .github/workflows/build.yml | 4 ++-- library/xml | 2 +- scripts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fb98bfa0b..8c3819f11 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,7 +24,7 @@ jobs: zlib1g-dev pip install sphinx - name: Clone DFHack - uses: actions/checkout@v2 + uses: actions/checkout@v1 with: fetch-depth: 0 # unlimited - we need past tags submodules: true @@ -99,7 +99,7 @@ jobs: sudo apt-get update sudo apt-get install lua5.3 - name: Clone DFHack - uses: actions/checkout@v2 + uses: actions/checkout@v1 with: submodules: true # don't need tags here diff --git a/library/xml b/library/xml index d6800389a..61bdd4236 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit d6800389a501d53dcc353d7e82137f5e2a7d08c8 +Subproject commit 61bdd4236ef9cdde03516d73444ff3708c8ee822 diff --git a/scripts b/scripts index 3678042e4..9799af8cb 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 3678042e41f84669c0faf5984f22cf3742186091 +Subproject commit 9799af8cb4c825ca9dbe6e6293c28790a5edbfef From c1219642b518b57722c6d6d19f63152dc27c8ac0 Mon Sep 17 00:00:00 2001 From: lethosor Date: Tue, 28 Jul 2020 00:21:23 -0400 Subject: [PATCH 230/547] Reorganize dev docs TOC, add label to remote TOC --- docs/Remote.rst | 2 +- docs/index-dev.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/Remote.rst b/docs/Remote.rst index a6f07ebc0..435873f71 100644 --- a/docs/Remote.rst +++ b/docs/Remote.rst @@ -12,7 +12,7 @@ available are not comprehensive, but can be extended with plugins. .. _Google protobuf: https://developers.google.com/protocol-buffers -.. contents:: +.. contents:: Contents :local: diff --git a/docs/index-dev.rst b/docs/index-dev.rst index 560137609..95e5e3fdd 100644 --- a/docs/index-dev.rst +++ b/docs/index-dev.rst @@ -12,9 +12,9 @@ These are pages relevant to people developing for DFHack. /docs/Compile /docs/NEWS-dev /docs/Lua API + /docs/Remote /docs/Documentation /docs/Structures-intro /docs/Memory-research - /docs/Remote /docs/Binpatches From 411176c75e40a7a5cd3cc49cd7a8520ab64373ae Mon Sep 17 00:00:00 2001 From: lethosor Date: Tue, 28 Jul 2020 00:38:22 -0400 Subject: [PATCH 231/547] Add rudimentary map docs with tile descriptions from @AtomicChicken Based on http://www.bay12forums.com/smf/index.php?topic=164123.msg8158676#msg8158676 --- docs/Lua API.rst | 2 ++ docs/api/Maps.rst | 59 ++++++++++++++++++++++++++++++++++++++++++++++ docs/api/index.rst | 8 +++++++ docs/index-dev.rst | 1 + 4 files changed, 70 insertions(+) create mode 100644 docs/api/Maps.rst create mode 100644 docs/api/index.rst diff --git a/docs/Lua API.rst b/docs/Lua API.rst index de5741861..8c3763245 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -1414,6 +1414,8 @@ Items module Checks whether the item is assigned to a squad. +.. _lua-maps: + Maps module ----------- diff --git a/docs/api/Maps.rst b/docs/api/Maps.rst new file mode 100644 index 000000000..cfffe7905 --- /dev/null +++ b/docs/api/Maps.rst @@ -0,0 +1,59 @@ +.. include:: + +======== +Maps API +======== + +DFHack offers several ways to access and manipulate map data. + +* C++: the ``Maps`` and ``MapCache`` modules +* Lua: the `dfhack.maps module `_ +* All languages: the ``map`` field of the ``world`` global contains raw map data + when the world is loaded. + +.. note:: + + This page will eventually go into more detail about the available APIs. + For now, it is just an overview of how DF map data is structured. + +.. contents:: Contents + :local: + +Tiles +===== + +The DF map has several types of tiles: + +- **Local tiles** are at the smallest scale. In regular fortress/adventure mode + play, the cursor takes up 1 local tile. + + Objects that use local tile coordinates include: + + - Units + - Items + - Projectiles + +- **Blocks** are 16 |times| 16 |times| 1 groups of local tiles. Internally, many + tile details are stored at the block level for space-efficiency reasons. + Blocks are visible during zoomed-in fast travel in adventure mode. + + Objects that use block coordinates include: + + - Armies + +- **Region tiles** are 3 |times| 3 groups of columns of blocks (they span the + entire z-axis), or 48 |times| 48 columns of local tiles. DF sometimes refers + to these as "mid-level tiles" (MLTs). Region tiles are visible when resizing + a fortress before embarking, or in zoomed-out fast travel in adventure mode. + +- **World tiles** are + + - 16 |times| 16 groups of region tiles, or + - 48 |times| 48 groups of columns of blocks, or + - 768 |times| 768 groups of columns of local tiles + + World tiles are visible on the world map before embarking, as well as in the + civilization map in fortress mode and the quest log in adventure mode. + +- Some map features are stored in 16 |times| 16 groups of world tiles, sometimes + referred to as "feature shells". diff --git a/docs/api/index.rst b/docs/api/index.rst new file mode 100644 index 000000000..1fe03e9a8 --- /dev/null +++ b/docs/api/index.rst @@ -0,0 +1,8 @@ +==================== +DFHack API Reference +==================== + +.. toctree:: + :maxdepth: 1 + + /docs/api/Maps diff --git a/docs/index-dev.rst b/docs/index-dev.rst index 95e5e3fdd..3788baf1d 100644 --- a/docs/index-dev.rst +++ b/docs/index-dev.rst @@ -13,6 +13,7 @@ These are pages relevant to people developing for DFHack. /docs/NEWS-dev /docs/Lua API /docs/Remote + /docs/api/index /docs/Documentation /docs/Structures-intro /docs/Memory-research From f546816eb984cd384c324ae0119640cb0e1a4b99 Mon Sep 17 00:00:00 2001 From: lethosor Date: Tue, 28 Jul 2020 00:39:59 -0400 Subject: [PATCH 232/547] Update submodules --- library/xml | 2 +- scripts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/xml b/library/xml index 61bdd4236..0afb796c4 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 61bdd4236ef9cdde03516d73444ff3708c8ee822 +Subproject commit 0afb796c4e81102a8cf57b120945b365c704793c diff --git a/scripts b/scripts index 9799af8cb..ef428bec5 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 9799af8cb4c825ca9dbe6e6293c28790a5edbfef +Subproject commit ef428bec5269a060c0d706cad75397db4e508db9 From d504e476c55a644647a0c99908ce39cab0928066 Mon Sep 17 00:00:00 2001 From: lethosor Date: Tue, 28 Jul 2020 23:42:37 -0400 Subject: [PATCH 233/547] Update xml --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index 0afb796c4..ecd6bcc9e 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 0afb796c4e81102a8cf57b120945b365c704793c +Subproject commit ecd6bcc9ed67c62fa605561b27574467df792342 From 437923bd2ef2a3e072ac8eaa0e1f177695116c7e Mon Sep 17 00:00:00 2001 From: lethosor Date: Wed, 29 Jul 2020 22:40:05 -0400 Subject: [PATCH 234/547] Update scripts/pref-adjust --- scripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts b/scripts index ef428bec5..a50a72a14 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit ef428bec5269a060c0d706cad75397db4e508db9 +Subproject commit a50a72a143cab62348909c3568ddbe63745e5451 From 19ad5c92d64396d77eac93e78a66b9714f6751d1 Mon Sep 17 00:00:00 2001 From: PatrikLundell Date: Thu, 30 Jul 2020 10:09:41 +0200 Subject: [PATCH 235/547] corrected incursion bugs --- plugins/embark-assistant/survey.cpp | 76 +++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 5 deletions(-) diff --git a/plugins/embark-assistant/survey.cpp b/plugins/embark-assistant/survey.cpp index 2d5dca04d..fb44440a1 100644 --- a/plugins/embark-assistant/survey.cpp +++ b/plugins/embark-assistant/survey.cpp @@ -1641,10 +1641,10 @@ uint8_t embark_assist::survey::translate_corner(embark_assist::defs::world_tile bool n_region_type_active; bool w_region_type_active; bool home_region_type_active; - uint8_t nw_region_type_level; - uint8_t n_region_type_level; - uint8_t w_region_type_level; - uint8_t home_region_type_level; + int8_t nw_region_type_level; + int8_t n_region_type_level; + int8_t w_region_type_level; + int8_t home_region_type_level; if (corner_location == 4) { // We're the reference. No change. } @@ -1666,6 +1666,39 @@ uint8_t embark_assist::survey::translate_corner(embark_assist::defs::world_tile return 4; } else { // East side corners of the east edge of the world + nw_region_type = embark_assist::survey::region_type_of(survey_results, x, y, effective_i - 1, effective_k - 1); + w_region_type = embark_assist::survey::region_type_of(survey_results, x, y, effective_i - 1, effective_k); + + if (nw_region_type == df::world_region_type::Lake || + nw_region_type == df::world_region_type::Ocean) { + nw_region_type_level = 0; + } + else if (nw_region_type == df::world_region_type::Mountains) { + nw_region_type_level = 1; + } + else { + nw_region_type_level = 2; + } + + if (w_region_type == df::world_region_type::Lake || + w_region_type == df::world_region_type::Ocean) { + w_region_type_level = 0; + } + else if (w_region_type == df::world_region_type::Mountains) { + w_region_type_level = 1; + } + else { + w_region_type_level = 2; + } + + if (nw_region_type_level < w_region_type_level) { + return 4; + } + else if (nw_region_type_level > w_region_type_level) { + return 1; + } + + // Neither tile will automatically yield to the other if (corner_location == 5) { return 1; } @@ -1675,11 +1708,44 @@ uint8_t embark_assist::survey::translate_corner(embark_assist::defs::world_tile } } else if (effective_y == world_data->world_height) { + nw_region_type = embark_assist::survey::region_type_of(survey_results, x, y, effective_i - 1, effective_k - 1); + n_region_type = embark_assist::survey::region_type_of(survey_results, x, y, effective_i, effective_k - 1); + + if (nw_region_type == df::world_region_type::Lake || + nw_region_type == df::world_region_type::Ocean) { + nw_region_type_level = 0; + } + else if (nw_region_type == df::world_region_type::Mountains) { + nw_region_type_level = 1; + } + else { + nw_region_type_level = 2; + } + + if (n_region_type == df::world_region_type::Lake || + n_region_type == df::world_region_type::Ocean) { + n_region_type_level = 0; + } + else if (n_region_type == df::world_region_type::Mountains) { + n_region_type_level = 1; + } + else { + n_region_type_level = 2; + } + + if (nw_region_type_level < n_region_type_level) { + return 4; + } + else if (nw_region_type_level > n_region_type_level) { + return 5; + } + + // Neither tile will automatically yield to the other if (corner_location == 7) { return 4; } else { // Can only be corner_location == 8 - return 3; + return 5; } } From bb66ef32a7f4ba6c66fca854482de092b8e447cd Mon Sep 17 00:00:00 2001 From: lethosor Date: Sun, 2 Aug 2020 12:55:36 -0400 Subject: [PATCH 236/547] Tone down a couple warnings There have been a few cases of people thinking these are more important than they actually are --- library/DataDefs.cpp | 2 +- library/PluginManager.cpp | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/library/DataDefs.cpp b/library/DataDefs.cpp index f8f65b108..28761efa3 100644 --- a/library/DataDefs.cpp +++ b/library/DataDefs.cpp @@ -334,7 +334,7 @@ virtual_identity *virtual_identity::find(void *vtable) return p; } - std::cerr << "UNKNOWN CLASS '" << name << "': vtable = 0x" + std::cerr << "Class not in symbols.xml: '" << name << "': vtable = 0x" << std::hex << uintptr_t(vtable) << std::dec << std::endl; known[vtable] = NULL; diff --git a/library/PluginManager.cpp b/library/PluginManager.cpp index 05db0521d..db42c5c84 100644 --- a/library/PluginManager.cpp +++ b/library/PluginManager.cpp @@ -313,8 +313,12 @@ bool Plugin::load(color_ostream &con) if (plug_git_desc_ptr) { if (strcmp(dfhack_git_desc, plug_git_desc) != 0) - con.printerr("Warning: Plugin %s compiled for DFHack %s, running DFHack %s\n", + { + std::string msg = stl_sprintf("Warning: Plugin %s compiled for DFHack %s, running DFHack %s\n", *plug_name, plug_git_desc, dfhack_git_desc); + con << msg; + cerr << msg; + } } else con.printerr("Warning: Plugin %s missing git information\n", *plug_name); From dba7df7ab8ba562726f10f6b9a5f6312e0637b70 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sun, 2 Aug 2020 23:10:35 -0400 Subject: [PATCH 237/547] Add "delete word" support to Console-posix --- docs/changelog.txt | 1 + library/Console-posix.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/docs/changelog.txt b/docs/changelog.txt index 8a45ba5b7..bf953d562 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -55,6 +55,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - Extended ``Filesystem::listdir_recursive`` to optionally make returned filenames relative to the start directory ## Internals +- Linux/macOS: Added console keybindings for deleting words (Alt+Backspace and Alt+d in most terminals) - Added support for splitting scripts into multiple files in the ``scripts/internal`` folder without polluting the output of `ls` ## Lua diff --git a/library/Console-posix.cpp b/library/Console-posix.cpp index 6fb1cbff3..595f50e97 100644 --- a/library/Console-posix.cpp +++ b/library/Console-posix.cpp @@ -541,6 +541,7 @@ namespace DFHack return Console::SHUTDOWN; } lock->lock(); + const int old_cursor = raw_cursor; /* Only autocomplete when the callback is set. It returns < 0 when * there was an error reading from fd. Otherwise it will return the * character that should be handled next. */ @@ -597,6 +598,29 @@ namespace DFHack { forward_word(); } + else if (seq[0] == 127 || seq[0] == 8) // backspace || ctrl-h + { + // delete word + back_word(); + if (old_cursor > raw_cursor) + { + yank_buffer = raw_buffer.substr(raw_cursor, old_cursor - raw_cursor); + raw_buffer.erase(raw_cursor, old_cursor - raw_cursor); + prompt_refresh(); + } + } + else if (seq[0] == 'd') + { + // delete word forward + forward_word(); + if (old_cursor < raw_cursor) + { + yank_buffer = raw_buffer.substr(old_cursor, raw_cursor - old_cursor); + raw_buffer.erase(old_cursor, raw_cursor - old_cursor); + raw_cursor = old_cursor; + prompt_refresh(); + } + } else if(seq[0] == '[') { if (!read_char(seq[1])) From 00a240fcaf55f6141153f97aba0ea63e6d2b95f3 Mon Sep 17 00:00:00 2001 From: lethosor Date: Tue, 4 Aug 2020 16:44:34 -0400 Subject: [PATCH 238/547] Update scripts (dfhack/scripts#114) --- scripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts b/scripts index a50a72a14..70ce0a12b 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit a50a72a143cab62348909c3568ddbe63745e5451 +Subproject commit 70ce0a12bc0eb14b3782abe7033a6d2dd31863fe From 9510dd52e13c037b08ebecfa23dd46491f77737e Mon Sep 17 00:00:00 2001 From: Ryan Bennitt Date: Tue, 4 Aug 2020 23:01:28 +0100 Subject: [PATCH 239/547] Add Goal to Manipulator Detail Modes --- library/include/modules/Units.h | 5 ++ library/modules/Units.cpp | 67 +++++++++++++++++++++++++++ plugins/manipulator.cpp | 81 +++++++++++++++++++++++++++++---- 3 files changed, 145 insertions(+), 8 deletions(-) diff --git a/library/include/modules/Units.h b/library/include/modules/Units.h index f5995583b..c719a60a9 100644 --- a/library/include/modules/Units.h +++ b/library/include/modules/Units.h @@ -32,6 +32,7 @@ distribution. #include "DataDefs.h" #include "df/caste_raw_flags.h" +#include "df/goal_type.h" #include "df/job_skill.h" #include "df/mental_attribute_type.h" #include "df/misc_trait_type.h" @@ -180,6 +181,10 @@ DFHACK_EXPORT std::string getCasteProfessionName(int race, int caste, df::profes DFHACK_EXPORT int8_t getProfessionColor(df::unit *unit, bool ignore_noble = false); DFHACK_EXPORT int8_t getCasteProfessionColor(int race, int caste, df::profession pid); +DFHACK_EXPORT df::goal_type getGoalType(df::unit *unit, int goalIndex = 0); +DFHACK_EXPORT std::string getGoalName(df::unit *unit, int goalIndex = 0); +DFHACK_EXPORT bool isGoalAchieved(df::unit *unit, int goalIndex = 0); + DFHACK_EXPORT std::string getSquadName(df::unit *unit); DFHACK_EXPORT df::activity_entry *getMainSocialActivity(df::unit *unit); diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index 422060803..87c71ac67 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -1437,6 +1437,73 @@ int8_t Units::getCasteProfessionColor(int race, int casteid, df::profession pid) return 3; } +df::goal_type Units::getGoalType(df::unit *unit, int goalIndex) +{ + CHECK_NULL_POINTER(unit); + + df::goal_type goal = df::goal_type::STAY_ALIVE; + if (unit->status.current_soul + && unit->status.current_soul->personality.dreams.size() > goalIndex) + { + goal = unit->status.current_soul->personality.dreams[goalIndex]->type; + } + return goal; +} + +std::string Units::getGoalName(df::unit *unit, int goalIndex) +{ + CHECK_NULL_POINTER(unit); + + df::goal_type goal = getGoalType(unit, goalIndex); + bool achieved_goal = isGoalAchieved(unit, goalIndex); + + switch (goal) + { + default: + case df::goal_type::STAY_ALIVE: + return achieved_goal ? "Stayed Alive" : "Stay Alive"; + case df::goal_type::MAINTAIN_ENTITY_STATUS: + return achieved_goal ? "Maintained Status" : "Maintain Status"; + case df::goal_type::START_A_FAMILY: + return isFemale(unit) ? + (achieved_goal ? "Is a Mother" : "Be a Mother") : + (achieved_goal ? "Is a Father" : "Be a Father"); + case df::goal_type::RULE_THE_WORLD: + return achieved_goal ? "Ruled the World" : "Rule the World"; + case df::goal_type::CREATE_A_GREAT_WORK_OF_ART: + return achieved_goal ? "Made Great Artwork" : "Create Great Artwork"; + case df::goal_type::CRAFT_A_MASTERWORK: + return achieved_goal ? "Crafted a Masterwork" : "Craft a Masterwork"; + case df::goal_type::BRING_PEACE_TO_THE_WORLD: + return achieved_goal ? "Brought World Peace" : "Bring Peace to World"; + case df::goal_type::BECOME_A_LEGENDARY_WARRIOR: + return achieved_goal ? "Is Legendary Warrior" : "Be Legendary Warrior"; + case df::goal_type::MASTER_A_SKILL: + return achieved_goal ? "Mastered a Skill" : "Master a Skill"; + case df::goal_type::FALL_IN_LOVE: + return achieved_goal ? "Fell in Love" : "Fall in Love"; + case df::goal_type::SEE_THE_GREAT_NATURAL_SITES: + return achieved_goal ? "Saw Natural Wonders" : "See Natural Wonders"; + case df::goal_type::IMMORTALITY: + return achieved_goal ? "Immortal" : "Immortality"; + case df::goal_type::MAKE_A_GREAT_DISCOVERY: + return achieved_goal ? "Made Great Discovery" : "Make Great Discovery"; + case df::goal_type::ATTAINING_RANK_IN_SOCIETY: + return achieved_goal ? "Attained Social Rank" : "Attain Social Rank"; + case df::goal_type::BATHING_THE_WORLD_IN_CHAOS: + return achieved_goal ? "World is in Chaos" : "Bathe World in Chaos"; + } +} + +bool Units::isGoalAchieved(df::unit *unit, int goalIndex) +{ + CHECK_NULL_POINTER(unit); + + return unit->status.current_soul + && unit->status.current_soul->personality.dreams.size() > goalIndex + && unit->status.current_soul->personality.dreams[goalIndex]->flags.whole != 0; +} + std::string Units::getSquadName(df::unit *unit) { CHECK_NULL_POINTER(unit); diff --git a/plugins/manipulator.cpp b/plugins/manipulator.cpp index a013df335..4bb285f0b 100644 --- a/plugins/manipulator.cpp +++ b/plugins/manipulator.cpp @@ -32,9 +32,12 @@ #include "df/caste_raw.h" #include "df/historical_entity.h" #include "df/entity_raw.h" +#include "df/goal_type.h" +#include "df/unit_personality.h" #include "uicommon.h" #include "listcolumn.h" +#include "manipulator.h" using std::stringstream; using std::set; @@ -287,6 +290,9 @@ struct UnitInfo string name; string transname; string profession; + string goal; + enum { NEUTRAL, MALE, FEMALE } goal_gender; + bool achieved_goal; int8_t color; int active_index; string squad_effective_name; @@ -310,7 +316,8 @@ struct UnitInfo enum detail_cols { DETAIL_MODE_PROFESSION, DETAIL_MODE_SQUAD, - DETAIL_MODE_JOB + DETAIL_MODE_JOB, + DETAIL_MODE_GOAL }; enum altsort_mode { ALTSORT_NAME, @@ -348,6 +355,21 @@ bool sortByProfession (const UnitInfo *d1, const UnitInfo *d2) return (d1->profession < d2->profession); } +bool sortByGoal (const UnitInfo *d1, const UnitInfo *d2) +{ + if (!d1->unit->status.current_soul) + return !descending; + if (!d2->unit->status.current_soul) + return descending; + + df::goal_type goal1 = Units::getGoalType(d1->unit); + df::goal_type goal2 = Units::getGoalType(d2->unit); + if (descending) + return (goal1 > goal2); + else + return (goal1 < goal2); +} + bool sortBySquad (const UnitInfo *d1, const UnitInfo *d2) { bool gt = false; @@ -583,6 +605,8 @@ namespace unit_ops { } string get_profname(UnitInfo *u) { return Units::getProfessionName(u->unit); } + string get_goalname(UnitInfo *u) + { return Units::getGoalName(u->unit); } string get_real_profname(UnitInfo *u) { string tmp = u->unit->custom_profession; @@ -1237,6 +1261,14 @@ void viewscreen_unitlaborsst::refreshNames() cur->name = Translation::TranslateName(Units::getVisibleName(unit), false); cur->transname = Translation::TranslateName(Units::getVisibleName(unit), true); cur->profession = Units::getProfessionName(unit); + cur->goal = Units::getGoalName(unit); + df::goal_type goal = Units::getGoalType(unit); + if (goal == df::goal_type::START_A_FAMILY) { + cur->goal_gender = Units::isFemale(unit) ? UnitInfo::FEMALE : UnitInfo::MALE; + } else { + cur->goal_gender = UnitInfo::NEUTRAL; + } + cur->achieved_goal = Units::isGoalAchieved(unit); if (unit->job.current_job == NULL) { df::activity_event *event = Units::getMainSocialEvent(unit); @@ -1298,8 +1330,10 @@ void viewscreen_unitlaborsst::calcSize() detail_cmp = units[i]->squad_info.size(); } else if (detail_mode == DETAIL_MODE_JOB) { detail_cmp = units[i]->job_desc.size(); - } else { + } else if (detail_mode == DETAIL_MODE_PROFESSION) { detail_cmp = units[i]->profession.size(); + } else { + detail_cmp = units[i]->goal.size(); } if (size_t(col_maxwidth[DISP_COLUMN_DETAIL]) < detail_cmp) col_maxwidth[DISP_COLUMN_DETAIL] = detail_cmp; @@ -1736,8 +1770,10 @@ void viewscreen_unitlaborsst::feed(set *events) std::stable_sort(units.begin(), units.end(), sortBySquad); } else if (detail_mode == DETAIL_MODE_JOB) { std::stable_sort(units.begin(), units.end(), sortByJob); - } else { + } else if (detail_mode == DETAIL_MODE_PROFESSION){ std::stable_sort(units.begin(), units.end(), sortByProfession); + } else { + std::stable_sort(units.begin(), units.end(), sortByGoal); } break; case ALTSORT_STRESS: @@ -1777,9 +1813,11 @@ void viewscreen_unitlaborsst::feed(set *events) if (detail_mode == DETAIL_MODE_SQUAD) { detail_mode = DETAIL_MODE_JOB; } else if (detail_mode == DETAIL_MODE_JOB) { - detail_mode = DETAIL_MODE_PROFESSION; - } else { + detail_mode = DETAIL_MODE_GOAL; + } else if (detail_mode == DETAIL_MODE_PROFESSION) { detail_mode = DETAIL_MODE_SQUAD; + } else { + detail_mode = DETAIL_MODE_PROFESSION; } } @@ -1888,8 +1926,10 @@ void viewscreen_unitlaborsst::render() detail_str = "Squad"; } else if (detail_mode == DETAIL_MODE_JOB) { detail_str = "Job"; - } else { + } else if (detail_mode == DETAIL_MODE_PROFESSION) { detail_str = "Profession"; + } else { + detail_str = "Goal"; } Screen::paintString(Screen::Pen(' ', 7, 0), col_offsets[DISP_COLUMN_DETAIL], 2, detail_str); @@ -1978,9 +2018,32 @@ void viewscreen_unitlaborsst::render() } else { fg = COLOR_LIGHTCYAN; } - } else { + } else if (detail_mode == DETAIL_MODE_PROFESSION) { fg = cur->color; detail_str = cur->profession; + } else { + if (cur->goal_gender == UnitInfo::NEUTRAL) { + if (cur->achieved_goal) { + fg = COLOR_LIGHTGREEN; + } else { + fg = COLOR_BROWN; + } + } else if (cur->goal_gender == UnitInfo::FEMALE) { + if (cur->achieved_goal) { + fg = COLOR_LIGHTRED; + } + else { + fg = COLOR_MAGENTA; + } + } else { + if (cur->achieved_goal) { + fg = COLOR_LIGHTCYAN; + } + else { + fg = COLOR_BLUE; + } + } + detail_str = cur->goal; } detail_str.resize(col_widths[DISP_COLUMN_DETAIL]); Screen::paintString(Screen::Pen(' ', fg, bg), col_offsets[DISP_COLUMN_DETAIL], 4 + row, detail_str); @@ -2140,8 +2203,10 @@ void viewscreen_unitlaborsst::render() OutputString(15, x, y, "Squad"); } else if (detail_mode == DETAIL_MODE_JOB) { OutputString(15, x, y, "Job"); - } else { + } else if (detail_mode == DETAIL_MODE_PROFESSION){ OutputString(15, x, y, "Profession"); + } else { + OutputString(15, x, y, "Goal"); } break; case ALTSORT_STRESS: From 2b26117685dbcab50106a46b6a05e71f4f338ff4 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Wed, 5 Aug 2020 15:44:00 -0700 Subject: [PATCH 240/547] update quickfort docs and configs --- data/blueprints/README.md | 15 + data/blueprints/README.txt | 14 - data/quickfort/aliases-common.txt | 497 ++++++++++++++++++++------ dfhack-config/quickfort/aliases.txt | 97 +++-- dfhack-config/quickfort/quickfort.txt | 26 +- 5 files changed, 501 insertions(+), 148 deletions(-) create mode 100644 data/blueprints/README.md delete mode 100644 data/blueprints/README.txt diff --git a/data/blueprints/README.md b/data/blueprints/README.md new file mode 100644 index 000000000..d81f0e3b4 --- /dev/null +++ b/data/blueprints/README.md @@ -0,0 +1,15 @@ +This directory is for quickfort blueprints. You can apply them to your fortress +map with the DFHack +[quickfort script](https://docs.dfhack.org/en/stable/docs/_auto/base.html#quickfort). + +You can create blueprints by hand or by using any spreadsheet application, +saving them as .xlsx or .csv files. You can also build your plan "for real" in +Dwarf Fortress, and then export your map using the DFHack +[blueprint plugin](https://docs.dfhack.org/en/stable/docs/Plugins.html#blueprint) +for later replay in a different fort. + +DFHack blueprints are compatible with the original Quickfort 2.0 syntax. If you +have existing blueprints that worked with https://github.com/joelpt/quickfort, +then they should work just fine in DFHack quickfort. + +There are many ready-to-use examples of blueprints in the library subfolder. diff --git a/data/blueprints/README.txt b/data/blueprints/README.txt deleted file mode 100644 index 2096476c5..000000000 --- a/data/blueprints/README.txt +++ /dev/null @@ -1,14 +0,0 @@ -This directory is for quickfort blueprints. You can apply them to your fortress -map with the DFHack quickfort plugin. See -https://docs.dfhack.org/en/stable/docs/Scripts.html#quickfort for details. - -You can create blueprints by hand or by using any spreadsheet application, -saving them as .xlsx or .csv files. You can also build your plan "for real" in -Dwarf Fortress, and then export your map using the DFHack blueprint for later -replay in a different fort. See -https://docs.dfhack.org/en/stable/docs/Plugins.html#blueprint for more info. - -DFHack blueprints follow the original Quickfort 2.0 syntax. See -https://github.com/joelpt/quickfort for joelpt's excellent documentation. - -There are many ready-to-use examples of blueprints in the library subfolder. diff --git a/data/quickfort/aliases-common.txt b/data/quickfort/aliases-common.txt index b4e19c782..09bb7e3f0 100644 --- a/data/quickfort/aliases-common.txt +++ b/data/quickfort/aliases-common.txt @@ -1,135 +1,428 @@ -# quickfort aliases common baseline configuration file +# Common baseline for aliases for quickfort query mode blueprints. # -# Defines custom keycode shortcuts for blueprints. Please DO NOT EDIT this file -# directly. Instead, custom aliases should be added to -# dfhack-config/quickfort/aliases.txt. +# Please DO NOT EDIT this file directly. Instead, custom aliases should be added +# to dfhack-config/quickfort/aliases.txt. See that file for syntax +# documentation. # -# Syntax: -# aliasname: keystrokes -# -# Special keys: -# {Right}, {Left}, {Up}, {Down}, >, < move the DF cursor -# {/}, {*}, {+}, {-} can be used to navigate some DF menus -# {Enter}, +{Enter}, {ExitMenu} - Enter, Shift+Enter, and Escape, respectively -# {Wait} pauses playback briefly -# -# Special keys can be repeated by adding a number inside the curly braces, for -# example: {Down 5} +# The aliases in this file were tested in DF 0.47.04 on 2020 Jul 18. # -# Some shorthand: -# & expands to {Enter} -# @ expands to +{Enter} -# ^ expands to {ExitMenu} -# % expands to {Wait} +# The aliases are generally split into three categories: +# 1) The aliases that name a type disables everything else for that stockpile +# category and enable only that type. For example, "preparedfood" enables +# prepared food and disables all other types of food. +# 2) The aliases that start with "forbid" only forbid (or toggle) the named type +# and leave the rest of the stockpile untouched. +# 3) The aliases that start with "permit" only permit (or toggle) the named type +# and leave the rest of the stockpile untouched. # -# The aliases in this file were tested in DF 0.47.04 on 2020 Jul 18. +# Aliases that don't fit into those two categories have comments explaining +# their usage. + + +######################################## +# general purpose stockpile adjustments +######################################## + +linksonly: a +nocontainers: CE + +# for configuring stockpiles to give to other nearby stockpiles/workshops +give2up: g{Up 2}& +give2down: g{Down 2}& +give2left: g{Left 2}& +give2right: g{Right 2}& +give10up: g{Up 10}& +give10down: g{Down 10}& +give10left: g{Left 10}& +give10right: g{Right 10}& + +# use to toggle a sequence of stockpile options. for example: {togglesequence 5} +togglesequence: &{Down} +togglesequence2: &{Down 2} +enablesequence: e{Down} + +# Enables everything but corpses and refuse. Refuse is excluded since otherwise +# clothes and armor in this quantum stockpile will rot away. If you want bones +# in your quantum stockpile, apply this alias to a refuse stockpile (but don't +# put useful clothes or armor in there!) +quantum: {linksonly}{nocontainers}{enableanimals}{enablefood}{furnitureprefix}{enablestone}{enableammo}{enablecoins}{enablebars}{enablegems}{enablefinishedgoods}{enableleather}{enablecloth}{enablewood}}{enableweapons}{enablearmor}{enablesheet} + +# Run one of the quantumstopfrom* aliases over a track stop that is set to dump +# into a quantum stockpile. The alias will set up the stop to accept all types +# (the actual types stored in the quantum stockpile is controlled by the feeder +# stockpile) and link the indicated adjacent feeder stockpile. All you need to +# do afterwards is assign a vehicle to the stop (and optionally give the route a +# name). The track stop does not need to be constructed yet, but the stockpile +# needs to be in place so we can link to it. +quantumstopprefix: ^hrs&xxx&{enablesequence 17}^ +quantumstopfromeast: {quantumstopprefix}s{Right}p^{Left}^q +quantumstopfromsouth: {quantumstopprefix}s{Down}p^{Up}^q +quantumstopfromwest: {quantumstopprefix}s{Left}p^{Right}^q +quantumstopfromnorth: {quantumstopprefix}s{Up}p^{Down}^q + + +################################## +# animal stockpile adjustments +################################## + +animalsprefix: s +enableanimals: {animalsprefix}e^ +disableanimals: {animalsprefix}d^ + +# enables only the specified type (and disables everything else) +cages: {animalsprefix}bu^ +traps: {animalsprefix}bj^ + +# forbids specific items in an already-configured stockpile +forbidcages: {animalsprefix}u^ +forbidtraps: {animalsprefix}j^ + ################################## # food stockpile adjustments ################################## -seeds: s{Down}deb{Right}{Down 9}p^ -noseeds: s{Down}dea{Right}{Down 9}f^ -booze: s{Down}deb{Right}{Down 5}p{Down}p^ -food: s{Down}dea{Right}{Down 5}f{Down}f{Down 3}f^ -plants: s{Down}deb{Right}{Down 4}p^ +foodprefix: s{Down} +enablefood: {foodprefix}e^ +disablefood: {foodprefix}d^ + +preparedfood: {foodprefix}bu^ +unpreparedfish: {foodprefix}b{Right}{Down 2}p^ +plants: {foodprefix}b{Right}{Down 4}p^ +booze: {foodprefix}b{Right}{Down 5}p{Down}p^ +seeds: {foodprefix}b{Right}{Down 9}p^ +dye: {foodprefix}b{Right}{Down 11}{Right}{Down 28}{togglesequence 4}^ +tallow: {foodprefix}b{Right}{Down 13}{Right}{Down}{togglesequence2 811}^ +miscliquid: {foodprefix}b{Right}{Down 18}p^ + +forbidpreparedfood: {foodprefix}u^ +forbidunpreparedfish: {foodprefix}{Right}{Down 2}f^ +forbidplants: {foodprefix}{Right}{Down 4}f^ +forbidbooze: {foodprefix}{Right}{Down 5}f{Down}f^ +forbidseeds: {foodprefix}{Right}{Down 9}f^ +forbiddye: {foodprefix}{Right}{Down 11}{Right}{Down 28}{togglesequence 4}^ +forbidtallow: {foodprefix}{Right}{Down 13}{Right}{Down}{togglesequence2 811}^ +forbidmiscliquid: {foodprefix}{Right}{Down 18}f^ + +permitpreparedfood: {forbidpreparedfood} +permitunpreparedfish: {foodprefix}{Right}{Down 2}p^ +permitplants: {foodprefix}{Right}{Down 4}p^ +permitbooze: {foodprefix}{Right}{Down 5}p{Down}p^ +permitseeds: {foodprefix}{Right}{Down 9}p^ +permitdye: {forbiddye} +permittallow: {forbidtallow} +permitmiscliquid: {foodprefix}{Right}{Down 18}p^ + +# enables everything but seeds +noseeds: {disablefood}{enablefood}{forbidseeds} + +# enables all food except for the types listed above +food: {noseeds}{forbidpreparedfood}{forbidunpreparedfish}{forbidplants}{forbidbooze}{forbiddye}{forbidtallow}{forbidmiscliquid} + ################################## -# refuse stockpile adjustments +# furniture stockpile adjustments ################################## -corpses: s{Down 4}deb{Right 2}&{Down 2}&{Left}{Down}p{Down}p^ -bones: s{Down 4}deb{Right}{Down 3}p{Down}p^ -rawhides: s{Down 4}deb{Right 2}{Down}&^ -tannedhides: s{Down 4}deb{Right 2}{Down 53}&^ +furnitureprefix: s{Down 2} +enablefurniture: {furnitureprefix}e^ +disablefurniture: {furnitureprefix}d^ + +pots: {furnitureprefix}de{Right}f{Right}{Up 5}&^ +bags: {furnitureprefix}de{Right}f{Right}{Up 10}&{Left}{Down}f{Down}f{Down}f{Right}{Down}&{Down 6}&{Down}&{Down 6}&^ +buckets: {furnitureprefix}de{Right}f{Right}{Up 12}&^ +sand: {furnitureprefix}de{Right}f{Right}{Up}&^ + + +########################################### +# corpses and refuse stockpile adjustments +########################################### + +corpsesprefix: s{Down 3} +enablecorpses: {corpsesprefix}e^ +disablecorpses: {corpsesprefix}d{Up}d^ + +refuseprefix: s{Down 4} +enablerefuse: {refuseprefix}e^ +disablerefuse: {refuseprefix}d^ + +# bodyparts include remains/corpses and rotten rawhdes +bodyparts: {refuseprefix}b{Right 2}&{Down 2}&{Left}{Down}p{Down}p^ +rawhides: {refuseprefix}b{Right 2}{Down}&^ +tannedhides: {refuseprefix}b{Right 2}{Down 53}&^ +skulls: {refuseprefix}b{Right}{Down 3}p^ +bones: {refuseprefix}b{Right}{Down 4}p^ +shells: {refuseprefix}b{Right}{Down 5}p^ +teeth: {refuseprefix}b{Right}{Down 6}p^ +horns: {refuseprefix}b{Right}{Down 7}p^ +hair: {refuseprefix}b{Right}{Down 8}p^ +craftrefuse: {skulls}{permitbones}{permitshells}{permitteeth}{permithorns}{permithair} + +forbidbodyparts: {refuseprefix}{Right 2}&{Down 2}&{Left}{Down}f{Down}f^ +forbidrawhides: {refuseprefix}{Right 2}{Down}&^ +forbidtannedhides: {refuseprefix}{Right 2}{Down 53}&^ +forbidskulls: {refuseprefix}{Right}{Down 3}f^ +forbidbones: {refuseprefix}{Right}{Down 4}f^ +forbidshells: {refuseprefix}{Right}{Down 5}f^ +forbidteeth: {refuseprefix}{Right}{Down 6}f^ +forbidhorns: {refuseprefix}{Right}{Down 7}f^ +forbidhair: {refuseprefix}{Right}{Down 8}f^ +forbidcraftrefuse: {forbidskulls}{forbidbones}{forbidshells}{forbidteeth}{forbidhorns}{forbidhair} + +permitbodyparts: {refuseprefix}{Right 2}&{Down 2}&{Left}{Down}p{Down}p^ +permitrawhides: {forbidrawhides} +permittannedhides: {forbidtannedhides} +permitskulls: {refuseprefix}{Right}{Down 3}p^ +permitbones: {refuseprefix}{Right}{Down 4}p^ +permitshells: {refuseprefix}{Right}{Down 5}p^ +permitteeth: {refuseprefix}{Right}{Down 6}p^ +permithorns: {refuseprefix}{Right}{Down 7}p^ +permithair: {refuseprefix}{Right}{Down 8}p^ +permitcraftrefuse: {permitskulls}{permitbones}{permitshells}{permitteeth}{permithorns}{permithair} + ################################## # stone stockpile adjustments ################################## -metal: s{Down 5}deb{Right}p^ -nometal: s{Down 5}dea{Right}f^ -bauxite: s{Down 5}deb{Right}{Down 2}{Right}{Down 42}&^ +stoneprefix: s{Down 5} +enablestone: {stoneprefix}e^ +disablestone: {stoneprefix}d^ + +metal: {stoneprefix}b{Right}p^ +iron: {stoneprefix}b{Right}{Right}&{Down}&{Down 13}&^ +economic: {stoneprefix}b{Right}{Down}p^ +flux: {stoneprefix}b{Right}{Down}{Right}{togglesequence 4}{Down 4}&^ +plaster: {stoneprefix}b{Right}{Down}{Right}{Down 6}&{Down 3}{togglesequence 3}^ +coalproducing: {stoneprefix}b{Right}{Down}{Right}{Down 4}{togglesequence 2}^ +otherstone: {stoneprefix}b{Right}{Down 2}p^ +bauxite: {stoneprefix}b{Right}{Down 2}{Right}{Down 42}&^ +clay: {stoneprefix}b{Right}{Down 3}p^ + +forbidmetal: {stoneprefix}{Right}f^ +forbidiron: {stoneprefix}{Right}{Right}&{Down}&{Down 13}&^ +forbideconomic: {stoneprefix}{Right}{Down}f^ +forbidflux: {stoneprefix}{Right}{Down}{Right}{togglesequence 4}{Down 4}&^ +forbidplaster: {stoneprefix}{Right}{Down}{Right}{Down 6}&{Down 3}{togglesequence 3}^ +forbidcoalproducing: {stoneprefix}{Right}{Down}{Right}{Down 4}{togglesequence 2}^ +forbidotherstone: {stoneprefix}{Right}{Down 2}f^ +forbidbauxite: {stoneprefix}{Right}{Down 2}{Right}{Down 42}&^ +forbidclay: {stoneprefix}{Right}{Down 3}f^ + +permitmetal: {stoneprefix}{Right}p^ +permitiron: {forbidiron} +permiteconomic: {stoneprefix}{Right}{Down}p^ +permitflux: {forbidflux} +permitplaster: {forbidplaster} +permitcoalproducing: {forbidcoalproducing} +permitotherstone: {stoneprefix}{Right}{Down 2}p^ +permitbauxite: {forbidbauxite} +permitclay: {stoneprefix}{Right}{Down 3}p^ + + +################################## +# ammo stockpile adjustments +################################## + +ammoprefix: s{Down 6} +enableammo: {ammoprefix}e^ +disableammo: {ammoprefix}d^ + +bolts: {ammoprefix}a{Right 2}{Down}{togglesequence 2}^ + +forbidmetalbolts: {ammoprefix}{Right}{Down}f^ +forbidwoodenbolts: {ammoprefix}{Right}{Down 2}{Right}&^ +forbidbonebolts: {ammoprefix}{Right}{Down 2}{Right}{Down}&^ + + +################################## +# bar stockpile adjustments +################################## + +barsprefix: s{Down 8} +enablebars: {barsprefix}e^ +disablebars: {barsprefix}d^ + +bars: {barsprefix}b{Right}p{Down}p^ +metalbars: {barsprefix}b{Right}p^ +ironbars: {barsprefix}b{Right 2}&^ +steelbars: {barsprefix}b{Right 2}{Down 8}&^ +pigironbars: {barsprefix}b{Right 2}{Down 9}&^ +otherbars: {barsprefix}b{Right}{Down}p^ +coal: {barsprefix}b{Right}{Down}{Right}&^ +potash: {barsprefix}b{Right}{Down}{Right}{Down}&^ +ash: {barsprefix}b{Right}{Down}{Right}{Down 2}&^ +pearlash: {barsprefix}b{Right}{Down}{Right}{Down 3}&^ +soap: {barsprefix}b{Right}{Down}{Right}{Down 4}&^ +blocks: {barsprefix}b{Down 2}p{Down}p{Down}p^ + +forbidbars: {barsprefix}{Right}f{Down}f^ +forbidmetalbars: {barsprefix}{Right}f^ +forbidironbars: {barsprefix}{Right 2}&^ +forbidsteelbars: {barsprefix}{Right 2}{Down 8}&^ +forbidpigironbars: {barsprefix}{Right 2}{Down 9}&^ +forbidotherbars: {barsprefix}{Right}{Down}f^ +forbidcoal: {barsprefix}{Right}{Down}{Right}&^ +forbidpotash: {barsprefix}{Right}{Down}{Right}{Down}&^ +forbidash: {barsprefix}{Right}{Down}{Right}{Down 2}&^ +forbidpearlash: {barsprefix}{Right}{Down}{Right}{Down 3}&^ +forbidsoap: {barsprefix}{Right}{Down}{Right}{Down 4}&^ +forbidblocks: {barsprefix}{Down 2}f{Down}f{Down}f^ + + +################################## +# gem stockpile adjustments +################################## + +gemsprefix: s{Down 9} +enablegems: {gemsprefix}e^ +disablegems: {gemsprefix}d^ + +roughgems: {gemsprefix}b{Right}p^ +roughglass: {gemsprefix}b{Right}{Down}p^ +cutgems: {gemsprefix}b{Right}{Down 2}p^ +cutglass: {gemsprefix}b{Right}{Down 3}p^ +cutstone: {gemsprefix}b{Right}{Down 4}p^ + +forbidroughgems: {gemsprefix}{Right}f^ +forbidroughglass: {gemsprefix}{Right}{Down}f^ +forbidcutgems: {gemsprefix}{Right}{Down 2}f^ +forbidcutglass: {gemsprefix}{Right}{Down 3}f^ +forbidcutstone: {gemsprefix}{Right}{Down 4}f^ + + +####################################### +# finished goods stockpile adjustments +####################################### + +finishedgoodsprefix: s{Down 10} +enablefinishedgoods: {finishedgoodsprefix}e^ +disablefinishedgoods: {finishedgoodsprefix}d^ + +jugs: {finishedgoodsprefix}{Right}f{Right}{Up 2}&{Left}{Down 2}f{Down}f{Down}f^ -# Only use nobauxite on stone piles that you want to accept all "Other Stone" on. -# This alias works by permitting all "Other Stone",then forbidding just bauxite. -# Thus you wouldn't want to use this on a metal-only pile, for example. -nobauxite: s{Down 5}{Right}{Down 2}p{Right}{Down 42}&^ ################################## -# misc stockpile adjustments +# cloth ################################## -# Artifacts-only stockpile, usable on any type of existing pile. -artifacts: sd{Down}d{Down}d{Down}d{Down}d{Down}d{Down}d{Down}d{Down}d{Down}d{Down}d{Down}d{Down}d{Down}d{Down}d{Down}d{Down 4}deu{Right}{Up}f{Right}{Up}&{Left 2}{Down 4}e{Right}{Up}f{Right}{Up}&{Left 2}{Down 4}e{Right}{Up}f{Right}{Up}&{Left 2}{Down 4}e{Right}{Up}f{Right}{Up}&{Left 2}{Down}e{Right}{Up}f{Right}{Up}&{Left 2}^ +clothprefix: s{Down 12} +enablecloth: {clothprefix}e^ +disablecloth: {clothprefix}d^ -# Bans artifacts on any pile (or rather, allows items of any quality except Artifact quality). -# This should be safe to run on any type of pile. -noartifacts: sd{Down 2}{Right}{Up}fp{Right}{Up}&{Down 2}{Left 2}{Down 4}{Right}{Up}fp{Right}{Up}&{Down 2}{Left 2}{Down 4}{Right}{Up}fp{Right}{Up}&{Down 2}{Left 2}{Down 4}{Right}{Up}fp{Right}{Up}&{Down 2}{Left 2}{Down}{Right}{Up}fp{Right}{Up}&{Down 2}{Left 2}^ +thread: {clothprefix}b{Right}p{Down}p{Down}p^ +adamantinethread: {clothprefix}b{Right}{Down 3}p^ +cloth: {clothprefix}b{Right}{Down 4}p{Down}p{Down}p^ +adamantinecloth: {clothprefix}b{Right}{Up}p^ + + +################################## +# weapon stockpile adjustments +################################## + +weaponsprefix: s{Down 14} +enableweapons: {weaponsprefix}e^ +disableweapons: {weaponsprefix}d^ + +metalweapons: {forbidtrapcomponents}{forbidstoneweapons}{forbidotherweapons} +ironweapons: {metalweapons}{forbidweapons}{permitironweapons} +copperweapons: {metalweapons}{forbidweapons}{permitcopperweapons} +steelweapons: {metalweapons}{forbidweapons}{permitsteelweapons} + +forbidweapons: {weaponsprefix}{Right}f^ +forbidtrapcomponents: {weaponsprefix}{Right}{Down}f^ +forbidmetalweapons: {weaponsprefix}{Right}{Down 2}f^ +forbidstoneweapons: {weaponsprefix}{Right}{Down 3}f^ +forbidotherweapons: {weaponsprefix}{Right}{Down 4}f^ +forbidironweapons: {weaponsprefix}{Right}{Down 2}{Right}&^ +forbidcopperweapons: {weaponsprefix}{Right}{Down 2}{Right}{Down 3}&^ +forbidsteelweapons: {weaponsprefix}{Right}{Down 2}{Right}{Down 8}&^ + +permitweapons: {weaponsprefix}{Right}p^ +permittrapcomponents: {weaponsprefix}{Right}{Down}p^ +permitmetalweapons: {weaponsprefix}{Right}{Down 2}p^ +permitstoneweapons: {weaponsprefix}{Right}{Down 3}p^ +permitotherweapons: {weaponsprefix}{Right}{Down 4}p^ +permitironweapons: {forbidironweapons} +permitcopperweapons: {forbidcopperweapons} +permitsteelweapons: {forbidsteelweapons} + +masterworkweapons: {weaponsprefix}{Right}{Down 5}f{Right}{Down 5}&^ +artifactweapons: {weaponsprefix}{Right}{Down 5}f{Right}{Down 6}&^ + +forbidmasterworkweapons: {weaponsprefix}{Right}{Down 5}{Right}{Down 5}&^ +forbidartifactweapons: {weaponsprefix}{Right}{Down 5}{Right}{Down 6}&^ + +permitmasterworkweapons: {forbidmasterworkweapons} +permitartifactweapons: {forbidartifactweapons} + + +################################## +# armor stockpile adjustments +################################## + +armorprefix: s{Down 15} +enablearmor: {armorprefix}e^ +disablearmor: {armorprefix}d^ + +metalarmor: {forbidotherarmor} +otherarmor: {forbidmetalarmor} +ironarmor: {metalarmor}{forbidmetalarmor}{permitironarmor} +copperarmor: {metalarmor}{forbidmetalarmor}{permitcopperarmor} +steelarmor: {metalarmor}{forbidmetalarmor}{permitsteelarmor} + +forbidmetalarmor: {armorprefix}{Right}{Down 6}f^ +forbidotherarmor: {armorprefix}{Right}{Down 7}f^ +forbidironarmor: {armorprefix}{Right}{Down 6}{Right}&^ +forbidcopperarmor: {armorprefix}{Right}{Down 6}{Right}{Down 3}&^ +forbidsteelarmor: {armorprefix}{Right}{Down 6}{Right}{Down 8}&^ + +permitmetalarmor: {armorprefix}{Right}{Down 6}p^ +permitotherarmor: {armorprefix}{Right}{Down 7}p^ +permitironarmor: {forbidironarmor} +permitcopperarmor: {forbidcopperarmor} +permitsteelarmor: {forbidsteelarmor} + +masterworkarmor: {armorprefix}{Right}{Down 8}f{Right}{Down 5}&^ +artifactarmor: {armorprefix}{Right}{Down 8}f{Right}{Down 6}&^ + +forbidmasterworkarmor: {armorprefix}{Right}{Down 8}{Right}{Down 5}&^ +forbidartifactarmor: {armorprefix}{Right}{Down 8}{Right}{Down 6}&^ + +permitmasterworkarmor: {forbidmasterworkarmor} +permitartifactarmor: {forbidartifactarmor} + + +################################## +# others +################################## + +coinsprefix: s{Down 7} +enablecoins: {coinsprefix}e^ +disablecoins: {coinsprefix}d^ + +leatherprefix: s{Down 11} +enableleather: {leatherprefix}e^ +disableleather: {leatherprefix}d^ + +woodprefix: s{Down 13} +enablewood: {woodprefix}e^ +disablewood: {woodprefix}d^ + +sheetprefix: s{Down 16} +enablesheet: {sheetprefix}e^ +disablesheet: {sheetprefix}d^ -# Set a finished goods stockpile to crappy low-quality trade goods only. -# Position such a stockpile near fort entrances to (hopefully) let thieves steal low quality junk. -junkgoods: s{Down 10}de{Right 2}&{Down 5}&{Down}&{Down}&{Down}&{Down 8}&{Down 2}&{Down}&{Down}&{Down}&{Down}&{Down}&{Left}{Down}f{Right}{Down}&{Down}&{Left}{Down}f{Down 2}f{Right}&{Down}&^ ################################## # farm plots ################################## -# Sets a farm plot to grow the LAST type of seed in the list of available seeds, for all 4 seasons. -# The last seed is used because it's usually Plump helmet spawn, suitable for post-embark. If you -# only have 1 seed type, that'll be grown. -growlastcropall: a{/}&b{/}&c{/}&d{/}& +# Sets a farm plot to grow the LAST type of seed in the list of available seeds +# for all 4 seasons. The last seed is used because it's usually Plump helmet +# spawn, suitable for post-embark. If you only have 1 seed type, that'll be +# grown. +growlastcropall: a/&b/&c/&d/& # Like growlastcropall but grows the first one in the list instead. growfirstcropall: a&b&c&d& - -################################## -# mining tracks -################################## - -# The following aliases make it more convenient to build the various types of mine tracks. -# For example, to build a north/south track 'Track (NS)', you would put trackNS in a cell(s). -trackN: CT{Enter} -trackS: CT{+ 1}{Enter} -trackE: CT{+ 2}{Enter} -trackW: CT{+ 3}{Enter} -trackNS: CT{+ 4}{Enter} -trackNE: CT{+ 5}{Enter} -trackNW: CT{+ 6}{Enter} -trackSE: CT{+ 7}{Enter} -trackSW: CT{+ 8}{Enter} -trackEW: CT{+ 9}{Enter} -trackNSE: CT{+ 10}{Enter} -trackNSW: CT{+ 11}{Enter} -trackNEW: CT{+ 12}{Enter} -trackSEW: CT{+ 13}{Enter} -trackNSEW: CT{+ 14}{Enter} -trackrampN: CT{+ 15}{Enter} -trackrampS: CT{+ 15}{+ 1}{Enter} -trackrampE: CT{+ 15}{+ 2}{Enter} -trackrampW: CT{+ 15}{+ 3}{Enter} -trackrampNS: CT{+ 15}{+ 4}{Enter} -trackrampNE: CT{+ 15}{+ 5}{Enter} -trackrampNW: CT{+ 15}{+ 6}{Enter} -trackrampSE: CT{+ 15}{+ 7}{Enter} -trackrampSW: CT{+ 15}{+ 8}{Enter} -trackrampEW: CT{+ 15}{+ 9}{Enter} -trackrampNSE: CT{+ 15}{+ 10}{Enter} -trackrampNSW: CT{+ 15}{+ 11}{Enter} -trackrampNEW: CT{+ 15}{+ 12}{Enter} -trackrampSEW: CT{+ 15}{+ 13}{Enter} -trackrampNSEW: CT{+ 15}{+ 14}{Enter} - -# Aliases for building track rollers; use e.g. rollerHqqq to make a low-speed horizontal roller -rollerH: Mrs -rollerV: Mr -rollerNS: Mr -rollerSN: Mrss -rollerEW: Mrs -rollerWE: Mrsss - -# Aliases for building track stops that dump in each of the four directions -trackstopN: CSd -trackstopS: CSdd -trackstopE: CSddd -trackstopW: CSdddd diff --git a/dfhack-config/quickfort/aliases.txt b/dfhack-config/quickfort/aliases.txt index 52cdb2893..05f2833f5 100644 --- a/dfhack-config/quickfort/aliases.txt +++ b/dfhack-config/quickfort/aliases.txt @@ -1,30 +1,83 @@ -# quickfort aliases configuration file +# aliases for quickfort query mode blueprints # -# Defines custom keycode shortcuts for blueprints. Definitions in this file take -# precedence over any definitions in the baseline aliases configuration file at -# hack/data/quickfort/aliases-common.txt. See that file for aliases that are -# already defined. +# This file defines custom keycode shortcuts for query mode blueprints. +# Definitions in this file take precedence over any definitions in the baseline +# aliases configuration file at hack/data/quickfort/aliases-common.txt. See that +# file for aliases that are already defined. # -# This file can be used to simplify repetitive tasks, such as building minecart -# tracks or adjusting a food stockpile to accept seeds only. Making new aliases -# is just a matter of mimicking the keys used to navigate through the menus and -# select options. +# If possible, build on the baseline aliases when defining your own aliases. If +# the DF UI screens change, updated baseline aliases may allow your aliases to +# automatically adapt to the new UI. For example, if you create an alias to +# modify particular furniture stockpile settings, start your alias with +# "{furnitureprefix}" instead of manually writing "s{Down 2}". Then, if the +# location of the furniture setting changes, your alias will automatically +# inherit the updated position when DFHack is updated. # -# Syntax: +# Aliases simplify repetitive tasks, such as configuring workshop profiles or +# adjusting a food stockpile to accept only seeds. Making new aliases is just a +# matter of mimicking the keys used to navigate through the menus and select +# options. Use the aliases in your blueprint spreadsheets by writing an alias by +# itself in a cell, like "nocontainers", or reference an alias in a larger +# sequence by enclosing in in curly brackets, like "{nocontainers}{linksonly}" +# +# For example, say you have the following build and place blueprints: +# +# #build start(4;1;upper left corner of stockpile) mason stockpile +# ~, ~, ~, `, `, ` +# ~, wm, ~, `, `, ` +# ~, ~, ~, `, `, ` +# +# #place start(4;1;upper left corner of stockpile) build mason +# ~, ~, ~, s, s, s +# ~, ~, ~, s, s, s +# ~, ~, ~, s, s, s +# +# and you want to configure the stockpile to hold only non-economic ("other") +# stone and to give to the adjacent mason workshop. You could write the +# keystrokes directly: +# +# #query start(4;1;upper left corner of stockpile) configure mason +# ~, ~, ~, s{Down 5}deb{Right}{Down 2}p^, `, ` +# ~, ~, ~, g{Left 2}&, `, ` +# ~, ~, ~, `, `, ` +# +# or you could use alias names: +# +# #query start(4;1;upper left corner of stockpile) configure mason +# ~, ~, ~, otherstone, `, ` +# ~, ~, ~, give2left, `, ` +# ~, ~, ~, `, `, ` +# +# +# The syntax for defining aliases is: # aliasname: keystrokes # -# Special keys: -# {Right}, {Left}, {Up}, {Down}, >, < move the DF cursor -# {/}, {*}, {+}, {-} can be used to navigate some DF menus -# {Enter}, +{Enter}, {ExitMenu} - Enter, Shift+Enter, and Escape, respectively -# {Wait} pauses playback briefly +# Where aliasname is at least two letters or digits long and keystrokes are +# whatever you would type into the DF UI. A keystroke can also be a named +# keycode from the DF interface definition file (data/init/interface.txt), +# enclosed in curly brackets like an alias, like: "{Right}" or "{Enter}". In +# order to avoid naming conflicts between aliases and keycodes, the convention +# is to start aliases with a lowercase letter. You can add spaces in between +# keystrokes to make them easier to read. Spaces in keystroke sequences will be +# ignored. To insert a literal space, use "{Space}" # -# Special keys can be repeated by adding a number inside the curly braces, for -# example: {Down 5} +# Anything enclosed within curly brackets can also have a number after it, +# indicating how many times that alias or keycode should be repeated. For +# example: "{buildblocks 9}" or "{Down 5}". # -# Some shorthand: +# Ctrl, Alt, and Shift modifiers can be specified for the next keycode by adding +# them as keycodes. For example, Alt-h is written as "{Alt}h". +# +# Some frequently-used keystrokes are assigned shorthand characters. Think of +# them as single-character aliases that don't need to be surrounded in curly +# brackets: # & expands to {Enter} -# @ expands to +{Enter} -# ^ expands to {ExitMenu} -# % expands to {Wait} - +# @ expands to {Shift}{Enter} +# + expands to {Shift} +# ~ expands to {Alt} +# ! expands to {Ctrl} +# ^ expands to {ESC} +# +# If you need literal verisons of the shorthand characters, surround them in +# curly brackets, for example: "{+}" +# diff --git a/dfhack-config/quickfort/quickfort.txt b/dfhack-config/quickfort/quickfort.txt index 683c1da7d..8a30124a1 100644 --- a/dfhack-config/quickfort/quickfort.txt +++ b/dfhack-config/quickfort/quickfort.txt @@ -1,20 +1,26 @@ # quickfort main configuration file # # Set startup defaults for the quickfort script in this file. Settings can be -# dynamically overridden in the active session with the `quickfort set` command. +# temporarily overridden in the active session with the `quickfort set` command. +# +# If you have edited this file but want to revert to "factory defaults", delete +# this file and a fresh one will be copied from +# dfhack-config/default/quickfort/qickfort.txt the next time you start DFHack. -# Directory to search for blueprints. Can be set to an absolute or relative +# Directory tree to search for blueprints. Can be set to an absolute or relative # path. If set to a relative path, resolves to a directory under the DF folder. blueprints_dir=blueprints # Set to "true" or "false". If true, will designate dig blueprints in marker -# mode. If false, only cells with dig codes prefixed with ``m`` will be -# designated in marker mode. +# mode. If false, only cells with dig codes explicitly prefixed with an "m" will +# be designated in marker mode. force_marker_mode=false -# Allows you to manually select building materials for each -# building/construction when running (or creating orders for) build blueprints. -# Materials in selection dialogs are ordered according to preferences in -# materials.txt. If false, will only prompt for materials that have :labels. -# See https://github.com/joelpt/quickfort#manual-material-selection for details. -force_interactive_build=false +# Set to the maximum number of resources you want assigned to stockpiles of the +# relevant types. Set to -1 for DF defaults (number of stockpile tiles for +# stockpiles that take barrels and bins, 1 wheelbarrow for stone stockpiles). +# The default here for wheelbarrows is 0 since using wheelbarrows normally +# *decreases* the efficiency of your fort. +stockpiles_max_barrels=-1 +stockpiles_max_bins=-1 +stockpiles_max_wheelbarrows=0 From 02c0a6c8f64bea5d823f3fc9f271fd25761c7d6c Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 6 Aug 2020 00:53:06 -0400 Subject: [PATCH 241/547] Update getplants to use new plant_raw.material_defs layout a9f219baf9dda6d8cc300251fc040420e84bbc49 applied to #1564 --- plugins/getplants.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/getplants.cpp b/plugins/getplants.cpp index 2f12029f6..cfe499a9b 100644 --- a/plugins/getplants.cpp +++ b/plugins/getplants.cpp @@ -264,7 +264,7 @@ bool picked(const df::plant *plant, int32_t growth_subtype) { bool designate(const df::plant *plant, bool farming) { df::plant_raw *plant_raw = world->raws.plants.all[plant->material]; - const DFHack::MaterialInfo basic_mat = DFHack::MaterialInfo(plant_raw->material_defs.type_basic_mat, plant_raw->material_defs.idx_basic_mat); + const DFHack::MaterialInfo basic_mat = DFHack::MaterialInfo(plant_raw->material_defs.type[plant_material_def::basic_mat], plant_raw->material_defs.idx[plant_material_def::basic_mat]); if (basic_mat.material->flags.is_set(material_flags::EDIBLE_RAW) || basic_mat.material->flags.is_set(material_flags::EDIBLE_COOKED)) @@ -309,8 +309,8 @@ bool designate(const df::plant *plant, bool farming) { { for (size_t k = 0; growth_mat.material->reaction_product.material.mat_type.size(); k++) { - if (growth_mat.material->reaction_product.material.mat_type[k] == plant_raw->material_defs.type_seed && - growth_mat.material->reaction_product.material.mat_index[k] == plant_raw->material_defs.idx_seed) + if (growth_mat.material->reaction_product.material.mat_type[k] == plant_raw->material_defs.type[plant_material_def::seed] && + growth_mat.material->reaction_product.material.mat_index[k] == plant_raw->material_defs.idx[plant_material_def::seed]) { seedSource = true; break; From 7c2af344a1e10f93c966da3b2a4a02a76544677e Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 6 Aug 2020 02:04:23 -0400 Subject: [PATCH 242/547] Update changelog (#1564) and xml (dfhack/df-structures#400) --- docs/changelog.txt | 1 + library/xml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index bf953d562..95d18693f 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: - Fixed a segfault when attempting to start a headless session with a graphical PRINT_MODE setting - Fixed an issue with the macOS launcher failing to un-quarantine some files - Linux: fixed ``dfhack.getDFPath()`` (Lua) and ``Process::getPath()`` (C++) to always return the DF root path, even if the working directory has changed +- `getplants`: fixed issues causing plants to be collected even if they have no growths (or unripe growths) - `labormanager`: fixed handling of new jobs in 0.47 - `embark-assistant`: fixed a couple of incursion handling bugs. - Fixed ``Units::isEggLayer``, ``Units::isGrazer``, ``Units::isMilkable``, ``Units::isTrainableHunting``, ``Units::isTrainableWar``, and ``Units::isTamable`` ignoring the unit's caste diff --git a/library/xml b/library/xml index ecd6bcc9e..9fca46ccc 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit ecd6bcc9ed67c62fa605561b27574467df792342 +Subproject commit 9fca46ccca28e0948014b9d56a096ad7343473f1 From bdb9433822685b519d26144be805acf0b74be75a Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 6 Aug 2020 02:30:17 -0400 Subject: [PATCH 243/547] Update/expand Contributing.rst regarding pull requests --- docs/Contributing.rst | 45 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/docs/Contributing.rst b/docs/Contributing.rst index ab92d0571..0619e8ba3 100644 --- a/docs/Contributing.rst +++ b/docs/Contributing.rst @@ -13,7 +13,7 @@ Contributing Code ================= Several things should be kept in mind when contributing code to DFHack. -Code Format +Code format ----------- * Four space indents for C++. Never use tabs for indentation in any language. * LF (Unix style) line terminators @@ -26,18 +26,45 @@ Code Format * #includes should be sorted. C++ libraries first, then dfhack modules, then df structures, then local includes. Within each category they should be sorted alphabetically. -How to get new code into DFHack +Pull request guidelines +----------------------- +* Pull requests should be based on (and submitted to) the default branch of the + relevant repo, which is the branch you see when you access the repo on GitHub + or clone the repo without specifying a branch. As of 0.47.04-r1, this is + ``develop`` for the main DFHack repo and ``master`` for other repos. +* Use a new branch for each feature or bugfix so that your changes can be merged + independently (i.e. not the ``master`` or ``develop`` branch of your fork). + + * An exception: for a collection of small miscellaneous changes (e.g. + structures research), one branch instead of many small branches is fine. It + is still preferred that this branch be dedicated to this purpose, i.e. not + ``master`` or ``develop``. Your pull request may be merged at any point + unless you indicate that it isn't ready (see below), but you can continue to + push to the same branch and open new pull requests as needed. + +* Try to keep pull requests relatively small so that they are easier to review + and merge. + + * If you expect to make a large number of related additions or changes (e.g. + adding a large new plugin), multiple PRs are preferred, as they allow more + frequent (and easier) feedback. If development of this feature is expected + to take a while, we may create a dedicated branch to merge your pull + requests into instead of the repo's default branch. + +* If you plan to make additional changes to your pull request in the near + future, or if it isn't quite ready to be merged, mark it as a + `draft pull request `_ + or add "WIP" to the title. Otherwise, your pull request may be reviewed and/or + merged prematurely. + +General contribution guidelines ------------------------------- -* Submit pull requests to the ``develop`` branch, not the ``master`` branch. - (The ``master`` branch always points at the most recent release) -* Use a new branch for each feature or bugfix so that your changes can be merged independently - (i.e. not the master or develop branch of your fork). -* If possible, compile on multiple platforms when changing anything that compiles -* It must pass CI - run ``python travis/all.py`` to check this. +* If convenient, compile on multiple platforms when changing anything that + compiles. Our CI should catch anything that fails to build, but checking in + advance can be faster. * Update documentation when applicable - see `docs-standards` for details. * Update ``changelog.txt`` and ``docs/Authors.rst`` when applicable. See `build-changelog` for more information on the changelog format. -* Create a GitHub pull request once finished * Submit ideas and bug reports as :issue:`issues on GitHub <>`. Posts in the forum thread can easily get missed or forgotten. * Work on :issue:`reported problems ` From 0c53b2b6c5e26899af7eaa1d7d6b44bf8672bed7 Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 6 Aug 2020 22:30:29 -0400 Subject: [PATCH 244/547] Add do-job-now tweak Forum thread: http://www.bay12forums.com/smf/index.php?topic=176700 Original source: https://github.com/dlmarquis/dfhack/blob/dojobnow-r1/plugins/dojobnow.cpp Co-authored-by: dlmarquis --- docs/Authors.rst | 1 + docs/Plugins.rst | 1 + docs/changelog.txt | 1 + plugins/tweak/tweak.cpp | 6 +++++ plugins/tweak/tweaks/do-job-now.h | 43 +++++++++++++++++++++++++++++++ 5 files changed, 52 insertions(+) create mode 100644 plugins/tweak/tweaks/do-job-now.h diff --git a/docs/Authors.rst b/docs/Authors.rst index 55ecbb17c..31789aa52 100644 --- a/docs/Authors.rst +++ b/docs/Authors.rst @@ -110,6 +110,7 @@ Nikolay Amiantov abbradar nocico nocico Omniclasm OwnageIsMagic OwnageIsMagic +palenerd dlmarquis Patrik Lundell PatrikLundell Paul Fenwick pjf PeridexisErrant PeridexisErrant diff --git a/docs/Plugins.rst b/docs/Plugins.rst index 3a4133873..120dae1d4 100644 --- a/docs/Plugins.rst +++ b/docs/Plugins.rst @@ -305,6 +305,7 @@ Subcommands that persist until disabled or DF quits: :craft-age-wear: Fixes the behavior of crafted items wearing out over time (:bug:`6003`). With this tweak, items made from cloth and leather will gain a level of wear every 20 years. +:do-job-now: Adds a job priority toggle to the jobs list :embark-profile-name: Allows the use of lowercase letters when saving embark profiles :eggs-fertile: Displays a fertility indicator on nestboxes :farm-plot-select: Adds "Select all" and "Deselect all" options to farm plot menus diff --git a/docs/changelog.txt b/docs/changelog.txt index 95d18693f..e7a01f4fe 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -34,6 +34,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: # Future ## New Tweaks +- `tweak` do-job-now: adds a job priority toggle to the jobs list - `tweak` reaction-gloves: adds an option to make reactions produce gloves in sets with correct handedness ## Fixes diff --git a/plugins/tweak/tweak.cpp b/plugins/tweak/tweak.cpp index 13e08f174..2c15c3903 100644 --- a/plugins/tweak/tweak.cpp +++ b/plugins/tweak/tweak.cpp @@ -86,6 +86,7 @@ #include "tweaks/civ-agreement-ui.h" #include "tweaks/condition-material.h" #include "tweaks/craft-age-wear.h" +#include "tweaks/do-job-now.h" #include "tweaks/eggs-fertile.h" #include "tweaks/embark-profile-name.h" #include "tweaks/farm-plot-select.h" @@ -200,6 +201,8 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector *input) { + if (input->count(interface_key::CUSTOM_N)) { + df::job *job = vector_get(jobs, cursor_pos); + if (job) { + job->flags.bits.do_now = !job->flags.bits.do_now; + } + + return true; + } + + return false; + } + + DEFINE_VMETHOD_INTERPOSE(void, feed, (std::set *input)) { + if (!handleInput(input)) { + INTERPOSE_NEXT(feed)(input); + } + } + + DEFINE_VMETHOD_INTERPOSE(void, render, ()) { + INTERPOSE_NEXT(render)(); + int x = 32; + auto dim = Screen::getWindowSize(); + int y = dim.y - 2; + bool do_now = false; + + df::job *job = vector_get(jobs, cursor_pos); + if (job) { + do_now = job->flags.bits.do_now; + } + + OutputHotkeyString(x, y, (!do_now ? "Do job now!" : "Normal priority"), + interface_key::CUSTOM_N, false, x, COLOR_WHITE, COLOR_LIGHTRED); + } +}; + +IMPLEMENT_VMETHOD_INTERPOSE(do_job_now_hook, feed); +IMPLEMENT_VMETHOD_INTERPOSE(do_job_now_hook, render); From c7e4c724e848696b4854010f2b20bcfb9ecb3756 Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 6 Aug 2020 22:34:39 -0400 Subject: [PATCH 245/547] Sort tweaks alphabetically --- docs/Plugins.rst | 6 +++++- plugins/tweak/tweak.cpp | 6 ++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/Plugins.rst b/docs/Plugins.rst index 120dae1d4..6699163c2 100644 --- a/docs/Plugins.rst +++ b/docs/Plugins.rst @@ -291,6 +291,8 @@ One-shot subcommands: Subcommands that persist until disabled or DF quits: +.. comment: sort these alphabetically + :adamantine-cloth-wear: Prevents adamantine clothing from wearing out while being worn (:bug:`6481`). :advmode-contained: Works around :bug:`6202`, custom reactions with container inputs in advmode. The issue is that the screen tries to force you to select @@ -336,12 +338,14 @@ Subcommands that persist until disabled or DF quits: i.e. stop the rightmost list of the Positions page of the military screen from constantly resetting to the top. :nestbox-color: Fixes the color of built nestboxes +:reaction-gloves: Fixes reactions to produce gloves in sets with correct handedness (:bug:`6273`) :shift-8-scroll: Gives Shift-8 (or :kbd:`*`) priority when scrolling menus, instead of scrolling the map :stable-cursor: Saves the exact cursor position between t/q/k/d/b/etc menus of fortress mode. :stone-status-all: Adds an option to toggle the economic status of all stones :title-start-rename: Adds a safe rename option to the title screen "Start Playing" menu :tradereq-pet-gender: Displays pet genders on the trade request screen -:reaction-gloves: Fixes reactions to produce gloves in sets with correct handedness (:bug:`6273`) + +.. comment: sort these alphabetically .. _fix-armory: diff --git a/plugins/tweak/tweak.cpp b/plugins/tweak/tweak.cpp index 2c15c3903..237014209 100644 --- a/plugins/tweak/tweak.cpp +++ b/plugins/tweak/tweak.cpp @@ -183,6 +183,7 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector Date: Thu, 6 Aug 2020 22:44:49 -0400 Subject: [PATCH 246/547] Use BUILDJOB_NOW key, dim text when no job is selected --- plugins/tweak/tweaks/do-job-now.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/tweak/tweaks/do-job-now.h b/plugins/tweak/tweaks/do-job-now.h index 74d4c36da..a498b1f8b 100644 --- a/plugins/tweak/tweaks/do-job-now.h +++ b/plugins/tweak/tweaks/do-job-now.h @@ -4,7 +4,7 @@ struct do_job_now_hook : public df::viewscreen_joblistst { typedef df::viewscreen_joblistst interpose_base; bool handleInput(std::set *input) { - if (input->count(interface_key::CUSTOM_N)) { + if (input->count(interface_key::BUILDJOB_NOW)) { df::job *job = vector_get(jobs, cursor_pos); if (job) { job->flags.bits.do_now = !job->flags.bits.do_now; @@ -34,8 +34,8 @@ struct do_job_now_hook : public df::viewscreen_joblistst { do_now = job->flags.bits.do_now; } - OutputHotkeyString(x, y, (!do_now ? "Do job now!" : "Normal priority"), - interface_key::CUSTOM_N, false, x, COLOR_WHITE, COLOR_LIGHTRED); + OutputHotkeyString(x, y, (!do_now ? "Do job now!" : "Reset priority"), + interface_key::BUILDJOB_NOW, false, x, job ? COLOR_WHITE : COLOR_DARKGREY, COLOR_LIGHTRED); } }; From 498fd9a1a67b2a609b912f911dd3848bb9ef4b00 Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 6 Aug 2020 22:45:46 -0400 Subject: [PATCH 247/547] Flush plugin warning messages --- library/PluginManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/PluginManager.cpp b/library/PluginManager.cpp index db42c5c84..a1b1bd293 100644 --- a/library/PluginManager.cpp +++ b/library/PluginManager.cpp @@ -316,8 +316,8 @@ bool Plugin::load(color_ostream &con) { std::string msg = stl_sprintf("Warning: Plugin %s compiled for DFHack %s, running DFHack %s\n", *plug_name, plug_git_desc, dfhack_git_desc); - con << msg; - cerr << msg; + con << msg << flush; + cerr << msg << flush; } } else From 939e97caa0021c6782d99a1763f8052764b17c2f Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 6 Aug 2020 22:46:21 -0400 Subject: [PATCH 248/547] Update scripts/list-agreements --- scripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts b/scripts index 70ce0a12b..823d47c4d 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 70ce0a12bc0eb14b3782abe7033a6d2dd31863fe +Subproject commit 823d47c4d181ac5b754dce5d605f3e7f242aed26 From 2302dfe3d62cc37d6ce7c815ad818ba5ca162ff8 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Thu, 6 Aug 2020 23:32:31 -0700 Subject: [PATCH 249/547] add quickfort user guide (first draft) Much of the text was reused (with permission) from Joel Thornton's Python Quickfort 2.0 user guide. --- data/blueprints/README.md | 458 +++++++++++++++++++++++++++++++++++++- 1 file changed, 446 insertions(+), 12 deletions(-) diff --git a/data/blueprints/README.md b/data/blueprints/README.md index d81f0e3b4..6f11df32a 100644 --- a/data/blueprints/README.md +++ b/data/blueprints/README.md @@ -1,15 +1,449 @@ -This directory is for quickfort blueprints. You can apply them to your fortress -map with the DFHack -[quickfort script](https://docs.dfhack.org/en/stable/docs/_auto/base.html#quickfort). -You can create blueprints by hand or by using any spreadsheet application, -saving them as .xlsx or .csv files. You can also build your plan "for real" in -Dwarf Fortress, and then export your map using the DFHack -[blueprint plugin](https://docs.dfhack.org/en/stable/docs/Plugins.html#blueprint) -for later replay in a different fort. +[//]: # (The online version of this manual, which may be easier to read, is) +[//]: # (at https://github.com/DFHack/dfhack/tree/develop/data/blueprints) -DFHack blueprints are compatible with the original Quickfort 2.0 syntax. If you -have existing blueprints that worked with https://github.com/joelpt/quickfort, -then they should work just fine in DFHack quickfort. +[//]: # (Note to editors: don't word wrap -- it breaks the formatting on GitHub) -There are many ready-to-use examples of blueprints in the library subfolder. +DFHack Quickfort User Manual +============================ + +DFHack Quickfort is a DFHack script that helps you build fortresses from "blueprint" .csv and .xlsx files. Many applications exist to edit these files, such as MS Excel and [Google Sheets](https://sheets.new). You can also build your plan "for real" in Dwarf Fortress, and then export your map using DFHack's [blueprint](https://docs.dfhack.org/en/stable/docs/Plugins.html#blueprint) plugin. Most layout and building-oriented DF commands are supported through the use of multiple files or spreadsheets, each describing a different phase of DF construction: designation, building, placing stockpiles, and setting configuration. + +The original idea and 1.0 codebase came from [Valdemar's](https://dwarffortresswiki.org/index.php/User:Valdemar) auto-designation macro. Joel Thornton (joelpt) reimplemented the core logic in Python and extended its functionality with [Quickfort 2.0](https://github.com/joelpt/quickfort). This DFHack-native implementation, called "DFHack Quickfort" or just "quickfort", builds upon Quickfort 2.0's formats and features. DFHack Quickfort is written in Lua and interacts with Dwarf Fortress memory structures directly, allowing for instantaneous blueprint application, error checking and recovery, and many other advanced features. + +This document focuses on DFHack Quickfort's capabilities and teaches players how to understand and build blueprint files. Much of the text was originally written by Joel Thornton, reused here with his permission. + +For those just looking to apply blueprints, check out the [quickfort command syntax](https://docs.dfhack.org/en/stable/docs/_auto/base.html#quickfort) in the DFHack Scripts documentation. There are many ready-to-use blueprints available in the `blueprints/library` subfolder in your DFHack installation. Browse them on your computer or [online](https://github.com/DFHack/dfhack/tree/develop/data/blueprints/library), or run `quickfort list -l` at the `DFHack#` prompt to list them, and then `quickfort run` to apply them to your fort! + +See the [Links section](#links) for more information and online resources. + + +Table of Contents +----------------- + +* [Features](#features) +* [Editing Blueprints](#editing-blueprints) + * [Area expansion syntax](#area-expansion-syntax) + * [Automatic area expansion](#automatic-area-expansion) + * [Specifying a starting position](#specifying-a-starting-position) + * [Multilevel blueprints](#multilevel-blueprints) + * [Minecart tracks](#minecart-tracks) +* [Packaging a set of blueprints](#packaging-a-set-of-blueprints) +* [Troubleshooting](#troubleshooting) +* [Tips and tricks](#tips-and-tricks) +* [Links](#links) + + +Features +-------- + +* General + * Manages complete blueprints to handle the four main phases of DF construction + * Supports .csv and multi-worksheet .xlsx blueprint files + * Near-instant application, even for very large and complex blueprints + * Blueprints can span multiple z-levels + * Undo functionality for dig, build, and place blueprints + * Automatic cropping of blueprints so you don't get errors if the blueprint extends off the map + * Can generate manager orders for everything required to apply build blueprints + * Library of ready-to-use blueprints included + * Verbose output mode for debugging blueprints +* Dig mode + * Supports all types of designations, including dumping/forbidding items and setting traffic areas + * Supports applying dig blueprints in marker mode + * Handles carving arbitrarily complex minecart tracks, including tracks that cross other tracks +* Build and place modes + * Supports stockpiles of all shapes, not just rectangular blocks + * Configurable maximums for bins, barrels and wheelbarrows assigned to created stockpiles + * Automatic expansion of building footprints to their minimum dimensions, so only the center tile of a multi-tile building needs to be recorded in the blueprint + * Designates complete constructions at once, without having to wait for each tile to become supported before you can build it + * Automatic splitting of stockpiles and buildings that exceed maximum dimension limits + * Tile occupancy and validity checking so, for example, buildings that cannot be placed on a certain tile will simply be skipped instead of the blueprint failing to apply. Blueprints that are only partially applied for any reason (for example, you need to dig out some more tiles) can be safely reapplied to build the remaining buildings. + * Relaxed rules for farm plot and road placement, allowing tiles that are separated by invalid tiles (e.g. stone tiles for farm plots) to be part of the same structure +* Query mode + * Support sending arbitrary keystroke sequences to the UI -- configure *anything* + * Supports aliases to automate frequent keystroke combos + * Supports including aliases in other aliases, and repeating key sequences a specified number of times + * Includes a library of pre-made and tested aliases to automate most common tasks, such as configuring stockpiles for important item types or creating hauling routes for quantum stockpiles. + * Skips sending key sequences when the cursor is over a tile that does not have a stockpile or building + * Instant halting of query blueprint application when keystroke errors are detected, such as when a key sequence leaves us stuck in a submenu + + +Editing Blueprints +------------------ + +The format of Quickfort-compatible blueprint files is straightforward. + +It is recommended to use a spreadsheet editor such as Excel, [Google Sheets](https://sheets.new), or [LibreOffice](https://www.libreoffice.org) to edit these files, but any text editor will do. + +The first line (or upper-left cell) of the spreadsheet should look like this: + + #dig This is a decription. + +The keyword "dig" tells Quickfort we are going to be using the Designations menu in DF. The following "mode" keywords are understood: + + dig Designations menu (d) + build Build menu (b) + place Place stockpiles menu (p) + query Set building tasks/prefs menu (q) + +Optionally following this keyword and a space, you may enter a comment. This comment will appear in the output of `quickfort list` when run from the `DFHack#` prompt. You can use this space for explanations, attribution, etc. + +Below this line begin entering the keys you want sent in each cell. For example, we could dig out a 4x4 room like so (spaces are used as column separators here for clarity, but a real .csv file would have commas): + + #dig + d d d d # + d d d d # + d d d d # + d d d d # + # # # # # + +Note the # symbols at the right end of each row and below the last row. These are completely optional, but can be helpful when visualizing the layout. + +Once the dwarves have that dug out, let's build a walled-in bedroom within our dug-out area: + + #build + Cw Cw Cw Cw # + Cw b h Cw # + Cw Cw # + Cw Cw Cw # + # # # # # + +Note my generosity - in addition to the bed (b) I've built a chest (h) here for the dwarf as well. Note that you must use the full series of keys needed to build something in each cell, e.g. 'Cw' enters DF's constructions submenu (C) and selects walls (w). + +I'd also like to place a booze stockpile in the 2 unoccupied tiles in the room. + + #place Place a food stockpile + ` ` ` ` # + ` ` ` ` # + ` f(2x1)# + ` ` ` ` # + # # # # # + +This illustration may be a little hard to understand. The f(2x1) is in column 2, row 3. All the other cells are empty. QF considers both "`" (backtick -- the character under the tilde) and "~" (tilde) characters within cells to be empty cells; this can help with multilayer or fortress-wide blueprint layouts as 'chalk lines'. + +With f(2x1), we've asked QF to place a food stockpile 2 units wide by 1 high unit. Note that the f(2x1) syntax isn't actually necessary here; we could have just used: + + #place Place a food stockpile + ` ` ` ` # + ` ` ` ` # + ` f f ` # + ` ` ` ` # + # # # # # + +QF is smart enough to recognize this as a 2x1 food stockpile, and creates it as such rather than as two 1x1 food stockpiles. Quickfort recognizes any connected region of identical designations as a single stockpile. The tiles can be connected orthogonally or diagonally, just as long as they are touching somehow. + +Lastly, let's turn the bed into a bedroom and set the food stockpile to hold only booze. + + #query + ` ` ` ` # + ` r& ` # + ` booze # + ` ` ` ` # + # # # # # + +In column 2, row 2 we have "r&". This sends the "r" key to DF when the cursor is over the bed, causing us to 'make room' and "&", which is a special symbol that expands to "{Enter}", to indicate that we're done. + +In column 2, row 3 we have "booze". This is one of many alias keywords defined in the included [baseline aliases file](https://github.com/DFHack/dfhack/tree/develop/data/quickfort/aliases-common.txt). This particular alias sets a food stockpile to carry booze only. It sends the keys needed to navigate DF's stockpile settings menu, and then sends an Escape character ("^" or "{ESC}") to exit back to the map. It is important to exit out of any menus that you enter while in query mode so that the cursor can move to the next tile when it is done configuring the current tile. + +Check out the included [blueprint library](https://github.com/DFHack/dfhack/tree/develop/data/blueprints/library) to see many more examples. Read the baseline aliases file for helpful pre-packaged aliases, or create your own in [dfhack-config/quickfort/aliases.txt](https://github.com/DFHack/dfhack/tree/develop/dfhack-config/quickfort/aliases.txt) in your DFHack installation. + + +Area expansion syntax +--------------------- + +In Quickfort, the following blueprints are equivalent: + + #dig a 3x3 area + d d d # + d d d # + d d d # + # # # # + + #dig the same area with d(3x3) specified in row 1, col 1 + d(3x3)# + ` ` ` # + ` ` ` # + # # # # + +The second example uses Quickfort's "area expansion syntax", which takes the form: + + cmds(WxH) + +In Quickfort the above two examples of specifying a contiguous 3x3 area produce identical output: a single 3x3 designation will be performed, rather than nine 1x1 designations as the first example might suggest. + +Area expansion syntax can only specify rectangular areas. If you want to create extent-based structures (e.g. farm plots or stockpiles) in different shapes, use the first format above. For example: + + #place L shaped food stockpile + f f ` ` # + f f ` ` # + f f f f # + f f f f # + # # # # # + +Area expansion syntax also sets boundaries, which can be useful if you want adjacent, but separate, stockpiles of the same type: + + #place Two touching but separate food stockpiles + f(4x2) # + ~ ~ ~ ~ # + f(4x2) # + ~ ~ ~ ~ # + # # # # # + +As mentioned previously, "~" characters are ignored as comment characters and can be used for visualizing the blueprint layout. The blueprint can be equivalently written as: + + #place Two touching but separate food stockpiles + f(4x2) # + ~ ~ ~ ~ # + f f f f # + f f f f # + # # # # # + +since the area expansion syntax of the upper stockpile prevents it from combining with the lower, freeform syntax stockpile. + +Area expansion syntax can also be used for buildings which have an adjustable size, like bridges. The following blueprints are equivalent: + + #build a 4x2 bridge from row 1, col 1 + ga(4x2) ` # + ` ` ` ` # + # # # # # + + #build a 4x2 bridge from row 1, col 1 + ga ga ga ga # + ga ga ga ga # + # # # # # + + +Automatic area expansion +------------------------ + +Buildings larger than 1x1, like workshops, can be represented in any of three ways. You can designate just their center tile with empty cells around it to leave room for the footprint, like this: + + #build a mason workshop in row 2, col 2 that will occupy the 3x3 area + ` ` ` # + ` wm ` # + ` ` ` # + # # # # + +Or you can fill out the entire footprint like this: + + #build a mason workshop + wm wm wm # + wm wm wm # + wm wm wm # + # # # # + +This format may be verbose for regular workshops, but it can be very helpful for laying out structures like screw pump towers and waterwheels, whose "center point" can be non-obvious. + +Finally, you can use area expansion syntax to represent the workshop: + + #build a mason workshop + wm(3x3) # + ` ` ` # + ` ` ` # + # # # # + +This style can be convenient for laying out multiple buildings of the same type. If you are building a large-scale block factory, for example, this will create 20 mason workshops all in a row: + + #build line of 20 mason workshops + wm(60x3) # + +Quickfort will intelligently break large areas of the same designation into appropriately-sized chunks. + + +Specifying a starting position +------------------------------ + +You can optionally specify a cursor starting position for a particular blueprint, simplifying the task of blueprint alignment. This can be helpful for blueprints that are based on a central staircase, for example. + +To specify a cursor starting position, use the following modified format for the header line of your blueprint: + + #mode start(X;Y;STARTCOMMENT) comment + +where X and Y specify the starting cursor position (1;1 is the top left cell) and STARTCOMMENT (optional) is information about where to position the cursor. This information appears in the `quickfort list` output. + +A couple examples: + + #dig start(3; 3; Center tile of a 5-tile square) Regular blueprint comment + #build start(10;15) + + +Multilevel blueprints +--------------------- + +Multilevel blueprints are accommodated by separating Z-levels of the blueprint with #> (go down one z-level) or #< (go up one z-level) at the end of each floor. + + #dig Stairs leading down to a small room below + j ` ` # + ` ` ` # + ` ` ` # + #> # # # + u d d # + d d d # + d d d # + # # # # + + +Minecart tracks +--------------- + +There are two ways to produce minecart tracks, and they are handled very differently by the game. You can carve them into hard natural floors or you can construct them out of building materials. Constructed tracks are conceptually simpler, so we'll start with them. + +### Constructed Tracks ### + +Quickfort supports the designation of track stops and rollers through the normal mechanisms: a #build blueprint with `CS` and some number of 'd' and 'a' characters (for selecting dump direction and friction) in a cell designates a track stop and a #build blueprint with `Mr` and some number of 's' and 'q' characters (for direction and speed) designates a roller. This can get confusing very quickly and is very difficult to read in a blueprint. Constructed track segments don't even have keys associated with them at all! + +To solve this problem, Quickfort provides the following keywords for use in build blueprints: + + -- Track segments -- + trackN + trackS + trackE + trackW + trackNS + trackNE + trackNW + trackSE + trackSW + trackEW + trackNSE + trackNSW + trackNEW + trackSEW + trackNSEW + + -- Track/ramp segments -- + trackrampN + trackrampS + trackrampE + trackrampW + trackrampNS + trackrampNE + trackrampNW + trackrampSE + trackrampSW + trackrampEW + trackrampNSE + trackrampNSW + trackrampNEW + trackrampSEW + trackrampNSEW + + -- Horizontal and vertical roller segments -- + rollerH + rollerV + rollerNS + rollerSN + rollerEW + rollerWE + + Note: append up to four 'q' characters to roller keywords to set roller + speed. E.g. a roller that propels from East to West at the slowest speed can + be specified with 'rollerEWqqqq'. + + -- Track stops that (optionally) dump to the N/S/E/W -- + trackstop + trackstopN + trackstopS + trackstopE + trackstopW + + Note: append up to four 'a' characters to trackstop keywords to set friction + amount. E.g. a stop that applies the smallest amount of friction can be + specified with 'trackstopaaaa'. + +As an example, you can create an E-W track with stops at each end that dump to their outside directions with the following blueprint: + + #build Example track + trackstopW trackEW trackEW trackEW trackstopE + +Note that the **only** way to build track and track/ramp segments is with the keywords. The UI method of using "+" and "-" keys to select the track type from a list does not work since DFHack Quickfort doesn't actually send keys to the UI in order to build buildings. The text in your spreadsheet cells is mapped directly into DFHack API calls. Only query-mode blueprints still send actual keycodes to the UI. + +### Carved Tracks ### + +In the game, you carve a minecart track by specifying a beginning and ending tile and the game "adds" the designation to the tiles. You cannot designate single tiles. For example to carve two track segments that cross each other, you might use the cursor to designate a line of three vertical tiles like this: + + ` start here ` # + ` ` ` # + ` end here ` # + +Then to carve the cross, you'd do a horizonal segment: + + ` ` ` # + start here ` end here # + ` ` ` # + +This will result in a carved track that would be equivalent to a constructed track of the form: + + #build + ` trackS ` # + trackE trackNSEW trackW # + ` trackN ` # + # # # # + +To carve this same track with a dig blueprint, you'd use area expansion syntax with a height or width of 1 to indicate the segments to designate: + + #dig + ` T(1x3) ` # + T(3x1) ` ` # + ` ` ` # + # # # # + +"But wait!", I can hear you say, "How do you designate a track corner that opens to the South and East? You can't put both T(1xH) and T(Wx1) in the same cell!" This is true, but you can specify both width and height, and for tracks, QF interprets it as an upper-left corner extending to the right W tiles and down H tiles. For example, to carve a track in a closed ring, you'd write: + + #dig + T(3x3) ` T(1x3) # + ` ` ` # + T(3x1) ` ` # + # # # # + +Which would result in a carved track simliar to a constructed track of the form: + + #build + trackSE trackEW trackSW # + trackNS ` trackNS # + trackNE trackEW trackNW # + # # # # + + +Packaging a set of blueprints +----------------------------- + +A complete QF specification for a section of your fortress may contain 4 or more separate blueprints, one for each "phase" of construction (dig, build, place stockpiles, query building adjustments). + +To manage all the separate blueprints, it is often convenient to keep related blueprints in a single .xlsx file, with each blueprint in a separate sheet within the file. Online spreadsheet applications like [Google Sheets](https://sheets.new) make it easy to work with multiple related blueprints, and, as a bonus, they retain any formatting you've set, like column sizes and coloring. + +Of course, you could still choose to keep your blueprints in single-sheet .csv files and just give related blueprints similar names. The blueprint modes suggest a convenient naming scheme for .csv-based blueprint "stacks": + + bedroom.1.dig.csv + bedroom.2.build.csv + bedroom.3.place.csv + bedroom.4.query.csv + +But the naming is completely up to you, of course. + + +Tips and Tricks +--------------- + +* During blueprint application, especially query blueprints, don't click the mouse on the DF window or type any keys. They can change the state of the game while the blueprint is being applied, resulting in strange errors. + +* After digging out an area, you may wish to smooth and/or engrave the area before starting the build phase, as dwarves may be unable to access walls or floors that are behind/under built objects. + +* As of DF 0.34.x, it is no longer possible to build doors (d) at the same time that you build adjacent walls (Cw). Doors must now be built *after* walls are constructed for them to be next to. This does not affect the more common case where walls exist as a side-effect of having dug-out a room in a #dig blueprint. + + +Links +----- + +### Quickfort links ### + +* [Quickfort command syntax](https://docs.dfhack.org/en/stable/docs/_auto/base.html#quickfort) +* [Quickfort forum thread](http://www.bay12forums.com/smf/index.php?topic=176889.0) +* [Quickfort blueprints library](https://github.com/DFHack/dfhack/tree/develop/data/blueprints/library) +* [DFHack issue tracker](https://github.com/DFHack/dfhack/issues) +* [Quickfort source code](https://github.com/DFHack/scripts/tree/master/internal/quickfort) + +### Related tools ### + +* DFHack's [blueprint plugin](https://docs.dfhack.org/en/stable/docs/Plugins.html#blueprint) can generate blueprints from actual DF maps. +* [Python Quickfort](http://joelpt.net/quickfort) is the previous, Python-based implementation that DFHack's quickfort script was inspired by. From b033e4644f8ea414aa12975b2261c797ccf5619c Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Fri, 7 Aug 2020 12:44:40 -0700 Subject: [PATCH 250/547] add xlsxio as a submodule --- .gitmodules | 4 ++++ depends/xlsxio | 1 + 2 files changed, 5 insertions(+) create mode 160000 depends/xlsxio diff --git a/.gitmodules b/.gitmodules index 98e06473d..0ccd3810a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,3 +16,7 @@ [submodule "depends/jsoncpp"] path = depends/jsoncpp-sub url = ../../DFHack/jsoncpp.git +[submodule "depends/xlsxio"] + path = depends/xlsxio + url = ../../brechtsanders/xlsxio.git + shallow = true diff --git a/depends/xlsxio b/depends/xlsxio new file mode 160000 index 000000000..2d12a8844 --- /dev/null +++ b/depends/xlsxio @@ -0,0 +1 @@ +Subproject commit 2d12a88448b6f40594b2b2e0d0ce7207d0efa021 From 1fc800e7652d344a53f988b3977cca37f08fa568 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Fri, 7 Aug 2020 13:08:06 -0700 Subject: [PATCH 251/547] fix xlsxio lib to current commit so it doesn't break us with incompatibile changes. we only need to update this lib if/when we run into a bug with it. no need to introduce instability by tracking HEAD --- depends/xlsxio | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/xlsxio b/depends/xlsxio index 2d12a8844..261d56815 160000 --- a/depends/xlsxio +++ b/depends/xlsxio @@ -1 +1 @@ -Subproject commit 2d12a88448b6f40594b2b2e0d0ce7207d0efa021 +Subproject commit 261d56815b29908fc960fecb9cb3143db4b485ad From a85b77e6f156a75684d00a60911b060f00c631b8 Mon Sep 17 00:00:00 2001 From: Ryan Bennitt Date: Fri, 7 Aug 2020 22:07:48 +0100 Subject: [PATCH 252/547] Retrieve goal string values from enum attributes and add new Units methods to Lua API and docs --- docs/Lua API.rst | 24 +++++++++++++++++++++ library/LuaApi.cpp | 3 +++ library/modules/Units.cpp | 45 +++++++++------------------------------ plugins/manipulator.cpp | 1 - 4 files changed, 37 insertions(+), 36 deletions(-) diff --git a/docs/Lua API.rst b/docs/Lua API.rst index 8c3763245..45ccd46a9 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -1277,6 +1277,30 @@ Units module Retrieves the profession color for the given race/caste using raws. +* ``dfhack.units.getGoalType(unit[,goalIndex])`` + + Retrieves the goal type of the dream that the given unit has. + By default the goal of the first dream is returned. + The goalIndex parameter may be used to retrieve additional dream goals. + Currently only one dream per unit is supported by Dwarf Fortress. + Support for multiple dreams may be added in future versions of Dwarf Fortress. + +* ``dfhack.units.getGoalName(unit[,goalIndex])`` + + Retrieves the short name describing the goal of the dream that the given unit has. + By default the goal of the first dream is returned. + The goalIndex parameter may be used to retrieve additional dream goals. + Currently only one dream per unit is supported by Dwarf Fortress. + Support for multiple dreams may be added in future versions of Dwarf Fortress. + +* ``dfhack.units.isGoalAchieved(unit[,goalIndex])`` + + Checks if given unit has achieved the goal of the dream. + By default the status of the goal of the first dream is returned. + The goalIndex parameter may be used to check additional dream goals. + Currently only one dream per unit is supported by Dwarf Fortress. + Support for multiple dreams may be added in future versions of Dwarf Fortress. + * ``dfhack.units.getStressCategory(unit)`` Returns a number from 0-6 indicating stress. 0 is most stressed; 6 is least. diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 25843875d..13c9386ff 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -1604,6 +1604,9 @@ static const LuaWrapper::FunctionReg dfhack_units_module[] = { WRAPM(Units, getCasteProfessionName), WRAPM(Units, getProfessionColor), WRAPM(Units, getCasteProfessionColor), + WRAPM(Units, getGoalType), + WRAPM(Units, getGoalName), + WRAPM(Units, isGoalAchieved), WRAPM(Units, getSquadName), WRAPM(Units, isWar), WRAPM(Units, isHunter), diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index 87c71ac67..32fe3b5b9 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -61,6 +61,7 @@ using namespace std; #include "df/identity_type.h" #include "df/game_mode.h" #include "df/histfig_entity_link_positionst.h" +#include "df/histfig_relationship_type.h" #include "df/historical_entity.h" #include "df/historical_figure.h" #include "df/historical_figure_info.h" @@ -1457,42 +1458,16 @@ std::string Units::getGoalName(df::unit *unit, int goalIndex) df::goal_type goal = getGoalType(unit, goalIndex); bool achieved_goal = isGoalAchieved(unit, goalIndex); - switch (goal) - { - default: - case df::goal_type::STAY_ALIVE: - return achieved_goal ? "Stayed Alive" : "Stay Alive"; - case df::goal_type::MAINTAIN_ENTITY_STATUS: - return achieved_goal ? "Maintained Status" : "Maintain Status"; - case df::goal_type::START_A_FAMILY: - return isFemale(unit) ? - (achieved_goal ? "Is a Mother" : "Be a Mother") : - (achieved_goal ? "Is a Father" : "Be a Father"); - case df::goal_type::RULE_THE_WORLD: - return achieved_goal ? "Ruled the World" : "Rule the World"; - case df::goal_type::CREATE_A_GREAT_WORK_OF_ART: - return achieved_goal ? "Made Great Artwork" : "Create Great Artwork"; - case df::goal_type::CRAFT_A_MASTERWORK: - return achieved_goal ? "Crafted a Masterwork" : "Craft a Masterwork"; - case df::goal_type::BRING_PEACE_TO_THE_WORLD: - return achieved_goal ? "Brought World Peace" : "Bring Peace to World"; - case df::goal_type::BECOME_A_LEGENDARY_WARRIOR: - return achieved_goal ? "Is Legendary Warrior" : "Be Legendary Warrior"; - case df::goal_type::MASTER_A_SKILL: - return achieved_goal ? "Mastered a Skill" : "Master a Skill"; - case df::goal_type::FALL_IN_LOVE: - return achieved_goal ? "Fell in Love" : "Fall in Love"; - case df::goal_type::SEE_THE_GREAT_NATURAL_SITES: - return achieved_goal ? "Saw Natural Wonders" : "See Natural Wonders"; - case df::goal_type::IMMORTALITY: - return achieved_goal ? "Immortal" : "Immortality"; - case df::goal_type::MAKE_A_GREAT_DISCOVERY: - return achieved_goal ? "Made Great Discovery" : "Make Great Discovery"; - case df::goal_type::ATTAINING_RANK_IN_SOCIETY: - return achieved_goal ? "Attained Social Rank" : "Attain Social Rank"; - case df::goal_type::BATHING_THE_WORLD_IN_CHAOS: - return achieved_goal ? "World is in Chaos" : "Bathe World in Chaos"; + std::string goal_name = achieved_goal ? ENUM_ATTR(goal_type, achieved_short_name, goal) : ENUM_ATTR(goal_type, short_name, goal); + if (goal == df::goal_type::START_A_FAMILY) { + std::string parent = ENUM_KEY_STR(histfig_relationship_type, histfig_relationship_type::Parent); + size_t start_pos = goal_name.find(parent); + if (start_pos != std::string::npos) { + df::histfig_relationship_type parent_type = isFemale(unit) ? histfig_relationship_type::Mother : histfig_relationship_type::Father; + goal_name.replace(start_pos, parent.length(), ENUM_KEY_STR(histfig_relationship_type, parent_type)); + } } + return goal_name; } bool Units::isGoalAchieved(df::unit *unit, int goalIndex) diff --git a/plugins/manipulator.cpp b/plugins/manipulator.cpp index 4bb285f0b..ae7b3f800 100644 --- a/plugins/manipulator.cpp +++ b/plugins/manipulator.cpp @@ -37,7 +37,6 @@ #include "uicommon.h" #include "listcolumn.h" -#include "manipulator.h" using std::stringstream; using std::set; From c76f71cd461f12a7ef861326321fc076f660864b Mon Sep 17 00:00:00 2001 From: Ryan Bennitt Date: Fri, 7 Aug 2020 22:20:11 +0100 Subject: [PATCH 253/547] Update xml library submodule --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index 9fca46ccc..51e237b9b 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 9fca46ccca28e0948014b9d56a096ad7343473f1 +Subproject commit 51e237b9b2e667d48fbb793ac29d782d7326c39a From f7fda8e7f52fbcecd18b0a7d5f87ef31797d8156 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 8 Aug 2020 00:06:59 -0400 Subject: [PATCH 254/547] Update changelog, authors, xml (#1615) --- docs/Authors.rst | 1 + docs/changelog.txt | 1 + library/xml | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/Authors.rst b/docs/Authors.rst index 31789aa52..a9036a33c 100644 --- a/docs/Authors.rst +++ b/docs/Authors.rst @@ -142,6 +142,7 @@ rout rubybrowncoat rubybrowncoat Rumrusher rumrusher RusAnon RusAnon +Ryan Bennitt ryanbennitt sami scamtank scamtank Sebastian Wolfertz Enkrod diff --git a/docs/changelog.txt b/docs/changelog.txt index e7a01f4fe..f5bdb42b3 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -55,6 +55,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## API - Added ``Filesystem::mkdir_recursive`` - Extended ``Filesystem::listdir_recursive`` to optionally make returned filenames relative to the start directory +- ``Units``: added goal-related functions: ``getGoalType()``, ``getGoalName()``, ``isGoalAchieved()`` ## Internals - Linux/macOS: Added console keybindings for deleting words (Alt+Backspace and Alt+d in most terminals) diff --git a/library/xml b/library/xml index 51e237b9b..daa353138 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 51e237b9b2e667d48fbb793ac29d782d7326c39a +Subproject commit daa3531384c6d222c7a28f6a73de3201a27f391d From ee8d1302980cf4e805a4f4ef170bd9f1411b3a27 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 8 Aug 2020 00:12:59 -0400 Subject: [PATCH 255/547] Use existing pronoun_type enum --- plugins/manipulator.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/manipulator.cpp b/plugins/manipulator.cpp index ae7b3f800..28b946be2 100644 --- a/plugins/manipulator.cpp +++ b/plugins/manipulator.cpp @@ -290,7 +290,7 @@ struct UnitInfo string transname; string profession; string goal; - enum { NEUTRAL, MALE, FEMALE } goal_gender; + df::pronoun_type goal_gender; bool achieved_goal; int8_t color; int active_index; @@ -1263,9 +1263,9 @@ void viewscreen_unitlaborsst::refreshNames() cur->goal = Units::getGoalName(unit); df::goal_type goal = Units::getGoalType(unit); if (goal == df::goal_type::START_A_FAMILY) { - cur->goal_gender = Units::isFemale(unit) ? UnitInfo::FEMALE : UnitInfo::MALE; + cur->goal_gender = unit->sex; } else { - cur->goal_gender = UnitInfo::NEUTRAL; + cur->goal_gender = df::pronoun_type::it; } cur->achieved_goal = Units::isGoalAchieved(unit); @@ -2021,13 +2021,13 @@ void viewscreen_unitlaborsst::render() fg = cur->color; detail_str = cur->profession; } else { - if (cur->goal_gender == UnitInfo::NEUTRAL) { + if (cur->goal_gender == df::pronoun_type::it) { if (cur->achieved_goal) { fg = COLOR_LIGHTGREEN; } else { fg = COLOR_BROWN; } - } else if (cur->goal_gender == UnitInfo::FEMALE) { + } else if (cur->goal_gender == df::pronoun_type::she) { if (cur->achieved_goal) { fg = COLOR_LIGHTRED; } From cb1b751988666bdca41d5e5e9ebb53f613a4decb Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 8 Aug 2020 00:31:28 -0400 Subject: [PATCH 256/547] Update submodules --- library/xml | 2 +- scripts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/xml b/library/xml index daa353138..ce21a92c0 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit daa3531384c6d222c7a28f6a73de3201a27f391d +Subproject commit ce21a92c03a5a512c740917cdff85eadf5c4fdd0 diff --git a/scripts b/scripts index 823d47c4d..f732c1e4b 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 823d47c4d181ac5b754dce5d605f3e7f242aed26 +Subproject commit f732c1e4b3c7c7577b2fc07e1655b81a24340ae3 From 6a1f046995391e383d28b590126c8367128892db Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 8 Aug 2020 00:31:33 -0400 Subject: [PATCH 257/547] Add --sizecheck option to Linux launcher script, update docs --- docs/Memory-research.rst | 19 +++++++++++++++---- package/linux/dfhack | 5 +++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/docs/Memory-research.rst b/docs/Memory-research.rst index 41aa437c8..3f615750a 100644 --- a/docs/Memory-research.rst +++ b/docs/Memory-research.rst @@ -86,10 +86,13 @@ You should not count on DF being stable when using this. DFHack's implementation of sizecheck is currently only tested on Linux, although it probably also works on macOS. It can be built with the ``BUILD_SIZECHECK`` `CMake option `, which produces a ``libsizecheck`` -library installed in the ``hack`` folder. You will need to preload this library -manually, by setting ``PRELOAD_LIB`` on Linux (or ``LD_PRELOAD`` if editing -the ``dfhack`` launcher script directly), or by editing the ``dfhack`` -launcher script and adding the library to ``DYLD_INSERT_LIBRARIES`` on macOS. +library installed in the ``hack`` folder. On Linux, passing ``--sc`` as the +first argument to the ``dfhack`` launcher script will load this library on +startup. On other platforms, or when passing a different argument to the +launcher (such as for `linux-gdb`), you will need to preload this library +manually, by setting ``PRELOAD_LIB`` on Linux (or ``LD_PRELOAD`` if editing the +``dfhack`` launcher script directly), or by editing the ``dfhack`` launcher +script and adding the library to ``DYLD_INSERT_LIBRARIES`` on macOS. There is also an older sizecheck implementation by Mifki available on `GitHub `__ (``b.cpp`` is the main @@ -129,6 +132,14 @@ Some basic GDB commands: See the `official GDB documentation `_ for more details. +Other analysis tools +-------------------- + +The ``dfhack`` launcher script on Linux has support for launching several other +tools alongside DFHack, including Valgrind (as well as Callgrind and Helgrind) +and strace. See the script for the exact command-line option to specify. Note +that currently only one tool at a time is supported, and must be specified +with the first argument to the script. df-structures GUI ----------------- diff --git a/package/linux/dfhack b/package/linux/dfhack index b63c3a253..6b542f405 100755 --- a/package/linux/dfhack +++ b/package/linux/dfhack @@ -146,6 +146,11 @@ case "$1" in exec setarch "$setarch_arch" -R env LD_PRELOAD="$PRELOAD_LIB" ./libs/Dwarf_Fortress "$@" # script does not resume ;; + --sc | --sizecheck) + PRELOAD_LIB="${PRELOAD_LIB:+$PRELOAD_LIB:}./hack/libsizecheck.so" + MALLOC_PERTURB_=45 setarch "$setarch_arch" -R env LD_PRELOAD="$PRELOAD_LIB" ./libs/Dwarf_Fortress "$@" + ret=$? + ;; *) setarch "$setarch_arch" -R env LD_PRELOAD="$PRELOAD_LIB" ./libs/Dwarf_Fortress "$@" ret=$? From a28e9393704d4de58760b06b87e564105df183d8 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 8 Aug 2020 00:45:57 -0400 Subject: [PATCH 258/547] Recalculate size after toggling columns (goals can be longer than professions) --- plugins/manipulator.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/manipulator.cpp b/plugins/manipulator.cpp index 28b946be2..b333afae5 100644 --- a/plugins/manipulator.cpp +++ b/plugins/manipulator.cpp @@ -1769,7 +1769,7 @@ void viewscreen_unitlaborsst::feed(set *events) std::stable_sort(units.begin(), units.end(), sortBySquad); } else if (detail_mode == DETAIL_MODE_JOB) { std::stable_sort(units.begin(), units.end(), sortByJob); - } else if (detail_mode == DETAIL_MODE_PROFESSION){ + } else if (detail_mode == DETAIL_MODE_PROFESSION) { std::stable_sort(units.begin(), units.end(), sortByProfession); } else { std::stable_sort(units.begin(), units.end(), sortByGoal); @@ -1818,6 +1818,7 @@ void viewscreen_unitlaborsst::feed(set *events) } else { detail_mode = DETAIL_MODE_PROFESSION; } + calcSize(); } if (events->count(interface_key::CUSTOM_SHIFT_X)) @@ -2202,7 +2203,7 @@ void viewscreen_unitlaborsst::render() OutputString(15, x, y, "Squad"); } else if (detail_mode == DETAIL_MODE_JOB) { OutputString(15, x, y, "Job"); - } else if (detail_mode == DETAIL_MODE_PROFESSION){ + } else if (detail_mode == DETAIL_MODE_PROFESSION) { OutputString(15, x, y, "Profession"); } else { OutputString(15, x, y, "Goal"); From 3b3b0be8c584eb7ba3ee33d4004ad1aadc3eb300 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 8 Aug 2020 02:00:12 -0400 Subject: [PATCH 259/547] Update submodules, tweak changelog order --- docs/changelog.txt | 2 +- library/xml | 2 +- scripts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index f5bdb42b3..e033f393b 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -48,6 +48,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - `RemoteFortressReader`: fixed a couple crashes that could result from decoding invalid enum items (``site_realization_building_type`` and ``improvement_type``) ## Misc Improvements +- Linux/macOS: Added console keybindings for deleting words (Alt+Backspace and Alt+d in most terminals) - `blueprint`: now writes blueprints to the ``blueprints/`` subfolder instead of the df root folder - `blueprint`: now automatically creates folder trees when organizing blueprints into subfolders (e.g. ``blueprint 30 30 1 rooms/dining dig`` will create the file ``blueprints/rooms/dining-dig.csv``); previously it would fail if the ``blueprints/rooms/`` directory didn't already exist - `confirm`: added a confirmation dialog for convicting dwarves of crimes @@ -58,7 +59,6 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - ``Units``: added goal-related functions: ``getGoalType()``, ``getGoalName()``, ``isGoalAchieved()`` ## Internals -- Linux/macOS: Added console keybindings for deleting words (Alt+Backspace and Alt+d in most terminals) - Added support for splitting scripts into multiple files in the ``scripts/internal`` folder without polluting the output of `ls` ## Lua diff --git a/library/xml b/library/xml index ce21a92c0..23e076b70 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit ce21a92c03a5a512c740917cdff85eadf5c4fdd0 +Subproject commit 23e076b7079a48b91c59451be64319dd36476994 diff --git a/scripts b/scripts index f732c1e4b..933849569 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit f732c1e4b3c7c7577b2fc07e1655b81a24340ae3 +Subproject commit 9338495695c3892b8ce407b71a79059b39624334 From 13380008c4959fc21b94a91cf09961a785c48f63 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 8 Aug 2020 13:28:31 -0400 Subject: [PATCH 260/547] Update scripts, authors, changelog --- docs/Authors.rst | 4 ++-- docs/changelog.txt | 10 ++++++++++ docs/sphinx_extensions/dfhack/changelog.py | 1 + scripts | 2 +- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/docs/Authors.rst b/docs/Authors.rst index a9036a33c..42fda0985 100644 --- a/docs/Authors.rst +++ b/docs/Authors.rst @@ -60,7 +60,6 @@ Ian S kremlin- IndigoFenix James Gilles kazimuth James Logsdon jlogsdon -Japa JapaMala Jared Adams Jeremy Apthorp nornagon Jim Lisi stonetoad @@ -136,6 +135,7 @@ Robert Janetzko robertjanetzko RocheLimit rofl0r rofl0r root +Rose RosaryMala Roses Pheosics Ross M RossM rout @@ -173,7 +173,7 @@ U-glouglou\\simon Valentin Ochs Cat-Ion Vitaly Pronkin pronvit mifki ViTuRaS ViTuRaS -Vjek +Vjek vjek Warmist warmist Wes Malone wesQ3 Will Rogers wjrogers diff --git a/docs/changelog.txt b/docs/changelog.txt index e033f393b..00c7fafcb 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -46,12 +46,17 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - `embark-assistant`: fixed a couple of incursion handling bugs. - Fixed ``Units::isEggLayer``, ``Units::isGrazer``, ``Units::isMilkable``, ``Units::isTrainableHunting``, ``Units::isTrainableWar``, and ``Units::isTamable`` ignoring the unit's caste - `RemoteFortressReader`: fixed a couple crashes that could result from decoding invalid enum items (``site_realization_building_type`` and ``improvement_type``) +- `RemoteFortressReader`: fixed an issue that could cause block coordinates to be incorrect +- `rendermax`: fixed a hang that could occur when enabling some renderers, notably on Linux +- `stonesense`: fixed a crash when launching Stonesense +- `stonesense`: fixed some issues that could cause the splash screen to hang ## Misc Improvements - Linux/macOS: Added console keybindings for deleting words (Alt+Backspace and Alt+d in most terminals) - `blueprint`: now writes blueprints to the ``blueprints/`` subfolder instead of the df root folder - `blueprint`: now automatically creates folder trees when organizing blueprints into subfolders (e.g. ``blueprint 30 30 1 rooms/dining dig`` will create the file ``blueprints/rooms/dining-dig.csv``); previously it would fail if the ``blueprints/rooms/`` directory didn't already exist - `confirm`: added a confirmation dialog for convicting dwarves of crimes +- `manipulator`: added a new column option to display units' goals ## API - Added ``Filesystem::mkdir_recursive`` @@ -67,6 +72,11 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## Ruby - Updated ``item_find`` and ``building_find`` to use centralized logic that works on more screens +## Documentation +- Expanded the installation guide +- Added some new dev-facing pages, including dedicated pages about the remote API, memory research, and documentation +- Made a couple theme adjustments + # 0.47.04-r1 ## Fixes diff --git a/docs/sphinx_extensions/dfhack/changelog.py b/docs/sphinx_extensions/dfhack/changelog.py index 6f444d36f..d38f8c060 100644 --- a/docs/sphinx_extensions/dfhack/changelog.py +++ b/docs/sphinx_extensions/dfhack/changelog.py @@ -29,6 +29,7 @@ CHANGELOG_SECTIONS = [ 'Lua', 'Ruby', 'Structures', + 'Documentation', ] REPLACEMENTS = { diff --git a/scripts b/scripts index 933849569..155b00ab6 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 9338495695c3892b8ce407b71a79059b39624334 +Subproject commit 155b00ab65dd9a1efc56c34c1238a68dce80fe5d From 8f047530c49094545f580d250587c0b6cae5ba5a Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 8 Aug 2020 14:28:17 -0400 Subject: [PATCH 261/547] Make Units::getRaceNameById and other ID-related functions available to Lua --- docs/changelog.txt | 1 + library/LuaApi.cpp | 3 +++ 2 files changed, 4 insertions(+) diff --git a/docs/changelog.txt b/docs/changelog.txt index 00c7fafcb..f1c423da2 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -68,6 +68,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## Lua - Added a ``ref_target`` field to primitive field references, corresponding to the ``ref-target`` XML attribute +- Made ``dfhack.units.getRaceNameById()``, ``dfhack.units.getRaceBabyNameById()``, and ``dfhack.units.getRaceChildNameById()`` available to Lua ## Ruby - Updated ``item_find`` and ``building_find`` to use centralized logic that works on more screens diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 13c9386ff..78364083f 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -1617,8 +1617,11 @@ static const LuaWrapper::FunctionReg dfhack_units_module[] = { WRAPM(Units, getPhysicalDescription), WRAPM(Units, getRaceName), WRAPM(Units, getRaceNamePlural), + WRAPM(Units, getRaceNameById), WRAPM(Units, getRaceBabyName), + WRAPM(Units, getRaceBabyNameById), WRAPM(Units, getRaceChildName), + WRAPM(Units, getRaceChildNameById), WRAPM(Units, isBaby), WRAPM(Units, isChild), WRAPM(Units, isAdult), From 7ee58ada7b976272e07af280a3567f1976088795 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 8 Aug 2020 14:29:24 -0400 Subject: [PATCH 262/547] Update scripts --- scripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts b/scripts index 155b00ab6..385950715 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 155b00ab65dd9a1efc56c34c1238a68dce80fe5d +Subproject commit 385950715a4cd8b62d57bf35d7e25c4025fd3f25 From 8c5b21b7eec7f6d41e6156b4a011c92486c62505 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 8 Aug 2020 14:34:47 -0400 Subject: [PATCH 263/547] Fix a couple warnings in the Units module (#1615) --- library/include/modules/Units.h | 6 +++--- library/modules/Units.cpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/library/include/modules/Units.h b/library/include/modules/Units.h index c719a60a9..e2d34254d 100644 --- a/library/include/modules/Units.h +++ b/library/include/modules/Units.h @@ -181,9 +181,9 @@ DFHACK_EXPORT std::string getCasteProfessionName(int race, int caste, df::profes DFHACK_EXPORT int8_t getProfessionColor(df::unit *unit, bool ignore_noble = false); DFHACK_EXPORT int8_t getCasteProfessionColor(int race, int caste, df::profession pid); -DFHACK_EXPORT df::goal_type getGoalType(df::unit *unit, int goalIndex = 0); -DFHACK_EXPORT std::string getGoalName(df::unit *unit, int goalIndex = 0); -DFHACK_EXPORT bool isGoalAchieved(df::unit *unit, int goalIndex = 0); +DFHACK_EXPORT df::goal_type getGoalType(df::unit *unit, size_t goalIndex = 0); +DFHACK_EXPORT std::string getGoalName(df::unit *unit, size_t goalIndex = 0); +DFHACK_EXPORT bool isGoalAchieved(df::unit *unit, size_t goalIndex = 0); DFHACK_EXPORT std::string getSquadName(df::unit *unit); diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index d5c871f5b..a8f96b29f 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -1439,7 +1439,7 @@ int8_t Units::getCasteProfessionColor(int race, int casteid, df::profession pid) return 3; } -df::goal_type Units::getGoalType(df::unit *unit, int goalIndex) +df::goal_type Units::getGoalType(df::unit *unit, size_t goalIndex) { CHECK_NULL_POINTER(unit); @@ -1452,7 +1452,7 @@ df::goal_type Units::getGoalType(df::unit *unit, int goalIndex) return goal; } -std::string Units::getGoalName(df::unit *unit, int goalIndex) +std::string Units::getGoalName(df::unit *unit, size_t goalIndex) { CHECK_NULL_POINTER(unit); @@ -1471,7 +1471,7 @@ std::string Units::getGoalName(df::unit *unit, int goalIndex) return goal_name; } -bool Units::isGoalAchieved(df::unit *unit, int goalIndex) +bool Units::isGoalAchieved(df::unit *unit, size_t goalIndex) { CHECK_NULL_POINTER(unit); From 73ba692f15f35bf9e9ea2452b280e4bed694f9e6 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 8 Aug 2020 14:46:42 -0400 Subject: [PATCH 264/547] Fix road building (#1596) Paved roads need architecture before road building --- plugins/labormanager/joblabormapper.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/labormanager/joblabormapper.cpp b/plugins/labormanager/joblabormapper.cpp index 4a71b40bf..6a97aa75f 100644 --- a/plugins/labormanager/joblabormapper.cpp +++ b/plugins/labormanager/joblabormapper.cpp @@ -200,6 +200,8 @@ static df::building* get_building_from_job(df::job* j) static df::unit_labor construction_build_labor(df::building_actual* b) { + if (b->getType() == df::building_type::RoadPaved) + return df::unit_labor::BUILD_ROAD; // Find last item in building with use mode appropriate to the building's constructions state // For screw pumps contained_items[0] = pipe, 1 corkscrew, 2 block // For wells 0 mechanism, 1 rope, 2 bucket, 3 block @@ -332,6 +334,7 @@ public: case df::building_type::Bridge: case df::building_type::ArcheryTarget: case df::building_type::WaterWheel: + case df::building_type::RoadPaved: case df::building_type::Well: case df::building_type::ScrewPump: case df::building_type::Wagon: @@ -345,8 +348,6 @@ public: return construction_build_labor(b); } break; - case df::building_type::RoadPaved: - return df::unit_labor::BUILD_ROAD; case df::building_type::FarmPlot: return df::unit_labor::PLANT; case df::building_type::Chair: From 504b0c1ec7f748789b01773003afcb292a756727 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 8 Aug 2020 14:47:59 -0400 Subject: [PATCH 265/547] Update changelog (#1596) --- docs/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog.txt b/docs/changelog.txt index f1c423da2..f147e2a67 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: - Linux: fixed ``dfhack.getDFPath()`` (Lua) and ``Process::getPath()`` (C++) to always return the DF root path, even if the working directory has changed - `getplants`: fixed issues causing plants to be collected even if they have no growths (or unripe growths) - `labormanager`: fixed handling of new jobs in 0.47 +- `labormanager`: fixed an issue preventing custom furnaces from being built - `embark-assistant`: fixed a couple of incursion handling bugs. - Fixed ``Units::isEggLayer``, ``Units::isGrazer``, ``Units::isMilkable``, ``Units::isTrainableHunting``, ``Units::isTrainableWar``, and ``Units::isTamable`` ignoring the unit's caste - `RemoteFortressReader`: fixed a couple crashes that could result from decoding invalid enum items (``site_realization_building_type`` and ``improvement_type``) From f2b0f012c9895aa3fd743ad50fab9e6fb78b479d Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 8 Aug 2020 14:53:24 -0400 Subject: [PATCH 266/547] Bump to 0.47.04-r2 --- CMakeLists.txt | 2 +- docs/changelog.txt | 2 ++ library/xml | 2 +- scripts | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 44d6a02ce..cd06587eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -184,7 +184,7 @@ endif() # set up versioning. set(DF_VERSION "0.47.04") -set(DFHACK_RELEASE "r1") +set(DFHACK_RELEASE "r2") set(DFHACK_PRERELEASE FALSE) set(DFHACK_VERSION "${DF_VERSION}-${DFHACK_RELEASE}") diff --git a/docs/changelog.txt b/docs/changelog.txt index f147e2a67..9317df86e 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -33,6 +33,8 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: # Future +# 0.47.04-r2 + ## New Tweaks - `tweak` do-job-now: adds a job priority toggle to the jobs list - `tweak` reaction-gloves: adds an option to make reactions produce gloves in sets with correct handedness diff --git a/library/xml b/library/xml index 23e076b70..036b662a1 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 23e076b7079a48b91c59451be64319dd36476994 +Subproject commit 036b662a1bbc96b4911f3cbe74dfa1243b6459bc diff --git a/scripts b/scripts index 385950715..568c586ce 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 385950715a4cd8b62d57bf35d7e25c4025fd3f25 +Subproject commit 568c586ce2474af89c64a4cc7c876edb35931d43 From 89a6309788a6ff2d1a64ba951c5427f9de8f0f79 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 8 Aug 2020 15:24:12 -0700 Subject: [PATCH 267/547] build xlsxio and link it into dfhack, add lua api --- CMakeLists.txt | 19 +++++ depends/CMakeLists.txt | 11 +++ library/CMakeLists.txt | 4 +- library/LuaApi.cpp | 43 ++++++++++ library/include/modules/XlsxReader.h | 45 +++++++++++ library/modules/XlsxReader.cpp | 115 +++++++++++++++++++++++++++ 6 files changed, 236 insertions(+), 1 deletion(-) create mode 100644 library/include/modules/XlsxReader.h create mode 100644 library/modules/XlsxReader.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 44d6a02ce..6a2230721 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -364,6 +364,8 @@ endif() #### expose depends #### +include(ExternalProject) + if(UNIX) # Rescan for pthread and zlib if the build arch changed if(NOT "${DFHACK_BUILD_ARCH}" STREQUAL "${DFHACK_BUILD_ARCH_PREV}") @@ -415,6 +417,23 @@ endif() # build the lib itself if(BUILD_LIBRARY) + ExternalProject_Get_Property(xlsxio_project INSTALL_DIR) + set(XLSXIO_INSTALL_DIR ${INSTALL_DIR}) + include_directories(${XLSXIO_INSTALL_DIR}/include) + add_library(xlsxio_read STATIC IMPORTED) + set_target_properties(xlsxio_read PROPERTIES + IMPORTED_LOCATION ${XLSXIO_INSTALL_DIR}/lib/libxlsxio_read.a) + add_dependencies(xlsxio_read xlsxio_project) + + # just pull from the system until I figure out how to integrate these deps + # into the build + add_library(zip SHARED IMPORTED) + set_target_properties(zip PROPERTIES + IMPORTED_LOCATION /usr/lib64/libzip.so) + add_library(expat SHARED IMPORTED) + set_target_properties(expat PROPERTIES + IMPORTED_LOCATION /usr/lib64/libexpat.so) + add_subdirectory(library) install(FILES LICENSE.rst docs/changelog.txt DESTINATION ${DFHACK_USERDOC_DESTINATION}) endif() diff --git a/depends/CMakeLists.txt b/depends/CMakeLists.txt index aac250c39..e43c80266 100644 --- a/depends/CMakeLists.txt +++ b/depends/CMakeLists.txt @@ -17,3 +17,14 @@ option(CLSOCKET_SHARED "Build clsocket lib as shared." OFF) option(CLSOCKET_DEP_ONLY "Build for use inside other CMake projects as dependency." ON) add_subdirectory(clsocket) ide_folder(clsocket "Depends") + +set(XLSXIO_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/xlsxio) +ExternalProject_Add(xlsxio_project + PREFIX xlsxio + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/xlsxio + INSTALL_DIR ${XLSXIO_INSTALL_DIR} + BUILD_BYPRODUCTS ${XLSXIO_INSTALL_DIR}/lib/libxlsxio_read.a + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${XLSXIO_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_STATIC=ON -DBUILD_SHARED=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_TOOLS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_DOCUMENTATION=OFF -DWITH_LIBZIP=ON -DZLIB_DIR=${ZLIB_DIR} +) + #-DLIBZIP_DIR= + #-DEXPAT_DIR= diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 2de293e15..583c8768f 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -144,6 +144,7 @@ set(MODULE_HEADERS include/modules/Translation.h include/modules/Units.h include/modules/World.h + include/modules/XlsxReader.h ) set(MODULE_SOURCES @@ -172,6 +173,7 @@ set(MODULE_SOURCES modules/Units.cpp modules/Windows.cpp modules/World.cpp + modules/XlsxReader.cpp ) set(STATIC_FIELDS_FILES) @@ -409,7 +411,7 @@ if(APPLE) set_target_properties(dfhack PROPERTIES SOVERSION 1.0.0) endif() -target_link_libraries(dfhack protobuf-lite clsocket lua jsoncpp_lib_static dfhack-version ${PROJECT_LIBS}) +target_link_libraries(dfhack protobuf-lite clsocket lua jsoncpp_lib_static xlsxio_read zip expat dfhack-version ${PROJECT_LIBS}) set_target_properties(dfhack PROPERTIES INTERFACE_LINK_LIBRARIES "") target_link_libraries(dfhack-client protobuf-lite clsocket jsoncpp_lib_static) diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 25843875d..49fdf4c73 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -60,6 +60,7 @@ distribution. #include "modules/Translation.h" #include "modules/Units.h" #include "modules/World.h" +#include "modules/XlsxReader.h" #include "LuaWrapper.h" #include "LuaTools.h" @@ -2474,6 +2475,47 @@ static const LuaWrapper::FunctionReg dfhack_kitchen_module[] = { {NULL, NULL} }; +/***** XlsxReader module *****/ + +static const LuaWrapper::FunctionReg dfhack_xlsxreader_module[] = { + WRAPM(XlsxReader, open_xlsx_file), + WRAPM(XlsxReader, close_xlsx_file), + WRAPM(XlsxReader, list_sheets), + WRAPM(XlsxReader, open_sheet), + WRAPM(XlsxReader, close_sheet), + WRAPM(XlsxReader, get_next_row), + {NULL, NULL} +}; + +// takes the sheet handle and returns a string, or nil if there is no next cell +// in the current row. +static int xlsxreader_get_next_cell(lua_State *L) +{ + if (lua_gettop(L) != 1 || lua_isnil(L, 1)) + { + luaL_error(L, "invalid sheet handle"); + } + luaL_checktype(L, 1, LUA_TUSERDATA); + XlsxReader::xlsx_sheet_handle sheet_handle = lua_touserdata(L, 1); + + std::string value; + bool ok = XlsxReader::get_next_cell(sheet_handle, value); + if (!ok) + { + lua_pushnil(L); + } + else + { + lua_pushstring(L, value.c_str()); + } + return 1; +} + +static const luaL_Reg dfhack_xlsxreader_funcs[] = { + {"get_next_cell", xlsxreader_get_next_cell}, + {NULL, NULL} +}; + /***** Console module *****/ namespace console { @@ -3027,6 +3069,7 @@ void OpenDFHackApi(lua_State *state) OpenModule(state, "filesystem", dfhack_filesystem_module, dfhack_filesystem_funcs); OpenModule(state, "designations", dfhack_designations_module, dfhack_designations_funcs); OpenModule(state, "kitchen", dfhack_kitchen_module); + OpenModule(state, "xlsxreader", dfhack_xlsxreader_module, dfhack_xlsxreader_funcs); OpenModule(state, "console", dfhack_console_module); OpenModule(state, "internal", dfhack_internal_module, dfhack_internal_funcs); } diff --git a/library/include/modules/XlsxReader.h b/library/include/modules/XlsxReader.h new file mode 100644 index 000000000..93ea1cf20 --- /dev/null +++ b/library/include/modules/XlsxReader.h @@ -0,0 +1,45 @@ +/* + * Wrapper for xlsxio_read library functions. + */ + +#pragma once + +#include +#include + +#include "Export.h" + +/** + * \defgroup grp_xlsx_reader Xlsx file reader + * @ingroup grp_modules + */ +namespace DFHack +{ +namespace XlsxReader +{ + +typedef void* xlsx_file_handle; +typedef void* xlsx_sheet_handle; + +// returns NULL on error +DFHACK_EXPORT xlsx_file_handle open_xlsx_file(std::string filename); +DFHACK_EXPORT void close_xlsx_file(xlsx_file_handle file_handle); +DFHACK_EXPORT std::vector list_sheets(xlsx_file_handle file_handle); + +// returns XLSXIOReaderSheet object or NULL on error +DFHACK_EXPORT xlsx_sheet_handle open_sheet( + xlsx_file_handle file_handle, std::string sheet_name); +DFHACK_EXPORT void close_sheet(xlsx_sheet_handle sheet_handle); + +// start reading the next row of data; must be called before GetNextCell . +// returns false if there is no next row to get. +DFHACK_EXPORT bool get_next_row(xlsx_sheet_handle sheet_handle); + +// fills the value param with the contents of the cell in the next column cell +// in the current row. +// returns false if there are no more cells in this row. +DFHACK_EXPORT bool get_next_cell( + xlsx_sheet_handle sheet_handle, std::string& value); + +} +} diff --git a/library/modules/XlsxReader.cpp b/library/modules/XlsxReader.cpp new file mode 100644 index 000000000..d13582450 --- /dev/null +++ b/library/modules/XlsxReader.cpp @@ -0,0 +1,115 @@ +/* + * Wrapper for xlsxio_read library functions. + * + * Sample usage: + * + * std::string filename = "sample_file.xlsx"; + * xlsxioreader xlsxfile = XlsxReader::open_xlsx_file(filename); + * if (xlsxfile == NULL) { + * printf("cannot open file: '%s'", filename.c_str()); + * return false; + * } + * auto sheetNames = XlsxReader::list_sheets(xlsxfile); + * for (auto sheetName = sheetNames.begin(); + * sheetName != sheetNames.end(); + * ++sheetName) { + * printf("reading sheet: %s\n", sheetName->c_str()); + * xlsxioreadersheet xlsxsheet = + * XlsxReader::open_sheet(xlsxfile, *sheetName); + * if (xlsxsheet == NULL) { + * printf("cannot open sheet: '%s'", sheetName->c_str()); + * continue; + * } + * std::string value; + * int row_num = 1; + * while (XlsxReader::GetNextRow(xlsxsheet)) { + * std::string s; + * printf("%d:\t", row_num); + * while (XlsxReader::GetNextCell(xlsxsheet, s)) { + * printf("%s\t", s.c_str()); + * } + * printf("\n"); + * ++row_num; + * } + * XlsxReader::close_sheet(xlsxsheet); + * } + * XlsxReader::close_xlsx_file(xlsxfile); + * return true; + */ + +#include + +#include "modules/XlsxReader.h" + +using namespace DFHack; + + +// returns NULL on error +DFHACK_EXPORT XlsxReader::xlsx_file_handle XlsxReader::open_xlsx_file( + std::string filename) +{ + return xlsxioread_open(filename.c_str()); +} + +DFHACK_EXPORT void XlsxReader::close_xlsx_file( + XlsxReader::xlsx_file_handle file_handle) +{ + xlsxioread_close((xlsxioreader)file_handle); +} + +static int list_callback(const XLSXIOCHAR* name, void* cbdata) +{ + auto sheetNames = (std::vector *)cbdata; + sheetNames->push_back(name); + return 0; +} + +DFHACK_EXPORT std::vector XlsxReader::list_sheets( + XlsxReader::xlsx_file_handle file_handle) +{ + auto sheetNames = std::vector(); + xlsxioread_list_sheets( + (xlsxioreader)file_handle, list_callback, &sheetNames); + return sheetNames; +} + +// returns XLSXIOReaderSheet object or NULL on error +DFHACK_EXPORT XlsxReader::xlsx_sheet_handle XlsxReader::open_sheet( + XlsxReader::xlsx_file_handle file_handle, std::string sheet_name) +{ + if (file_handle == NULL) + return NULL; + return xlsxioread_sheet_open( + (xlsxioreader)file_handle, sheet_name.c_str(), XLSXIOREAD_SKIP_NONE); +} + +DFHACK_EXPORT void XlsxReader::close_sheet( + XlsxReader::xlsx_sheet_handle sheet_handle) +{ + xlsxioread_sheet_close((xlsxioreadersheet)sheet_handle); +} + +// start reading the next row of data; must be called before GetNextCell . +// returns false if there is no next row to get. +DFHACK_EXPORT bool XlsxReader::get_next_row( + XlsxReader::xlsx_sheet_handle sheet_handle) +{ + return xlsxioread_sheet_next_row((xlsxioreadersheet)sheet_handle) != 0; +} + +// fills the value param with the contents of the cell in the next column cell +// in the current row. +// returns false if there are no more cells in this row. +DFHACK_EXPORT bool XlsxReader::get_next_cell( + XlsxReader::xlsx_sheet_handle sheet_handle, std::string& value) +{ + char* result; + if (!xlsxioread_sheet_next_cell_string((xlsxioreadersheet)sheet_handle, + &result)) { + value.clear(); + return false; + } + value.assign(result); + free(result); + return true; +} From 8c7fb808e14f7cbfd0bbb5307f50202947061274 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 8 Aug 2020 17:55:49 -0700 Subject: [PATCH 268/547] get xlsxio Lua API working --- library/LuaApi.cpp | 44 +++++++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 30a084635..0265eee20 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -2486,39 +2486,57 @@ static const LuaWrapper::FunctionReg dfhack_kitchen_module[] = { static const LuaWrapper::FunctionReg dfhack_xlsxreader_module[] = { WRAPM(XlsxReader, open_xlsx_file), WRAPM(XlsxReader, close_xlsx_file), - WRAPM(XlsxReader, list_sheets), WRAPM(XlsxReader, open_sheet), WRAPM(XlsxReader, close_sheet), - WRAPM(XlsxReader, get_next_row), {NULL, NULL} }; -// takes the sheet handle and returns a string, or nil if there is no next cell -// in the current row. -static int xlsxreader_get_next_cell(lua_State *L) +// internal function to factor out handle extraction +static void * get_xlsxreader_handle(lua_State *L) { - if (lua_gettop(L) != 1 || lua_isnil(L, 1)) + if (lua_gettop(L) < 1 || lua_isnil(L, 1)) { - luaL_error(L, "invalid sheet handle"); + luaL_error(L, "invalid xlsxreader handle"); } - luaL_checktype(L, 1, LUA_TUSERDATA); - XlsxReader::xlsx_sheet_handle sheet_handle = lua_touserdata(L, 1); + luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); + return lua_touserdata(L, 1); +} + +// takes a file handle and returns a table-list of sheet names +static int xlsxreader_list_sheets(lua_State *L) +{ + XlsxReader::xlsx_file_handle file_handle = get_xlsxreader_handle(L); + Lua::PushVector(L, XlsxReader::list_sheets(file_handle), true); + return 1; +} - std::string value; - bool ok = XlsxReader::get_next_cell(sheet_handle, value); +// takes the sheet handle and returns a table-list of strings, or nil if we +// already processed the last row in the file. +static int xlsxreader_get_row(lua_State *L) +{ + XlsxReader::xlsx_sheet_handle sheet_handle = get_xlsxreader_handle(L); + bool ok = XlsxReader::get_next_row(sheet_handle); if (!ok) { lua_pushnil(L); } else { - lua_pushstring(L, value.c_str()); + std::string value; + auto cells = std::vector(); + while (XlsxReader::get_next_cell(sheet_handle, value)) + { + cells.push_back(value); + } + Lua::PushVector(L, cells, true); } + return 1; } static const luaL_Reg dfhack_xlsxreader_funcs[] = { - {"get_next_cell", xlsxreader_get_next_cell}, + {"list_sheets", xlsxreader_list_sheets}, + {"get_row", xlsxreader_get_row}, {NULL, NULL} }; From 4f0eb4bca6d80fb1d7f1822f509c4082a3e79158 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 8 Aug 2020 19:47:02 -0700 Subject: [PATCH 269/547] add libzip dep --- .gitmodules | 3 +++ depends/libzip | 1 + 2 files changed, 4 insertions(+) create mode 160000 depends/libzip diff --git a/.gitmodules b/.gitmodules index 0ccd3810a..b41fa0437 100644 --- a/.gitmodules +++ b/.gitmodules @@ -20,3 +20,6 @@ path = depends/xlsxio url = ../../brechtsanders/xlsxio.git shallow = true +[submodule "depends/libzip"] + path = depends/libzip + url = ../../nih-at/libzip.git diff --git a/depends/libzip b/depends/libzip new file mode 160000 index 000000000..2134d8c34 --- /dev/null +++ b/depends/libzip @@ -0,0 +1 @@ +Subproject commit 2134d8c34dbb8988076e8f2fc3b8be75fdb780bf From eeeb638c1c5641c94771601558321ccbb0e5f4c3 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 8 Aug 2020 19:48:11 -0700 Subject: [PATCH 270/547] fix libzip at v1.7.3 --- depends/libzip | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/libzip b/depends/libzip index 2134d8c34..66e496489 160000 --- a/depends/libzip +++ b/depends/libzip @@ -1 +1 @@ -Subproject commit 2134d8c34dbb8988076e8f2fc3b8be75fdb780bf +Subproject commit 66e496489bdae81bfda8b0088172871d8fda0032 From 28eaf0ae8b6eba53d164d5a642202e16cbd42ff8 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 8 Aug 2020 20:04:46 -0700 Subject: [PATCH 271/547] add libzip to the build --- CMakeLists.txt | 11 ++++++++--- depends/CMakeLists.txt | 9 +++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c9ada74a..490e1bb55 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -425,11 +425,16 @@ if(BUILD_LIBRARY) IMPORTED_LOCATION ${XLSXIO_INSTALL_DIR}/lib/libxlsxio_read.a) add_dependencies(xlsxio_read xlsxio_project) + ExternalProject_Get_Property(libzip_project INSTALL_DIR) + set(LIBZIP_INSTALL_DIR ${INSTALL_DIR}) + include_directories(${LIBZIP_INSTALL_DIR}/include) + add_library(zip STATIC IMPORTED) + set_target_properties(zip PROPERTIES + IMPORTED_LOCATION ${LIBZIP_INSTALL_DIR}/lib64/libzip.a) + add_dependencies(zip libzip_project) + # just pull from the system until I figure out how to integrate these deps # into the build - add_library(zip SHARED IMPORTED) - set_target_properties(zip PROPERTIES - IMPORTED_LOCATION /usr/lib64/libzip.so) add_library(expat SHARED IMPORTED) set_target_properties(expat PROPERTIES IMPORTED_LOCATION /usr/lib64/libexpat.so) diff --git a/depends/CMakeLists.txt b/depends/CMakeLists.txt index e43c80266..d5669080e 100644 --- a/depends/CMakeLists.txt +++ b/depends/CMakeLists.txt @@ -18,6 +18,15 @@ option(CLSOCKET_DEP_ONLY "Build for use inside other CMake projects as dependenc add_subdirectory(clsocket) ide_folder(clsocket "Depends") +set(LIBZIP_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/libzip) +ExternalProject_Add(libzip_project + PREFIX libzip + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libzip + INSTALL_DIR ${LIBZIP_INSTALL_DIR} + BUILD_BYPRODUCTS ${LIBZIP_INSTALL_DIR}/lib64/libzip.a + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBZIP_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_DOC=OFF -DBUILD_EXAMPLES=OFF -DBUILD_REGRESS=OFF -DBUILD_SHARED_LIBS=OFF -DBUILD_TOOLS=OFF -DENABLE_BZIP2=OFF -DENABLE_COMMONCRYPTO=OFF -DENABLE_GNUTLS=OFF -DENABLE_LZMA=OFF -DENABLE_MBEDTLS=OFF -DENABLE_OPENSSL=OFF -DENABLE_WINDOWS_CRYPTO=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON +) + set(XLSXIO_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/xlsxio) ExternalProject_Add(xlsxio_project PREFIX xlsxio From cffac8ed93078d1d3e22087d3e5f415466b4004a Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 8 Aug 2020 20:07:54 -0700 Subject: [PATCH 272/547] fix line endings in XlsxReader.cpp --- library/modules/XlsxReader.cpp | 230 ++++++++++++++++----------------- 1 file changed, 115 insertions(+), 115 deletions(-) diff --git a/library/modules/XlsxReader.cpp b/library/modules/XlsxReader.cpp index d13582450..405369c85 100644 --- a/library/modules/XlsxReader.cpp +++ b/library/modules/XlsxReader.cpp @@ -1,115 +1,115 @@ -/* - * Wrapper for xlsxio_read library functions. - * - * Sample usage: - * - * std::string filename = "sample_file.xlsx"; - * xlsxioreader xlsxfile = XlsxReader::open_xlsx_file(filename); - * if (xlsxfile == NULL) { - * printf("cannot open file: '%s'", filename.c_str()); - * return false; - * } - * auto sheetNames = XlsxReader::list_sheets(xlsxfile); - * for (auto sheetName = sheetNames.begin(); - * sheetName != sheetNames.end(); - * ++sheetName) { - * printf("reading sheet: %s\n", sheetName->c_str()); - * xlsxioreadersheet xlsxsheet = - * XlsxReader::open_sheet(xlsxfile, *sheetName); - * if (xlsxsheet == NULL) { - * printf("cannot open sheet: '%s'", sheetName->c_str()); - * continue; - * } - * std::string value; - * int row_num = 1; - * while (XlsxReader::GetNextRow(xlsxsheet)) { - * std::string s; - * printf("%d:\t", row_num); - * while (XlsxReader::GetNextCell(xlsxsheet, s)) { - * printf("%s\t", s.c_str()); - * } - * printf("\n"); - * ++row_num; - * } - * XlsxReader::close_sheet(xlsxsheet); - * } - * XlsxReader::close_xlsx_file(xlsxfile); - * return true; - */ - -#include - -#include "modules/XlsxReader.h" - -using namespace DFHack; - - -// returns NULL on error -DFHACK_EXPORT XlsxReader::xlsx_file_handle XlsxReader::open_xlsx_file( - std::string filename) -{ - return xlsxioread_open(filename.c_str()); -} - -DFHACK_EXPORT void XlsxReader::close_xlsx_file( - XlsxReader::xlsx_file_handle file_handle) -{ - xlsxioread_close((xlsxioreader)file_handle); -} - -static int list_callback(const XLSXIOCHAR* name, void* cbdata) -{ - auto sheetNames = (std::vector *)cbdata; - sheetNames->push_back(name); - return 0; -} - -DFHACK_EXPORT std::vector XlsxReader::list_sheets( - XlsxReader::xlsx_file_handle file_handle) -{ - auto sheetNames = std::vector(); - xlsxioread_list_sheets( - (xlsxioreader)file_handle, list_callback, &sheetNames); - return sheetNames; -} - -// returns XLSXIOReaderSheet object or NULL on error -DFHACK_EXPORT XlsxReader::xlsx_sheet_handle XlsxReader::open_sheet( - XlsxReader::xlsx_file_handle file_handle, std::string sheet_name) -{ - if (file_handle == NULL) - return NULL; - return xlsxioread_sheet_open( - (xlsxioreader)file_handle, sheet_name.c_str(), XLSXIOREAD_SKIP_NONE); -} - -DFHACK_EXPORT void XlsxReader::close_sheet( - XlsxReader::xlsx_sheet_handle sheet_handle) -{ - xlsxioread_sheet_close((xlsxioreadersheet)sheet_handle); -} - -// start reading the next row of data; must be called before GetNextCell . -// returns false if there is no next row to get. -DFHACK_EXPORT bool XlsxReader::get_next_row( - XlsxReader::xlsx_sheet_handle sheet_handle) -{ - return xlsxioread_sheet_next_row((xlsxioreadersheet)sheet_handle) != 0; -} - -// fills the value param with the contents of the cell in the next column cell -// in the current row. -// returns false if there are no more cells in this row. -DFHACK_EXPORT bool XlsxReader::get_next_cell( - XlsxReader::xlsx_sheet_handle sheet_handle, std::string& value) -{ - char* result; - if (!xlsxioread_sheet_next_cell_string((xlsxioreadersheet)sheet_handle, - &result)) { - value.clear(); - return false; - } - value.assign(result); - free(result); - return true; -} +/* + * Wrapper for xlsxio_read library functions. + * + * Sample usage: + * + * std::string filename = "sample_file.xlsx"; + * xlsxioreader xlsxfile = XlsxReader::open_xlsx_file(filename); + * if (xlsxfile == NULL) { + * printf("cannot open file: '%s'", filename.c_str()); + * return false; + * } + * auto sheetNames = XlsxReader::list_sheets(xlsxfile); + * for (auto sheetName = sheetNames.begin(); + * sheetName != sheetNames.end(); + * ++sheetName) { + * printf("reading sheet: %s\n", sheetName->c_str()); + * xlsxioreadersheet xlsxsheet = + * XlsxReader::open_sheet(xlsxfile, *sheetName); + * if (xlsxsheet == NULL) { + * printf("cannot open sheet: '%s'", sheetName->c_str()); + * continue; + * } + * std::string value; + * int row_num = 1; + * while (XlsxReader::GetNextRow(xlsxsheet)) { + * std::string s; + * printf("%d:\t", row_num); + * while (XlsxReader::GetNextCell(xlsxsheet, s)) { + * printf("%s\t", s.c_str()); + * } + * printf("\n"); + * ++row_num; + * } + * XlsxReader::close_sheet(xlsxsheet); + * } + * XlsxReader::close_xlsx_file(xlsxfile); + * return true; + */ + +#include + +#include "modules/XlsxReader.h" + +using namespace DFHack; + + +// returns NULL on error +DFHACK_EXPORT XlsxReader::xlsx_file_handle XlsxReader::open_xlsx_file( + std::string filename) +{ + return xlsxioread_open(filename.c_str()); +} + +DFHACK_EXPORT void XlsxReader::close_xlsx_file( + XlsxReader::xlsx_file_handle file_handle) +{ + xlsxioread_close((xlsxioreader)file_handle); +} + +static int list_callback(const XLSXIOCHAR* name, void* cbdata) +{ + auto sheetNames = (std::vector *)cbdata; + sheetNames->push_back(name); + return 0; +} + +DFHACK_EXPORT std::vector XlsxReader::list_sheets( + XlsxReader::xlsx_file_handle file_handle) +{ + auto sheetNames = std::vector(); + xlsxioread_list_sheets( + (xlsxioreader)file_handle, list_callback, &sheetNames); + return sheetNames; +} + +// returns XLSXIOReaderSheet object or NULL on error +DFHACK_EXPORT XlsxReader::xlsx_sheet_handle XlsxReader::open_sheet( + XlsxReader::xlsx_file_handle file_handle, std::string sheet_name) +{ + if (file_handle == NULL) + return NULL; + return xlsxioread_sheet_open( + (xlsxioreader)file_handle, sheet_name.c_str(), XLSXIOREAD_SKIP_NONE); +} + +DFHACK_EXPORT void XlsxReader::close_sheet( + XlsxReader::xlsx_sheet_handle sheet_handle) +{ + xlsxioread_sheet_close((xlsxioreadersheet)sheet_handle); +} + +// start reading the next row of data; must be called before GetNextCell . +// returns false if there is no next row to get. +DFHACK_EXPORT bool XlsxReader::get_next_row( + XlsxReader::xlsx_sheet_handle sheet_handle) +{ + return xlsxioread_sheet_next_row((xlsxioreadersheet)sheet_handle) != 0; +} + +// fills the value param with the contents of the cell in the next column cell +// in the current row. +// returns false if there are no more cells in this row. +DFHACK_EXPORT bool XlsxReader::get_next_cell( + XlsxReader::xlsx_sheet_handle sheet_handle, std::string& value) +{ + char* result; + if (!xlsxioread_sheet_next_cell_string((xlsxioreadersheet)sheet_handle, + &result)) { + value.clear(); + return false; + } + value.assign(result); + free(result); + return true; +} From 8de39c2d7d1c64631043eab751d0ce4787b65612 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 8 Aug 2020 20:09:29 -0700 Subject: [PATCH 273/547] add libexpat as a submodule --- .gitmodules | 5 +++++ depends/libexpat | 1 + 2 files changed, 6 insertions(+) create mode 160000 depends/libexpat diff --git a/.gitmodules b/.gitmodules index b41fa0437..e24bfb707 100644 --- a/.gitmodules +++ b/.gitmodules @@ -23,3 +23,8 @@ [submodule "depends/libzip"] path = depends/libzip url = ../../nih-at/libzip.git + shallow = true +[submodule "depends/libexpat"] + path = depends/libexpat + url = ../../libexpat/libexpat.git + shallow = true diff --git a/depends/libexpat b/depends/libexpat new file mode 160000 index 000000000..990e3d07e --- /dev/null +++ b/depends/libexpat @@ -0,0 +1 @@ +Subproject commit 990e3d07eaa127007f9d304a9b4c6ffadc61b1fe From e7afc4cfeb6d8c0e4670e7d517b926f2164dbbac Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 8 Aug 2020 20:10:13 -0700 Subject: [PATCH 274/547] fix libexpat at v2.2.9 --- depends/libexpat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/libexpat b/depends/libexpat index 990e3d07e..a7bc26b69 160000 --- a/depends/libexpat +++ b/depends/libexpat @@ -1 +1 @@ -Subproject commit 990e3d07eaa127007f9d304a9b4c6ffadc61b1fe +Subproject commit a7bc26b69768f7fb24f0c7976fae24b157b85b13 From 8a05f09cd612249897c8767d4acc0f6ac956d92b Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 8 Aug 2020 20:18:43 -0700 Subject: [PATCH 275/547] add libexpat to the build --- CMakeLists.txt | 10 ++++++---- depends/CMakeLists.txt | 15 ++++++++++++--- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 490e1bb55..5dcd87b56 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -433,11 +433,13 @@ if(BUILD_LIBRARY) IMPORTED_LOCATION ${LIBZIP_INSTALL_DIR}/lib64/libzip.a) add_dependencies(zip libzip_project) - # just pull from the system until I figure out how to integrate these deps - # into the build - add_library(expat SHARED IMPORTED) + ExternalProject_Get_Property(libexpat_project INSTALL_DIR) + set(LIBEXPAT_INSTALL_DIR ${INSTALL_DIR}) + include_directories(${LIBEXPAT_INSTALL_DIR}/include) + add_library(expat STATIC IMPORTED) set_target_properties(expat PROPERTIES - IMPORTED_LOCATION /usr/lib64/libexpat.so) + IMPORTED_LOCATION ${LIBEXPAT_INSTALL_DIR}/lib64/libexpat.a) + add_dependencies(expat libexpat_project) add_subdirectory(library) install(FILES LICENSE.rst docs/changelog.txt DESTINATION ${DFHACK_USERDOC_DESTINATION}) diff --git a/depends/CMakeLists.txt b/depends/CMakeLists.txt index d5669080e..9735e7fc7 100644 --- a/depends/CMakeLists.txt +++ b/depends/CMakeLists.txt @@ -18,6 +18,15 @@ option(CLSOCKET_DEP_ONLY "Build for use inside other CMake projects as dependenc add_subdirectory(clsocket) ide_folder(clsocket "Depends") +set(LIBEXPAT_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/libexpat) +ExternalProject_Add(libexpat_project + PREFIX libexpat + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libexpat/expat + INSTALL_DIR ${LIBEXPAT_INSTALL_DIR} + BUILD_BYPRODUCTS ${LIBEXPAT_INSTALL_DIR}/lib64/libexpat.a + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBEXPAT_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DEXPAT_BUILD_EXAMPLES=OFF -DEXPAT_BUILD_TESTS=OFF -DEXPAT_BUILD_TOOLS=OFF -DEXPAT_SHARED_LIBS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON +) + set(LIBZIP_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/libzip) ExternalProject_Add(libzip_project PREFIX libzip @@ -33,7 +42,7 @@ ExternalProject_Add(xlsxio_project SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/xlsxio INSTALL_DIR ${XLSXIO_INSTALL_DIR} BUILD_BYPRODUCTS ${XLSXIO_INSTALL_DIR}/lib/libxlsxio_read.a - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${XLSXIO_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_STATIC=ON -DBUILD_SHARED=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_TOOLS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_DOCUMENTATION=OFF -DWITH_LIBZIP=ON -DZLIB_DIR=${ZLIB_DIR} + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${XLSXIO_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_STATIC=ON -DBUILD_SHARED=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_TOOLS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_DOCUMENTATION=OFF -DWITH_LIBZIP=ON -DZLIB_DIR=${ZLIB_DIR} -DLIBZIP_DIR=${LIBZIP_INSTALL_DIR} -DEXPAT_DIR=${LIBEXPAT_INSTALL_DIR} ) - #-DLIBZIP_DIR= - #-DEXPAT_DIR= +add_dependencies(xlsxio_project libexpat_project) +add_dependencies(xlsxio_project libzip_project) From 8753f9feaff9df8367e6031e2cc299014dac1d55 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 8 Aug 2020 20:42:03 -0700 Subject: [PATCH 276/547] use correct lib dir on 32-bit --- CMakeLists.txt | 15 +++++++++------ depends/CMakeLists.txt | 10 ++++++++-- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5dcd87b56..dbd028a36 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -419,26 +419,29 @@ endif() if(BUILD_LIBRARY) ExternalProject_Get_Property(xlsxio_project INSTALL_DIR) set(XLSXIO_INSTALL_DIR ${INSTALL_DIR}) + ExternalProject_Get_Property(xlsxio_project BUILD_BYPRODUCTS) + set(XLSXIO_LIB ${BUILD_BYPRODUCTS}) include_directories(${XLSXIO_INSTALL_DIR}/include) add_library(xlsxio_read STATIC IMPORTED) - set_target_properties(xlsxio_read PROPERTIES - IMPORTED_LOCATION ${XLSXIO_INSTALL_DIR}/lib/libxlsxio_read.a) + set_target_properties(xlsxio_read PROPERTIES IMPORTED_LOCATION ${XLSXIO_LIB}) add_dependencies(xlsxio_read xlsxio_project) ExternalProject_Get_Property(libzip_project INSTALL_DIR) set(LIBZIP_INSTALL_DIR ${INSTALL_DIR}) + ExternalProject_Get_Property(libzip_project BUILD_BYPRODUCTS) + set(LIBZIP_LIB ${BUILD_BYPRODUCTS}) include_directories(${LIBZIP_INSTALL_DIR}/include) add_library(zip STATIC IMPORTED) - set_target_properties(zip PROPERTIES - IMPORTED_LOCATION ${LIBZIP_INSTALL_DIR}/lib64/libzip.a) + set_target_properties(zip PROPERTIES IMPORTED_LOCATION ${LIBZIP_LIB}) add_dependencies(zip libzip_project) ExternalProject_Get_Property(libexpat_project INSTALL_DIR) set(LIBEXPAT_INSTALL_DIR ${INSTALL_DIR}) + ExternalProject_Get_Property(libexpat_project BUILD_BYPRODUCTS) + set(LIBEXPAT_LIB ${BUILD_BYPRODUCTS}) include_directories(${LIBEXPAT_INSTALL_DIR}/include) add_library(expat STATIC IMPORTED) - set_target_properties(expat PROPERTIES - IMPORTED_LOCATION ${LIBEXPAT_INSTALL_DIR}/lib64/libexpat.a) + set_target_properties(expat PROPERTIES IMPORTED_LOCATION ${LIBEXPAT_LIB}) add_dependencies(expat libexpat_project) add_subdirectory(library) diff --git a/depends/CMakeLists.txt b/depends/CMakeLists.txt index 9735e7fc7..4b11f4110 100644 --- a/depends/CMakeLists.txt +++ b/depends/CMakeLists.txt @@ -18,12 +18,18 @@ option(CLSOCKET_DEP_ONLY "Build for use inside other CMake projects as dependenc add_subdirectory(clsocket) ide_folder(clsocket "Depends") +if("${DFHACK_BUILD_ARCH}" STREQUAL "64") + set(OUTPUT_LIB_DIR "lib64") +else() + set(OUTPUT_LIB_DIR "lib") +endif() + set(LIBEXPAT_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/libexpat) ExternalProject_Add(libexpat_project PREFIX libexpat SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libexpat/expat INSTALL_DIR ${LIBEXPAT_INSTALL_DIR} - BUILD_BYPRODUCTS ${LIBEXPAT_INSTALL_DIR}/lib64/libexpat.a + BUILD_BYPRODUCTS ${LIBEXPAT_INSTALL_DIR}/${OUTPUT_LIB_DIR}/libexpat.a CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBEXPAT_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DEXPAT_BUILD_EXAMPLES=OFF -DEXPAT_BUILD_TESTS=OFF -DEXPAT_BUILD_TOOLS=OFF -DEXPAT_SHARED_LIBS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON ) @@ -32,7 +38,7 @@ ExternalProject_Add(libzip_project PREFIX libzip SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libzip INSTALL_DIR ${LIBZIP_INSTALL_DIR} - BUILD_BYPRODUCTS ${LIBZIP_INSTALL_DIR}/lib64/libzip.a + BUILD_BYPRODUCTS ${LIBZIP_INSTALL_DIR}/${OUTPUT_LIB_DIR}/libzip.a CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBZIP_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_DOC=OFF -DBUILD_EXAMPLES=OFF -DBUILD_REGRESS=OFF -DBUILD_SHARED_LIBS=OFF -DBUILD_TOOLS=OFF -DENABLE_BZIP2=OFF -DENABLE_COMMONCRYPTO=OFF -DENABLE_GNUTLS=OFF -DENABLE_LZMA=OFF -DENABLE_MBEDTLS=OFF -DENABLE_OPENSSL=OFF -DENABLE_WINDOWS_CRYPTO=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON ) From d65504eb828e76bdff7348c15e3d6a1629942524 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 8 Aug 2020 21:19:38 -0700 Subject: [PATCH 277/547] ensure CFLAGS and CXXFLAGS get propagated to deps --- depends/CMakeLists.txt | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/depends/CMakeLists.txt b/depends/CMakeLists.txt index 4b11f4110..2e2872d20 100644 --- a/depends/CMakeLists.txt +++ b/depends/CMakeLists.txt @@ -18,19 +18,13 @@ option(CLSOCKET_DEP_ONLY "Build for use inside other CMake projects as dependenc add_subdirectory(clsocket) ide_folder(clsocket "Depends") -if("${DFHACK_BUILD_ARCH}" STREQUAL "64") - set(OUTPUT_LIB_DIR "lib64") -else() - set(OUTPUT_LIB_DIR "lib") -endif() - set(LIBEXPAT_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/libexpat) ExternalProject_Add(libexpat_project PREFIX libexpat SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libexpat/expat INSTALL_DIR ${LIBEXPAT_INSTALL_DIR} - BUILD_BYPRODUCTS ${LIBEXPAT_INSTALL_DIR}/${OUTPUT_LIB_DIR}/libexpat.a - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBEXPAT_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DEXPAT_BUILD_EXAMPLES=OFF -DEXPAT_BUILD_TESTS=OFF -DEXPAT_BUILD_TOOLS=OFF -DEXPAT_SHARED_LIBS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON + BUILD_BYPRODUCTS ${LIBEXPAT_INSTALL_DIR}/lib/libexpat.a + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBEXPAT_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DEXPAT_BUILD_EXAMPLES=OFF -DEXPAT_BUILD_TESTS=OFF -DEXPAT_BUILD_TOOLS=OFF -DEXPAT_SHARED_LIBS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} ) set(LIBZIP_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/libzip) @@ -38,8 +32,8 @@ ExternalProject_Add(libzip_project PREFIX libzip SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libzip INSTALL_DIR ${LIBZIP_INSTALL_DIR} - BUILD_BYPRODUCTS ${LIBZIP_INSTALL_DIR}/${OUTPUT_LIB_DIR}/libzip.a - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBZIP_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_DOC=OFF -DBUILD_EXAMPLES=OFF -DBUILD_REGRESS=OFF -DBUILD_SHARED_LIBS=OFF -DBUILD_TOOLS=OFF -DENABLE_BZIP2=OFF -DENABLE_COMMONCRYPTO=OFF -DENABLE_GNUTLS=OFF -DENABLE_LZMA=OFF -DENABLE_MBEDTLS=OFF -DENABLE_OPENSSL=OFF -DENABLE_WINDOWS_CRYPTO=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON + BUILD_BYPRODUCTS ${LIBZIP_INSTALL_DIR}/lib/libzip.a + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBZIP_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_DOC=OFF -DBUILD_EXAMPLES=OFF -DBUILD_REGRESS=OFF -DBUILD_SHARED_LIBS=OFF -DBUILD_TOOLS=OFF -DENABLE_BZIP2=OFF -DENABLE_COMMONCRYPTO=OFF -DENABLE_GNUTLS=OFF -DENABLE_LZMA=OFF -DENABLE_MBEDTLS=OFF -DENABLE_OPENSSL=OFF -DENABLE_WINDOWS_CRYPTO=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} ) set(XLSXIO_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/xlsxio) @@ -48,7 +42,7 @@ ExternalProject_Add(xlsxio_project SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/xlsxio INSTALL_DIR ${XLSXIO_INSTALL_DIR} BUILD_BYPRODUCTS ${XLSXIO_INSTALL_DIR}/lib/libxlsxio_read.a - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${XLSXIO_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_STATIC=ON -DBUILD_SHARED=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_TOOLS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_DOCUMENTATION=OFF -DWITH_LIBZIP=ON -DZLIB_DIR=${ZLIB_DIR} -DLIBZIP_DIR=${LIBZIP_INSTALL_DIR} -DEXPAT_DIR=${LIBEXPAT_INSTALL_DIR} + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${XLSXIO_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_STATIC=ON -DBUILD_SHARED=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_TOOLS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_DOCUMENTATION=OFF -DWITH_LIBZIP=ON -DZLIB_DIR=${ZLIB_DIR} -DLIBZIP_DIR=${LIBZIP_INSTALL_DIR} -DEXPAT_DIR=${LIBEXPAT_INSTALL_DIR} -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} ) add_dependencies(xlsxio_project libexpat_project) add_dependencies(xlsxio_project libzip_project) From 1cfe2735d3eb59a006efb110641954f0fd1e1b9a Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 8 Aug 2020 22:03:42 -0700 Subject: [PATCH 278/547] build deps in verbose mode for debugging --- depends/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/depends/CMakeLists.txt b/depends/CMakeLists.txt index 2e2872d20..2e5dde062 100644 --- a/depends/CMakeLists.txt +++ b/depends/CMakeLists.txt @@ -24,7 +24,7 @@ ExternalProject_Add(libexpat_project SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libexpat/expat INSTALL_DIR ${LIBEXPAT_INSTALL_DIR} BUILD_BYPRODUCTS ${LIBEXPAT_INSTALL_DIR}/lib/libexpat.a - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBEXPAT_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DEXPAT_BUILD_EXAMPLES=OFF -DEXPAT_BUILD_TESTS=OFF -DEXPAT_BUILD_TOOLS=OFF -DEXPAT_SHARED_LIBS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBEXPAT_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DEXPAT_BUILD_EXAMPLES=OFF -DEXPAT_BUILD_TESTS=OFF -DEXPAT_BUILD_TOOLS=OFF -DEXPAT_SHARED_LIBS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON ) set(LIBZIP_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/libzip) @@ -33,7 +33,7 @@ ExternalProject_Add(libzip_project SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libzip INSTALL_DIR ${LIBZIP_INSTALL_DIR} BUILD_BYPRODUCTS ${LIBZIP_INSTALL_DIR}/lib/libzip.a - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBZIP_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_DOC=OFF -DBUILD_EXAMPLES=OFF -DBUILD_REGRESS=OFF -DBUILD_SHARED_LIBS=OFF -DBUILD_TOOLS=OFF -DENABLE_BZIP2=OFF -DENABLE_COMMONCRYPTO=OFF -DENABLE_GNUTLS=OFF -DENABLE_LZMA=OFF -DENABLE_MBEDTLS=OFF -DENABLE_OPENSSL=OFF -DENABLE_WINDOWS_CRYPTO=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBZIP_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_DOC=OFF -DBUILD_EXAMPLES=OFF -DBUILD_REGRESS=OFF -DBUILD_SHARED_LIBS=OFF -DBUILD_TOOLS=OFF -DENABLE_BZIP2=OFF -DENABLE_COMMONCRYPTO=OFF -DENABLE_GNUTLS=OFF -DENABLE_LZMA=OFF -DENABLE_MBEDTLS=OFF -DENABLE_OPENSSL=OFF -DENABLE_WINDOWS_CRYPTO=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON ) set(XLSXIO_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/xlsxio) @@ -42,7 +42,7 @@ ExternalProject_Add(xlsxio_project SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/xlsxio INSTALL_DIR ${XLSXIO_INSTALL_DIR} BUILD_BYPRODUCTS ${XLSXIO_INSTALL_DIR}/lib/libxlsxio_read.a - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${XLSXIO_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_STATIC=ON -DBUILD_SHARED=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_TOOLS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_DOCUMENTATION=OFF -DWITH_LIBZIP=ON -DZLIB_DIR=${ZLIB_DIR} -DLIBZIP_DIR=${LIBZIP_INSTALL_DIR} -DEXPAT_DIR=${LIBEXPAT_INSTALL_DIR} -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${XLSXIO_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_STATIC=ON -DBUILD_SHARED=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_TOOLS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_DOCUMENTATION=OFF -DWITH_LIBZIP=ON -DZLIB_DIR=${ZLIB_DIR} -DLIBZIP_DIR=${LIBZIP_INSTALL_DIR} -DEXPAT_DIR=${LIBEXPAT_INSTALL_DIR} -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON ) add_dependencies(xlsxio_project libexpat_project) add_dependencies(xlsxio_project libzip_project) From 8d157012d0a43c1a2fe0518a274cd28598c50fbf Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 8 Aug 2020 22:04:49 -0700 Subject: [PATCH 279/547] build dfhack with verbosity on too --- library/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 583c8768f..c78f7f58e 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -4,6 +4,8 @@ cmake_minimum_required(VERSION 2.8.12) # prevent CMake warnings about INTERFACE_LINK_LIBRARIES vs LINK_INTERFACE_LIBRARIES cmake_policy(SET CMP0022 NEW) +set(CMAKE_VERBOSE_MAKEFILE ON) + # build options option(BUILD_DEVEL "Install/package files required for development(For SDK)." OFF) if(UNIX) From b0cb40c5ea2941287450c1fd9352a40c2e50a49d Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 8 Aug 2020 22:42:50 -0700 Subject: [PATCH 280/547] pass the cmake environment to deps --- depends/CMakeLists.txt | 16 +++++++++++++--- library/CMakeLists.txt | 2 -- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/depends/CMakeLists.txt b/depends/CMakeLists.txt index 2e5dde062..87e9d74bf 100644 --- a/depends/CMakeLists.txt +++ b/depends/CMakeLists.txt @@ -18,13 +18,23 @@ option(CLSOCKET_DEP_ONLY "Build for use inside other CMake projects as dependenc add_subdirectory(clsocket) ide_folder(clsocket "Depends") +# assemble environment args to pass on to dependency projects +get_cmake_property(vars CACHE_VARIABLES) +foreach(var ${vars}) + get_property(currentHelpString CACHE "${var}" PROPERTY HELPSTRING) + if("${currentHelpString}" MATCHES "No help, variable specified on the command line." OR "${currentHelpString}" STREQUAL "") + message("${var} = [${${var}}] -- ${currentHelpString}") # uncomment to see the variables being processed + list(APPEND CL_ARGS "-D${var}=${${var}}") + endif() +endforeach() + set(LIBEXPAT_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/libexpat) ExternalProject_Add(libexpat_project PREFIX libexpat SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libexpat/expat INSTALL_DIR ${LIBEXPAT_INSTALL_DIR} BUILD_BYPRODUCTS ${LIBEXPAT_INSTALL_DIR}/lib/libexpat.a - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBEXPAT_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DEXPAT_BUILD_EXAMPLES=OFF -DEXPAT_BUILD_TESTS=OFF -DEXPAT_BUILD_TOOLS=OFF -DEXPAT_SHARED_LIBS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON + CMAKE_ARGS ${CL_ARGS} -DCMAKE_INSTALL_PREFIX=${LIBEXPAT_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DEXPAT_BUILD_EXAMPLES=OFF -DEXPAT_BUILD_TESTS=OFF -DEXPAT_BUILD_TOOLS=OFF -DEXPAT_SHARED_LIBS=OFF -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON ) set(LIBZIP_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/libzip) @@ -33,7 +43,7 @@ ExternalProject_Add(libzip_project SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libzip INSTALL_DIR ${LIBZIP_INSTALL_DIR} BUILD_BYPRODUCTS ${LIBZIP_INSTALL_DIR}/lib/libzip.a - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBZIP_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_DOC=OFF -DBUILD_EXAMPLES=OFF -DBUILD_REGRESS=OFF -DBUILD_SHARED_LIBS=OFF -DBUILD_TOOLS=OFF -DENABLE_BZIP2=OFF -DENABLE_COMMONCRYPTO=OFF -DENABLE_GNUTLS=OFF -DENABLE_LZMA=OFF -DENABLE_MBEDTLS=OFF -DENABLE_OPENSSL=OFF -DENABLE_WINDOWS_CRYPTO=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON + CMAKE_ARGS ${CL_ARGS} -DCMAKE_INSTALL_PREFIX=${LIBZIP_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_DOC=OFF -DBUILD_EXAMPLES=OFF -DBUILD_REGRESS=OFF -DBUILD_SHARED_LIBS=OFF -DBUILD_TOOLS=OFF -DENABLE_BZIP2=OFF -DENABLE_COMMONCRYPTO=OFF -DENABLE_GNUTLS=OFF -DENABLE_LZMA=OFF -DENABLE_MBEDTLS=OFF -DENABLE_OPENSSL=OFF -DENABLE_WINDOWS_CRYPTO=OFF -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON ) set(XLSXIO_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/xlsxio) @@ -42,7 +52,7 @@ ExternalProject_Add(xlsxio_project SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/xlsxio INSTALL_DIR ${XLSXIO_INSTALL_DIR} BUILD_BYPRODUCTS ${XLSXIO_INSTALL_DIR}/lib/libxlsxio_read.a - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${XLSXIO_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_STATIC=ON -DBUILD_SHARED=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_TOOLS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_DOCUMENTATION=OFF -DWITH_LIBZIP=ON -DZLIB_DIR=${ZLIB_DIR} -DLIBZIP_DIR=${LIBZIP_INSTALL_DIR} -DEXPAT_DIR=${LIBEXPAT_INSTALL_DIR} -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON + CMAKE_ARGS ${CL_ARGS} -DCMAKE_INSTALL_PREFIX=${XLSXIO_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_STATIC=ON -DBUILD_SHARED=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_TOOLS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_DOCUMENTATION=OFF -DWITH_LIBZIP=ON -DZLIB_DIR=${ZLIB_DIR} -DLIBZIP_DIR=${LIBZIP_INSTALL_DIR} -DEXPAT_DIR=${LIBEXPAT_INSTALL_DIR} -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON ) add_dependencies(xlsxio_project libexpat_project) add_dependencies(xlsxio_project libzip_project) diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index c78f7f58e..583c8768f 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -4,8 +4,6 @@ cmake_minimum_required(VERSION 2.8.12) # prevent CMake warnings about INTERFACE_LINK_LIBRARIES vs LINK_INTERFACE_LIBRARIES cmake_policy(SET CMP0022 NEW) -set(CMAKE_VERBOSE_MAKEFILE ON) - # build options option(BUILD_DEVEL "Install/package files required for development(For SDK)." OFF) if(UNIX) From 51794d91eda59faeadd1190b96a55f922f881b07 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 8 Aug 2020 23:55:24 -0700 Subject: [PATCH 281/547] really get the env vars --- depends/CMakeLists.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/depends/CMakeLists.txt b/depends/CMakeLists.txt index 87e9d74bf..f2ccff398 100644 --- a/depends/CMakeLists.txt +++ b/depends/CMakeLists.txt @@ -21,12 +21,12 @@ ide_folder(clsocket "Depends") # assemble environment args to pass on to dependency projects get_cmake_property(vars CACHE_VARIABLES) foreach(var ${vars}) - get_property(currentHelpString CACHE "${var}" PROPERTY HELPSTRING) - if("${currentHelpString}" MATCHES "No help, variable specified on the command line." OR "${currentHelpString}" STREQUAL "") - message("${var} = [${${var}}] -- ${currentHelpString}") # uncomment to see the variables being processed - list(APPEND CL_ARGS "-D${var}=${${var}}") - endif() + if(var MATCHES "^CMAKE_" AND NOT var MATCHES "^CMAKE_CACHE" AND NOT var MATCHES "^CMAKE_HOME" AND NOT var MATCHES "^CMAKE_PROJECT") + message("${var} = [${${var}}]") + list(APPEND CL_ARGS "-D${var}=${${var}}") + endif() endforeach() +message("final CL_ARGS = ${CL_ARGS}") set(LIBEXPAT_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/libexpat) ExternalProject_Add(libexpat_project From bb988d25e674ede1d2fe74af18a0885708d7f156 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sun, 9 Aug 2020 00:24:25 -0700 Subject: [PATCH 282/547] try to get the library suffix right for windows --- depends/CMakeLists.txt | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/depends/CMakeLists.txt b/depends/CMakeLists.txt index f2ccff398..7e0a4027b 100644 --- a/depends/CMakeLists.txt +++ b/depends/CMakeLists.txt @@ -21,19 +21,31 @@ ide_folder(clsocket "Depends") # assemble environment args to pass on to dependency projects get_cmake_property(vars CACHE_VARIABLES) foreach(var ${vars}) - if(var MATCHES "^CMAKE_" AND NOT var MATCHES "^CMAKE_CACHE" AND NOT var MATCHES "^CMAKE_HOME" AND NOT var MATCHES "^CMAKE_PROJECT") + if(var MATCHES "^CMAKE_" + AND NOT var MATCHES "^CMAKE_CACHE" + AND NOT var MATCHES "^CMAKE_HOME" + AND NOT var MATCHES "^CMAKE_PROJECT") + message("${var} = [${${var}}]") + list(APPEND CL_ARGS "-D${var}=${${var}}") + endif() + if(var MATCHES "^ZLIB") message("${var} = [${${var}}]") list(APPEND CL_ARGS "-D${var}=${${var}}") endif() endforeach() -message("final CL_ARGS = ${CL_ARGS}") + +if(WIN32) + set(LIB_SUFFIX "MD.lib") +else() + set(LIB_SUFFIX ".a") +endif() set(LIBEXPAT_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/libexpat) ExternalProject_Add(libexpat_project PREFIX libexpat SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libexpat/expat INSTALL_DIR ${LIBEXPAT_INSTALL_DIR} - BUILD_BYPRODUCTS ${LIBEXPAT_INSTALL_DIR}/lib/libexpat.a + BUILD_BYPRODUCTS ${LIBEXPAT_INSTALL_DIR}/lib/libexpat${LIB_SUFFIX} CMAKE_ARGS ${CL_ARGS} -DCMAKE_INSTALL_PREFIX=${LIBEXPAT_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DEXPAT_BUILD_EXAMPLES=OFF -DEXPAT_BUILD_TESTS=OFF -DEXPAT_BUILD_TOOLS=OFF -DEXPAT_SHARED_LIBS=OFF -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON ) @@ -42,7 +54,7 @@ ExternalProject_Add(libzip_project PREFIX libzip SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libzip INSTALL_DIR ${LIBZIP_INSTALL_DIR} - BUILD_BYPRODUCTS ${LIBZIP_INSTALL_DIR}/lib/libzip.a + BUILD_BYPRODUCTS ${LIBZIP_INSTALL_DIR}/lib/libzip${LIB_SUFFIX} CMAKE_ARGS ${CL_ARGS} -DCMAKE_INSTALL_PREFIX=${LIBZIP_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_DOC=OFF -DBUILD_EXAMPLES=OFF -DBUILD_REGRESS=OFF -DBUILD_SHARED_LIBS=OFF -DBUILD_TOOLS=OFF -DENABLE_BZIP2=OFF -DENABLE_COMMONCRYPTO=OFF -DENABLE_GNUTLS=OFF -DENABLE_LZMA=OFF -DENABLE_MBEDTLS=OFF -DENABLE_OPENSSL=OFF -DENABLE_WINDOWS_CRYPTO=OFF -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON ) @@ -51,7 +63,7 @@ ExternalProject_Add(xlsxio_project PREFIX xlsxio SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/xlsxio INSTALL_DIR ${XLSXIO_INSTALL_DIR} - BUILD_BYPRODUCTS ${XLSXIO_INSTALL_DIR}/lib/libxlsxio_read.a + BUILD_BYPRODUCTS ${XLSXIO_INSTALL_DIR}/lib/libxlsxio_read${LIB_SUFFIX} CMAKE_ARGS ${CL_ARGS} -DCMAKE_INSTALL_PREFIX=${XLSXIO_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_STATIC=ON -DBUILD_SHARED=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_TOOLS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_DOCUMENTATION=OFF -DWITH_LIBZIP=ON -DZLIB_DIR=${ZLIB_DIR} -DLIBZIP_DIR=${LIBZIP_INSTALL_DIR} -DEXPAT_DIR=${LIBEXPAT_INSTALL_DIR} -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON ) add_dependencies(xlsxio_project libexpat_project) From 43bcec4a57c55ed2cce404013820d378aaf973f1 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sun, 9 Aug 2020 00:46:50 -0700 Subject: [PATCH 283/547] move libzip to older version although they declare that they only need cmake 3.0.2, they started using add_compile_definitions(), which was added in cmake 3.12 git checkout 29b881d fixes this --- depends/libzip | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/libzip b/depends/libzip index 66e496489..29b881d28 160000 --- a/depends/libzip +++ b/depends/libzip @@ -1 +1 @@ -Subproject commit 66e496489bdae81bfda8b0088172871d8fda0032 +Subproject commit 29b881d286f43189ff7392f609da78daa80c0606 From c7cf7fdd30fc2bef7193464cecc503008a6698c4 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sun, 9 Aug 2020 02:00:06 -0700 Subject: [PATCH 284/547] define EXPAT_LIBRARIES for xlsxio --- depends/CMakeLists.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/depends/CMakeLists.txt b/depends/CMakeLists.txt index 7e0a4027b..21b244272 100644 --- a/depends/CMakeLists.txt +++ b/depends/CMakeLists.txt @@ -41,11 +41,12 @@ else() endif() set(LIBEXPAT_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/libexpat) +set(LIBEXPAT_OUTPUT_LIB ${LIBEXPAT_INSTALL_DIR}/lib/libexpat${LIB_SUFFIX}) ExternalProject_Add(libexpat_project PREFIX libexpat SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libexpat/expat INSTALL_DIR ${LIBEXPAT_INSTALL_DIR} - BUILD_BYPRODUCTS ${LIBEXPAT_INSTALL_DIR}/lib/libexpat${LIB_SUFFIX} + BUILD_BYPRODUCTS ${LIBEXPAT_OUTPUT_LIB} CMAKE_ARGS ${CL_ARGS} -DCMAKE_INSTALL_PREFIX=${LIBEXPAT_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DEXPAT_BUILD_EXAMPLES=OFF -DEXPAT_BUILD_TESTS=OFF -DEXPAT_BUILD_TOOLS=OFF -DEXPAT_SHARED_LIBS=OFF -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON ) @@ -64,7 +65,7 @@ ExternalProject_Add(xlsxio_project SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/xlsxio INSTALL_DIR ${XLSXIO_INSTALL_DIR} BUILD_BYPRODUCTS ${XLSXIO_INSTALL_DIR}/lib/libxlsxio_read${LIB_SUFFIX} - CMAKE_ARGS ${CL_ARGS} -DCMAKE_INSTALL_PREFIX=${XLSXIO_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_STATIC=ON -DBUILD_SHARED=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_TOOLS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_DOCUMENTATION=OFF -DWITH_LIBZIP=ON -DZLIB_DIR=${ZLIB_DIR} -DLIBZIP_DIR=${LIBZIP_INSTALL_DIR} -DEXPAT_DIR=${LIBEXPAT_INSTALL_DIR} -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON + CMAKE_ARGS ${CL_ARGS} -DCMAKE_INSTALL_PREFIX=${XLSXIO_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_STATIC=ON -DBUILD_SHARED=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_TOOLS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_DOCUMENTATION=OFF -DWITH_LIBZIP=ON -DZLIB_DIR=${ZLIB_DIR} -DLIBZIP_DIR=${LIBZIP_INSTALL_DIR} -DEXPAT_DIR=${LIBEXPAT_INSTALL_DIR} -DEXPAT_LIBRARIES=${LIBEXPAT_OUTPUT_LIB} -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON ) add_dependencies(xlsxio_project libexpat_project) add_dependencies(xlsxio_project libzip_project) From 204240f3e34d0d1522157cf9306117a2c80063e2 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sun, 9 Aug 2020 02:14:37 -0700 Subject: [PATCH 285/547] specify expat include dir for xlsxio --- depends/CMakeLists.txt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/depends/CMakeLists.txt b/depends/CMakeLists.txt index 21b244272..9f2e98763 100644 --- a/depends/CMakeLists.txt +++ b/depends/CMakeLists.txt @@ -35,13 +35,15 @@ foreach(var ${vars}) endforeach() if(WIN32) - set(LIB_SUFFIX "MD.lib") + set(EXPAT_LIB_SUFFIX "MD.lib") + set(LIB_SUFFIX ".lib") else() + set(EXPAT_LIB_SUFFIX ".a") set(LIB_SUFFIX ".a") endif() set(LIBEXPAT_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/libexpat) -set(LIBEXPAT_OUTPUT_LIB ${LIBEXPAT_INSTALL_DIR}/lib/libexpat${LIB_SUFFIX}) +set(LIBEXPAT_OUTPUT_LIB ${LIBEXPAT_INSTALL_DIR}/lib/libexpat${EXPAT_LIB_SUFFIX}) ExternalProject_Add(libexpat_project PREFIX libexpat SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libexpat/expat @@ -65,7 +67,7 @@ ExternalProject_Add(xlsxio_project SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/xlsxio INSTALL_DIR ${XLSXIO_INSTALL_DIR} BUILD_BYPRODUCTS ${XLSXIO_INSTALL_DIR}/lib/libxlsxio_read${LIB_SUFFIX} - CMAKE_ARGS ${CL_ARGS} -DCMAKE_INSTALL_PREFIX=${XLSXIO_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_STATIC=ON -DBUILD_SHARED=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_TOOLS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_DOCUMENTATION=OFF -DWITH_LIBZIP=ON -DZLIB_DIR=${ZLIB_DIR} -DLIBZIP_DIR=${LIBZIP_INSTALL_DIR} -DEXPAT_DIR=${LIBEXPAT_INSTALL_DIR} -DEXPAT_LIBRARIES=${LIBEXPAT_OUTPUT_LIB} -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON + CMAKE_ARGS ${CL_ARGS} -DCMAKE_INSTALL_PREFIX=${XLSXIO_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_STATIC=ON -DBUILD_SHARED=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_TOOLS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_DOCUMENTATION=OFF -DWITH_LIBZIP=ON -DZLIB_DIR=${ZLIB_DIR} -DLIBZIP_DIR=${LIBZIP_INSTALL_DIR} -DEXPAT_DIR=${LIBEXPAT_INSTALL_DIR} -DEXPAT_LIBRARIES=${LIBEXPAT_OUTPUT_LIB} -DEXPAT_INCLUDE_DIR=${LIBEXPAT_INSTALL_DIR}/include -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON ) add_dependencies(xlsxio_project libexpat_project) add_dependencies(xlsxio_project libzip_project) From 79415cf097b1de8e9b33734d347b44259d47fb11 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sun, 9 Aug 2020 02:24:05 -0700 Subject: [PATCH 286/547] clean up dep lib vars --- CMakeLists.txt | 15 --------------- depends/CMakeLists.txt | 18 +++++++++++++----- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dbd028a36..e5e88ceb3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -417,32 +417,17 @@ endif() # build the lib itself if(BUILD_LIBRARY) - ExternalProject_Get_Property(xlsxio_project INSTALL_DIR) - set(XLSXIO_INSTALL_DIR ${INSTALL_DIR}) - ExternalProject_Get_Property(xlsxio_project BUILD_BYPRODUCTS) - set(XLSXIO_LIB ${BUILD_BYPRODUCTS}) include_directories(${XLSXIO_INSTALL_DIR}/include) add_library(xlsxio_read STATIC IMPORTED) set_target_properties(xlsxio_read PROPERTIES IMPORTED_LOCATION ${XLSXIO_LIB}) - add_dependencies(xlsxio_read xlsxio_project) - ExternalProject_Get_Property(libzip_project INSTALL_DIR) - set(LIBZIP_INSTALL_DIR ${INSTALL_DIR}) - ExternalProject_Get_Property(libzip_project BUILD_BYPRODUCTS) - set(LIBZIP_LIB ${BUILD_BYPRODUCTS}) include_directories(${LIBZIP_INSTALL_DIR}/include) add_library(zip STATIC IMPORTED) set_target_properties(zip PROPERTIES IMPORTED_LOCATION ${LIBZIP_LIB}) - add_dependencies(zip libzip_project) - ExternalProject_Get_Property(libexpat_project INSTALL_DIR) - set(LIBEXPAT_INSTALL_DIR ${INSTALL_DIR}) - ExternalProject_Get_Property(libexpat_project BUILD_BYPRODUCTS) - set(LIBEXPAT_LIB ${BUILD_BYPRODUCTS}) include_directories(${LIBEXPAT_INSTALL_DIR}/include) add_library(expat STATIC IMPORTED) set_target_properties(expat PROPERTIES IMPORTED_LOCATION ${LIBEXPAT_LIB}) - add_dependencies(expat libexpat_project) add_subdirectory(library) install(FILES LICENSE.rst docs/changelog.txt DESTINATION ${DFHACK_USERDOC_DESTINATION}) diff --git a/depends/CMakeLists.txt b/depends/CMakeLists.txt index 9f2e98763..475166285 100644 --- a/depends/CMakeLists.txt +++ b/depends/CMakeLists.txt @@ -43,31 +43,39 @@ else() endif() set(LIBEXPAT_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/libexpat) -set(LIBEXPAT_OUTPUT_LIB ${LIBEXPAT_INSTALL_DIR}/lib/libexpat${EXPAT_LIB_SUFFIX}) +set(LIBEXPAT_INSTALL_DIR ${LIBEXPAT_INSTALL_DIR} PARENT_SCOPE) +set(LIBEXPAT_LIB ${LIBEXPAT_INSTALL_DIR}/lib/libexpat${EXPAT_LIB_SUFFIX}) +set(LIBEXPAT_LIB ${LIBEXPAT_LIB} PARENT_SCOPE) ExternalProject_Add(libexpat_project PREFIX libexpat SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libexpat/expat INSTALL_DIR ${LIBEXPAT_INSTALL_DIR} - BUILD_BYPRODUCTS ${LIBEXPAT_OUTPUT_LIB} + BUILD_BYPRODUCTS ${LIBEXPAT_LIB} CMAKE_ARGS ${CL_ARGS} -DCMAKE_INSTALL_PREFIX=${LIBEXPAT_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DEXPAT_BUILD_EXAMPLES=OFF -DEXPAT_BUILD_TESTS=OFF -DEXPAT_BUILD_TOOLS=OFF -DEXPAT_SHARED_LIBS=OFF -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON ) set(LIBZIP_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/libzip) +set(LIBZIP_INSTALL_DIR ${LIBZIP_INSTALL_DIR} PARENT_SCOPE) +set(LIBZIP_LIB ${LIBZIP_INSTALL_DIR}/lib/libzip${LIB_SUFFIX}) +set(LIBZIP_LIB ${LIBZIP_LIB} PARENT_SCOPE) ExternalProject_Add(libzip_project PREFIX libzip SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libzip INSTALL_DIR ${LIBZIP_INSTALL_DIR} - BUILD_BYPRODUCTS ${LIBZIP_INSTALL_DIR}/lib/libzip${LIB_SUFFIX} + BUILD_BYPRODUCTS ${LIBZIP_LIB} CMAKE_ARGS ${CL_ARGS} -DCMAKE_INSTALL_PREFIX=${LIBZIP_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_DOC=OFF -DBUILD_EXAMPLES=OFF -DBUILD_REGRESS=OFF -DBUILD_SHARED_LIBS=OFF -DBUILD_TOOLS=OFF -DENABLE_BZIP2=OFF -DENABLE_COMMONCRYPTO=OFF -DENABLE_GNUTLS=OFF -DENABLE_LZMA=OFF -DENABLE_MBEDTLS=OFF -DENABLE_OPENSSL=OFF -DENABLE_WINDOWS_CRYPTO=OFF -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON ) set(XLSXIO_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/xlsxio) +set(XLSXIO_INSTALL_DIR ${XLSXIO_INSTALL_DIR} PARENT_SCOPE) +set(XLSXIO_LIB ${XLSXIO_INSTALL_DIR}/lib/libxlsxio_read${LIB_SUFFIX}) +set(XLSXIO_LIB ${XLSXIO_LIB} PARENT_SCOPE) ExternalProject_Add(xlsxio_project PREFIX xlsxio SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/xlsxio INSTALL_DIR ${XLSXIO_INSTALL_DIR} - BUILD_BYPRODUCTS ${XLSXIO_INSTALL_DIR}/lib/libxlsxio_read${LIB_SUFFIX} - CMAKE_ARGS ${CL_ARGS} -DCMAKE_INSTALL_PREFIX=${XLSXIO_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_STATIC=ON -DBUILD_SHARED=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_TOOLS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_DOCUMENTATION=OFF -DWITH_LIBZIP=ON -DZLIB_DIR=${ZLIB_DIR} -DLIBZIP_DIR=${LIBZIP_INSTALL_DIR} -DEXPAT_DIR=${LIBEXPAT_INSTALL_DIR} -DEXPAT_LIBRARIES=${LIBEXPAT_OUTPUT_LIB} -DEXPAT_INCLUDE_DIR=${LIBEXPAT_INSTALL_DIR}/include -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON + BUILD_BYPRODUCTS ${XLSXIO_LIB} + CMAKE_ARGS ${CL_ARGS} -DCMAKE_INSTALL_PREFIX=${XLSXIO_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_STATIC=ON -DBUILD_SHARED=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_TOOLS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_DOCUMENTATION=OFF -DWITH_LIBZIP=ON -DZLIB_DIR=${ZLIB_DIR} -DLIBZIP_DIR=${LIBZIP_INSTALL_DIR} -DEXPAT_DIR=${LIBEXPAT_INSTALL_DIR} -DEXPAT_LIBRARIES=${LIBEXPAT_LIB} -DEXPAT_INCLUDE_DIR=${LIBEXPAT_INSTALL_DIR}/include -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON ) add_dependencies(xlsxio_project libexpat_project) add_dependencies(xlsxio_project libzip_project) From f04a9c3180b6a32f77e57a130a0636868a70ee7f Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sun, 9 Aug 2020 02:32:31 -0700 Subject: [PATCH 287/547] clean up logging; use xlsxio's misspelling of "DIRS" --- depends/CMakeLists.txt | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/depends/CMakeLists.txt b/depends/CMakeLists.txt index 475166285..808bb4304 100644 --- a/depends/CMakeLists.txt +++ b/depends/CMakeLists.txt @@ -25,11 +25,9 @@ foreach(var ${vars}) AND NOT var MATCHES "^CMAKE_CACHE" AND NOT var MATCHES "^CMAKE_HOME" AND NOT var MATCHES "^CMAKE_PROJECT") - message("${var} = [${${var}}]") list(APPEND CL_ARGS "-D${var}=${${var}}") endif() if(var MATCHES "^ZLIB") - message("${var} = [${${var}}]") list(APPEND CL_ARGS "-D${var}=${${var}}") endif() endforeach() @@ -51,7 +49,7 @@ ExternalProject_Add(libexpat_project SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libexpat/expat INSTALL_DIR ${LIBEXPAT_INSTALL_DIR} BUILD_BYPRODUCTS ${LIBEXPAT_LIB} - CMAKE_ARGS ${CL_ARGS} -DCMAKE_INSTALL_PREFIX=${LIBEXPAT_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DEXPAT_BUILD_EXAMPLES=OFF -DEXPAT_BUILD_TESTS=OFF -DEXPAT_BUILD_TOOLS=OFF -DEXPAT_SHARED_LIBS=OFF -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON + CMAKE_ARGS ${CL_ARGS} -DCMAKE_INSTALL_PREFIX=${LIBEXPAT_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DEXPAT_BUILD_EXAMPLES=OFF -DEXPAT_BUILD_TESTS=OFF -DEXPAT_BUILD_TOOLS=OFF -DEXPAT_SHARED_LIBS=OFF -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_POSITION_INDEPENDENT_CODE=ON ) set(LIBZIP_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/libzip) @@ -63,7 +61,7 @@ ExternalProject_Add(libzip_project SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libzip INSTALL_DIR ${LIBZIP_INSTALL_DIR} BUILD_BYPRODUCTS ${LIBZIP_LIB} - CMAKE_ARGS ${CL_ARGS} -DCMAKE_INSTALL_PREFIX=${LIBZIP_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_DOC=OFF -DBUILD_EXAMPLES=OFF -DBUILD_REGRESS=OFF -DBUILD_SHARED_LIBS=OFF -DBUILD_TOOLS=OFF -DENABLE_BZIP2=OFF -DENABLE_COMMONCRYPTO=OFF -DENABLE_GNUTLS=OFF -DENABLE_LZMA=OFF -DENABLE_MBEDTLS=OFF -DENABLE_OPENSSL=OFF -DENABLE_WINDOWS_CRYPTO=OFF -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON + CMAKE_ARGS ${CL_ARGS} -DCMAKE_INSTALL_PREFIX=${LIBZIP_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_DOC=OFF -DBUILD_EXAMPLES=OFF -DBUILD_REGRESS=OFF -DBUILD_SHARED_LIBS=OFF -DBUILD_TOOLS=OFF -DENABLE_BZIP2=OFF -DENABLE_COMMONCRYPTO=OFF -DENABLE_GNUTLS=OFF -DENABLE_LZMA=OFF -DENABLE_MBEDTLS=OFF -DENABLE_OPENSSL=OFF -DENABLE_WINDOWS_CRYPTO=OFF -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_POSITION_INDEPENDENT_CODE=ON ) set(XLSXIO_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/xlsxio) @@ -75,7 +73,7 @@ ExternalProject_Add(xlsxio_project SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/xlsxio INSTALL_DIR ${XLSXIO_INSTALL_DIR} BUILD_BYPRODUCTS ${XLSXIO_LIB} - CMAKE_ARGS ${CL_ARGS} -DCMAKE_INSTALL_PREFIX=${XLSXIO_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_STATIC=ON -DBUILD_SHARED=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_TOOLS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_DOCUMENTATION=OFF -DWITH_LIBZIP=ON -DZLIB_DIR=${ZLIB_DIR} -DLIBZIP_DIR=${LIBZIP_INSTALL_DIR} -DEXPAT_DIR=${LIBEXPAT_INSTALL_DIR} -DEXPAT_LIBRARIES=${LIBEXPAT_LIB} -DEXPAT_INCLUDE_DIR=${LIBEXPAT_INSTALL_DIR}/include -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON + CMAKE_ARGS ${CL_ARGS} -DCMAKE_INSTALL_PREFIX=${XLSXIO_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_STATIC=ON -DBUILD_SHARED=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_TOOLS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_DOCUMENTATION=OFF -DWITH_LIBZIP=ON -DZLIB_DIR=${ZLIB_DIR} -DLIBZIP_DIR=${LIBZIP_INSTALL_DIR} -DEXPAT_DIR=${LIBEXPAT_INSTALL_DIR} -DEXPAT_LIBRARIES=${LIBEXPAT_LIB} -DEXPAT_INCLUDE_DIRS=${LIBEXPAT_INSTALL_DIR}/include -DCMAKE_POSITION_INDEPENDENT_CODE=ON ) add_dependencies(xlsxio_project libexpat_project) add_dependencies(xlsxio_project libzip_project) From 8913d43d6f8cfe8d3921ef3f05f7fae4ddce2947 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sun, 9 Aug 2020 02:59:22 -0700 Subject: [PATCH 288/547] ensure xlsxio_project gets built before dfhack --- CMakeLists.txt | 6 ++---- depends/CMakeLists.txt | 2 -- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e5e88ceb3..eeb8c8d12 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -420,17 +420,15 @@ if(BUILD_LIBRARY) include_directories(${XLSXIO_INSTALL_DIR}/include) add_library(xlsxio_read STATIC IMPORTED) set_target_properties(xlsxio_read PROPERTIES IMPORTED_LOCATION ${XLSXIO_LIB}) - - include_directories(${LIBZIP_INSTALL_DIR}/include) add_library(zip STATIC IMPORTED) set_target_properties(zip PROPERTIES IMPORTED_LOCATION ${LIBZIP_LIB}) - - include_directories(${LIBEXPAT_INSTALL_DIR}/include) add_library(expat STATIC IMPORTED) set_target_properties(expat PROPERTIES IMPORTED_LOCATION ${LIBEXPAT_LIB}) add_subdirectory(library) install(FILES LICENSE.rst docs/changelog.txt DESTINATION ${DFHACK_USERDOC_DESTINATION}) + + add_dependencies(dfhack xlsxio_project) endif() file(WRITE "${CMAKE_BINARY_DIR}/dfhack_setarch.txt" ${DFHACK_SETARCH}) diff --git a/depends/CMakeLists.txt b/depends/CMakeLists.txt index 808bb4304..0b747c157 100644 --- a/depends/CMakeLists.txt +++ b/depends/CMakeLists.txt @@ -41,7 +41,6 @@ else() endif() set(LIBEXPAT_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/libexpat) -set(LIBEXPAT_INSTALL_DIR ${LIBEXPAT_INSTALL_DIR} PARENT_SCOPE) set(LIBEXPAT_LIB ${LIBEXPAT_INSTALL_DIR}/lib/libexpat${EXPAT_LIB_SUFFIX}) set(LIBEXPAT_LIB ${LIBEXPAT_LIB} PARENT_SCOPE) ExternalProject_Add(libexpat_project @@ -53,7 +52,6 @@ ExternalProject_Add(libexpat_project ) set(LIBZIP_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/libzip) -set(LIBZIP_INSTALL_DIR ${LIBZIP_INSTALL_DIR} PARENT_SCOPE) set(LIBZIP_LIB ${LIBZIP_INSTALL_DIR}/lib/libzip${LIB_SUFFIX}) set(LIBZIP_LIB ${LIBZIP_LIB} PARENT_SCOPE) ExternalProject_Add(libzip_project From 7a0853025a0955190b9a53a87c85180d96cd627e Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sun, 9 Aug 2020 03:30:59 -0700 Subject: [PATCH 289/547] use non-standard xlsxio lib name on windows --- depends/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/depends/CMakeLists.txt b/depends/CMakeLists.txt index 0b747c157..db132a809 100644 --- a/depends/CMakeLists.txt +++ b/depends/CMakeLists.txt @@ -35,9 +35,11 @@ endforeach() if(WIN32) set(EXPAT_LIB_SUFFIX "MD.lib") set(LIB_SUFFIX ".lib") + set(XLSXIO_LIB_PREFIX "") else() set(EXPAT_LIB_SUFFIX ".a") set(LIB_SUFFIX ".a") + set(XLSXIO_LIB_PREFIX "lib") endif() set(LIBEXPAT_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/libexpat) @@ -64,7 +66,7 @@ ExternalProject_Add(libzip_project set(XLSXIO_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/xlsxio) set(XLSXIO_INSTALL_DIR ${XLSXIO_INSTALL_DIR} PARENT_SCOPE) -set(XLSXIO_LIB ${XLSXIO_INSTALL_DIR}/lib/libxlsxio_read${LIB_SUFFIX}) +set(XLSXIO_LIB ${XLSXIO_INSTALL_DIR}/lib/${XLSXIO_LIB_PREFIX}xlsxio_read${LIB_SUFFIX}) set(XLSXIO_LIB ${XLSXIO_LIB} PARENT_SCOPE) ExternalProject_Add(xlsxio_project PREFIX xlsxio From 5fc627a16f26c7acae4d0bf8b858066440afa9d1 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sun, 9 Aug 2020 04:03:04 -0700 Subject: [PATCH 290/547] no lib prefix for libzip on windows too --- depends/CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/depends/CMakeLists.txt b/depends/CMakeLists.txt index db132a809..bb5dc72dc 100644 --- a/depends/CMakeLists.txt +++ b/depends/CMakeLists.txt @@ -35,11 +35,11 @@ endforeach() if(WIN32) set(EXPAT_LIB_SUFFIX "MD.lib") set(LIB_SUFFIX ".lib") - set(XLSXIO_LIB_PREFIX "") + set(LIB_PREFIX "") else() set(EXPAT_LIB_SUFFIX ".a") set(LIB_SUFFIX ".a") - set(XLSXIO_LIB_PREFIX "lib") + set(LIB_PREFIX "lib") endif() set(LIBEXPAT_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/libexpat) @@ -54,7 +54,7 @@ ExternalProject_Add(libexpat_project ) set(LIBZIP_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/libzip) -set(LIBZIP_LIB ${LIBZIP_INSTALL_DIR}/lib/libzip${LIB_SUFFIX}) +set(LIBZIP_LIB ${LIBZIP_INSTALL_DIR}/lib/${LIB_PREFIX}zip${LIB_SUFFIX}) set(LIBZIP_LIB ${LIBZIP_LIB} PARENT_SCOPE) ExternalProject_Add(libzip_project PREFIX libzip @@ -66,7 +66,7 @@ ExternalProject_Add(libzip_project set(XLSXIO_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/xlsxio) set(XLSXIO_INSTALL_DIR ${XLSXIO_INSTALL_DIR} PARENT_SCOPE) -set(XLSXIO_LIB ${XLSXIO_INSTALL_DIR}/lib/${XLSXIO_LIB_PREFIX}xlsxio_read${LIB_SUFFIX}) +set(XLSXIO_LIB ${XLSXIO_INSTALL_DIR}/lib/${LIB_PREFIX}xlsxio_read${LIB_SUFFIX}) set(XLSXIO_LIB ${XLSXIO_LIB} PARENT_SCOPE) ExternalProject_Add(xlsxio_project PREFIX xlsxio From a41f7c099843d23286857f976ab962b336e679c5 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sun, 9 Aug 2020 08:54:42 -0700 Subject: [PATCH 291/547] convert XlsxReader module to xlsxreader plugin --- CMakeLists.txt | 12 -- depends/CMakeLists.txt | 2 + library/CMakeLists.txt | 4 +- library/LuaApi.cpp | 61 ---------- library/include/modules/XlsxReader.h | 45 ------- library/modules/XlsxReader.cpp | 115 ----------------- plugins/CMakeLists.txt | 11 ++ plugins/lua/xlsxreader.lua | 17 +++ plugins/xlsxreader.cpp | 176 +++++++++++++++++++++++++++ 9 files changed, 207 insertions(+), 236 deletions(-) delete mode 100644 library/include/modules/XlsxReader.h delete mode 100644 library/modules/XlsxReader.cpp create mode 100644 plugins/lua/xlsxreader.lua create mode 100644 plugins/xlsxreader.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index eeb8c8d12..cd06587eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -364,8 +364,6 @@ endif() #### expose depends #### -include(ExternalProject) - if(UNIX) # Rescan for pthread and zlib if the build arch changed if(NOT "${DFHACK_BUILD_ARCH}" STREQUAL "${DFHACK_BUILD_ARCH_PREV}") @@ -417,18 +415,8 @@ endif() # build the lib itself if(BUILD_LIBRARY) - include_directories(${XLSXIO_INSTALL_DIR}/include) - add_library(xlsxio_read STATIC IMPORTED) - set_target_properties(xlsxio_read PROPERTIES IMPORTED_LOCATION ${XLSXIO_LIB}) - add_library(zip STATIC IMPORTED) - set_target_properties(zip PROPERTIES IMPORTED_LOCATION ${LIBZIP_LIB}) - add_library(expat STATIC IMPORTED) - set_target_properties(expat PROPERTIES IMPORTED_LOCATION ${LIBEXPAT_LIB}) - add_subdirectory(library) install(FILES LICENSE.rst docs/changelog.txt DESTINATION ${DFHACK_USERDOC_DESTINATION}) - - add_dependencies(dfhack xlsxio_project) endif() file(WRITE "${CMAKE_BINARY_DIR}/dfhack_setarch.txt" ${DFHACK_SETARCH}) diff --git a/depends/CMakeLists.txt b/depends/CMakeLists.txt index bb5dc72dc..69ce40ae3 100644 --- a/depends/CMakeLists.txt +++ b/depends/CMakeLists.txt @@ -32,6 +32,8 @@ foreach(var ${vars}) endif() endforeach() +include(ExternalProject) + if(WIN32) set(EXPAT_LIB_SUFFIX "MD.lib") set(LIB_SUFFIX ".lib") diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 583c8768f..2de293e15 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -144,7 +144,6 @@ set(MODULE_HEADERS include/modules/Translation.h include/modules/Units.h include/modules/World.h - include/modules/XlsxReader.h ) set(MODULE_SOURCES @@ -173,7 +172,6 @@ set(MODULE_SOURCES modules/Units.cpp modules/Windows.cpp modules/World.cpp - modules/XlsxReader.cpp ) set(STATIC_FIELDS_FILES) @@ -411,7 +409,7 @@ if(APPLE) set_target_properties(dfhack PROPERTIES SOVERSION 1.0.0) endif() -target_link_libraries(dfhack protobuf-lite clsocket lua jsoncpp_lib_static xlsxio_read zip expat dfhack-version ${PROJECT_LIBS}) +target_link_libraries(dfhack protobuf-lite clsocket lua jsoncpp_lib_static dfhack-version ${PROJECT_LIBS}) set_target_properties(dfhack PROPERTIES INTERFACE_LINK_LIBRARIES "") target_link_libraries(dfhack-client protobuf-lite clsocket jsoncpp_lib_static) diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 0265eee20..78364083f 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -60,7 +60,6 @@ distribution. #include "modules/Translation.h" #include "modules/Units.h" #include "modules/World.h" -#include "modules/XlsxReader.h" #include "LuaWrapper.h" #include "LuaTools.h" @@ -2481,65 +2480,6 @@ static const LuaWrapper::FunctionReg dfhack_kitchen_module[] = { {NULL, NULL} }; -/***** XlsxReader module *****/ - -static const LuaWrapper::FunctionReg dfhack_xlsxreader_module[] = { - WRAPM(XlsxReader, open_xlsx_file), - WRAPM(XlsxReader, close_xlsx_file), - WRAPM(XlsxReader, open_sheet), - WRAPM(XlsxReader, close_sheet), - {NULL, NULL} -}; - -// internal function to factor out handle extraction -static void * get_xlsxreader_handle(lua_State *L) -{ - if (lua_gettop(L) < 1 || lua_isnil(L, 1)) - { - luaL_error(L, "invalid xlsxreader handle"); - } - luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); - return lua_touserdata(L, 1); -} - -// takes a file handle and returns a table-list of sheet names -static int xlsxreader_list_sheets(lua_State *L) -{ - XlsxReader::xlsx_file_handle file_handle = get_xlsxreader_handle(L); - Lua::PushVector(L, XlsxReader::list_sheets(file_handle), true); - return 1; -} - -// takes the sheet handle and returns a table-list of strings, or nil if we -// already processed the last row in the file. -static int xlsxreader_get_row(lua_State *L) -{ - XlsxReader::xlsx_sheet_handle sheet_handle = get_xlsxreader_handle(L); - bool ok = XlsxReader::get_next_row(sheet_handle); - if (!ok) - { - lua_pushnil(L); - } - else - { - std::string value; - auto cells = std::vector(); - while (XlsxReader::get_next_cell(sheet_handle, value)) - { - cells.push_back(value); - } - Lua::PushVector(L, cells, true); - } - - return 1; -} - -static const luaL_Reg dfhack_xlsxreader_funcs[] = { - {"list_sheets", xlsxreader_list_sheets}, - {"get_row", xlsxreader_get_row}, - {NULL, NULL} -}; - /***** Console module *****/ namespace console { @@ -3093,7 +3033,6 @@ void OpenDFHackApi(lua_State *state) OpenModule(state, "filesystem", dfhack_filesystem_module, dfhack_filesystem_funcs); OpenModule(state, "designations", dfhack_designations_module, dfhack_designations_funcs); OpenModule(state, "kitchen", dfhack_kitchen_module); - OpenModule(state, "xlsxreader", dfhack_xlsxreader_module, dfhack_xlsxreader_funcs); OpenModule(state, "console", dfhack_console_module); OpenModule(state, "internal", dfhack_internal_module, dfhack_internal_funcs); } diff --git a/library/include/modules/XlsxReader.h b/library/include/modules/XlsxReader.h deleted file mode 100644 index 93ea1cf20..000000000 --- a/library/include/modules/XlsxReader.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Wrapper for xlsxio_read library functions. - */ - -#pragma once - -#include -#include - -#include "Export.h" - -/** - * \defgroup grp_xlsx_reader Xlsx file reader - * @ingroup grp_modules - */ -namespace DFHack -{ -namespace XlsxReader -{ - -typedef void* xlsx_file_handle; -typedef void* xlsx_sheet_handle; - -// returns NULL on error -DFHACK_EXPORT xlsx_file_handle open_xlsx_file(std::string filename); -DFHACK_EXPORT void close_xlsx_file(xlsx_file_handle file_handle); -DFHACK_EXPORT std::vector list_sheets(xlsx_file_handle file_handle); - -// returns XLSXIOReaderSheet object or NULL on error -DFHACK_EXPORT xlsx_sheet_handle open_sheet( - xlsx_file_handle file_handle, std::string sheet_name); -DFHACK_EXPORT void close_sheet(xlsx_sheet_handle sheet_handle); - -// start reading the next row of data; must be called before GetNextCell . -// returns false if there is no next row to get. -DFHACK_EXPORT bool get_next_row(xlsx_sheet_handle sheet_handle); - -// fills the value param with the contents of the cell in the next column cell -// in the current row. -// returns false if there are no more cells in this row. -DFHACK_EXPORT bool get_next_cell( - xlsx_sheet_handle sheet_handle, std::string& value); - -} -} diff --git a/library/modules/XlsxReader.cpp b/library/modules/XlsxReader.cpp deleted file mode 100644 index 405369c85..000000000 --- a/library/modules/XlsxReader.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Wrapper for xlsxio_read library functions. - * - * Sample usage: - * - * std::string filename = "sample_file.xlsx"; - * xlsxioreader xlsxfile = XlsxReader::open_xlsx_file(filename); - * if (xlsxfile == NULL) { - * printf("cannot open file: '%s'", filename.c_str()); - * return false; - * } - * auto sheetNames = XlsxReader::list_sheets(xlsxfile); - * for (auto sheetName = sheetNames.begin(); - * sheetName != sheetNames.end(); - * ++sheetName) { - * printf("reading sheet: %s\n", sheetName->c_str()); - * xlsxioreadersheet xlsxsheet = - * XlsxReader::open_sheet(xlsxfile, *sheetName); - * if (xlsxsheet == NULL) { - * printf("cannot open sheet: '%s'", sheetName->c_str()); - * continue; - * } - * std::string value; - * int row_num = 1; - * while (XlsxReader::GetNextRow(xlsxsheet)) { - * std::string s; - * printf("%d:\t", row_num); - * while (XlsxReader::GetNextCell(xlsxsheet, s)) { - * printf("%s\t", s.c_str()); - * } - * printf("\n"); - * ++row_num; - * } - * XlsxReader::close_sheet(xlsxsheet); - * } - * XlsxReader::close_xlsx_file(xlsxfile); - * return true; - */ - -#include - -#include "modules/XlsxReader.h" - -using namespace DFHack; - - -// returns NULL on error -DFHACK_EXPORT XlsxReader::xlsx_file_handle XlsxReader::open_xlsx_file( - std::string filename) -{ - return xlsxioread_open(filename.c_str()); -} - -DFHACK_EXPORT void XlsxReader::close_xlsx_file( - XlsxReader::xlsx_file_handle file_handle) -{ - xlsxioread_close((xlsxioreader)file_handle); -} - -static int list_callback(const XLSXIOCHAR* name, void* cbdata) -{ - auto sheetNames = (std::vector *)cbdata; - sheetNames->push_back(name); - return 0; -} - -DFHACK_EXPORT std::vector XlsxReader::list_sheets( - XlsxReader::xlsx_file_handle file_handle) -{ - auto sheetNames = std::vector(); - xlsxioread_list_sheets( - (xlsxioreader)file_handle, list_callback, &sheetNames); - return sheetNames; -} - -// returns XLSXIOReaderSheet object or NULL on error -DFHACK_EXPORT XlsxReader::xlsx_sheet_handle XlsxReader::open_sheet( - XlsxReader::xlsx_file_handle file_handle, std::string sheet_name) -{ - if (file_handle == NULL) - return NULL; - return xlsxioread_sheet_open( - (xlsxioreader)file_handle, sheet_name.c_str(), XLSXIOREAD_SKIP_NONE); -} - -DFHACK_EXPORT void XlsxReader::close_sheet( - XlsxReader::xlsx_sheet_handle sheet_handle) -{ - xlsxioread_sheet_close((xlsxioreadersheet)sheet_handle); -} - -// start reading the next row of data; must be called before GetNextCell . -// returns false if there is no next row to get. -DFHACK_EXPORT bool XlsxReader::get_next_row( - XlsxReader::xlsx_sheet_handle sheet_handle) -{ - return xlsxioread_sheet_next_row((xlsxioreadersheet)sheet_handle) != 0; -} - -// fills the value param with the contents of the cell in the next column cell -// in the current row. -// returns false if there are no more cells in this row. -DFHACK_EXPORT bool XlsxReader::get_next_cell( - XlsxReader::xlsx_sheet_handle sheet_handle, std::string& value) -{ - char* result; - if (!xlsxioread_sheet_next_cell_string((xlsxioreadersheet)sheet_handle, - &result)) { - value.clear(); - return false; - } - value.assign(result); - free(result); - return true; -} diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 678b7eec2..6531165e1 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -77,6 +77,14 @@ set_source_files_properties( Brushes.h PROPERTIES HEADER_FILE_ONLY TRUE ) add_library(buildingplan-lib STATIC buildingplan-lib.cpp) target_link_libraries(buildingplan-lib dfhack) +# xlsxreader deps +add_library(xlsxio_read STATIC IMPORTED) +set_target_properties(xlsxio_read PROPERTIES IMPORTED_LOCATION ${XLSXIO_LIB}) +add_library(zip STATIC IMPORTED) +set_target_properties(zip PROPERTIES IMPORTED_LOCATION ${LIBZIP_LIB}) +add_library(expat STATIC IMPORTED) +set_target_properties(expat PROPERTIES IMPORTED_LOCATION ${LIBEXPAT_LIB}) + # Plugins option(BUILD_SUPPORTED "Build the supported plugins (reveal, probe, etc.)." ON) if(BUILD_SUPPORTED) @@ -175,8 +183,11 @@ if(BUILD_SUPPORTED) add_subdirectory(tweak) dfhack_plugin(workflow workflow.cpp LINK_LIBRARIES lua) dfhack_plugin(workNow workNow.cpp) + dfhack_plugin(xlsxreader xlsxreader.cpp LINK_LIBRARIES lua xlsxio_read zip expat z) dfhack_plugin(zone zone.cpp LINK_LIBRARIES lua) endif() +target_include_directories(xlsxreader PRIVATE ${XLSXIO_INSTALL_DIR}/include) +add_dependencies(xlsxreader xlsxio_project) # this is the skeleton plugin. If you want to make your own, make a copy and then change it option(BUILD_SKELETON "Build the skeleton plugin." OFF) diff --git a/plugins/lua/xlsxreader.lua b/plugins/lua/xlsxreader.lua new file mode 100644 index 000000000..3dbc1f2d8 --- /dev/null +++ b/plugins/lua/xlsxreader.lua @@ -0,0 +1,17 @@ +local _ENV = mkmodule('plugins.xlsxreader') + +--[[ + + Native functions: + + * file_handle open_xlsx_file(filename) + * close_xlsx_file(file_handle) + * sheet_names list_sheets(file_handle) + + * sheet_handle open_sheet(file_handle, sheet_name) + * close_sheet(sheet_handle) + * cell_strings get_row(sheet_handle) + +--]] + +return _ENV diff --git a/plugins/xlsxreader.cpp b/plugins/xlsxreader.cpp new file mode 100644 index 000000000..9c773718d --- /dev/null +++ b/plugins/xlsxreader.cpp @@ -0,0 +1,176 @@ +/* + * Wrapper for xlsxio_read library functions. + * + * Sample usage: + * + * std::string filename = "sample_file.xlsx"; + * xlsxioreader xlsxfile = XlsxReader::open_xlsx_file(filename); + * if (xlsxfile == NULL) { + * printf("cannot open file: '%s'", filename.c_str()); + * return false; + * } + * auto sheetNames = XlsxReader::list_sheets(xlsxfile); + * for (auto sheetName = sheetNames.begin(); + * sheetName != sheetNames.end(); + * ++sheetName) { + * printf("reading sheet: %s\n", sheetName->c_str()); + * xlsxioreadersheet xlsxsheet = + * XlsxReader::open_sheet(xlsxfile, *sheetName); + * if (xlsxsheet == NULL) { + * printf("cannot open sheet: '%s'", sheetName->c_str()); + * continue; + * } + * std::string value; + * int row_num = 1; + * while (XlsxReader::GetNextRow(xlsxsheet)) { + * std::string s; + * printf("%d:\t", row_num); + * while (XlsxReader::GetNextCell(xlsxsheet, s)) { + * printf("%s\t", s.c_str()); + * } + * printf("\n"); + * ++row_num; + * } + * XlsxReader::close_sheet(xlsxsheet); + * } + * XlsxReader::close_xlsx_file(xlsxfile); + * return true; + */ + +#include + +#include "DataFuncs.h" +#include "LuaTools.h" +#include "PluginManager.h" + +using namespace DFHack; + +DFHACK_PLUGIN("xlsxreader"); + +typedef void* xlsx_file_handle; +typedef void* xlsx_sheet_handle; + +// returns NULL on error +xlsx_file_handle open_xlsx_file(std::string filename) +{ + return xlsxioread_open(filename.c_str()); +} + +void close_xlsx_file(xlsx_file_handle file_handle) +{ + xlsxioread_close((xlsxioreader)file_handle); +} + +// returns XLSXIOReaderSheet object or NULL on error +xlsx_sheet_handle open_sheet(xlsx_file_handle file_handle, std::string sheet_name) +{ + if (file_handle == NULL) + return NULL; + return xlsxioread_sheet_open((xlsxioreader)file_handle, + sheet_name.c_str(), XLSXIOREAD_SKIP_NONE); +} + +void close_sheet(xlsx_sheet_handle sheet_handle) +{ + xlsxioread_sheet_close((xlsxioreadersheet)sheet_handle); +} + +static int list_callback(const XLSXIOCHAR* name, void* cbdata) +{ + auto sheetNames = (std::vector *)cbdata; + sheetNames->push_back(name); + return 0; +} + +// start reading the next row of data; must be called before get_next_cell. +// returns false if there is no next row to get. +static bool get_next_row(xlsx_sheet_handle sheet_handle) +{ + return xlsxioread_sheet_next_row((xlsxioreadersheet)sheet_handle) != 0; +} + +// fills the value param with the contents of the cell in the next column cell +// in the current row. +// returns false if there are no more cells in this row. +static bool get_next_cell(xlsx_sheet_handle sheet_handle, std::string& value) +{ + char* result; + if (!xlsxioread_sheet_next_cell_string( + (xlsxioreadersheet)sheet_handle, &result)) { + value.clear(); + return false; + } + value.assign(result); + free(result); + return true; +} + +// internal function to factor out handle extraction +static void * get_xlsxreader_handle(lua_State *L) +{ + if (lua_gettop(L) < 1 || lua_isnil(L, 1)) + { + luaL_error(L, "invalid xlsxreader handle"); + } + luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); + return lua_touserdata(L, 1); +} + +// takes a file handle and returns a table-list of sheet names +int list_sheets(lua_State *L) +{ + xlsxioreader file_handle = (xlsxioreader)get_xlsxreader_handle(L); + auto sheetNames = std::vector(); + xlsxioread_list_sheets(file_handle, list_callback, &sheetNames); + Lua::PushVector(L, sheetNames, true); + return 1; +} + +// takes the sheet handle and returns a table-list of strings, or nil if we +// already processed the last row in the file. +int get_row(lua_State *L) +{ + xlsxioreadersheet sheet_handle = + (xlsxioreadersheet)get_xlsxreader_handle(L); + bool ok = get_next_row(sheet_handle); + if (!ok) + { + lua_pushnil(L); + } + else + { + std::string value; + auto cells = std::vector(); + while (get_next_cell(sheet_handle, value)) + { + cells.push_back(value); + } + Lua::PushVector(L, cells, true); + } + + return 1; +} + +DFHACK_PLUGIN_LUA_FUNCTIONS { + DFHACK_LUA_FUNCTION(open_xlsx_file), + DFHACK_LUA_FUNCTION(close_xlsx_file), + DFHACK_LUA_FUNCTION(open_sheet), + DFHACK_LUA_FUNCTION(close_sheet), + DFHACK_LUA_END +}; + +DFHACK_PLUGIN_LUA_COMMANDS{ + DFHACK_LUA_COMMAND(list_sheets), + DFHACK_LUA_COMMAND(get_row), + DFHACK_LUA_END +}; + +DFhackCExport command_result plugin_init(color_ostream &, std::vector &) +{ + return CR_OK; +} + +DFhackCExport command_result plugin_shutdown(color_ostream &) +{ + return CR_OK; +} From 4a04273fae91ff7aaa9c3bb2cb2bebed65220f3f Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sun, 9 Aug 2020 09:28:19 -0700 Subject: [PATCH 292/547] document xlsxreader functions --- docs/Lua API.rst | 31 +++++++++++++++++++++++++++++++ docs/Plugins.rst | 3 ++- plugins/lua/xlsxreader.lua | 18 ++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/docs/Lua API.rst b/docs/Lua API.rst index 45ccd46a9..e66989e35 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -4102,6 +4102,37 @@ Lua plugin classes - ``shuffle()``: shuffles the sequence of numbers - ``next()``: returns next number in the sequence +xlsxreader +========== + +Utility functions to facilitate reading .xlsx spreadsheets. It provides the +following API methods: + + - ``file_handle open_xlsx_file(filename)`` + - ``close_xlsx_file(file_handle)`` + - ``sheet_names list_sheets(file_handle)`` + - ``sheet_handle open_sheet(file_handle, sheet_name)`` + - ``close_sheet(sheet_handle)`` + - ``cell_strings get_row(sheet_handle)`` + + Example:: + + local xlsxreader = require('plugins.xlsxreader') + + local filepath = "path/to/some_file.xlsx" + local xlsx_file = xlsxreader.open_xlsx_file(filepath) + for _, sheet_name in ipairs(xlsxreader.list_sheets(xlsx_file)) do + print('reading sheet: '..sheet_name) + local xlsx_sheet = xlsxreader.open_sheet(xlsx_file, sheet_name) + local row_cells = xlsxreader.get_row(xlsx_sheet) + while row_cells do + printall(row_cells) + row_cells = xlsxreader.get_row(xlsx_sheet) + end + xlsxreader.close_sheet(xlsx_sheet) + end + xlsxreader.close_xlsx_file(xlsx_file) + ======= Scripts ======= diff --git a/docs/Plugins.rst b/docs/Plugins.rst index 6699163c2..9b5569e62 100644 --- a/docs/Plugins.rst +++ b/docs/Plugins.rst @@ -2939,10 +2939,11 @@ Lua API ======= Some plugins consist solely of native libraries exposed to Lua. They are listed -in the `lua-api` file under `lua-plugins`: +in the `lua-api` file under `lua-plugins`:: * `eventful` * `building-hacks` * `luasocket` * `map-render` * `cxxrandom` +* `xlsxreader` diff --git a/plugins/lua/xlsxreader.lua b/plugins/lua/xlsxreader.lua index 3dbc1f2d8..09ba01978 100644 --- a/plugins/lua/xlsxreader.lua +++ b/plugins/lua/xlsxreader.lua @@ -12,6 +12,24 @@ local _ENV = mkmodule('plugins.xlsxreader') * close_sheet(sheet_handle) * cell_strings get_row(sheet_handle) +Sample usage: + + local xlsxreader = require('plugins.xlsxreader') + + local filepath = "path/to/some_file.xlsx" + local xlsx_file = xlsxreader.open_xlsx_file(filepath) + for _, sheet_name in ipairs(xlsxreader.list_sheets(xlsx_file)) do + print('reading sheet: '..sheet_name) + local xlsx_sheet = xlsxreader.open_sheet(xlsx_file, sheet_name) + local row_cells = xlsxreader.get_row(xlsx_sheet) + while row_cells do + printall(row_cells) + row_cells = xlsxreader.get_row(xlsx_sheet) + end + xlsxreader.close_sheet(xlsx_sheet) + end + xlsxreader.close_xlsx_file(xlsx_file) + --]] return _ENV From 5294360908c462ea24a613230df18dc336f55d75 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sun, 9 Aug 2020 09:46:54 -0700 Subject: [PATCH 293/547] more windows library naming shenanigans --- plugins/CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 6531165e1..2bc135d33 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -85,6 +85,12 @@ set_target_properties(zip PROPERTIES IMPORTED_LOCATION ${LIBZIP_LIB}) add_library(expat STATIC IMPORTED) set_target_properties(expat PROPERTIES IMPORTED_LOCATION ${LIBEXPAT_LIB}) +if(WIN32) + set(LIB_Z_LIB "zlib.lib") +else() + set(LIB_Z_LIB "z") +endif() + # Plugins option(BUILD_SUPPORTED "Build the supported plugins (reveal, probe, etc.)." ON) if(BUILD_SUPPORTED) @@ -183,7 +189,7 @@ if(BUILD_SUPPORTED) add_subdirectory(tweak) dfhack_plugin(workflow workflow.cpp LINK_LIBRARIES lua) dfhack_plugin(workNow workNow.cpp) - dfhack_plugin(xlsxreader xlsxreader.cpp LINK_LIBRARIES lua xlsxio_read zip expat z) + dfhack_plugin(xlsxreader xlsxreader.cpp LINK_LIBRARIES lua xlsxio_read zip expat ${LIB_Z_LIB}) dfhack_plugin(zone zone.cpp LINK_LIBRARIES lua) endif() target_include_directories(xlsxreader PRIVATE ${XLSXIO_INSTALL_DIR}/include) From e2129673c12750a89b5939d0d353cfc597fc8c46 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sun, 9 Aug 2020 10:11:24 -0700 Subject: [PATCH 294/547] fix zlib path on windows --- plugins/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 2bc135d33..c2798cd7d 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -86,7 +86,7 @@ add_library(expat STATIC IMPORTED) set_target_properties(expat PROPERTIES IMPORTED_LOCATION ${LIBEXPAT_LIB}) if(WIN32) - set(LIB_Z_LIB "zlib.lib") + set(LIB_Z_LIB "depends/zlib/lib/zlib.lib") else() set(LIB_Z_LIB "z") endif() From 06e3f77e39d106fdc1633e3e6bfc207447a1d805 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sun, 9 Aug 2020 10:47:15 -0700 Subject: [PATCH 295/547] fix windows zlib path, hopefully for the last time --- plugins/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index c2798cd7d..bc897ba7d 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -86,7 +86,7 @@ add_library(expat STATIC IMPORTED) set_target_properties(expat PROPERTIES IMPORTED_LOCATION ${LIBEXPAT_LIB}) if(WIN32) - set(LIB_Z_LIB "depends/zlib/lib/zlib.lib") + set(LIB_Z_LIB "depends/zlib/lib/zlib") else() set(LIB_Z_LIB "z") endif() From 679ca41da8739aad216fd28735b30ef08903011d Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sun, 9 Aug 2020 21:22:17 -0700 Subject: [PATCH 296/547] make sure xlsxio knows to link statically --- depends/CMakeLists.txt | 3 +-- plugins/xlsxreader.cpp | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/CMakeLists.txt b/depends/CMakeLists.txt index 69ce40ae3..a2eafb052 100644 --- a/depends/CMakeLists.txt +++ b/depends/CMakeLists.txt @@ -72,10 +72,9 @@ set(XLSXIO_LIB ${XLSXIO_INSTALL_DIR}/lib/${LIB_PREFIX}xlsxio_read${LIB_SUFFIX}) set(XLSXIO_LIB ${XLSXIO_LIB} PARENT_SCOPE) ExternalProject_Add(xlsxio_project PREFIX xlsxio + DEPENDS libexpat_project libzip_project SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/xlsxio INSTALL_DIR ${XLSXIO_INSTALL_DIR} BUILD_BYPRODUCTS ${XLSXIO_LIB} CMAKE_ARGS ${CL_ARGS} -DCMAKE_INSTALL_PREFIX=${XLSXIO_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_STATIC=ON -DBUILD_SHARED=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_TOOLS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_DOCUMENTATION=OFF -DWITH_LIBZIP=ON -DZLIB_DIR=${ZLIB_DIR} -DLIBZIP_DIR=${LIBZIP_INSTALL_DIR} -DEXPAT_DIR=${LIBEXPAT_INSTALL_DIR} -DEXPAT_LIBRARIES=${LIBEXPAT_LIB} -DEXPAT_INCLUDE_DIRS=${LIBEXPAT_INSTALL_DIR}/include -DCMAKE_POSITION_INDEPENDENT_CODE=ON ) -add_dependencies(xlsxio_project libexpat_project) -add_dependencies(xlsxio_project libzip_project) diff --git a/plugins/xlsxreader.cpp b/plugins/xlsxreader.cpp index 9c773718d..fb5039465 100644 --- a/plugins/xlsxreader.cpp +++ b/plugins/xlsxreader.cpp @@ -37,6 +37,7 @@ * return true; */ +#define BUILD_XLSXIO_STATIC #include #include "DataFuncs.h" From 6da364a60b628a078c45bea1870ca3991561e404 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Mon, 10 Aug 2020 00:01:47 -0700 Subject: [PATCH 297/547] ensure libexpat is used as a static lib --- depends/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/depends/CMakeLists.txt b/depends/CMakeLists.txt index a2eafb052..9d63f3c37 100644 --- a/depends/CMakeLists.txt +++ b/depends/CMakeLists.txt @@ -38,10 +38,12 @@ if(WIN32) set(EXPAT_LIB_SUFFIX "MD.lib") set(LIB_SUFFIX ".lib") set(LIB_PREFIX "") + set(XLSXIO_C_FLAGS "${CMAKE_C_FLAGS} /DXML_STATIC") else() set(EXPAT_LIB_SUFFIX ".a") set(LIB_SUFFIX ".a") set(LIB_PREFIX "lib") + set(XLSXIO_C_FLAGS "${CMAKE_C_FLAGS} -DXML_STATIC") endif() set(LIBEXPAT_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/libexpat) @@ -76,5 +78,5 @@ ExternalProject_Add(xlsxio_project SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/xlsxio INSTALL_DIR ${XLSXIO_INSTALL_DIR} BUILD_BYPRODUCTS ${XLSXIO_LIB} - CMAKE_ARGS ${CL_ARGS} -DCMAKE_INSTALL_PREFIX=${XLSXIO_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_STATIC=ON -DBUILD_SHARED=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_TOOLS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_DOCUMENTATION=OFF -DWITH_LIBZIP=ON -DZLIB_DIR=${ZLIB_DIR} -DLIBZIP_DIR=${LIBZIP_INSTALL_DIR} -DEXPAT_DIR=${LIBEXPAT_INSTALL_DIR} -DEXPAT_LIBRARIES=${LIBEXPAT_LIB} -DEXPAT_INCLUDE_DIRS=${LIBEXPAT_INSTALL_DIR}/include -DCMAKE_POSITION_INDEPENDENT_CODE=ON + CMAKE_ARGS ${CL_ARGS} -DCMAKE_INSTALL_PREFIX=${XLSXIO_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DBUILD_STATIC=ON -DBUILD_SHARED=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_TOOLS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_DOCUMENTATION=OFF -DWITH_LIBZIP=ON -DZLIB_DIR=${ZLIB_DIR} -DLIBZIP_DIR=${LIBZIP_INSTALL_DIR} -DEXPAT_DIR=${LIBEXPAT_INSTALL_DIR} -DEXPAT_LIBRARIES=${LIBEXPAT_LIB} -DEXPAT_INCLUDE_DIRS=${LIBEXPAT_INSTALL_DIR}/include -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_C_FLAGS=${XLSXIO_C_FLAGS} ) From 702228bf124ad656153c65eb17e2d9b93a107082 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Mon, 10 Aug 2020 01:01:13 -0700 Subject: [PATCH 298/547] use standard CMAKE vars for prefixes and suffixes --- depends/CMakeLists.txt | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/depends/CMakeLists.txt b/depends/CMakeLists.txt index 9d63f3c37..2437794bb 100644 --- a/depends/CMakeLists.txt +++ b/depends/CMakeLists.txt @@ -35,19 +35,15 @@ endforeach() include(ExternalProject) if(WIN32) - set(EXPAT_LIB_SUFFIX "MD.lib") - set(LIB_SUFFIX ".lib") - set(LIB_PREFIX "") + set(EXPAT_LIB_NAME_SUFFIX "MD") set(XLSXIO_C_FLAGS "${CMAKE_C_FLAGS} /DXML_STATIC") else() - set(EXPAT_LIB_SUFFIX ".a") - set(LIB_SUFFIX ".a") - set(LIB_PREFIX "lib") + set(EXPAT_LIB_NAME_SUFFIX "") set(XLSXIO_C_FLAGS "${CMAKE_C_FLAGS} -DXML_STATIC") endif() set(LIBEXPAT_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/libexpat) -set(LIBEXPAT_LIB ${LIBEXPAT_INSTALL_DIR}/lib/libexpat${EXPAT_LIB_SUFFIX}) +set(LIBEXPAT_LIB ${LIBEXPAT_INSTALL_DIR}/lib/libexpat${EXPAT_LIB_NAME_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}) set(LIBEXPAT_LIB ${LIBEXPAT_LIB} PARENT_SCOPE) ExternalProject_Add(libexpat_project PREFIX libexpat @@ -58,7 +54,7 @@ ExternalProject_Add(libexpat_project ) set(LIBZIP_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/libzip) -set(LIBZIP_LIB ${LIBZIP_INSTALL_DIR}/lib/${LIB_PREFIX}zip${LIB_SUFFIX}) +set(LIBZIP_LIB ${LIBZIP_INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}zip${CMAKE_STATIC_LIBRARY_SUFFIX}) set(LIBZIP_LIB ${LIBZIP_LIB} PARENT_SCOPE) ExternalProject_Add(libzip_project PREFIX libzip @@ -70,7 +66,7 @@ ExternalProject_Add(libzip_project set(XLSXIO_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/xlsxio) set(XLSXIO_INSTALL_DIR ${XLSXIO_INSTALL_DIR} PARENT_SCOPE) -set(XLSXIO_LIB ${XLSXIO_INSTALL_DIR}/lib/${LIB_PREFIX}xlsxio_read${LIB_SUFFIX}) +set(XLSXIO_LIB ${XLSXIO_INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}xlsxio_read${CMAKE_STATIC_LIBRARY_SUFFIX}) set(XLSXIO_LIB ${XLSXIO_LIB} PARENT_SCOPE) ExternalProject_Add(xlsxio_project PREFIX xlsxio From 69322ec4299e09c19d0581654d933cd29a75d4b1 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Mon, 10 Aug 2020 01:13:16 -0700 Subject: [PATCH 299/547] use proper USERDATA instead of LIGHTUSERDATA --- plugins/xlsxreader.cpp | 108 +++++++++++++++++++++-------------------- 1 file changed, 56 insertions(+), 52 deletions(-) diff --git a/plugins/xlsxreader.cpp b/plugins/xlsxreader.cpp index fb5039465..02b83127d 100644 --- a/plugins/xlsxreader.cpp +++ b/plugins/xlsxreader.cpp @@ -48,36 +48,53 @@ using namespace DFHack; DFHACK_PLUGIN("xlsxreader"); -typedef void* xlsx_file_handle; -typedef void* xlsx_sheet_handle; +struct handle_identity : public compound_identity { + handle_identity(): compound_identity(0, nullptr, nullptr, "handle") {}; + DFHack::identity_type type() override { return IDTYPE_OPAQUE; } +}; + +struct xlsx_file_handle { + const xlsxioreader handle; + xlsx_file_handle(xlsxioreader handle): handle(handle) {} + static handle_identity _identity; +}; + +struct xlsx_sheet_handle { + const xlsxioreadersheet handle; + xlsx_sheet_handle(xlsxioreadersheet handle): handle(handle) {} + static handle_identity _identity; +}; + +handle_identity xlsx_file_handle::_identity; +handle_identity xlsx_sheet_handle::_identity; // returns NULL on error -xlsx_file_handle open_xlsx_file(std::string filename) -{ - return xlsxioread_open(filename.c_str()); +xlsx_file_handle* open_xlsx_file(std::string filename) { + return new xlsx_file_handle(xlsxioread_open(filename.c_str())); } -void close_xlsx_file(xlsx_file_handle file_handle) -{ - xlsxioread_close((xlsxioreader)file_handle); +void close_xlsx_file(xlsx_file_handle *file_handle) { + CHECK_NULL_POINTER(file_handle); + xlsxioread_close(file_handle->handle); + delete(file_handle); } // returns XLSXIOReaderSheet object or NULL on error -xlsx_sheet_handle open_sheet(xlsx_file_handle file_handle, std::string sheet_name) -{ - if (file_handle == NULL) - return NULL; - return xlsxioread_sheet_open((xlsxioreader)file_handle, - sheet_name.c_str(), XLSXIOREAD_SKIP_NONE); +xlsx_sheet_handle* open_sheet(xlsx_file_handle *file_handle, + std::string sheet_name) { + CHECK_NULL_POINTER(file_handle); + return new xlsx_sheet_handle( + xlsxioread_sheet_open(file_handle->handle, + sheet_name.c_str(), XLSXIOREAD_SKIP_NONE)); } -void close_sheet(xlsx_sheet_handle sheet_handle) -{ - xlsxioread_sheet_close((xlsxioreadersheet)sheet_handle); +void close_sheet(xlsx_sheet_handle *sheet_handle) { + CHECK_NULL_POINTER(sheet_handle); + xlsxioread_sheet_close(sheet_handle->handle); + delete(sheet_handle); } -static int list_callback(const XLSXIOCHAR* name, void* cbdata) -{ +static int list_callback(const XLSXIOCHAR* name, void* cbdata) { auto sheetNames = (std::vector *)cbdata; sheetNames->push_back(name); return 0; @@ -85,19 +102,16 @@ static int list_callback(const XLSXIOCHAR* name, void* cbdata) // start reading the next row of data; must be called before get_next_cell. // returns false if there is no next row to get. -static bool get_next_row(xlsx_sheet_handle sheet_handle) -{ - return xlsxioread_sheet_next_row((xlsxioreadersheet)sheet_handle) != 0; +static bool get_next_row(xlsx_sheet_handle *sheet_handle) { + return xlsxioread_sheet_next_row(sheet_handle->handle) != 0; } // fills the value param with the contents of the cell in the next column cell // in the current row. // returns false if there are no more cells in this row. -static bool get_next_cell(xlsx_sheet_handle sheet_handle, std::string& value) -{ +static bool get_next_cell(xlsx_sheet_handle *sheet_handle, std::string& value) { char* result; - if (!xlsxioread_sheet_next_cell_string( - (xlsxioreadersheet)sheet_handle, &result)) { + if (!xlsxioread_sheet_next_cell_string(sheet_handle->handle, &result)) { value.clear(); return false; } @@ -106,44 +120,35 @@ static bool get_next_cell(xlsx_sheet_handle sheet_handle, std::string& value) return true; } -// internal function to factor out handle extraction -static void * get_xlsxreader_handle(lua_State *L) -{ - if (lua_gettop(L) < 1 || lua_isnil(L, 1)) - { +// internal function to extract a handle from the first stack param +static void * get_xlsxreader_handle(lua_State *L) { + if (lua_gettop(L) < 1 || lua_isnil(L, 1)) { luaL_error(L, "invalid xlsxreader handle"); } - luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); - return lua_touserdata(L, 1); + luaL_checktype(L, 1, LUA_TUSERDATA); + return LuaWrapper::get_object_ref(L, 1); } // takes a file handle and returns a table-list of sheet names -int list_sheets(lua_State *L) -{ - xlsxioreader file_handle = (xlsxioreader)get_xlsxreader_handle(L); +int list_sheets(lua_State *L) { + auto file_handle = (xlsx_file_handle *)get_xlsxreader_handle(L); auto sheetNames = std::vector(); - xlsxioread_list_sheets(file_handle, list_callback, &sheetNames); + xlsxioread_list_sheets(file_handle->handle, list_callback, &sheetNames); Lua::PushVector(L, sheetNames, true); return 1; } // takes the sheet handle and returns a table-list of strings, or nil if we // already processed the last row in the file. -int get_row(lua_State *L) -{ - xlsxioreadersheet sheet_handle = - (xlsxioreadersheet)get_xlsxreader_handle(L); +int get_row(lua_State *L) { + auto sheet_handle = (xlsx_sheet_handle *)get_xlsxreader_handle(L); bool ok = get_next_row(sheet_handle); - if (!ok) - { + if (!ok) { lua_pushnil(L); - } - else - { + } else { std::string value; auto cells = std::vector(); - while (get_next_cell(sheet_handle, value)) - { + while (get_next_cell(sheet_handle, value)) { cells.push_back(value); } Lua::PushVector(L, cells, true); @@ -166,12 +171,11 @@ DFHACK_PLUGIN_LUA_COMMANDS{ DFHACK_LUA_END }; -DFhackCExport command_result plugin_init(color_ostream &, std::vector &) -{ +DFhackCExport command_result plugin_init(color_ostream &, + std::vector &) { return CR_OK; } -DFhackCExport command_result plugin_shutdown(color_ostream &) -{ +DFhackCExport command_result plugin_shutdown(color_ostream &) { return CR_OK; } From 17c509a5961def16be02a4d1279944e89418a9b4 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Mon, 10 Aug 2020 09:18:49 -0700 Subject: [PATCH 300/547] update sample code for xlsxreader to use finalize --- plugins/lua/xlsxreader.lua | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/plugins/lua/xlsxreader.lua b/plugins/lua/xlsxreader.lua index 09ba01978..323231915 100644 --- a/plugins/lua/xlsxreader.lua +++ b/plugins/lua/xlsxreader.lua @@ -16,19 +16,31 @@ Sample usage: local xlsxreader = require('plugins.xlsxreader') - local filepath = "path/to/some_file.xlsx" - local xlsx_file = xlsxreader.open_xlsx_file(filepath) - for _, sheet_name in ipairs(xlsxreader.list_sheets(xlsx_file)) do + local function dump_sheet(xlsx_file, sheet_name) print('reading sheet: '..sheet_name) local xlsx_sheet = xlsxreader.open_sheet(xlsx_file, sheet_name) - local row_cells = xlsxreader.get_row(xlsx_sheet) - while row_cells do - printall(row_cells) - row_cells = xlsxreader.get_row(xlsx_sheet) - end - xlsxreader.close_sheet(xlsx_sheet) + dfhack.with_finalize( + function () xlsxreader.close_sheet(xlsx_sheet) end, + function () + local row_cells = xlsxreader.get_row(xlsx_sheet) + while row_cells do + printall(row_cells) + row_cells = xlsxreader.get_row(xlsx_sheet) + end + end + ) end - xlsxreader.close_xlsx_file(xlsx_file) + + local filepath = "path/to/some_file.xlsx" + local xlsx_file = xlsxreader.open_xlsx_file(filepath) + dfhack.with_finalize( + function () xlsxreader.close_xlsx_file(xlsx_file) end, + function () + for _, sheet_name in ipairs(xlsxreader.list_sheets(xlsx_file)) do + dump_sheet(xlsx_file, sheet_name) + end + end + ) --]] From a2279cc9a72b567812856f6e606bba38c55e6c2f Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Mon, 10 Aug 2020 14:37:59 -0700 Subject: [PATCH 301/547] update docs in Lua API.rst too --- docs/Lua API.rst | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/docs/Lua API.rst b/docs/Lua API.rst index e66989e35..45eeca78e 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -4119,19 +4119,31 @@ following API methods: local xlsxreader = require('plugins.xlsxreader') - local filepath = "path/to/some_file.xlsx" - local xlsx_file = xlsxreader.open_xlsx_file(filepath) - for _, sheet_name in ipairs(xlsxreader.list_sheets(xlsx_file)) do + local function dump_sheet(xlsx_file, sheet_name) print('reading sheet: '..sheet_name) local xlsx_sheet = xlsxreader.open_sheet(xlsx_file, sheet_name) - local row_cells = xlsxreader.get_row(xlsx_sheet) - while row_cells do - printall(row_cells) - row_cells = xlsxreader.get_row(xlsx_sheet) - end - xlsxreader.close_sheet(xlsx_sheet) + dfhack.with_finalize( + function () xlsxreader.close_sheet(xlsx_sheet) end, + function () + local row_cells = xlsxreader.get_row(xlsx_sheet) + while row_cells do + printall(row_cells) + row_cells = xlsxreader.get_row(xlsx_sheet) + end + end + ) end - xlsxreader.close_xlsx_file(xlsx_file) + + local filepath = "path/to/some_file.xlsx" + local xlsx_file = xlsxreader.open_xlsx_file(filepath) + dfhack.with_finalize( + function () xlsxreader.close_xlsx_file(xlsx_file) end, + function () + for _, sheet_name in ipairs(xlsxreader.list_sheets(xlsx_file)) do + dump_sheet(xlsx_file, sheet_name) + end + end + ) ======= Scripts From 0d9614154f1f85e508549941a7519b59e21135bf Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Mon, 10 Aug 2020 23:04:05 -0700 Subject: [PATCH 302/547] don't turn a rst list into code --- docs/Plugins.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Plugins.rst b/docs/Plugins.rst index 9b5569e62..e98e46073 100644 --- a/docs/Plugins.rst +++ b/docs/Plugins.rst @@ -2939,7 +2939,7 @@ Lua API ======= Some plugins consist solely of native libraries exposed to Lua. They are listed -in the `lua-api` file under `lua-plugins`:: +in the `lua-api` file under `lua-plugins`: * `eventful` * `building-hacks` From 438d264b3154cb95fbf6c66d0146202b8347016c Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Mon, 10 Aug 2020 23:09:03 -0700 Subject: [PATCH 303/547] use separate identity classes for each handle type --- plugins/xlsxreader.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/plugins/xlsxreader.cpp b/plugins/xlsxreader.cpp index 02b83127d..58321705d 100644 --- a/plugins/xlsxreader.cpp +++ b/plugins/xlsxreader.cpp @@ -48,25 +48,32 @@ using namespace DFHack; DFHACK_PLUGIN("xlsxreader"); -struct handle_identity : public compound_identity { - handle_identity(): compound_identity(0, nullptr, nullptr, "handle") {}; +struct xlsx_file_handle_identity : public compound_identity { + xlsx_file_handle_identity() + :compound_identity(0, nullptr, nullptr, "handle") {}; + DFHack::identity_type type() override { return IDTYPE_OPAQUE; } +}; + +struct xlsx_sheet_handle_identity : public compound_identity { + xlsx_sheet_handle_identity() + :compound_identity(0, nullptr, nullptr, "handle") {}; DFHack::identity_type type() override { return IDTYPE_OPAQUE; } }; struct xlsx_file_handle { const xlsxioreader handle; xlsx_file_handle(xlsxioreader handle): handle(handle) {} - static handle_identity _identity; + static xlsx_file_handle_identity _identity; }; struct xlsx_sheet_handle { const xlsxioreadersheet handle; xlsx_sheet_handle(xlsxioreadersheet handle): handle(handle) {} - static handle_identity _identity; + static xlsx_sheet_handle_identity _identity; }; -handle_identity xlsx_file_handle::_identity; -handle_identity xlsx_sheet_handle::_identity; +xlsx_file_handle_identity xlsx_file_handle::_identity; +xlsx_sheet_handle_identity xlsx_sheet_handle::_identity; // returns NULL on error xlsx_file_handle* open_xlsx_file(std::string filename) { From 1e9562bd76a83557ed4af7ac574e445f801366f8 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Mon, 10 Aug 2020 23:35:38 -0700 Subject: [PATCH 304/547] add target label for xlsxreader --- docs/Lua API.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/Lua API.rst b/docs/Lua API.rst index 45eeca78e..5cecfb7f2 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -4102,6 +4102,8 @@ Lua plugin classes - ``shuffle()``: shuffles the sequence of numbers - ``next()``: returns next number in the sequence +.. _xlsxreader: + xlsxreader ========== From c6f9eb519a166c49d6bb37aecf3948689a71788f Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Tue, 11 Aug 2020 13:44:07 -0700 Subject: [PATCH 305/547] remove outdated example code in xlsxreader.cpp there is already good example code in Lua API.rst and in xlsxreader.lua, so just remove this one --- plugins/xlsxreader.cpp | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/plugins/xlsxreader.cpp b/plugins/xlsxreader.cpp index 58321705d..560d3cc2e 100644 --- a/plugins/xlsxreader.cpp +++ b/plugins/xlsxreader.cpp @@ -1,40 +1,5 @@ /* * Wrapper for xlsxio_read library functions. - * - * Sample usage: - * - * std::string filename = "sample_file.xlsx"; - * xlsxioreader xlsxfile = XlsxReader::open_xlsx_file(filename); - * if (xlsxfile == NULL) { - * printf("cannot open file: '%s'", filename.c_str()); - * return false; - * } - * auto sheetNames = XlsxReader::list_sheets(xlsxfile); - * for (auto sheetName = sheetNames.begin(); - * sheetName != sheetNames.end(); - * ++sheetName) { - * printf("reading sheet: %s\n", sheetName->c_str()); - * xlsxioreadersheet xlsxsheet = - * XlsxReader::open_sheet(xlsxfile, *sheetName); - * if (xlsxsheet == NULL) { - * printf("cannot open sheet: '%s'", sheetName->c_str()); - * continue; - * } - * std::string value; - * int row_num = 1; - * while (XlsxReader::GetNextRow(xlsxsheet)) { - * std::string s; - * printf("%d:\t", row_num); - * while (XlsxReader::GetNextCell(xlsxsheet, s)) { - * printf("%s\t", s.c_str()); - * } - * printf("\n"); - * ++row_num; - * } - * XlsxReader::close_sheet(xlsxsheet); - * } - * XlsxReader::close_xlsx_file(xlsxfile); - * return true; */ #define BUILD_XLSXIO_STATIC From cfc736caa1d627c800cee49221d30945bfc8567d Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Tue, 11 Aug 2020 14:18:09 -0700 Subject: [PATCH 306/547] give the identity classes distinctive name fields both would have been represented as "handle" to Lua --- plugins/xlsxreader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/xlsxreader.cpp b/plugins/xlsxreader.cpp index 560d3cc2e..d8e6264f7 100644 --- a/plugins/xlsxreader.cpp +++ b/plugins/xlsxreader.cpp @@ -15,13 +15,13 @@ DFHACK_PLUGIN("xlsxreader"); struct xlsx_file_handle_identity : public compound_identity { xlsx_file_handle_identity() - :compound_identity(0, nullptr, nullptr, "handle") {}; + :compound_identity(0, nullptr, nullptr, "xlsx_file_handle") {}; DFHack::identity_type type() override { return IDTYPE_OPAQUE; } }; struct xlsx_sheet_handle_identity : public compound_identity { xlsx_sheet_handle_identity() - :compound_identity(0, nullptr, nullptr, "handle") {}; + :compound_identity(0, nullptr, nullptr, "xlsx_sheet_handle") {}; DFHack::identity_type type() override { return IDTYPE_OPAQUE; } }; From 0bda289b1769429fa17e12862626502498440529 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Tue, 11 Aug 2020 14:51:17 -0700 Subject: [PATCH 307/547] move xlsxreader identity statics to dfhack lib --- library/CMakeLists.txt | 3 +++ library/PluginStatics.cpp | 9 +++++++++ library/include/PluginStatics.h | 34 +++++++++++++++++++++++++++++++++ plugins/xlsxreader.cpp | 28 +-------------------------- 4 files changed, 47 insertions(+), 27 deletions(-) create mode 100644 library/PluginStatics.cpp create mode 100644 library/include/PluginStatics.h diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 2de293e15..b551c03f9 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -40,6 +40,8 @@ set(MAIN_HEADERS include/Module.h include/Pragma.h include/MemAccess.h + include/PluginManager.h + include/PluginStatics.h include/Signal.hpp include/TileTypes.h include/Types.h @@ -72,6 +74,7 @@ set(MAIN_SOURCES MiscUtils.cpp Types.cpp PluginManager.cpp + PluginStatics.cpp TileTypes.cpp VersionInfoFactory.cpp RemoteClient.cpp diff --git a/library/PluginStatics.cpp b/library/PluginStatics.cpp new file mode 100644 index 000000000..d5abdb840 --- /dev/null +++ b/library/PluginStatics.cpp @@ -0,0 +1,9 @@ +#include "PluginStatics.h" + +namespace DFHack { + +// xlsxreader statics +DFHACK_EXPORT xlsx_file_handle_identity xlsx_file_handle::_identity; +DFHACK_EXPORT xlsx_sheet_handle_identity xlsx_sheet_handle::_identity; + +} diff --git a/library/include/PluginStatics.h b/library/include/PluginStatics.h new file mode 100644 index 000000000..b5ca4b468 --- /dev/null +++ b/library/include/PluginStatics.h @@ -0,0 +1,34 @@ +#pragma once + +#include "DataIdentity.h" + +namespace DFHack { + +// xlsxreader definitions +struct xlsx_file_handle_identity : public compound_identity { + xlsx_file_handle_identity() + :compound_identity(0, nullptr, nullptr, "xlsx_file_handle") {}; + DFHack::identity_type type() override { return IDTYPE_OPAQUE; } +}; + +struct xlsx_sheet_handle_identity : public compound_identity { + xlsx_sheet_handle_identity() + :compound_identity(0, nullptr, nullptr, "xlsx_sheet_handle") {}; + DFHack::identity_type type() override { return IDTYPE_OPAQUE; } +}; + +struct xlsx_file_handle { + typedef struct xlsxio_read_struct* xlsxioreader; + const xlsxioreader handle; + xlsx_file_handle(xlsxioreader handle): handle(handle) {} + static xlsx_file_handle_identity _identity; +}; + +struct xlsx_sheet_handle { + typedef struct xlsxio_read_sheet_struct* xlsxioreadersheet; + const xlsxioreadersheet handle; + xlsx_sheet_handle(xlsxioreadersheet handle): handle(handle) {} + static xlsx_sheet_handle_identity _identity; +}; + +} diff --git a/plugins/xlsxreader.cpp b/plugins/xlsxreader.cpp index d8e6264f7..6f76f5e97 100644 --- a/plugins/xlsxreader.cpp +++ b/plugins/xlsxreader.cpp @@ -8,38 +8,12 @@ #include "DataFuncs.h" #include "LuaTools.h" #include "PluginManager.h" +#include "PluginStatics.h" using namespace DFHack; DFHACK_PLUGIN("xlsxreader"); -struct xlsx_file_handle_identity : public compound_identity { - xlsx_file_handle_identity() - :compound_identity(0, nullptr, nullptr, "xlsx_file_handle") {}; - DFHack::identity_type type() override { return IDTYPE_OPAQUE; } -}; - -struct xlsx_sheet_handle_identity : public compound_identity { - xlsx_sheet_handle_identity() - :compound_identity(0, nullptr, nullptr, "xlsx_sheet_handle") {}; - DFHack::identity_type type() override { return IDTYPE_OPAQUE; } -}; - -struct xlsx_file_handle { - const xlsxioreader handle; - xlsx_file_handle(xlsxioreader handle): handle(handle) {} - static xlsx_file_handle_identity _identity; -}; - -struct xlsx_sheet_handle { - const xlsxioreadersheet handle; - xlsx_sheet_handle(xlsxioreadersheet handle): handle(handle) {} - static xlsx_sheet_handle_identity _identity; -}; - -xlsx_file_handle_identity xlsx_file_handle::_identity; -xlsx_sheet_handle_identity xlsx_sheet_handle::_identity; - // returns NULL on error xlsx_file_handle* open_xlsx_file(std::string filename) { return new xlsx_file_handle(xlsxioread_open(filename.c_str())); From 4f88bb4c3d3f33e44990778d41d1167bacba39fd Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Tue, 11 Aug 2020 16:54:53 -0700 Subject: [PATCH 308/547] attempt to solve compilation error on windows --- library/include/PluginStatics.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/include/PluginStatics.h b/library/include/PluginStatics.h index b5ca4b468..a88249eae 100644 --- a/library/include/PluginStatics.h +++ b/library/include/PluginStatics.h @@ -21,14 +21,14 @@ struct xlsx_file_handle { typedef struct xlsxio_read_struct* xlsxioreader; const xlsxioreader handle; xlsx_file_handle(xlsxioreader handle): handle(handle) {} - static xlsx_file_handle_identity _identity; + DFHACK_IMPORT static xlsx_file_handle_identity _identity; }; struct xlsx_sheet_handle { typedef struct xlsxio_read_sheet_struct* xlsxioreadersheet; const xlsxioreadersheet handle; xlsx_sheet_handle(xlsxioreadersheet handle): handle(handle) {} - static xlsx_sheet_handle_identity _identity; + DFHACK_IMPORT static xlsx_sheet_handle_identity _identity; }; } From 39ae2d95fc78d547dd84002d77770a862b794ea1 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Tue, 11 Aug 2020 17:06:28 -0700 Subject: [PATCH 309/547] 2nd attempt to solve compilation errors on windows --- library/include/PluginStatics.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/library/include/PluginStatics.h b/library/include/PluginStatics.h index a88249eae..d0835e90f 100644 --- a/library/include/PluginStatics.h +++ b/library/include/PluginStatics.h @@ -5,30 +5,30 @@ namespace DFHack { // xlsxreader definitions -struct xlsx_file_handle_identity : public compound_identity { +struct DFHACK_EXPORT xlsx_file_handle_identity : public compound_identity { xlsx_file_handle_identity() :compound_identity(0, nullptr, nullptr, "xlsx_file_handle") {}; DFHack::identity_type type() override { return IDTYPE_OPAQUE; } }; -struct xlsx_sheet_handle_identity : public compound_identity { +struct DFHACK_EXPORT xlsx_sheet_handle_identity : public compound_identity { xlsx_sheet_handle_identity() :compound_identity(0, nullptr, nullptr, "xlsx_sheet_handle") {}; DFHack::identity_type type() override { return IDTYPE_OPAQUE; } }; -struct xlsx_file_handle { +struct DFHACK_EXPORT xlsx_file_handle { typedef struct xlsxio_read_struct* xlsxioreader; const xlsxioreader handle; xlsx_file_handle(xlsxioreader handle): handle(handle) {} - DFHACK_IMPORT static xlsx_file_handle_identity _identity; + static xlsx_file_handle_identity _identity; }; -struct xlsx_sheet_handle { +struct DFHACK_EXPORT xlsx_sheet_handle { typedef struct xlsxio_read_sheet_struct* xlsxioreadersheet; const xlsxioreadersheet handle; xlsx_sheet_handle(xlsxioreadersheet handle): handle(handle) {} - DFHACK_IMPORT static xlsx_sheet_handle_identity _identity; + static xlsx_sheet_handle_identity _identity; }; } From bda678bcd4d1ca609b296bcf8effc6364ae88fa2 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Tue, 11 Aug 2020 19:47:04 -0700 Subject: [PATCH 310/547] add some explanatory text to the top of the header --- library/include/PluginStatics.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/library/include/PluginStatics.h b/library/include/PluginStatics.h index d0835e90f..061fd3a21 100644 --- a/library/include/PluginStatics.h +++ b/library/include/PluginStatics.h @@ -1,3 +1,11 @@ +/* + * This file and the companion PluginStatics.cpp contain static structures used + * by DFHack plugins. Linking them here, into the dfhack library, instead of + * into the plugins themselves allows the plugins to be freely unloaded and + * reloaded without fear of causing cached references to static data becoming + * corrupted. + */ + #pragma once #include "DataIdentity.h" From 0f9f64d13762c28029af04c871aa23f13b4ce3d5 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Wed, 12 Aug 2020 15:14:59 -0700 Subject: [PATCH 311/547] remove materials files and replace with settings --- data/quickfort/materials-common.txt | 8 -------- dfhack-config/quickfort/materials.txt | 9 --------- dfhack-config/quickfort/quickfort.txt | 6 ++++++ 3 files changed, 6 insertions(+), 17 deletions(-) delete mode 100644 data/quickfort/materials-common.txt delete mode 100644 dfhack-config/quickfort/materials.txt diff --git a/data/quickfort/materials-common.txt b/data/quickfort/materials-common.txt deleted file mode 100644 index 256d5deb8..000000000 --- a/data/quickfort/materials-common.txt +++ /dev/null @@ -1,8 +0,0 @@ -# quickfort materials common baseline configuration file -# -# Defines forbidden materials and material preferences for build blueprints. -# Please DO NOT EDIT this file directly. Instead, custom materials preferences -# should be added to dfhack-config/quickfort/materials.txt. -# -# Syntax TBD - diff --git a/dfhack-config/quickfort/materials.txt b/dfhack-config/quickfort/materials.txt deleted file mode 100644 index 5938f16fe..000000000 --- a/dfhack-config/quickfort/materials.txt +++ /dev/null @@ -1,9 +0,0 @@ -# quickfort materials preference configuration file -# -# Defines forbidden materials and material preferences for build blueprints. -# Settings in this file take precedence over any settings in the baseline -# materials configuration file at hack/data/quickfort/materials-common.txt. See -# that file to view the global defaults. -# -# Syntax TBD - diff --git a/dfhack-config/quickfort/quickfort.txt b/dfhack-config/quickfort/quickfort.txt index 8a30124a1..575b7a804 100644 --- a/dfhack-config/quickfort/quickfort.txt +++ b/dfhack-config/quickfort/quickfort.txt @@ -11,6 +11,12 @@ # path. If set to a relative path, resolves to a directory under the DF folder. blueprints_dir=blueprints +# Force all blueprint buildings that could be built with any building material +# to only use blocks. The prevents logs, boulders, and bars (e.g. potash and +# coal) from being wasted on constructions. If set to false, buildings will be +# built with any available building material. +buildings_use_blocks=true + # Set to "true" or "false". If true, will designate dig blueprints in marker # mode. If false, only cells with dig codes explicitly prefixed with an "m" will # be designated in marker mode. From 42108a64b9e249a2e7d31cd5b3c9ebd706bc78fa Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Wed, 12 Aug 2020 15:12:53 -0700 Subject: [PATCH 312/547] expose basic buildingplan functionality to Lua --- plugins/CMakeLists.txt | 2 +- plugins/buildingplan-lib.cpp | 5 ----- plugins/buildingplan-lib.h | 5 +++++ plugins/buildingplan.cpp | 22 ++++++++++++++++++++++ plugins/lua/buildingplan.lua | 3 +++ 5 files changed, 31 insertions(+), 6 deletions(-) create mode 100644 plugins/lua/buildingplan.lua diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 678b7eec2..aa2f70625 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -96,7 +96,7 @@ if(BUILD_SUPPORTED) dfhack_plugin(blueprint blueprint.cpp LINK_LIBRARIES lua) dfhack_plugin(burrows burrows.cpp LINK_LIBRARIES lua) dfhack_plugin(building-hacks building-hacks.cpp LINK_LIBRARIES lua) - dfhack_plugin(buildingplan buildingplan.cpp LINK_LIBRARIES buildingplan-lib) + dfhack_plugin(buildingplan buildingplan.cpp LINK_LIBRARIES lua buildingplan-lib) dfhack_plugin(changeitem changeitem.cpp) dfhack_plugin(changelayer changelayer.cpp) dfhack_plugin(changevein changevein.cpp) diff --git a/plugins/buildingplan-lib.cpp b/plugins/buildingplan-lib.cpp index 0c29284db..e21c843aa 100644 --- a/plugins/buildingplan-lib.cpp +++ b/plugins/buildingplan-lib.cpp @@ -623,11 +623,6 @@ bool Planner::allocatePlannedBuilding(df::building_type type) return false; } - for (auto iter = newinst->jobs.begin(); iter != newinst->jobs.end(); iter++) - { - (*iter)->flags.bits.suspend = true; - } - if (type == building_type::Door) { auto door = virtual_cast(newinst); diff --git a/plugins/buildingplan-lib.h b/plugins/buildingplan-lib.h index 0d66e3248..d8d276a55 100644 --- a/plugins/buildingplan-lib.h +++ b/plugins/buildingplan-lib.h @@ -403,6 +403,11 @@ public: void addPlannedBuilding(df::building *bld) { + for (auto iter = bld->jobs.begin(); iter != bld->jobs.end(); iter++) + { + (*iter)->flags.bits.suspend = true; + } + PlannedBuilding pb(bld, &default_item_filters[bld->getType()]); planned_buildings.push_back(pb); } diff --git a/plugins/buildingplan.cpp b/plugins/buildingplan.cpp index c19eb02e9..c42aeac53 100644 --- a/plugins/buildingplan.cpp +++ b/plugins/buildingplan.cpp @@ -1,3 +1,4 @@ +#include "LuaTools.h" #include "buildingplan-lib.h" DFHACK_PLUGIN("buildingplan"); @@ -414,3 +415,24 @@ DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_chan return CR_OK; } + +// Lua API section + +static bool isPlannableBuilding(df::building_type type) { + return planner.isPlanableBuilding(type); +} + +static void addPlannedBuilding(df::building *bld) { + planner.addPlannedBuilding(bld); +} + +static void doCycle() { + planner.doCycle(); +} + +DFHACK_PLUGIN_LUA_FUNCTIONS { + DFHACK_LUA_FUNCTION(isPlannableBuilding), + DFHACK_LUA_FUNCTION(addPlannedBuilding), + DFHACK_LUA_FUNCTION(doCycle), + DFHACK_LUA_END +}; diff --git a/plugins/lua/buildingplan.lua b/plugins/lua/buildingplan.lua new file mode 100644 index 000000000..c1f86081c --- /dev/null +++ b/plugins/lua/buildingplan.lua @@ -0,0 +1,3 @@ +local _ENV = mkmodule('plugins.buildingplan') + +return _ENV From 26ce6fe199fa88b18b3463c6d71448f44f1f1b96 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Thu, 13 Aug 2020 00:51:34 -0700 Subject: [PATCH 313/547] document labels and multi-blueprint file formats --- data/blueprints/README.md | 70 +++++++++++++++++++++++++++++++-------- 1 file changed, 57 insertions(+), 13 deletions(-) diff --git a/data/blueprints/README.md b/data/blueprints/README.md index 6f11df32a..f54bbde97 100644 --- a/data/blueprints/README.md +++ b/data/blueprints/README.md @@ -13,7 +13,7 @@ The original idea and 1.0 codebase came from [Valdemar's](https://dwarffortressw This document focuses on DFHack Quickfort's capabilities and teaches players how to understand and build blueprint files. Much of the text was originally written by Joel Thornton, reused here with his permission. -For those just looking to apply blueprints, check out the [quickfort command syntax](https://docs.dfhack.org/en/stable/docs/_auto/base.html#quickfort) in the DFHack Scripts documentation. There are many ready-to-use blueprints available in the `blueprints/library` subfolder in your DFHack installation. Browse them on your computer or [online](https://github.com/DFHack/dfhack/tree/develop/data/blueprints/library), or run `quickfort list -l` at the `DFHack#` prompt to list them, and then `quickfort run` to apply them to your fort! +For those just looking to apply blueprints, check out the [quickfort command syntax](https://docs.dfhack.org/en/stable/docs/_auto/base.html#quickfort) in the DFHack Scripts documentation. There are also many ready-to-use blueprints available in the `blueprints/library` subfolder in your DFHack installation. Browse them on your computer or [online](https://github.com/DFHack/dfhack/tree/develop/data/blueprints/library), or run `quickfort list -l` at the `DFHack#` prompt to list them, and then `quickfort run` to apply them to your fort! See the [Links section](#links) for more information and online resources. @@ -25,7 +25,7 @@ Table of Contents * [Editing Blueprints](#editing-blueprints) * [Area expansion syntax](#area-expansion-syntax) * [Automatic area expansion](#automatic-area-expansion) - * [Specifying a starting position](#specifying-a-starting-position) + * [Blueprint labels and cursor offsets](#blueprint-labels-and-cursor-offsets) * [Multilevel blueprints](#multilevel-blueprints) * [Minecart tracks](#minecart-tracks) * [Packaging a set of blueprints](#packaging-a-set-of-blueprints) @@ -40,6 +40,7 @@ Features * General * Manages complete blueprints to handle the four main phases of DF construction * Supports .csv and multi-worksheet .xlsx blueprint files + * Supports multiple blueprints per .csv file/spreadsheet sheet * Near-instant application, even for very large and complex blueprints * Blueprints can span multiple z-levels * Undo functionality for dig, build, and place blueprints @@ -250,21 +251,28 @@ This style can be convenient for laying out multiple buildings of the same type. Quickfort will intelligently break large areas of the same designation into appropriately-sized chunks. -Specifying a starting position ------------------------------- +Blueprint labels and cursor offsets +----------------------------------- -You can optionally specify a cursor starting position for a particular blueprint, simplifying the task of blueprint alignment. This can be helpful for blueprints that are based on a central staircase, for example. +The modeline has some additional components that we haven't talked about yet. You can give a blueprint a label by adding a `label()` marker and a cursor offset by adding a `start()` marker. -To specify a cursor starting position, use the following modified format for the header line of your blueprint: +Labels are displayed in the `quickfort list` output and are used for addressing specific blueprints when there are multiple blueprints in a single file or spreadsheet sheet (see [Packaging a set of blueprints](#packaging-a-set-of-blueprints) below). If a blueprint has no label, the label becomes the ordinal of the blueprint's position in the file or sheet. For example, the label of the first blueprint will be "1" if it is not otherwise set, the label of the second blueprint will be "2" if it is not otherwise set, etc. Labels that are explicitly defined must start with a letter to ensure the auto-generated labels don't conflict with user-defined labels. - #mode start(X;Y;STARTCOMMENT) comment +Start positions specify a cursor offset for a particular blueprint, simplifying the task of blueprint alignment. This can be helpful for blueprints that are based on a central staircase, for example. -where X and Y specify the starting cursor position (1;1 is the top left cell) and STARTCOMMENT (optional) is information about where to position the cursor. This information appears in the `quickfort list` output. +The full modeline syntax is: + + #mode label(mylabel) start(X;Y;STARTCOMMENT) comment + +where X and Y specify the starting cursor position (1;1 is the top left cell) and STARTCOMMENT (optional) is information about where to position the cursor. This information also appears in the `quickfort list` output. + +Note that all elements are optional except for the initial `#mode`, and, of course, if `label` is specified, there must be a label string, and if `start()` is specified, values for X and Y must be present. A couple examples: #dig start(3; 3; Center tile of a 5-tile square) Regular blueprint comment - #build start(10;15) + #build label(noblebedroom) start(10;15) + #query label(configstockpiles) No explicit start() means cursor is at upper left corner Multilevel blueprints @@ -408,18 +416,54 @@ Which would result in a carved track simliar to a constructed track of the form: Packaging a set of blueprints ----------------------------- -A complete QF specification for a section of your fortress may contain 4 or more separate blueprints, one for each "phase" of construction (dig, build, place stockpiles, query building adjustments). +A complete specification for a section of your fortress may contain 4 or more separate blueprints, one for each "phase" of construction (dig, build, place stockpiles, query building adjustments). + +To manage all the separate blueprints, it is often convenient to keep related blueprints in a single file. For .xlsx spreadsheets, you can keep each blueprint in a separate sheet. Online spreadsheet applications like [Google Sheets](https://sheets.new) make it easy to work with multiple related blueprints, and, as a bonus, they retain any formatting you've set, like column sizes and coloring. + +For both .csv files and .xlsx spreadsheets you can also add as many blueprints as you want in a single file or sheet. Just add a modeline in the first column to indicate the start of a new blueprint. Instead of multiple .csv files, you can concatenate them into one single file. + +For example, you can store multiple blueprints together like this: + + #dig label(digbed) + d d d d # + d d d d # + d d d d # + d d d d # + # # # # # + #build label(buildbed) + b f h # + # + # + n # + # # # # # + #place label(placebed) + # + f(2x2) # + # + # + # # # # # + #query label(boozebed) + # + booze # + # + # + # # # # # + #query label(roombed) + r{+ 3}& # + # + # + # + # # # # # -To manage all the separate blueprints, it is often convenient to keep related blueprints in a single .xlsx file, with each blueprint in a separate sheet within the file. Online spreadsheet applications like [Google Sheets](https://sheets.new) make it easy to work with multiple related blueprints, and, as a bonus, they retain any formatting you've set, like column sizes and coloring. -Of course, you could still choose to keep your blueprints in single-sheet .csv files and just give related blueprints similar names. The blueprint modes suggest a convenient naming scheme for .csv-based blueprint "stacks": +Of course, you could still choose to keep your blueprints in single-sheet .csv files and just give related blueprints similar names: bedroom.1.dig.csv bedroom.2.build.csv bedroom.3.place.csv bedroom.4.query.csv -But the naming is completely up to you, of course. +But the naming and organization is completely up to you. Tips and Tricks From 7fd7bd2fab5709713463875096fc9aa424cb90c7 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Thu, 13 Aug 2020 11:52:34 -0700 Subject: [PATCH 314/547] document meta blueprints and reorg sections --- data/blueprints/README.md | 185 ++++++++++++++++++++++++++++---------- 1 file changed, 140 insertions(+), 45 deletions(-) diff --git a/data/blueprints/README.md b/data/blueprints/README.md index f54bbde97..05f4c6926 100644 --- a/data/blueprints/README.md +++ b/data/blueprints/README.md @@ -25,10 +25,11 @@ Table of Contents * [Editing Blueprints](#editing-blueprints) * [Area expansion syntax](#area-expansion-syntax) * [Automatic area expansion](#automatic-area-expansion) - * [Blueprint labels and cursor offsets](#blueprint-labels-and-cursor-offsets) - * [Multilevel blueprints](#multilevel-blueprints) * [Minecart tracks](#minecart-tracks) -* [Packaging a set of blueprints](#packaging-a-set-of-blueprints) + * [Multilevel blueprints](#multilevel-blueprints) + * [Blueprint labels and cursor offsets](#blueprint-labels-and-cursor-offsets) + * [Packaging a set of blueprints](#packaging-a-set-of-blueprints) + * [Meta blueprints](#meta-blueprints) * [Troubleshooting](#troubleshooting) * [Tips and tricks](#tips-and-tricks) * [Links](#links) @@ -40,14 +41,15 @@ Features * General * Manages complete blueprints to handle the four main phases of DF construction * Supports .csv and multi-worksheet .xlsx blueprint files - * Supports multiple blueprints per .csv file/spreadsheet sheet * Near-instant application, even for very large and complex blueprints + * Supports multiple blueprints per .csv file/spreadsheet sheet + * "meta" blueprints that automate the application of sequences of blueprints * Blueprints can span multiple z-levels * Undo functionality for dig, build, and place blueprints * Automatic cropping of blueprints so you don't get errors if the blueprint extends off the map * Can generate manager orders for everything required to apply build blueprints * Library of ready-to-use blueprints included - * Verbose output mode for debugging blueprints + * Verbose output mode for debugging * Dig mode * Supports all types of designations, including dumping/forbidding items and setting traffic areas * Supports applying dig blueprints in marker mode @@ -87,6 +89,8 @@ The keyword "dig" tells Quickfort we are going to be using the Designations menu place Place stockpiles menu (p) query Set building tasks/prefs menu (q) +There are also "meta" blueprints, but we'll talk about those [later](#meta-blueprints). + Optionally following this keyword and a space, you may enter a comment. This comment will appear in the output of `quickfort list` when run from the `DFHack#` prompt. You can use this space for explanations, attribution, etc. Below this line begin entering the keys you want sent in each cell. For example, we could dig out a 4x4 room like so (spaces are used as column separators here for clarity, but a real .csv file would have commas): @@ -251,46 +255,6 @@ This style can be convenient for laying out multiple buildings of the same type. Quickfort will intelligently break large areas of the same designation into appropriately-sized chunks. -Blueprint labels and cursor offsets ------------------------------------ - -The modeline has some additional components that we haven't talked about yet. You can give a blueprint a label by adding a `label()` marker and a cursor offset by adding a `start()` marker. - -Labels are displayed in the `quickfort list` output and are used for addressing specific blueprints when there are multiple blueprints in a single file or spreadsheet sheet (see [Packaging a set of blueprints](#packaging-a-set-of-blueprints) below). If a blueprint has no label, the label becomes the ordinal of the blueprint's position in the file or sheet. For example, the label of the first blueprint will be "1" if it is not otherwise set, the label of the second blueprint will be "2" if it is not otherwise set, etc. Labels that are explicitly defined must start with a letter to ensure the auto-generated labels don't conflict with user-defined labels. - -Start positions specify a cursor offset for a particular blueprint, simplifying the task of blueprint alignment. This can be helpful for blueprints that are based on a central staircase, for example. - -The full modeline syntax is: - - #mode label(mylabel) start(X;Y;STARTCOMMENT) comment - -where X and Y specify the starting cursor position (1;1 is the top left cell) and STARTCOMMENT (optional) is information about where to position the cursor. This information also appears in the `quickfort list` output. - -Note that all elements are optional except for the initial `#mode`, and, of course, if `label` is specified, there must be a label string, and if `start()` is specified, values for X and Y must be present. - -A couple examples: - - #dig start(3; 3; Center tile of a 5-tile square) Regular blueprint comment - #build label(noblebedroom) start(10;15) - #query label(configstockpiles) No explicit start() means cursor is at upper left corner - - -Multilevel blueprints ---------------------- - -Multilevel blueprints are accommodated by separating Z-levels of the blueprint with #> (go down one z-level) or #< (go up one z-level) at the end of each floor. - - #dig Stairs leading down to a small room below - j ` ` # - ` ` ` # - ` ` ` # - #> # # # - u d d # - d d d # - d d d # - # # # # - - Minecart tracks --------------- @@ -413,6 +377,48 @@ Which would result in a carved track simliar to a constructed track of the form: # # # # +Multilevel blueprints +--------------------- + +Multilevel blueprints are accommodated by separating Z-levels of the blueprint with `#>` (go down one z-level) or `#<` (go up one z-level) at the end of each floor. + + #dig Stairs leading down to a small room below + j ` ` # + ` ` ` # + ` ` ` # + #> # # # + u d d # + d d d # + d d d # + # # # # + +The marker must appear in the first column of the row to be recognized, just like a modeline. + + +Blueprint labels and cursor offsets +----------------------------------- + +The modeline has some additional components that we haven't talked about yet. You can give a blueprint a label by adding a `label()` marker and a cursor offset by adding a `start()` marker. + +Labels are displayed in the `quickfort list` output and are used for addressing specific blueprints when there are multiple blueprints in a single file or spreadsheet sheet (see [Packaging a set of blueprints](#packaging-a-set-of-blueprints) below). If a blueprint has no label, the label becomes the ordinal of the blueprint's position in the file or sheet. For example, the label of the first blueprint will be "1" if it is not otherwise set, the label of the second blueprint will be "2" if it is not otherwise set, etc. Labels that are explicitly defined must start with a letter to ensure the auto-generated labels don't conflict with user-defined labels. + +Start positions specify a cursor offset for a particular blueprint, simplifying the task of blueprint alignment. This can be helpful for blueprints that are based on a central staircase, for example. + +The full modeline syntax is: + + #mode label(mylabel) start(X;Y;STARTCOMMENT) comment + +where X and Y specify the starting cursor position (1;1 is the top left cell) and STARTCOMMENT (optional) is information about where to position the cursor. This information also appears in the `quickfort list` output. + +Note that all elements are optional except for the initial `#mode`, and, of course, if `label` is specified, there must be a label string, and if `start()` is specified, values for X and Y must be present. + +A couple examples: + + #dig start(3; 3; Center tile of a 5-tile square) Regular blueprint comment + #build label(noblebedroom) start(10;15) + #query label(configstockpiles) No explicit start() means cursor is at upper left corner + + Packaging a set of blueprints ----------------------------- @@ -466,6 +472,95 @@ Of course, you could still choose to keep your blueprints in single-sheet .csv f But the naming and organization is completely up to you. +Meta blueprints +--------------- + +Meta blueprints are blueprints that script a series of other blueprints. Many blueprint packages follow this pattern: + +- Apply dig blueprint to designate dig areas +- Wait for miners to dig +- **Apply build buildprint** to designate buildings +- **Apply place buildprint** to designate stockpiles +- **Apply query blueprint** to configure stockpiles +- Wait for buildings to get built +- Apply a different query blueprint to configure rooms + +Those three "apply"s in the middle might as well get done in one command instead of three. A meta blueprint can encode that sequence. A meta blueprint refers to other blueprints by their label (see the [labels and offsets section](#blueprint-labels-and-cursor-offsets) above) in the same format used by the `DFHack#` quickfort command: "/