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

develop
lethosor 2020-12-04 23:54:50 -05:00
commit db03f943c9
No known key found for this signature in database
GPG Key ID: 76A269552F4F58C1
6 changed files with 71 additions and 142 deletions

@ -41,6 +41,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
- `dwarfvet`: fixed a crash that could occur when discharging patients
- `dwarfmonitor`: fixed a crash when opening the ``prefs`` screen if units have vague preferences
- `embark-assistant`: fixed an issue causing incursion resource matching (e.g. sand/clay) to skip some tiles if those resources were provided only through incursions
- `embark-assistant`: corrected river size determination by performing it at the MLT level rather than the world tile one
- `zone`: fixed an issue causing the ``enumnick`` subcommand to run when attempting to run ``assign``, ``unassign``, or ``slaughter``
## Misc Improvements

@ -78,7 +78,7 @@ namespace embark_assist {
int8_t soil_depth;
int8_t offset;
int16_t elevation;
bool river_present = false;
river_sizes river_size = river_sizes::None;
int16_t river_elevation = 100;
int8_t adamantine_level; // -1 = none, 0 .. 3 = cavern 1 .. magma sea. Currently not used beyond present/absent.
int8_t magma_level; // -1 = none, 0 .. 3 = cavern 3 .. surface/volcano
@ -110,7 +110,8 @@ namespace embark_assist {
uint8_t min_region_soil = 10;
uint8_t max_region_soil = 0;
uint8_t max_waterfall = 0;
river_sizes river_size;
river_sizes min_river_size = river_sizes::None; // The smallest actual river size, with none only if no rivers exist.
river_sizes max_river_size = river_sizes::None;
int16_t biome_index[10]; // Indexed through biome_offset; -1 = null, Index of region, [0] not used
int16_t biome[10]; // Indexed through biome_offset; -1 = null, df::biome_type, [0] not used
uint8_t biome_count;

@ -334,7 +334,8 @@ command_result embark_assistant(color_ostream &out, std::vector <std::string> &
embark_assist::main::state->survey_results[i][k].min_region_soil = 10;
embark_assist::main::state->survey_results[i][k].max_region_soil = 0;
embark_assist::main::state->survey_results[i][k].max_waterfall = 0;
embark_assist::main::state->survey_results[i][k].river_size = embark_assist::defs::river_sizes::None;
embark_assist::main::state->survey_results[i][k].min_river_size = embark_assist::defs::river_sizes::None;
embark_assist::main::state->survey_results[i][k].max_river_size = embark_assist::defs::river_sizes::None;
embark_assist::main::state->survey_results[i][k].min_tree_level = embark_assist::defs::tree_levels::Heavily_Forested;
embark_assist::main::state->survey_results[i][k].max_tree_level = embark_assist::defs::tree_levels::None;

@ -340,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.12 2020-11-17");
help_text.push_back("Version 0.13 2020-12-03");
break;
}

@ -684,13 +684,15 @@ namespace embark_assist {
}
// River & Waterfall
if (mlt->at(i).at(k).river_present) {
// Actual size values were checked on the world tile level for min rivers
if (mlt->at(i).at(k).river_size != embark_assist::defs::river_sizes::None) {
if (finder->min_river != embark_assist::defs::river_ranges::NA &&
finder->min_river > static_cast<embark_assist::defs::river_ranges>(mlt->at(i).at(k).river_size)) return false;
if (finder->max_river != embark_assist::defs::river_ranges::NA &&
finder->max_river < static_cast<embark_assist::defs::river_ranges>(survey_results->at(x).at(y).river_size)) return false;
finder->max_river < static_cast<embark_assist::defs::river_ranges>(mlt->at(i).at(k).river_size)) return false;
if (i < start_x + finder->x_dim - 2 &&
mlt->at(i + 1).at(k).river_present &&
mlt->at(i + 1).at(k).river_size != embark_assist::defs::river_sizes::None &&
abs(mlt->at(i).at(k).river_elevation - mlt->at(i + 1).at(k).river_elevation) > result.max_waterfall) {
if (finder->min_waterfall == 0) return false; // 0 = Absent
result.max_waterfall =
@ -698,7 +700,7 @@ namespace embark_assist {
}
if (k < start_y + finder->y_dim - 2 &&
mlt->at(i).at(k + 1).river_present &&
mlt->at(i).at(k + 1).river_size != embark_assist::defs::river_sizes::None &&
abs(mlt->at(i).at(k).river_elevation - mlt->at(i).at(k + 1).river_elevation) > result.max_waterfall) {
if (finder->min_waterfall == 0) return false; // 0 = Absent
result.max_waterfall =
@ -1588,7 +1590,7 @@ namespace embark_assist {
}
// River size. Every tile has riverless tiles, so max rivers has to be checked on the detailed level.
switch (tile->river_size) {
switch (tile->max_river_size) {
case embark_assist::defs::river_sizes::None:
if (finder->min_river > embark_assist::defs::river_ranges::None) {
if (trace) out.print("matcher::world_tile_match: River_Size None (%i, %i)\n", x, y);
@ -2204,7 +2206,10 @@ namespace embark_assist {
}
}
}
else { // Not surveyed
else { // Not surveyed. This code is essentially obsolete size we're now surveying every tile the first time,
// but it does still provide a hint about the number of matching world tiles, and thus is kept.
// If designed this way originally the effort to code it wouldn't have been made, though...
// Savagery
for (uint8_t i = 0; i < 3; i++)
{
@ -2267,54 +2272,11 @@ namespace embark_assist {
// Aquifer // Requires survey
// River size
switch (tile->river_size) {
case embark_assist::defs::river_sizes::None:
if (finder->min_river > embark_assist::defs::river_ranges::None) {
if (trace) out.print("matcher::world_tile_match: NS River None (%i, %i)\n", x, y);
return false;
}
break;
case embark_assist::defs::river_sizes::Brook:
if (finder->min_river > embark_assist::defs::river_ranges::Brook) {
if (trace) out.print("matcher::world_tile_match: NS River Brook (%i, %i)\n", x, y);
return false;
}
break;
case embark_assist::defs::river_sizes::Stream:
if (finder->min_river > embark_assist::defs::river_ranges::Stream) {
if (trace) out.print("matcher::world_tile_match: NS River Stream (%i, %i)\n", x, y);
return false;
}
break;
case embark_assist::defs::river_sizes::Minor:
if (finder->min_river > embark_assist::defs::river_ranges::Minor) {
if (trace) out.print("matcher::world_tile_match: NS River Minor (%i, %i)\n", x, y);
return false;
}
break;
case embark_assist::defs::river_sizes::Medium:
if (finder->min_river > embark_assist::defs::river_ranges::Medium) {
if (trace) out.print("matcher::world_tile_match: NS River Medium (%i, %i)\n", x, y);
return false;
}
break;
case embark_assist::defs::river_sizes::Major:
if (finder->max_river != embark_assist::defs::river_ranges::NA) {
if (trace) out.print("matcher::world_tile_match: NS River Major (%i, %i)\n", x, y);
return false;
}
break;
}
// River size // Requires survey
// Waterfall
if (finder->min_waterfall > 0 &&
tile->river_size == embark_assist::defs::river_sizes::None) {
tile->min_river_size == embark_assist::defs::river_sizes::None) {
if (trace) out.print("matcher::world_tile_match: NS Waterfall (%i, %i)\n", x, y);
return false;
}

@ -88,6 +88,23 @@ namespace embark_assist {
//=======================================================================================
embark_assist::defs::river_sizes river_size_of(uint8_t width) {
if (width < 7) {
return embark_assist::defs::river_sizes::Stream;
}
else if (width < 13) {
return embark_assist::defs::river_sizes::Minor;
}
else if (width < 24) {
return embark_assist::defs::river_sizes::Medium;
}
else {
return embark_assist::defs::river_sizes::Major;
}
}
//=======================================================================================
bool geo_survey(embark_assist::defs::geo_data *geo_summary) {
color_ostream_proxy out(Core::getInstance().getConsole());
df::world_data *world_data = world->world_data;
@ -229,71 +246,6 @@ namespace embark_assist {
return true;
}
//=================================================================================
void survey_rivers(embark_assist::defs::world_tile_data *survey_results) {
// color_ostream_proxy out(Core::getInstance().getConsole());
df::world_data *world_data = world->world_data;
int16_t x;
int16_t y;
for (uint16_t i = 0; i < world_data->rivers.size(); i++) {
for (uint16_t k = 0; k < world_data->rivers[i]->path.x.size(); k++) {
x = world_data->rivers[i]->path.x[k];
y = world_data->rivers[i]->path.y[k];
if (world_data->rivers[i]->flow[k] < 5000) {
if (world_data->region_map[x][y].flags.is_set(df::region_map_entry_flags::is_brook)) {
survey_results->at(x).at(y).river_size = embark_assist::defs::river_sizes::Brook;
}
else {
survey_results->at(x).at(y).river_size = embark_assist::defs::river_sizes::Stream;
}
}
else if (world_data->rivers[i]->flow[k] < 10000) {
survey_results->at(x).at(y).river_size = embark_assist::defs::river_sizes::Minor;
}
else if (world_data->rivers[i]->flow[k] < 20000) {
survey_results->at(x).at(y).river_size = embark_assist::defs::river_sizes::Medium;
}
else {
survey_results->at(x).at(y).river_size = embark_assist::defs::river_sizes::Major;
}
}
x = world_data->rivers[i]->end_pos.x;
y = world_data->rivers[i]->end_pos.y;
// Make the guess the river size for the end is the same as the tile next to the end. Note that DF
// doesn't actually recognize this tile as part of the river in the pre embark river name display.
// We also assume the is_river/is_brook flags are actually set properly for the end tile.
//
if (x >= 0 && y >= 0 && x < world->worldgen.worldgen_parms.dim_x && y < world->worldgen.worldgen_parms.dim_y) {
if (survey_results->at(x).at(y).river_size == embark_assist::defs::river_sizes::None) {
if (world_data->rivers[i]->path.x.size() &&
world_data->rivers[i]->flow[world_data->rivers[i]->path.x.size() - 1] < 5000) {
if (world_data->region_map[x][y].flags.is_set(df::region_map_entry_flags::is_brook)) {
survey_results->at(x).at(y).river_size = embark_assist::defs::river_sizes::Brook;
}
else {
survey_results->at(x).at(y).river_size = embark_assist::defs::river_sizes::Stream;
}
}
else if (world_data->rivers[i]->flow[world_data->rivers[i]->path.x.size() - 1] < 10000) {
survey_results->at(x).at(y).river_size = embark_assist::defs::river_sizes::Minor;
}
else if (world_data->rivers[i]->flow[world_data->rivers[i]->path.x.size() - 1] < 20000) {
survey_results->at(x).at(y).river_size = embark_assist::defs::river_sizes::Medium;
}
else {
survey_results->at(x).at(y).river_size = embark_assist::defs::river_sizes::Major;
}
}
}
}
}
//=================================================================================
void survey_evil_weather(embark_assist::defs::world_tile_data *survey_results) {
@ -945,7 +897,6 @@ void embark_assist::survey::high_level_world_survey(embark_assist::defs::geo_dat
}
}
embark_assist::survey::survey_rivers(survey_results);
embark_assist::survey::survey_evil_weather(survey_results);
}
@ -1112,18 +1063,23 @@ void embark_assist::survey::survey_mid_level_tile(embark_assist::defs::geo_data
}
mlt->at(i).at(k).offset = offset;
mlt->at(i).at(k).elevation = details->elevation[i][k];
mlt->at(i).at(k).river_present = false;
mlt->at(i).at(k).river_size = embark_assist::defs::river_sizes::None;
mlt->at(i).at(k).river_elevation = 100;
if (details->rivers_vertical.active[i][k] != 0) {
mlt->at(i).at(k).river_present = true;
mlt->at(i).at(k).river_size = river_size_of (details->rivers_vertical.x_max[i][k] - details->rivers_vertical.x_min[i][k] + 1);
mlt->at(i).at(k).river_elevation = details->rivers_vertical.elevation[i][k];
}
else if (details->rivers_horizontal.active[i][k] != 0) {
mlt->at(i).at(k).river_present = true;
mlt->at(i).at(k).river_size = river_size_of (details->rivers_horizontal.y_max[i][k] - details->rivers_horizontal.y_min[i][k] + 1);
mlt->at(i).at(k).river_elevation = details->rivers_horizontal.elevation[i][k];
}
if (mlt->at(i).at(k).river_size != embark_assist::defs::river_sizes::None &&
world_tile->flags.is_set(df::region_map_entry_flags::is_brook)) {
mlt->at(i).at(k).river_size = embark_assist::defs::river_sizes::Brook;
}
if (tile->min_region_soil > mlt->at(i).at(k).soil_depth) {
tile->min_region_soil = mlt->at(i).at(k).soil_depth;
}
@ -1277,8 +1233,8 @@ void embark_assist::survey::survey_mid_level_tile(embark_assist::defs::geo_data
for (uint8_t k = 0; k < 15; k++) {
if (details->rivers_horizontal.active[i][k] != 0 &&
details->rivers_vertical.active[i - 1][k + 1] != 0 &&
!mlt->at(i - 1).at(k).river_present) { // Probably never true
mlt->at(i - 1).at(k).river_present = true;
mlt->at(i - 1).at(k).river_size == embark_assist::defs::river_sizes::None) { // Probably never true
mlt->at(i - 1).at(k).river_size = mlt->at(i).at(k).river_size;
mlt->at(i - 1).at(k).river_elevation = mlt->at(i).at(k).river_elevation;
if (mlt->at(i - 1).at(k).river_elevation > mlt->at(i - 1).at(k + 1).river_elevation) {
@ -1291,8 +1247,8 @@ void embark_assist::survey::survey_mid_level_tile(embark_assist::defs::geo_data
for (uint8_t i = 0; i < 16; i++) {
for (uint8_t k = 1; k < 16; k++) {
if (details->rivers_vertical.active[i][k] != 0 &&
!mlt->at(i).at(k - 1).river_present) {
mlt->at(i).at(k - 1).river_present = true;
mlt->at(i).at(k - 1).river_size == embark_assist::defs::river_sizes::None) {
mlt->at(i).at(k - 1).river_size = mlt->at(i).at(k).river_size;
mlt->at(i).at(k - 1).river_elevation = mlt->at(i).at(k).river_elevation;
}
}
@ -1301,8 +1257,8 @@ void embark_assist::survey::survey_mid_level_tile(embark_assist::defs::geo_data
for (uint8_t i = 1; i < 16; i++) {
for (uint8_t k = 0; k < 16; k++) {
if (details->rivers_horizontal.active[i][k] != 0 &&
!mlt->at(i - 1).at(k).river_present) {
mlt->at(i - 1).at(k).river_present = true;
mlt->at(i - 1).at(k).river_size == embark_assist::defs::river_sizes::None) {
mlt->at(i - 1).at(k).river_size = mlt->at(i).at(k).river_size;
mlt->at(i - 1).at(k).river_elevation = mlt->at(i).at(k).river_elevation;
}
}
@ -1338,9 +1294,18 @@ void embark_assist::survey::survey_mid_level_tile(embark_assist::defs::geo_data
survey_results->at(x).at(y).max_region_soil = mlt->at(i).at(k).soil_depth;
}
if (mlt->at(i).at(k).river_present) {
if (mlt->at(i).at(k).river_size != embark_assist::defs::river_sizes::None) {
if (survey_results->at(x).at(y).min_river_size == embark_assist::defs::river_sizes::None ||
mlt->at(i).at(k).river_size < survey_results->at(x).at(y).min_river_size) {
survey_results->at(x).at(y).min_river_size = mlt->at(i).at(k).river_size;
}
if (survey_results->at(x).at(y).max_river_size < mlt->at(i).at(k).river_size) {
survey_results->at(x).at(y).max_river_size = mlt->at(i).at(k).river_size;
}
if (i < 15 &&
mlt->at(i + 1).at(k).river_present &&
mlt->at(i + 1).at(k).river_size != embark_assist::defs::river_sizes::None &&
abs (mlt->at(i).at(k).river_elevation - mlt->at(i + 1).at(k).river_elevation) >
survey_results->at(x).at(y).max_waterfall) {
survey_results->at(x).at(y).max_waterfall =
@ -1348,7 +1313,7 @@ void embark_assist::survey::survey_mid_level_tile(embark_assist::defs::geo_data
}
if (k < 15 &&
mlt->at(i).at(k + 1).river_present &&
mlt->at(i).at(k + 1).river_size != embark_assist::defs::river_sizes::None &&
abs(mlt->at(i).at(k).river_elevation - mlt->at(i).at(k + 1).river_elevation) >
survey_results->at(x).at(y).max_waterfall) {
survey_results->at(x).at(y).max_waterfall =
@ -1356,7 +1321,6 @@ void embark_assist::survey::survey_mid_level_tile(embark_assist::defs::geo_data
}
}
// River size surveyed separately
// biome_index handled above
// biome handled below
// evil weather handled separately
@ -1442,10 +1406,10 @@ void embark_assist::survey::survey_mid_level_tile(embark_assist::defs::geo_data
tile->west_column[i].elevation = mlt->at(0).at(i).elevation;
tile->east_column[i].elevation = mlt->at(15).at(i).elevation;
tile->north_row[i].river_present = mlt->at(i).at(0).river_present; // Not used
tile->south_row[i].river_present = mlt->at(i).at(15).river_present;
tile->west_column[i].river_present = mlt->at(0).at(i).river_present;
tile->east_column[i].river_present = mlt->at(15).at(i).river_present;
tile->north_row[i].river_size = mlt->at(i).at(0).river_size; // Not used
tile->south_row[i].river_size = mlt->at(i).at(15).river_size;
tile->west_column[i].river_size = mlt->at(0).at(i).river_size;
tile->east_column[i].river_size = mlt->at(15).at(i).river_size;
tile->north_row[i].river_elevation = mlt->at(i).at(0).river_elevation; // Not used
tile->south_row[i].river_elevation = mlt->at(i).at(15).river_elevation;
@ -2325,9 +2289,9 @@ void embark_assist::survey::survey_embark(embark_assist::defs::mid_level_tiles *
site_info->flat = false;
}
if (mlt->at(i).at(k).river_present) {
if (mlt->at(i).at(k).river_size != embark_assist::defs::river_sizes::None) {
if (i < 15 &&
mlt->at(i + 1).at(k).river_present &&
mlt->at(i + 1).at(k).river_size != embark_assist::defs::river_sizes::None &&
abs(mlt->at(i).at(k).river_elevation - mlt->at(i + 1).at(k).river_elevation) >
site_info->max_waterfall) {
site_info->max_waterfall =
@ -2335,7 +2299,7 @@ void embark_assist::survey::survey_embark(embark_assist::defs::mid_level_tiles *
}
if (k < 15 &&
mlt->at(i).at(k + 1).river_present &&
mlt->at(i).at(k + 1).river_size != embark_assist::defs::river_sizes::None &&
abs(mlt->at(i).at(k).river_elevation - mlt->at(i).at(k + 1).river_elevation) >
site_info->max_waterfall) {
site_info->max_waterfall =