From 6014a452353b61374408c6fc1bf1a085a3e7981b Mon Sep 17 00:00:00 2001 From: PatrikLundell Date: Fri, 13 Nov 2020 20:11:03 +0100 Subject: [PATCH] Fixed bug missing world tiles lacking incurson supplied resources --- plugins/embark-assistant/defs.h | 4 + plugins/embark-assistant/embark-assistant.cpp | 4 + plugins/embark-assistant/matcher.cpp | 164 ++++++++++++------ plugins/embark-assistant/survey.cpp | 6 +- 4 files changed, 127 insertions(+), 51 deletions(-) diff --git a/plugins/embark-assistant/defs.h b/plugins/embark-assistant/defs.h index d22b7436d..caecc2d49 100644 --- a/plugins/embark-assistant/defs.h +++ b/plugins/embark-assistant/defs.h @@ -71,6 +71,10 @@ namespace embark_assist { struct region_tile_datum { bool surveyed = false; + bool survey_completed = false; + bool neighboring_clay = false; // These elements are updated after the survey by checking if there are any border MLTs in neighboring tiles that would would provide the resource + bool neighboring_sand = false; // if they actually provided an incursion. This allows the code to add these potential tiles to the ones checked. + aquifer_sizes neighboring_aquifer = aquifer_sizes::NA; aquifer_sizes aquifer = aquifer_sizes::NA; uint16_t clay_count = 0; uint16_t sand_count = 0; diff --git a/plugins/embark-assistant/embark-assistant.cpp b/plugins/embark-assistant/embark-assistant.cpp index eb6722640..e6f18f639 100644 --- a/plugins/embark-assistant/embark-assistant.cpp +++ b/plugins/embark-assistant/embark-assistant.cpp @@ -311,6 +311,10 @@ command_result embark_assistant(color_ostream &out, std::vector & for (uint16_t k = 0; k < world->worldgen.worldgen_parms.dim_y; k++) { embark_assist::main::state->survey_results[i][k].surveyed = false; + embark_assist::main::state->survey_results[i][k].survey_completed = false; + embark_assist::main::state->survey_results[i][k].neighboring_clay = false; + embark_assist::main::state->survey_results[i][k].neighboring_sand = false; + embark_assist::main::state->survey_results[i][k].neighboring_aquifer = embark_assist::defs::aquifer_sizes::NA; embark_assist::main::state->survey_results[i][k].aquifer = embark_assist::defs::aquifer_sizes::NA; embark_assist::main::state->survey_results[i][k].clay_count = 0; embark_assist::main::state->survey_results[i][k].sand_count = 0; diff --git a/plugins/embark-assistant/matcher.cpp b/plugins/embark-assistant/matcher.cpp index 7575b1287..3c31574f7 100644 --- a/plugins/embark-assistant/matcher.cpp +++ b/plugins/embark-assistant/matcher.cpp @@ -1496,6 +1496,9 @@ namespace embark_assist { } // Aquifer + // Survey can only augment results with incursions, but single results can't be achieved without the native tile matching it, + // so extra checks are needed only for combinations. Also note that while two incursions won't be sufficient to actually get a match, + // the important thing here is not to miss matches due to aborting too early. switch (finder->aquifer) { case embark_assist::defs::aquifer_ranges::NA: break; @@ -1515,16 +1518,20 @@ namespace embark_assist { break; case embark_assist::defs::aquifer_ranges::None_Plus_Light: - if (!(static_cast(tile->aquifer) & static_cast(embark_assist::defs::aquifer_sizes::None)) || - !(static_cast(tile->aquifer) & static_cast(embark_assist::defs::aquifer_sizes::Light))) { + if ((!(static_cast(tile->aquifer) & static_cast(embark_assist::defs::aquifer_sizes::None)) && + (!(static_cast(tile->neighboring_aquifer) & static_cast(embark_assist::defs::aquifer_sizes::None)))) || + (!(static_cast(tile->aquifer) & static_cast(embark_assist::defs::aquifer_sizes::Light)) && + (!(static_cast(tile->neighboring_aquifer) & static_cast(embark_assist::defs::aquifer_sizes::Light))))) { if (trace) out.print("matcher::world_tile_match: Aquifer None_Plus_Light (%i, %i)\n", x, y); return false; } break; case embark_assist::defs::aquifer_ranges::None_Plus_At_Least_Light: - if (!(static_cast(tile->aquifer) & static_cast(embark_assist::defs::aquifer_sizes::None)) || - !(static_cast(tile->aquifer) & static_cast(embark_assist::defs::aquifer_sizes::Light_Heavy))) { + if ((!(static_cast(tile->aquifer) & static_cast(embark_assist::defs::aquifer_sizes::None)) && + (!(static_cast(tile->neighboring_aquifer) & static_cast(embark_assist::defs::aquifer_sizes::None)))) || + (!(static_cast(tile->aquifer) & static_cast(embark_assist::defs::aquifer_sizes::Light_Heavy)) && + (!(static_cast(tile->neighboring_aquifer) & static_cast(embark_assist::defs::aquifer_sizes::Light_Heavy))))) { if (trace) out.print("matcher::world_tile_match: Aquifer None_Plus_At_Least_Light (%i, %i)\n", x, y); return false; } @@ -1538,31 +1545,38 @@ namespace embark_assist { break; case embark_assist::defs::aquifer_ranges::At_Least_Light: - if (tile->aquifer == embark_assist::defs::aquifer_sizes::None) { + if (tile->aquifer == embark_assist::defs::aquifer_sizes::None && + ((static_cast(tile->neighboring_aquifer) & static_cast(embark_assist::defs::aquifer_sizes::None)))) { if (trace) out.print("matcher::world_tile_match: Aquifer At_Least_Light (%i, %i)\n", x, y); return false; } break; case embark_assist::defs::aquifer_ranges::None_Plus_Heavy: - if (!(static_cast(tile->aquifer) & static_cast(embark_assist::defs::aquifer_sizes::None)) || - !(static_cast(tile->aquifer) & static_cast(embark_assist::defs::aquifer_sizes::Heavy))) { + if ((!(static_cast(tile->aquifer) & static_cast(embark_assist::defs::aquifer_sizes::None)) && + (!(static_cast(tile->neighboring_aquifer) & static_cast(embark_assist::defs::aquifer_sizes::None)))) || + (!(static_cast(tile->aquifer) & static_cast(embark_assist::defs::aquifer_sizes::Heavy)) && + (!(static_cast(tile->neighboring_aquifer) & static_cast(embark_assist::defs::aquifer_sizes::Heavy))))) { if (trace) out.print("matcher::world_tile_match: Aquifer None_Plus_Heavy (%i, %i)\n", x, y); return false; } break; case embark_assist::defs::aquifer_ranges::At_Most_Light_Plus_Heavy: - if (!(static_cast(tile->aquifer) & static_cast(embark_assist::defs::aquifer_sizes::Heavy)) || - !(static_cast(tile->aquifer) & static_cast(embark_assist::defs::aquifer_sizes::None_Light))) { + if ((!(static_cast(tile->aquifer) & static_cast(embark_assist::defs::aquifer_sizes::Heavy)) && + (!(static_cast(tile->neighboring_aquifer) & static_cast(embark_assist::defs::aquifer_sizes::Heavy)))) || + (!(static_cast(tile->aquifer) & static_cast(embark_assist::defs::aquifer_sizes::None_Light)) && + (!(static_cast(tile->neighboring_aquifer) & static_cast(embark_assist::defs::aquifer_sizes::None_Light))))) { if (trace) out.print("matcher::world_tile_match: Aquifer At_Most_Light_Plus_Heavy (%i, %i)\n", x, y); return false; } break; case embark_assist::defs::aquifer_ranges::Light_Plus_Heavy: - if (!(static_cast(tile->aquifer) & static_cast(embark_assist::defs::aquifer_sizes::Light)) || - !(static_cast(tile->aquifer) & static_cast(embark_assist::defs::aquifer_sizes::Heavy))) { + if ((!(static_cast(tile->aquifer) & static_cast(embark_assist::defs::aquifer_sizes::Light)) && + (!(static_cast(tile->neighboring_aquifer) & static_cast(embark_assist::defs::aquifer_sizes::Light)))) || + (!(static_cast(tile->aquifer) & static_cast(embark_assist::defs::aquifer_sizes::Heavy)) && + (!(static_cast(tile->neighboring_aquifer) & static_cast(embark_assist::defs::aquifer_sizes::Heavy))))) { if (trace) out.print("matcher::world_tile_match: Aquifer Light_Plus_Heavy (%i, %i)\n", x, y); return false; } @@ -1648,7 +1662,8 @@ namespace embark_assist { break; // No restriction case embark_assist::defs::present_absent_ranges::Present: - if (tile->clay_count == 0) { + if (tile->clay_count == 0 && + !tile->neighboring_clay) { if (trace) out.print("matcher::world_tile_match: Clay Present (%i, %i)\n", x, y); return false; } @@ -1668,7 +1683,8 @@ namespace embark_assist { break; // No restriction case embark_assist::defs::present_absent_ranges::Present: - if (tile->sand_count == 0) { + if (tile->sand_count == 0 && + !tile->neighboring_sand) { if (trace) out.print("matcher::world_tile_match: Sand Present (%i, %i)\n", x, y); return false; } @@ -2380,46 +2396,12 @@ namespace embark_assist { } // Flat. No world tile checks. Need to look at the details - + // Clay - switch (finder->clay) { - case embark_assist::defs::present_absent_ranges::NA: - break; // No restriction - - case embark_assist::defs::present_absent_ranges::Present: - if (tile->clay_count == 0) { - if (trace) out.print("matcher::world_tile_match: NS Clay Present (%i, %i)\n", x, y); - return false; - } - break; - - case embark_assist::defs::present_absent_ranges::Absent: - if (tile->clay_count == 256) { - if (trace) out.print("matcher::world_tile_match: NS Clay Absent (%i, %i)\n", x, y); - return false; - } - break; - } + // With no preliminary survey we don't know if incursions might bring clay, so we can't really exclude any tiles. // Sand - switch (finder->sand) { - case embark_assist::defs::present_absent_ranges::NA: - break; // No restriction - - case embark_assist::defs::present_absent_ranges::Present: - if (tile->sand_count == 0) { - if (trace) out.print("matcher::world_tile_match: NS Sand Present (%i, %i)\n", x, y); - return false; - } - break; - - case embark_assist::defs::present_absent_ranges::Absent: - if (tile->sand_count == 256) { - if (trace) out.print("matcher::world_tile_match: NS Sand Absent (%i, %i)\n", x, y); - return false; - } - break; - } + // Same as with clay. // Flux switch (finder->flux) { @@ -3181,6 +3163,88 @@ uint16_t embark_assist::matcher::find(embark_assist::defs::match_iterators *iter if (!iterator->active) { embark_assist::matcher::move_cursor(iterator->x, iterator->y); + + if (!survey_results->at(0).at(0).survey_completed) { // Every world tile has gone through preliminary survey, so add possible incursion resources to each tile. + 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++) { + embark_assist::defs::region_tile_datum* current = &survey_results->at(i).at(k); + + if (i > 0 && k > 0) { + embark_assist::defs::region_tile_datum* target = &survey_results->at(i - 1).at(k - 1); + + current->neighboring_sand |= target->south_row [15].sand; + current->neighboring_clay |= target->south_row[15].clay; + current->neighboring_aquifer = static_cast(static_cast(current->neighboring_aquifer) | static_cast(target->south_row[15].aquifer)); + } + + if (k > 0) { + embark_assist::defs::region_tile_datum* target = &survey_results->at(i).at(k - 1); + + for (uint16_t l = 0; l < 16; l++) { + current->neighboring_sand |= target->south_row[l].sand; + current->neighboring_clay |= target->south_row[l].clay; + current->neighboring_aquifer = static_cast(static_cast(current->neighboring_aquifer) | static_cast(target->south_row[l].aquifer)); + } + } + + if (i < world->worldgen.worldgen_parms.dim_x - 1 && k > 0) { + embark_assist::defs::region_tile_datum* target = &survey_results->at(i + 1).at(k - 1); + + current->neighboring_sand |= target->south_row[0].sand; + current->neighboring_clay |= target->south_row[0].clay; + current->neighboring_aquifer = static_cast(static_cast(current->neighboring_aquifer) | static_cast(target->south_row[0].aquifer)); + } + + if (i > 0) { + embark_assist::defs::region_tile_datum* target = &survey_results->at(i - 1).at(k); + + for (uint16_t l = 0; l < 16; l++) { + current->neighboring_sand |= target->east_column[l].sand; + current->neighboring_clay |= target->east_column[l].clay; + current->neighboring_aquifer = static_cast(static_cast(current->neighboring_aquifer) | static_cast(target->east_column[l].aquifer)); + } + } + + if (i < world->worldgen.worldgen_parms.dim_x - 1) { + embark_assist::defs::region_tile_datum* target = &survey_results->at(i + 1).at(k); + + for (uint16_t l = 0; l < 16; l++) { + current->neighboring_sand |= target->west_column[l].sand; + current->neighboring_clay |= target->west_column[l].clay; + current->neighboring_aquifer = static_cast(static_cast(current->neighboring_aquifer) | static_cast(target->west_column[l].aquifer)); + } + } + + if (i > 0 && k < world->worldgen.worldgen_parms.dim_y - 1) { + embark_assist::defs::region_tile_datum* target = &survey_results->at(i - 1).at(k + 1); + + current->neighboring_sand |= target->north_row[15].sand; + current->neighboring_clay |= target->north_row[15].clay; + current->neighboring_aquifer = static_cast(static_cast(current->neighboring_aquifer) | static_cast(target->north_row[15].aquifer)); + } + + if (k < world->worldgen.worldgen_parms.dim_y - 1) { + embark_assist::defs::region_tile_datum* target = &survey_results->at(i).at(k + 1); + + for (uint16_t l = 0; l < 16; l++) { + current->neighboring_sand |= target->north_row[l].sand; + current->neighboring_clay |= target->north_row[l].clay; + current->neighboring_aquifer = static_cast(static_cast(current->neighboring_aquifer) | static_cast(target->north_row[l].aquifer)); + } + } + + if (i < world->worldgen.worldgen_parms.dim_x - 1 && k < world->worldgen.worldgen_parms.dim_y - 1) { + embark_assist::defs::region_tile_datum* target = &survey_results->at(i + 1).at(k + 1); + + current->neighboring_sand |= target->north_row[0].sand; + current->neighboring_clay |= target->north_row[0].clay; + current->neighboring_aquifer = static_cast(static_cast(current->neighboring_aquifer) | static_cast(target->north_row[0].aquifer)); + } + + survey_results->at(i).at(k).survey_completed = true; // A bit wasteful to add a flag to every entry when only the very first one is ever read... + } + } + } } } diff --git a/plugins/embark-assistant/survey.cpp b/plugins/embark-assistant/survey.cpp index fb44440a1..c77dbc12c 100644 --- a/plugins/embark-assistant/survey.cpp +++ b/plugins/embark-assistant/survey.cpp @@ -802,6 +802,10 @@ void embark_assist::survey::high_level_world_survey(embark_assist::defs::geo_dat uint8_t offset_count = 0; auto &results = survey_results->at(i).at(k); results.surveyed = false; + results.survey_completed = false; + results.neighboring_sand = false; + results.neighboring_clay = false; + results.neighboring_aquifer = embark_assist::defs::aquifer_sizes::NA; results.aquifer = embark_assist::defs::aquifer_sizes::NA; results.clay_count = 0; results.sand_count = 0; @@ -925,7 +929,7 @@ void embark_assist::survey::high_level_world_survey(embark_assist::defs::geo_dat void embark_assist::survey::survey_mid_level_tile(embark_assist::defs::geo_data *geo_summary, embark_assist::defs::world_tile_data *survey_results, embark_assist::defs::mid_level_tiles *mlt) { -// color_ostream_proxy out(Core::getInstance().getConsole()); +// color_ostream_proxy out(Core::getInstance().getConsole()); auto screen = Gui::getViewscreenByType(0); int16_t x = screen->location.region_pos.x; int16_t y = screen->location.region_pos.y;