From 3bf0ce9bfaad1e40ffeeed3d66ca2e628fea8e29 Mon Sep 17 00:00:00 2001 From: zaaarf Date: Wed, 27 Dec 2023 23:56:28 +0100 Subject: feat: loading climate.txt and continent.txt --- src/openvic-simulation/dataloader/Dataloader.cpp | 19 ++++- src/openvic-simulation/map/Map.cpp | 90 ++++++++++++++++++++++++ src/openvic-simulation/map/Map.hpp | 5 +- src/openvic-simulation/map/Province.cpp | 4 +- src/openvic-simulation/map/Province.hpp | 6 ++ src/openvic-simulation/map/Region.cpp | 3 + src/openvic-simulation/map/Region.hpp | 8 +++ src/openvic-simulation/map/TerrainType.hpp | 2 +- 8 files changed, 131 insertions(+), 6 deletions(-) diff --git a/src/openvic-simulation/dataloader/Dataloader.cpp b/src/openvic-simulation/dataloader/Dataloader.cpp index fc4e64c..cc09c1a 100644 --- a/src/openvic-simulation/dataloader/Dataloader.cpp +++ b/src/openvic-simulation/dataloader/Dataloader.cpp @@ -603,8 +603,7 @@ bool Dataloader::_load_map_dir(GameManager& game_manager) const { static constexpr std::string_view default_region = "region.txt"; static constexpr std::string_view default_region_sea = "region_sea.txt"; // TODO static constexpr std::string_view default_province_flag_sprite = "province_flag_sprites"; // TODO - - static constexpr std::string_view climate_filename = "climate.txt"; // TODO + static constexpr std::string_view climate_file = "climate.txt"; // TODO /* Parser stored so the filename string_views persist until the end of this function. */ const v2script::Parser parser = parse_defines(lookup_file(append_string_views(map_directory, defaults_filename))); @@ -702,6 +701,22 @@ bool Dataloader::_load_map_dir(GameManager& game_manager) const { ret = false; } + if (!map.load_climate_file( + game_manager.get_modifier_manager(), + parse_defines(lookup_file(append_string_views(map_directory, climate_file))).get_file_node() + )) { + Logger::error("Failed to load climates!"); + ret = false; + } + + if (!map.load_continent_file( + game_manager.get_modifier_manager(), + parse_defines(lookup_file(append_string_views(map_directory, continent))).get_file_node() + )) { + Logger::error("Failed to load continents!"); + ret = false; + } + return ret; } diff --git a/src/openvic-simulation/map/Map.cpp b/src/openvic-simulation/map/Map.cpp index cdedebd..67e91cd 100644 --- a/src/openvic-simulation/map/Map.cpp +++ b/src/openvic-simulation/map/Map.cpp @@ -1,7 +1,9 @@ #include "Map.hpp" #include +#include #include +#include #include "openvic-simulation/economy/Good.hpp" #include "openvic-simulation/history/ProvinceHistory.hpp" @@ -644,3 +646,91 @@ bool Map::generate_and_load_province_adjacencies(std::vector 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(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; +} diff --git a/src/openvic-simulation/map/Map.hpp b/src/openvic-simulation/map/Map.hpp index 523a8e7..2575324 100644 --- a/src/openvic-simulation/map/Map.hpp +++ b/src/openvic-simulation/map/Map.hpp @@ -49,7 +49,6 @@ namespace OpenVic { * MAP-4 */ struct Map { - #pragma pack(push, 1) /* Used to represent tightly packed 3-byte integer pixel information. */ struct shape_pixel_t { @@ -63,6 +62,8 @@ namespace OpenVic { IdentifierRegistry IDENTIFIER_REGISTRY_CUSTOM_INDEX_OFFSET(province, 1); IdentifierRegistry IDENTIFIER_REGISTRY(region); IdentifierRegistry IDENTIFIER_REGISTRY(mapmode); + IdentifierRegistry IDENTIFIER_REGISTRY(climate); + IdentifierRegistry IDENTIFIER_REGISTRY(continent); ProvinceSet water_provinces; TerrainTypeManager PROPERTY_REF(terrain_type_manager); @@ -132,5 +133,7 @@ namespace OpenVic { bool load_region_file(ast::NodeCPtr root); bool load_map_images(fs::path const& province_path, fs::path const& terrain_path, bool detailed_errors); bool generate_and_load_province_adjacencies(std::vector const& additional_adjacencies); + bool load_climate_file(ModifierManager const& modifier_manager, ast::NodeCPtr root); + bool load_continent_file(ModifierManager const& modifier_manager, ast::NodeCPtr root); }; } diff --git a/src/openvic-simulation/map/Province.cpp b/src/openvic-simulation/map/Province.cpp index cb9095b..2d301e8 100644 --- a/src/openvic-simulation/map/Province.cpp +++ b/src/openvic-simulation/map/Province.cpp @@ -8,8 +8,8 @@ using namespace OpenVic::NodeTools; Province::Province( std::string_view new_identifier, colour_t new_colour, index_t new_index ) : HasIdentifierAndColour { new_identifier, new_colour, true }, index { new_index }, region { nullptr }, - on_map { false }, has_region { false }, water { false }, coastal { false }, port { false }, - default_terrain_type { nullptr }, positions {}, terrain_type { nullptr }, life_rating { 0 }, + climate { nullptr }, continent { nullptr }, on_map { false }, has_region { false }, water { false }, coastal { false }, + port { false }, default_terrain_type { nullptr }, positions {}, terrain_type { nullptr }, life_rating { 0 }, colony_status { colony_status_t::STATE }, state { nullptr }, owner { nullptr }, controller { nullptr }, slave { false }, crime { nullptr }, rgo { nullptr }, buildings { "buildings", false }, total_population { 0 } { assert(index != NULL_INDEX); diff --git a/src/openvic-simulation/map/Province.hpp b/src/openvic-simulation/map/Province.hpp index 58fe29e..431b4c2 100644 --- a/src/openvic-simulation/map/Province.hpp +++ b/src/openvic-simulation/map/Province.hpp @@ -16,6 +16,10 @@ namespace OpenVic { struct TerrainType; struct TerrainTypeMapping; struct ProvinceHistoryEntry; + struct ProvinceSetModifier; + using Climate = ProvinceSetModifier; + using Continent = ProvinceSetModifier; + /* REQUIREMENTS: * MAP-5, MAP-7, MAP-8, MAP-43, MAP-47 @@ -88,6 +92,8 @@ namespace OpenVic { /* Immutable attributes (unchanged after initial game load) */ const index_t PROPERTY(index); Region const* PROPERTY(region); + Climate const* PROPERTY(climate); + Continent const* PROPERTY(continent); bool PROPERTY(on_map); bool PROPERTY(has_region); bool PROPERTY_CUSTOM_PREFIX(water, is); diff --git a/src/openvic-simulation/map/Region.cpp b/src/openvic-simulation/map/Region.cpp index e356c89..6f40338 100644 --- a/src/openvic-simulation/map/Region.cpp +++ b/src/openvic-simulation/map/Region.cpp @@ -94,6 +94,9 @@ ProvinceSet::provinces_t const& ProvinceSet::get_provinces() const { Region::Region(std::string_view new_identifier, colour_t new_colour, bool new_meta) : HasIdentifierAndColour { new_identifier, new_colour, false }, meta { new_meta } {} +ProvinceSetModifier::ProvinceSetModifier(std::string_view new_identifier, ModifierValue&& new_values) + : Modifier { new_identifier, std::move(new_values), 0 } {} + bool Region::get_meta() const { return meta; } diff --git a/src/openvic-simulation/map/Region.hpp b/src/openvic-simulation/map/Region.hpp index e4565c9..d8948b7 100644 --- a/src/openvic-simulation/map/Region.hpp +++ b/src/openvic-simulation/map/Region.hpp @@ -27,6 +27,14 @@ namespace OpenVic { provinces_t const& get_provinces() const; }; + struct ProvinceSetModifier : Modifier, ProvinceSet { + friend struct Map; + private: + ProvinceSetModifier(std::string_view new_identifier, ModifierValue&& new_values); + public: + ProvinceSetModifier(ProvinceSetModifier&&) = default; + }; + /* REQUIREMENTS: * MAP-6, MAP-44, MAP-48 */ diff --git a/src/openvic-simulation/map/TerrainType.hpp b/src/openvic-simulation/map/TerrainType.hpp index 1a5b09c..dc9bc56 100644 --- a/src/openvic-simulation/map/TerrainType.hpp +++ b/src/openvic-simulation/map/TerrainType.hpp @@ -5,7 +5,7 @@ namespace OpenVic { struct TerrainTypeManager; - struct TerrainType : HasIdentifierAndColour, ModifierValue { + struct TerrainType : HasIdentifierAndColour { friend struct TerrainTypeManager; private: -- cgit v1.2.3-56-ga3b1