aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/map
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvic-simulation/map')
-rw-r--r--src/openvic-simulation/map/Map.cpp36
-rw-r--r--src/openvic-simulation/map/Province.cpp12
-rw-r--r--src/openvic-simulation/map/Province.hpp13
-rw-r--r--src/openvic-simulation/map/TerrainType.cpp26
-rw-r--r--src/openvic-simulation/map/TerrainType.hpp4
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);