aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/map/Map.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvic-simulation/map/Map.cpp')
-rw-r--r--src/openvic-simulation/map/Map.cpp156
1 files changed, 110 insertions, 46 deletions
diff --git a/src/openvic-simulation/map/Map.cpp b/src/openvic-simulation/map/Map.cpp
index fde3b3a..67e91cd 100644
--- a/src/openvic-simulation/map/Map.cpp
+++ b/src/openvic-simulation/map/Map.cpp
@@ -1,7 +1,9 @@
#include "Map.hpp"
#include <cassert>
+#include <cstddef>
#include <unordered_set>
+#include <vector>
#include "openvic-simulation/economy/Good.hpp"
#include "openvic-simulation/history/ProvinceHistory.hpp"
@@ -108,42 +110,30 @@ void Map::lock_water_provinces() {
Logger::info("Locked water provinces after registering ", water_provinces.size());
}
-bool Map::add_region(std::string_view identifier, std::vector<std::string_view> const& province_identifiers) {
+bool Map::add_region(std::string_view identifier, Region::provinces_t const& provinces) {
if (identifier.empty()) {
Logger::error("Invalid region identifier - empty!");
return false;
}
- Region::provinces_t provinces;
- provinces.reserve(province_identifiers.size());
- bool meta = false, ret = true;
- for (const std::string_view province_identifier : province_identifiers) {
- Province* province = get_province_by_identifier(province_identifier);
- if (province != nullptr) {
- if (std::find(provinces.begin(), provinces.end(), province) != provinces.end()) {
- Logger::error("Duplicate province identifier ", province_identifier, " in region ", identifier);
- ret = false;
- } else {
- if (province->get_has_region()) {
- meta = true;
- }
- provinces.push_back(province);
- }
- } else {
- Logger::error("Invalid province identifier ", province_identifier, " for region ", identifier);
- ret = false;
- }
- }
if (provinces.empty()) {
Logger::warning("No valid provinces in list for ", identifier);
- return ret;
+ return true;
}
- if (!meta) {
- for (Province* province : provinces) {
- province->has_region = true;
+ const bool meta = std::any_of(provinces.begin(), provinces.end(), std::bind_front(&Province::get_has_region));
+
+ Region region { identifier, provinces.front()->get_colour(), meta };
+ bool ret = region.add_provinces(provinces);
+ region.lock();
+ if (regions.add_item(std::move(region))) {
+ if (!meta) {
+ for (Province const* province : provinces) {
+ remove_province_const(province)->has_region = true;
+ }
}
+ } else {
+ ret = false;
}
- ret &= regions.add_item({ identifier, std::move(provinces), meta });
return ret;
}
@@ -387,36 +377,22 @@ bool Map::load_province_positions(BuildingTypeManager const& building_type_manag
bool Map::load_region_file(ast::NodeCPtr root) {
const bool ret = expect_dictionary_reserve_length(regions,
[this](std::string_view region_identifier, ast::NodeCPtr region_node) -> bool {
- std::vector<std::string_view> province_identifiers;
+ Region::provinces_t provinces;
bool ret = expect_list_reserve_length(
- province_identifiers, expect_identifier(vector_callback(province_identifiers))
+ provinces, expect_province_identifier(vector_callback_pointer(provinces))
)(region_node);
- ret &= add_region(region_identifier, province_identifiers);
+ ret &= add_region(region_identifier, provinces);
return ret;
}
)(root);
lock_regions();
- for (Region& region : regions.get_items()) {
+ for (Region const& region : regions.get_items()) {
if (!region.meta) {
- for (Province* province : region.get_provinces()) {
- if (!province->get_has_region()) {
- Logger::error("Province in non-meta region without has_region set: ", province->get_identifier());
- province->has_region = true;
- }
- province->region = &region;
+ for (Province const* province : region.get_provinces()) {
+ remove_province_const(province)->region = &region;
}
}
}
- for (Province& province : provinces.get_items()) {
- const bool region_null = province.get_region() == nullptr;
- if (province.get_has_region() == region_null) {
- Logger::error(
- "Province has_region / region mismatch: has_region = ", province.get_has_region(),
- ", region = ", province.get_region()
- );
- province.has_region = !region_null;
- }
- }
return ret;
}
@@ -670,3 +646,91 @@ bool Map::generate_and_load_province_adjacencies(std::vector<LineObject> const&
);
return ret;
}
+
+bool Map::load_climate_file(ModifierManager const& modifier_manager, ast::NodeCPtr root) {
+ bool ret = expect_dictionary_reserve_length(climates, [this, &modifier_manager](std::string_view identifier, ast::NodeCPtr node) -> bool {
+ if (identifier.empty()) {
+ Logger::error("Invalid climate identifier - empty!");
+ return false;
+ }
+
+ bool ret = true;
+ Climate* cur_climate = climates.get_item_by_identifier(identifier);
+ if (cur_climate == nullptr) {
+ ModifierValue values;
+ ret &= modifier_manager.expect_modifier_value(move_variable_callback(values))(node);
+ ret &= climates.add_item({ identifier, std::move(values) });
+ } else {
+ ret &= expect_list_reserve_length(*cur_climate, expect_province_identifier(
+ [cur_climate, &identifier](Province& province) {
+ if (province.climate != cur_climate) {
+ cur_climate->add_province(&province);
+ if (province.climate != nullptr) {
+ Climate* old_climate = const_cast<Climate*>(province.climate);
+ old_climate->remove_province(&province);
+ Logger::warning(
+ "Province with id ", province.get_identifier(),
+ " found in multiple climates: ", identifier,
+ " and ", old_climate->get_identifier()
+ );
+ }
+ province.climate = cur_climate;
+ } else {
+ Logger::warning(
+ "Province with id ", province.get_identifier(),
+ "defined twice in climate ", identifier
+ );
+ }
+ return true;
+ }
+ ))(node);
+ cur_climate->lock();
+ }
+ return ret;
+ })(root);
+
+ lock_climates();
+
+ return ret;
+}
+
+bool Map::load_continent_file(ModifierManager const& modifier_manager, ast::NodeCPtr root) {
+ bool ret = expect_dictionary_reserve_length(continents, [this, &modifier_manager](std::string_view identifier, ast::NodeCPtr node) -> bool {
+ if (identifier.empty()) {
+ Logger::error("Invalid continent identifier - empty!");
+ return false;
+ }
+
+ ModifierValue values;
+ ProvinceSetModifier::provinces_t prov_list;
+ bool ret = modifier_manager.expect_modifier_value_and_keys(move_variable_callback(values),
+ "provinces", ONE_EXACTLY, expect_list_reserve_length(prov_list, expect_province_identifier(
+ [&prov_list](Province const& province) -> bool {
+ if (province.continent == nullptr) {
+ prov_list.emplace_back(&province);
+ }
+ return true;
+ }
+ ))
+ )(node);
+
+ Continent continent = { identifier, std::move(values) };
+ continent.add_provinces(prov_list);
+ continent.lock();
+
+ if (continents.add_item(std::move(continent))) {
+ Continent const& moved_continent = continents.get_items().back();
+ for (Province const* prov : moved_continent.get_provinces()) {
+ remove_province_const(prov)->continent = &moved_continent;
+ }
+ } else {
+ ret = false;
+ }
+
+ return ret;
+ })(root);
+
+ lock_continents();
+
+ return ret;
+}