aboutsummaryrefslogtreecommitdiff
path: root/src/openvic/map/Map.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvic/map/Map.cpp')
-rw-r--r--src/openvic/map/Map.cpp125
1 files changed, 118 insertions, 7 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;
+}