aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation
diff options
context:
space:
mode:
author Hop311 <hop3114@gmail.com>2023-09-25 20:04:07 +0200
committer Hop311 <hop3114@gmail.com>2023-09-25 20:04:07 +0200
commitb84f5a03b40f1925c456cd247c2c2f04af8ef778 (patch)
treecec684e859b9631bd581699563800bb9888990db /src/openvic-simulation
parentbbfa8faf5337ebdff60ef2106074417aa628eca1 (diff)
Calculate terrain types from pixels
Diffstat (limited to 'src/openvic-simulation')
-rw-r--r--src/openvic-simulation/GameManager.cpp30
-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
-rw-r--r--src/openvic-simulation/types/Date.cpp2
7 files changed, 97 insertions, 26 deletions
diff --git a/src/openvic-simulation/GameManager.cpp b/src/openvic-simulation/GameManager.cpp
index d969132..1d95aa4 100644
--- a/src/openvic-simulation/GameManager.cpp
+++ b/src/openvic-simulation/GameManager.cpp
@@ -132,16 +132,23 @@ bool GameManager::expand_building(Province::index_t province_index, const std::s
return province->expand_building(building_type_identifier);
}
+static constexpr colour_t LOW_ALPHA_VALUE = float_to_alpha_value(0.4f);
+static constexpr colour_t HIGH_ALPHA_VALUE = float_to_alpha_value(0.7f);
+static constexpr colour_t LAND_COLOUR = 0x0D7017;
+static constexpr colour_t WATER_COLOUR = 0x4287F5;
+
+static colour_t default_colour(Province const& province) {
+ return LOW_ALPHA_VALUE | (province.get_water() ? WATER_COLOUR : LAND_COLOUR);
+}
+
bool GameManager::load_hardcoded_defines() {
bool ret = true;
- static constexpr colour_t LOW_ALPHA_VALUE = float_to_alpha_value(0.4f);
- static constexpr colour_t HIGH_ALPHA_VALUE = float_to_alpha_value(0.7f);
using mapmode_t = std::pair<std::string, Mapmode::colour_func_t>;
const std::vector<mapmode_t> mapmodes {
{ "mapmode_terrain",
[](Map const&, Province const& province) -> colour_t {
- return LOW_ALPHA_VALUE | (province.get_water() ? 0x4287F5 : 0x0D7017);
+ return default_colour(province);
} },
{ "mapmode_province",
[](Map const&, Province const& province) -> colour_t {
@@ -150,19 +157,22 @@ bool GameManager::load_hardcoded_defines() {
{ "mapmode_region",
[](Map const&, Province const& province) -> colour_t {
Region const* region = province.get_region();
- if (region != nullptr) return HIGH_ALPHA_VALUE | region->get_colour();
- return NULL_COLOUR;
+ return region != nullptr ? HIGH_ALPHA_VALUE | region->get_colour() : default_colour(province);
} },
{ "mapmode_index",
[](Map const& map, Province const& province) -> colour_t {
const colour_t f = fraction_to_colour_byte(province.get_index(), map.get_province_count() + 1);
return HIGH_ALPHA_VALUE | (f << 16) | (f << 8) | f;
} },
+ { "mapmode_terrain_type",
+ [](Map const& map, Province const& province) -> colour_t {
+ TerrainType const* terrarin_type = province.get_terrain_type();
+ return terrarin_type != nullptr ? HIGH_ALPHA_VALUE | terrarin_type->get_colour() : default_colour(province);
+ } },
{ "mapmode_rgo",
[](Map const& map, Province const& province) -> colour_t {
Good const* rgo = province.get_rgo();
- if (rgo != nullptr) return HIGH_ALPHA_VALUE | rgo->get_colour();
- return NULL_COLOUR;
+ return rgo != nullptr ? HIGH_ALPHA_VALUE | rgo->get_colour() : default_colour(province);
} },
{ "mapmode_infrastructure",
[](Map const& map, Province const& province) -> colour_t {
@@ -176,7 +186,7 @@ bool GameManager::load_hardcoded_defines() {
}
return HIGH_ALPHA_VALUE | val;
}
- return NULL_COLOUR;
+ return default_colour(province);
} },
{ "mapmode_population",
[](Map const& map, Province const& province) -> colour_t {
@@ -185,12 +195,12 @@ bool GameManager::load_hardcoded_defines() {
{ "mapmode_culture",
[](Map const& map, Province const& province) -> colour_t {
HasIdentifierAndColour const* largest = get_largest_item(province.get_culture_distribution()).first;
- return largest != nullptr ? HIGH_ALPHA_VALUE | largest->get_colour() : NULL_COLOUR;
+ return largest != nullptr ? HIGH_ALPHA_VALUE | largest->get_colour() : default_colour(province);
} },
{ "mapmode_religion",
[](Map const& map, Province const& province) -> colour_t {
HasIdentifierAndColour const* largest = get_largest_item(province.get_religion_distribution()).first;
- return largest != nullptr ? HIGH_ALPHA_VALUE | largest->get_colour() : NULL_COLOUR;
+ return largest != nullptr ? HIGH_ALPHA_VALUE | largest->get_colour() : default_colour(province);
} }
};
for (mapmode_t const& mapmode : mapmodes)
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);
diff --git a/src/openvic-simulation/types/Date.cpp b/src/openvic-simulation/types/Date.cpp
index 3449591..203d647 100644
--- a/src/openvic-simulation/types/Date.cpp
+++ b/src/openvic-simulation/types/Date.cpp
@@ -190,7 +190,7 @@ Date Date::from_string(char const* const str, char const* const end, bool* succe
bool sub_successful = false;
uint64_t val = StringUtils::string_to_uint64(str, year_end, &sub_successful, 10);
- if (!sub_successful || val >= 1 << (8 * sizeof(year_t))) {
+ if (!sub_successful || val > std::numeric_limits<year_t>::max()) {
Logger::error("Failed to read year: ", std::string_view { str, static_cast<size_t>(end - str) });
if (successful != nullptr) *successful = false;
return { year, month, day };