diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/openvic-simulation/dataloader/Dataloader.cpp | 4 | ||||
-rw-r--r-- | src/openvic-simulation/politics/PoliticsManager.hpp | 6 | ||||
-rw-r--r-- | src/openvic-simulation/politics/Rule.cpp | 138 | ||||
-rw-r--r-- | src/openvic-simulation/politics/Rule.hpp | 57 |
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; + }; +} |