From ddbb6af66e30e896f07a39503a1bb935e462c095 Mon Sep 17 00:00:00 2001 From: wvpm <24685035+wvpm@users.noreply.github.com> Date: Sun, 7 Jan 2024 13:49:20 +0100 Subject: Reparations & optional end date --- .../history/DiplomaticHistory.cpp | 137 +++++++++++++-------- .../history/DiplomaticHistory.hpp | 29 +++-- src/openvic-simulation/history/Period.cpp | 27 ++++ src/openvic-simulation/history/Period.hpp | 18 +++ 4 files changed, 153 insertions(+), 58 deletions(-) create mode 100644 src/openvic-simulation/history/Period.cpp create mode 100644 src/openvic-simulation/history/Period.hpp diff --git a/src/openvic-simulation/history/DiplomaticHistory.cpp b/src/openvic-simulation/history/DiplomaticHistory.cpp index 088ec0a..883a212 100644 --- a/src/openvic-simulation/history/DiplomaticHistory.cpp +++ b/src/openvic-simulation/history/DiplomaticHistory.cpp @@ -2,6 +2,7 @@ #include "openvic-simulation/GameManager.hpp" #include "openvic-simulation/dataloader/NodeTools.hpp" +#include "openvic-simulation/history/Period.hpp" using namespace OpenVic; using namespace OpenVic::NodeTools; @@ -17,9 +18,8 @@ WarHistory::added_wargoal_t::added_wargoal_t( WarHistory::war_participant_t::war_participant_t( Country const* new_country, - Date new_joined, - std::optional new_exited -) : country { new_country }, joined { new_joined }, exited { new_exited } {} + const Period new_period +) : country { new_country }, period { new_period } {} WarHistory::WarHistory( std::string_view new_war_name, @@ -29,14 +29,23 @@ WarHistory::WarHistory( ) : war_name { new_war_name }, attackers { std::move(new_attackers) }, defenders { std::move(new_defenders) }, wargoals { std::move(new_wargoals) } {} AllianceHistory::AllianceHistory( - Country const* new_first, Country const* new_second, - Date new_start, Date new_end -) : first { new_first }, second { new_second }, start { new_start }, end { new_end } {} + Country const* new_first, + Country const* new_second, + const Period new_period +) : first { new_first }, second { new_second }, period {new_period} {} + +ReparationsHistory::ReparationsHistory( + Country const* new_receiver, + Country const* new_sender, + const Period new_period +) : receiver { new_receiver }, sender { new_sender }, period {new_period} {} SubjectHistory::SubjectHistory( - Country const* new_overlord, Country const* new_subject, - const type_t new_type, const Date new_start, const Date new_end -) : overlord { new_overlord }, subject { new_subject }, type { new_type }, start { new_start }, end { new_end } {} + Country const* new_overlord, + Country const* new_subject, + const type_t new_type, + const Period new_period +) : overlord { new_overlord }, subject { new_subject }, type { new_type }, period {new_period} {} void DiplomaticHistoryManager::lock_diplomatic_history() { Logger::info("Locked diplomacy history registry after registering ", alliances.size() + subjects.size() + wars.size(), " items"); @@ -48,19 +57,29 @@ bool DiplomaticHistoryManager::is_locked() const { } std::vector DiplomaticHistoryManager::get_alliances(Date date) const { - std::vector ret; + std::vector ret {}; for (const auto& alliance : alliances) { - if (alliance.start <= date && alliance.end >= date) { + if (alliance.period.is_date_in_period(date)) { ret.push_back(&alliance); } } return ret; } +std::vector DiplomaticHistoryManager::get_reparations(Date date) const { + std::vector ret {}; + for (const auto& reparation : reparations) { + if (reparation.period.is_date_in_period(date)) { + ret.push_back(&reparation); + } + } + return ret; +} + std::vector DiplomaticHistoryManager::get_subjects(Date date) const { - std::vector ret; + std::vector ret {}; for (const auto& subject : subjects) { - if (subject.start <= date && subject.end >= date) { + if (subject.period.is_date_in_period(date)) { ret.push_back(&subject); } } @@ -70,7 +89,7 @@ std::vector DiplomaticHistoryManager::get_subjects(Date d std::vector DiplomaticHistoryManager::get_wars(Date date) const { std::vector ret; for (const auto& war : wars) { - Date start; + Date start {}; for (const auto& wargoal : war.wargoals) { if (wargoal.added < start) start = wargoal.added; } @@ -82,63 +101,83 @@ std::vector DiplomaticHistoryManager::get_wars(Date date) con bool DiplomaticHistoryManager::load_diplomacy_history_file(CountryManager const& country_manager, ast::NodeCPtr root) { return expect_dictionary_keys( "alliance", ZERO_OR_MORE, [this, &country_manager](ast::NodeCPtr node) -> bool { - Country const* first; - Country const* second; - Date start, end; + Country const* first = nullptr; + Country const* second = nullptr; + Date start {}; + std::optional end {}; bool ret = expect_dictionary_keys( "first", ONE_EXACTLY, expect_identifier_or_string(country_manager.expect_country_str(assign_variable_callback_pointer(first))), "second", ONE_EXACTLY, expect_identifier_or_string(country_manager.expect_country_str(assign_variable_callback_pointer(second))), "start_date", ONE_EXACTLY, expect_identifier_or_string(expect_date_str(assign_variable_callback(start))), - "end_date", ONE_EXACTLY, expect_identifier_or_string(expect_date_str(assign_variable_callback(end))) + "end_date", ZERO_OR_ONE, expect_identifier_or_string(expect_date_str(assign_variable_callback(end))) )(node); - alliances.push_back({ first, second, start, end }); + alliances.push_back({ first, second, { start, end } }); return ret; }, "vassal", ZERO_OR_MORE, [this, &country_manager](ast::NodeCPtr node) -> bool { - Country const* overlord; - Country const* subject; - Date start, end; + Country const* overlord = nullptr; + Country const* subject = nullptr; + Date start {}; + std::optional end {}; bool ret = expect_dictionary_keys( "first", ONE_EXACTLY, expect_identifier_or_string(country_manager.expect_country_str(assign_variable_callback_pointer(overlord))), "second", ONE_EXACTLY, expect_identifier_or_string(country_manager.expect_country_str(assign_variable_callback_pointer(subject))), "start_date", ONE_EXACTLY, expect_identifier_or_string(expect_date_str(assign_variable_callback(start))), - "end_date", ONE_EXACTLY, expect_identifier_or_string(expect_date_str(assign_variable_callback(end))) + "end_date", ZERO_OR_ONE, expect_identifier_or_string(expect_date_str(assign_variable_callback(end))) )(node); - subjects.push_back({ overlord, subject, SubjectHistory::type_t::VASSAL, start, end }); + subjects.push_back({ overlord, subject, SubjectHistory::type_t::VASSAL, { start, end } }); return ret; }, "union", ZERO_OR_MORE, [this, &country_manager](ast::NodeCPtr node) -> bool { - Country const* overlord; - Country const* subject; - Date start, end; + Country const* overlord = nullptr; + Country const* subject = nullptr; + Date start {}; + std::optional end {}; bool ret = expect_dictionary_keys( "first", ONE_EXACTLY, country_manager.expect_country_identifier(assign_variable_callback_pointer(overlord)), "second", ONE_EXACTLY, country_manager.expect_country_identifier(assign_variable_callback_pointer(subject)), "start_date", ONE_EXACTLY, expect_date(assign_variable_callback(start)), - "end_date", ONE_EXACTLY, expect_date(assign_variable_callback(end)) + "end_date", ZERO_OR_ONE, expect_date(assign_variable_callback(end)) )(node); - subjects.push_back({ overlord, subject, SubjectHistory::type_t::UNION, start, end }); + subjects.push_back({ overlord, subject, SubjectHistory::type_t::UNION, { start, end } }); return ret; }, "substate", ZERO_OR_MORE, [this, &country_manager](ast::NodeCPtr node) -> bool { - Country const* overlord; - Country const* subject; - Date start, end; + Country const* overlord = nullptr; + Country const* subject = nullptr; + Date start {}; + std::optional end {}; bool ret = expect_dictionary_keys( "first", ONE_EXACTLY, country_manager.expect_country_identifier(assign_variable_callback_pointer(overlord)), "second", ONE_EXACTLY, country_manager.expect_country_identifier(assign_variable_callback_pointer(subject)), "start_date", ONE_EXACTLY, expect_date(assign_variable_callback(start)), - "end_date", ONE_EXACTLY, expect_date(assign_variable_callback(end)) + "end_date", ZERO_OR_ONE, expect_date(assign_variable_callback(end)) + )(node); + + subjects.push_back({ overlord, subject, SubjectHistory::type_t::SUBSTATE, { start, end } }); + return ret; + }, + "reparations", ZERO_OR_MORE, [this, &country_manager](ast::NodeCPtr node) -> bool { + Country const* receiver = nullptr; + Country const* sender = nullptr; + Date start {}; + std::optional end {}; + + bool ret = expect_dictionary_keys( + "first", ONE_EXACTLY, country_manager.expect_country_identifier(assign_variable_callback_pointer(receiver)), + "second", ONE_EXACTLY, country_manager.expect_country_identifier(assign_variable_callback_pointer(sender)), + "start_date", ONE_EXACTLY, expect_date(assign_variable_callback(start)), + "end_date", ZERO_OR_ONE, expect_date(assign_variable_callback(end)) )(node); - subjects.push_back({ overlord, subject, SubjectHistory::type_t::SUBSTATE, start, end }); + reparations.push_back({ receiver, sender, { start, end } }); return ret; } )(root); @@ -146,10 +185,10 @@ bool DiplomaticHistoryManager::load_diplomacy_history_file(CountryManager const& bool DiplomaticHistoryManager::load_war_history_file(GameManager const& game_manager, ast::NodeCPtr root) { std::string name = ""; - std::vector attackers; - std::vector defenders; - std::vector wargoals; - Date current_date; + std::vector attackers {}; + std::vector defenders {}; + std::vector wargoals {}; + Date current_date {}; bool ret = expect_dictionary_keys_and_default( [&game_manager, &attackers, &defenders, &wargoals, ¤t_date, &name](std::string_view key, ast::NodeCPtr node) -> bool { @@ -162,7 +201,8 @@ bool DiplomaticHistoryManager::load_war_history_file(GameManager const& game_man return false; } } - attackers.push_back({ &country, current_date, {} }); + + attackers.push_back({ &country, { current_date, {} } }); return true; }), "add_defender", ZERO_OR_MORE, game_manager.get_country_manager().expect_country_identifier([&defenders, ¤t_date, &name](Country const& country) -> bool { @@ -172,7 +212,8 @@ bool DiplomaticHistoryManager::load_war_history_file(GameManager const& game_man return false; } } - defenders.push_back({ &country, current_date, {} }); + + defenders.push_back({ &country, { current_date, {} } }); return true; }), "rem_attacker", ZERO_OR_MORE, game_manager.get_country_manager().expect_country_identifier([&attackers, ¤t_date, &name](Country const& country) -> bool { @@ -190,8 +231,7 @@ bool DiplomaticHistoryManager::load_war_history_file(GameManager const& game_man return true; } - participant_to_remove->exited.emplace(current_date); - return true; + return participant_to_remove->period.try_set_end(current_date); }), "rem_defender", ZERO_OR_MORE, game_manager.get_country_manager().expect_country_identifier([&defenders, ¤t_date, &name](Country const& country) -> bool { WarHistory::war_participant_t* participant_to_remove = nullptr; @@ -208,15 +248,14 @@ bool DiplomaticHistoryManager::load_war_history_file(GameManager const& game_man return true; } - participant_to_remove->exited.emplace(current_date); - return true; + return participant_to_remove->period.try_set_end(current_date); }), "war_goal", ZERO_OR_MORE, [&game_manager, &wargoals, ¤t_date](ast::NodeCPtr value) -> bool { - Country const* actor; - Country const* receiver; - WargoalType const* type; - std::optional third_party; - std::optional target; + Country const* actor = nullptr; + Country const* receiver = nullptr; + WargoalType const* type = nullptr; + std::optional third_party {}; + std::optional target {}; bool ret = expect_dictionary_keys( "actor", ONE_EXACTLY, game_manager.get_country_manager().expect_country_identifier(assign_variable_callback_pointer(actor)), diff --git a/src/openvic-simulation/history/DiplomaticHistory.hpp b/src/openvic-simulation/history/DiplomaticHistory.hpp index 3e877eb..07302ac 100644 --- a/src/openvic-simulation/history/DiplomaticHistory.hpp +++ b/src/openvic-simulation/history/DiplomaticHistory.hpp @@ -8,6 +8,7 @@ #include "openvic-simulation/country/Country.hpp" #include "openvic-simulation/military/Wargoal.hpp" #include "openvic-simulation/map/Province.hpp" +#include "openvic-simulation/history/Period.hpp" namespace OpenVic { struct DiplomaticHistoryManager; @@ -34,10 +35,9 @@ namespace OpenVic { private: Country const* PROPERTY(country); - Date PROPERTY_CUSTOM_PREFIX(joined, get_date); - std::optional PROPERTY_CUSTOM_PREFIX(exited, get_date); + Period PROPERTY(period); - war_participant_t(Country const* new_country, Date new_joined, std::optional new_exited); + war_participant_t(Country const* new_country, const Period period); }; private: @@ -55,10 +55,20 @@ namespace OpenVic { private: Country const* PROPERTY(first); Country const* PROPERTY(second); - const Date start; - const Date end; + const Period PROPERTY(period); - AllianceHistory(Country const* new_first, Country const* new_second, const Date new_start, const Date new_end); + AllianceHistory(Country const* new_first, Country const* new_second, const Period period); + }; + + struct ReparationsHistory { + friend struct DiplomaticHistoryManager; + + private: + Country const* PROPERTY(receiver); + Country const* PROPERTY(sender); + const Period PROPERTY(period); + + ReparationsHistory(Country const* new_receiver, Country const* new_sender, const Period period); }; struct SubjectHistory { @@ -74,15 +84,15 @@ namespace OpenVic { Country const* PROPERTY(overlord); Country const* PROPERTY(subject); const type_t PROPERTY_CUSTOM_PREFIX(type, get_subject); - const Date start; - const Date end; + const Period PROPERTY(period); - SubjectHistory(Country const* new_overlord, Country const* new_subject, const type_t new_type, const Date new_start, const Date new_end); + SubjectHistory(Country const* new_overlord, Country const* new_subject, const type_t new_type, const Period period); }; struct DiplomaticHistoryManager { private: std::vector alliances; + std::vector reparations; std::vector subjects; std::vector wars; bool locked = false; @@ -94,6 +104,7 @@ namespace OpenVic { bool is_locked() const; std::vector get_alliances(Date date) const; + std::vector get_reparations(Date date) const; std::vector get_subjects(Date date) const; /* Returns all wars that begin before date. NOTE: Some wargoals may be added or countries may join after date, should be checked for by functions that use get_wars() */ std::vector get_wars(Date date) const; diff --git a/src/openvic-simulation/history/Period.cpp b/src/openvic-simulation/history/Period.cpp new file mode 100644 index 0000000..cb133dd --- /dev/null +++ b/src/openvic-simulation/history/Period.cpp @@ -0,0 +1,27 @@ +#include "openvic-simulation/history/Period.hpp" + +using namespace OpenVic; + +Period::Period( + const Date new_start_date, + const std::optional new_end_date +) : start_date {new_start_date}, end_date {new_end_date} {} + +bool Period::is_date_in_period(const Date date) const { + return start_date <= date && (!end_date.has_value() || end_date.value() >= date); +} + +bool Period::try_set_end(const Date date) { + if (end_date.has_value()) { + Logger::error("Period already has end date ", end_date.value()); + return false; + } + + if (date < start_date) { + Logger::error("Proposed end date ", date, " is before start date ", start_date); + return false; + } + + end_date = date; + return true; +} \ No newline at end of file diff --git a/src/openvic-simulation/history/Period.hpp b/src/openvic-simulation/history/Period.hpp new file mode 100644 index 0000000..c788be9 --- /dev/null +++ b/src/openvic-simulation/history/Period.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include +#include "openvic-simulation/types/Date.hpp" +#include "openvic-simulation/utility/Logger.hpp" + +namespace OpenVic { + struct Period { + private: + const Date start_date; + std::optional end_date; + + public: + Period(const Date new_start_date, const std::optional new_end_date); + bool is_date_in_period(const Date date) const; + bool try_set_end(const Date date); + }; +} \ No newline at end of file -- cgit v1.2.3-56-ga3b1