aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/misc/Modifier.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvic-simulation/misc/Modifier.cpp')
-rw-r--r--src/openvic-simulation/misc/Modifier.cpp95
1 files changed, 92 insertions, 3 deletions
diff --git a/src/openvic-simulation/misc/Modifier.cpp b/src/openvic-simulation/misc/Modifier.cpp
index e201fdd..333bb20 100644
--- a/src/openvic-simulation/misc/Modifier.cpp
+++ b/src/openvic-simulation/misc/Modifier.cpp
@@ -49,7 +49,7 @@ bool ModifierValue::empty() const {
return values.empty();
}
-fixed_point_t ModifierValue::get_effect(ModifierEffect const* effect, bool* successful) {
+fixed_point_t ModifierValue::get_effect(ModifierEffect const* effect, bool* successful) const {
const effect_map_t::const_iterator it = values.find(effect);
if (it != values.end()) {
if (successful != nullptr) {
@@ -67,6 +67,14 @@ bool ModifierValue::has_effect(ModifierEffect const* effect) const {
return values.contains(effect);
}
+void ModifierValue::set_effect(ModifierEffect const* effect, fixed_point_t value) {
+ if (effect != nullptr) {
+ values[effect] = value;
+ } else {
+ Logger::error("Tried to set null modifier effect on ModifierValue!");
+ }
+}
+
ModifierValue& ModifierValue::operator+=(ModifierValue const& right) {
for (effect_map_t::value_type const& value : right.values) {
values[value.first] += value.second;
@@ -99,6 +107,32 @@ ModifierValue ModifierValue::operator-(ModifierValue const& right) const {
return ret -= 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 ret = *this;
+ return ret *= 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)
: HasIdentifier { new_identifier }, ModifierValue { std::move(new_values) }, icon { new_icon } {}
@@ -110,8 +144,63 @@ 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 } {}
+
+void ModifierSum::clear() {
+ modifiers.clear();
+ value_sum.clear();
+}
+
+bool ModifierSum::empty() {
+ return modifiers.empty();
+}
+
+fixed_point_t ModifierSum::get_effect(ModifierEffect const* effect, bool* successful) const {
+ return value_sum.get_effect(effect, successful);
+}
+
+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 successful = false;
+ const fixed_point_t value = modifier->get_effect(effect, &successful);
+
+ if (successful) {
+ ret.emplace_back(modifier, value * multiplier);
+ }
+ }
+
+ return ret;
+}
bool ModifierManager::add_modifier_effect(
std::string_view identifier, bool positive_good, ModifierEffect::format_t format, std::string_view localisation_key