aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/openvic-simulation/modifier/Modifier.cpp64
-rw-r--r--src/openvic-simulation/modifier/Modifier.hpp16
-rw-r--r--src/openvic-simulation/modifier/ModifierSum.cpp58
-rw-r--r--src/openvic-simulation/modifier/ModifierSum.hpp30
-rw-r--r--src/openvic-simulation/politics/Rule.cpp50
-rw-r--r--src/openvic-simulation/politics/Rule.hpp8
6 files changed, 170 insertions, 56 deletions
diff --git a/src/openvic-simulation/modifier/Modifier.cpp b/src/openvic-simulation/modifier/Modifier.cpp
index e201fdd..28aa777 100644
--- a/src/openvic-simulation/modifier/Modifier.cpp
+++ b/src/openvic-simulation/modifier/Modifier.cpp
@@ -49,22 +49,26 @@ bool ModifierValue::empty() const {
return values.empty();
}
-fixed_point_t ModifierValue::get_effect(ModifierEffect const* effect, bool* successful) {
- const effect_map_t::const_iterator it = values.find(effect);
+fixed_point_t ModifierValue::get_effect(ModifierEffect const& effect, bool* effect_found) const {
+ const effect_map_t::const_iterator it = values.find(&effect);
if (it != values.end()) {
- if (successful != nullptr) {
- *successful = true;
+ if (effect_found != nullptr) {
+ *effect_found = true;
}
return it->second;
}
- if (successful != nullptr) {
- *successful = false;
+ if (effect_found != nullptr) {
+ *effect_found = false;
}
return fixed_point_t::_0();
}
-bool ModifierValue::has_effect(ModifierEffect const* effect) const {
- return values.contains(effect);
+bool ModifierValue::has_effect(ModifierEffect const& effect) const {
+ return values.contains(&effect);
+}
+
+void ModifierValue::set_effect(ModifierEffect const& effect, fixed_point_t value) {
+ values[&effect] = value;
}
ModifierValue& ModifierValue::operator+=(ModifierValue const& right) {
@@ -75,16 +79,16 @@ ModifierValue& ModifierValue::operator+=(ModifierValue const& right) {
}
ModifierValue ModifierValue::operator+(ModifierValue const& right) const {
- ModifierValue ret = *this;
- return ret += right;
+ ModifierValue copy = *this;
+ return copy += right;
}
ModifierValue ModifierValue::operator-() const {
- ModifierValue ret = *this;
- for (auto value : mutable_iterator(ret.values)) {
+ ModifierValue copy = *this;
+ for (auto value : mutable_iterator(copy.values)) {
value.second = -value.second;
}
- return ret;
+ return copy;
}
ModifierValue& ModifierValue::operator-=(ModifierValue const& right) {
@@ -95,8 +99,34 @@ ModifierValue& ModifierValue::operator-=(ModifierValue const& right) {
}
ModifierValue ModifierValue::operator-(ModifierValue const& right) const {
- ModifierValue ret = *this;
- return ret -= right;
+ ModifierValue copy = *this;
+ return copy -= right;
+}
+
+ModifierValue& ModifierValue::operator*=(fixed_point_t const& right) {
+ for (auto value : mutable_iterator(values)) {
+ value.second *= right;
+ }
+ return *this;
+}
+
+ModifierValue ModifierValue::operator*(fixed_point_t const& right) const {
+ ModifierValue copy = *this;
+ return copy *= right;
+}
+
+fixed_point_t& ModifierValue::operator[](ModifierEffect const& effect) {
+ return values[&effect];
+}
+
+void ModifierValue::multiply_add(ModifierValue const& other, fixed_point_t multiplier) {
+ if (multiplier == fixed_point_t::_1()) {
+ *this += other;
+ } else if (multiplier != fixed_point_t::_0()) {
+ for (effect_map_t::value_type const& value : other.values) {
+ values[value.first] += value.second * multiplier;
+ }
+ }
}
Modifier::Modifier(std::string_view new_identifier, ModifierValue&& new_values, icon_t new_icon)
@@ -110,8 +140,8 @@ bool TriggeredModifier::parse_scripts(DefinitionManager const& definition_manage
return trigger.parse_script(false, definition_manager);
}
-ModifierInstance::ModifierInstance(Modifier const& modifier, Date expiry_date)
- : modifier { modifier }, expiry_date { expiry_date } {}
+ModifierInstance::ModifierInstance(Modifier const& new_modifier, Date new_expiry_date)
+ : modifier { &new_modifier }, expiry_date { new_expiry_date } {}
bool ModifierManager::add_modifier_effect(
std::string_view identifier, bool positive_good, ModifierEffect::format_t format, std::string_view localisation_key
diff --git a/src/openvic-simulation/modifier/Modifier.hpp b/src/openvic-simulation/modifier/Modifier.hpp
index f3cc0f6..f525d6a 100644
--- a/src/openvic-simulation/modifier/Modifier.hpp
+++ b/src/openvic-simulation/modifier/Modifier.hpp
@@ -57,14 +57,21 @@ namespace OpenVic {
void clear();
bool empty() const;
- fixed_point_t get_effect(ModifierEffect const* effect, bool* successful = nullptr);
- bool has_effect(ModifierEffect const* effect) const;
+ fixed_point_t get_effect(ModifierEffect const& effect, bool* effect_found = nullptr) const;
+ bool has_effect(ModifierEffect const& effect) const;
+ void set_effect(ModifierEffect const& effect, fixed_point_t value);
ModifierValue& operator+=(ModifierValue const& right);
ModifierValue operator+(ModifierValue const& right) const;
ModifierValue operator-() const;
ModifierValue& operator-=(ModifierValue const& right);
ModifierValue operator-(ModifierValue const& right) const;
+ ModifierValue& operator*=(fixed_point_t const& right);
+ ModifierValue operator*(fixed_point_t const& right) const;
+
+ fixed_point_t& operator[](ModifierEffect const& effect);
+
+ void multiply_add(ModifierValue const& other, fixed_point_t multiplier);
friend std::ostream& operator<<(std::ostream& stream, ModifierValue const& value);
};
@@ -105,10 +112,11 @@ namespace OpenVic {
struct ModifierInstance {
private:
- Modifier const& PROPERTY(modifier);
+ Modifier const* PROPERTY(modifier); // We can assume this is never null
Date PROPERTY(expiry_date);
- ModifierInstance(Modifier const& modifier, Date expiry_date);
+ public:
+ ModifierInstance(Modifier const& new_modifier, Date new_expiry_date);
};
template<typename Fn>
diff --git a/src/openvic-simulation/modifier/ModifierSum.cpp b/src/openvic-simulation/modifier/ModifierSum.cpp
new file mode 100644
index 0000000..8e5ce48
--- /dev/null
+++ b/src/openvic-simulation/modifier/ModifierSum.cpp
@@ -0,0 +1,58 @@
+#include "ModifierSum.hpp"
+
+using namespace OpenVic;
+
+void ModifierSum::clear() {
+ modifiers.clear();
+ value_sum.clear();
+}
+
+bool ModifierSum::empty() {
+ return modifiers.empty();
+}
+
+fixed_point_t ModifierSum::get_effect(ModifierEffect const& effect, bool* effect_found) const {
+ return value_sum.get_effect(effect, effect_found);
+}
+
+bool ModifierSum::has_effect(ModifierEffect const& effect) const {
+ return value_sum.has_effect(effect);
+}
+
+void ModifierSum::add_modifier(Modifier const& modifier, fixed_point_t multiplier) {
+ modifiers[&modifier] += multiplier;
+ value_sum.multiply_add(modifier, multiplier);
+}
+
+void ModifierSum::add_modifier_sum(ModifierSum const& modifier_sum) {
+ modifiers += modifier_sum.modifiers;
+ value_sum += modifier_sum.value_sum;
+}
+
+ModifierSum& ModifierSum::operator+=(Modifier const& modifier) {
+ add_modifier(modifier);
+ return *this;
+}
+
+ModifierSum& ModifierSum::operator+=(ModifierSum const& modifier_sum) {
+ add_modifier_sum(modifier_sum);
+ return *this;
+}
+
+// TODO - include value_sum[effect] in result? Early return if lookup in value_sum fails?
+std::vector<std::pair<Modifier const*, fixed_point_t>> ModifierSum::get_contributing_modifiers(
+ ModifierEffect const& effect
+) const {
+ std::vector<std::pair<Modifier const*, fixed_point_t>> ret;
+
+ for (auto const& [modifier, multiplier] : modifiers) {
+ bool effect_found = false;
+ const fixed_point_t value = modifier->get_effect(effect, &effect_found);
+
+ if (effect_found) {
+ ret.emplace_back(modifier, value * multiplier);
+ }
+ }
+
+ return ret;
+}
diff --git a/src/openvic-simulation/modifier/ModifierSum.hpp b/src/openvic-simulation/modifier/ModifierSum.hpp
new file mode 100644
index 0000000..957ffab
--- /dev/null
+++ b/src/openvic-simulation/modifier/ModifierSum.hpp
@@ -0,0 +1,30 @@
+#pragma once
+
+#include "openvic-simulation/modifier/Modifier.hpp"
+#include "openvic-simulation/types/fixed_point/FixedPointMap.hpp"
+
+namespace OpenVic {
+ struct ModifierSum {
+ private:
+ fixed_point_map_t<Modifier const*> PROPERTY(modifiers);
+ ModifierValue PROPERTY(value_sum);
+
+ public:
+ ModifierSum() = default;
+ ModifierSum(ModifierSum&&) = default;
+
+ void clear();
+ bool empty();
+
+ fixed_point_t get_effect(ModifierEffect const& effect, bool* effect_found = nullptr) const;
+ bool has_effect(ModifierEffect const& effect) const;
+
+ void add_modifier(Modifier const& modifier, fixed_point_t multiplier = fixed_point_t::_1());
+ void add_modifier_sum(ModifierSum const& modifier_sum);
+
+ ModifierSum& operator+=(Modifier const& modifier);
+ ModifierSum& operator+=(ModifierSum const& modifier_sum);
+
+ std::vector<std::pair<Modifier const*, fixed_point_t>> get_contributing_modifiers(ModifierEffect const& effect) const;
+ };
+}
diff --git a/src/openvic-simulation/politics/Rule.cpp b/src/openvic-simulation/politics/Rule.cpp
index f2c0f8d..64d06f1 100644
--- a/src/openvic-simulation/politics/Rule.cpp
+++ b/src/openvic-simulation/politics/Rule.cpp
@@ -83,54 +83,42 @@ bool RuleSet::empty() const {
return true;
}
-RuleSet::rule_map_t const& RuleSet::get_rule_group(Rule::rule_group_t group, bool* successful) const {
+RuleSet::rule_map_t const& RuleSet::get_rule_group(Rule::rule_group_t group, bool* rule_group_found) const {
const rule_group_map_t::const_iterator it = rule_groups.find(group);
if (it != rule_groups.end()) {
- if (successful != nullptr) {
- *successful = true;
+ if (rule_group_found != nullptr) {
+ *rule_group_found = true;
}
return it->second;
}
- if (successful != nullptr) {
- *successful = false;
+ if (rule_group_found != nullptr) {
+ *rule_group_found = false;
}
static const rule_map_t empty_map {};
return empty_map;
}
-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);
+bool RuleSet::get_rule(Rule const& rule, bool* rule_found) const {
+ 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;
+ if (rule_found != nullptr) {
+ *rule_found = true;
}
return it->second;
}
- if (successful != nullptr) {
- *successful = false;
+ if (rule_found != nullptr) {
+ *rule_found = false;
}
- return Rule::is_default_enabled(rule->get_group());
+ return Rule::is_default_enabled(rule.get_group());
}
-bool RuleSet::has_rule(Rule const* rule) const {
- if (rule == nullptr) {
- Logger::error("Invalid rule - null!");
- return false;
- }
- return get_rule_group(rule->get_group()).contains(rule);
+bool RuleSet::has_rule(Rule const& rule) const {
+ 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_groups[rule->get_group()][rule] = value;
+bool RuleSet::set_rule(Rule const& rule, bool value) {
+ rule_groups[rule.get_group()][&rule] = value;
return true;
}
@@ -144,8 +132,8 @@ RuleSet& RuleSet::operator|=(RuleSet const& right) {
}
RuleSet RuleSet::operator|(RuleSet const& right) const {
- RuleSet ret = *this;
- return ret |= right;
+ RuleSet copy = *this;
+ return copy |= right;
}
bool RuleManager::add_rule(std::string_view identifier, Rule::rule_group_t group, std::string_view localisation_key) {
diff --git a/src/openvic-simulation/politics/Rule.hpp b/src/openvic-simulation/politics/Rule.hpp
index 579299b..0bbac82 100644
--- a/src/openvic-simulation/politics/Rule.hpp
+++ b/src/openvic-simulation/politics/Rule.hpp
@@ -65,12 +65,12 @@ namespace OpenVic {
void clear();
bool empty() const;
- 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;
+ rule_map_t const& get_rule_group(Rule::rule_group_t group, bool* rule_group_found = nullptr) const;
+ bool get_rule(Rule const& rule, bool* rule_found = 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);
+ bool set_rule(Rule const& rule, bool value);
RuleSet& operator|=(RuleSet const& right);
RuleSet operator|(RuleSet const& right) const;