aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/politics/Issue.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvic-simulation/politics/Issue.cpp')
-rw-r--r--src/openvic-simulation/politics/Issue.cpp133
1 files changed, 108 insertions, 25 deletions
diff --git a/src/openvic-simulation/politics/Issue.cpp b/src/openvic-simulation/politics/Issue.cpp
index d8fe52e..8e0907a 100644
--- a/src/openvic-simulation/politics/Issue.cpp
+++ b/src/openvic-simulation/politics/Issue.cpp
@@ -5,9 +5,11 @@ using namespace OpenVic::NodeTools;
IssueGroup::IssueGroup(std::string_view new_identifier) : HasIdentifier { new_identifier } {}
-Issue::Issue(std::string_view new_identifier, ModifierValue&& new_values, IssueGroup const& new_group, RuleSet&& new_rules, bool new_jingoism)
- : Modifier { new_identifier, std::move(new_values), 0 }, group { new_group }, rules { std::move(new_rules) },
- jingoism { new_jingoism } {}
+Issue::Issue(
+ std::string_view new_identifier, colour_t new_colour, ModifierValue&& new_values, IssueGroup const& new_group,
+ RuleSet&& new_rules, bool new_jingoism
+) : HasIdentifierAndColour { new_identifier, new_colour, false }, ModifierValue { std::move(new_values) },
+ group { new_group }, rules { std::move(new_rules) }, jingoism { new_jingoism } {}
ReformType::ReformType(std::string_view new_identifier, bool new_uncivilised)
: HasIdentifier { new_identifier }, uncivilised { new_uncivilised } {}
@@ -16,10 +18,10 @@ ReformGroup::ReformGroup(std::string_view new_identifier, ReformType const& new_
: IssueGroup { new_identifier }, type { new_type }, ordered { new_ordered }, administrative { new_administrative } {}
Reform::Reform(
- std::string_view new_identifier, ModifierValue&& new_values, ReformGroup const& new_group, size_t new_ordinal,
- RuleSet&& new_rules, tech_cost_t new_technology_cost, ConditionScript&& new_allow,
+ std::string_view new_identifier, colour_t new_colour, ModifierValue&& new_values, ReformGroup const& new_group,
+ size_t new_ordinal, RuleSet&& new_rules, tech_cost_t new_technology_cost, ConditionScript&& new_allow,
ConditionScript&& new_on_execute_trigger, EffectScript&& new_on_execute_effect
-) : Issue { new_identifier, std::move(new_values), new_group, std::move(new_rules), false }, ordinal { new_ordinal },
+) : Issue { new_identifier, new_colour, std::move(new_values), new_group, std::move(new_rules), false }, ordinal { new_ordinal },
reform_group { new_group }, technology_cost { new_technology_cost }, allow { std::move(new_allow) },
on_execute_trigger { std::move(new_on_execute_trigger) }, on_execute_effect { std::move(new_on_execute_effect) } {}
@@ -41,7 +43,8 @@ bool IssueManager::add_issue_group(std::string_view identifier) {
}
bool IssueManager::add_issue(
- std::string_view identifier, ModifierValue&& values, IssueGroup const* group, RuleSet&& rules, bool jingoism
+ std::string_view identifier, colour_t new_colour, ModifierValue&& values, IssueGroup const* group, RuleSet&& rules,
+ bool jingoism
) {
if (identifier.empty()) {
Logger::error("Invalid issue identifier - empty!");
@@ -53,7 +56,7 @@ bool IssueManager::add_issue(
return false;
}
- return issues.add_item({ identifier, std::move(values), *group, std::move(rules), jingoism });
+ return issues.add_item({ identifier, new_colour, std::move(values), *group, std::move(rules), jingoism });
}
bool IssueManager::add_reform_type(std::string_view identifier, bool uncivilised) {
@@ -80,8 +83,8 @@ bool IssueManager::add_reform_group(std::string_view identifier, ReformType cons
}
bool IssueManager::add_reform(
- std::string_view identifier, ModifierValue&& values, ReformGroup const* group, size_t ordinal, RuleSet&& rules,
- Reform::tech_cost_t technology_cost, ConditionScript&& allow, ConditionScript&& on_execute_trigger,
+ std::string_view identifier, colour_t new_colour, ModifierValue&& values, ReformGroup const* group, size_t ordinal,
+ RuleSet&& rules, Reform::tech_cost_t technology_cost, ConditionScript&& allow, ConditionScript&& on_execute_trigger,
EffectScript&& on_execute_effect
) {
if (identifier.empty()) {
@@ -114,7 +117,7 @@ bool IssueManager::add_reform(
}
return reforms.add_item({
- identifier, std::move(values), *group, ordinal, std::move(rules), technology_cost, std::move(allow),
+ identifier, new_colour, std::move(values), *group, ordinal, std::move(rules), technology_cost, std::move(allow),
std::move(on_execute_trigger), std::move(on_execute_effect)
});
}
@@ -124,6 +127,40 @@ bool IssueManager::_load_issue_group(size_t& expected_issues, std::string_view i
& add_issue_group(identifier);
}
+/* Each colour is made up of these components in some order:
+ * - 0
+ * - floor(max_value * 0.99) = 252
+ * - floor(max_value * i / 60) = floor(4.25 * i) for some i in [0, 60) */
+
+static constexpr colour_t::value_type dim_colour_component = 0;
+static constexpr colour_t::value_type bright_colour_component = static_cast<uint32_t>(colour_t::max_value) * 99 / 100;
+
+/* Prime factor to scatter [0, 60) */
+static constexpr size_t scattering_prime = 4057;
+static constexpr size_t varying_colour_denominator = 60;
+
+/* 3! = 3 (choices for 0) * 2 (choices for 252) * 1 (choices for 4.25 * i) */
+static constexpr size_t colour_pattern_period = 6;
+
+static constexpr std::array<size_t, colour_pattern_period> dim_colour_indices { 0, 1, 2, 0, 1, 2 };
+static constexpr std::array<size_t, colour_pattern_period> bright_colour_indices { 1, 2, 0, 2, 0, 1 };
+static constexpr std::array<size_t, colour_pattern_period> varying_colour_indices { 2, 0, 1, 1, 2, 0 };
+
+static constexpr colour_t create_issue_reform_colour(size_t index) {
+ colour_t ret {};
+
+ const size_t periodic_index = index % colour_pattern_period;
+
+ ret[dim_colour_indices[periodic_index]] = dim_colour_component;
+
+ ret[bright_colour_indices[periodic_index]] = bright_colour_component;
+
+ ret[varying_colour_indices[periodic_index]] = static_cast<size_t>(colour_t::max_value)
+ * ((index * scattering_prime) % varying_colour_denominator) / varying_colour_denominator;
+
+ return ret;
+}
+
bool IssueManager::_load_issue(
ModifierManager const& modifier_manager, RuleManager const& rule_manager, std::string_view identifier,
IssueGroup const* group, ast::NodeCPtr node
@@ -135,7 +172,10 @@ bool IssueManager::_load_issue(
"is_jingoism", ZERO_OR_ONE, expect_bool(assign_variable_callback(jingoism)),
"rules", ZERO_OR_ONE, rule_manager.expect_rule_set(move_variable_callback(rules))
)(node);
- ret &= add_issue(identifier, std::move(values), group, std::move(rules), jingoism);
+ ret &= add_issue(
+ identifier, create_issue_reform_colour(get_issue_count() + get_reform_count()), std::move(values), group,
+ std::move(rules), jingoism
+ );
return ret;
}
@@ -173,8 +213,8 @@ bool IssueManager::_load_reform(
)
)(node);
ret &= add_reform(
- identifier, std::move(values), group, ordinal, std::move(rules), technology_cost, std::move(allow),
- std::move(on_execute_trigger), std::move(on_execute_effect)
+ identifier, create_issue_reform_colour(get_issue_count() + get_reform_count()), std::move(values), group, ordinal,
+ std::move(rules), technology_cost, std::move(allow), std::move(on_execute_trigger), std::move(on_execute_effect)
);
return ret;
}
@@ -188,18 +228,33 @@ bool IssueManager::_load_reform(
* POL-99, POL-101, POL-102, POL-103, POL-104, POL-105, POL-107, POL-108, POL-109, POL-110, POL-111, POL-113,
* POL-113, POL-114, POL-115, POL-116
*/
-bool IssueManager::load_issues_file(ModifierManager const& modifier_manager, RuleManager const& rule_manager, ast::NodeCPtr root) {
+bool IssueManager::load_issues_file(
+ ModifierManager const& modifier_manager, RuleManager const& rule_manager, ast::NodeCPtr root
+) {
+ bool party_issues_found = false;
size_t expected_issue_groups = 0;
size_t expected_reform_groups = 0;
+
+ /* Reserve space for issue and reform groups and reserve space for and load reform types. */
bool ret = expect_dictionary_reserve_length(
reform_types,
- [this, &expected_issue_groups, &expected_reform_groups](std::string_view key, ast::NodeCPtr value) -> bool {
+ [this, &party_issues_found, &expected_issue_groups, &expected_reform_groups](
+ std::string_view key, ast::NodeCPtr value
+ ) -> bool {
if (key == "party_issues") {
+ if (party_issues_found) {
+ /* Error emitted here allowing later passes to return true with no error message. */
+ Logger::error("Duplicate party issues found!");
+ return false;
+ }
+ party_issues_found = true;
+
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, uncivilised_reform_groups.contains(key));
}
@@ -210,16 +265,27 @@ bool IssueManager::load_issues_file(ModifierManager const& modifier_manager, Rul
reserve_more_issue_groups(expected_issue_groups);
reserve_more_reform_groups(expected_reform_groups);
+ party_issues_found = false;
size_t expected_issues = 0;
size_t expected_reforms = 0;
+
+ /* Load issue and reform groups. */
ret &= expect_dictionary(
- [this, &expected_issues, &expected_reforms](std::string_view type_key, ast::NodeCPtr type_value) -> bool {
+ [this, &party_issues_found, &expected_issues, &expected_reforms](
+ std::string_view type_key, ast::NodeCPtr type_value
+ ) -> bool {
if (type_key == "party_issues") {
+ if (party_issues_found) {
+ return true; /* Error will have been emitted in first pass. */
+ }
+ party_issues_found = true;
+
return expect_dictionary([this, &expected_issues](std::string_view key, ast::NodeCPtr value) -> bool {
return _load_issue_group(expected_issues, key, value);
})(type_value);
} else {
ReformType const* reform_type = get_reform_type_by_identifier(type_key);
+
return expect_dictionary(
[this, reform_type, &expected_reforms](std::string_view key, ast::NodeCPtr value) -> bool {
return _load_reform_group(expected_reforms, key, reform_type, value);
@@ -234,31 +300,48 @@ bool IssueManager::load_issues_file(ModifierManager const& modifier_manager, Rul
reserve_more_issues(expected_issues);
reserve_more_reforms(expected_reforms);
+ party_issues_found = false;
+
+ /* Load issues and reforms. */
ret &= expect_dictionary(
- [this, &modifier_manager, &rule_manager](std::string_view type_key, ast::NodeCPtr type_value) -> bool {
- return expect_dictionary([this, &modifier_manager, &rule_manager, type_key](
- std::string_view group_key, ast::NodeCPtr group_value
- ) -> bool {
- if (type_key == "party_issues") {
+ [this, &party_issues_found, &modifier_manager, &rule_manager](
+ std::string_view type_key, ast::NodeCPtr type_value
+ ) -> bool {
+ if (type_key == "party_issues") {
+ if (party_issues_found) {
+ return true;
+ }
+ party_issues_found = true;
+
+ return expect_dictionary([this, &modifier_manager, &rule_manager](
+ std::string_view group_key, ast::NodeCPtr group_value
+ ) -> bool {
IssueGroup const* issue_group = get_issue_group_by_identifier(group_key);
+
return expect_dictionary([this, &modifier_manager, &rule_manager, issue_group](
std::string_view key, ast::NodeCPtr value
) -> bool {
return _load_issue(modifier_manager, rule_manager, key, issue_group, value);
})(group_value);
- } else {
+ })(type_value);
+ } else {
+ return expect_dictionary([this, &party_issues_found, &modifier_manager, &rule_manager](
+ std::string_view group_key, ast::NodeCPtr group_value
+ ) -> bool {
ReformGroup const* reform_group = get_reform_group_by_identifier(group_key);
size_t ordinal = 0;
+
return expect_dictionary([this, &modifier_manager, &rule_manager, reform_group, &ordinal](
std::string_view key, ast::NodeCPtr value
) -> bool {
if (key == "next_step_only" || key == "administrative") {
return true;
}
+
return _load_reform(modifier_manager, rule_manager, ordinal++, key, reform_group, value);
})(group_value);
- }
- })(type_value);
+ })(type_value);
+ }
}
)(root);
lock_issues();