diff options
author | Hop311 <hop3114@gmail.com> | 2023-09-25 20:04:07 +0200 |
---|---|---|
committer | Hop311 <hop3114@gmail.com> | 2023-09-25 20:04:07 +0200 |
commit | b84f5a03b40f1925c456cd247c2c2f04af8ef778 (patch) | |
tree | cec684e859b9631bd581699563800bb9888990db /src/openvic-simulation/map | |
parent | bbfa8faf5337ebdff60ef2106074417aa628eca1 (diff) |
Calculate terrain types from pixels
Diffstat (limited to 'src/openvic-simulation/map')
-rw-r--r-- | src/openvic-simulation/map/Map.cpp | 36 | ||||
-rw-r--r-- | src/openvic-simulation/map/Province.cpp | 12 | ||||
-rw-r--r-- | src/openvic-simulation/map/Province.hpp | 13 | ||||
-rw-r--r-- | src/openvic-simulation/map/TerrainType.cpp | 26 | ||||
-rw-r--r-- | src/openvic-simulation/map/TerrainType.hpp | 4 |
5 files changed, 76 insertions, 15 deletions
diff --git a/src/openvic-simulation/map/Map.cpp b/src/openvic-simulation/map/Map.cpp index 203e100..936feba 100644 --- a/src/openvic-simulation/map/Map.cpp +++ b/src/openvic-simulation/map/Map.cpp @@ -453,6 +453,7 @@ bool Map::load_map_images(fs::path const& province_path, fs::path const& terrain uint8_t const* terrain_data = terrain_bmp.get_pixel_data().data(); std::vector<bool> province_checklist(provinces.size()); + std::vector<distribution_t> terrain_type_pixels_list(provinces.size()); bool ret = true; std::unordered_set<colour_t> unrecognised_province_colours; @@ -460,28 +461,28 @@ bool Map::load_map_images(fs::path const& province_path, fs::path const& terrain for (size_t x = 0; x < width; ++x) { const size_t idx = x + y * width; - province_shape_image[idx].terrain = terrain_data[idx] < terrain_type_manager.get_terrain_texture_limit() ? terrain_data[idx] + 1 : 0; - const colour_t province_colour = colour_at(province_data, idx); if (x > 0) { const size_t jdx = idx - 1; if (colour_at(province_data, jdx) == province_colour) { province_shape_image[idx].index = province_shape_image[jdx].index; - continue; + goto set_terrain; } } if (y > 0) { const size_t jdx = idx - width; if (colour_at(province_data, jdx) == province_colour) { province_shape_image[idx].index = province_shape_image[jdx].index; - continue; + goto set_terrain; } } - const Province::index_t index = get_index_from_colour(province_colour); - if (index != Province::NULL_INDEX) { - province_checklist[index - 1] = true; - province_shape_image[idx].index = index; - continue; + { + const Province::index_t index = get_index_from_colour(province_colour); + if (index != Province::NULL_INDEX) { + province_checklist[index - 1] = true; + province_shape_image[idx].index = index; + goto set_terrain; + } } if (unrecognised_province_colours.find(province_colour) == unrecognised_province_colours.end()) { unrecognised_province_colours.insert(province_colour); @@ -491,6 +492,19 @@ bool Map::load_map_images(fs::path const& province_path, fs::path const& terrain } } province_shape_image[idx].index = Province::NULL_INDEX; + + set_terrain: + const TerrainTypeMapping::index_t terrain = terrain_data[idx]; + TerrainTypeMapping const* mapping = terrain_type_manager.get_terrain_type_mapping_for(terrain); + if (mapping != nullptr) { + if (province_shape_image[idx].index != Province::NULL_INDEX) { + terrain_type_pixels_list[province_shape_image[idx].index - 1][&mapping->get_type()]++; + } + + province_shape_image[idx].terrain = mapping->get_has_texture() && terrain < terrain_type_manager.get_terrain_texture_limit() ? terrain + 1 : 0; + } else { + province_shape_image[idx].terrain = 0; + } } } @@ -500,9 +514,11 @@ bool Map::load_map_images(fs::path const& province_path, fs::path const& terrain size_t missing = 0; for (size_t idx = 0; idx < province_checklist.size(); ++idx) { + Province* province = provinces.get_item_by_index(idx); + province->_set_terrain_type(reinterpret_cast<TerrainType const*>(get_largest_item(terrain_type_pixels_list[idx]).first)); if (!province_checklist[idx]) { if (detailed_errors) { - Logger::error("Province missing from shape image: ", provinces.get_item_by_index(idx)->to_string()); + Logger::error("Province missing from shape image: ", province->to_string()); } missing++; } diff --git a/src/openvic-simulation/map/Province.cpp b/src/openvic-simulation/map/Province.cpp index c1e96e9..ef574cf 100644 --- a/src/openvic-simulation/map/Province.cpp +++ b/src/openvic-simulation/map/Province.cpp @@ -6,6 +6,8 @@ #include <iterator> #include <sstream> +#include "openvic-simulation/map/TerrainType.hpp" + using namespace OpenVic; using namespace OpenVic::NodeTools; @@ -32,6 +34,10 @@ bool Province::get_water() const { return water; } +TerrainType const* Province::get_terrain_type() const { + return terrain_type; +} + Province::life_rating_t Province::get_life_rating() const { return life_rating; } @@ -149,7 +155,7 @@ Province::distance_t Province::adjacency_t::get_distance() const { return distance; } -Province::flags_t Province::adjacency_t::get_flags() { +Province::flags_t Province::adjacency_t::get_flags() const { return flags; } @@ -175,3 +181,7 @@ bool Province::add_adjacency(Province const* province, distance_t distance, flag std::vector<Province::adjacency_t> const& Province::get_adjacencies() const { return adjacencies; } + +void Province::_set_terrain_type(TerrainType const* type) { + terrain_type = type; +} diff --git a/src/openvic-simulation/map/Province.hpp b/src/openvic-simulation/map/Province.hpp index 0a4aa46..6e4ac7e 100644 --- a/src/openvic-simulation/map/Province.hpp +++ b/src/openvic-simulation/map/Province.hpp @@ -1,5 +1,7 @@ #pragma once +#include <limits> + #include "openvic-simulation/map/Building.hpp" #include "openvic-simulation/pop/Pop.hpp" @@ -7,6 +9,8 @@ namespace OpenVic { struct Map; struct Region; struct Good; + struct TerrainType; + struct TerrainTypeMapping; /* REQUIREMENTS: * MAP-5, MAP-7, MAP-8, MAP-43, MAP-47 @@ -32,10 +36,10 @@ namespace OpenVic { public: distance_t get_distance() const; - flags_t get_flags(); + flags_t get_flags() const; }; - static constexpr index_t NULL_INDEX = 0, MAX_INDEX = (1 << (8 * sizeof(index_t))) - 1; + static constexpr index_t NULL_INDEX = 0, MAX_INDEX = std::numeric_limits<index_t>::max(); private: const index_t index; @@ -52,6 +56,10 @@ namespace OpenVic { std::vector<adjacency_t> adjacencies; + TerrainType const* terrain_type = nullptr; + + void _set_terrain_type(TerrainType const* type); + Province(const std::string_view new_identifier, colour_t new_colour, index_t new_index); public: @@ -61,6 +69,7 @@ namespace OpenVic { Region* get_region() const; bool get_has_region() const; bool get_water() const; + TerrainType const* get_terrain_type() const; life_rating_t get_life_rating() const; bool load_positions(BuildingManager const& building_manager, ast::NodeCPtr root); diff --git a/src/openvic-simulation/map/TerrainType.cpp b/src/openvic-simulation/map/TerrainType.cpp index 8464421..3134332 100644 --- a/src/openvic-simulation/map/TerrainType.cpp +++ b/src/openvic-simulation/map/TerrainType.cpp @@ -1,5 +1,7 @@ #include "TerrainType.hpp" +#include <limits> + using namespace OpenVic; using namespace OpenVic::NodeTools; @@ -59,7 +61,19 @@ bool TerrainTypeManager::add_terrain_type_mapping(const std::string_view identif Logger::error("Null terrain type for mapping ", identifier); return false; } - return terrain_type_mappings.add_item({ identifier, *type, std::move(terrain_indicies), priority, has_texture }); + bool ret = true; + for (TerrainTypeMapping::index_t idx : terrain_indicies) { + const terrain_type_mappings_map_t::const_iterator it = terrain_type_mappings_map.find(idx); + if (it == terrain_type_mappings_map.end()) { + terrain_type_mappings_map.emplace(idx, terrain_type_mappings.size()); + } else { + Logger::error("Terrain index ", static_cast<size_t>(idx), " cannot map to ", identifier, + " as it already maps to ", terrain_type_mappings.get_item_by_index(it->second)); + ret = false; + } + } + ret &= terrain_type_mappings.add_item({ identifier, *type, std::move(terrain_indicies), priority, has_texture }); + return ret; } bool TerrainTypeManager::_load_terrain_type_categories(ModifierManager const& modifier_manager, ast::NodeCPtr root) { @@ -115,7 +129,7 @@ bool TerrainTypeManager::_load_terrain_type_mapping(std::string_view mapping_key "type", ONE_EXACTLY, expect_terrain_type_identifier(assign_variable_callback_pointer(type)), "color", ONE_EXACTLY, expect_list_reserve_length(terrain_indicies, expect_uint( [&terrain_indicies](uint64_t val) -> bool { - if (val <= 1 << 8 * sizeof(TerrainTypeMapping::index_t)) { + if (val <= std::numeric_limits<TerrainTypeMapping::index_t>::max()) { TerrainTypeMapping::index_t index = val; if (std::find(terrain_indicies.begin(), terrain_indicies.end(), index) == terrain_indicies.end()) { terrain_indicies.push_back(val); @@ -141,6 +155,14 @@ bool TerrainTypeManager::_load_terrain_type_mapping(std::string_view mapping_key return true; } +TerrainTypeMapping const* TerrainTypeManager::get_terrain_type_mapping_for(TerrainTypeMapping::index_t idx) const { + const terrain_type_mappings_map_t::const_iterator it = terrain_type_mappings_map.find(idx); + if (it != terrain_type_mappings_map.end()) { + return terrain_type_mappings.get_item_by_index(it->second); + } + return nullptr; +} + TerrainTypeMapping::index_t TerrainTypeManager::get_terrain_texture_limit() const { return terrain_texture_limit; } diff --git a/src/openvic-simulation/map/TerrainType.hpp b/src/openvic-simulation/map/TerrainType.hpp index 48b811a..0cc28c2 100644 --- a/src/openvic-simulation/map/TerrainType.hpp +++ b/src/openvic-simulation/map/TerrainType.hpp @@ -43,8 +43,10 @@ namespace OpenVic { struct TerrainTypeManager { private: + using terrain_type_mappings_map_t = std::map<TerrainTypeMapping::index_t, size_t>; IdentifierRegistry<TerrainType> terrain_types; IdentifierRegistry<TerrainTypeMapping> terrain_type_mappings; + terrain_type_mappings_map_t terrain_type_mappings_map; TerrainTypeMapping::index_t terrain_texture_limit = 0, terrain_texture_count = 0; @@ -61,6 +63,8 @@ namespace OpenVic { std::vector<TerrainTypeMapping::index_t>&& terrain_indicies, TerrainTypeMapping::index_t priority, bool has_texture); IDENTIFIER_REGISTRY_ACCESSORS(TerrainTypeMapping, terrain_type_mapping) + TerrainTypeMapping const* get_terrain_type_mapping_for(TerrainTypeMapping::index_t idx) const; + TerrainTypeMapping::index_t get_terrain_texture_limit() const; bool load_terrain_types(ModifierManager const& modifier_manager, ast::NodeCPtr root); |