diff options
author | Hop311 <Hop3114@gmail.com> | 2024-01-02 15:40:00 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-02 15:40:00 +0100 |
commit | 4c8da86c3bede8834f381fa63edaa3e140131f69 (patch) | |
tree | ff3433a63e91b9239eb7226e75054314182d6c1f /src/openvic-simulation/scripts | |
parent | 66b80459c9d49895de902432bce11176b1270878 (diff) | |
parent | 5f64f983d0cead266a28791be42162c443fd2a75 (diff) |
Merge pull request #112 from OpenVicProject/script-framework
Added framework for loading all Conditions and Effects
Diffstat (limited to 'src/openvic-simulation/scripts')
-rw-r--r-- | src/openvic-simulation/scripts/ConditionScript.cpp | 8 | ||||
-rw-r--r-- | src/openvic-simulation/scripts/ConditionScript.hpp | 12 | ||||
-rw-r--r-- | src/openvic-simulation/scripts/ConditionalWeight.cpp | 64 | ||||
-rw-r--r-- | src/openvic-simulation/scripts/ConditionalWeight.hpp | 44 | ||||
-rw-r--r-- | src/openvic-simulation/scripts/EffectScript.cpp | 8 | ||||
-rw-r--r-- | src/openvic-simulation/scripts/EffectScript.hpp | 12 | ||||
-rw-r--r-- | src/openvic-simulation/scripts/Script.hpp | 38 |
7 files changed, 186 insertions, 0 deletions
diff --git a/src/openvic-simulation/scripts/ConditionScript.cpp b/src/openvic-simulation/scripts/ConditionScript.cpp new file mode 100644 index 0000000..af2faf7 --- /dev/null +++ b/src/openvic-simulation/scripts/ConditionScript.cpp @@ -0,0 +1,8 @@ +#include "ConditionScript.hpp" + +using namespace OpenVic; + +bool ConditionScript::_parse_script(ast::NodeCPtr root, GameManager const& game_manager) { + // TODO - parse condition script + return true; +} diff --git a/src/openvic-simulation/scripts/ConditionScript.hpp b/src/openvic-simulation/scripts/ConditionScript.hpp new file mode 100644 index 0000000..cb967a2 --- /dev/null +++ b/src/openvic-simulation/scripts/ConditionScript.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "openvic-simulation/scripts/Script.hpp" + +namespace OpenVic { + struct GameManager; + + struct ConditionScript final : Script<GameManager const&> { + protected: + bool _parse_script(ast::NodeCPtr root, GameManager const& game_manager) override; + }; +} diff --git a/src/openvic-simulation/scripts/ConditionalWeight.cpp b/src/openvic-simulation/scripts/ConditionalWeight.cpp new file mode 100644 index 0000000..29dc93b --- /dev/null +++ b/src/openvic-simulation/scripts/ConditionalWeight.cpp @@ -0,0 +1,64 @@ +#include "ConditionalWeight.hpp" + +using namespace OpenVic; +using namespace OpenVic::NodeTools; + +template<typename T> +static NodeCallback auto expect_modifier(std::vector<T>& items) { + return [&items](ast::NodeCPtr node) -> bool { + fixed_point_t weight = 0; + bool successful = false; + bool ret = expect_key("factor", expect_fixed_point(assign_variable_callback(weight)), &successful)(node); + if (!successful) { + Logger::info("ConditionalWeight modifier missing factor key!"); + return false; + } + ConditionScript condition; + ret &= condition.expect_script()(node); + items.emplace_back(std::make_pair(weight, std::move(condition))); + return ret; + }; +} + +node_callback_t ConditionalWeight::expect_conditional_weight(base_key_t base_key) { + return expect_dictionary_keys( + // TODO - add days and years as options with a shared expected count of ONE_EXACTLY + base_key_to_string(base_key), ONE_EXACTLY, expect_fixed_point(assign_variable_callback(base)), + "modifier", ZERO_OR_MORE, expect_modifier(condition_weight_items), + "group", ZERO_OR_MORE, [this](ast::NodeCPtr node) -> bool { + condition_weight_group_t items; + const bool ret = expect_dictionary_keys( + "modifier", ONE_OR_MORE, expect_modifier(items) + )(node); + if (!items.empty()) { + condition_weight_items.emplace_back(std::move(items)); + return ret; + } + Logger::error("ConditionalWeight group must have at least one modifier!"); + return false; + } + ); +} + +struct ConditionalWeight::parse_scripts_visitor_t { + GameManager const& game_manager; + + bool operator()(condition_weight_t& condition_weight) const { + return condition_weight.second.parse_script(false, game_manager); + } + bool operator()(condition_weight_item_t& item) const { + return std::visit(*this, item); + } + template<typename T> + bool operator()(std::vector<T>& items) const { + bool ret = true; + for (T& item : items) { + ret &= (*this)(item); + } + return ret; + } +}; + +bool ConditionalWeight::parse_scripts(GameManager const& game_manager) { + return parse_scripts_visitor_t { game_manager }(condition_weight_items); +} diff --git a/src/openvic-simulation/scripts/ConditionalWeight.hpp b/src/openvic-simulation/scripts/ConditionalWeight.hpp new file mode 100644 index 0000000..a965ae1 --- /dev/null +++ b/src/openvic-simulation/scripts/ConditionalWeight.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include <variant> +#include <vector> + +#include "openvic-simulation/dataloader/NodeTools.hpp" +#include "openvic-simulation/scripts/ConditionScript.hpp" +#include "openvic-simulation/types/fixed_point/FixedPoint.hpp" + +namespace OpenVic { + struct ConditionalWeight { + using condition_weight_t = std::pair<fixed_point_t, ConditionScript>; + using condition_weight_group_t = std::vector<condition_weight_t>; + using condition_weight_item_t = std::variant<condition_weight_t, condition_weight_group_t>; + + enum class base_key_t : uint8_t { + BASE, FACTOR, MONTHS + }; + using enum base_key_t; + + private: + fixed_point_t PROPERTY(base); + std::vector<condition_weight_item_t> PROPERTY(condition_weight_items); + + struct parse_scripts_visitor_t; + + public: + ConditionalWeight() = default; + ConditionalWeight(ConditionalWeight&&) = default; + + static constexpr std::string_view base_key_to_string(base_key_t base_key) { + switch (base_key) { + case base_key_t::BASE: return "base"; + case base_key_t::FACTOR: return "factor"; + case base_key_t::MONTHS: return "months"; // TODO - add functionality for days or months or years + default: return "INVALID BASE KEY"; + } + } + + NodeTools::node_callback_t expect_conditional_weight(base_key_t base_key); + + bool parse_scripts(GameManager const& game_manager); + }; +} diff --git a/src/openvic-simulation/scripts/EffectScript.cpp b/src/openvic-simulation/scripts/EffectScript.cpp new file mode 100644 index 0000000..f51c053 --- /dev/null +++ b/src/openvic-simulation/scripts/EffectScript.cpp @@ -0,0 +1,8 @@ +#include "EffectScript.hpp" + +using namespace OpenVic; + +bool EffectScript::_parse_script(ast::NodeCPtr root, GameManager& game_manager) { + // TODO - parse effect script + return true; +} diff --git a/src/openvic-simulation/scripts/EffectScript.hpp b/src/openvic-simulation/scripts/EffectScript.hpp new file mode 100644 index 0000000..f5acf78 --- /dev/null +++ b/src/openvic-simulation/scripts/EffectScript.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "openvic-simulation/scripts/Script.hpp" + +namespace OpenVic { + struct GameManager; + + struct EffectScript final : Script<GameManager&> { + protected: + bool _parse_script(ast::NodeCPtr root, GameManager& game_manager) override; + }; +} diff --git a/src/openvic-simulation/scripts/Script.hpp b/src/openvic-simulation/scripts/Script.hpp new file mode 100644 index 0000000..8efc277 --- /dev/null +++ b/src/openvic-simulation/scripts/Script.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include "openvic-simulation/dataloader/NodeTools.hpp" + +namespace OpenVic { + template<typename... _Context> + struct Script { + private: + ast::NodeCPtr _root; + + protected: + virtual bool _parse_script(ast::NodeCPtr root, _Context... context) = 0; + + public: + Script() : _root { nullptr } {} + Script(Script&&) = default; + + constexpr bool has_defines_node() const { + return _root != nullptr; + } + + constexpr NodeTools::NodeCallback auto expect_script() { + return NodeTools::assign_variable_callback(_root); + } + + bool parse_script(bool can_be_null, _Context... context) { + if (_root == nullptr) { + if (!can_be_null) { + Logger::error("Null/missing script node!"); + } + return can_be_null; + } + const bool ret = _parse_script(_root, context...); + _root = nullptr; + return ret; + } + }; +} |