|
|
|
@ -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();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1039,17 +1287,25 @@ 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) {
|
|
|
|
|