Merge remote-tracking branch 'PatrikLundell/embark-assistant' into develop

develop
lethosor 2020-11-18 11:12:17 -05:00
commit 8548295fe5
No known key found for this signature in database
GPG Key ID: 76A269552F4F58C1
6 changed files with 417 additions and 227 deletions

@ -52,6 +52,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
- `buildingplan`: new global settings for whether generic building materials should match blocks, boulders, logs, and/or bars. defaults are everything but bars.
- `quickfort`: The Dreamfort sample blueprints now have complete walkthroughs for each fort level and importable orders that automate basic fort stock management
- `quickfort`: More blueprints have been added to the blueprints library: several bedroom layouts, the Saracen Crypts, and the complete fortress example from Python Quickfort: TheQuickFortress
- `embark-assistant`: split the lair types displayed on the local map into mound, burrow, and lair
## API
- `buildingplan`: added Lua interface API

@ -3,6 +3,7 @@
#include <array>
#include <string>
#include <vector>
#include "df/biome_type.h"
#include "df/world_region_type.h"
using namespace std;
@ -31,6 +32,35 @@ namespace embark_assist {
const uint8_t Light_Aquifer_Bit = 2;
const uint8_t Heavy_Aquifer_Bit = 4;
namespace directions {
enum directions {
Northwest,
North,
Northeast,
West,
Center,
East,
Southwest,
South,
Southeast
};
};
namespace offset_directions {
enum offset_directions {
NA, // 0 isn't used for offsets
Southwest,
South,
Southeast,
West,
Center,
East,
Northwest,
North,
Northeast
};
};
enum class tree_levels : int8_t {
None,
Very_Scarce,
@ -66,9 +96,12 @@ 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.
uint8_t neighboring_aquifer = Clear_Aquifer_Bits;
bool neighboring_clay = false; // These elements are updated after the survey by checking if there are any border MLTs in neighboring tiles that
bool neighboring_sand = false; // provide the resource through an incursion.
bool neighboring_biomes[ENUM_LAST_ITEM(biome_type) + 1];
bool neighboring_region_types[ENUM_LAST_ITEM(world_region_type) + 1];
bool neighboring_savagery[3];
bool neighboring_evilness[3];
uint8_t aquifer = Clear_Aquifer_Bits;
uint16_t clay_count = 0;
uint16_t sand_count = 0;

@ -314,7 +314,19 @@ command_result embark_assistant(color_ostream &out, std::vector <std::string> &
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::Clear_Aquifer_Bits;
for (uint8_t l = 0; l <= ENUM_LAST_ITEM(biome_type); l++) {
embark_assist::main::state->survey_results[i][k].neighboring_biomes[l] = false;
}
for (uint8_t l = 0; l <= ENUM_LAST_ITEM(world_region_type); l++) {
embark_assist::main::state->survey_results[i][k].neighboring_region_types[l] = false;
}
for (uint8_t l = 0; l < 2; l++) {
embark_assist::main::state->survey_results[i][k].neighboring_savagery[l] = false;
embark_assist::main::state->survey_results[i][k].neighboring_evilness[l] = false;
}
embark_assist::main::state->survey_results[i][k].aquifer = embark_assist::defs::Clear_Aquifer_Bits;
embark_assist::main::state->survey_results[i][k].clay_count = 0;
embark_assist::main::state->survey_results[i][k].sand_count = 0;

@ -157,7 +157,9 @@ namespace embark_assist{
help_text.push_back("C: Camp");
help_text.push_back("c: Cave. Only displayed if the DF worldgen parameter does not display caves.");
help_text.push_back("i: Important Location. The author doesn't actually know what those are.");
help_text.push_back("l: Lair");
help_text.push_back("m: Lair (Simple Mound)");
help_text.push_back("b: Lair (Simple Burrow)");
help_text.push_back("l: Lair (Wilderness Location)");
help_text.push_back("L: Labyrinth");
help_text.push_back("M: Monument. The author is unsure how/if this is broken down further.");
help_text.push_back("S: Shrine");
@ -338,7 +340,7 @@ namespace embark_assist{
help_text.push_back(" the N, followed by the one to the W, and lastly the one acting as the");
help_text.push_back(" reference. This means there's a risk embarks with such 'trouble' corners");
help_text.push_back(" may get affected corner(s) evaluated incorrectly.");
help_text.push_back("Version 0.11 2020-03-03");
help_text.push_back("Version 0.12 2020-11-17");
break;
}
@ -367,11 +369,13 @@ namespace embark_assist{
embark_assist::screen::paintString(site_pen, 1, 4, "C");
embark_assist::screen::paintString(site_pen, 1, 5, "c");
embark_assist::screen::paintString(site_pen, 1, 6, "i");
embark_assist::screen::paintString(site_pen, 1, 7, "l");
embark_assist::screen::paintString(site_pen, 1, 8, "L");
embark_assist::screen::paintString(site_pen, 1, 9, "M");
embark_assist::screen::paintString(site_pen, 1, 10, "S");
embark_assist::screen::paintString(site_pen, 1, 11, "V");
embark_assist::screen::paintString(site_pen, 1, 7, "m");
embark_assist::screen::paintString(site_pen, 1, 8, "b");
embark_assist::screen::paintString(site_pen, 1, 9, "l");
embark_assist::screen::paintString(site_pen, 1, 10, "L");
embark_assist::screen::paintString(site_pen, 1, 11, "M");
embark_assist::screen::paintString(site_pen, 1, 12, "S");
embark_assist::screen::paintString(site_pen, 1, 13, "V");
break;
case pages::Finder:

@ -408,42 +408,42 @@ namespace embark_assist {
// Logic can be implemented with modulo and division, but that's harder to read.
switch (from_direction) {
case 0:
case embark_assist::defs::directions::Northwest:
fetch_i = i - 1;
fetch_k = k - 1;
break;
case 1:
case embark_assist::defs::directions::North:
fetch_k = k - 1;
break;
case 2:
case embark_assist::defs::directions::Northeast:
fetch_i = i + 1;
fetch_k = k - 1;
break;
case 3:
case embark_assist::defs::directions::West:
fetch_i = i - 1;
break;
case 4:
case embark_assist::defs::directions::Center:
return; // Own tile provides the data, so there's no incursion.
break;
case 5:
case embark_assist::defs::directions::East:
fetch_i = i + 1;
break;
case 6:
case embark_assist::defs::directions::Southwest:
fetch_i = i - 1;
fetch_k = k + 1;
break;
case 7:
case embark_assist::defs::directions::South:
fetch_k = k + 1;
break;
case 8:
case embark_assist::defs::directions::Southeast:
fetch_i = i + 1;
fetch_k = k + 1;
}
@ -910,7 +910,7 @@ namespace embark_assist {
else {
process_embark_incursion_mid_level_tile
(embark_assist::survey::translate_corner(survey_results,
4,
embark_assist::defs::directions::Center,
x,
y,
i,
@ -958,7 +958,7 @@ namespace embark_assist {
else {
process_embark_incursion_mid_level_tile
(embark_assist::survey::translate_corner(survey_results,
5,
embark_assist::defs::directions::East,
x,
y,
i,
@ -983,7 +983,7 @@ namespace embark_assist {
else {
process_embark_incursion_mid_level_tile
(embark_assist::survey::translate_corner(survey_results,
7,
embark_assist::defs::directions::South,
x,
y,
i,
@ -1031,7 +1031,7 @@ namespace embark_assist {
else {
process_embark_incursion_mid_level_tile
(embark_assist::survey::translate_corner(survey_results,
8,
embark_assist::defs::directions::Southeast,
x,
y,
i,
@ -1058,7 +1058,7 @@ namespace embark_assist {
else if (k > start_y) { // We've already covered the NW corner of the NW, with its complications.
process_embark_incursion_mid_level_tile
(embark_assist::survey::translate_corner(survey_results,
4,
embark_assist::defs::directions::Center,
x,
y,
start_x,
@ -1104,7 +1104,7 @@ namespace embark_assist {
else if (k < start_y + finder->y_dim - 1) { // We've already covered the SW corner of the SW tile, with its complicatinons.
process_embark_incursion_mid_level_tile
(embark_assist::survey::translate_corner(survey_results,
7,
embark_assist::defs::directions::South,
x,
y,
start_x,
@ -1127,7 +1127,7 @@ namespace embark_assist {
else if (k > start_y) { // We've already covered the NE tile's NE corner, with its complications.
process_embark_incursion_mid_level_tile
(embark_assist::survey::translate_corner(survey_results,
5,
embark_assist::defs::directions::East,
x,
y,
start_x + finder->x_dim - 1,
@ -1173,7 +1173,7 @@ namespace embark_assist {
else if (k < start_y + finder->y_dim - 1) { // We've already covered the SE tile's SE corner, with its complications.
process_embark_incursion_mid_level_tile
(embark_assist::survey::translate_corner(survey_results,
8,
embark_assist::defs::directions::Southeast,
x,
y,
start_x + finder->x_dim - 1,
@ -1450,7 +1450,7 @@ namespace embark_assist {
break;
case embark_assist::defs::evil_savagery_values::Present:
if (tile->savagery_count[i] == 0) {
if (tile->savagery_count[i] == 0 && !tile->neighboring_savagery[i]) {
if (trace) out.print("matcher::world_tile_match: Savagery Present (%i, %i)\n", x, y);
return false;
}
@ -1480,7 +1480,7 @@ namespace embark_assist {
break;
case embark_assist::defs::evil_savagery_values::Present:
if (tile->evilness_count[i] == 0) {
if (tile->evilness_count[i] == 0 && !tile->neighboring_evilness[i]) {
if (trace) out.print("matcher::world_tile_match: Evil Present (%i, %i)\n", x, y);
return false;
}
@ -1518,16 +1518,16 @@ namespace embark_assist {
break;
case embark_assist::defs::aquifer_ranges::None_Plus_Light:
if (!((tile->aquifer | tile->neighboring_aquifer) & embark_assist::defs::None_Aquifer_Bit) ||
!((tile->aquifer | tile->neighboring_aquifer) & embark_assist::defs::Light_Aquifer_Bit)) {
if (!(tile->aquifer & embark_assist::defs::None_Aquifer_Bit) ||
!(tile->aquifer & embark_assist::defs::Light_Aquifer_Bit)) {
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 (!((tile->aquifer | tile->neighboring_aquifer) & embark_assist::defs::None_Aquifer_Bit) ||
((tile->aquifer | tile->neighboring_aquifer) == embark_assist::defs::None_Aquifer_Bit)) {
if (!(tile->aquifer & embark_assist::defs::None_Aquifer_Bit) ||
(tile->aquifer == embark_assist::defs::None_Aquifer_Bit)) {
if (trace) out.print("matcher::world_tile_match: Aquifer None_Plus_At_Least_Light (%i, %i)\n", x, y);
return false;
}
@ -1541,38 +1541,38 @@ namespace embark_assist {
break;
case embark_assist::defs::aquifer_ranges::At_Least_Light:
if ((tile->aquifer | tile->neighboring_aquifer) == embark_assist::defs::None_Aquifer_Bit) {
if (tile->aquifer == embark_assist::defs::None_Aquifer_Bit) {
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 (!((tile->aquifer | tile->neighboring_aquifer) & embark_assist::defs::None_Aquifer_Bit) ||
!((tile->aquifer | tile->neighboring_aquifer) & embark_assist::defs::Heavy_Aquifer_Bit)) {
if (!(tile->aquifer & embark_assist::defs::None_Aquifer_Bit) ||
!(tile->aquifer & embark_assist::defs::Heavy_Aquifer_Bit)) {
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 ((tile->aquifer | tile->neighboring_aquifer) == embark_assist::defs::Heavy_Aquifer_Bit ||
!((tile->aquifer | tile->neighboring_aquifer) & embark_assist::defs::Heavy_Aquifer_Bit)) {
if (tile->aquifer == embark_assist::defs::Heavy_Aquifer_Bit ||
!(tile->aquifer & embark_assist::defs::Heavy_Aquifer_Bit)) {
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 (!((tile->aquifer | tile->neighboring_aquifer) & embark_assist::defs::Light_Aquifer_Bit) ||
!((tile->aquifer | tile->neighboring_aquifer) & embark_assist::defs::Heavy_Aquifer_Bit)) {
if (!(tile->aquifer & embark_assist::defs::Light_Aquifer_Bit) ||
!(tile->aquifer & embark_assist::defs::Heavy_Aquifer_Bit)) {
if (trace) out.print("matcher::world_tile_match: Aquifer Light_Plus_Heavy (%i, %i)\n", x, y);
return false;
}
break;
case embark_assist::defs::aquifer_ranges::None_Light_Heavy:
if ((tile->aquifer | tile->neighboring_aquifer) !=
if (tile->aquifer !=
(embark_assist::defs::None_Aquifer_Bit | embark_assist::defs::Light_Aquifer_Bit | embark_assist::defs::Heavy_Aquifer_Bit)) {
if (trace) out.print("matcher::world_tile_match: Aquifer None_Light_Heavy (%i, %i)\n", x, y);
return false;
@ -2056,20 +2056,7 @@ namespace embark_assist {
// Region Type 1
if (finder->region_type_1 != -1) {
found = false;
for (uint8_t k = 1; k < 10; k++) {
if (tile->biome_index[k] != -1) {
if (world_data->regions[tile->biome_index[k]]->type == finder->region_type_1) {
found = true;
break;
}
}
if (found) break;
}
if (!found) {
if (!tile->neighboring_region_types[finder->region_type_1]) {
if (trace) out.print("matcher::world_tile_match: Region_Type_1 (%i, %i)\n", x, y);
return false;
}
@ -2077,20 +2064,7 @@ namespace embark_assist {
// Region Type 2
if (finder->region_type_2 != -1) {
found = false;
for (uint8_t k = 1; k < 10; k++) {
if (tile->biome_index[k] != -1) {
if (world_data->regions[tile->biome_index[k]]->type == finder->region_type_2) {
found = true;
break;
}
}
if (found) break;
}
if (!found) {
if (!tile->neighboring_region_types[finder->region_type_2]) {
if (trace) out.print("matcher::world_tile_match: Region_Type_2 (%i, %i)\n", x, y);
return false;
}
@ -2098,20 +2072,7 @@ namespace embark_assist {
// Region Type 3
if (finder->region_type_3 != -1) {
found = false;
for (uint8_t k = 1; k < 10; k++) {
if (tile->biome_index[k] != -1) {
if (world_data->regions[tile->biome_index[k]]->type == finder->region_type_3) {
found = true;
break;
}
}
if (found) break;
}
if (!found) {
if (!tile->neighboring_region_types[finder->region_type_3]) {
if (trace) out.print("matcher::world_tile_match: Region_Type_3 (%i, %i)\n", x, y);
return false;
}
@ -2119,16 +2080,7 @@ namespace embark_assist {
// Biome 1
if (finder->biome_1 != -1) {
found = false;
for (uint8_t i = 1; i < 10; i++) {
if (tile->biome[i] == finder->biome_1) {
found = true;
break;
}
}
if (!found) {
if (!tile->neighboring_biomes[finder->biome_1]) {
if (trace) out.print("matcher::world_tile_match: Biome_1 (%i, %i)\n", x, y);
return false;
}
@ -2136,16 +2088,7 @@ namespace embark_assist {
// Biome 2
if (finder->biome_2 != -1) {
found = false;
for (uint8_t i = 1; i < 10; i++) {
if (tile->biome[i] == finder->biome_2) {
found = true;
break;
}
}
if (!found) {
if (!tile->neighboring_biomes[finder->biome_2]) {
if (trace) out.print("matcher::world_tile_match: Biome_2 (%i, %i)\n", x, y);
return false;
}
@ -2153,16 +2096,7 @@ namespace embark_assist {
// Biome 3
if (finder->biome_3 != -1) {
found = false;
for (uint8_t i = 1; i < 10; i++) {
if (tile->biome[i] == finder->biome_3) {
found = true;
break;
}
}
if (!found) {
if (!tile->neighboring_biomes[finder->biome_3]) {
if (trace) out.print("matcher::world_tile_match: Biome_3 (%i, %i)\n", x, y);
return false;
}
@ -2798,6 +2732,22 @@ namespace embark_assist {
finder,
match_results);
}
//=======================================================================================
void merge_incursion_into_world_tile(embark_assist::defs::region_tile_datum* current,
embark_assist::defs::region_tile_datum* target_tile,
embark_assist::defs::mid_level_tile* target_mlt) {
df::world_data* world_data = world->world_data;
current->aquifer |= target_mlt->aquifer;
current->neighboring_sand |= target_mlt->sand;
current->neighboring_clay |= target_mlt->clay;
if (current->min_region_soil > target_mlt->soil_depth) current->min_region_soil = target_mlt->soil_depth;
if (current->max_region_soil < target_mlt->soil_depth) current->max_region_soil = target_mlt->soil_depth;
current->neighboring_biomes[target_tile->biome[target_mlt->biome_offset]] = true;
current->neighboring_region_types[world_data->regions[target_tile->biome_index[target_mlt->biome_offset]]->type] = true;
}
}
}
@ -2899,6 +2849,7 @@ uint16_t embark_assist::matcher::find(embark_assist::defs::match_iterators *iter
embark_assist::defs::match_results *match_results) {
color_ostream_proxy out(Core::getInstance().getConsole());
df::world_data* world_data = world->world_data;
auto screen = Gui::getViewscreenByType<df::viewscreen_choose_start_sitest>(0);
uint16_t x_end;
uint16_t y_end;
@ -3159,76 +3110,227 @@ uint16_t embark_assist::matcher::find(embark_assist::defs::match_iterators *iter
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);
for (uint8_t l = 0; l < 16; l++) {
// Start with the north row west corners
switch (embark_assist::survey::translate_corner(survey_results,
embark_assist::defs::directions::Center,
i,
k,
l,
0)) {
case embark_assist::defs::directions::Northwest:
{
if (l == 0) {
embark_assist::defs::region_tile_datum* target_tile = &survey_results->at(i - 1).at(k - 1);
merge_incursion_into_world_tile(current, target_tile, &target_tile->south_row[15]);
}
else {
embark_assist::defs::region_tile_datum* target_tile = &survey_results->at(i).at(k - 1);
merge_incursion_into_world_tile(current, target_tile, &target_tile->south_row[l - 1]);
}
break;
}
case embark_assist::defs::directions::North:
{
embark_assist::defs::region_tile_datum* target_tile = &survey_results->at(i).at(k - 1);
merge_incursion_into_world_tile(current, target_tile, &target_tile->south_row[l]);
break;
}
case embark_assist::defs::directions::West:
{
if (l == 0) {
embark_assist::defs::region_tile_datum* target_tile = &survey_results->at(i - 1).at(k);
merge_incursion_into_world_tile(current, target_tile, &target_tile->east_column[0]);
}
break;
}
// Only legal remaining result is Center, and we don't need to do anything for that case.
}
// North row edges
if (embark_assist::survey::translate_ns_edge(survey_results,
true,
i,
k,
l,
0) == embark_assist::defs::directions::North) {
current->neighboring_sand |= target->south_row [15].sand;
current->neighboring_clay |= target->south_row[15].clay;
current->neighboring_aquifer |= target->south_row[15].aquifer;
embark_assist::defs::region_tile_datum* target_tile = &survey_results->at(i).at(k - 1);
merge_incursion_into_world_tile(current, target_tile, &target_tile->south_row[l]);
}
if (k > 0) {
embark_assist::defs::region_tile_datum* target = &survey_results->at(i).at(k - 1);
// North row east corners
switch (embark_assist::survey::translate_corner(survey_results,
embark_assist::defs::directions::East,
i,
k,
l,
0)) {
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 |= target->south_row[l].aquifer;
case embark_assist::defs::directions::North:
{
embark_assist::defs::region_tile_datum* target_tile = &survey_results->at(i).at(k - 1);
merge_incursion_into_world_tile(current, target_tile, &target_tile->south_row[l]);
break;
}
case embark_assist::defs::directions::Northeast:
{
if (l == 15) {
embark_assist::defs::region_tile_datum* target_tile = &survey_results->at(i + 1).at(k - 1);
merge_incursion_into_world_tile(current, target_tile, &target_tile->south_row[0]);
}
else {
embark_assist::defs::region_tile_datum* target_tile = &survey_results->at(i).at(k - 1);
merge_incursion_into_world_tile(current, target_tile, &target_tile->south_row[l + 1]);
}
break;
}
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);
case embark_assist::defs::directions::East:
{
if (l == 15) {
embark_assist::defs::region_tile_datum* target_tile = &survey_results->at(i + 1).at(k);
merge_incursion_into_world_tile(current, target_tile, &target_tile->west_column[0]);
}
break;
}
current->neighboring_sand |= target->south_row[0].sand;
current->neighboring_clay |= target->south_row[0].clay;
current->neighboring_aquifer |= target->south_row[0].aquifer;
// Only legal remaining result is Center, and we don't need to do anything for that case.
}
// West column
if (i > 0) {
embark_assist::defs::region_tile_datum* target = &survey_results->at(i - 1).at(k);
if (embark_assist::survey::translate_ew_edge(survey_results,
true,
i,
k,
0,
l) == embark_assist::defs::directions::West) {
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 |= target->east_column[l].aquifer;
embark_assist::defs::region_tile_datum* target_tile = &survey_results->at(i - 1).at(k);
merge_incursion_into_world_tile(current, target_tile, &target_tile->east_column[l]);
}
// East column
if (embark_assist::survey::translate_ew_edge(survey_results,
false,
i,
k,
15,
l) == embark_assist::defs::directions::East) {
embark_assist::defs::region_tile_datum* target_tile = &survey_results->at(i + 1).at(k);
merge_incursion_into_world_tile(current, target_tile, &target_tile->west_column[l]);
}
if (i < world->worldgen.worldgen_parms.dim_x - 1) {
embark_assist::defs::region_tile_datum* target = &survey_results->at(i + 1).at(k);
// South row west corners
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 |= target->west_column[l].aquifer;
switch (embark_assist::survey::translate_corner(survey_results,
embark_assist::defs::directions::South,
i,
k,
l,
15)) {
case embark_assist::defs::directions::West:
{
if (l == 0) {
embark_assist::defs::region_tile_datum* target_tile = &survey_results->at(i - 1).at(k);
merge_incursion_into_world_tile(current, target_tile, &target_tile->east_column[15]);
}
break;
}
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);
case embark_assist::defs::directions::Southwest:
{
if (l == 0) {
embark_assist::defs::region_tile_datum* target_tile = &survey_results->at(i - 1).at(k + 1);
merge_incursion_into_world_tile(current, target_tile, &target_tile->north_row[15]);
}
else {
embark_assist::defs::region_tile_datum* target_tile = &survey_results->at(i).at(k + 1);
merge_incursion_into_world_tile(current, target_tile, &target_tile->north_row[l - 1]);
}
break;
}
current->neighboring_sand |= target->north_row[15].sand;
current->neighboring_clay |= target->north_row[15].clay;
current->neighboring_aquifer |= target->north_row[15].aquifer;
case embark_assist::defs::directions::South:
{
embark_assist::defs::region_tile_datum* target_tile = &survey_results->at(i).at(k + 1);
merge_incursion_into_world_tile(current, target_tile, &target_tile->north_row[l]);
break;
}
// Only legal remaining result is Center, and we don't need to do anything for that case.
}
if (k < world->worldgen.worldgen_parms.dim_y - 1) {
embark_assist::defs::region_tile_datum* target = &survey_results->at(i).at(k + 1);
// South row edges
if (embark_assist::survey::translate_ns_edge(survey_results,
false,
i,
k,
l,
15) == embark_assist::defs::directions::South) {
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 |= target->north_row[l].aquifer;
embark_assist::defs::region_tile_datum* target_tile = &survey_results->at(i).at(k + 1);
merge_incursion_into_world_tile(current, target_tile, &target_tile->north_row[l]);
}
// South row east corners
switch (embark_assist::survey::translate_corner(survey_results,
embark_assist::defs::directions::Southeast,
i,
k,
l,
15)) {
case embark_assist::defs::directions::East:
{
if (l == 15) {
embark_assist::defs::region_tile_datum* target_tile = &survey_results->at(i + 1).at(k);
merge_incursion_into_world_tile(current, target_tile, &target_tile->west_column[15]);
}
break;
}
case embark_assist::defs::directions::South:
{
embark_assist::defs::region_tile_datum* target_tile = &survey_results->at(i).at(k + 1);
merge_incursion_into_world_tile(current, target_tile, &target_tile->north_row[l]);
break;
}
case embark_assist::defs::directions::Southeast:
{
if (l == 15) {
embark_assist::defs::region_tile_datum* target_tile = &survey_results->at(i + 1).at(k + 1);
merge_incursion_into_world_tile(current, target_tile, &target_tile->north_row[0]);
}
else {
embark_assist::defs::region_tile_datum* target_tile = &survey_results->at(i).at(k + 1);
merge_incursion_into_world_tile(current, target_tile, &target_tile->north_row[l + 1]);
}
break;
}
}
}
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);
// The complete set of biomes and region types is stored in the "neighboring" elements, which is a little misleading.
for (uint8_t l = 0; l < 10; l++) {
if (current->biome_index[l] != -1) {
current->neighboring_biomes[current->biome[l]] = true;
current->neighboring_region_types[world_data->regions[current->biome_index[l]]->type] = true;
}
}
current->neighboring_sand |= target->north_row[0].sand;
current->neighboring_clay |= target->north_row[0].clay;
current->neighboring_aquifer |= target->north_row[0].aquifer;
current->biome_count = 0;
for (uint8_t l = 0; l <= ENUM_LAST_ITEM(biome_type); l++) {
if (current->neighboring_biomes[l]) current->biome_count++;
}
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...

@ -567,42 +567,42 @@ namespace embark_assist {
// Logic can be implemented with modulo and division, but that's harder to read.
switch (from_direction) {
case 0:
case embark_assist::defs::directions::Northwest:
fetch_i = i - 1;
fetch_k = k - 1;
break;
case 1:
case embark_assist::defs::directions::North:
fetch_k = k - 1;
break;
case 2:
case embark_assist::defs::directions::Northeast:
fetch_i = i + 1;
fetch_k = k - 1;
break;
case 3:
case embark_assist::defs::directions::West:
fetch_i = i - 1;
break;
case 4:
case embark_assist::defs::directions::Center:
return; // Own tile provides the data, so there's no incursion.
break;
case 5:
case embark_assist::defs::directions::East:
fetch_i = i + 1;
break;
case 6:
case embark_assist::defs::directions::Southwest:
fetch_i = i - 1;
fetch_k = k + 1;
break;
case 7:
case embark_assist::defs::directions::South:
fetch_k = k + 1;
break;
case 8:
case embark_assist::defs::directions::Southeast:
fetch_i = i + 1;
fetch_k = k + 1;
break;
@ -803,9 +803,21 @@ void embark_assist::survey::high_level_world_survey(embark_assist::defs::geo_dat
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::Clear_Aquifer_Bits;
results.neighboring_sand = false;
for (uint8_t l = 0; l <= ENUM_LAST_ITEM(biome_type); l++) {
results.neighboring_biomes[l] = false;
}
for (uint8_t l = 0; l <= ENUM_LAST_ITEM(world_region_type); l++) {
results.neighboring_region_types[l] = false;
}
for (uint8_t l = 0; l < 2; l++) {
results.neighboring_savagery[l] = false;
results.neighboring_evilness[l] = false;
}
results.aquifer = embark_assist::defs::Clear_Aquifer_Bits;
results.clay_count = 0;
results.sand_count = 0;
@ -903,11 +915,24 @@ void embark_assist::survey::high_level_world_survey(embark_assist::defs::geo_dat
}
}
results.biome_count = 0;
for (uint8_t l = 1; l < 10; l++) {
if (results.biome[l] != -1) results.biome_count++;
bool biomes[ENUM_LAST_ITEM(biome_type) + 1];
for (uint8_t l = 0; l <= ENUM_LAST_ITEM(biome_type); l++) {
biomes[l] = false;
}
for (uint8_t l = 1; l < 10; l++)
{
if (results.biome[l] != -1) {
biomes[results.biome[l]] = true;
}
}
int count = 0;
for (uint8_t l = 0; l <= ENUM_LAST_ITEM(biome_type); l++) {
if (biomes[l]) count++;
}
results.biome_count = count;
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;
@ -1511,41 +1536,41 @@ df::coord2d embark_assist::survey::apply_offset(uint16_t x, uint16_t y, int8_t o
result.y = y;
switch (offset) {
case 1:
case embark_assist::defs::offset_directions::Southwest:
result.x--;
result.y++;
break;
case 2:
case embark_assist::defs::offset_directions::South:
result.y++;
break;
case 3:
case embark_assist::defs::offset_directions::Southeast:
result.x++;
result.y++;
break;
case 4:
case embark_assist::defs::offset_directions::West:
result.x--;
break;
case 5:
case embark_assist::defs::offset_directions::Center:
break; // Center. No change
case 6:
case embark_assist::defs::offset_directions::East:
result.x++;
break;
case 7:
case embark_assist::defs::offset_directions::Northwest:
result.x--;
result.y--;
break;
case 8:
case embark_assist::defs::offset_directions::North:
result.y--;
break;
case 9:
case embark_assist::defs::offset_directions::Northeast:
result.x++;
result.y--;
break;
@ -1650,12 +1675,12 @@ uint8_t embark_assist::survey::translate_corner(embark_assist::defs::world_tile
int8_t w_region_type_level;
int8_t home_region_type_level;
if (corner_location == 4) { // We're the reference. No change.
if (corner_location == embark_assist::defs::directions::Center) { // We're the reference. No change.
}
else if (corner_location == 5) { // Tile to the east is the reference
else if (corner_location == embark_assist::defs::directions::East) { // Tile to the east is the reference
effective_i = i + 1;
}
else if (corner_location == 7) { // Tile to the south is the reference
else if (corner_location == embark_assist::defs::directions::South) { // Tile to the south is the reference
effective_k = k + 1;
}
else { // 8, tile to the southeast is the reference.
@ -1667,9 +1692,13 @@ uint8_t embark_assist::survey::translate_corner(embark_assist::defs::world_tile
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.
return 4;
return embark_assist::defs::directions::Center;
}
else { // East side corners of the east edge of the world
if (effective_y == 0 && effective_k == 0) { // North edge of the world. Only one alternative exists.
return embark_assist::defs::directions::Center;
}
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);
@ -1696,18 +1725,18 @@ uint8_t embark_assist::survey::translate_corner(embark_assist::defs::world_tile
}
if (nw_region_type_level < w_region_type_level) {
return 4;
return embark_assist::defs::directions::Center;
}
else if (nw_region_type_level > w_region_type_level) {
return 1;
return embark_assist::defs::directions::North;
}
// Neither tile will automatically yield to the other
if (corner_location == 5) {
return 1;
if (corner_location == embark_assist::defs::directions::East) {
return embark_assist::defs::directions::North;
}
else { // Can only be corner_location == 8
return 4;
else { // Can only be corner_location == embark_assist::defs::SE
return embark_assist::defs::directions::Center;
}
}
}
@ -1738,18 +1767,18 @@ uint8_t embark_assist::survey::translate_corner(embark_assist::defs::world_tile
}
if (nw_region_type_level < n_region_type_level) {
return 4;
return embark_assist::defs::directions::Center;
}
else if (nw_region_type_level > n_region_type_level) {
return 5;
return embark_assist::defs::directions::East;
}
// Neither tile will automatically yield to the other
if (corner_location == 7) {
return 4;
if (corner_location == embark_assist::defs::directions::South) {
return embark_assist::defs::directions::Center;
}
else { // Can only be corner_location == 8
return 5;
else { // Can only be corner_location == embark_assist::defs::directions::Southeast
return embark_assist::defs::directions::East;
}
}
@ -1814,7 +1843,7 @@ uint8_t embark_assist::survey::translate_corner(embark_assist::defs::world_tile
if (effective_x == 0 && effective_i == 0) { // West edge of the world
if (effective_y == 0 && effective_k == 0) {
return 4; // Only a single reference to this info, the own tile.
return embark_assist::defs::directions::Center; // Only a single reference to this info, the own tile.
}
else {
nw_region_type_level = -1; // Knock out the unreachable corners
@ -1826,8 +1855,8 @@ uint8_t embark_assist::survey::translate_corner(embark_assist::defs::world_tile
nw_region_type_level = -1; // Knock out the unreachable corners
n_region_type_level = -1;
if (corner_location == 4 && effective_corner == 1) { // The logic below would select the wrong alternative.
effective_corner = 3;
if (corner_location == embark_assist::defs::directions::Center && effective_corner == embark_assist::defs::directions::North) { // The logic below would select the wrong alternative.
effective_corner = embark_assist::defs::directions::West;
}
}
@ -1986,6 +2015,8 @@ uint8_t embark_assist::survey::translate_ns_edge(embark_assist::defs::world_tile
df::world_region_type south_region_type;
if (own_edge) {
if (y == 0 && k == 0) return embark_assist::defs::directions::Center; // There's nothing to the north, so we fall back on our own tile.
effective_edge = world_data->region_details[0]->edges.biome_x[i][k];
south_region_type = embark_assist::survey::region_type_of(survey_results, x, y, i, k);
north_region_type = embark_assist::survey::region_type_of(survey_results, x, y, i, k - 1);
@ -1994,9 +2025,10 @@ uint8_t embark_assist::survey::translate_ns_edge(embark_assist::defs::world_tile
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
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.
return embark_assist::defs::directions::Center; // 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];
@ -2039,18 +2071,18 @@ uint8_t embark_assist::survey::translate_ns_edge(embark_assist::defs::world_tile
if (effective_edge == 0) {
if (own_edge) {
return 1;
return embark_assist::defs::directions::North;
}
else {
return 4;
return embark_assist::defs::directions::Center;
}
}
else {
if (own_edge) {
return 4;
return embark_assist::defs::directions::Center;
}
else {
return 7;
return embark_assist::defs::directions::South;
}
}
}
@ -2070,6 +2102,7 @@ uint8_t embark_assist::survey::translate_ew_edge(embark_assist::defs::world_tile
df::world_region_type east_region_type;
if (own_edge) {
if (x == 0 && i == 0) return embark_assist::defs::directions::Center; // There's nothing to the west, so we fall back on our own tile.
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);
@ -2080,7 +2113,7 @@ uint8_t embark_assist::survey::translate_ew_edge(embark_assist::defs::world_tile
}
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.
return embark_assist::defs::directions::Center; // 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];
@ -2121,18 +2154,18 @@ uint8_t embark_assist::survey::translate_ew_edge(embark_assist::defs::world_tile
}
if (effective_edge == 0) {
if (own_edge) {
return 3;
return embark_assist::defs::directions::West;
}
else {
return 4;
return embark_assist::defs::directions::Center;
}
}
else {
if (own_edge) {
return 4;
return embark_assist::defs::directions::Center;
}
else {
return 5;
return embark_assist::defs::directions::East;
}
}
}
@ -2190,7 +2223,12 @@ void embark_assist::survey::survey_region_sites(embark_assist::defs::site_lists
break;
case df::lair_type::SIMPLE_MOUND:
site_list->push_back({ (uint8_t)site->rgn_min_x , (uint8_t)site->rgn_min_y, 'm' });
break;
case df::lair_type::SIMPLE_BURROW:
site_list->push_back({ (uint8_t)site->rgn_min_x , (uint8_t)site->rgn_min_y, 'b' });
break;
case df::lair_type::WILDERNESS_LOCATION:
site_list->push_back({ (uint8_t)site->rgn_min_x , (uint8_t)site->rgn_min_y, 'l' });
break;
@ -2375,7 +2413,7 @@ void embark_assist::survey::survey_embark(embark_assist::defs::mid_level_tiles *
else {
process_embark_incursion_mid_level_tile
(translate_corner(survey_results,
4,
embark_assist::defs::directions::Center,
x,
y,
i,
@ -2415,7 +2453,7 @@ void embark_assist::survey::survey_embark(embark_assist::defs::mid_level_tiles *
else {
process_embark_incursion_mid_level_tile
(translate_corner(survey_results,
5,
embark_assist::defs::directions::East,
x,
y,
i,
@ -2436,7 +2474,7 @@ void embark_assist::survey::survey_embark(embark_assist::defs::mid_level_tiles *
else {
process_embark_incursion_mid_level_tile
(translate_corner(survey_results,
7,
embark_assist::defs::directions::South,
x,
y,
i,
@ -2476,7 +2514,7 @@ void embark_assist::survey::survey_embark(embark_assist::defs::mid_level_tiles *
else {
process_embark_incursion_mid_level_tile
(translate_corner(survey_results,
8,
embark_assist::defs::directions::Southeast,
x,
y,
i,
@ -2497,7 +2535,7 @@ void embark_assist::survey::survey_embark(embark_assist::defs::mid_level_tiles *
else if (k > state->local_min_y) { // We've already covered the NW corner of the NW, with its complications.
process_embark_incursion_mid_level_tile
(translate_corner(survey_results,
4,
embark_assist::defs::directions::Center,
x,
y,
state->local_min_x,
@ -2535,7 +2573,7 @@ void embark_assist::survey::survey_embark(embark_assist::defs::mid_level_tiles *
else if (k < state->local_max_y) { // We've already covered the SW corner of the SW tile, with its complicatinons.
process_embark_incursion_mid_level_tile
(translate_corner(survey_results,
7,
embark_assist::defs::directions::South,
x,
y,
state->local_min_x,
@ -2554,7 +2592,7 @@ void embark_assist::survey::survey_embark(embark_assist::defs::mid_level_tiles *
else if (k > state->local_min_y) { // We've already covered the NE tile's NE corner, with its complications.
process_embark_incursion_mid_level_tile
(translate_corner(survey_results,
5,
embark_assist::defs::directions::East,
x,
y,
state->local_max_x,
@ -2592,7 +2630,7 @@ void embark_assist::survey::survey_embark(embark_assist::defs::mid_level_tiles *
else if (k < state->local_max_y) { // We've already covered the SE tile's SE corner, with its complications.
process_embark_incursion_mid_level_tile
(translate_corner(survey_results,
8,
embark_assist::defs::directions::Southeast,
x,
y,
state->local_max_x,