diff options
Diffstat (limited to 'src/openvic-simulation/history')
-rw-r--r-- | src/openvic-simulation/history/Bookmark.hpp | 5 | ||||
-rw-r--r-- | src/openvic-simulation/history/CountryHistory.cpp | 187 | ||||
-rw-r--r-- | src/openvic-simulation/history/CountryHistory.hpp | 34 | ||||
-rw-r--r-- | src/openvic-simulation/history/ProvinceHistory.cpp | 217 | ||||
-rw-r--r-- | src/openvic-simulation/history/ProvinceHistory.hpp | 41 |
5 files changed, 232 insertions, 252 deletions
diff --git a/src/openvic-simulation/history/Bookmark.hpp b/src/openvic-simulation/history/Bookmark.hpp index e93718f..d5253fe 100644 --- a/src/openvic-simulation/history/Bookmark.hpp +++ b/src/openvic-simulation/history/Bookmark.hpp @@ -42,9 +42,10 @@ namespace OpenVic { BookmarkManager(); bool add_bookmark( - std::string_view name, std::string_view description, Date date, uint32_t initial_camera_x, uint32_t initial_camera_y + std::string_view name, std::string_view description, Date date, uint32_t initial_camera_x, + uint32_t initial_camera_y ); - IDENTIFIER_REGISTRY_ACCESSORS(bookmark); + IDENTIFIER_REGISTRY_ACCESSORS(bookmark) bool load_bookmark_file(ast::NodeCPtr root); }; diff --git a/src/openvic-simulation/history/CountryHistory.cpp b/src/openvic-simulation/history/CountryHistory.cpp index ed72f52..cd682bd 100644 --- a/src/openvic-simulation/history/CountryHistory.cpp +++ b/src/openvic-simulation/history/CountryHistory.cpp @@ -7,7 +7,7 @@ using namespace OpenVic::NodeTools; CountryHistory::CountryHistory( Culture const* new_primary_culture, std::vector<Culture const*>&& new_accepted_cultures, Religion const* new_religion, - CountryParty const* new_ruling_party, Date new_last_election, std::map<Ideology const*, fixed_point_t>&& new_upper_house, + CountryParty const* new_ruling_party, Date new_last_election, decimal_map_t<Ideology const*>&& new_upper_house, Province const* new_capital, GovernmentType const* new_government_type, fixed_point_t new_plurality, NationalValue const* new_national_value, bool new_civilised, fixed_point_t new_prestige, std::vector<Reform const*>&& new_reforms, Deployment const* new_inital_oob @@ -21,7 +21,7 @@ Culture const* CountryHistory::get_primary_culture() const { return primary_culture; } -const std::vector<Culture const*>& CountryHistory::get_accepted_cultures() const { +std::vector<Culture const*> const& CountryHistory::get_accepted_cultures() const { return accepted_cultures; } @@ -37,7 +37,7 @@ Date CountryHistory::get_last_election() const { return last_election; } -const std::map<Ideology const*, fixed_point_t>& CountryHistory::get_upper_house() const { +decimal_map_t<Ideology const*> const& CountryHistory::get_upper_house() const { return upper_house; } @@ -49,7 +49,7 @@ GovernmentType const* CountryHistory::get_government_type() const { return government_type; } -const fixed_point_t CountryHistory::get_plurality() const { +fixed_point_t CountryHistory::get_plurality() const { return plurality; } @@ -57,15 +57,15 @@ NationalValue const* CountryHistory::get_national_value() const { return national_value; } -const bool CountryHistory::is_civilised() const { +bool CountryHistory::is_civilised() const { return civilised; } -const fixed_point_t CountryHistory::get_prestige() const { +fixed_point_t CountryHistory::get_prestige() const { return prestige; } -const std::vector<Reform const*>& CountryHistory::get_reforms() const { +std::vector<Reform const*> const& CountryHistory::get_reforms() const { return reforms; } @@ -76,9 +76,9 @@ Deployment const* CountryHistory::get_inital_oob() const { bool CountryHistoryManager::add_country_history_entry( Country const* country, Date date, Culture const* primary_culture, std::vector<Culture const*>&& accepted_cultures, Religion const* religion, CountryParty const* ruling_party, Date last_election, - std::map<Ideology const*, fixed_point_t>&& upper_house, Province const* capital, GovernmentType const* government_type, + decimal_map_t<Ideology const*>&& upper_house, Province const* capital, GovernmentType const* government_type, fixed_point_t plurality, NationalValue const* national_value, bool civilised, fixed_point_t prestige, - std::vector<Reform const*>&& reforms, Deployment const* initial_oob, bool updated_accepted_cultures, + std::vector<Reform const*>&& reforms, std::optional<Deployment const*> initial_oob, bool updated_accepted_cultures, bool updated_upper_house, bool updated_reforms ) { if (locked) { @@ -87,8 +87,8 @@ bool CountryHistoryManager::add_country_history_entry( } /* combine duplicate histories, priority to current (defined later) */ - auto& country_registry = country_histories[country]; - const auto existing_entry = country_registry.find(date); + country_history_map_t& country_registry = country_histories[country]; + const country_history_map_t::iterator existing_entry = country_registry.find(date); if (existing_entry != country_registry.end()) { if (primary_culture != nullptr) { @@ -130,15 +130,15 @@ bool CountryHistoryManager::add_country_history_entry( if (updated_reforms) { existing_entry->second.reforms = std::move(reforms); } - if (initial_oob != nullptr) { - existing_entry->second.inital_oob = initial_oob; + if (initial_oob) { + existing_entry->second.inital_oob = *initial_oob; } } else { country_registry.emplace( date, CountryHistory { primary_culture, std::move(accepted_cultures), religion, ruling_party, last_election, std::move(upper_house), capital, government_type, plurality, national_value, civilised, - prestige, std::move(reforms), initial_oob + prestige, std::move(reforms), std::move(*initial_oob) } ); } @@ -195,57 +195,68 @@ inline CountryHistory const* CountryHistoryManager::get_country_history(Country } inline bool CountryHistoryManager::_load_country_history_entry( - GameManager& game_manager, std::string_view name, Date date, ast::NodeCPtr root + GameManager& game_manager, Dataloader const& dataloader, Country const& country, Date date, ast::NodeCPtr root ) { + PoliticsManager const& politics_manager = game_manager.get_politics_manager(); + IssueManager const& issue_manager = politics_manager.get_issue_manager(); + CultureManager const& culture_manager = game_manager.get_pop_manager().get_culture_manager(); + Province const* capital = nullptr; Culture const* primary_culture = nullptr; Religion const* religion = nullptr; GovernmentType const* government_type = nullptr; NationalValue const* national_value = nullptr; CountryParty const* ruling_party = nullptr; - std::vector<Culture const*> accepted_cultures; - std::vector<Reform const*> reforms; - std::map<Ideology const*, fixed_point_t> upper_house; + std::vector<Culture const*> accepted_cultures {}; + std::vector<Reform const*> reforms {}; + decimal_map_t<Ideology const*> upper_house {}; fixed_point_t plurality = -1, prestige = -1; bool civilised = false; Date last_election {}; - Deployment const* initial_oob = nullptr; + std::optional<Deployment const*> initial_oob; bool updated_accepted_cultures = false, updated_upper_house = false, updated_reforms = false; bool ret = expect_dictionary_keys_and_default( - [this, &game_manager, &reforms, &updated_reforms, &name](std::string_view key, ast::NodeCPtr value) -> bool { - if (game_manager.get_politics_manager().get_issue_manager().has_reform_group_identifier(key)) { + [this, &issue_manager, &reforms, &updated_reforms, &country](std::string_view key, ast::NodeCPtr value) -> bool { + ReformGroup const* reform_group = issue_manager.get_reform_group_by_identifier(key); + if (reform_group != nullptr) { updated_reforms = true; - - Reform const* reform; - - bool ret = game_manager.get_politics_manager().get_issue_manager() - .expect_reform_identifier(assign_variable_callback_pointer(reform))(value); - if (std::find(reforms.begin(), reforms.end(), reform) != reforms.end()) { - Logger::error("Redefinition of reform ", reform->get_identifier(), " in history of ", name); - return false; - } - - reforms.push_back(reform); - return ret; + return issue_manager.expect_reform_identifier( + [reform_group, &reforms, &country](Reform const& reform) -> bool { + if (&reform.get_reform_group() != reform_group) { + Logger::warning( + "Listing ", reform.get_identifier(), " as belonging to the reform group ", + reform_group->get_identifier(), " when it actually belongs to ", + reform.get_reform_group().get_identifier() + ); + } + if (std::find(reforms.begin(), reforms.end(), &reform) != reforms.end()) { + Logger::error( + "Redefinition of reform ", reform.get_identifier(), " in history of ", country.get_identifier() + ); + return false; + } + reforms.push_back(&reform); + return true; + } + )(value); } // TODO: technologies & inventions return true; }, /* we have to use a lambda, assign_variable_callback_pointer * apparently doesn't play nice with const & non-const accessors */ + // TODO - fix this issue (cause by provinces having non-const accessors) "capital", ZERO_OR_ONE, game_manager.get_map().expect_province_identifier([&capital](Province const& province) -> bool { capital = &province; return true; }), "primary_culture", ZERO_OR_ONE, - game_manager.get_pop_manager().get_culture_manager().expect_culture_identifier( - assign_variable_callback_pointer(primary_culture) - ), + culture_manager.expect_culture_identifier(assign_variable_callback_pointer(primary_culture)), "culture", ZERO_OR_MORE, - game_manager.get_pop_manager().get_culture_manager().expect_culture_identifier( + culture_manager.expect_culture_identifier( [&game_manager, &accepted_cultures, &updated_accepted_cultures](Culture const& culture) -> bool { updated_accepted_cultures = true; accepted_cultures.push_back(&culture); @@ -257,102 +268,62 @@ inline bool CountryHistoryManager::_load_country_history_entry( assign_variable_callback_pointer(religion) ), "government", ZERO_OR_ONE, - game_manager.get_politics_manager().get_government_type_manager().expect_government_type_identifier( + politics_manager.get_government_type_manager().expect_government_type_identifier( assign_variable_callback_pointer(government_type) ), "plurality", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(plurality)), "nationalvalue", ZERO_OR_ONE, - game_manager.get_politics_manager().get_national_value_manager().expect_national_value_identifier( + politics_manager.get_national_value_manager().expect_national_value_identifier( assign_variable_callback_pointer(national_value) ), "civilized", ZERO_OR_ONE, expect_bool(assign_variable_callback(civilised)), "prestige", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(prestige)), - "ruling_party", ZERO_OR_ONE, - expect_identifier([this, &game_manager, &ruling_party, &name, &date](std::string_view identifier) -> bool { - const std::vector<CountryParty>* parties = - &game_manager.get_country_manager().get_country_by_identifier(name)->get_parties(); - for (auto& party : *parties) { - if (party.get_identifier() == identifier) { - if (party.get_start_date() <= date && date <= party.get_end_date()) { - ruling_party = &party; - return true; - } else { - if (party.get_start_date() > date) { - Logger::warning( - "Ruling party ", identifier, " of country ", name, " has invalid start date ", - party.get_start_date(), " for bookmark: ", date.to_string() - ); - } - if (party.get_end_date() < date) { - Logger::warning( - "Ruling party ", identifier, " of country ", name, " has invalid end date ", - party.get_end_date(), " for bookmark: ", date.to_string() - ); - } - ruling_party = &party; - return true; - } - } - } - Logger::error("Ruling party ", identifier, " of country ", name, " is not defined!"); - return false; - }), + "ruling_party", ZERO_OR_ONE, country.expect_party_identifier(assign_variable_callback_pointer(ruling_party)), "last_election", ZERO_OR_ONE, expect_date(assign_variable_callback(last_election)), "upper_house", ZERO_OR_ONE, - game_manager.get_politics_manager().get_ideology_manager().expect_ideology_dictionary( + politics_manager.get_ideology_manager().expect_ideology_dictionary( [&upper_house, &updated_upper_house](Ideology const& ideology, ast::NodeCPtr value) -> bool { - fixed_point_t popularity; - - updated_upper_house = true; - bool ret = expect_fixed_point(assign_variable_callback(popularity))(value); - upper_house.emplace(&ideology, popularity); - return ret; - } - ), - "oob", ZERO_OR_ONE, - [&game_manager, &initial_oob](ast::NodeCPtr node) -> bool { - std::string_view string; - expect_string(assign_variable_callback(string))(node); - - if (string.starts_with('/')) { - if (game_manager.get_military_manager().get_deployment_manager() - .has_deployment_identifier(string.substr(1))) { - initial_oob = game_manager.get_military_manager().get_deployment_manager() - .get_deployment_by_identifier(string.substr(1)); + return expect_fixed_point([&upper_house, &updated_upper_house, &ideology](fixed_point_t val) -> bool { + if (val != 0) { + upper_house[&ideology] += val; + updated_upper_house = true; + } return true; - } - } else { - if (game_manager.get_military_manager().get_deployment_manager().has_deployment_identifier(string)) { - initial_oob = - game_manager.get_military_manager().get_deployment_manager().get_deployment_by_identifier(string); - } + })(value); } - - initial_oob = - game_manager.get_military_manager().get_deployment_manager().get_deployment_by_identifier("NULL"); - return true; - }, + ), + "oob", ZERO_OR_ONE, expect_identifier_or_string([&game_manager, &dataloader, &initial_oob](std::string_view path) -> bool { + if(!initial_oob.has_value()) + initial_oob = decltype(initial_oob)::value_type {}; + return game_manager.get_military_manager().get_deployment_manager().load_oob_file( + game_manager, dataloader, path, *initial_oob, false + ); + }), "schools", ZERO_OR_ONE, success_callback, // TODO: technology school "foreign_investment", ZERO_OR_ONE, success_callback // TODO: foreign investment )(root); ret &= add_country_history_entry( - game_manager.get_country_manager().get_country_by_identifier(name), date, primary_culture, + &country, date, primary_culture, std::move(accepted_cultures), religion, ruling_party, last_election, std::move(upper_house), capital, government_type, - plurality, national_value, civilised, prestige, std::move(reforms), initial_oob, updated_accepted_cultures, + plurality, national_value, civilised, prestige, std::move(reforms), std::move(initial_oob), updated_accepted_cultures, updated_upper_house, updated_reforms ); return ret; } -bool CountryHistoryManager::load_country_history_file(GameManager& game_manager, std::string_view name, ast::NodeCPtr root) { - if (game_manager.get_country_manager().get_country_by_identifier(name)->is_dynamic_tag()) { +bool CountryHistoryManager::load_country_history_file( + GameManager& game_manager, Dataloader const& dataloader, Country const& country, ast::NodeCPtr root +) { + if (country.is_dynamic_tag()) { return true; /* as far as I can tell dynamic countries are hardcoded, broken, and unused */ } - bool ret = _load_country_history_entry(game_manager, name, game_manager.get_define_manager().get_start_date(), root); + bool ret = _load_country_history_entry( + game_manager, dataloader, country, game_manager.get_define_manager().get_start_date(), root + ); - ret &= expect_dictionary([this, &game_manager, &name](std::string_view key, ast::NodeCPtr value) -> bool { + ret &= expect_dictionary([this, &game_manager, &dataloader, &country](std::string_view key, ast::NodeCPtr value) -> bool { bool is_date = false; Date entry = Date::from_string(key, &is_date, true); if (!is_date) { @@ -362,13 +333,13 @@ bool CountryHistoryManager::load_country_history_file(GameManager& game_manager, Date end_date = game_manager.get_define_manager().get_end_date(); if (entry > end_date) { Logger::error( - "History entry ", entry.to_string(), " of country ", name, " defined after defined end date ", - end_date.to_string() + "History entry ", entry.to_string(), " of country ", country.get_identifier(), + " defined after defined end date ", end_date.to_string() ); return false; } - return _load_country_history_entry(game_manager, name, entry, value); + return _load_country_history_entry(game_manager, dataloader, country, entry, value); })(root); return ret; diff --git a/src/openvic-simulation/history/CountryHistory.hpp b/src/openvic-simulation/history/CountryHistory.hpp index 0401ec4..3109d4f 100644 --- a/src/openvic-simulation/history/CountryHistory.hpp +++ b/src/openvic-simulation/history/CountryHistory.hpp @@ -28,7 +28,7 @@ namespace OpenVic { Religion const* religion; CountryParty const* ruling_party; Date last_election; - std::map<Ideology const*, fixed_point_t> upper_house; + decimal_map_t<Ideology const*> upper_house; Province const* capital; GovernmentType const* government_type; fixed_point_t plurality; @@ -43,7 +43,7 @@ namespace OpenVic { CountryHistory( Culture const* new_primary_culture, std::vector<Culture const*>&& new_accepted_cultures, Religion const* new_religion, CountryParty const* new_ruling_party, Date new_last_election, - std::map<Ideology const*, fixed_point_t>&& new_upper_house, Province const* new_capital, + decimal_map_t<Ideology const*>&& new_upper_house, Province const* new_capital, GovernmentType const* new_government_type, fixed_point_t new_plurality, NationalValue const* new_national_value, bool new_civilised, fixed_point_t new_prestige, std::vector<Reform const*>&& new_reforms, Deployment const* new_inital_oob @@ -51,28 +51,30 @@ namespace OpenVic { public: Culture const* get_primary_culture() const; - const std::vector<Culture const*>& get_accepted_cultures() const; + std::vector<Culture const*> const& get_accepted_cultures() const; Religion const* get_religion() const; CountryParty const* get_ruling_party() const; Date get_last_election() const; - const std::map<Ideology const*, fixed_point_t>& get_upper_house() const; + decimal_map_t<Ideology const*> const& get_upper_house() const; Province const* get_capital() const; GovernmentType const* get_government_type() const; - const fixed_point_t get_plurality() const; + fixed_point_t get_plurality() const; NationalValue const* get_national_value() const; - const bool is_civilised() const; - const fixed_point_t get_prestige() const; - const std::vector<Reform const*>& get_reforms() const; + bool is_civilised() const; + fixed_point_t get_prestige() const; + std::vector<Reform const*> const& get_reforms() const; Deployment const* get_inital_oob() const; }; struct CountryHistoryManager { private: - std::map<Country const*, std::map<Date, CountryHistory>> country_histories; + using country_history_map_t = std::map<Date, CountryHistory>; + std::map<Country const*, country_history_map_t> country_histories; bool locked = false; inline bool _load_country_history_entry( - GameManager& game_manager, std::string_view name, Date date, ast::NodeCPtr root + GameManager& game_manager, Dataloader const& dataloader, Country const& country, Date date, + ast::NodeCPtr root ); public: @@ -81,10 +83,10 @@ namespace OpenVic { bool add_country_history_entry( Country const* country, Date date, Culture const* primary_culture, std::vector<Culture const*>&& accepted_cultures, Religion const* religion, CountryParty const* ruling_party, Date last_election, - std::map<Ideology const*, fixed_point_t>&& upper_house, Province const* capital, - GovernmentType const* government_type, fixed_point_t plurality, NationalValue const* national_value, bool civilised, - fixed_point_t prestige, std::vector<Reform const*>&& reforms, Deployment const* initial_oob, - bool updated_accepted_cultures, bool updated_upper_house, bool updated_reforms + decimal_map_t<Ideology const*>&& upper_house, Province const* capital, GovernmentType const* government_type, + fixed_point_t plurality, NationalValue const* national_value, bool civilised, fixed_point_t prestige, + std::vector<Reform const*>&& reforms, std::optional<Deployment const*> initial_oob, bool updated_accepted_cultures, + bool updated_upper_house, bool updated_reforms ); void lock_country_histories(); @@ -96,7 +98,9 @@ namespace OpenVic { /* Returns history of country at bookmark date. Return can be nullptr if an error occurs. */ inline CountryHistory const* get_country_history(Country const* country, Bookmark const* entry) const; - bool load_country_history_file(GameManager& game_manager, std::string_view name, ast::NodeCPtr root); + bool load_country_history_file( + GameManager& game_manager, Dataloader const& dataloader, Country const& country, ast::NodeCPtr root + ); }; } // namespace OpenVic diff --git a/src/openvic-simulation/history/ProvinceHistory.cpp b/src/openvic-simulation/history/ProvinceHistory.cpp index 6dbf6a4..65e37e1 100644 --- a/src/openvic-simulation/history/ProvinceHistory.cpp +++ b/src/openvic-simulation/history/ProvinceHistory.cpp @@ -7,9 +7,10 @@ using namespace OpenVic; using namespace OpenVic::NodeTools; ProvinceHistory::ProvinceHistory( - Country const* new_owner, Country const* new_controller, uint8_t new_colonial, bool new_slave, - std::vector<Country const*>&& new_cores, Good const* new_rgo, uint8_t new_life_rating, TerrainType const* new_terrain_type, - std::map<Building const*, uint8_t>&& new_buildings, std::map<Ideology const*, uint8_t>&& new_party_loyalties + Country const* new_owner, Country const* new_controller, Province::colony_status_t new_colonial, bool new_slave, + std::vector<Country const*>&& new_cores, Good const* new_rgo, Province::life_rating_t new_life_rating, + TerrainType const* new_terrain_type, building_level_map_t&& new_buildings, + decimal_map_t<Ideology const*>&& new_party_loyalties ) : owner { new_owner }, controller { new_controller }, colonial { new_colonial }, slave { new_slave }, cores { std::move(new_cores) }, rgo { new_rgo }, life_rating { new_life_rating }, terrain_type { new_terrain_type }, buildings { std::move(new_buildings) }, party_loyalties { std::move(new_party_loyalties) } {} @@ -22,7 +23,7 @@ Country const* ProvinceHistory::get_controller() const { return controller; } -uint8_t ProvinceHistory::get_colony_status() const { +Province::colony_status_t ProvinceHistory::get_colony_status() const { return colonial; } @@ -42,7 +43,7 @@ Good const* ProvinceHistory::get_rgo() const { return rgo; } -uint8_t ProvinceHistory::get_life_rating() const { +Province::life_rating_t ProvinceHistory::get_life_rating() const { return life_rating; } @@ -50,20 +51,20 @@ TerrainType const* ProvinceHistory::get_terrain_type() const { return terrain_type; } -std::map<Building const*, uint8_t> const& ProvinceHistory::get_buildings() const { +ProvinceHistory::building_level_map_t const& ProvinceHistory::get_buildings() const { return buildings; } -std::map<Ideology const*, uint8_t> const& ProvinceHistory::get_party_loyalties() const { +decimal_map_t<Ideology const*> const& ProvinceHistory::get_party_loyalties() const { return party_loyalties; } bool ProvinceHistoryManager::add_province_history_entry( - Province const* province, Date date, Country const* owner, Country const* controller, std::optional<uint8_t>&& colonial, - std::optional<bool>&& slave, std::vector<Country const*>&& cores, std::vector<Country const*>&& remove_cores, - Good const* rgo, std::optional<uint8_t>&& life_rating, TerrainType const* terrain_type, - std::optional<std::map<Building const*, uint8_t>>&& buildings, - std::optional<std::map<Ideology const*, uint8_t>>&& party_loyalties + Province const* province, Date date, Country const* owner, Country const* controller, + std::optional<Province::colony_status_t>&& colonial, std::optional<bool>&& slave, std::vector<Country const*>&& cores, + std::vector<Country const*>&& remove_cores, Good const* rgo, std::optional<Province::life_rating_t>&& life_rating, + TerrainType const* terrain_type, std::optional<ProvinceHistory::building_level_map_t>&& buildings, + std::optional<decimal_map_t<Ideology const*>>&& party_loyalties ) { if (locked) { Logger::error("Cannot add new history entry to province history registry: locked!"); @@ -104,7 +105,7 @@ bool ProvinceHistoryManager::add_province_history_entry( } // province history cores are additive existing_entry->second.cores.insert(existing_entry->second.cores.end(), cores.begin(), cores.end()); - for (const auto which : remove_cores) { + for (Country const* which : remove_cores) { const auto core = std::find(cores.begin(), cores.end(), which); if (core == cores.end()) { Logger::error( @@ -176,114 +177,109 @@ inline ProvinceHistory const* ProvinceHistoryManager::get_province_history( } inline bool ProvinceHistoryManager::_load_province_history_entry( - GameManager& game_manager, std::string_view province, Date date, ast::NodeCPtr root + GameManager const& game_manager, Province const& province, Date date, ast::NodeCPtr root, + bool is_base_entry ) { + BuildingManager const& building_manager = game_manager.get_economy_manager().get_building_manager(); + CountryManager const& country_manager = game_manager.get_country_manager(); + GoodManager const& good_manager = game_manager.get_economy_manager().get_good_manager(); + IdeologyManager const& ideology_manager = game_manager.get_politics_manager().get_ideology_manager(); + TerrainTypeManager const& terrain_type_manager = game_manager.get_map().get_terrain_type_manager(); + Country const* owner = nullptr; Country const* controller = nullptr; - std::vector<Country const*> cores; - std::vector<Country const*> remove_cores; - Good const* rgo; - std::optional<uint8_t> life_rating, colonial; + std::vector<Country const*> cores {}; + std::vector<Country const*> remove_cores {}; + Good const* rgo = nullptr; + std::optional<Province::colony_status_t> colonial; + std::optional<Province::life_rating_t> life_rating; std::optional<bool> slave; - TerrainType const* terrain_type; - std::optional<std::map<Building const*, uint8_t>> buildings; - std::optional<std::map<Ideology const*, uint8_t>> party_loyalties; + TerrainType const* terrain_type = nullptr; + std::optional<ProvinceHistory::building_level_map_t> buildings; + std::optional<decimal_map_t<Ideology const*>> party_loyalties; + + using enum Province::colony_status_t; + static const string_map_t<Province::colony_status_t> colony_status_map { + { "0", STATE }, { "1", PROTECTORATE }, { "2", COLONY } + }; bool ret = expect_dictionary_keys_and_default( - [&game_manager, &buildings](std::string_view key, ast::NodeCPtr value) -> bool { + [&building_manager, &buildings, date, is_base_entry](std::string_view key, ast::NodeCPtr value) -> bool { // used for province buildings like forts or railroads - if (game_manager.get_economy_manager().get_building_manager().has_building_identifier(key)) { - Building const* building; - uint8_t level; - - bool ret = game_manager.get_economy_manager().get_building_manager() - .expect_building_str(assign_variable_callback_pointer(building))(key); - ret &= expect_uint(assign_variable_callback(level))(value); - - if(!buildings.has_value()) - buildings = decltype(buildings)::value_type {}; - buildings->emplace(building, level); - return ret; + Building const* building = building_manager.get_building_by_identifier(key); + if (building != nullptr) { + return expect_uint<Building::level_t>([&buildings, building](Building::level_t level) -> bool { + if(!buildings.has_value()) + buildings = decltype(buildings)::value_type {}; + buildings->emplace(building, level); + return true; + })(value); } - bool is_date; - Date::from_string(key, &is_date, true); + /* Date blocks are skipped here (they get their own invocation of _load_province_history_entry) */ + bool is_date = false; + const Date sub_date { Date::from_string(key, &is_date, true) }; if (is_date) { - return true; + if (is_base_entry) { + return true; + } else { + Logger::error( + "Province history nested multiple levels deep! ", sub_date, " is inside ", date, + " (Any date blocks within a date block are ignored)" + ); + return false; + } } return key_value_invalid_callback(key, value); }, - "owner", ZERO_OR_ONE, game_manager.get_country_manager() - .expect_country_identifier(assign_variable_callback_pointer(owner)), - "controller", ZERO_OR_ONE, game_manager.get_country_manager() - .expect_country_identifier(assign_variable_callback_pointer(controller)), - "add_core", ZERO_OR_MORE, [&game_manager, &cores](ast::NodeCPtr node) -> bool { - Country const* core; - - bool ret = game_manager.get_country_manager() - .expect_country_identifier(assign_variable_callback_pointer(core))(node); - cores.push_back(core); - return ret; - }, - "remove_core", ZERO_OR_MORE, [&game_manager, &remove_cores](ast::NodeCPtr node) -> bool { - Country const* remove; - - bool ret = game_manager.get_country_manager() - .expect_country_identifier(assign_variable_callback_pointer(remove))(node); - remove_cores.push_back(remove); - return ret; - }, - "colonial", ZERO_OR_ONE, expect_uint<uint8_t>([&colonial](uint8_t colony_level) -> bool { - colonial = colony_level; - - return true; - }), - "colony", ZERO_OR_ONE, expect_uint<uint8_t>([&colonial](uint8_t colony_level) -> bool { - colonial = colony_level; - - return true; - }), - "is_slave", ZERO_OR_ONE, expect_bool([&slave](bool is_slave) -> bool { - if (is_slave) { - slave = true; - } else { - slave = false; + "owner", ZERO_OR_ONE, country_manager.expect_country_identifier(assign_variable_callback_pointer(owner)), + "controller", ZERO_OR_ONE, country_manager.expect_country_identifier(assign_variable_callback_pointer(controller)), + "add_core", ZERO_OR_MORE, country_manager.expect_country_identifier( + [&cores](Country const& core) -> bool { + cores.push_back(&core); + return true; } - - return true; - }), - "trade_goods", ZERO_OR_ONE, game_manager.get_economy_manager().get_good_manager() - .expect_good_identifier(assign_variable_callback_pointer(rgo)), - "life_rating", ZERO_OR_ONE, expect_uint<uint8_t>([&life_rating](uint8_t rating) -> bool { - life_rating = rating; - - return true; - }), - "terrain", ZERO_OR_ONE, game_manager.get_map().get_terrain_type_manager() - .expect_terrain_type_identifier(assign_variable_callback_pointer(terrain_type)), - "party_loyalty", ZERO_OR_MORE, [&game_manager, &party_loyalties](ast::NodeCPtr node) -> bool { - Ideology const* ideology; - uint8_t amount; // percent I do believe - - bool ret = expect_dictionary_keys( - "ideology", ONE_EXACTLY, game_manager.get_politics_manager().get_ideology_manager() - .expect_ideology_identifier(assign_variable_callback_pointer(ideology)), - "loyalty_value", ONE_EXACTLY, expect_uint(assign_variable_callback(amount)) + ), + "remove_core", ZERO_OR_MORE, country_manager.expect_country_identifier( + [&remove_cores](Country const& core) -> bool { + remove_cores.push_back(&core); + return true; + } + ), + "colonial", ZERO_OR_ONE, + expect_identifier(expect_mapped_string(colony_status_map, assign_variable_callback(colonial))), + "colony", ZERO_OR_ONE, expect_identifier(expect_mapped_string(colony_status_map, assign_variable_callback(colonial))), + "is_slave", ZERO_OR_ONE, expect_bool(assign_variable_callback(slave)), + "trade_goods", ZERO_OR_ONE, good_manager.expect_good_identifier(assign_variable_callback_pointer(rgo)), + "life_rating", ZERO_OR_ONE, expect_uint<Province::life_rating_t>(assign_variable_callback(life_rating)), + "terrain", ZERO_OR_ONE, terrain_type_manager.expect_terrain_type_identifier( + assign_variable_callback_pointer(terrain_type) + ), + "party_loyalty", ZERO_OR_MORE, [&ideology_manager, &party_loyalties](ast::NodeCPtr node) -> bool { + Ideology const* ideology = nullptr; + fixed_point_t amount = 0; // percent I do believe + + const bool ret = expect_dictionary_keys( + "ideology", ONE_EXACTLY, ideology_manager.expect_ideology_identifier( + assign_variable_callback_pointer(ideology) + ), + "loyalty_value", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(amount)) )(node); if(!party_loyalties.has_value()) party_loyalties = decltype(party_loyalties)::value_type {}; party_loyalties->emplace(ideology, amount); return ret; }, - "state_building", ZERO_OR_MORE, [&game_manager, &buildings](ast::NodeCPtr node) -> bool { - Building const* building; - uint8_t level; + "state_building", ZERO_OR_MORE, [&building_manager, &buildings](ast::NodeCPtr node) -> bool { + Building const* building = nullptr; + uint8_t level = 0; - bool ret = expect_dictionary_keys( + const bool ret = expect_dictionary_keys( "level", ONE_EXACTLY, expect_uint(assign_variable_callback(level)), - "building", ONE_EXACTLY, game_manager.get_economy_manager().get_building_manager() - .expect_building_identifier(assign_variable_callback_pointer(building)), + "building", ONE_EXACTLY, building_manager.expect_building_identifier( + assign_variable_callback_pointer(building) + ), "upgrade", ZERO_OR_ONE, success_callback // doesn't appear to have an effect )(node); if(!buildings.has_value()) @@ -294,34 +290,37 @@ inline bool ProvinceHistoryManager::_load_province_history_entry( )(root); ret &= add_province_history_entry( - game_manager.get_map().get_province_by_identifier(province), date, owner, controller, std::move(colonial), std::move(slave), - std::move(cores), std::move(remove_cores), rgo, std::move(life_rating), terrain_type, std::move(buildings), - std::move(party_loyalties) + &province, date, owner, controller, std::move(colonial), std::move(slave), std::move(cores), std::move(remove_cores), + rgo, std::move(life_rating), terrain_type, std::move(buildings), std::move(party_loyalties) ); return ret; } -bool ProvinceHistoryManager::load_province_history_file(GameManager& game_manager, std::string_view name, ast::NodeCPtr root) { - bool ret = _load_province_history_entry(game_manager, name, game_manager.get_define_manager().get_start_date(), root); +bool ProvinceHistoryManager::load_province_history_file( + GameManager const& game_manager, Province const& province, ast::NodeCPtr root +) { + bool ret = _load_province_history_entry( + game_manager, province, game_manager.get_define_manager().get_start_date(), root, true + ); ret &= expect_dictionary( - [this, &game_manager, &name](std::string_view key, ast::NodeCPtr value) -> bool { + [this, &game_manager, &province, end_date = game_manager.get_define_manager().get_end_date()]( + std::string_view key, ast::NodeCPtr value) -> bool { bool is_date = false; - Date entry = Date::from_string(key, &is_date, true); + const Date entry = Date::from_string(key, &is_date, true); if (!is_date) { return true; } - Date end_date = game_manager.get_define_manager().get_end_date(); if (entry > end_date) { Logger::error( - "History entry ", entry.to_string(), " of province ", name, " defined after defined end date ", - end_date.to_string() + "History entry ", entry, " of province ", province.get_identifier(), + " defined after defined end date ", end_date ); return false; } - return _load_province_history_entry(game_manager, name, entry, value); + return _load_province_history_entry(game_manager, province, entry, value, false); } )(root); diff --git a/src/openvic-simulation/history/ProvinceHistory.hpp b/src/openvic-simulation/history/ProvinceHistory.hpp index 90c87e2..fb90cc4 100644 --- a/src/openvic-simulation/history/ProvinceHistory.hpp +++ b/src/openvic-simulation/history/ProvinceHistory.hpp @@ -17,37 +17,39 @@ namespace OpenVic { struct ProvinceHistory { friend struct ProvinceHistoryManager; + using building_level_map_t = std::map<Building const*, Building::level_t>; + private: Country const* owner; Country const* controller; - uint8_t colonial; + Province::colony_status_t colonial; bool slave; std::vector<Country const*> cores; // non-standard, maintains cores between entries Good const* rgo; - uint8_t life_rating; + Province::life_rating_t life_rating; TerrainType const* terrain_type; - std::map<Building const*, uint8_t> buildings; - std::map<Ideology const*, uint8_t> party_loyalties; + building_level_map_t buildings; + decimal_map_t<Ideology const*> party_loyalties; ProvinceHistory( - Country const* new_owner, Country const* new_controller, uint8_t new_colonial, bool new_slave, - std::vector<Country const*>&& new_cores, Good const* new_rgo, uint8_t new_life_rating, - TerrainType const* new_terrain_type, std::map<Building const*, uint8_t>&& new_buildings, - std::map<Ideology const*, uint8_t>&& new_party_loyalties + Country const* new_owner, Country const* new_controller, Province::colony_status_t new_colonial, bool new_slave, + std::vector<Country const*>&& new_cores, Good const* new_rgo, Province::life_rating_t new_life_rating, + TerrainType const* new_terrain_type, building_level_map_t&& new_buildings, + decimal_map_t<Ideology const*>&& new_party_loyalties ); public: Country const* get_owner() const; Country const* get_controller() const; - uint8_t get_colony_status() const; // 0 = state, 1 = protectorate, 2 = colony + Province::colony_status_t get_colony_status() const; // 0 = state, 1 = protectorate, 2 = colony bool is_slave() const; std::vector<Country const*> const& get_cores() const; bool is_core_of(Country const* country) const; Good const* get_rgo() const; - uint8_t get_life_rating() const; + Province::life_rating_t get_life_rating() const; TerrainType const* get_terrain_type() const; - std::map<Building const*, uint8_t> const& get_buildings() const; - std::map<Ideology const*, uint8_t> const& get_party_loyalties() const; + building_level_map_t const& get_buildings() const; + decimal_map_t<Ideology const*> const& get_party_loyalties() const; }; struct ProvinceHistoryManager { @@ -56,7 +58,8 @@ namespace OpenVic { bool locked = false; inline bool _load_province_history_entry( - GameManager& game_manager, std::string_view province, Date date, ast::NodeCPtr root + GameManager const& game_manager, Province const& province, Date date, ast::NodeCPtr root, + bool is_base_entry ); public: @@ -64,12 +67,12 @@ namespace OpenVic { bool add_province_history_entry( Province const* province, Date date, Country const* owner, Country const* controller, - std::optional<uint8_t>&& colonial, std::optional<bool>&& slave, + std::optional<Province::colony_status_t>&& colonial, std::optional<bool>&& slave, std::vector<Country const*>&& cores, // additive to existing entries std::vector<Country const*>&& remove_cores, // existing cores that need to be removed - Good const* rgo, std::optional<uint8_t>&& life_rating, TerrainType const* terrain_type, - std::optional<std::map<Building const*, uint8_t>>&& buildings, - std::optional<std::map<Ideology const*, uint8_t>>&& party_loyalties + Good const* rgo, std::optional<Province::life_rating_t>&& life_rating, TerrainType const* terrain_type, + std::optional<ProvinceHistory::building_level_map_t>&& buildings, + std::optional<decimal_map_t<Ideology const*>>&& party_loyalties ); void lock_province_histories(); @@ -81,6 +84,8 @@ namespace OpenVic { /* Returns history of province at bookmark date. Return can be nullptr if an error occurs. */ inline ProvinceHistory const* get_province_history(Province const* province, Bookmark const* bookmark) const; - bool load_province_history_file(GameManager& game_manager, std::string_view name, ast::NodeCPtr root); + bool load_province_history_file( + GameManager const& game_manager, Province const& province, ast::NodeCPtr root + ); }; } // namespace OpenVic |