diff --git a/library/include/modules/Maps.h b/library/include/modules/Maps.h index 0c41bf7f6..f33abf4e0 100644 --- a/library/include/modules/Maps.h +++ b/library/include/modules/Maps.h @@ -36,6 +36,7 @@ distribution. #include "BitArray.h" #include "modules/Materials.h" +#include "df/biome_type.h" #include "df/block_flags.h" #include "df/feature_type.h" #include "df/flow_type.h" @@ -333,6 +334,12 @@ extern DFHACK_EXPORT bool RemoveBlockEvent(uint32_t x, uint32_t y, uint32_t z, d DFHACK_EXPORT bool canWalkBetween(df::coord pos1, df::coord pos2); DFHACK_EXPORT bool canStepBetween(df::coord pos1, df::coord pos2); + +DFHACK_EXPORT df::enums::biome_type::biome_type GetBiomeType(int world_coord_x, int world_coord_y); +DFHACK_EXPORT df::enums::biome_type::biome_type GetBiomeTypeWithRef(int world_coord_x, int world_coord_y, int world_ref_y_coord); + } + + } #endif diff --git a/library/modules/Maps.cpp b/library/modules/Maps.cpp index 54f314db8..361ada0f1 100644 --- a/library/modules/Maps.cpp +++ b/library/modules/Maps.cpp @@ -46,6 +46,7 @@ using namespace std; #include "modules/MapCache.h" #include "modules/Maps.h" +#include "df/biome_type.h" #include "df/block_burrow.h" #include "df/block_burrow_link.h" #include "df/block_square_event_grassst.h" @@ -711,3 +712,393 @@ bool Maps::canStepBetween(df::coord pos1, df::coord pos2) return false; } + +/* The code below is a heavily refactored version of code found at + https://github.com/ragundo/exportmaps/blob/master/cpp/df_utils/biome_type.cpp. +*/ + +/* +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: +1. The origin of this software must not be misrepresented; you must not +claim that you wrote the original software. If you use this software +in a product, an acknowledgment in the product documentation would be +appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be +misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +namespace { + //----------------------------------------------------------------------------// + // Utility function + // + //----------------------------------------------------------------------------// + std::pair check_tropicality(df::region_map_entry& region, + int y_pos + ) + { + int flip_latitude = df::global::world->world_data->flip_latitude; + + bool is_possible_tropical_area_by_latitude = false; + bool is_tropical_area_by_latitude = false; + + if (flip_latitude == -1) // NO POLES + { + // If there're no poles, tropical area is determined by temperature + is_possible_tropical_area_by_latitude = region.temperature >= 75; + is_tropical_area_by_latitude = region.temperature >= 85; + } + + else + { + int v6 = 0; + + df::world_data* wdata = df::global::world->world_data; + + if (flip_latitude == 0) // NORTH POLE ONLY + { + v6 = y_pos; + } + + else if (flip_latitude == 1) // SOUTH_POLE ONLY + { + v6 = df::global::world->world_data->world_height - y_pos - 1; + } + + else if (flip_latitude == 2) // BOTH POLES + { + if (y_pos < wdata->world_height / 2) + v6 = 2 * y_pos; + else + { + v6 = wdata->world_height + 2 * (wdata->world_height / 2 - y_pos) - 1; + if (v6 < 0) + v6 = 0; + if (v6 >= wdata->world_height) + v6 = wdata->world_height - 1; + } + } + + if (wdata->world_height == 17) + v6 *= 16; + else if (wdata->world_height == 33) + v6 *= 8; + else if (wdata->world_height == 65) + v6 *= 4; + else if (wdata->world_height == 129) + v6 *= 2; + + is_possible_tropical_area_by_latitude = v6 > 170; + is_tropical_area_by_latitude = v6 >= 200; + } + + return std::pair(is_possible_tropical_area_by_latitude, + is_tropical_area_by_latitude + ); + } + + + //----------------------------------------------------------------------------// + // Utility function + // + // return some unknow parameter as a percentage + //----------------------------------------------------------------------------// + int get_region_parameter(int y, + int x + ) + { + int world_height = df::global::world->world_data->world_height; + if (world_height > 65) // Medium and large worlds + { + // access to region 2D array + df::region_map_entry& region = df::global::world->world_data->region_map[x][y]; + int flip_latitude = df::global::world->world_data->flip_latitude; + int rainfall = region.rainfall; + int result; + int y_pos = y; + int ypos = y_pos; + + if (flip_latitude == -1) // NO POLES + return 100; + + else if (flip_latitude == 1) // SOUTH POLE + ypos = world_height - y_pos - 1; + else if (flip_latitude == 2) // NORTH & SOUTH POLE + { + if (ypos < world_height / 2) + ypos *= 2; + else + { + ypos = world_height + 2 * (world_height / 2 - ypos) - 1; + if (ypos < 0) + ypos = 0; + if (ypos >= world_height) + ypos = world_height - 1; + } + } + + int latitude; // 0 - 256 (size of a large world) + switch (world_height) + { + case 17: // Pocket world + latitude = 16 * ypos; + break; + case 33: // Smaller world + latitude = 8 * ypos; + break; + case 65: // Small world + latitude = 4 * ypos; + break; + case 129: // Medium world + latitude = 2 * ypos; + break; + default: // Large world + latitude = ypos; + break; + } + + // latitude > 220 + if ((latitude - 171) > 49) + return 100; + + + // Latitude between 191 and 200 + if ((latitude > 190) && (latitude < 201)) + return 0; + + // Latitude between 201 and 220 + if ((latitude > 190) && (latitude >= 201)) + result = rainfall + 16 * (latitude - 207); + else + // Latitude between 0 and 190 + result = (16 * (184 - latitude) - rainfall); + + if (result < 0) + return 0; + + if (result > 100) + return 100; + + return result; + } + + return 100; + } +} + + +/***************************************************************************** +Module main function. +Return the biome type, given a position coordinate expressed in world_tiles +The world ref coordinates are used for tropicality determination and may refer +to a tile neighboring the "official" one. +*****************************************************************************/ +df::enums::biome_type::biome_type Maps::GetBiomeTypeWithRef(int world_coord_x, + int world_coord_y, + int world_ref_coord_y +) +{ + // Biome is per region, so get the region where this biome exists + df::region_map_entry& region = df::global::world->world_data->region_map[world_coord_x][world_coord_y]; + + // Check if the y reference position coordinate belongs to a tropical area + std::pair p = check_tropicality(region, + world_ref_coord_y + ); + bool is_possible_tropical_area_by_latitude = p.first; + bool is_tropical_area_by_latitude = p.second; + + int parameter = get_region_parameter(world_coord_y, world_coord_x); + + // Begin the discrimination + if (region.flags.is_set(df::region_map_entry_flags::is_lake)) // is it a lake? + { + // salinity values tell us the lake type + // greater than 66 is a salt water lake + // between 33 and 65 is a brackish water lake + // less than 33 is a fresh water lake + if (region.salinity < 33) + if (is_possible_tropical_area_by_latitude) + return df::enums::biome_type::biome_type::LAKE_TROPICAL_FRESHWATER; // 39 + else + return df::enums::biome_type::biome_type::LAKE_TEMPERATE_FRESHWATER; // 36 + else if (region.salinity < 66) + if (is_possible_tropical_area_by_latitude) + return df::enums::biome_type::biome_type::LAKE_TROPICAL_BRACKISHWATER; // 40 + else + return df::enums::biome_type::biome_type::LAKE_TEMPERATE_BRACKISHWATER; // 37 + else // salinity >= 66 + if (is_possible_tropical_area_by_latitude) + return df::enums::biome_type::biome_type::LAKE_TROPICAL_SALTWATER;// 41 + else + return df::enums::biome_type::biome_type::LAKE_TEMPERATE_SALTWATER; // 38 + } + + // Not a lake. Check elevation + // Elevation greater then 149 means a mountain biome + // Elevation below 100 means a ocean biome + // Elevation between 100 and 149 are land biomes + + if (region.elevation >= 150) // is it a mountain? + return df::enums::biome_type::biome_type::MOUNTAIN; // 0 + + if (region.elevation < 100) // is it a ocean? + { + if (is_tropical_area_by_latitude) + return df::enums::biome_type::biome_type::OCEAN_TROPICAL; // 27 + else if (region.temperature <= -5) + return df::enums::biome_type::biome_type::OCEAN_ARCTIC; // 29 + else + return df::enums::biome_type::biome_type::OCEAN_TEMPERATE; // 28 + } + + // land biome. Elevation between 100 and 149 + + if (region.temperature <= -5) + { + if (region.drainage < 75) + return df::enums::biome_type::biome_type::TUNDRA; // 2 + else + return df::enums::biome_type::biome_type::GLACIER; // 1 + } + + // Not a lake, mountain, ocean, glacier or tundra + // Vegetation determines the biome type + + if (region.vegetation < 10) + { + if (region.drainage < 33) + return df::enums::biome_type::biome_type::DESERT_SAND; // 26 + else if (region.drainage < 66) + return df::enums::biome_type::biome_type::DESERT_ROCK; // 25 + else // drainage >= 66 + return df::enums::biome_type::biome_type::DESERT_BADLAND; // 24 + } + else if (region.vegetation < 20) + { + if ((is_possible_tropical_area_by_latitude && (parameter < 66)) || is_tropical_area_by_latitude) + return df::enums::biome_type::biome_type::GRASSLAND_TROPICAL; // 21 + else + return df::enums::biome_type::biome_type::GRASSLAND_TEMPERATE; //18; + } + else if (region.vegetation < 33) + { + // vegetation between 20 and 32 + if ((is_possible_tropical_area_by_latitude && (parameter <= 6)) || is_tropical_area_by_latitude) + return df::enums::biome_type::biome_type::SAVANNA_TROPICAL; // 22 + else + return df::enums::biome_type::biome_type::SAVANNA_TEMPERATE; //19; + } + else if (region.vegetation < 66) + { + if (region.drainage >= 33) + { + if (is_possible_tropical_area_by_latitude && (parameter < 66 || is_tropical_area_by_latitude)) + return df::enums::biome_type::biome_type::SHRUBLAND_TROPICAL; // 23 + else + return df::enums::biome_type::biome_type::SHRUBLAND_TEMPERATE; // 20 + } + // drainage < 33 + { + if (region.salinity < 66) + { + if ((is_possible_tropical_area_by_latitude && (parameter < 66)) || is_tropical_area_by_latitude) + return df::enums::biome_type::biome_type::MARSH_TROPICAL_FRESHWATER; // 10 + else + return df::enums::biome_type::biome_type::MARSH_TEMPERATE_FRESHWATER; // 5 + } + else // drainage < 33, salinity >= 66 + { + if ((is_possible_tropical_area_by_latitude && (parameter < 66)) || is_tropical_area_by_latitude) + return df::enums::biome_type::biome_type::MARSH_TROPICAL_SALTWATER; // 11 + else + return df::enums::biome_type::biome_type::MARSH_TEMPERATE_SALTWATER; // 6 + } + } + } + + // Not a lake, mountain, ocean, glacier, tundra, desert, grassland or savanna + // vegetation >= 66 + else if (region.drainage >= 33) + { + // drainage >= 33, not tropical area + if (!is_possible_tropical_area_by_latitude) + { + if ((region.rainfall < 75) || (region.temperature < 65)) + { + if (region.temperature >= 10) + return df::enums::biome_type::biome_type::FOREST_TEMPERATE_CONIFER; // 13 + else + return df::enums::biome_type::biome_type::FOREST_TAIGA; // 12 + } + else + return df::enums::biome_type::biome_type::FOREST_TEMPERATE_BROADLEAF; // 14 + } + else // drainage >= 33, tropical area + { + if (((parameter < 66) || is_tropical_area_by_latitude) && (region.rainfall < 75)) + return df::enums::biome_type::biome_type::FOREST_TROPICAL_CONIFER; // 15 + if (parameter < 66) + return df::enums::biome_type::biome_type::FOREST_TROPICAL_DRY_BROADLEAF; // 16 + if (is_tropical_area_by_latitude) + return df::enums::biome_type::biome_type::FOREST_TROPICAL_MOIST_BROADLEAF; // 17 + else + { + if ((region.rainfall < 75) || (region.temperature < 65)) + { + if (region.temperature >= 10) + return df::enums::biome_type::biome_type::FOREST_TEMPERATE_CONIFER; // 13 + else + return df::enums::biome_type::biome_type::FOREST_TAIGA; // 12 + } + else + return df::enums::biome_type::biome_type::FOREST_TEMPERATE_BROADLEAF; // 14 + } + } + } + + // Not a lake, mountain, ocean, glacier, tundra, desert, grassland, savanna or forest + // vegetation >= 66, drainage < 33 + + else if (is_possible_tropical_area_by_latitude) + { + if (region.salinity < 66) + { + if ((parameter < 66) || is_tropical_area_by_latitude) + return df::enums::biome_type::biome_type::SWAMP_TROPICAL_FRESHWATER; // 7 + else + return df::enums::biome_type::biome_type::SWAMP_TEMPERATE_FRESHWATER;// 3 + } + else // elevation between 100 and 149, vegetation >= 66, drainage < 33, salinity >= 66 + { + if ((parameter < 66) || is_tropical_area_by_latitude) + if (region.drainage < 10) + return df::enums::biome_type::biome_type::SWAMP_MANGROVE; //9 + else // drainage >= 10 + return df::enums::biome_type::biome_type::SWAMP_TROPICAL_SALTWATER; // 8 + else + return df::enums::biome_type::biome_type::SWAMP_TEMPERATE_SALTWATER; // 4 + } + } + + else if (region.salinity >= 66) + // elevation between 100 and 149, vegetation >= 66, drainage < 33, not tropical area + return df::enums::biome_type::biome_type::SWAMP_TEMPERATE_SALTWATER; // 4 + else + return df::enums::biome_type::biome_type::SWAMP_TEMPERATE_FRESHWATER; // 3 +} + +/***************************************************************************** +Module main function. +Return the biome type, given a position coordinate expressed in world_tiles +*****************************************************************************/ +df::enums::biome_type::biome_type Maps::GetBiomeType(int world_coord_x, int world_coord_y) +{ + return Maps::GetBiomeTypeWithRef(world_coord_x, world_coord_y, world_coord_y); +} + diff --git a/plugins/embark-assistant/CMakeLists.txt b/plugins/embark-assistant/CMakeLists.txt index 917d2ec5a..dfc1a294f 100644 --- a/plugins/embark-assistant/CMakeLists.txt +++ b/plugins/embark-assistant/CMakeLists.txt @@ -1,7 +1,6 @@ PROJECT (embark-assistant) # A list of source files SET(PROJECT_SRCS - biome_type.cpp embark-assistant.cpp finder_ui.cpp help_ui.cpp @@ -12,7 +11,6 @@ SET(PROJECT_SRCS ) # A list of headers SET(PROJECT_HDRS - biome_type.h defs.h embark-assistant.h finder_ui.h diff --git a/plugins/embark-assistant/biome_type.cpp b/plugins/embark-assistant/biome_type.cpp deleted file mode 100644 index 01bc0044a..000000000 --- a/plugins/embark-assistant/biome_type.cpp +++ /dev/null @@ -1,754 +0,0 @@ -/* The code is copied from Ragundo's repo referenced below. -The changes are: -- The addition of a .h file reference. -- The simplification of the code using ofsub to remove the use of (and - .h reference to) that function (analysis of the code showed the - simplified code is the result, as the ofsub expressions will never be - true given the range of the values it can be passed in these functions). -- The change of the main function to take a separate y coordinate for - use in the tropicality determination to allow proper determination of - the tropicality of mid level tiles ("region tiles") referencing a - neighboring world tile's biome. -*/ -/* -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: -1. The origin of this software must not be misrepresented; you must not -claim that you wrote the original software. If you use this software -in a product, an acknowledgment in the product documentation would be -appreciated but is not required. -2. Altered source versions must be plainly marked as such, and must not be -misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. -*/ - -// You can always find the latest version of this plugin in Github -// https://github.com/ragundo/exportmaps - -#include - -#include "DataDefs.h" -#include -#include -#include -#include - -#include "biome_type.h" - -/***************************************************************************** -Local functions forward declaration -*****************************************************************************/ -std::pair check_tropicality(df::region_map_entry& region, - int a1 -); - -int get_lake_biome(df::region_map_entry& region, - bool is_possible_tropical_area_by_latitude -); - -int get_ocean_biome(df::region_map_entry& region, - bool is_tropical_area_by_latitude -); - -int get_desert_biome(df::region_map_entry& region); - -int get_biome_grassland(bool is_possible_tropical_area_by_latitude, - bool is_tropical_area_by_latitude, - int y, - int x -); - -int get_biome_savanna(bool is_possible_tropical_area_by_latitude, - bool is_tropical_area_by_latitude, - int y, - int x -); - -int get_biome_shrubland(bool is_possible_tropical_area_by_latitude, - bool is_tropical_area_by_latitude, - int y, - int x -); - -int get_biome_marsh(df::region_map_entry& region, - bool is_possible_tropical_area_by_latitude, - bool is_tropical_area_by_latitude, - int y, - int x -); - -int get_biome_forest(df::region_map_entry& region, - bool is_possible_tropical_area_by_latitude, - bool is_tropical_area_by_latitude, - int y, - int x -); - -int get_biome_swamp(df::region_map_entry& region, - bool is_possible_tropical_area_by_latitude, - bool is_tropical_area_by_latitude, - int y, - int x -); - -int get_biome_desert_or_grassland_or_savanna(df::region_map_entry& region, - bool is_possible_tropical_area_by_latitude, - bool is_tropical_area_by_latitude, - int y, - int x -); - -int get_biome_shrubland_or_marsh(df::region_map_entry& region, - bool is_possible_tropical_area_by_latitude, - bool is_tropical_area_by_latitude, - int y, - int x -); - -/***************************************************************************** -Module main function. -Return the biome type, given a position coordinate expressed in world_tiles -The world ref coordinates are used for tropicality determination and may refer -to a tile neighboring the "official" one. -*****************************************************************************/ -int get_biome_type(int world_coord_x, - int world_coord_y, - int world_ref_coord_y -) -{ - // Biome is per region, so get the region where this biome exists - df::region_map_entry& region = df::global::world->world_data->region_map[world_coord_x][world_coord_y]; - - // Check if the y reference position coordinate belongs to a tropical area - std::pair p = check_tropicality(region, - world_ref_coord_y - ); - bool is_possible_tropical_area_by_latitude = p.first; - bool is_tropical_area_by_latitude = p.second; - - // Begin the discrimination - if (region.flags.is_set(df::region_map_entry_flags::is_lake)) // is it a lake? - return get_lake_biome(region, - is_possible_tropical_area_by_latitude - ); - - // Not a lake. Check elevation - // Elevation greater then 149 means a mountain biome - // Elevation below 100 means a ocean biome - // Elevation between 100 and 149 are land biomes - - if (region.elevation >= 150) // is it a mountain? - return df::enums::biome_type::biome_type::MOUNTAIN; // 0 - - if (region.elevation < 100) // is it a ocean? - return get_ocean_biome(region, - is_possible_tropical_area_by_latitude - ); - - // land biome. Elevation between 100 and 149 - if (region.temperature <= -5) - { - if (region.drainage < 75) - return df::enums::biome_type::biome_type::TUNDRA; // 2 - else - return df::enums::biome_type::biome_type::GLACIER; // 1 - } - - // Not a lake, mountain, ocean, glacier or tundra - // Vegetation determines the biome type - if (region.vegetation < 66) - { - if (region.vegetation < 33) - return get_biome_desert_or_grassland_or_savanna(region, - is_possible_tropical_area_by_latitude, - is_tropical_area_by_latitude, - world_coord_y, - world_coord_x - ); - else // vegetation between 33 and 65 - return get_biome_shrubland_or_marsh(region, - is_possible_tropical_area_by_latitude, - is_tropical_area_by_latitude, - world_coord_y, - world_coord_x - ); - } - - // Not a lake, mountain, ocean, glacier, tundra, desert, grassland or savanna - // vegetation >= 66 - if (region.drainage >= 33) - return get_biome_forest(region, - is_possible_tropical_area_by_latitude, - is_tropical_area_by_latitude, - world_coord_y, - world_coord_x - ); - - // Not a lake, mountain, ocean, glacier, tundra, desert, grassland, savanna or forest - // vegetation >= 66, drainage < 33 - return get_biome_swamp(region, - is_possible_tropical_area_by_latitude, - is_tropical_area_by_latitude, - world_coord_y, - world_coord_x); -} - - - -//----------------------------------------------------------------------------// -// Utility function -// -//----------------------------------------------------------------------------// -std::pair check_tropicality_no_poles_world(df::region_map_entry& region, - int y_pos -) -{ - bool is_possible_tropical_area_by_latitude = false; - bool is_tropical_area_by_latitude = false; - - // If there're no poles, tropical area is determined by temperature - if (region.temperature >= 75) - is_possible_tropical_area_by_latitude = true; - is_tropical_area_by_latitude = region.temperature >= 85; - - return std::pair(is_possible_tropical_area_by_latitude, - is_tropical_area_by_latitude - ); -} - -//----------------------------------------------------------------------------// -// Utility function -// -//----------------------------------------------------------------------------// -std::pair check_tropicality_north_pole_only_world(df::region_map_entry& region, - int y_pos -) -{ - int v6; - bool is_possible_tropical_area_by_latitude = false; - bool is_tropical_area_by_latitude = false; - df::world_data* wdata = df::global::world->world_data; - - // Scale the smaller worlds to the big one - if (wdata->world_height == 17) - v6 = 16 * y_pos; - else if (wdata->world_height == 33) - v6 = 8 * y_pos; - else if (wdata->world_height == 65) - v6 = 4 * y_pos; - else if (wdata->world_height == 129) - v6 = 2 * y_pos; - else - v6 = y_pos; - - is_possible_tropical_area_by_latitude = v6 > 170; - is_tropical_area_by_latitude = v6 >= 200; - - return std::pair(is_possible_tropical_area_by_latitude, - is_tropical_area_by_latitude - ); -} - -//----------------------------------------------------------------------------// -// Utility function -// -//----------------------------------------------------------------------------// -std::pair check_tropicality_south_pole_only_world(df::region_map_entry& region, - int y_pos -) -{ - int v6 = df::global::world->world_data->world_height - y_pos - 1; - bool is_possible_tropical_area_by_latitude = false; - bool is_tropical_area_by_latitude = false; - df::world_data* wdata = df::global::world->world_data; - - if (wdata->world_height == 17) - v6 *= 16; - else if (wdata->world_height == 33) - v6 *= 8; - else if (wdata->world_height == 65) - v6 *= 4; - else if (wdata->world_height == 129) - v6 *= 2; - else - v6 *= 1; - - is_possible_tropical_area_by_latitude = v6 > 170; - is_tropical_area_by_latitude = v6 >= 200; - - return std::pair(is_possible_tropical_area_by_latitude, - is_tropical_area_by_latitude - ); -} - -//----------------------------------------------------------------------------// -// Utility function -// -//----------------------------------------------------------------------------// -std::pair check_tropicality_both_poles_world(df::region_map_entry& region, - int y_pos -) -{ - int v6; - bool is_possible_tropical_area_by_latitude = false; - bool is_tropical_area_by_latitude = false; - df::world_data* wdata = df::global::world->world_data; - - if (y_pos < wdata->world_height / 2) - v6 = 2 * y_pos; - else - { - v6 = wdata->world_height + 2 * (wdata->world_height / 2 - y_pos) - 1; - if (v6 < 0) - v6 = 0; - if (v6 >= wdata->world_height) - v6 = wdata->world_height - 1; - } - - if (wdata->world_height == 17) - v6 *= 16; - else if (wdata->world_height == 33) - v6 *= 8; - else if (wdata->world_height == 65) - v6 *= 4; - else if (wdata->world_height == 129) - v6 *= 2; - else - v6 *= 1; - - is_possible_tropical_area_by_latitude = v6 > 170; - is_tropical_area_by_latitude = v6 >= 200; - - return std::pair(is_possible_tropical_area_by_latitude, - is_tropical_area_by_latitude - ); -} - -//----------------------------------------------------------------------------// -// Utility function -// -//----------------------------------------------------------------------------// -std::pair check_tropicality(df::region_map_entry& region, - int y_pos -) -{ - int flip_latitude = df::global::world->world_data->flip_latitude; - - if (flip_latitude == -1) // NO POLES - return check_tropicality_no_poles_world(region, - y_pos - ); - - else if (flip_latitude == 0) // NORTH POLE ONLY - return check_tropicality_north_pole_only_world(region, - y_pos - ); - - else if (flip_latitude == 1) // SOUTH_POLE ONLY - return check_tropicality_south_pole_only_world(region, - y_pos - ); - - else if (flip_latitude == 2) // BOTH POLES - return check_tropicality_both_poles_world(region, - y_pos - ); - - return std::pair(false, false); -} - -//----------------------------------------------------------------------------// -// Utility function -// -//----------------------------------------------------------------------------// -int get_parameter_percentage(int flip_latitude, - int y_pos, - int rainfall, - int world_height -) -{ - int result; - int ypos = y_pos; - - if (flip_latitude == -1) // NO POLES - return 100; - - else if (flip_latitude == 1) // SOUTH POLE - ypos = world_height - y_pos - 1; - else if (flip_latitude == 2) // NORTH & SOUTH POLE - { - if (ypos < world_height / 2) - ypos *= 2; - else - { - ypos = world_height + 2 * (world_height / 2 - ypos) - 1; - if (ypos < 0) - ypos = 0; - if (ypos >= world_height) - ypos = world_height - 1; - } - } - - int latitude; // 0 - 256 (size of a large world) - switch (world_height) - { - case 17: // Pocket world - latitude = 16 * ypos; - break; - case 33: // Smaller world - latitude = 8 * ypos; - break; - case 65: // Small world - latitude = 4 * ypos; - break; - case 129: // Medium world - latitude = 2 * ypos; - break; - default: // Large world - latitude = ypos; - break; - } - - // latitude > 220 - if ((latitude - 171) > 49) - return 100; - - - // Latitude between 191 and 200 - if ((latitude > 190) && (latitude < 201)) - return 0; - - // Latitude between 201 and 220 - if ((latitude > 190) && (latitude >= 201)) - result = rainfall + 16 * (latitude - 207); - else - // Latitude between 0 and 190 - result = (16 * (184 - latitude) - rainfall); - - if (result < 0) - return 0; - - if (result > 100) - return 100; - - return result; -} - -//----------------------------------------------------------------------------// -// Utility function -// -// return some unknow parameter as a percentage -//----------------------------------------------------------------------------// -int get_region_parameter(int y, - int x, - char a4 -) -{ - int result = 100; - - if ((df::global::cur_season && *df::global::cur_season != 1) || !a4) - { - int world_height = df::global::world->world_data->world_height; - if (world_height > 65) // Medium and large worlds - { - // access to region 2D array - df::region_map_entry& region = df::global::world->world_data->region_map[x][y]; - return get_parameter_percentage(df::global::world->world_data->flip_latitude, - y, - region.rainfall, - world_height - ); - } - } - return result; -} - -//----------------------------------------------------------------------------// -// Utility function -// -//----------------------------------------------------------------------------// -int get_lake_biome(df::region_map_entry& region, - bool is_possible_tropical_area_by_latitude -) -{ - // salinity values tell us the lake type - // greater than 66 is a salt water lake - // between 33 and 65 is a brackish water lake - // less than 33 is a fresh water lake - if (region.salinity < 66) - { - if (region.salinity < 33) - if (is_possible_tropical_area_by_latitude) - return df::enums::biome_type::biome_type::LAKE_TROPICAL_FRESHWATER; // 39 - else - return df::enums::biome_type::biome_type::LAKE_TEMPERATE_FRESHWATER; // 36 - else // salinity >= 33 - if (is_possible_tropical_area_by_latitude) - return df::enums::biome_type::biome_type::LAKE_TROPICAL_BRACKISHWATER; // 40 - else - return df::enums::biome_type::biome_type::LAKE_TEMPERATE_BRACKISHWATER; // 37 - } - else // salinity >= 66 - { - if (is_possible_tropical_area_by_latitude) - return df::enums::biome_type::biome_type::LAKE_TROPICAL_SALTWATER;// 41 - else - return df::enums::biome_type::biome_type::LAKE_TEMPERATE_SALTWATER; // 38 - } -} - -//----------------------------------------------------------------------------// -// Utility function -// -//----------------------------------------------------------------------------// -int get_ocean_biome(df::region_map_entry& region, - bool is_tropical_area_by_latitude -) -{ - if (is_tropical_area_by_latitude) - return df::enums::biome_type::biome_type::OCEAN_TROPICAL; // 27 - else - if (region.temperature <= -5) - return df::enums::biome_type::biome_type::OCEAN_ARCTIC; // 29 - else - return df::enums::biome_type::biome_type::OCEAN_TEMPERATE; // 28 -} - -//----------------------------------------------------------------------------// -// Utility function -// -//----------------------------------------------------------------------------// -int get_desert_biome(df::region_map_entry& region) -{ - if (region.drainage < 66) - { - if (region.drainage < 33) - return df::enums::biome_type::biome_type::DESERT_SAND; // 26 - else // drainage between 33 and 65 - return df::enums::biome_type::biome_type::DESERT_ROCK; // 25 - } - // drainage >= 66 - return df::enums::biome_type::biome_type::DESERT_BADLAND; // 24 -} - -//----------------------------------------------------------------------------// -// Utility function -// -//----------------------------------------------------------------------------// -int get_biome_grassland(bool is_possible_tropical_area_by_latitude, - bool is_tropical_area_by_latitude, - int y, - int x -) -{ - if ((is_possible_tropical_area_by_latitude && (get_region_parameter(y, x, 0) < 66)) || is_tropical_area_by_latitude) - return df::enums::biome_type::biome_type::GRASSLAND_TROPICAL; // 21 - else - return df::enums::biome_type::biome_type::GRASSLAND_TEMPERATE; //18; -} - -//----------------------------------------------------------------------------// -// Utility function -// -//----------------------------------------------------------------------------// -int get_biome_savanna(bool is_possible_tropical_area_by_latitude, - bool is_tropical_area_by_latitude, - int y, - int x -) -{ - if ((is_possible_tropical_area_by_latitude && (get_region_parameter(y, x, 0) <= 6)) || is_tropical_area_by_latitude) - return df::enums::biome_type::biome_type::SAVANNA_TROPICAL; // 22 - else - return df::enums::biome_type::biome_type::SAVANNA_TEMPERATE; //19; - -} - -//----------------------------------------------------------------------------// -// Utility function -// -//----------------------------------------------------------------------------// -int get_biome_desert_or_grassland_or_savanna(df::region_map_entry& region, - bool is_possible_tropical_area_by_latitude, - bool is_tropical_area_by_latitude, - int y, - int x -) -{ - if (region.vegetation < 20) - { - if (region.vegetation < 10) - return get_desert_biome(region); - else // vegetation between 10 and 19 - return get_biome_grassland(is_possible_tropical_area_by_latitude, is_tropical_area_by_latitude, y, x); - } - // vegetation between 20 and 32 - return get_biome_savanna(is_possible_tropical_area_by_latitude, is_tropical_area_by_latitude, y, x); -} - -//----------------------------------------------------------------------------// -// Utility function -// -//----------------------------------------------------------------------------// -int get_biome_shrubland(bool is_possible_tropical_area_by_latitude, - bool is_tropical_area_by_latitude, - int y, - int x -) -{ - if (is_possible_tropical_area_by_latitude && (get_region_parameter(y, x, 0) < 66 || is_tropical_area_by_latitude)) - return df::enums::biome_type::biome_type::SHRUBLAND_TROPICAL; // 23 - else - return df::enums::biome_type::biome_type::SHRUBLAND_TEMPERATE; // 20 -} - -//----------------------------------------------------------------------------// -// Utility function -// -//----------------------------------------------------------------------------// -int get_biome_marsh(df::region_map_entry& region, - bool is_possible_tropical_area_by_latitude, - bool is_tropical_area_by_latitude, - int y, - int x -) -{ - if (region.salinity < 66) - { - if ((is_possible_tropical_area_by_latitude && (get_region_parameter(y, x, 0) < 66)) || is_tropical_area_by_latitude) - return df::enums::biome_type::biome_type::MARSH_TROPICAL_FRESHWATER; // 10 - else - return df::enums::biome_type::biome_type::MARSH_TEMPERATE_FRESHWATER; // 5 - } - else // drainage < 33, salinity >= 66 - { - if ((is_possible_tropical_area_by_latitude && (get_region_parameter(y, x, 0) < 66)) || is_tropical_area_by_latitude) - return df::enums::biome_type::biome_type::MARSH_TROPICAL_SALTWATER; // 11 - else - return df::enums::biome_type::biome_type::MARSH_TEMPERATE_SALTWATER; // 6 - } -} - -//----------------------------------------------------------------------------// -// Utility function -// -//----------------------------------------------------------------------------// -int get_biome_shrubland_or_marsh(df::region_map_entry& region, - bool is_possible_tropical_area_by_latitude, - bool is_tropical_area_by_latitude, - int y, - int x -) -{ - if (region.drainage >= 33) - return get_biome_shrubland(is_possible_tropical_area_by_latitude, - is_tropical_area_by_latitude, - y, - x - ); - // drainage < 33 - return get_biome_marsh(region, - is_possible_tropical_area_by_latitude, - is_tropical_area_by_latitude, - y, - x - ); -} - - -//----------------------------------------------------------------------------// -// Utility function -// -//----------------------------------------------------------------------------// -int get_biome_forest(df::region_map_entry& region, - bool is_possible_tropical_area_by_latitude, - bool is_tropical_area_by_latitude, - int y, - int x -) -{ - int parameter = get_region_parameter(y, x, 0); - - // drainage >= 33, not tropical area - if (!is_possible_tropical_area_by_latitude) - { - if ((region.rainfall < 75) || (region.temperature < 65)) - { - if (region.temperature >= 10) - return df::enums::biome_type::biome_type::FOREST_TEMPERATE_CONIFER; // 13 - else - return df::enums::biome_type::biome_type::FOREST_TAIGA; // 12 - } - else - return df::enums::biome_type::biome_type::FOREST_TEMPERATE_BROADLEAF; // 14 - } - else // drainage >= 33, tropical area - { - if (((parameter < 66) || is_tropical_area_by_latitude) && (region.rainfall < 75)) - return df::enums::biome_type::biome_type::FOREST_TROPICAL_CONIFER; // 15 - if (parameter < 66) - return df::enums::biome_type::biome_type::FOREST_TROPICAL_DRY_BROADLEAF; // 16 - if (is_tropical_area_by_latitude) - return df::enums::biome_type::biome_type::FOREST_TROPICAL_MOIST_BROADLEAF; // 17 - else - { - if ((region.rainfall < 75) || (region.temperature < 65)) - { - if (region.temperature >= 10) - return df::enums::biome_type::biome_type::FOREST_TEMPERATE_CONIFER; // 13 - else - return df::enums::biome_type::biome_type::FOREST_TAIGA; // 12 - } - else - return df::enums::biome_type::biome_type::FOREST_TEMPERATE_BROADLEAF; // 14 - } - } -} - -//----------------------------------------------------------------------------// -// Utility function -// -//----------------------------------------------------------------------------// -int get_biome_swamp(df::region_map_entry& region, - bool is_possible_tropical_area_by_latitude, - bool is_tropical_area_by_latitude, - int y, - int x -) -{ - int parameter = get_region_parameter(y, x, 0); - - if (is_possible_tropical_area_by_latitude) - { - if (region.salinity < 66) - { - if ((parameter < 66) || is_tropical_area_by_latitude) - return df::enums::biome_type::biome_type::SWAMP_TROPICAL_FRESHWATER; // 7 - else - return df::enums::biome_type::biome_type::SWAMP_TEMPERATE_FRESHWATER;// 3 - } - else // elevation between 100 and 149, vegetation >= 66, drainage < 33, salinity >= 66 - { - if ((parameter < 66) || is_tropical_area_by_latitude) - { - if (region.drainage < 10) - return df::enums::biome_type::biome_type::SWAMP_MANGROVE; //9 - else // drainage >= 10 - return df::enums::biome_type::biome_type::SWAMP_TROPICAL_SALTWATER; // 8 - } - else - return df::enums::biome_type::biome_type::SWAMP_TEMPERATE_SALTWATER; // 4 - } - } - else // elevation between 100 and 149, vegetation >= 66, drainage < 33, not tropical area - { - if (region.salinity >= 66) - return df::enums::biome_type::biome_type::SWAMP_TEMPERATE_SALTWATER; // 4 - else - return df::enums::biome_type::biome_type::SWAMP_TEMPERATE_FRESHWATER; // 3 - } -} \ No newline at end of file diff --git a/plugins/embark-assistant/biome_type.h b/plugins/embark-assistant/biome_type.h deleted file mode 100644 index 9ea562749..000000000 --- a/plugins/embark-assistant/biome_type.h +++ /dev/null @@ -1,7 +0,0 @@ -// world_coord_x/y is the location of the tile "owning" the biome, while world_ref_coord_y is the -// location of the tile the biome appears on. They differ when a mid level tile ("region tile") -// refers to a neighboring tile for the biome parameters. The difference can affect the tropicality -// determination. Since Tropicality is determined by latitude, the x coordinate of the reference is -// omitted. -// -int get_biome_type(int world_coord_x, int world_coord_y, int world_ref_coord_y); diff --git a/plugins/embark-assistant/survey.cpp b/plugins/embark-assistant/survey.cpp index f19f3cd4a..68cd3597f 100644 --- a/plugins/embark-assistant/survey.cpp +++ b/plugins/embark-assistant/survey.cpp @@ -8,6 +8,7 @@ #include #include "modules/Materials.h" +#include "modules/Maps.h" #include "DataDefs.h" #include "df/builtin_mats.h" @@ -55,7 +56,6 @@ #include "df/world_site_type.h" #include "df/world_underground_region.h" -#include "biome_type.h" #include "defs.h" #include "survey.h" @@ -586,7 +586,7 @@ void embark_assist::survey::high_level_world_survey(embark_assist::defs::geo_dat offset_count++; 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); + results.biome[l] = DFHack::Maps::GetBiomeTypeWithRef(adjusted.x, adjusted.y, k); temperature = world_data->region_map[adjusted.x][adjusted.y].temperature; negative = temperature < 0;