diff --git a/docs/changelog.txt b/docs/changelog.txt index 2635e1497..380636198 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -54,6 +54,10 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## Misc Improvements - `devel/export-dt-ini`: added viewscreen offsets for DT 40.1.2 +- `embark-assistant`: + - added match indicator display on the right ("World") map + - changed 'c'ancel to abort find if it's under way and clear results if not, allowing use of partial surveys. + - added Coal as a search criterion, as well as a coal indication as current embark selection info. - `labormanager`: now takes nature value into account when assigning jobs ## Internals diff --git a/plugins/embark-assistant/defs.h b/plugins/embark-assistant/defs.h index 43f2ddc0a..f7a9ed680 100644 --- a/plugins/embark-assistant/defs.h +++ b/plugins/embark-assistant/defs.h @@ -28,6 +28,7 @@ namespace embark_assist { bool clay = false; bool sand = false; bool flux = false; + bool coal = false; int8_t soil_depth; int8_t offset; int16_t elevation; @@ -51,6 +52,7 @@ namespace embark_assist { uint16_t clay_count = 0; uint16_t sand_count = 0; uint16_t flux_count = 0; + uint16_t coal_count = 0; uint8_t min_region_soil = 10; uint8_t max_region_soil = 0; bool waterfall = false; @@ -90,6 +92,7 @@ namespace embark_assist { bool clay_absent = true; bool sand_absent = true; bool flux_absent = true; + bool coal_absent = true; std::vector possible_metals; std::vector possible_economics; std::vector possible_minerals; @@ -113,6 +116,7 @@ namespace embark_assist { bool clay; bool sand; bool flux; + bool coal; std::vector metals; std::vector economics; std::vector minerals; @@ -253,6 +257,7 @@ namespace embark_assist { present_absent_ranges clay; present_absent_ranges sand; present_absent_ranges flux; + present_absent_ranges coal; soil_ranges soil_min; all_present_ranges soil_min_everywhere; soil_ranges soil_max; diff --git a/plugins/embark-assistant/embark-assistant.cpp b/plugins/embark-assistant/embark-assistant.cpp index 728d96f58..cfd44a30b 100644 --- a/plugins/embark-assistant/embark-assistant.cpp +++ b/plugins/embark-assistant/embark-assistant.cpp @@ -143,7 +143,7 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector finder_list.push_back({ "Flux", static_cast(i) }); break; + case fields::coal: + state->finder_list.push_back({ "Coal", static_cast(i) }); + break; + case fields::soil_min: state->finder_list.push_back({ "Min Soil", static_cast(i) }); break; @@ -1228,6 +1234,11 @@ namespace embark_assist { static_cast(state->ui[static_cast(i)]->current_value); break; + case fields::coal: + finder.coal = + static_cast(state->ui[static_cast(i)]->current_value); + break; + case fields::soil_min: finder.soil_min = static_cast(state->ui[static_cast(i)]->current_value); diff --git a/plugins/embark-assistant/help_ui.cpp b/plugins/embark-assistant/help_ui.cpp index 7c0763a71..e92ae67c0 100644 --- a/plugins/embark-assistant/help_ui.cpp +++ b/plugins/embark-assistant/help_ui.cpp @@ -127,8 +127,8 @@ namespace embark_assist{ help_text.push_back("Main screen control keys used by the Embark Assistant:"); help_text.push_back("i: Info/Help. Brings up this display."); help_text.push_back("f: Brings up the Find Embark screen. See the Find page for more information."); - help_text.push_back("c: Clears the results of a Find operation, and also cancels an operation if"); - help_text.push_back(" one is under way."); + help_text.push_back("c: Clears the results of a Find operation, or cancels an operation if one is"); + help_text.push_back(" under way (at which time a second 'c' clears it)."); help_text.push_back("q: Quits the Embark Assistant and brings you back to the vanilla DF interface."); help_text.push_back(" It can be noted that the Embark Assistant automatically cancels itself"); help_text.push_back(" when DF leaves the embark screen either through Abort Game or by"); @@ -171,8 +171,8 @@ namespace embark_assist{ help_text.push_back("A list of all economic minerals present in the embark. Both clays and flux"); help_text.push_back("stones are economic, so they show up here as well."); help_text.push_back("In addition to the above, the Find functionality can also produce blinking"); - help_text.push_back("overlays over the region map and the middle world map to indicate where"); - help_text.push_back("matching embarks are found. The region display marks the top left corner of"); + help_text.push_back("overlays over the Local, Region, and World maps to indicate where"); + help_text.push_back("matching embarks are found. The Local display marks the top left corner of"); help_text.push_back("a matching embark rectangle as a matching tile."); break; @@ -257,14 +257,13 @@ namespace embark_assist{ help_text.push_back("- The geo information is gathered by code which is essentially a"); help_text.push_back(" copy of parts of prospector's code adapted for this plugin."); help_text.push_back("- Clay determination is made by finding the reaction MAKE_CLAY_BRICKS."); - help_text.push_back(" Flux determination is made by finding the reaction PIG_IRON_MAKING."); - help_text.push_back("- Right world map overlay not implemented as author has failed to"); - help_text.push_back(" emulate the sizing logic exactly."); + help_text.push_back("- Flux determination is made by finding the reaction PIG_IRON_MAKING."); + help_text.push_back("- Coal is detected by finding COAL producing reactions on minerals."); help_text.push_back("- There's currently a DF bug (#0010267) that causes adamantine spires"); help_text.push_back(" reaching caverns that have been removed at world gen to fail to be"); help_text.push_back(" generated at all. It's likely this bug also affects magma pools."); help_text.push_back(" This plugin does not address this but scripts can correct it."); - help_text.push_back("Version 0.5 2018-07-13"); + help_text.push_back("Version 0.8 2018-12-04"); break; } diff --git a/plugins/embark-assistant/matcher.cpp b/plugins/embark-assistant/matcher.cpp index 28c72b76f..7b3d385cb 100644 --- a/plugins/embark-assistant/matcher.cpp +++ b/plugins/embark-assistant/matcher.cpp @@ -46,6 +46,7 @@ namespace embark_assist { bool clay_found = false; bool sand_found = false; bool flux_found = false; + bool coal_found = false; uint8_t max_soil = 0; bool uneven = false; int16_t min_temperature = survey_results->at(x).at(y).min_temperature[mlt->at(start_x).at(start_y).biome_offset]; @@ -174,6 +175,12 @@ namespace embark_assist { flux_found = true; } + // Coal + if (mlt->at(i).at(k).coal) { + if (finder->coal == embark_assist::defs::present_absent_ranges::Absent) return false; + coal_found = true; + } + // Min Soil if (finder->soil_min != embark_assist::defs::soil_ranges::NA && mlt->at(i).at(k).soil_depth < static_cast(finder->soil_min) && @@ -335,6 +342,9 @@ namespace embark_assist { // Flux if (finder->flux == embark_assist::defs::present_absent_ranges::Present && !flux_found) return false; + // Coal + if (finder->coal == embark_assist::defs::present_absent_ranges::Present && !coal_found) return false; + // Min Soil if (finder->soil_min != embark_assist::defs::soil_ranges::NA && finder->soil_min_everywhere == embark_assist::defs::all_present_ranges::Present && @@ -571,6 +581,7 @@ namespace embark_assist { case embark_assist::defs::present_absent_ranges::Present: if (tile->clay_count == 0) return false; break; + case embark_assist::defs::present_absent_ranges::Absent: if (tile->clay_count > 256 - embark_size) return false; break; @@ -584,6 +595,7 @@ namespace embark_assist { case embark_assist::defs::present_absent_ranges::Present: if (tile->sand_count == 0) return false; break; + case embark_assist::defs::present_absent_ranges::Absent: if (tile->sand_count > 256 - embark_size) return false; break; @@ -597,11 +609,26 @@ namespace embark_assist { case embark_assist::defs::present_absent_ranges::Present: if (tile->flux_count == 0) return false; break; + case embark_assist::defs::present_absent_ranges::Absent: if (tile->flux_count > 256 - embark_size) return false; break; } + // Coal + switch (finder->coal) { + case embark_assist::defs::present_absent_ranges::NA: + break; // No restriction + + case embark_assist::defs::present_absent_ranges::Present: + if (tile->coal_count == 0) return false; + break; + + case embark_assist::defs::present_absent_ranges::Absent: + if (tile->coal_count > 256 - embark_size) return false; + break; + } + // Soil Min switch (finder->soil_min) { case embark_assist::defs::soil_ranges::NA: @@ -1027,6 +1054,7 @@ namespace embark_assist { case embark_assist::defs::present_absent_ranges::Present: if (tile->clay_count == 0) return false; break; + case embark_assist::defs::present_absent_ranges::Absent: if (tile->clay_count == 256) return false; break; @@ -1040,6 +1068,7 @@ namespace embark_assist { case embark_assist::defs::present_absent_ranges::Present: if (tile->sand_count == 0) return false; break; + case embark_assist::defs::present_absent_ranges::Absent: if (tile->sand_count == 256) return false; break; @@ -1053,11 +1082,26 @@ namespace embark_assist { case embark_assist::defs::present_absent_ranges::Present: if (tile->flux_count == 0) return false; break; + case embark_assist::defs::present_absent_ranges::Absent: if (tile->flux_count == 256) return false; break; } + // Coal + switch (finder->coal) { + case embark_assist::defs::present_absent_ranges::NA: + break; // No restriction + + case embark_assist::defs::present_absent_ranges::Present: + if (tile->coal_count == 0) return false; + break; + + case embark_assist::defs::present_absent_ranges::Absent: + if (tile->coal_count == 256) return false; + break; + } + // Soil Min switch (finder->soil_min) { case embark_assist::defs::soil_ranges::NA: @@ -1518,11 +1562,11 @@ uint16_t embark_assist::matcher::find(embark_assist::defs::match_iterators *iter preliminary_matches = preliminary_world_match(survey_results, &iterator->finder, match_results); if (preliminary_matches == 0) { - out.printerr("matcher::find: Preliminarily matching world tiles: %i\n", preliminary_matches); + out.printerr("matcher::find: Preliminarily matching World Tiles: %i\n", preliminary_matches); return 0; } else { - out.print("matcher::find: Preliminarily matching world tiles: %i\n", preliminary_matches); + out.print("matcher::find: Preliminarily matching World Tiles: %i\n", preliminary_matches); } while (screen->location.region_pos.x != 0 || screen->location.region_pos.y != 0) { diff --git a/plugins/embark-assistant/overlay.cpp b/plugins/embark-assistant/overlay.cpp index 19615cac5..c25859ccb 100644 --- a/plugins/embark-assistant/overlay.cpp +++ b/plugins/embark-assistant/overlay.cpp @@ -48,7 +48,7 @@ namespace embark_assist { std::vector embark_info; - Screen::Pen region_match_grid[16][16]; + Screen::Pen local_match_grid[16][16]; pen_column *world_match_grid = nullptr; uint16_t match_count = 0; @@ -60,26 +60,15 @@ namespace embark_assist { //==================================================================== -/* // Attempt to replicate the DF logic for sizing the right world map. This - // code seems to compute the values correctly, but the author hasn't been - // able to apply them at the same time as DF does to 100%. - // DF seems to round down on 0.5 values. - df::coord2d world_dimension_size(uint16_t available_screen, uint16_t map_size) { - uint16_t result; - - for (uint16_t factor = 1; factor < 17; factor++) { - result = map_size / factor; - if ((map_size - result * factor) * 2 != factor) { - result = (map_size + factor / 2) / factor; - } + // Logic for sizing the World map to the right. + df::coord2d world_dimension_size(uint16_t map_size, uint16_t region_size) { + uint16_t factor = (map_size - 1 + region_size - 1) / region_size; + uint16_t result = (map_size + ((factor - 1) / 2)) / factor; + if (result > region_size) { result = region_size; } - if (result <= available_screen) { - return {result, factor}; - } - } - return{16, 16}; // Should never get here. + return{ result, factor}; } -*/ + //==================================================================== class ViewscreenOverlay : public df::viewscreen_choose_start_sitest @@ -114,9 +103,13 @@ namespace embark_assist { state->embark_update(); } else if (input->count(df::interface_key::CUSTOM_C)) { - state->match_active = false; - state->matching = false; - state->clear_match_callback(); + if (state->matching) { + state->matching = false; + } + else { + state->match_active = false; + state->clear_match_callback(); + } } else if (input->count(df::interface_key::CUSTOM_F)) { if (!state->match_active && !state->matching) { @@ -155,6 +148,7 @@ namespace embark_assist { Screen::Pen pen_lr(' ', COLOR_LIGHTRED); Screen::Pen pen_w(' ', COLOR_WHITE); + Screen::Pen pen_g(' ', COLOR_GREY); Screen::paintString(pen_lr, width - 28, 20, DFHack::Screen::getKeyDisplay(df::interface_key::CUSTOM_I).c_str(), false); Screen::paintString(pen_w, width - 27, 20, ": Embark Assistant Info", false); @@ -166,6 +160,7 @@ namespace embark_assist { Screen::paintString(pen_w, width - 27, 23, ": Quit Embark Assistant", false); Screen::paintString(pen_w, width - 28, 25, "Matching World Tiles:", false); Screen::paintString(empty_pen, width - 6, 25, to_string(state->match_count), false); + Screen::paintString(pen_g, width - 28, 26, "(Those on the Region Map)", false); if (height > 25) { // Mask the vanilla DF find help as it's overridden. Screen::paintString(pen_w, 50, height - 2, " ", false); @@ -221,29 +216,22 @@ namespace embark_assist { for (uint8_t i = 0; i < 16; i++) { for (uint8_t k = 0; k < 16; k++) { - if (state->region_match_grid[i][k].ch) { - Screen::paintTile(state->region_match_grid[i][k], i + 1, k + 2); + if (state->local_match_grid[i][k].ch) { + Screen::paintTile(state->local_match_grid[i][k], i + 1, k + 2); } } } -/* // Stuff for trying to replicate the DF right world map sizing logic. Close, but not there. - Screen::Pen pen(' ', COLOR_YELLOW); - // Boundaries of the top level world map - Screen::paintString(pen, width / 2 - 5, 2, "X", false); // Marks UL corner of right world map. Constant -// Screen::paintString(pen, width - 30, 2, "X", false); // Marks UR corner of right world map area. -// Screen::paintString(pen, width / 2 - 5, height - 8, "X", false); // BL corner of right world map area. -// Screen::paintString(pen, width - 30, height - 8, "X", false); // BR corner of right world map area. - - uint16_t l_width = width - 30 - (width / 2 - 5) + 1; // Horizontal space available for right world map. - uint16_t l_height = height - 8 - 2 + 1; // Vertical space available for right world map. - df::coord2d size_factor_x = world_dimension_size(l_width, world->worldgen.worldgen_parms.dim_x); - df::coord2d size_factor_y = world_dimension_size(l_height, world->worldgen.worldgen_parms.dim_y); - - Screen::paintString(pen, width / 2 - 5 + size_factor_x.x - 1, 2, "X", false); - Screen::paintString(pen, width / 2 - 5, 2 + size_factor_y.x - 1, "X", false); - Screen::paintString(pen, width / 2 - 5 + size_factor_x.x - 1, 2 + size_factor_y.x - 1, "X", false); - */ + df::coord2d size_factor_x = world_dimension_size(world->worldgen.worldgen_parms.dim_x, width / 2 - 24); + df::coord2d size_factor_y = world_dimension_size(world->worldgen.worldgen_parms.dim_y, height - 9); + + for (uint16_t i = 0; i < world->worldgen.worldgen_parms.dim_x; i++) { + for (uint16_t k = 0; k < world->worldgen.worldgen_parms.dim_y; k++) { + if (state->world_match_grid[i][k].ch) { + Screen::paintTile(state->world_match_grid[i][k], width / 2 - 5 + min(size_factor_x.x - 1, i / size_factor_x.y), 2 + min(size_factor_y.x - 1, k / size_factor_y.y)); + } + } + } } if (state->matching) { @@ -351,6 +339,10 @@ void embark_assist::overlay::set_embark(embark_assist::defs::site_infos *site_in state->embark_info.push_back({ Screen::Pen(' ', COLOR_RED), "Clay" }); } + if (site_info->coal) { + state->embark_info.push_back({ Screen::Pen(' ', COLOR_GREY), "Coal" }); + } + state->embark_info.push_back({ Screen::Pen(' ', COLOR_BROWN), "Soil " + std::to_string(site_info->min_soil) + " - " + std::to_string(site_info->max_soil) }); if (site_info->flat) { @@ -390,11 +382,11 @@ void embark_assist::overlay::set_mid_level_tile_match(embark_assist::defs::mlt_m for (uint8_t i = 0; i < 16; i++) { for (uint8_t k = 0; k < 16; k++) { if (mlt_matches[i][k]) { - state->region_match_grid[i][k] = green_x_pen; + state->local_match_grid[i][k] = green_x_pen; } else { - state->region_match_grid[i][k] = empty_pen; + state->local_match_grid[i][k] = empty_pen; } } } @@ -411,7 +403,7 @@ void embark_assist::overlay::clear_match_results() { for (uint8_t i = 0; i < 16; i++) { for (uint8_t k = 0; k < 16; k++) { - state->region_match_grid[i][k] = empty_pen; + state->local_match_grid[i][k] = empty_pen; } } } diff --git a/plugins/embark-assistant/survey.cpp b/plugins/embark-assistant/survey.cpp index 4071d78b3..f19f3cd4a 100644 --- a/plugins/embark-assistant/survey.cpp +++ b/plugins/embark-assistant/survey.cpp @@ -10,6 +10,7 @@ #include "modules/Materials.h" #include "DataDefs.h" +#include "df/builtin_mats.h" #include "df/coord2d.h" #include "df/creature_interaction_effect.h" #include "df/creature_interaction_effect_display_symbolst.h" @@ -34,6 +35,9 @@ #include "df/interaction_target_materialst.h" #include "df/material_common.h" #include "df/reaction.h" +#include "df/reaction_product.h" +#include "df/reaction_product_itemst.h" +#include "df/reaction_product_type.h" #include "df/region_map_entry.h" #include "df/syndrome.h" #include "df/viewscreen.h" @@ -66,6 +70,7 @@ namespace embark_assist { struct states { uint16_t clay_reaction = -1; uint16_t flux_reaction = -1; + std::vector coals; uint16_t x; uint16_t y; uint8_t local_min_x; @@ -104,6 +109,19 @@ namespace embark_assist { out.printerr("The reaction 'PIG_IRON_MAKING' was not found, so flux can't be identified.\n"); } + for (uint16_t i = 0; i < world->raws.inorganics.size(); i++) { + for (uint16_t k = 0; k < world->raws.inorganics[i]->economic_uses.size(); k++) { + for (uint16_t l = 0; l < world->raws.reactions.reactions[world->raws.inorganics[i]->economic_uses[k]]->products.size(); l++) { + df::reaction_product_itemst *product = static_cast(world->raws.reactions.reactions[world->raws.inorganics[i]->economic_uses[k]]->products[l]); + + if (product->mat_type == df::builtin_mats::COAL) { + state->coals.push_back(i); + break; + } + } + } + } + for (uint16_t i = 0; i < world_data->geo_biomes.size(); i++) { geo_summary->at(i).possible_metals.resize(state->max_inorganic); geo_summary->at(i).possible_economics.resize(state->max_inorganic); @@ -154,6 +172,13 @@ namespace embark_assist { } } + for (uint16_t l = 0; l < state->coals.size(); l++) { + if (layer->mat_index == state->coals[l]) { + geo_summary->at(i).coal_absent = false; + break; + } + } + size = (uint16_t)layer->vein_mat.size(); for (uint16_t l = 0; l < size; l++) { @@ -176,6 +201,14 @@ namespace embark_assist { geo_summary->at(i).flux_absent = false; } } + + for (uint16_t m = 0; m < state->coals.size(); m++) { + if (vein== state->coals[m]) { + geo_summary->at(i).coal_absent = false; + break; + } + } + } } @@ -531,6 +564,7 @@ void embark_assist::survey::high_level_world_survey(embark_assist::defs::geo_dat results.clay_count = 0; results.sand_count = 0; results.flux_count = 0; + results.coal_count = 0; results.min_region_soil = 10; results.max_region_soil = 0; results.waterfall = false; @@ -576,6 +610,7 @@ void embark_assist::survey::high_level_world_survey(embark_assist::defs::geo_dat if (!geo_summary->at(geo_index).clay_absent) results.clay_count++; if (!geo_summary->at(geo_index).sand_absent) results.sand_count++; if (!geo_summary->at(geo_index).flux_absent) results.flux_count++; + if (!geo_summary->at(geo_index).coal_absent) results.coal_count++; if (geo_summary->at(geo_index).soil_size < results.min_region_soil) results.min_region_soil = geo_summary->at(geo_index).soil_size; @@ -614,6 +649,8 @@ void embark_assist::survey::high_level_world_survey(embark_assist::defs::geo_dat if (results.clay_count == offset_count) results.clay_count = 256; if (results.sand_count == offset_count) results.sand_count = 256; if (results.flux_count == offset_count) results.flux_count = 256; + if (results.coal_count == offset_count) results.coal_count = 256; + for (uint8_t l = 0; l < 3; l++) { if (results.savagery_count[l] == offset_count) results.savagery_count[l] = 256; if (results.evilness_count[l] == offset_count) results.evilness_count[l] = 256; @@ -776,6 +813,8 @@ void embark_assist::survey::survey_mid_level_tile(embark_assist::defs::geo_data mlt->at(i).at(k).clay = false; mlt->at(i).at(k).sand = false; mlt->at(i).at(k).flux = false; + mlt->at(i).at(k).coal = false; + if (max_soil_depth == 0) { mlt->at(i).at(k).soil_depth = 0; } @@ -869,6 +908,13 @@ void embark_assist::survey::survey_mid_level_tile(embark_assist::defs::geo_data mlt->at(i).at(k).flux = true; } } + + for (uint16_t m = 0; m < state->coals.size(); m++) { + if (layer->mat_index == state->coals [m]) { + mlt->at(i).at(k).coal = true; + break; + } + } } end_check_m = static_cast(layer->vein_mat.size()); @@ -895,6 +941,13 @@ void embark_assist::survey::survey_mid_level_tile(embark_assist::defs::geo_data mlt->at(i).at(k).flux = true; } } + + for (uint16_t n = 0; n < state->coals.size(); n++) { + if (layer->vein_mat [m] == state->coals[n]) { + mlt->at(i).at(k).coal = true; + break; + } + } } } @@ -911,6 +964,7 @@ void embark_assist::survey::survey_mid_level_tile(embark_assist::defs::geo_data survey_results->at(x).at(y).clay_count = 0; survey_results->at(x).at(y).sand_count = 0; survey_results->at(x).at(y).flux_count = 0; + survey_results->at(x).at(y).coal_count = 0; survey_results->at(x).at(y).min_region_soil = 10; survey_results->at(x).at(y).max_region_soil = 0; survey_results->at(x).at(y).savagery_count[0] = 0; @@ -929,6 +983,7 @@ void embark_assist::survey::survey_mid_level_tile(embark_assist::defs::geo_data if (mlt->at(i).at(k).clay) { survey_results->at(x).at(y).clay_count++; } if (mlt->at(i).at(k).sand) { survey_results->at(x).at(y).sand_count++; } if (mlt->at(i).at(k).flux) { survey_results->at(x).at(y).flux_count++; } + if (mlt->at(i).at(k).coal) { survey_results->at(x).at(y).coal_count++; } if (mlt->at(i).at(k).soil_depth < survey_results->at(x).at(y).min_region_soil) { survey_results->at(x).at(y).min_region_soil = mlt->at(i).at(k).soil_depth; @@ -1170,6 +1225,7 @@ void embark_assist::survey::survey_embark(embark_assist::defs::mid_level_tiles * site_info->clay = false; site_info->sand = false; site_info->flux = false; + site_info->coal = false; site_info->metals.clear(); site_info->economics.clear(); site_info->metals.clear(); @@ -1222,6 +1278,10 @@ void embark_assist::survey::survey_embark(embark_assist::defs::mid_level_tiles * site_info->flux = true; } + if (mlt->at(i).at(k).coal) { + site_info->coal = true; + } + for (uint16_t l = 0; l < state->max_inorganic; l++) { metals[l] = metals[l] || mlt->at(i).at(k).metals[l]; economics[l] = economics[l] || mlt->at(i).at(k).economics[l];