aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/diplomacy
diff options
context:
space:
mode:
author Spartan322 <Megacake1234@gmail.com>2023-12-20 00:45:09 +0100
committer Spartan322 <Megacake1234@gmail.com>2024-01-03 01:46:54 +0100
commit5fa456c21ad950a6f269b83f5e88ce8c90ae9a14 (patch)
treef8f1b23dd13a0f2029747404ad30ffa346b5e99f /src/openvic-simulation/diplomacy
parent66b80459c9d49895de902432bce11176b1270878 (diff)
Add diplomatic actions skeleton
Add AnyRef for cheap "move only" reference Add FunctionRef for cheap "move only" function reference Based on https://github.com/think-cell/think-cell-library/blob/main/tc/base/ref.h
Diffstat (limited to 'src/openvic-simulation/diplomacy')
-rw-r--r--src/openvic-simulation/diplomacy/DiplomacyManager.hpp9
-rw-r--r--src/openvic-simulation/diplomacy/DiplomaticAction.cpp146
-rw-r--r--src/openvic-simulation/diplomacy/DiplomaticAction.hpp134
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();
+ };
+}