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

develop
lethosor 2018-07-13 19:58:27 -04:00
commit 210510591b
7 changed files with 281 additions and 35 deletions

@ -539,7 +539,7 @@ This plugin provides embark site selection help. It has to be run with the
extended (and correct(?)) resource information for the embark rectangle as well
as normally undisplayed sites in the current embark region. It also has a site
selection tool with more options than DF's vanilla search tool. For detailed
help invoke the in game info screen. Requires 46 lines to display properly.
help invoke the in game info screen.
.. _embark-tools:

@ -49,7 +49,10 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
## Misc Improvements
- Reduced time for designation jobs from tools like `digv` to be assigned workers
- `embark-assistant`: switched to standard scrolling keys, improved spacing slightly
- `embark-assistant`:
- Switched to standard scrolling keys, improved spacing slightly
- Introduced scrolling of Finder search criteria, removing requirement for 46 lines to work properly (Help/Info still formatted for 46 lines).
- Added Freezing search criterion, allowing searches for NA/Frozen/At_Least_Partial/Partial/At_Most_Partial/Never Freezing embarks.
- `rejuvenate`:
- Added ``-all`` argument to apply to all citizens
- Added ``-force`` to include units under 20 years old

@ -58,6 +58,8 @@ namespace embark_assist {
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;
int16_t min_temperature[10]; // Indexed through biome_offset; -30000 = null, Urists - 10000, [0] not used
int16_t max_temperature[10]; // Indexed through biome_offset; -30000 = null, Urists - 10000, [0] not used
bool blood_rain[10];
bool blood_rain_possible;
bool blood_rain_full;
@ -229,16 +231,14 @@ namespace embark_assist {
None
};
/* // Future possible enhancement
enum class freezing_ranges : int8_t {
NA = -1,
Permanent,
At_Least_Partial,
Partial,
At_Most_Partial,
Never
NA = -1,
Permanent,
At_Least_Partial,
Partial,
At_Most_Partial,
Never
};
*/
struct finders {
uint16_t x_dim;
@ -256,7 +256,7 @@ namespace embark_assist {
soil_ranges soil_min;
all_present_ranges soil_min_everywhere;
soil_ranges soil_max;
/*freezing_ranges freezing;*/
freezing_ranges freezing;
yes_no_ranges blood_rain; // Will probably blow up with the magic release arcs...
syndrome_rain_ranges syndrome_rain;
reanimation_ranges reanimation;

@ -12,6 +12,7 @@
#include "df/material_flags.h"
#include "df/viewscreen_choose_start_sitest.h"
#include "df/world.h"
#include "df/world_data.h"
#include "df/world_region_type.h"
#include "df/world_raws.h"
@ -46,6 +47,7 @@ namespace embark_assist {
soil_min,
soil_min_everywhere,
soil_max,
freezing,
blood_rain,
syndrome_rain,
reanimation,
@ -574,6 +576,52 @@ namespace embark_assist {
break;
case fields::freezing:
{
embark_assist::defs::freezing_ranges k = embark_assist::defs::freezing_ranges::NA;
while (true) {
switch (k) {
case embark_assist::defs::freezing_ranges::NA:
element->list.push_back({ "N/A", static_cast<int8_t>(k) });
break;
case embark_assist::defs::freezing_ranges::Permanent:
element->list.push_back({ "Permanent", static_cast<int8_t>(k) });
break;
case embark_assist::defs::freezing_ranges::At_Least_Partial:
element->list.push_back({ "At Least Partially Frozen", static_cast<int8_t>(k) });
break;
case embark_assist::defs::freezing_ranges::Partial:
element->list.push_back({ "Partially Frozen", static_cast<int8_t>(k) });
break;
case embark_assist::defs::freezing_ranges::At_Most_Partial:
element->list.push_back({ "At Most Partially Frozen", static_cast<int8_t>(k) });
break;
case embark_assist::defs::freezing_ranges::Never:
element->list.push_back({ "Never Frozen", static_cast<int8_t>(k) });
break;
}
if (k == embark_assist::defs::freezing_ranges::Never ||
(world->world_data->world_height != 17 && // Can't handle temperature in non standard height worlds.
world->world_data->world_height != 33 &&
world->world_data->world_height != 65 &&
world->world_data->world_height != 129 &&
world->world_data->world_height != 257)) {
break;
}
k = static_cast <embark_assist::defs::freezing_ranges>(static_cast<int8_t>(k) + 1);
}
}
break;
case fields::syndrome_rain:
{
embark_assist::defs::syndrome_rain_ranges k = embark_assist::defs::syndrome_rain_ranges::NA;
@ -917,6 +965,10 @@ namespace embark_assist {
state->finder_list.push_back({ "Min Soil Everywhere", static_cast<int8_t>(i) });
break;
case fields::freezing:
state->finder_list.push_back({ "Freezing", static_cast<int8_t>(i) });
break;
case fields::blood_rain:
state->finder_list.push_back({ "Blood Rain", static_cast<int8_t>(i) });
break;
@ -1141,6 +1193,11 @@ namespace embark_assist {
static_cast<embark_assist::defs::all_present_ranges>(state->ui[static_cast<uint8_t>(i)]->current_value);
break;
case fields::freezing:
finder.freezing =
static_cast<embark_assist::defs::freezing_ranges>(state->ui[static_cast<uint8_t>(i)]->current_value);
break;
case fields::blood_rain:
finder.blood_rain =
static_cast<embark_assist::defs::yes_no_ranges>(state->ui[static_cast<uint8_t>(i)]->current_value);
@ -1366,7 +1423,8 @@ namespace embark_assist {
void ViewscreenFindUi::render() {
// color_ostream_proxy out(Core::getInstance().getConsole());
auto screen_size = DFHack::Screen::getWindowSize();
const int list_column = 53;
uint16_t top_row = 2;
uint16_t list_column = 53;
uint16_t offset = 0;
Screen::clear();
@ -1391,34 +1449,50 @@ namespace embark_assist {
embark_assist::screen::paintString(lr_pen, 60, 1, DFHack::Screen::getKeyDisplay(df::interface_key::CUSTOM_L).c_str());
embark_assist::screen::paintString(white_pen, 61, 1, ": Load");
for (uint16_t i = 0; i < state->finder_list.size(); i++) {
// Implement scrolling lists if they don't fit on the screen.
if (int32_t(state->finder_list.size()) > screen_size.y - top_row - 1) {
offset = (screen_size.y - top_row - 1) / 2;
if (state->finder_list_focus < offset) {
offset = 0;
}
else {
offset = state->finder_list_focus - offset;
}
if (int32_t(state->finder_list.size() - offset) < screen_size.y - top_row - 1) {
offset = static_cast<uint16_t>(state->finder_list.size()) - (screen_size.y - top_row - 1);
}
}
for (uint16_t i = offset; i < state->finder_list.size(); i++) {
if (i == state->finder_list_focus) {
if (state->finder_list_active) {
embark_assist::screen::paintString(active_pen, 1, 2 + i, state->finder_list[i].text);
embark_assist::screen::paintString(active_pen, 1, top_row + i - offset, state->finder_list[i].text);
}
else {
embark_assist::screen::paintString(passive_pen, 1, 2 + i, state->finder_list[i].text);
embark_assist::screen::paintString(passive_pen, 1, top_row + i - offset, state->finder_list[i].text);
}
embark_assist::screen::paintString(active_pen,
21,
2 + i,
top_row + i - offset,
state->ui[i]->list[state->ui[i]->current_display_value].text);
}
else {
embark_assist::screen::paintString(normal_pen, 1, 2 + i, state->finder_list[i].text);
embark_assist::screen::paintString(normal_pen, 1, top_row + i - offset, state->finder_list[i].text);
embark_assist::screen::paintString(white_pen,
21,
2 + i,
top_row + i - offset,
state->ui[i]->list[state->ui[i]->current_display_value].text);
}
}
// Implement scrolling lists if they don't fit on the screen.
if (int32_t(state->ui[state->finder_list_focus]->list.size()) > screen_size.y - 3) {
offset = (screen_size.y - 3) / 2;
offset = 0;
if (int32_t(state->ui[state->finder_list_focus]->list.size()) > screen_size.y - top_row - 1) {
offset = (screen_size.y - top_row - 1) / 2;
if (state->ui[state->finder_list_focus]->current_index < offset) {
offset = 0;
}
@ -1426,22 +1500,22 @@ namespace embark_assist {
offset = state->ui[state->finder_list_focus]->current_index - offset;
}
if (int32_t(state->ui[state->finder_list_focus]->list.size() - offset) < screen_size.y - 3) {
offset = static_cast<uint16_t>(state->ui[state->finder_list_focus]->list.size()) - (screen_size.y - 3);
if (int32_t(state->ui[state->finder_list_focus]->list.size() - offset) < screen_size.y - top_row - 1) {
offset = static_cast<uint16_t>(state->ui[state->finder_list_focus]->list.size()) - (screen_size.y - top_row - 1);
}
}
for (uint16_t i = 0; i < state->ui[state->finder_list_focus]->list.size(); i++) {
for (uint16_t i = offset; i < state->ui[state->finder_list_focus]->list.size(); i++) {
if (i == state->ui[state->finder_list_focus]->current_index) {
if (!state->finder_list_active) { // Negated expression to get the display lines in the same order as above.
embark_assist::screen::paintString(active_pen, list_column, 2 + i - offset, state->ui[state->finder_list_focus]->list[i].text);
embark_assist::screen::paintString(active_pen, list_column, top_row + i - offset, state->ui[state->finder_list_focus]->list[i].text);
}
else {
embark_assist::screen::paintString(passive_pen, list_column, 2 + i - offset, state->ui[state->finder_list_focus]->list[i].text);
embark_assist::screen::paintString(passive_pen, list_column, top_row + i - offset, state->ui[state->finder_list_focus]->list[i].text);
}
}
else {
embark_assist::screen::paintString(normal_pen, list_column, 2 + i - offset, state->ui[state->finder_list_focus]->list[i].text);
embark_assist::screen::paintString(normal_pen, list_column, top_row + i - offset, state->ui[state->finder_list_focus]->list[i].text);
}
}

@ -108,10 +108,10 @@ namespace embark_assist{
help_text.push_back("- Site find search. Richer set of selection criteria than the vanilla");
help_text.push_back(" DF Find that Embark Assistant suppresses (by using the same key).");
help_text.push_back("");
help_text.push_back("The functionality requires a screen height of at least 46 lines to display");
help_text.push_back("correctly (that's the height of the Finder screen), as fitting everything");
help_text.push_back("onto a standard 80*25 screen would be too challenging. The help is adjusted");
help_text.push_back("to fit into onto an 80*46 screen as well.");
help_text.push_back("The functionality requires a screen height larger than the default 80*25,");
help_text.push_back("and while the Finder screen provides for scrolling, the embark resources");
help_text.push_back("list will spill over the bottom if many resources are present and the");
help_text.push_back("screen isn't deep enough. This help info is adapted to fit onto 80*46.");
help_text.push_back("This help/info is split over several screens, and you can move between them");
help_text.push_back("using the TAB/Shift-TAB keys, and leave the help from any screen using ESC.");
help_text.push_back("");
@ -209,6 +209,9 @@ namespace embark_assist{
help_text.push_back("Min/Max soil uses the same terminology as DF for 1-4. The Min Soil");
help_text.push_back("Everywhere toggles the Min Soil parameter between acting as All and");
help_text.push_back("and Present.");
help_text.push_back("Freezing allows you to select embarks to select/avoid various freezing");
help_text.push_back("conditions. Note that the minimum temperature is held for only 10 ticks");
help_text.push_back("in many embarks.");
help_text.push_back("Syndrome Rain allows you to search for Permanent and Temporary syndromes,");
help_text.push_back("where Permanent allows for Temporary ones as well, but not the reverse, as");
help_text.push_back("Not Permanent matches everything except Permanent syndromes.");
@ -261,7 +264,7 @@ namespace embark_assist{
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.4 2018-06-21");
help_text.push_back("Version 0.5 2018-07-13");
break;
}

@ -48,6 +48,8 @@ namespace embark_assist {
bool flux_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];
int16_t max_temperature = survey_results->at(x).at(y).max_temperature[mlt->at(start_x).at(start_y).biome_offset];
bool blood_rain_found = false;
bool permanent_syndrome_rain_found = false;
bool temporary_syndrome_rain_found = false;
@ -185,6 +187,21 @@ namespace embark_assist {
if (finder->soil_max != embark_assist::defs::soil_ranges::NA &&
mlt->at(i).at(k).soil_depth > static_cast<uint16_t>(finder->soil_max)) return false;
// Freezing
if (min_temperature > survey_results->at(x).at(y).min_temperature[mlt->at(i).at(k).biome_offset]) {
min_temperature = survey_results->at(x).at(y).min_temperature[mlt->at(i).at(k).biome_offset];
}
if (max_temperature < survey_results->at(x).at(y).max_temperature[mlt->at(i).at(k).biome_offset]) {
max_temperature = survey_results->at(x).at(y).max_temperature[mlt->at(i).at(k).biome_offset];
}
if (min_temperature <= 0 &&
finder->freezing == embark_assist::defs::freezing_ranges::Never) return false;
if (max_temperature > 0 &&
finder->freezing == embark_assist::defs::freezing_ranges::Permanent) return false;
// Blood Rain
if (survey_results->at(x).at(y).blood_rain[mlt->at(i).at(k).biome_offset]) {
if (finder->blood_rain == embark_assist::defs::yes_no_ranges::No) return false;
@ -323,6 +340,17 @@ namespace embark_assist {
finder->soil_min_everywhere == embark_assist::defs::all_present_ranges::Present &&
max_soil < static_cast<uint8_t>(finder->soil_min)) return false;
// Freezing
if (finder->freezing == embark_assist::defs::freezing_ranges::At_Least_Partial &&
min_temperature > 0) return false;
if (finder->freezing == embark_assist::defs::freezing_ranges::Partial &&
(min_temperature > 0 ||
max_temperature <= 0)) return false;
if (finder->freezing == embark_assist::defs::freezing_ranges::At_Most_Partial &&
max_temperature <= 0) return false;
// Blood Rain
if (finder->blood_rain == embark_assist::defs::yes_no_ranges::Yes && !blood_rain_found) return false;
@ -415,7 +443,7 @@ namespace embark_assist {
uint16_t y,
embark_assist::defs::finders *finder) {
// color_ostream_proxy out(Core::getInstance().getConsole());
color_ostream_proxy out(Core::getInstance().getConsole());
df::world_data *world_data = world->world_data;
embark_assist::defs::region_tile_datum *tile = &survey_results->at(x).at(y);
const uint16_t embark_size = finder->x_dim * finder->y_dim;
@ -622,6 +650,61 @@ namespace embark_assist {
break;
}
// Freezing
if (finder->freezing != embark_assist::defs::freezing_ranges::NA)
{
int16_t max_max_temperature = tile->max_temperature[5];
int16_t min_max_temperature = tile->max_temperature[5];
int16_t max_min_temperature = tile->min_temperature[5];
int16_t min_min_temperature = tile->min_temperature[5];
for (uint8_t i = 1; i < 10; i++) {
if (tile->max_temperature[i] > max_max_temperature) {
max_max_temperature = tile->max_temperature[i];
}
if (tile->max_temperature[i] != - 30000 &&
tile->max_temperature[i] < min_max_temperature) {
min_max_temperature = tile->max_temperature[i];
}
if (tile->min_temperature[i] != -30000 &&
tile->min_temperature[i] < min_min_temperature) {
min_min_temperature = tile->min_temperature[i];
}
if (tile->min_temperature[i] > max_min_temperature) {
max_min_temperature = tile->min_temperature[i];
}
}
switch (finder->freezing) {
case embark_assist::defs::freezing_ranges::NA:
break; // Excluded above, but the Travis complains if it's not here.
case embark_assist::defs::freezing_ranges::Permanent:
if (min_max_temperature > 0) return false;
break;
case embark_assist::defs::freezing_ranges::At_Least_Partial:
if (min_min_temperature > 0) return false;
break;
case embark_assist::defs::freezing_ranges::Partial:
if (min_min_temperature > 0 ||
max_max_temperature <= 0) return false;
break;
case embark_assist::defs::freezing_ranges::At_Most_Partial:
if (max_max_temperature <= 0) return false;
break;
case embark_assist::defs::freezing_ranges::Never:
if (max_min_temperature <= 0) return false;
break;
}
}
// Blood Rain
switch (finder->blood_rain) {
case embark_assist::defs::yes_no_ranges::NA:

@ -1,3 +1,4 @@
#include <math.h>
#include <vector>
#include "Core.h"
@ -399,6 +400,67 @@ namespace embark_assist {
}
}
}
//=================================================================================
int16_t min_temperature(int16_t max_temperature, uint16_t latitude) {
uint16_t divisor;
uint16_t steps;
uint16_t lat;
if (world->world_data->flip_latitude == df::world_data::T_flip_latitude::None) {
return max_temperature;
}
else if (world->world_data->flip_latitude == df::world_data::T_flip_latitude::North ||
world->world_data->flip_latitude == df::world_data::T_flip_latitude::South) {
steps = world->world_data->world_height / 2;
if (latitude > steps) {
lat = world->world_data->world_height - 1 - latitude;
}
else
{
lat = latitude;
}
}
else { // Both
steps = world->world_data->world_height / 4;
if (latitude < steps) {
lat = latitude;
}
else if (latitude <= steps * 2) {
lat = steps * 2 - latitude;
}
else if (latitude <= steps * 3) {
lat = latitude - steps * 2;
}
else {
lat = world->world_data->world_height - latitude;
}
}
if (world->world_data->world_height == 17) {
divisor = (57 / steps * lat + 0.4);
}
else if (world->world_data->world_height == 33) {
divisor = (61 / steps * lat + 0.1);
}
else if (world->world_data->world_height == 65) {
divisor = (63 / steps * lat);
}
else if (world->world_data->world_height == 129 ||
world->world_data->world_height == 257) {
divisor = (64 / steps * lat);
}
else {
return max_temperature; // Not any standard world height. No formula available
}
return max_temperature - ceil(divisor * 3 / 4);
}
}
}
@ -450,7 +512,10 @@ void embark_assist::survey::clear_results(embark_assist::defs::match_results *ma
void embark_assist::survey::high_level_world_survey(embark_assist::defs::geo_data *geo_summary,
embark_assist::defs::world_tile_data *survey_results) {
// color_ostream_proxy out(Core::getInstance().getConsole());
// color_ostream_proxy out(Core::getInstance().getConsole());
int16_t temperature;
bool negative;
embark_assist::survey::geo_survey(geo_summary);
for (uint16_t i = 0; i < world->worldgen.worldgen_parms.dim_x; i++) {
@ -488,6 +553,23 @@ void embark_assist::survey::high_level_world_survey(embark_assist::defs::geo_dat
results.biome_index[l] = world_data->region_map[adjusted.x][adjusted.y].region_id;
results.biome[l] = get_biome_type(adjusted.x, adjusted.y, k);
temperature = world_data->region_map[adjusted.x][adjusted.y].temperature;
negative = temperature < 0;
if (negative) {
temperature = -temperature;
}
results.max_temperature[l] = (temperature / 4) * 3;
if (temperature % 4 > 1) {
results.max_temperature[l] = results.max_temperature[l] + temperature % 4 - 1;
}
if (negative) {
results.max_temperature[l] = -results.max_temperature[l];
}
results.min_temperature[l] = min_temperature(results.max_temperature[l], adjusted.y);
geo_index = world_data->region_map[adjusted.x][adjusted.y].geo_index;
if (!geo_summary->at(geo_index).aquifer_absent) results.aquifer_count++;
@ -518,6 +600,8 @@ void embark_assist::survey::high_level_world_survey(embark_assist::defs::geo_dat
else {
results.biome_index[l] = -1;
results.biome[l] = -1;
results.max_temperature[l] = -30000;
results.min_temperature[l] = -30000;
}
}
@ -1109,7 +1193,6 @@ void embark_assist::survey::survey_embark(embark_assist::defs::mid_level_tiles *
if (i == state->local_min_x && k == state->local_min_y) {
elevation = mlt->at(i).at(k).elevation;
}
else if (elevation != mlt->at(i).at(k).elevation) {
site_info->flat = false;