2017-09-01 06:13:34 -06:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <array>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
2020-11-17 11:52:46 -07:00
|
|
|
#include "df/biome_type.h"
|
2019-07-12 14:09:03 -06:00
|
|
|
#include "df/world_region_type.h"
|
2017-09-01 06:13:34 -06:00
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
using std::array;
|
|
|
|
using std::ostringstream;
|
|
|
|
using std::string;
|
|
|
|
using std::vector;
|
|
|
|
|
2019-09-23 05:13:04 -06:00
|
|
|
#define fileresult_file_name "./data/init/embark_assistant_fileresult.txt"
|
|
|
|
|
2017-09-01 06:13:34 -06:00
|
|
|
namespace embark_assist {
|
|
|
|
namespace defs {
|
|
|
|
// Survey types
|
|
|
|
//
|
2020-03-03 13:45:20 -07:00
|
|
|
enum class river_sizes : int8_t {
|
2017-09-01 06:13:34 -06:00
|
|
|
None,
|
|
|
|
Brook,
|
|
|
|
Stream,
|
|
|
|
Minor,
|
|
|
|
Medium,
|
|
|
|
Major
|
|
|
|
};
|
|
|
|
|
2020-11-14 06:43:43 -07:00
|
|
|
const uint8_t Clear_Aquifer_Bits = 0;
|
|
|
|
const uint8_t None_Aquifer_Bit = 1;
|
|
|
|
const uint8_t Light_Aquifer_Bit = 2;
|
|
|
|
const uint8_t Heavy_Aquifer_Bit = 4;
|
2020-03-03 13:45:20 -07:00
|
|
|
|
2020-11-17 11:52:46 -07:00
|
|
|
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
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2020-03-03 13:45:20 -07:00
|
|
|
enum class tree_levels : int8_t {
|
|
|
|
None,
|
|
|
|
Very_Scarce,
|
|
|
|
Scarce,
|
|
|
|
Woodland,
|
|
|
|
Heavily_Forested
|
|
|
|
};
|
2021-01-18 15:23:50 -07:00
|
|
|
|
|
|
|
// only contains those attributes that are being handled during incursion processing
|
|
|
|
struct mid_level_tile_incursion_base {
|
2020-11-14 06:43:43 -07:00
|
|
|
uint8_t aquifer = Clear_Aquifer_Bits;
|
2017-09-01 06:13:34 -06:00
|
|
|
bool clay = false;
|
|
|
|
bool sand = false;
|
2021-01-18 15:23:50 -07:00
|
|
|
int8_t soil_depth;
|
|
|
|
int16_t elevation;
|
|
|
|
int8_t biome_offset;
|
|
|
|
tree_levels trees;
|
|
|
|
uint8_t savagery_level; // 0 - 2
|
|
|
|
uint8_t evilness_level; // 0 - 2
|
|
|
|
};
|
|
|
|
|
|
|
|
// contains all attributes (some by inheritance), used for regular survey/matching
|
|
|
|
struct mid_level_tile : public mid_level_tile_incursion_base {
|
2017-09-01 06:13:34 -06:00
|
|
|
bool flux = false;
|
2018-12-04 06:55:16 -07:00
|
|
|
bool coal = false;
|
2017-09-01 06:13:34 -06:00
|
|
|
int8_t offset;
|
2020-12-03 07:40:22 -07:00
|
|
|
river_sizes river_size = river_sizes::None;
|
2017-09-01 06:13:34 -06:00
|
|
|
int16_t river_elevation = 100;
|
2018-02-26 10:31:33 -07:00
|
|
|
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
|
2017-09-01 06:13:34 -06:00
|
|
|
std::vector<bool> metals;
|
|
|
|
std::vector<bool> economics;
|
|
|
|
std::vector<bool> minerals;
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef std::array<std::array<mid_level_tile, 16>, 16> mid_level_tiles;
|
|
|
|
|
|
|
|
struct region_tile_datum {
|
|
|
|
bool surveyed = false;
|
2020-11-13 12:11:03 -07:00
|
|
|
bool survey_completed = false;
|
2020-11-17 11:52:46 -07:00
|
|
|
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];
|
2020-11-14 06:43:43 -07:00
|
|
|
uint8_t aquifer = Clear_Aquifer_Bits;
|
2017-09-01 06:13:34 -06:00
|
|
|
uint16_t clay_count = 0;
|
|
|
|
uint16_t sand_count = 0;
|
|
|
|
uint16_t flux_count = 0;
|
2018-12-04 06:55:16 -07:00
|
|
|
uint16_t coal_count = 0;
|
2017-09-01 06:13:34 -06:00
|
|
|
uint8_t min_region_soil = 10;
|
|
|
|
uint8_t max_region_soil = 0;
|
2019-07-01 05:28:40 -06:00
|
|
|
uint8_t max_waterfall = 0;
|
2020-12-03 07:40:22 -07:00
|
|
|
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;
|
2017-09-01 06:13:34 -06:00
|
|
|
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;
|
2018-07-13 09:21:42 -06:00
|
|
|
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
|
2020-03-03 13:45:20 -07:00
|
|
|
tree_levels min_tree_level = embark_assist::defs::tree_levels::Heavily_Forested;
|
|
|
|
tree_levels max_tree_level = embark_assist::defs::tree_levels::None;
|
2018-06-21 12:48:35 -06:00
|
|
|
bool blood_rain[10];
|
|
|
|
bool blood_rain_possible;
|
|
|
|
bool blood_rain_full;
|
|
|
|
bool permanent_syndrome_rain[10];
|
|
|
|
bool permanent_syndrome_rain_possible;
|
|
|
|
bool permanent_syndrome_rain_full;
|
|
|
|
bool temporary_syndrome_rain[10];
|
|
|
|
bool temporary_syndrome_rain_possible;
|
|
|
|
bool temporary_syndrome_rain_full;
|
2017-09-01 06:13:34 -06:00
|
|
|
bool reanimating[10];
|
|
|
|
bool reanimating_possible;
|
|
|
|
bool reanimating_full;
|
|
|
|
bool thralling[10];
|
|
|
|
bool thralling_possible;
|
|
|
|
bool thralling_full;
|
|
|
|
uint16_t savagery_count[3];
|
|
|
|
uint16_t evilness_count[3];
|
|
|
|
std::vector<bool> metals;
|
|
|
|
std::vector<bool> economics;
|
|
|
|
std::vector<bool> minerals;
|
2020-03-03 13:45:20 -07:00
|
|
|
std::vector<int16_t> neighbors; // entity_raw indices
|
|
|
|
uint8_t necro_neighbors;
|
2019-07-12 14:09:03 -06:00
|
|
|
mid_level_tile north_row[16];
|
|
|
|
mid_level_tile south_row[16];
|
|
|
|
mid_level_tile west_column[16];
|
|
|
|
mid_level_tile east_column[16];
|
|
|
|
uint8_t north_corner_selection[16]; // 0 - 3. For some reason DF stores everything needed for incursion
|
|
|
|
uint8_t west_corner_selection[16]; // detection in 17:th row/colum data in the region details except
|
|
|
|
// this info, so we have to go to neighboring world tiles to fetch it.
|
|
|
|
df::world_region_type region_type[16][16]; // Required for incursion override detection. We could store only the
|
|
|
|
// edges, but storing it for every tile allows for a unified fetching
|
|
|
|
// logic.
|
2020-06-02 07:58:46 -06:00
|
|
|
int8_t north_row_biome_x[16]; // "biome_x" data cached for the northern row for access from the north.
|
|
|
|
int8_t west_column_biome_y[16]; // "biome_y" data cached for the western row for access from the west.
|
2017-09-01 06:13:34 -06:00
|
|
|
};
|
|
|
|
|
|
|
|
struct geo_datum {
|
|
|
|
uint8_t soil_size = 0;
|
|
|
|
bool top_soil_only = true;
|
|
|
|
bool top_soil_aquifer_only = true;
|
|
|
|
bool aquifer_absent = true;
|
|
|
|
bool clay_absent = true;
|
|
|
|
bool sand_absent = true;
|
|
|
|
bool flux_absent = true;
|
2018-12-04 06:55:16 -07:00
|
|
|
bool coal_absent = true;
|
2017-09-01 06:13:34 -06:00
|
|
|
std::vector<bool> possible_metals;
|
|
|
|
std::vector<bool> possible_economics;
|
|
|
|
std::vector<bool> possible_minerals;
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef std::vector<geo_datum> geo_data;
|
|
|
|
|
|
|
|
struct sites {
|
|
|
|
uint8_t x;
|
|
|
|
uint8_t y;
|
|
|
|
char type;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct site_infos {
|
2019-07-12 14:09:03 -06:00
|
|
|
bool incursions_processed;
|
2020-11-14 06:43:43 -07:00
|
|
|
uint8_t aquifer;
|
2017-09-01 06:13:34 -06:00
|
|
|
uint8_t min_soil;
|
|
|
|
uint8_t max_soil;
|
2019-07-12 14:09:03 -06:00
|
|
|
bool flat;
|
2019-07-01 05:28:40 -06:00
|
|
|
uint8_t max_waterfall;
|
2017-09-01 06:13:34 -06:00
|
|
|
bool clay;
|
|
|
|
bool sand;
|
|
|
|
bool flux;
|
2018-12-04 06:55:16 -07:00
|
|
|
bool coal;
|
2019-07-12 14:09:03 -06:00
|
|
|
bool blood_rain;
|
|
|
|
bool permanent_syndrome_rain;
|
|
|
|
bool temporary_syndrome_rain;
|
|
|
|
bool reanimating;
|
|
|
|
bool thralling;
|
2017-09-01 06:13:34 -06:00
|
|
|
std::vector<uint16_t> metals;
|
|
|
|
std::vector<uint16_t> economics;
|
|
|
|
std::vector<uint16_t> minerals;
|
|
|
|
// Could add savagery, evilness, and biomes, but DF provides those easily.
|
2020-03-03 13:45:20 -07:00
|
|
|
std::vector<int16_t> neighbors; // entity_raw indices
|
|
|
|
uint8_t necro_neighbors;
|
2017-09-01 06:13:34 -06:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef std::vector<sites> site_lists;
|
|
|
|
|
|
|
|
typedef std::vector<std::vector<region_tile_datum>> world_tile_data;
|
|
|
|
|
|
|
|
typedef bool mlt_matches[16][16];
|
|
|
|
// An embark region match is indicated by marking the top left corner
|
|
|
|
// tile as a match. Thus, the bottom and right side won't show matches
|
|
|
|
// unless the appropriate dimension has a width of 1.
|
|
|
|
|
|
|
|
struct matches {
|
|
|
|
bool preliminary_match;
|
|
|
|
bool contains_match;
|
|
|
|
mlt_matches mlt_match;
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef std::vector<std::vector<matches>> match_results;
|
|
|
|
|
|
|
|
// matcher types
|
|
|
|
//
|
|
|
|
enum class evil_savagery_values : int8_t {
|
|
|
|
NA = -1,
|
|
|
|
All,
|
|
|
|
Present,
|
|
|
|
Absent
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class evil_savagery_ranges : int8_t {
|
|
|
|
Low,
|
|
|
|
Medium,
|
|
|
|
High
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class aquifer_ranges : int8_t {
|
|
|
|
NA = -1,
|
2020-03-03 13:45:20 -07:00
|
|
|
None,
|
|
|
|
At_Most_Light,
|
|
|
|
None_Plus_Light,
|
|
|
|
None_Plus_At_Least_Light,
|
|
|
|
Light,
|
|
|
|
At_Least_Light,
|
|
|
|
None_Plus_Heavy,
|
|
|
|
At_Most_Light_Plus_Heavy,
|
|
|
|
Light_Plus_Heavy,
|
|
|
|
None_Light_Heavy,
|
|
|
|
Heavy
|
2017-09-01 06:13:34 -06:00
|
|
|
};
|
|
|
|
|
|
|
|
enum class river_ranges : int8_t {
|
|
|
|
NA = -1,
|
|
|
|
None,
|
|
|
|
Brook,
|
|
|
|
Stream,
|
|
|
|
Minor,
|
|
|
|
Medium,
|
|
|
|
Major
|
|
|
|
};
|
|
|
|
|
2018-02-27 02:46:06 -07:00
|
|
|
// For possible future use. That's the level of data actually collected.
|
2018-02-26 10:31:33 -07:00
|
|
|
// 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
|
|
|
|
};
|
|
|
|
|
2017-09-01 06:13:34 -06:00
|
|
|
enum class yes_no_ranges : int8_t {
|
|
|
|
NA = -1,
|
|
|
|
Yes,
|
|
|
|
No
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class all_present_ranges : int8_t {
|
|
|
|
All,
|
|
|
|
Present
|
|
|
|
};
|
|
|
|
enum class present_absent_ranges : int8_t {
|
|
|
|
NA = -1,
|
|
|
|
Present,
|
|
|
|
Absent
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class soil_ranges : int8_t {
|
|
|
|
NA = -1,
|
|
|
|
None,
|
|
|
|
Very_Shallow,
|
|
|
|
Shallow,
|
|
|
|
Deep,
|
|
|
|
Very_Deep
|
|
|
|
};
|
|
|
|
|
2018-06-21 12:48:35 -06:00
|
|
|
enum class syndrome_rain_ranges : int8_t {
|
|
|
|
NA = -1,
|
|
|
|
Any,
|
|
|
|
Permanent,
|
|
|
|
Temporary,
|
|
|
|
Not_Permanent,
|
|
|
|
None
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class reanimation_ranges : int8_t {
|
|
|
|
NA = -1,
|
|
|
|
Both,
|
|
|
|
Any,
|
|
|
|
Thralling,
|
|
|
|
Reanimation,
|
|
|
|
Not_Thralling,
|
|
|
|
None
|
|
|
|
};
|
|
|
|
|
2017-09-01 06:13:34 -06:00
|
|
|
enum class freezing_ranges : int8_t {
|
2018-07-13 09:21:42 -06:00
|
|
|
NA = -1,
|
|
|
|
Permanent,
|
|
|
|
At_Least_Partial,
|
|
|
|
Partial,
|
|
|
|
At_Most_Partial,
|
|
|
|
Never
|
2017-09-01 06:13:34 -06:00
|
|
|
};
|
|
|
|
|
2020-03-03 13:45:20 -07:00
|
|
|
enum class tree_ranges : int8_t {
|
|
|
|
NA = -1,
|
|
|
|
None,
|
|
|
|
Very_Scarce, // DF dislays this with a different color but still the "scarce" text
|
|
|
|
Scarce,
|
|
|
|
Woodland,
|
|
|
|
Heavily_Forested
|
|
|
|
};
|
|
|
|
|
|
|
|
struct neighbor {
|
|
|
|
int16_t entity_raw; // entity_raw
|
|
|
|
present_absent_ranges present;
|
|
|
|
};
|
|
|
|
|
2017-09-01 06:13:34 -06:00
|
|
|
struct finders {
|
|
|
|
uint16_t x_dim;
|
|
|
|
uint16_t y_dim;
|
|
|
|
evil_savagery_values savagery[static_cast<int8_t>(evil_savagery_ranges::High) + 1];
|
|
|
|
evil_savagery_values evilness[static_cast<int8_t>(evil_savagery_ranges::High) + 1];
|
|
|
|
aquifer_ranges aquifer;
|
|
|
|
river_ranges min_river;
|
|
|
|
river_ranges max_river;
|
2020-08-23 07:20:45 -06:00
|
|
|
int8_t min_waterfall; // N/A(-1), Absent, 1-50
|
2019-07-12 14:09:03 -06:00
|
|
|
yes_no_ranges flat;
|
2017-09-01 06:13:34 -06:00
|
|
|
present_absent_ranges clay;
|
|
|
|
present_absent_ranges sand;
|
|
|
|
present_absent_ranges flux;
|
2018-12-04 06:55:16 -07:00
|
|
|
present_absent_ranges coal;
|
2017-09-01 06:13:34 -06:00
|
|
|
soil_ranges soil_min;
|
|
|
|
all_present_ranges soil_min_everywhere;
|
|
|
|
soil_ranges soil_max;
|
2018-07-13 09:21:42 -06:00
|
|
|
freezing_ranges freezing;
|
2018-06-21 12:48:35 -06:00
|
|
|
yes_no_ranges blood_rain; // Will probably blow up with the magic release arcs...
|
|
|
|
syndrome_rain_ranges syndrome_rain;
|
|
|
|
reanimation_ranges reanimation;
|
2018-02-26 10:31:33 -07:00
|
|
|
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;
|
2017-09-01 06:13:34 -06:00
|
|
|
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
|
|
|
|
int8_t region_type_2; // N/A(-1), df::world_region_type
|
|
|
|
int8_t region_type_3; // N/A(-1), df::world_region_type
|
|
|
|
int8_t biome_1; // N/A(-1), df::biome_type
|
|
|
|
int8_t biome_2; // N/A(-1), df::biome_type
|
|
|
|
int8_t biome_3; // N/A(-1), df::biome_type
|
2020-03-03 13:45:20 -07:00
|
|
|
tree_ranges min_trees;
|
|
|
|
tree_ranges max_trees;
|
2017-09-01 06:13:34 -06:00
|
|
|
int16_t metal_1; // N/A(-1), 0-max_inorganic;
|
|
|
|
int16_t metal_2; // N/A(-1), 0-max_inorganic;
|
|
|
|
int16_t metal_3; // N/A(-1), 0-max_inorganic;
|
|
|
|
int16_t economic_1; // N/A(-1), 0-max_inorganic;
|
|
|
|
int16_t economic_2; // N/A(-1), 0-max_inorganic;
|
|
|
|
int16_t economic_3; // N/A(-1), 0-max_inorganic;
|
|
|
|
int16_t mineral_1; // N/A(-1), 0-max_inorganic;
|
|
|
|
int16_t mineral_2; // N/A(-1), 0-max_inorganic;
|
|
|
|
int16_t mineral_3; // N/A(-1), 0-max_inorganic;
|
2020-03-03 13:45:20 -07:00
|
|
|
int8_t min_necro_neighbors; // N/A(-1), 0 - 9, where 9 = 9+
|
|
|
|
int8_t max_necro_neighbors; // N/A(-1), 0 - 9, where 9 = 9+
|
|
|
|
int8_t min_civ_neighbors; // N/A(-1), 0 - 9, where 9 = 9+
|
|
|
|
int8_t max_civ_neighbors; // N/A(-1), 0 - 9, where 9 = 9+
|
|
|
|
std::vector<neighbor> neighbors;
|
2017-09-01 06:13:34 -06:00
|
|
|
};
|
|
|
|
|
|
|
|
struct match_iterators {
|
|
|
|
bool active;
|
|
|
|
uint16_t x; // x position of focus when iteration started so we can return it.
|
|
|
|
uint16_t y; // y
|
|
|
|
uint16_t i;
|
|
|
|
uint16_t k;
|
|
|
|
bool x_right;
|
|
|
|
bool y_down;
|
|
|
|
bool inhibit_x_turn;
|
|
|
|
bool inhibit_y_turn;
|
2019-09-23 05:13:04 -06:00
|
|
|
uint16_t target_location_x;
|
|
|
|
uint16_t target_location_y;
|
2017-09-01 06:13:34 -06:00
|
|
|
uint16_t count;
|
|
|
|
finders finder;
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef void(*find_callbacks) (embark_assist::defs::finders finder);
|
|
|
|
}
|
|
|
|
}
|