aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation
diff options
context:
space:
mode:
author zaaarf <80046572+zaaarf@users.noreply.github.com>2023-12-27 00:12:17 +0100
committer GitHub <noreply@github.com>2023-12-27 00:12:17 +0100
commitcc808c115d8ec6c7b6e47db47f81395b4d52941f (patch)
tree1ac5bbac53d493682de60d1285c80b9be0ea40c0 /src/openvic-simulation
parentbff91f78f9c5339079c10adfbf8232e5159c1a2d (diff)
parentdfa42bc38ebc34904b2325a88cdd16514044cfcb (diff)
Merge pull request #106 from OpenVicProject/rules
Added political/policy rules
Diffstat (limited to 'src/openvic-simulation')
-rw-r--r--src/openvic-simulation/dataloader/Dataloader.cpp4
-rw-r--r--src/openvic-simulation/politics/PoliticsManager.hpp6
-rw-r--r--src/openvic-simulation/politics/Rule.cpp138
-rw-r--r--src/openvic-simulation/politics/Rule.hpp57
4 files changed, 204 insertions, 1 deletions
diff --git a/src/openvic-simulation/dataloader/Dataloader.cpp b/src/openvic-simulation/dataloader/Dataloader.cpp
index 71cef82..fc4e64c 100644
--- a/src/openvic-simulation/dataloader/Dataloader.cpp
+++ b/src/openvic-simulation/dataloader/Dataloader.cpp
@@ -737,6 +737,10 @@ bool Dataloader::load_defines(GameManager& game_manager) const {
Logger::error("Failed to set up modifier effects!");
ret = false;
}
+ if (!game_manager.get_politics_manager().get_rule_manager().setup_rules()) {
+ Logger::error("Failed to set up rules!");
+ ret = false;
+ }
if (!game_manager.get_define_manager().load_defines_file(parse_lua_defines(lookup_file(defines_file)).get_file_node())) {
Logger::error("Failed to load defines!");
ret = false;
diff --git a/src/openvic-simulation/politics/PoliticsManager.hpp b/src/openvic-simulation/politics/PoliticsManager.hpp
index 1111f0a..d2ed380 100644
--- a/src/openvic-simulation/politics/PoliticsManager.hpp
+++ b/src/openvic-simulation/politics/PoliticsManager.hpp
@@ -6,12 +6,14 @@
#include "openvic-simulation/politics/NationalFocus.hpp"
#include "openvic-simulation/politics/NationalValue.hpp"
#include "openvic-simulation/politics/Rebel.hpp"
+#include "openvic-simulation/politics/Rule.hpp"
namespace OpenVic {
struct PoliticsManager {
private:
GovernmentTypeManager PROPERTY_REF(government_type_manager);
IdeologyManager PROPERTY_REF(ideology_manager);
+ RuleManager PROPERTY_REF(rule_manager);
IssueManager PROPERTY_REF(issue_manager);
NationalValueManager PROPERTY_REF(national_value_manager);
NationalFocusManager PROPERTY_REF(national_focus_manager);
@@ -25,7 +27,9 @@ namespace OpenVic {
PopManager const& pop_manager, GoodManager const& good_manager, ModifierManager const& modifier_manager,
ast::NodeCPtr root
) {
- return national_focus_manager.load_national_foci_file(pop_manager, ideology_manager, good_manager, modifier_manager, root);
+ return national_focus_manager.load_national_foci_file(
+ pop_manager, ideology_manager, good_manager, modifier_manager, root
+ );
}
inline bool load_rebels_file(ast::NodeCPtr root) {
return rebel_manager.load_rebels_file(ideology_manager, government_type_manager, root);
diff --git a/src/openvic-simulation/politics/Rule.cpp b/src/openvic-simulation/politics/Rule.cpp
new file mode 100644
index 0000000..12db4f4
--- /dev/null
+++ b/src/openvic-simulation/politics/Rule.cpp
@@ -0,0 +1,138 @@
+#include "Rule.hpp"
+
+using namespace OpenVic;
+using namespace OpenVic::NodeTools;
+
+Rule::Rule(std::string_view new_identifier) : HasIdentifier { new_identifier } {}
+
+RuleSet::RuleSet(rule_map_t&& new_rules) : rules { std::move(new_rules) } {}
+
+size_t RuleSet::get_rule_count() const {
+ return rules.size();
+}
+
+bool RuleSet::get_rule(Rule const* rule, bool* successful) {
+ const rule_map_t::const_iterator it = rules.find(rule);
+ if (it != rules.end()) {
+ if (successful != nullptr) {
+ *successful = true;
+ }
+ return it->second;
+ }
+ if (successful != nullptr) {
+ *successful = false;
+ }
+ return false;
+}
+
+bool RuleSet::has_rule(Rule const* rule) const {
+ return rules.contains(rule);
+}
+
+RuleSet& RuleSet::operator|=(RuleSet const& right) {
+ for (rule_map_t::value_type const& value : right.rules) {
+ rules[value.first] |= value.second;
+ }
+ return *this;
+}
+
+RuleSet RuleSet::operator|(RuleSet const& right) const {
+ RuleSet ret = *this;
+ return ret |= right;
+}
+
+bool RuleManager::add_rule(std::string_view identifier) {
+ if (identifier.empty()) {
+ Logger::error("Invalid rule identifier - empty!");
+ return false;
+ }
+ return rules.add_item({ identifier });
+}
+
+bool RuleManager::setup_rules() {
+ bool ret = true;
+
+ /* Economic Rules */
+ ret &= add_rule("build_factory");
+ ret &= add_rule("expand_factory");
+ ret &= add_rule("open_factory");
+ ret &= add_rule("destroy_factory");
+
+ ret &= add_rule("pop_build_factory");
+ ret &= add_rule("pop_expand_factory");
+ ret &= add_rule("pop_open_factory");
+
+ ret &= add_rule("build_railway");
+ ret &= add_rule("can_subsidise");
+ ret &= add_rule("factory_priority");
+ ret &= add_rule("delete_factory_if_no_input");
+
+ ret &= add_rule("build_factory_invest");
+ ret &= add_rule("expand_factory_invest");
+ ret &= add_rule("open_factory_invest");
+ ret &= add_rule("build_railway_invest");
+
+ ret &= add_rule("pop_build_factory_invest");
+ ret &= add_rule("pop_expand_factory_invest");
+
+ ret &= add_rule("can_invest_in_pop_projects");
+ ret &= add_rule("allow_foreign_investment");
+
+ /* Citizenship Rules */
+ ret &= add_rule("primary_culture_voting");
+ ret &= add_rule("culture_voting");
+ ret &= add_rule("all_voting");
+
+ /* Slavery Rule */
+ ret &= add_rule("slavery_allowed");
+
+ /* Upper House Composition Rules */
+ ret &= add_rule("same_as_ruling_party");
+ ret &= add_rule("rich_only");
+ ret &= add_rule("state_vote");
+ ret &= add_rule("population_vote");
+
+ /* Voting System Rules */
+ ret &= add_rule("largest_share"); // First Past the Post
+ ret &= add_rule("dhont"); // Jefferson Method
+ ret &= add_rule("sainte_laque"); // Proportional Representation
+
+ lock_rules();
+
+ return ret;
+}
+
+node_callback_t RuleManager::expect_rule_set(callback_t<RuleSet&&> ruleset_callback) const {
+ return [this, ruleset_callback](ast::NodeCPtr root) -> bool {
+ RuleSet ruleset;
+ bool ret = expect_dictionary(
+ [this, &ruleset](std::string_view rule_key, ast::NodeCPtr rule_value) -> bool {
+ Rule const* rule = get_rule_by_identifier(rule_key);
+ if (rule != nullptr) {
+ return expect_bool(
+ [&ruleset, rule](bool value) -> bool {
+ if (!ruleset.rules.emplace(rule, value).second) {
+ Logger::warning("Duplicate rule entry: ", rule, " - overwriting existing value!");
+ }
+ return true;
+ }
+ )(rule_value);
+ } else {
+ Logger::error("Invalid rule identifier: ", rule_key);
+ return false;
+ }
+ }
+ )(root);
+ ret &= ruleset_callback(std::move(ruleset));
+ return ret;
+ };
+}
+
+namespace OpenVic { // so the compiler shuts up (copied from Modifier.cpp)
+ std::ostream& operator<<(std::ostream& stream, RuleSet const& value) {
+ for (RuleSet::rule_map_t::value_type const& rule : value.rules) {
+ stream << rule.first << ": " << (rule.second ? "yes" : "no") << "\n";
+ }
+ return stream;
+ }
+}
diff --git a/src/openvic-simulation/politics/Rule.hpp b/src/openvic-simulation/politics/Rule.hpp
new file mode 100644
index 0000000..260fb9e
--- /dev/null
+++ b/src/openvic-simulation/politics/Rule.hpp
@@ -0,0 +1,57 @@
+#pragma once
+
+#include "openvic-simulation/types/IdentifierRegistry.hpp"
+
+namespace OpenVic {
+ struct RuleManager;
+
+ struct Rule : HasIdentifier {
+ friend struct RuleManager;
+
+ private:
+ Rule(std::string_view new_identifier);
+
+ public:
+ Rule(Rule&&) = default;
+ };
+
+ struct RuleSet {
+ friend struct RuleManager;
+
+ using rule_map_t = std::map<Rule const*, bool>;
+
+ private:
+ rule_map_t rules;
+
+ public:
+ RuleSet() = default;
+ RuleSet(rule_map_t&& new_rules);
+ RuleSet(RuleSet const&) = default;
+ RuleSet(RuleSet&&) = default;
+
+ RuleSet& operator=(RuleSet const&) = default;
+ RuleSet& operator=(RuleSet&&) = default;
+
+ size_t get_rule_count() const;
+
+ bool get_rule(Rule const* rule, bool* successful = nullptr);
+ bool has_rule(Rule const* rule) const;
+
+ RuleSet& operator|=(RuleSet const& right);
+ RuleSet operator|(RuleSet const& right) const;
+
+ friend std::ostream& operator<<(std::ostream& stream, RuleSet const& value);
+ };
+
+ struct RuleManager {
+ private:
+ IdentifierRegistry<Rule> IDENTIFIER_REGISTRY(rule);
+
+ public:
+ bool add_rule(std::string_view identifier);
+
+ bool setup_rules();
+
+ NodeTools::node_callback_t expect_rule_set(NodeTools::callback_t<RuleSet&&> ruleset_callback) const;
+ };
+}