diff options
Diffstat (limited to 'src/openvic-simulation/diplomacy')
5 files changed, 253 insertions, 38 deletions
diff --git a/src/openvic-simulation/diplomacy/CountryRelation.cpp b/src/openvic-simulation/diplomacy/CountryRelation.cpp new file mode 100644 index 0000000..d07739c --- /dev/null +++ b/src/openvic-simulation/diplomacy/CountryRelation.cpp @@ -0,0 +1,53 @@ +#include "CountryRelation.hpp" + +#include <cassert> + +#include "openvic-simulation/country/CountryInstance.hpp" +#include "openvic-simulation/utility/ErrorMacros.hpp" + +using namespace OpenVic; + +CountryRelationInstanceProxy::CountryRelationInstanceProxy(std::string_view id) : country_id { id } {} + +CountryRelationInstanceProxy::CountryRelationInstanceProxy(CountryInstance const* country) + : country_id { country->get_base_country()->get_identifier() } {} + +CountryRelationInstanceProxy::operator std::string_view() const { + return country_id; +} + +CountryRelationManager::CountryRelationManager(/* TODO: Country Instance Manager Reference */) {} + +bool CountryRelationManager::add_country(CountryRelationInstanceProxy country) { + // TODO: iterate through Country Instances adding country to every previously existing country_relations + return true; +} + +bool CountryRelationManager::remove_country(CountryRelationInstanceProxy country) { + // TODO: iterate through country_relations removing every pair that references the country's id + return true; +} + +country_relation_value_t CountryRelationManager::get_country_relation( + CountryRelationInstanceProxy country, CountryRelationInstanceProxy recepient +) const { + auto it = country_relations.find({ country.country_id, recepient.country_id }); + OV_ERR_FAIL_COND_V(it == country_relations.end(), 0); + return it->second; +} + +country_relation_value_t* +CountryRelationManager::get_country_relation_ptr(CountryRelationInstanceProxy country, CountryRelationInstanceProxy recepient) { + auto it = country_relations.find({ country.country_id, recepient.country_id }); + OV_ERR_FAIL_COND_V(it == country_relations.end(), nullptr); + return &it.value(); +} + +bool CountryRelationManager::set_country_relation( + CountryRelationInstanceProxy country, CountryRelationInstanceProxy recepient, country_relation_value_t value +) { + auto it = country_relations.find({ country.country_id, recepient.country_id }); + OV_ERR_FAIL_COND_V(it == country_relations.end(), false); + it.value() = value; + return true; +} diff --git a/src/openvic-simulation/diplomacy/CountryRelation.hpp b/src/openvic-simulation/diplomacy/CountryRelation.hpp new file mode 100644 index 0000000..76b3897 --- /dev/null +++ b/src/openvic-simulation/diplomacy/CountryRelation.hpp @@ -0,0 +1,95 @@ +#pragma once + +#include <compare> +#include <tuple> + +#include "openvic-simulation/types/OrderedContainers.hpp" +#include "openvic-simulation/utility/Utility.hpp" + +namespace OpenVic { + struct CountryInstance; + + struct CountryRelationInstanceProxy { + std::string_view country_id; + + CountryRelationInstanceProxy(std::string_view id); + CountryRelationInstanceProxy(CountryInstance const* country); + + operator std::string_view() const; + }; + + struct CountryRelationPair : std::pair<std::string_view, std::string_view> { + using base_type = std::pair<std::string_view, std::string_view>; + using base_type::base_type; + + inline constexpr auto operator<=>(CountryRelationPair const& rhs) const { + using ordering = decltype(OpenVic::utility::three_way(std::tie(first, second), std::tie(rhs.first, rhs.second))); + + auto tied = std::tie(first, second); + if (tied == std::tie(rhs.first, rhs.second)) { + return ordering::equivalent; + } else if (tied == std::tie(rhs.second, rhs.first)) { + return ordering::equivalent; + } + + auto& [lhs_left, lhs_right] = *this; + auto& [rhs_left, rhs_right] = rhs; + + auto& lhs_comp_first = lhs_left > lhs_right ? lhs_left : lhs_right; + auto& lhs_comp_second = lhs_left < lhs_right ? lhs_left : lhs_right; + + auto& rhs_comp_first = rhs_left > rhs_right ? rhs_left : rhs_right; + auto& rhs_comp_second = rhs_left < rhs_right ? rhs_left : rhs_right; + + return OpenVic::utility::three_way( + std::tie(lhs_comp_first, lhs_comp_second), std::tie(rhs_comp_first, rhs_comp_second) + ); + } + + inline constexpr bool operator==(CountryRelationPair const& rhs) const { + auto tied = std::tie(first, second); + return tied == std::tie(rhs.first, rhs.second) || tied == std::tie(rhs.second, rhs.first); + } + }; +} + +namespace std { + template<> + struct hash<OpenVic::CountryRelationPair> { + size_t operator()(OpenVic::CountryRelationPair const& pair) const { + std::size_t seed1(0); + OpenVic::utility::hash_combine(seed1, pair.first); + OpenVic::utility::hash_combine(seed1, pair.second); + + std::size_t seed2(0); + OpenVic::utility::hash_combine(seed2, pair.second); + OpenVic::utility::hash_combine(seed2, pair.first); + + return std::min(seed1, seed2); + } + }; +} + +namespace OpenVic { + using country_relation_value_t = int16_t; + + struct CountryRelationManager { + private: + // TODO: reference of manager responsible for storing CountryInstances + ordered_map<CountryRelationPair, country_relation_value_t> country_relations; + + public: + CountryRelationManager(/* TODO: Country Instance Manager Reference */); + + bool add_country(CountryRelationInstanceProxy country); + bool remove_country(CountryRelationInstanceProxy country); + + country_relation_value_t + get_country_relation(CountryRelationInstanceProxy country, CountryRelationInstanceProxy recepient) const; + country_relation_value_t* + get_country_relation_ptr(CountryRelationInstanceProxy country, CountryRelationInstanceProxy recepient); + bool set_country_relation( + CountryRelationInstanceProxy country, CountryRelationInstanceProxy recepient, country_relation_value_t value + ); + }; +} diff --git a/src/openvic-simulation/diplomacy/DiplomacyManager.hpp b/src/openvic-simulation/diplomacy/DiplomacyManager.hpp index c71bdbf..7aca409 100644 --- a/src/openvic-simulation/diplomacy/DiplomacyManager.hpp +++ b/src/openvic-simulation/diplomacy/DiplomacyManager.hpp @@ -1,9 +1,11 @@ #pragma once +#include "openvic-simulation/diplomacy/CountryRelation.hpp" #include "openvic-simulation/diplomacy/DiplomaticAction.hpp" namespace OpenVic { class DiplomacyManager { DiplomaticActionManager PROPERTY_REF(diplomatic_action_manager); + CountryRelationManager PROPERTY_REF(country_relation_manager); }; } diff --git a/src/openvic-simulation/diplomacy/DiplomaticAction.cpp b/src/openvic-simulation/diplomacy/DiplomaticAction.cpp index d10eda3..a386d9f 100644 --- a/src/openvic-simulation/diplomacy/DiplomaticAction.cpp +++ b/src/openvic-simulation/diplomacy/DiplomaticAction.cpp @@ -1,19 +1,19 @@ #include "DiplomaticAction.hpp" #include <string_view> -#include <variant> +#include "openvic-simulation/GameManager.hpp" #include "openvic-simulation/types/IdentifierRegistry.hpp" #include "openvic-simulation/utility/Logger.hpp" using namespace OpenVic; DiplomaticActionType::DiplomaticActionType(DiplomaticActionType::Initializer&& initializer) - : commit_action_caller { std::move(initializer.commit) }, - allowed_to_commit { std::move(initializer.allowed) }, get_acceptance { std::move(initializer.get_acceptance) } {} + : commit_action_caller { std::move(initializer.commit) }, allowed_to_commit { std::move(initializer.allowed) }, + get_acceptance { std::move(initializer.get_acceptance) } {} CancelableDiplomaticActionType::CancelableDiplomaticActionType(CancelableDiplomaticActionType::Initializer&& initializer) - : allowed_to_cancel{std::move(initializer.allowed_cancel)}, DiplomaticActionType(std::move(initializer)) {} + : allowed_to_cancel { std::move(initializer.allowed_cancel) }, DiplomaticActionType(std::move(initializer)) {} DiplomaticActionManager::DiplomaticActionManager() {} @@ -38,7 +38,7 @@ bool DiplomaticActionManager::add_cancelable_diplomatic_action( } DiplomaticActionTickCache DiplomaticActionManager::create_diplomatic_action_tick( - std::string_view identifier, Country& sender, Country& reciever, std::any context_data + std::string_view identifier, CountryInstance* sender, CountryInstance* reciever, std::any context_data ) { auto type = diplomatic_action_types.get_item_by_identifier(identifier); @@ -52,92 +52,151 @@ DiplomaticActionTickCache DiplomaticActionManager::create_diplomatic_action_tick return result; } -bool DiplomaticActionManager::setup_diplomatic_actions() { +bool DiplomaticActionManager::setup_diplomatic_actions(GameManager& manager) { using Argument = DiplomaticActionType::Argument; bool result = true; result &= add_diplomatic_action( "form_alliance", - { [](Argument& arg) {} } + { + [](Argument& arg) {}, + } ); result &= add_diplomatic_action( "call_ally", { .commit = [](Argument& arg) {}, - .allowed = [](const Argument& arg) { return false; }, - .get_acceptance = [](const Argument& arg) { return 1; } + .allowed = + [](const Argument& arg) { + return false; + }, + .get_acceptance = + [](const Argument& arg) { + return 1; + }, } ); result &= add_cancelable_diplomatic_action( "request_military_access", { .commit = [](Argument& arg) {}, - .allowed_cancel = [](const Argument& arg) { return true; } + .allowed_cancel = + [](const Argument& arg) { + return true; + }, } ); - result &= add_diplomatic_action( - "give_military_access", - { [](Argument& arg) {} } - ); + result &= add_diplomatic_action("give_military_access", { [](Argument& arg) {} }); result &= add_diplomatic_action( "increase_relations", { - .commit = [](Argument& arg) {}, - .allowed = [](const Argument& arg) { return false; }, + .commit = + [&manager](Argument& arg) { + auto relation = manager.get_diplomacy_manager().get_country_relation_manager().get_country_relation_ptr( + arg.sender, arg.reciever + ); + if (!relation) { + return; + } + *relation += 25; + }, + .allowed = + [](const Argument& arg) { + return false; + }, } ); result &= add_diplomatic_action( "decrease_relations", - { [](Argument& arg) {} } + { + .commit = + [&manager](Argument& arg) { + auto relation = manager.get_diplomacy_manager().get_country_relation_manager().get_country_relation_ptr( + arg.sender, arg.reciever + ); + if (!relation) { + return; + } + *relation -= 25; + }, + .allowed = + [](const Argument& arg) { + return false; + }, + } ); result &= add_diplomatic_action( "war_subsidies", - { [](Argument& arg) {} } + { + [](Argument& arg) {}, + } ); result &= add_diplomatic_action( "declare_war", - { [](Argument& arg) {} } + { + [](Argument& arg) {}, + } ); result &= add_diplomatic_action( "offer_peace", - { [](Argument& arg) {} } + { + [](Argument& arg) {}, + } ); result &= add_diplomatic_action( "command_units", - { [](Argument& arg) {} } + { + [](Argument& arg) {}, + } ); result &= add_diplomatic_action( "discredit", - { [](Argument& arg) {} } + { + [](Argument& arg) {}, + } ); result &= add_diplomatic_action( "expel_advisors", - { [](Argument& arg) {} } + { + [](Argument& arg) {}, + } ); result &= add_diplomatic_action( "increase_opinion", - { [](Argument& arg) {} } + { + [](Argument& arg) {}, + } ); result &= add_diplomatic_action( "decrease_opinion", - { [](Argument& arg) {} } + { + [](Argument& arg) {}, + } ); result &= add_diplomatic_action( "add_to_sphere", - { [](Argument& arg) {} } + { + [](Argument& arg) {}, + } ); result &= add_diplomatic_action( "remove_from_sphere", - { [](Argument& arg) {} } + { + [](Argument& arg) {}, + } ); result &= add_diplomatic_action( "justify_war", - { [](Argument& arg) {} } + { + [](Argument& arg) {}, + } ); result &= add_diplomatic_action( "give_vision", - { [](Argument& arg) {} } + { + [](Argument& arg) {}, + } ); diplomatic_action_types.lock(); diff --git a/src/openvic-simulation/diplomacy/DiplomaticAction.hpp b/src/openvic-simulation/diplomacy/DiplomaticAction.hpp index 8f659c6..352b16e 100644 --- a/src/openvic-simulation/diplomacy/DiplomaticAction.hpp +++ b/src/openvic-simulation/diplomacy/DiplomaticAction.hpp @@ -8,17 +8,20 @@ #include <variant> #include "openvic-simulation/country/Country.hpp" +#include "openvic-simulation/country/CountryInstance.hpp" #include "openvic-simulation/types/FunctionRef.hpp" #include "openvic-simulation/types/IdentifierRegistry.hpp" namespace OpenVic { + struct GameManager; + struct DiplomaticActionType { friend struct DiplomaticActionManager; friend struct CancelableDiplomaticActionType; struct Argument { - Country& sender; - Country& reciever; + CountryInstance* sender; + CountryInstance* reciever; std::any context_data; }; @@ -68,7 +71,7 @@ namespace OpenVic { allowed_to_cancel_func allowed_cancel = allowed_to_cancel_default; operator DiplomaticActionType::Initializer() { - return {commit, allowed, get_acceptance}; + return { commit, allowed, get_acceptance }; } }; @@ -87,7 +90,7 @@ namespace OpenVic { constexpr DiplomaticActionTypeStorage(std::string_view identifier, T&& t) : HasIdentifier(identifier), base_type(t) {} template<class Visitor> - constexpr decltype(auto) visit(Visitor&& vis){ + constexpr decltype(auto) visit(Visitor&& vis) { return std::visit(std::forward<Visitor>(vis), *this); } @@ -99,7 +102,7 @@ namespace OpenVic { constexpr bool is_cancelable() const { return visit([](auto&& arg) -> bool { using T = std::decay_t<decltype(arg)>; - if constexpr(std::same_as<T, CancelableDiplomaticActionType>) { + if constexpr (std::same_as<T, CancelableDiplomaticActionType>) { return true; } else { return false; @@ -123,11 +126,14 @@ namespace OpenVic { DiplomaticActionManager(); bool add_diplomatic_action(std::string_view identifier, DiplomaticActionType::Initializer&& initializer); - bool add_cancelable_diplomatic_action(std::string_view identifier, CancelableDiplomaticActionType::Initializer&& initializer); + bool add_cancelable_diplomatic_action( + std::string_view identifier, CancelableDiplomaticActionType::Initializer&& initializer + ); - DiplomaticActionTickCache - create_diplomatic_action_tick(std::string_view identifier, Country& sender, Country& reciever, std::any context_data); + DiplomaticActionTickCache create_diplomatic_action_tick( + std::string_view identifier, CountryInstance* sender, CountryInstance* reciever, std::any context_data + ); - bool setup_diplomatic_actions(); + bool setup_diplomatic_actions(GameManager& manager); }; } |