diff options
author | Hop311 <Hop3114@gmail.com> | 2024-09-20 14:18:59 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-20 14:18:59 +0200 |
commit | 85da7fb84197d617d1b3cde6969bf7bcfbb93d1d (patch) | |
tree | 0f103095b45de46688206d0e33e24f0331afbabd | |
parent | 7fe8ba2b3bd3bafad374a691280bbf5102b58678 (diff) | |
parent | 3703851ced696a2d4559c3e3340c537982d5ebc7 (diff) |
Merge pull request #203 from OpenVicProject/modifier-sum
Add ModifierSum and improve ModifierValue
21 files changed, 184 insertions, 72 deletions
diff --git a/src/openvic-simulation/DefinitionManager.hpp b/src/openvic-simulation/DefinitionManager.hpp index f38beb0..887cc1b 100644 --- a/src/openvic-simulation/DefinitionManager.hpp +++ b/src/openvic-simulation/DefinitionManager.hpp @@ -12,9 +12,9 @@ #include "openvic-simulation/misc/Decision.hpp" #include "openvic-simulation/misc/Define.hpp" #include "openvic-simulation/misc/Event.hpp" -#include "openvic-simulation/misc/Modifier.hpp" #include "openvic-simulation/misc/SongChance.hpp" #include "openvic-simulation/misc/SoundEffect.hpp" +#include "openvic-simulation/modifier/Modifier.hpp" #include "openvic-simulation/politics/PoliticsManager.hpp" #include "openvic-simulation/pop/Pop.hpp" #include "openvic-simulation/research/ResearchManager.hpp" diff --git a/src/openvic-simulation/economy/BuildingType.hpp b/src/openvic-simulation/economy/BuildingType.hpp index d9a9bd0..b8cfecf 100644 --- a/src/openvic-simulation/economy/BuildingType.hpp +++ b/src/openvic-simulation/economy/BuildingType.hpp @@ -2,7 +2,7 @@ #include "openvic-simulation/economy/GoodDefinition.hpp" #include "openvic-simulation/economy/production/ProductionType.hpp" -#include "openvic-simulation/misc/Modifier.hpp" +#include "openvic-simulation/modifier/Modifier.hpp" #include "openvic-simulation/types/Date.hpp" #include "openvic-simulation/types/IdentifierRegistry.hpp" #include "openvic-simulation/types/fixed_point/FixedPoint.hpp" diff --git a/src/openvic-simulation/economy/GoodDefinition.hpp b/src/openvic-simulation/economy/GoodDefinition.hpp index 15eb4e8..bc231cb 100644 --- a/src/openvic-simulation/economy/GoodDefinition.hpp +++ b/src/openvic-simulation/economy/GoodDefinition.hpp @@ -1,6 +1,6 @@ #pragma once -#include "openvic-simulation/misc/Modifier.hpp" +#include "openvic-simulation/modifier/Modifier.hpp" #include "openvic-simulation/types/IdentifierRegistry.hpp" namespace OpenVic { diff --git a/src/openvic-simulation/map/Crime.hpp b/src/openvic-simulation/map/Crime.hpp index 6aaf12c..757a75e 100644 --- a/src/openvic-simulation/map/Crime.hpp +++ b/src/openvic-simulation/map/Crime.hpp @@ -1,6 +1,6 @@ #pragma once -#include "openvic-simulation/misc/Modifier.hpp" +#include "openvic-simulation/modifier/Modifier.hpp" namespace OpenVic { struct Crime final : TriggeredModifier { diff --git a/src/openvic-simulation/map/Region.hpp b/src/openvic-simulation/map/Region.hpp index 1152dab..ef25b7b 100644 --- a/src/openvic-simulation/map/Region.hpp +++ b/src/openvic-simulation/map/Region.hpp @@ -4,7 +4,7 @@ #include <string_view> #include <vector> -#include "openvic-simulation/misc/Modifier.hpp" +#include "openvic-simulation/modifier/Modifier.hpp" namespace OpenVic { diff --git a/src/openvic-simulation/map/TerrainType.hpp b/src/openvic-simulation/map/TerrainType.hpp index ec36363..3a88610 100644 --- a/src/openvic-simulation/map/TerrainType.hpp +++ b/src/openvic-simulation/map/TerrainType.hpp @@ -1,6 +1,6 @@ #pragma once -#include "openvic-simulation/misc/Modifier.hpp" +#include "openvic-simulation/modifier/Modifier.hpp" #include "openvic-simulation/types/OrderedContainers.hpp" namespace OpenVic { diff --git a/src/openvic-simulation/military/LeaderTrait.hpp b/src/openvic-simulation/military/LeaderTrait.hpp index 65f45f8..cbc5b45 100644 --- a/src/openvic-simulation/military/LeaderTrait.hpp +++ b/src/openvic-simulation/military/LeaderTrait.hpp @@ -2,8 +2,8 @@ #include <string_view> -#include "openvic-simulation/misc/Modifier.hpp" #include "openvic-simulation/dataloader/NodeTools.hpp" +#include "openvic-simulation/modifier/Modifier.hpp" #include "openvic-simulation/types/IdentifierRegistry.hpp" namespace OpenVic { diff --git a/src/openvic-simulation/military/UnitType.hpp b/src/openvic-simulation/military/UnitType.hpp index 6bbaca7..3fa9af5 100644 --- a/src/openvic-simulation/military/UnitType.hpp +++ b/src/openvic-simulation/military/UnitType.hpp @@ -7,7 +7,7 @@ #include "openvic-simulation/dataloader/NodeTools.hpp" #include "openvic-simulation/economy/GoodDefinition.hpp" -#include "openvic-simulation/misc/Modifier.hpp" +#include "openvic-simulation/modifier/Modifier.hpp" #include "openvic-simulation/types/Date.hpp" #include "openvic-simulation/types/IdentifierRegistry.hpp" #include "openvic-simulation/types/fixed_point/FixedPoint.hpp" diff --git a/src/openvic-simulation/misc/Modifier.cpp b/src/openvic-simulation/modifier/Modifier.cpp index e201fdd..28aa777 100644 --- a/src/openvic-simulation/misc/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/misc/Modifier.hpp b/src/openvic-simulation/modifier/Modifier.hpp index f3cc0f6..f525d6a 100644 --- a/src/openvic-simulation/misc/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/Issue.hpp b/src/openvic-simulation/politics/Issue.hpp index 3a6daed..9f2d842 100644 --- a/src/openvic-simulation/politics/Issue.hpp +++ b/src/openvic-simulation/politics/Issue.hpp @@ -1,6 +1,6 @@ #pragma once -#include "openvic-simulation/misc/Modifier.hpp" +#include "openvic-simulation/modifier/Modifier.hpp" #include "openvic-simulation/politics/Rule.hpp" #include "openvic-simulation/scripts/ConditionScript.hpp" #include "openvic-simulation/scripts/EffectScript.hpp" diff --git a/src/openvic-simulation/politics/NationalFocus.hpp b/src/openvic-simulation/politics/NationalFocus.hpp index 04a4100..327b25b 100644 --- a/src/openvic-simulation/politics/NationalFocus.hpp +++ b/src/openvic-simulation/politics/NationalFocus.hpp @@ -1,6 +1,6 @@ #pragma once -#include "openvic-simulation/misc/Modifier.hpp" +#include "openvic-simulation/modifier/Modifier.hpp" #include "openvic-simulation/scripts/ConditionScript.hpp" #include "openvic-simulation/types/IdentifierRegistry.hpp" #include "openvic-simulation/utility/Getters.hpp" diff --git a/src/openvic-simulation/politics/NationalValue.hpp b/src/openvic-simulation/politics/NationalValue.hpp index b896fd7..e69aa28 100644 --- a/src/openvic-simulation/politics/NationalValue.hpp +++ b/src/openvic-simulation/politics/NationalValue.hpp @@ -1,6 +1,6 @@ #pragma once -#include "openvic-simulation/misc/Modifier.hpp" +#include "openvic-simulation/modifier/Modifier.hpp" #include "openvic-simulation/types/IdentifierRegistry.hpp" namespace OpenVic { diff --git a/src/openvic-simulation/politics/Rebel.cpp b/src/openvic-simulation/politics/Rebel.cpp index 1c54f06..fef61c0 100644 --- a/src/openvic-simulation/politics/Rebel.cpp +++ b/src/openvic-simulation/politics/Rebel.cpp @@ -2,8 +2,6 @@ #include <string_view> -#include "openvic-simulation/misc/Modifier.hpp" - using namespace OpenVic; using namespace OpenVic::NodeTools; diff --git a/src/openvic-simulation/politics/Rebel.hpp b/src/openvic-simulation/politics/Rebel.hpp index 7aeb31b..fc82c84 100644 --- a/src/openvic-simulation/politics/Rebel.hpp +++ b/src/openvic-simulation/politics/Rebel.hpp @@ -2,7 +2,7 @@ #include <cstdint> -#include "openvic-simulation/misc/Modifier.hpp" +#include "openvic-simulation/modifier/Modifier.hpp" #include "openvic-simulation/politics/Government.hpp" #include "openvic-simulation/politics/Ideology.hpp" #include "openvic-simulation/scripts/ConditionalWeight.hpp" 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; diff --git a/src/openvic-simulation/research/Invention.hpp b/src/openvic-simulation/research/Invention.hpp index 7c6c07b..58e4030 100644 --- a/src/openvic-simulation/research/Invention.hpp +++ b/src/openvic-simulation/research/Invention.hpp @@ -1,6 +1,6 @@ #pragma once -#include "openvic-simulation/misc/Modifier.hpp" +#include "openvic-simulation/modifier/Modifier.hpp" #include "openvic-simulation/scripts/ConditionalWeight.hpp" #include "openvic-simulation/types/IdentifierRegistry.hpp" #include "openvic-simulation/types/OrderedContainers.hpp" diff --git a/src/openvic-simulation/research/Technology.hpp b/src/openvic-simulation/research/Technology.hpp index 3afeb0b..3d0a438 100644 --- a/src/openvic-simulation/research/Technology.hpp +++ b/src/openvic-simulation/research/Technology.hpp @@ -5,7 +5,7 @@ #include "openvic-simulation/country/CountryInstance.hpp" #include "openvic-simulation/economy/BuildingType.hpp" #include "openvic-simulation/military/UnitType.hpp" -#include "openvic-simulation/misc/Modifier.hpp" +#include "openvic-simulation/modifier/Modifier.hpp" #include "openvic-simulation/scripts/ConditionalWeight.hpp" #include "openvic-simulation/types/Date.hpp" #include "openvic-simulation/types/OrderedContainers.hpp" |