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
} ;
2022-04-12 12:48:19 -06:00
2021-01-18 16:07:28 -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
} ;
2021-01-18 16:07:28 -07:00
// contains all attributes (some by inheritance), used for regular survey/matching
2021-01-18 15:23:50 -07:00
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
2021-05-23 06:12:16 -06:00
// using uint8_t instead of bool as vector<bool> gets optimized for a small memory footprint which leads to a significant overhead when iterating over all entries,
2021-05-23 03:28:48 -06:00
// also there seems to be no template specialization for std::fill in MSVS C++11 in regards to std::vector<bool> and std::memset does not work as expected (=> not at all that is)
// have a look here https://github.com/DFHack/dfhack/pull/1771#discussion_r579498636 for the related discussion and furter resources
std : : vector < uint8_t > metals ;
std : : vector < uint8_t > economics ;
std : : vector < uint8_t > minerals ;
2017-09-01 06:13:34 -06:00
} ;
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 ;
2021-01-18 16:01:54 -07:00
mid_level_tile_incursion_base north_row [ 16 ] ;
mid_level_tile_incursion_base south_row [ 16 ] ;
mid_level_tile_incursion_base west_column [ 16 ] ;
mid_level_tile_incursion_base east_column [ 16 ] ;
2019-07-12 14:09:03 -06:00
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 ) ;
}
2022-04-12 12:48:19 -06:00
}