aboutsummaryrefslogtreecommitdiff
path: root/src/openvic/map
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvic/map')
-rw-r--r--src/openvic/map/Map.cpp125
-rw-r--r--src/openvic/map/Map.hpp12
-rw-r--r--src/openvic/map/Province.cpp22
-rw-r--r--src/openvic/map/Province.hpp4
-rw-r--r--src/openvic/map/Region.cpp12
-rw-r--r--src/openvic/map/Region.hpp3
6 files changed, 168 insertions, 10 deletions
diff --git a/src/openvic/map/Map.cpp b/src/openvic/map/Map.cpp
index c9dd9d2..439338b 100644
--- a/src/openvic/map/Map.cpp
+++ b/src/openvic/map/Map.cpp
@@ -31,8 +31,8 @@ Map::Map() : provinces { "provinces" },
mapmodes { "mapmodes" } {}
return_t Map::add_province(const std::string_view identifier, colour_t colour) {
- if (provinces.size() >= Province::MAX_INDEX) {
- Logger::error("The map's province list is full - there can be at most ", Province::MAX_INDEX, " provinces");
+ if (provinces.size() >= max_provinces) {
+ Logger::error("The map's province list is full - maximum number of provinces is ", max_provinces, " (this can be at most ", Province::MAX_INDEX, ")");
return FAILURE;
}
if (identifier.empty()) {
@@ -40,7 +40,7 @@ return_t Map::add_province(const std::string_view identifier, colour_t colour) {
return FAILURE;
}
if (colour == NULL_COLOUR || colour > MAX_COLOUR_RGB) {
- Logger::error("Invalid province colour for ", identifier, ": ", Province::colour_to_hex_string(colour));
+ Logger::error("Invalid province colour for ", identifier, ": ", colour_to_hex_string(colour));
return FAILURE;
}
Province new_province { identifier, colour, static_cast<Province::index_t>(provinces.size() + 1) };
@@ -79,9 +79,20 @@ return_t Map::set_water_province(const std::string_view identifier) {
return SUCCESS;
}
+return_t Map::set_water_province_list(std::vector<std::string_view> const& list) {
+ return_t ret = SUCCESS;
+ water_provinces.reserve(water_provinces.size() + list.size());
+ for (std::string_view const& identifier : list) {
+ if (set_water_province(identifier) != SUCCESS) {
+ ret = FAILURE;
+ }
+ }
+ return ret;
+}
+
void Map::lock_water_provinces() {
water_provinces.lock();
- Logger::info("Locked water provinces after registering ", water_provinces.get_province_count());
+ Logger::info("Locked water provinces after registering ", water_provinces.size());
}
return_t Map::add_region(const std::string_view identifier, std::vector<std::string_view> const& province_identifiers) {
@@ -117,7 +128,7 @@ return_t Map::add_region(const std::string_view identifier, std::vector<std::str
}
}
new_region.lock();
- if (!new_region.get_province_count()) {
+ if (!new_region.size()) {
Logger::error("No valid provinces in list for ", identifier);
return FAILURE;
}
@@ -142,6 +153,10 @@ size_t Map::get_province_count() const {
return provinces.size();
}
+std::vector<Province> const& Map::get_provinces() const {
+ return provinces.get_items();
+}
+
Province* Map::get_province_by_index(Province::index_t index) {
return index != Province::NULL_INDEX ? provinces.get_item_by_index(index - 1) : nullptr;
}
@@ -169,6 +184,23 @@ Province::index_t Map::get_province_index_at(size_t x, size_t y) const {
return Province::NULL_INDEX;
}
+return_t Map::set_max_provinces(Province::index_t new_max_provinces) {
+ if (new_max_provinces <= Province::NULL_INDEX) {
+ Logger::error("Trying to set max province count to an invalid value ", new_max_provinces, " (must be greater than ", Province::NULL_INDEX, ")");
+ return FAILURE;
+ }
+ if (!provinces.empty() || provinces.is_locked()) {
+ Logger::error("Trying to set max province count to ", new_max_provinces, " after provinces have already been added and/or locked");
+ return FAILURE;
+ }
+ max_provinces = new_max_provinces;
+ return SUCCESS;
+}
+
+Province::index_t Map::get_max_provinces() const {
+ return max_provinces;
+}
+
void Map::set_selected_province(Province::index_t index) {
if (index > get_province_count()) {
Logger::error("Trying to set selected province to an invalid index ", index, " (max index is ", get_province_count(), ")");
@@ -194,6 +226,14 @@ Region const* Map::get_region_by_identifier(const std::string_view identifier) c
return regions.get_item_by_identifier(identifier);
}
+size_t Map::get_region_count() const {
+ return regions.size();
+}
+
+std::vector<Region> const& Map::get_regions() const {
+ return regions.get_items();
+}
+
static colour_t colour_at(uint8_t const* colour_data, int32_t idx) {
idx *= 3;
return (colour_data[idx] << 16) | (colour_data[idx + 1] << 8) | colour_data[idx + 2];
@@ -240,7 +280,7 @@ return_t Map::generate_province_shape_image(size_t new_width, size_t new_height,
if (unrecognised_terrain_colours.find(terrain_colour) == unrecognised_terrain_colours.end()) {
unrecognised_terrain_colours.insert(terrain_colour);
if (detailed_errors) {
- Logger::error("Unrecognised terrain colour ", Province::colour_to_hex_string(terrain_colour),
+ Logger::error("Unrecognised terrain colour ", colour_to_hex_string(terrain_colour),
" at (", x, ", ", y, ")");
}
}
@@ -271,7 +311,7 @@ return_t Map::generate_province_shape_image(size_t new_width, size_t new_height,
if (unrecognised_province_colours.find(province_colour) == unrecognised_province_colours.end()) {
unrecognised_province_colours.insert(province_colour);
if (detailed_errors) {
- Logger::error("Unrecognised province colour ", Province::colour_to_hex_string(province_colour),
+ Logger::error("Unrecognised province colour ", colour_to_hex_string(province_colour),
" at (", x, ", ", y, ")");
}
}
@@ -335,6 +375,10 @@ size_t Map::get_mapmode_count() const {
return mapmodes.size();
}
+std::vector<Mapmode> const& Map::get_mapmodes() const {
+ return mapmodes.get_items();
+}
+
Mapmode const* Map::get_mapmode_by_index(size_t index) const {
return mapmodes.get_item_by_index(index);
}
@@ -418,3 +462,70 @@ void Map::tick(Date const& today) {
for (Province& province : provinces.get_items())
province.tick(today);
}
+
+using namespace ovdl::csv;
+
+static return_t validate_province_definitions_header(LineObject const& header) {
+ static const std::vector<std::string> standard_header { "province", "red", "green", "blue" };
+ for (size_t i = 0; i < standard_header.size(); ++i) {
+ const std::string_view val = header.get_value_for(i);
+ if (i == 0 && val.empty()) break;
+ if (val != standard_header[i]) return FAILURE;
+ }
+ return SUCCESS;
+}
+
+static return_t parse_province_colour(colour_t& colour, std::array<std::string_view, 3> components) {
+ return_t ret = SUCCESS;
+ colour = NULL_COLOUR;
+ for (std::string_view& c : components) {
+ colour <<= 8;
+ if (c.ends_with('.')) c.remove_suffix(1);
+ bool successful = false;
+ uint64_t val = StringUtils::string_to_uint64(c, &successful, 10);
+ if (successful && val <= 255) {
+ colour |= val;
+ } else {
+ ret = FAILURE;
+ }
+ }
+ return ret;
+}
+
+return_t Map::load_province_definitions(std::vector<LineObject> const& lines) {
+ if (lines.empty()) {
+ Logger::error("No header or entries in province definition file!");
+ return FAILURE;
+ }
+ {
+ LineObject const& header = lines.front();
+ if (validate_province_definitions_header(header) != SUCCESS) {
+ Logger::error("Non-standard province definition file header - make sure this is not a province definition: ", header);
+ }
+ }
+ if (lines.size() <= 1) {
+ Logger::error("No entries in province definition file!");
+ return FAILURE;
+ }
+ provinces.reserve(lines.size() - 1);
+ return_t ret = SUCCESS;
+ std::for_each(lines.begin() + 1, lines.end(),
+ [this, &ret](LineObject const& line) -> void {
+ const std::string_view identifier = line.get_value_for(0);
+ if (!identifier.empty()) {
+ colour_t colour;
+ if (parse_province_colour(colour, {
+ line.get_value_for(1),
+ line.get_value_for(2),
+ line.get_value_for(3)
+ }) != SUCCESS) {
+ Logger::error("Error reading colour in province definition: ", line);
+ ret = FAILURE;
+ }
+ if (add_province(identifier, colour) != SUCCESS) ret = FAILURE;
+ }
+ }
+ );
+ lock_provinces();
+ return ret;
+}
diff --git a/src/openvic/map/Map.hpp b/src/openvic/map/Map.hpp
index 26c07c8..0a2c7c6 100644
--- a/src/openvic/map/Map.hpp
+++ b/src/openvic/map/Map.hpp
@@ -2,6 +2,8 @@
#include <functional>
+#include <openvic-dataloader/csv/LineObject.hpp>
+
#include "openvic/map/Region.hpp"
namespace OpenVic {
@@ -53,6 +55,7 @@ namespace OpenVic {
size_t width = 0, height = 0;
std::vector<shape_pixel_t> province_shape_image;
colour_index_map_t colour_index_map;
+ Province::index_t max_provinces = Province::MAX_INDEX;
Province::index_t selected_province = Province::NULL_INDEX;
Pop::pop_size_t highest_province_population, total_map_population;
@@ -65,22 +68,28 @@ namespace OpenVic {
return_t add_province(const std::string_view identifier, colour_t colour);
void lock_provinces();
return_t set_water_province(const std::string_view identifier);
+ return_t set_water_province_list(std::vector<std::string_view> const& list);
void lock_water_provinces();
return_t add_region(const std::string_view identifier, std::vector<std::string_view> const& province_identifiers);
void lock_regions();
size_t get_province_count() const;
+ std::vector<Province> const& get_provinces() const;
Province* get_province_by_index(Province::index_t index);
Province const* get_province_by_index(Province::index_t index) const;
Province* get_province_by_identifier(const std::string_view identifier);
Province const* get_province_by_identifier(const std::string_view identifier) const;
Province::index_t get_province_index_at(size_t x, size_t y) const;
+ return_t set_max_provinces(Province::index_t new_max_provinces);
+ Province::index_t get_max_provinces() const;
void set_selected_province(Province::index_t index);
Province::index_t get_selected_province_index() const;
Province const* get_selected_province() const;
Region* get_region_by_identifier(const std::string_view identifier);
Region const* get_region_by_identifier(const std::string_view identifier) const;
+ size_t get_region_count() const;
+ std::vector<Region> const& get_regions() const;
return_t generate_province_shape_image(size_t new_width, size_t new_height, uint8_t const* colour_data,
uint8_t const* terrain_data, terrain_variant_map_t const& terrain_variant_map, bool detailed_errors);
@@ -91,6 +100,7 @@ namespace OpenVic {
return_t add_mapmode(const std::string_view identifier, Mapmode::colour_func_t colour_func);
void lock_mapmodes();
size_t get_mapmode_count() const;
+ std::vector<Mapmode> const& get_mapmodes() const;
Mapmode const* get_mapmode_by_index(Mapmode::index_t index) const;
Mapmode const* get_mapmode_by_identifier(const std::string_view identifier) const;
static constexpr size_t MAPMODE_COLOUR_SIZE = 4;
@@ -105,5 +115,7 @@ namespace OpenVic {
void update_state(Date const& today);
void tick(Date const& today);
+
+ return_t load_province_definitions(std::vector<ovdl::csv::LineObject> const& lines);
};
}
diff --git a/src/openvic/map/Province.cpp b/src/openvic/map/Province.cpp
index f4588d4..7d03604 100644
--- a/src/openvic/map/Province.cpp
+++ b/src/openvic/map/Province.cpp
@@ -5,6 +5,7 @@
#include <sstream>
using namespace OpenVic;
+using namespace OpenVic::NodeTools;
Province::Province(const std::string_view new_identifier, colour_t new_colour, index_t new_index)
: HasIdentifierAndColour { new_identifier, new_colour, false },
@@ -45,6 +46,10 @@ Building const* Province::get_building_by_identifier(const std::string_view iden
return buildings.get_item_by_identifier(identifier);
}
+size_t Province::get_building_count() const {
+ return buildings.size();
+}
+
std::vector<Building> const& Province::get_buildings() const {
return buildings.get_items();
}
@@ -65,6 +70,15 @@ std::string Province::to_string() const {
return stream.str();
}
+return_t Province::load_pop_list(PopManager const& pop_manager, ast::NodeCPtr root) {
+ return expect_list_reserve_length(
+ pops,
+ [this, &pop_manager](ast::NodeCPtr pop_node) -> return_t {
+ return pop_manager.load_pop_into_province(*this, pop_node);
+ }
+ )(root);
+}
+
return_t Province::add_pop(Pop&& pop) {
if (!is_water()) {
pops.push_back(std::move(pop));
@@ -79,6 +93,14 @@ void Province::clear_pops() {
pops.clear();
}
+size_t Province::get_pop_count() const {
+ return pops.size();
+}
+
+std::vector<Pop> const& Province::get_pops() const {
+ return pops;
+}
+
Pop::pop_size_t Province::get_total_population() const {
return total_population;
}
diff --git a/src/openvic/map/Province.hpp b/src/openvic/map/Province.hpp
index 527a6fe..364bbf8 100644
--- a/src/openvic/map/Province.hpp
+++ b/src/openvic/map/Province.hpp
@@ -45,13 +45,17 @@ namespace OpenVic {
void lock_buildings();
void reset_buildings();
Building const* get_building_by_identifier(const std::string_view identifier) const;
+ size_t get_building_count() const;
std::vector<Building> const& get_buildings() const;
return_t expand_building(const std::string_view building_type_identifier);
Good const* get_rgo() const;
std::string to_string() const;
+ return_t load_pop_list(PopManager const& pop_manager, ast::NodeCPtr root);
return_t add_pop(Pop&& pop);
void clear_pops();
+ size_t get_pop_count() const;
+ std::vector<Pop> const& get_pops() const;
Pop::pop_size_t get_total_population() const;
distribution_t const& get_pop_type_distribution() const;
distribution_t const& get_culture_distribution() const;
diff --git a/src/openvic/map/Region.cpp b/src/openvic/map/Region.cpp
index 8ea45f0..6372e15 100644
--- a/src/openvic/map/Region.cpp
+++ b/src/openvic/map/Region.cpp
@@ -24,7 +24,7 @@ void ProvinceSet::lock(bool log) {
Logger::error("Failed to lock province set - already locked!");
} else {
locked = true;
- if (log) Logger::info("Locked province set with ", get_province_count(), " provinces");
+ if (log) Logger::info("Locked province set with ", size(), " provinces");
}
}
@@ -37,10 +37,18 @@ void ProvinceSet::reset() {
locked = false;
}
-size_t ProvinceSet::get_province_count() const {
+size_t ProvinceSet::size() const {
return provinces.size();
}
+void ProvinceSet::reserve(size_t size) {
+ if (locked) {
+ Logger::error("Failed to reserve space for ", size, " items in province set - already locked!");
+ } else {
+ provinces.reserve(size);
+ }
+}
+
bool ProvinceSet::contains_province(Province const* province) const {
return province && std::find(provinces.begin(), provinces.end(), province) != provinces.end();
}
diff --git a/src/openvic/map/Region.hpp b/src/openvic/map/Region.hpp
index 9b5b914..e67edaa 100644
--- a/src/openvic/map/Region.hpp
+++ b/src/openvic/map/Region.hpp
@@ -14,7 +14,8 @@ namespace OpenVic {
void lock(bool log = false);
bool is_locked() const;
void reset();
- size_t get_province_count() const;
+ size_t size() const;
+ void reserve(size_t size);
bool contains_province(Province const* province) const;
std::vector<Province*> const& get_provinces() const;
};