aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
author hop311 <hop3114@gmail.com>2024-01-03 01:13:39 +0100
committer hop311 <hop3114@gmail.com>2024-01-03 01:13:39 +0100
commite067471f55cd11c6cd86920f9486991d6b552726 (patch)
treefa0904084e5e6a842e0ca9060155ed7ad30dc9a8 /src
parentd893c0ad8c6a0c347dcec72762be49f20886a90a (diff)
Mutually exclusive rule groups + modded building rules
Diffstat (limited to 'src')
-rw-r--r--src/openvic-simulation/dataloader/Dataloader.cpp36
-rw-r--r--src/openvic-simulation/economy/BuildingType.cpp2
-rw-r--r--src/openvic-simulation/economy/BuildingType.hpp1
-rw-r--r--src/openvic-simulation/economy/Good.cpp23
-rw-r--r--src/openvic-simulation/map/Map.cpp2
-rw-r--r--src/openvic-simulation/misc/Modifier.cpp8
-rw-r--r--src/openvic-simulation/politics/Issue.cpp20
-rw-r--r--src/openvic-simulation/politics/Rule.cpp201
-rw-r--r--src/openvic-simulation/politics/Rule.hpp43
9 files changed, 237 insertions, 99 deletions
diff --git a/src/openvic-simulation/dataloader/Dataloader.cpp b/src/openvic-simulation/dataloader/Dataloader.cpp
index a09b999..26f3c4c 100644
--- a/src/openvic-simulation/dataloader/Dataloader.cpp
+++ b/src/openvic-simulation/dataloader/Dataloader.cpp
@@ -780,10 +780,6 @@ bool Dataloader::load_defines(GameManager& game_manager) {
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;
@@ -830,19 +826,6 @@ bool Dataloader::load_defines(GameManager& game_manager) {
Logger::error("Failed to load pop types!");
ret = false;
}
- if (!game_manager.get_politics_manager().load_issues_file(
- game_manager.get_modifier_manager(),
- parse_defines_cached(lookup_file(issues_file)).get_file_node()
- )) {
- Logger::error("Failed to load issues and reforms!");
- ret = false;
- }
- if (!game_manager.get_pop_manager().load_delayed_parse_pop_type_data(
- game_manager.get_politics_manager().get_issue_manager()
- )) {
- Logger::error("Failed to load delayed parse pop type data (promotion and issue weights)!");
- ret = false;
- }
if (!game_manager.get_economy_manager().load_production_types_file(game_manager.get_pop_manager(),
parse_defines_cached(lookup_file(production_types_file)).get_file_node()
)) {
@@ -862,6 +845,25 @@ bool Dataloader::load_defines(GameManager& game_manager) {
if (!_load_technologies(game_manager)) {
ret = false;
}
+ if (!game_manager.get_politics_manager().get_rule_manager().setup_rules(
+ game_manager.get_economy_manager().get_building_type_manager()
+ )) {
+ Logger::error("Failed to set up rules!");
+ ret = false;
+ }
+ if (!game_manager.get_politics_manager().load_issues_file(
+ game_manager.get_modifier_manager(),
+ parse_defines_cached(lookup_file(issues_file)).get_file_node()
+ )) {
+ Logger::error("Failed to load issues and reforms!");
+ ret = false;
+ }
+ if (!game_manager.get_pop_manager().load_delayed_parse_pop_type_data(
+ game_manager.get_politics_manager().get_issue_manager()
+ )) {
+ Logger::error("Failed to load delayed parse pop type data (promotion and issue weights)!");
+ ret = false;
+ }
if (!game_manager.get_politics_manager().load_national_foci_file(
game_manager.get_pop_manager(), game_manager.get_economy_manager().get_good_manager(),
game_manager.get_modifier_manager(), parse_defines_cached(lookup_file(national_foci_file)).get_file_node()
diff --git a/src/openvic-simulation/economy/BuildingType.cpp b/src/openvic-simulation/economy/BuildingType.cpp
index c11933f..c9ed410 100644
--- a/src/openvic-simulation/economy/BuildingType.cpp
+++ b/src/openvic-simulation/economy/BuildingType.cpp
@@ -22,6 +22,8 @@ bool BuildingTypeManager::add_building_type(std::string_view identifier, ARGS) {
return false;
}
+ building_type_types.emplace(type);
+
return building_types.add_item({
identifier, type, std::move(modifier), on_completion, completion_size, max_level, std::move(goods_cost),
cost, build_time, visibility, on_map, default_enabled, production_type, pop_build_factory, strategic_factory,
diff --git a/src/openvic-simulation/economy/BuildingType.hpp b/src/openvic-simulation/economy/BuildingType.hpp
index b1eb6f8..d751ff1 100644
--- a/src/openvic-simulation/economy/BuildingType.hpp
+++ b/src/openvic-simulation/economy/BuildingType.hpp
@@ -74,6 +74,7 @@ namespace OpenVic {
private:
IdentifierRegistry<BuildingType> IDENTIFIER_REGISTRY(building_type);
+ string_set_t PROPERTY(building_type_types);
std::vector<BuildingType const*> PROPERTY(province_building_types);
BuildingType const* PROPERTY(port_building_type);
diff --git a/src/openvic-simulation/economy/Good.cpp b/src/openvic-simulation/economy/Good.cpp
index 3b420f1..2170666 100644
--- a/src/openvic-simulation/economy/Good.cpp
+++ b/src/openvic-simulation/economy/Good.cpp
@@ -93,25 +93,24 @@ bool GoodManager::load_goods_file(ast::NodeCPtr root) {
bool GoodManager::generate_modifiers(ModifierManager& modifier_manager) const {
bool ret = true;
- const auto good_modifier = [this, &modifier_manager, &ret](std::string_view name) -> void {
+ const auto good_modifier = [this, &modifier_manager, &ret](std::string_view name, bool positive_good) -> void {
ret &= modifier_manager.register_complex_modifier(name);
for (Good const& good : get_goods()) {
ret &= modifier_manager.add_modifier_effect(
- StringUtils::append_string_views(name, "_", good.get_identifier()), true
+ StringUtils::append_string_views(name, "_", good.get_identifier()), positive_good
);
}
};
- good_modifier("artisan_goods_input");
- good_modifier("artisan_goods_output");
- good_modifier("artisan_goods_throughput");
- good_modifier("factory_goods_input");
- good_modifier("factory_goods_output");
- good_modifier("factory_goods_throughput");
- good_modifier("rgo_goods_input");
- good_modifier("rgo_goods_output");
- good_modifier("rgo_goods_throughput");
- good_modifier("rgo_size");
+ good_modifier("artisan_goods_input", false);
+ good_modifier("artisan_goods_output", true);
+ good_modifier("artisan_goods_throughput", true);
+ good_modifier("factory_goods_input", false);
+ good_modifier("factory_goods_output", true);
+ good_modifier("factory_goods_throughput", true);
+ good_modifier("rgo_goods_output", true);
+ good_modifier("rgo_goods_throughput", true);
+ good_modifier("rgo_size", true);
return ret;
}
diff --git a/src/openvic-simulation/map/Map.cpp b/src/openvic-simulation/map/Map.cpp
index 95f4991..a8cc4a0 100644
--- a/src/openvic-simulation/map/Map.cpp
+++ b/src/openvic-simulation/map/Map.cpp
@@ -845,7 +845,7 @@ bool Map::load_climate_file(ModifierManager const& modifier_manager, ast::NodeCP
} else {
Logger::warning(
"Province with id ", province.get_identifier(),
- "defined twice in climate ", identifier
+ " defined twice in climate ", identifier
);
}
return true;
diff --git a/src/openvic-simulation/misc/Modifier.cpp b/src/openvic-simulation/misc/Modifier.cpp
index bbc8f59..ca4c950 100644
--- a/src/openvic-simulation/misc/Modifier.cpp
+++ b/src/openvic-simulation/misc/Modifier.cpp
@@ -111,6 +111,9 @@ bool ModifierManager::setup_modifier_effects() {
/* Country Modifier Effects */
ret &= add_modifier_effect("administrative_efficiency", true);
ret &= add_modifier_effect("administrative_efficiency_modifier", true);
+ ret &= add_modifier_effect("artisan_input", false);
+ ret &= add_modifier_effect("artisan_output", true);
+ ret &= add_modifier_effect("artisan_throughput", true);
ret &= add_modifier_effect("badboy", false, RAW_DECIMAL);
ret &= add_modifier_effect("cb_creation_speed", true); //seemingly works the same way as cb_generation_speed_modifier
ret &= add_modifier_effect("cb_generation_speed_modifier", true);
@@ -127,6 +130,7 @@ bool ModifierManager::setup_modifier_effects() {
ret &= add_modifier_effect("education_efficiency_modifier", true);
ret &= add_modifier_effect("factory_cost", false);
ret &= add_modifier_effect("factory_input", false);
+ ret &= add_modifier_effect("factory_maintenance", false);
ret &= add_modifier_effect("factory_output", true);
ret &= add_modifier_effect("factory_owner_cost", false);
ret &= add_modifier_effect("factory_throughput", true);
@@ -226,10 +230,10 @@ bool ModifierManager::setup_modifier_effects() {
ret &= add_modifier_effect("immigrant_attract", true);
ret &= add_modifier_effect("immigrant_push", false);
ret &= add_modifier_effect("life_rating", true);
- ret &= add_modifier_effect("local_artisan_input", true);
+ ret &= add_modifier_effect("local_artisan_input", false);
ret &= add_modifier_effect("local_artisan_output", true);
ret &= add_modifier_effect("local_artisan_throughput", true);
- ret &= add_modifier_effect("local_factory_input", true);
+ ret &= add_modifier_effect("local_factory_input", false);
ret &= add_modifier_effect("local_factory_output", true);
ret &= add_modifier_effect("local_factory_throughput", true);
ret &= add_modifier_effect("local_repair", true);
diff --git a/src/openvic-simulation/politics/Issue.cpp b/src/openvic-simulation/politics/Issue.cpp
index 3e64af4..28e34cb 100644
--- a/src/openvic-simulation/politics/Issue.cpp
+++ b/src/openvic-simulation/politics/Issue.cpp
@@ -95,8 +95,19 @@ bool IssueManager::add_reform(
}
if (group->get_type().is_uncivilised()) {
- if (technology_cost <= 0) {
- Logger::warning("Non-positive technology cost ", technology_cost, " found in uncivilised reform ", identifier, "!");
+ if (ordinal == 0) {
+ if (technology_cost != 0) {
+ Logger::warning(
+ "Non-zero technology cost ", technology_cost, " found in ordinal 0 uncivilised reform ", identifier, "!"
+ );
+ }
+ } else {
+ if (technology_cost <= 0) {
+ Logger::warning(
+ "Non-positive technology cost ", technology_cost, " found in ordinal ", ordinal,
+ " uncivilised reform ", identifier, "!"
+ );
+ }
}
} else if (technology_cost != 0) {
Logger::warning("Non-zero technology cost ", technology_cost, " found in civilised reform ", identifier, "!");
@@ -184,8 +195,11 @@ bool IssueManager::load_issues_file(ModifierManager const& modifier_manager, Rul
if (key == "party_issues") {
return expect_length(add_variable_callback(expected_issue_groups))(value);
} else {
+ static const string_set_t uncivilised_reform_groups {
+ "economic_reforms", "education_reforms", "military_reforms"
+ };
return expect_length(add_variable_callback(expected_reform_groups))(value)
- & add_reform_type(key, key == "economic_reforms" || key == "education_reforms" || key == "military_reforms");
+ & add_reform_type(key, uncivilised_reform_groups.contains(key));
}
}
)(root);
diff --git a/src/openvic-simulation/politics/Rule.cpp b/src/openvic-simulation/politics/Rule.cpp
index 12db4f4..9ac992a 100644
--- a/src/openvic-simulation/politics/Rule.cpp
+++ b/src/openvic-simulation/politics/Rule.cpp
@@ -1,19 +1,90 @@
#include "Rule.hpp"
+#include "openvic-simulation/economy/BuildingType.hpp"
+#include "openvic-simulation/utility/TslHelper.hpp"
+
using namespace OpenVic;
using namespace OpenVic::NodeTools;
-Rule::Rule(std::string_view new_identifier) : HasIdentifier { new_identifier } {}
+Rule::Rule(std::string_view new_identifier, rule_group_t new_group, size_t new_index)
+ : HasIdentifier { new_identifier }, group { new_group }, index { new_index } {}
-RuleSet::RuleSet(rule_map_t&& new_rules) : rules { std::move(new_rules) } {}
+RuleSet::RuleSet(rule_group_map_t&& new_rule_groups) : rule_groups { std::move(new_rule_groups) } {}
+
+bool RuleSet::trim_and_resolve_conflicts(bool log) {
+ bool ret = true;
+ for (auto [group, rule_map] : mutable_iterator(rule_groups)) {
+ if (Rule::is_mutually_exclusive_group(group)) {
+ Rule const* primary_rule = nullptr;
+ for (auto const& [rule, value] : rule_map) {
+ if (value) {
+ if (primary_rule == nullptr) {
+ primary_rule = rule;
+ } else {
+ if (primary_rule->get_index() < rule->get_index()) {
+ primary_rule = rule;
+ }
+ ret = false;
+ }
+ }
+ }
+ if (log) {
+ for (auto const& [rule, value] : rule_map) {
+ if (value) {
+ if (rule != primary_rule) {
+ Logger::error(
+ "Conflicting mutually exclusive rule: ", rule, " superceeded by ", primary_rule, " - removing!"
+ );
+ }
+ } else {
+ Logger::warning("Disabled mutually exclusive rule: ", rule, " - removing!");
+ }
+ }
+ }
+ rule_map.clear();
+ if (primary_rule != nullptr) {
+ rule_map.emplace(primary_rule, true);
+ }
+ }
+ }
+ return ret;
+}
+
+size_t RuleSet::get_rule_group_count() const {
+ return rule_groups.size();
+}
size_t RuleSet::get_rule_count() const {
- return rules.size();
+ size_t ret = 0;
+ for (auto const& [group, rule_map] : rule_groups) {
+ ret += rule_map.size();
+ }
+ return ret;
+}
+
+RuleSet::rule_map_t const& RuleSet::get_rule_group(Rule::rule_group_t group, bool* successful) const {
+ const rule_group_map_t::const_iterator it = rule_groups.find(group);
+ if (it != rule_groups.end()) {
+ if (successful != nullptr) {
+ *successful = true;
+ }
+ return it->second;
+ }
+ if (successful != nullptr) {
+ *successful = false;
+ }
+ static const rule_map_t empty_map {};
+ return empty_map;
}
-bool RuleSet::get_rule(Rule const* rule, bool* successful) {
- const rule_map_t::const_iterator it = rules.find(rule);
- if (it != rules.end()) {
+bool RuleSet::get_rule(Rule const* rule, bool* successful) const {
+ if (rule == nullptr) {
+ Logger::error("Invalid rule - null!");
+ return false;
+ }
+ rule_map_t const& rule_map = get_rule_group(rule->get_group());
+ const rule_map_t::const_iterator it = rule_map.find(rule);
+ if (it != rule_map.end()) {
if (successful != nullptr) {
*successful = true;
}
@@ -22,16 +93,31 @@ bool RuleSet::get_rule(Rule const* rule, bool* successful) {
if (successful != nullptr) {
*successful = false;
}
- return false;
+ return Rule::is_default_enabled(rule->get_group());
}
bool RuleSet::has_rule(Rule const* rule) const {
- return rules.contains(rule);
+ if (rule == nullptr) {
+ Logger::error("Invalid rule - null!");
+ return false;
+ }
+ return get_rule_group(rule->get_group()).contains(rule);
+}
+
+bool RuleSet::set_rule(Rule const* rule, bool value) {
+ if (rule == nullptr) {
+ Logger::error("Invalid rule - null!");
+ return false;
+ }
+ rule_map_t& rule_map = rule_groups[rule->get_group()];
+ return rule_groups[rule->get_group()].emplace(rule, value).second;
}
RuleSet& RuleSet::operator|=(RuleSet const& right) {
- for (rule_map_t::value_type const& value : right.rules) {
- rules[value.first] |= value.second;
+ for (auto const& [group, rule_map] : right.rule_groups) {
+ for (auto const& [rule, value] : rule_map) {
+ rule_groups[group][rule] |= value;
+ }
}
return *this;
}
@@ -41,61 +127,57 @@ RuleSet RuleSet::operator|(RuleSet const& right) const {
return ret |= right;
}
-bool RuleManager::add_rule(std::string_view identifier) {
+bool RuleManager::add_rule(std::string_view identifier, Rule::rule_group_t group) {
if (identifier.empty()) {
Logger::error("Invalid rule identifier - empty!");
return false;
}
- return rules.add_item({ identifier });
+ return rules.add_item({ identifier, group, rule_group_sizes[group]++ });
}
-bool RuleManager::setup_rules() {
+bool RuleManager::setup_rules(BuildingTypeManager const& building_type_manager) {
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");
+ using enum Rule::rule_group_t;
+
+ static const ordered_map<Rule::rule_group_t, std::vector<std::string_view>> hardcoded_rules {
+ { ECONOMY, {
+ "expand_factory", "open_factory", "destroy_factory", "pop_build_factory", "pop_expand_factory", "pop_open_factory",
+ "can_subsidise", "factory_priority", "delete_factory_if_no_input", "build_factory_invest", "expand_factory_invest",
+ "open_factory_invest", "build_railway_invest", "pop_build_factory_invest", "pop_expand_factory_invest",
+ "can_invest_in_pop_projects", "allow_foreign_investment"
+ } },
+ { CITIZENSHIP, { "primary_culture_voting", "culture_voting", "all_voting" } },
+ { SLAVERY, { "slavery_allowed" } },
+ { UPPER_HOUSE, { "same_as_ruling_party", "rich_only", "state_vote", "population_vote" } },
+ { VOTING, {
+ "largest_share" /* First Past the Post */,
+ "dhont" /* Jefferson Method */,
+ "sainte_laque" /* Proportional Representation */
+ } }
+ };
- /* Slavery Rule */
- ret &= add_rule("slavery_allowed");
+ size_t rule_count = building_type_manager.get_building_type_types().size();
+ for (auto const& [group, rule_list] : hardcoded_rules) {
+ rule_count += rule_list.size();
+ }
+ rules.reserve(rule_count);
- /* 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");
+ for (auto const& [group, rule_list] : hardcoded_rules) {
+ for (std::string_view const& rule : rule_list) {
+ ret &= add_rule(rule, group);
+ }
+ }
- /* 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
+ for (std::string const& type : building_type_manager.get_building_type_types()) {
+ std::string build_rule_string = "build_";
+ if (type != "infrastructure") {
+ build_rule_string += type;
+ } else {
+ build_rule_string += "railway";
+ }
+ ret &= add_rule(build_rule_string, ECONOMY);
+ }
lock_rules();
@@ -111,8 +193,8 @@ node_callback_t RuleManager::expect_rule_set(callback_t<RuleSet&&> ruleset_callb
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!");
+ if (!ruleset.rule_groups[rule->get_group()].emplace(rule, value).second) {
+ Logger::warning("Duplicate rule entry: ", rule, " - ignoring!");
}
return true;
}
@@ -123,6 +205,7 @@ node_callback_t RuleManager::expect_rule_set(callback_t<RuleSet&&> ruleset_callb
}
}
)(root);
+ ret &= ruleset.trim_and_resolve_conflicts(true);
ret &= ruleset_callback(std::move(ruleset));
return ret;
};
@@ -130,8 +213,10 @@ node_callback_t RuleManager::expect_rule_set(callback_t<RuleSet&&> ruleset_callb
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";
+ for (auto const& [group, rule_map] : value.rule_groups) {
+ for (auto const& [rule, value] : rule_map) {
+ stream << rule << ": " << (value ? "yes" : "no") << "\n";
+ }
}
return stream;
}
diff --git a/src/openvic-simulation/politics/Rule.hpp b/src/openvic-simulation/politics/Rule.hpp
index 4b47abf..70a59e8 100644
--- a/src/openvic-simulation/politics/Rule.hpp
+++ b/src/openvic-simulation/politics/Rule.hpp
@@ -5,12 +5,32 @@
namespace OpenVic {
struct RuleManager;
+ struct BuildingTypeManager;
struct Rule : HasIdentifier {
friend struct RuleManager;
+ enum class rule_group_t : uint8_t {
+ ECONOMY, CITIZENSHIP, SLAVERY, UPPER_HOUSE, VOTING
+ };
+
+ static constexpr bool is_mutually_exclusive_group(rule_group_t group) {
+ using enum rule_group_t;
+ return group == CITIZENSHIP || group == UPPER_HOUSE || group == VOTING;
+ }
+
+ /* Mutually exclusive groups must be default disabled! */
+ static constexpr bool is_default_enabled(rule_group_t group) {
+ using enum rule_group_t;
+ return !is_mutually_exclusive_group(group) && group != SLAVERY;
+ }
+
private:
- Rule(std::string_view new_identifier);
+ const rule_group_t PROPERTY(group);
+ /* The index of the Rule within its group, used to determine precedence in mutually exclusive rule groups. */
+ const size_t PROPERTY(index);
+
+ Rule(std::string_view new_identifier, rule_group_t new_group, size_t new_index);
public:
Rule(Rule&&) = default;
@@ -20,24 +40,34 @@ namespace OpenVic {
friend struct RuleManager;
using rule_map_t = ordered_map<Rule const*, bool>;
+ using rule_group_map_t = ordered_map<Rule::rule_group_t, rule_map_t>;
private:
- rule_map_t rules;
+ rule_group_map_t rule_groups;
public:
RuleSet() = default;
- RuleSet(rule_map_t&& new_rules);
+ RuleSet(rule_group_map_t&& new_rule_groups);
RuleSet(RuleSet const&) = default;
RuleSet(RuleSet&&) = default;
RuleSet& operator=(RuleSet const&) = default;
RuleSet& operator=(RuleSet&&) = default;
+ /* Removes conflicting and disabled mutually exclusive rules. If log is true, a warning will be emitted for each
+ * removed disabled rule and an error will be emitted for each removed conflicting rule. Returns true if no conflicts
+ * are found (regardless of whether disabled rules are removed or not), false otherwise. */
+ bool trim_and_resolve_conflicts(bool log);
+ size_t get_rule_group_count() const;
size_t get_rule_count() const;
- bool get_rule(Rule const* rule, bool* successful = nullptr);
+ rule_map_t const& get_rule_group(Rule::rule_group_t group, bool* successful = nullptr) const;
+ bool get_rule(Rule const* rule, bool* successful = nullptr) const;
bool has_rule(Rule const* rule) const;
+ /* Sets the rule to the specified value. Returns false if there was an existing rule, regardless of its value. */
+ bool set_rule(Rule const* rule, bool value);
+
RuleSet& operator|=(RuleSet const& right);
RuleSet operator|(RuleSet const& right) const;
@@ -47,11 +77,12 @@ namespace OpenVic {
struct RuleManager {
private:
IdentifierRegistry<Rule> IDENTIFIER_REGISTRY(rule);
+ ordered_map<Rule::rule_group_t, size_t> rule_group_sizes;
public:
- bool add_rule(std::string_view identifier);
+ bool add_rule(std::string_view identifier, Rule::rule_group_t group);
- bool setup_rules();
+ bool setup_rules(BuildingTypeManager const& building_type_manager);
NodeTools::node_callback_t expect_rule_set(NodeTools::callback_t<RuleSet&&> ruleset_callback) const;
};