diff options
Diffstat (limited to 'src/openvic-simulation/diplomacy')
-rw-r--r-- | src/openvic-simulation/diplomacy/DiplomacyManager.hpp | 9 | ||||
-rw-r--r-- | src/openvic-simulation/diplomacy/DiplomaticAction.cpp | 146 | ||||
-rw-r--r-- | src/openvic-simulation/diplomacy/DiplomaticAction.hpp | 134 |
3 files changed, 289 insertions, 0 deletions
diff --git a/src/openvic-simulation/diplomacy/DiplomacyManager.hpp b/src/openvic-simulation/diplomacy/DiplomacyManager.hpp new file mode 100644 index 0000000..c71bdbf --- /dev/null +++ b/src/openvic-simulation/diplomacy/DiplomacyManager.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include "openvic-simulation/diplomacy/DiplomaticAction.hpp" + +namespace OpenVic { + class DiplomacyManager { + DiplomaticActionManager PROPERTY_REF(diplomatic_action_manager); + }; +} diff --git a/src/openvic-simulation/diplomacy/DiplomaticAction.cpp b/src/openvic-simulation/diplomacy/DiplomaticAction.cpp new file mode 100644 index 0000000..c1aa3df --- /dev/null +++ b/src/openvic-simulation/diplomacy/DiplomaticAction.cpp @@ -0,0 +1,146 @@ +#include "DiplomaticAction.hpp" + +#include <string_view> +#include <variant> + +#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) } {} + +CancelableDiplomaticActionType::CancelableDiplomaticActionType(CancelableDiplomaticActionType::Initializer&& initializer) + : allowed_to_cancel{std::move(initializer.allowed_cancel)}, DiplomaticActionType(std::move(initializer)) {} + + +DiplomaticActionManager::DiplomaticActionManager() {} + +bool DiplomaticActionManager::add_diplomatic_action( + std::string_view identifier, DiplomaticActionType::Initializer&& initializer +) { + if (identifier.empty()) { + Logger::error("Invalid diplomatic action identifier - empty!"); + return false; + } + return diplomatic_action_types.add_item({ identifier, DiplomaticActionType { std::move(initializer) } }); +} + +bool DiplomaticActionManager::add_cancelable_diplomatic_action( + std::string_view identifier, CancelableDiplomaticActionType::Initializer&& initializer +) { + if (identifier.empty()) { + Logger::error("Invalid cancelable diplomatic action identifier - empty!"); + return false; + } + return diplomatic_action_types.add_item({ identifier, CancelableDiplomaticActionType { std::move(initializer) } }); +} + +DiplomaticActionTickCache DiplomaticActionManager::create_diplomatic_action_tick( + std::string_view identifier, Country& sender, Country& reciever, std::any context_data +) { + auto type = diplomatic_action_types.get_item_by_identifier(identifier); + + DiplomaticActionTickCache result { { sender, reciever, context_data }, type }; + type->visit([&](auto type) { + if ((result.allowed_to_commit = type.allowed_to_commit(result.argument))) { + result.acceptance = type.get_acceptance(result.argument); + } + }); + + return result; +} + +bool DiplomaticActionManager::setup_diplomatic_actions() { + using Argument = DiplomaticActionType::Argument; + + bool result = true; + + result &= add_diplomatic_action( + "form_alliance", + { [](Argument& arg) {} } + ); + result &= add_diplomatic_action( + "call_ally", + { + .commit = [](Argument& arg) {}, + .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; } + } + ); + result &= add_diplomatic_action( + "give_military_access", + { [](Argument& arg) {} } + ); + result &= add_diplomatic_action( + "increase_relations", + { + .commit = [](Argument& arg) {}, + .allowed = [](const Argument& arg) { return false; }, + } + ); + result &= add_diplomatic_action( + "decrease_relations", + { [](Argument& arg) {} } + ); + result &= add_diplomatic_action( + "war_subsidies", + { [](Argument& arg) {} } + ); + result &= add_diplomatic_action( + "declare_war", + { [](Argument& arg) {} } + ); + result &= add_diplomatic_action( + "offer_peace", + { [](Argument& arg) {} } + ); + result &= add_diplomatic_action( + "command_units", + { [](Argument& arg) {} } + ); + result &= add_diplomatic_action( + "discredit", + { [](Argument& arg) {} } + ); + result &= add_diplomatic_action( + "expel_advisors", + { [](Argument& arg) {} } + ); + result &= add_diplomatic_action( + "increase_opinion", + { [](Argument& arg) {} } + ); + result &= add_diplomatic_action( + "decrease_opinion", + { [](Argument& arg) {} } + ); + result &= add_diplomatic_action( + "add_to_sphere", + { [](Argument& arg) {} } + ); + result &= add_diplomatic_action( + "remove_from_sphere", + { [](Argument& arg) {} } + ); + result &= add_diplomatic_action( + "justify_war", + { [](Argument& arg) {} } + ); + result &= add_diplomatic_action( + "give_vision", + { [](Argument& arg) {} } + ); + diplomatic_action_types.lock(); + + return result; +} diff --git a/src/openvic-simulation/diplomacy/DiplomaticAction.hpp b/src/openvic-simulation/diplomacy/DiplomaticAction.hpp new file mode 100644 index 0000000..7254510 --- /dev/null +++ b/src/openvic-simulation/diplomacy/DiplomaticAction.hpp @@ -0,0 +1,134 @@ +#pragma once + +#include <any> +#include <concepts> +#include <cstdint> +#include <string_view> +#include <type_traits> +#include <variant> + +#include "openvic-simulation/country/Country.hpp" +#include "openvic-simulation/types/FunctionRef.hpp" +#include "openvic-simulation/types/IdentifierRegistry.hpp" + +namespace OpenVic { + struct DiplomaticActionType { + friend struct DiplomaticActionManager; + friend struct CancelableDiplomaticActionType; + + struct Argument { + Country& sender; + Country& reciever; + std::any context_data; + }; + + using allowed_to_commit_func = FunctionRef<bool(const Argument&)>; + using get_acceptance_func = FunctionRef<std::int32_t(const Argument&)>; + using commit_action_func = FunctionRef<void(Argument&)>; + + static bool allowed_to_commit_default(const Argument& argument) { + return true; + } + + static std::int32_t get_acceptance_default(const Argument& argument) { + return 1; + } + + struct Initializer { + commit_action_func commit; + allowed_to_commit_func allowed = allowed_to_commit_default; + get_acceptance_func get_acceptance = get_acceptance_default; + }; + + const commit_action_func commit_action_caller; + const allowed_to_commit_func allowed_to_commit = allowed_to_commit_default; + const get_acceptance_func get_acceptance = get_acceptance_default; + + void commit_action(Argument& arg) const { + commit_action_caller(arg); + } + + private: + DiplomaticActionType(Initializer&& initializer); + }; + + struct CancelableDiplomaticActionType : DiplomaticActionType { + friend struct DiplomaticActionManager; + + using allowed_to_cancel_func = FunctionRef<bool(const Argument&)>; + + + static bool allowed_to_cancel_default(const Argument& argument) { + return true; + } + + struct Initializer { + commit_action_func commit; + allowed_to_commit_func allowed = allowed_to_commit_default; + get_acceptance_func get_acceptance = get_acceptance_default; + allowed_to_cancel_func allowed_cancel = allowed_to_cancel_default; + + operator DiplomaticActionType::Initializer() { + return {commit, allowed, get_acceptance}; + } + }; + + const allowed_to_cancel_func allowed_to_cancel = allowed_to_cancel_default; + + private: + CancelableDiplomaticActionType(Initializer&& initializer); + }; + + struct DiplomaticActionTickCache; + + struct DiplomaticActionTypeStorage : std::variant<DiplomaticActionType, CancelableDiplomaticActionType>, HasIdentifier { + using base_type = std::variant<DiplomaticActionType, CancelableDiplomaticActionType>; + + template<typename T> + constexpr DiplomaticActionTypeStorage(std::string_view identifier, T&& t) : HasIdentifier(identifier), base_type(t) {} + + template<class Visitor> + constexpr decltype(auto) visit(Visitor&& vis){ + return std::visit(std::forward<Visitor>(vis), *this); + } + + template<class Visitor> + constexpr decltype(auto) visit(Visitor&& vis) const { + return std::visit(std::forward<Visitor>(vis), *this); + } + + constexpr bool is_cancelable() const { + return visit([](auto&& arg) -> bool { + using T = std::decay_t<decltype(arg)>; + if constexpr(std::same_as<T, CancelableDiplomaticActionType>) { + return true; + } else { + return false; + } + }); + } + }; + + struct DiplomaticActionTickCache { + DiplomaticActionType::Argument argument; + const DiplomaticActionTypeStorage* type; + bool allowed_to_commit; + std::int32_t acceptance = -1; + }; + + struct DiplomaticActionManager { + private: + IdentifierRegistry<DiplomaticActionTypeStorage> IDENTIFIER_REGISTRY(diplomatic_action_type); + + public: + DiplomaticActionManager(); + + bool add_diplomatic_action(std::string_view identifier, DiplomaticActionType::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); + + bool setup_diplomatic_actions(); + }; +} |