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

develop
lethosor 2018-03-14 09:24:47 -04:00
commit 1e7a38f0b1
7 changed files with 404 additions and 38 deletions

@ -33,6 +33,8 @@ namespace embark_assist {
int16_t elevation;
bool river_present = false;
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
int8_t biome_offset;
uint8_t savagery_level; // 0 - 2
uint8_t evilness_level; // 0 - 2
@ -42,7 +44,6 @@ namespace embark_assist {
};
typedef std::array<std::array<mid_level_tile, 16>, 16> mid_level_tiles;
// typedef mid_level_tile mid_level_tiles[16][16];
struct region_tile_datum {
bool surveyed = false;
@ -53,7 +54,6 @@ namespace embark_assist {
uint8_t min_region_soil = 10;
uint8_t max_region_soil = 0;
bool waterfall = false;
river_sizes river_size;
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
@ -162,6 +162,23 @@ namespace embark_assist {
Major
};
// For possible future use. That's the level of data actually collected.
// enum class adamantine_ranges : int8_t {
// NA = -1,
// Cavern_1,
// Cavern_2,
// Cavern_3,
// Magma_Sea
// };
enum class magma_ranges : int8_t {
NA = -1,
Cavern_3,
Cavern_2,
Cavern_1,
Volcano
};
enum class yes_no_ranges : int8_t {
NA = -1,
Yes,
@ -218,6 +235,10 @@ namespace embark_assist {
yes_no_ranges evil_weather; // Will probably blow up with the magic release arcs...
yes_no_ranges reanimation;
yes_no_ranges thralling;
int8_t spire_count_min; // N/A(-1), 0-9
int8_t spire_count_max; // N/A(-1), 0-9
magma_ranges magma_min;
magma_ranges magma_max;
int8_t biome_count_min; // N/A(-1), 1-9
int8_t biome_count_max; // N/A(-1), 1-9
int8_t region_type_1; // N/A(-1), df::world_region_type

@ -143,7 +143,7 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector <Plugi
" the embark rectangle as well as normally undisplayed sites in the\n"
" current embark region. It also has a site selection tool with more\n"
" options than DF's vanilla search tool. For detailed help invoke the\n"
" in game info screen. Requires 42 lines to display properly.\n"
" in game info screen. Requires 46 lines to display properly.\n"
));
return CR_OK;
}

@ -1,3 +1,4 @@
#include <stdio.h>
#include "Core.h"
#include <Console.h>
@ -5,6 +6,7 @@
#include "Types.h"
#include "MemAccess.h"
#include "df/biome_type.h"
#include "df/inorganic_raw.h"
#include "df/material_flags.h"
@ -19,6 +21,8 @@
using df::global::world;
#define profile_file_name "./data/init/embark_assistant_profile.txt"
namespace embark_assist {
namespace finder_ui {
@ -45,6 +49,10 @@ namespace embark_assist {
evil_weather,
reanimation,
thralling,
spire_count_min,
spire_count_max,
magma_min,
magma_max,
biome_count_min,
biome_count_max,
region_type_1,
@ -136,6 +144,154 @@ namespace embark_assist {
//==========================================================================================================
void save_profile() {
color_ostream_proxy out(Core::getInstance().getConsole());
FILE* outfile = fopen(profile_file_name, "w");
fields i = first_fields;
while (true) {
for (int k = 0; k < state->ui[static_cast<int8_t>(i)]->list.size(); k++) {
if (state->ui[static_cast<int8_t>(i)]->current_value == state->ui[static_cast<int8_t>(i)]->list[k].key) {
fprintf(outfile, "[%s:%s]\n", state->finder_list[static_cast<int8_t>(i)].text.c_str(), state->ui[static_cast<int8_t>(i)]->list[k].text.c_str());
break;
}
}
// fprintf(outfile, "[%s:%i]\n", state->finder_list[static_cast<int8_t>(i)].text.c_str(), state->ui[static_cast<int8_t>(i)]->current_value);
if (i == last_fields) {
break; // done
}
i = static_cast <fields>(static_cast<int8_t>(i) + 1);
}
fclose(outfile);
}
//==========================================================================================================
void load_profile() {
color_ostream_proxy out(Core::getInstance().getConsole());
FILE* infile = fopen(profile_file_name, "r");
if (!infile) {
out.printerr("No profile file found at %s\n", profile_file_name);
return;
}
fields i = first_fields;
char line[80];
int count = 80;
bool found;
while (true) {
fgets(line, count, infile);
if (line[0] != '[') {
out.printerr("Failed to find token start '[' at line %i\n", static_cast<int8_t>(i));
fclose(infile);
return;
}
for (int k = 1; k < count; k++) {
if (line[k] == ':') {
for (int l = 1; l < k; l++) {
if (state->finder_list[static_cast<int8_t>(i)].text.c_str()[l - 1] != line[l]) {
out.printerr("Token mismatch of %s vs %s\n", line, state->finder_list[static_cast<int8_t>(i)].text.c_str());
fclose(infile);
return;
}
}
found = false;
for (int l = 0; l < state->ui[static_cast<int8_t>(i)]->list.size(); l++) {
for (int m = k + 1; m < count; m++) {
if (state->ui[static_cast<int8_t>(i)]->list[l].text.c_str()[m - (k + 1)] != line[m]) {
if (state->ui[static_cast<int8_t>(i)]->list[l].text.c_str()[m - (k + 1)] == '\0' &&
line[m] == ']') {
found = true;
}
break;
}
}
if (found) {
break;
}
}
if (!found) {
out.printerr("Value extraction failure from %s\n", line);
fclose(infile);
return;
}
break;
}
}
if (!found) {
out.printerr("Value delimiter not found in %s\n", line);
fclose(infile);
return;
}
if (i == last_fields) {
break; // done
}
i = static_cast <fields>(static_cast<int8_t>(i) + 1);
}
fclose(infile);
// Checking done. No do the work.
infile = fopen(profile_file_name, "r");
i = first_fields;
while (true) {
fgets(line, count, infile);
for (int k = 1; k < count; k++) {
if (line[k] == ':') {
found = false;
for (int l = 0; l < state->ui[static_cast<int8_t>(i)]->list.size(); l++) {
for (int m = k + 1; m < count; m++) {
if (state->ui[static_cast<int8_t>(i)]->list[l].text.c_str()[m - (k + 1)] != line[m]) {
if (state->ui[static_cast<int8_t>(i)]->list[l].text.c_str()[m - (k + 1)] == '\0' &&
line[m] == ']') {
state->ui[static_cast<int8_t>(i)]->current_value = state->ui[static_cast<int8_t>(i)]->list[l].key;
state->ui[static_cast<int8_t>(i)]->current_display_value = l;
found = true;
}
break;
}
}
if (found) {
break;
}
}
break;
}
}
if (i == last_fields) {
break; // done
}
i = static_cast <fields>(static_cast<int8_t>(i) + 1);
}
fclose(infile);
}
//==========================================================================================================
void ui_setup(embark_assist::defs::find_callbacks find_callback, uint16_t max_inorganic) {
// color_ostream_proxy out(Core::getInstance().getConsole());
if (!embark_assist::finder_ui::state) {
@ -419,6 +575,56 @@ namespace embark_assist {
break;
case fields::spire_count_min:
case fields::spire_count_max:
for (int16_t k = -1; k <= 9; k++) {
if (k == -1) {
element->list.push_back({ "N/A", k });
}
else {
element->list.push_back({ std::to_string(k), k });
}
}
break;
case fields::magma_min:
case fields::magma_max:
{
embark_assist::defs::magma_ranges k = embark_assist::defs::magma_ranges::NA;
while (true) {
switch (k) {
case embark_assist::defs::magma_ranges::NA:
element->list.push_back({ "N/A", static_cast<int8_t>(k) });
break;
case embark_assist::defs::magma_ranges::Cavern_3:
element->list.push_back({ "Third Cavern", static_cast<int8_t>(k) });
break;
case embark_assist::defs::magma_ranges::Cavern_2:
element->list.push_back({ "Second Cavern", static_cast<int8_t>(k) });
break;
case embark_assist::defs::magma_ranges::Cavern_1:
element->list.push_back({ "Third Cavern", static_cast<int8_t>(k) });
break;
case embark_assist::defs::magma_ranges::Volcano:
element->list.push_back({ "Volcano", static_cast<int8_t>(k) });
break;
}
if (k == embark_assist::defs::magma_ranges::Volcano) {
break;
}
k = static_cast <embark_assist::defs::magma_ranges>(static_cast<int8_t>(k) + 1);
}
}
break;
case fields::biome_count_min:
case fields::biome_count_max:
for (int16_t k = 0; k < 10; k++) {
@ -659,6 +865,22 @@ namespace embark_assist {
state->finder_list.push_back({ "Max Soil", static_cast<int8_t>(i) });
break;
case fields::spire_count_min:
state->finder_list.push_back({ "Min Adamantine", static_cast<int8_t>(i) });
break;
case fields::spire_count_max:
state->finder_list.push_back({ "Max Adamantine", static_cast<int8_t>(i) });
break;
case fields::magma_min:
state->finder_list.push_back({ "Min Magma", static_cast<int8_t>(i) });
break;
case fields::magma_max:
state->finder_list.push_back({ "Max Magma", static_cast<int8_t>(i) });
break;
case fields::biome_count_min:
state->finder_list.push_back({ "Min Biome Count", static_cast<int8_t>(i) });
break;
@ -875,6 +1097,24 @@ namespace embark_assist {
static_cast<embark_assist::defs::soil_ranges>(state->ui[static_cast<uint8_t>(i)]->current_value);
break;
case fields::spire_count_min:
finder.spire_count_min = state->ui[static_cast<uint8_t>(i)]->current_value;
break;
case fields::spire_count_max:
finder.spire_count_max = state->ui[static_cast<uint8_t>(i)]->current_value;
break;
case fields::magma_min:
finder.magma_min =
static_cast<embark_assist::defs::magma_ranges>(state->ui[static_cast<uint8_t>(i)]->current_value);
break;
case fields::magma_max:
finder.magma_max =
static_cast<embark_assist::defs::magma_ranges>(state->ui[static_cast<uint8_t>(i)]->current_value);
break;
case fields::biome_count_min:
finder.biome_count_min = state->ui[static_cast<uint8_t>(i)]->current_value;
break;
@ -1015,17 +1255,25 @@ namespace embark_assist {
state->ui[state->finder_list_focus]->current_index = 0;
}
}
} else if (input->count(df::interface_key::SELECT)) {
if (!state->finder_list_active) {
state->ui[state->finder_list_focus]->current_display_value = state->ui[state->finder_list_focus]->current_index;
state->ui[state->finder_list_focus]->current_value = state->ui[state->finder_list_focus]->list[state->ui[state->finder_list_focus]->current_index].key;
state->finder_list_active = true;
}
} else if (input->count(df::interface_key::CUSTOM_F)) {
input->clear();
Screen::dismiss(this);
find();
return;
} else if (input->count(df::interface_key::CUSTOM_S)) { // Save
save_profile();
} else if (input->count(df::interface_key::CUSTOM_L)) { // Load
load_profile();
}
}
@ -1040,16 +1288,24 @@ namespace embark_assist {
Screen::clear();
Screen::drawBorder("Embark Assistant Site Finder");
embark_assist::screen::paintString(lr_pen, 1, 1, "4/6");
embark_assist::screen::paintString(white_pen, 4, 1, ":Shift list");
embark_assist::screen::paintString(lr_pen, 16, 1, "8/2");
embark_assist::screen::paintString(white_pen, 19, 1, ":Up/down");
embark_assist::screen::paintString(lr_pen, 28, 1, "ENTER");
embark_assist::screen::paintString(white_pen, 33, 1, ":Select item");
embark_assist::screen::paintString(lr_pen, 46, 1, "f");
embark_assist::screen::paintString(white_pen, 47, 1, ":Find");
embark_assist::screen::paintString(lr_pen, 53, 1, "ESC");
embark_assist::screen::paintString(white_pen, 56, 1, ":Abort");
embark_assist::screen::paintString(lr_pen, 1, 1, DFHack::Screen::getKeyDisplay(df::interface_key::CURSOR_LEFT).c_str());
embark_assist::screen::paintString(white_pen, 2, 1, "/");
embark_assist::screen::paintString(lr_pen, 3, 1, DFHack::Screen::getKeyDisplay(df::interface_key::CURSOR_RIGHT).c_str());
embark_assist::screen::paintString(white_pen, 4, 1, ":\x1b/\x1a");
embark_assist::screen::paintString(lr_pen, 9, 1, DFHack::Screen::getKeyDisplay(df::interface_key::CURSOR_UP).c_str());
embark_assist::screen::paintString(white_pen, 10, 1, "/");
embark_assist::screen::paintString(lr_pen, 11, 1, DFHack::Screen::getKeyDisplay(df::interface_key::CURSOR_DOWN).c_str());
embark_assist::screen::paintString(white_pen, 12, 1, ":Up/Down");
embark_assist::screen::paintString(lr_pen, 21, 1, DFHack::Screen::getKeyDisplay(df::interface_key::SELECT).c_str());
embark_assist::screen::paintString(white_pen, 26, 1, ":Select");
embark_assist::screen::paintString(lr_pen, 34, 1, DFHack::Screen::getKeyDisplay(df::interface_key::CUSTOM_F).c_str());
embark_assist::screen::paintString(white_pen, 35, 1, ":Find");
embark_assist::screen::paintString(lr_pen, 41, 1, DFHack::Screen::getKeyDisplay(df::interface_key::LEAVESCREEN).c_str());
embark_assist::screen::paintString(white_pen, 44, 1, ":Abort");
embark_assist::screen::paintString(lr_pen, 51, 1, DFHack::Screen::getKeyDisplay(df::interface_key::CUSTOM_S).c_str());
embark_assist::screen::paintString(white_pen, 52, 1, ":Save");
embark_assist::screen::paintString(lr_pen, 58, 1, DFHack::Screen::getKeyDisplay(df::interface_key::CUSTOM_L).c_str());
embark_assist::screen::paintString(white_pen, 59, 1, ":Load");
for (uint16_t i = 0; i < state->finder_list.size(); i++) {
if (i == state->finder_list_focus) {

@ -109,10 +109,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 42 lines to display");
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*42 screen.");
help_text.push_back("to fit into onto an 80*46 screen as well.");
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("");
@ -188,6 +188,9 @@ namespace embark_assist{
help_text.push_back("ENTER to select a value in the value list, entering it among the selections.");
help_text.push_back("f to activate the Find functionality using the values in the middle column.");
help_text.push_back("ESC to leave the screen without activating a Find operation.");
help_text.push_back("s/l is used to save/load search profile to/from embark_assistant_profile.txt");
help_text.push_back("stored in ./data/init. There's some minor error detection that will refuse");
help_text.push_back("to load a file that doesn't check out.");
help_text.push_back("The X and Y dimensions are those of the embark to search for. Unlike DF");
help_text.push_back("itself these parameters are initiated to match the actual embark rectangle");
help_text.push_back("when a new search is initiated (prior results are cleared.");
@ -211,7 +214,7 @@ namespace embark_assist{
help_text.push_back("feature is Present in the embark, and entering the same value multiple");
help_text.push_back("times does nothing (the first match ticks all requirements off). It can be");
help_text.push_back("noted that all the Economic materials are found in the much longer Mineral");
help_text.push_back("list. Note that Find is a fairly time consuming task (is it is in vanilla).");
help_text.push_back("list. Note that Find is a fairly time consuming task (as it is in vanilla).");
break;
case pages::Caveats:
@ -250,15 +253,21 @@ namespace embark_assist{
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("Version 0.1 2017-08-30");
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. 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.3 2018-02-26");
break;
}
// Add control keys to first line.
embark_assist::screen::paintString(pen_lr, 1, 1, "TAB/Shift-TAB");
embark_assist::screen::paintString(pen_lr, 1, 1, DFHack::Screen::getKeyDisplay(df::interface_key::CHANGETAB).c_str());
embark_assist::screen::paintString(pen, 4, 1, "/");
embark_assist::screen::paintString(pen_lr, 5, 1, DFHack::Screen::getKeyDisplay(df::interface_key::SEC_CHANGETAB).c_str());
embark_assist::screen::paintString(pen, 14, 1, ":Next/Previous Page");
embark_assist::screen::paintString(pen_lr, 34, 1, "ESC");
embark_assist::screen::paintString(pen_lr, 34, 1, DFHack::Screen::getKeyDisplay(df::interface_key::LEAVESCREEN).c_str());
embark_assist::screen::paintString(pen, 37, 1, ":Leave Info/Help");
for (uint16_t i = 0; i < help_text.size(); i++) {
@ -267,10 +276,10 @@ namespace embark_assist{
switch (current_page) {
case pages::Intro:
embark_assist::screen::paintString(pen_lr, 1, 26, "i");
embark_assist::screen::paintString(pen_lr, 1, 27, "f");
embark_assist::screen::paintString(pen_lr, 1, 28, "c");
embark_assist::screen::paintString(pen_lr, 1, 30, "q");
embark_assist::screen::paintString(pen_lr, 1, 26, DFHack::Screen::getKeyDisplay(df::interface_key::CUSTOM_I).c_str());
embark_assist::screen::paintString(pen_lr, 1, 27, DFHack::Screen::getKeyDisplay(df::interface_key::CUSTOM_F).c_str());
embark_assist::screen::paintString(pen_lr, 1, 28, DFHack::Screen::getKeyDisplay(df::interface_key::CUSTOM_C).c_str());
embark_assist::screen::paintString(pen_lr, 1, 30, DFHack::Screen::getKeyDisplay(df::interface_key::CUSTOM_Q).c_str());
break;
case pages::General:
@ -285,11 +294,15 @@ namespace embark_assist{
break;
case pages::Finder:
embark_assist::screen::paintString(pen_lr, 1, 4, "4/6");
embark_assist::screen::paintString(pen_lr, 1, 5, "8/2");
embark_assist::screen::paintString(pen_lr, 1, 6, "ENTER");
embark_assist::screen::paintString(pen_lr, 1, 7, "f");
embark_assist::screen::paintString(pen_lr, 1, 8, "ESC");
embark_assist::screen::paintString(pen_lr, 1, 4, DFHack::Screen::getKeyDisplay(df::interface_key::CURSOR_LEFT).c_str());
embark_assist::screen::paintString(pen_lr, 3, 4, DFHack::Screen::getKeyDisplay(df::interface_key::CURSOR_RIGHT).c_str());
embark_assist::screen::paintString(pen_lr, 1, 5, DFHack::Screen::getKeyDisplay(df::interface_key::CURSOR_UP).c_str());
embark_assist::screen::paintString(pen_lr, 3, 5, DFHack::Screen::getKeyDisplay(df::interface_key::CURSOR_DOWN).c_str());
embark_assist::screen::paintString(pen_lr, 1, 6, DFHack::Screen::getKeyDisplay(df::interface_key::SELECT).c_str());
embark_assist::screen::paintString(pen_lr, 1, 7, DFHack::Screen::getKeyDisplay(df::interface_key::CUSTOM_F).c_str());
embark_assist::screen::paintString(pen_lr, 1, 8, DFHack::Screen::getKeyDisplay(df::interface_key::LEAVESCREEN).c_str());
embark_assist::screen::paintString(pen_lr, 1, 9, DFHack::Screen::getKeyDisplay(df::interface_key::CUSTOM_S).c_str());
embark_assist::screen::paintString(pen_lr, 3, 9, DFHack::Screen::getKeyDisplay(df::interface_key::CUSTOM_L).c_str());
break;
case pages::Caveats:

@ -51,6 +51,8 @@ namespace embark_assist {
bool evil_weather_found = false;
bool reanimation_found = false;
bool thralling_found = false;
uint8_t spire_count = 0;
int8_t magma_level = -1;
bool biomes[ENUM_LAST_ITEM(biome_type) + 1];
bool region_types[ENUM_LAST_ITEM(world_region_type) + 1];
uint8_t biome_count;
@ -199,6 +201,24 @@ namespace embark_assist {
thralling_found = true;
}
// Spires
if (mlt->at(i).at(k).adamantine_level != -1) {
spire_count++;
if (finder->spire_count_max != -1 &&
finder->spire_count_max < spire_count) return false;
}
// Magma
if (mlt->at(i).at(k).magma_level != -1) {
if (mlt->at(i).at(k).magma_level > magma_level)
{
magma_level = mlt->at(i).at(k).magma_level;
if (finder->magma_max != embark_assist::defs::magma_ranges::NA &&
static_cast<int8_t>(finder->magma_max) < magma_level) return false;
}
}
// Biomes
biomes[survey_results->at(x).at(y).biome[mlt->at(i).at(k).biome_offset]] = true;
@ -292,6 +312,14 @@ namespace embark_assist {
// Thralling
if (finder->thralling == embark_assist::defs::yes_no_ranges::Yes && !thralling_found) return false;
// Spires
if (finder->spire_count_min != -1 && finder->spire_count_min > spire_count) return false;
if (finder->spire_count_max != -1 && finder->spire_count_max < spire_count) return false;
// Magma
if (// finder->magma_min != embark_assist::defs::magma_ranges::NA && // This check is redundant.
finder->magma_min > static_cast<embark_assist::defs::magma_ranges>(magma_level)) return false;
// Biomes
if (finder->biome_count_min != -1 ||
finder->biome_count_max != -1) {
@ -612,6 +640,8 @@ namespace embark_assist {
break;
}
// Spire Count Min/Max
// Magma Min/Max
// Biome Count Min (Can't do anything with Max at this level)
if (finder->biome_count_min > tile->biome_count) return false;
@ -964,6 +994,8 @@ namespace embark_assist {
break;
}
// Spire Count Min/Max
// Magma Min/Max
// Biome Count Min (Can't do anything with Max at this level)
if (finder->biome_count_min > tile->biome_count) return false;
@ -1304,6 +1336,18 @@ uint16_t embark_assist::matcher::find(embark_assist::defs::match_iterators *iter
return 0;
}
if (iterator->finder.spire_count_max < iterator->finder.spire_count_min &&
iterator->finder.spire_count_max != -1) {
out.printerr("matcher::find: Will never find any matches with max spires < min spires\n");
return 0;
}
if (iterator->finder.magma_max < iterator->finder.magma_min &&
iterator->finder.magma_max != embark_assist::defs::magma_ranges::NA) {
out.printerr("matcher::find: Will never find any matches with max magma < min magma\n");
return 0;
}
if (iterator->finder.biome_count_max < iterator->finder.biome_count_min &&
iterator->finder.biome_count_max != -1) {
out.printerr("matcher::find: Will never find any matches with max biomes < min biomes\n");

@ -156,13 +156,13 @@ namespace embark_assist {
Screen::Pen pen_lr(' ', COLOR_LIGHTRED);
Screen::Pen pen_w(' ', COLOR_WHITE);
Screen::paintString(pen_lr, width - 28, 20, "i", false);
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);
Screen::paintString(pen_lr, width - 28, 21, "f", false);
Screen::paintString(pen_lr, width - 28, 21, DFHack::Screen::getKeyDisplay(df::interface_key::CUSTOM_F).c_str(), false);
Screen::paintString(pen_w, width - 27, 21, ":Find Embark ", false);
Screen::paintString(pen_lr, width - 28, 22, "c", false);
Screen::paintString(pen_lr, width - 28, 22, DFHack::Screen::getKeyDisplay(df::interface_key::CUSTOM_C).c_str(), false);
Screen::paintString(pen_w, width - 27, 22, ":Cancel/Clear Find", false);
Screen::paintString(pen_lr, width - 28, 23, "q", false);
Screen::paintString(pen_lr, width - 28, 23, DFHack::Screen::getKeyDisplay(df::interface_key::CUSTOM_Q).c_str(), false);
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 - 7, 25, to_string(state->match_count), false);

@ -14,9 +14,16 @@
#include "df/creature_interaction_effect_display_symbolst.h"
#include "df/creature_interaction_effect_type.h"
#include "df/feature_init.h"
#include "df/feature_init_deep_special_tubest.h"
#include "df/feature_init_magma_poolst.h"
#include "df/feature_init_volcanost.h"
#include "df/feature_type.h"
#include "df/inorganic_flags.h"
#include "df/inorganic_raw.h"
#include "df/interaction.h"
#include "df/interaction_effect.h"
#include "df/interaction_effect_type.h"
#include "df/interaction_effect_animatest.h"
#include "df/interaction_instance.h"
#include "df/interaction_source.h"
#include "df/interaction_source_regionst.h"
@ -264,10 +271,15 @@ namespace embark_assist {
if (interaction->sources.size() &&
interaction->sources[0]->getType() == df::interaction_source_type::REGION) {
for (uint16_t k = 0; k < interaction->targets.size(); k++) {
if (interaction->targets[k]->getType() == 0) { // Returns wrong type. Should be df::interaction_target_type::CORPSE
if (interaction->targets[k]->getType() == df::interaction_target_type::CORPSE) {
for (uint16_t l = 0; l < interaction->effects.size(); l++) {
if (interaction->effects[l]->getType() == df::interaction_effect_type::ANIMATE) {
reanimating = true;
break;
}
}
else if (interaction->targets[k]->getType() == 2) {// Returns wrong type.. Should be df::interaction_target_type::MATERIAL
}
else if (interaction->targets[k]->getType() == df::interaction_target_type::MATERIAL) {
df::interaction_target_materialst* material = virtual_cast<df::interaction_target_materialst>(interaction->targets[k]);
if (material && DFHack::MaterialInfo(material->mat_type, material->mat_index).isInorganic()) {
for (uint16_t l = 0; l < world->raws.inorganics[material->mat_index]->material.syndrome.size(); l++) {
@ -569,12 +581,33 @@ void embark_assist::survey::survey_mid_level_tile(embark_assist::defs::geo_data
base_z = elevation - 1;
features = details->features[i][k];
std::map<int, int> layer_bottom, layer_top;
mlt->at(i).at(k).adamantine_level = -1;
mlt->at(i).at(k).magma_level = -1;
end_check_l = static_cast<uint16_t>(features.size());
for (size_t l = 0; l < end_check_l; l++) {
auto feature = features[l];
if (feature->layer != -1 &&
if (feature->feature_idx != -1) {
switch (world_data->feature_map[x / 16][y / 16].features->feature_init[x % 16][y % 16][feature->feature_idx]->getType())
{
case df::feature_type::deep_special_tube:
mlt->at(i).at(k).adamantine_level = world_data->feature_map[x / 16][y / 16].features->feature_init[x % 16][y % 16][feature->feature_idx]->start_depth;
break;
case df::feature_type::magma_pool:
mlt->at(i).at(k).magma_level = 2 - world_data->feature_map[x / 16][y / 16].features->feature_init[x % 16][y % 16][feature->feature_idx]->start_depth;
break;
case df::feature_type::volcano:
mlt->at(i).at(k).magma_level = 3;
break;
default:
break;
}
}
else if (feature->layer != -1 &&
feature->min_z != -30000) {
auto layer = world_data->underground_regions[feature->layer];
@ -584,7 +617,6 @@ void embark_assist::survey::survey_mid_level_tile(embark_assist::defs::geo_data
if (layer->type == df::world_underground_region::MagmaSea) {
min_z = feature->min_z; // The features are individual per region tile
break;
}
}
}