diff options
author | hop311 <hop3114@gmail.com> | 2024-10-19 12:31:40 +0200 |
---|---|---|
committer | hop311 <hop3114@gmail.com> | 2024-10-19 12:31:40 +0200 |
commit | 35909d6e79d524f19f9b69dffd02fcf162be5093 (patch) | |
tree | fff57526931ab126e1250457e7ccc07c793504f4 /src/openvic-simulation/modifier | |
parent | 18ab144ec4ecf1efca68a26bc79b9d54e28e54f8 (diff) |
Switch to excluding given modifier effect targets rather than using a positive filter
Diffstat (limited to 'src/openvic-simulation/modifier')
-rw-r--r-- | src/openvic-simulation/modifier/ModifierEffect.cpp | 32 | ||||
-rw-r--r-- | src/openvic-simulation/modifier/ModifierEffect.hpp | 10 | ||||
-rw-r--r-- | src/openvic-simulation/modifier/ModifierManager.cpp | 7 | ||||
-rw-r--r-- | src/openvic-simulation/modifier/ModifierSum.cpp | 58 | ||||
-rw-r--r-- | src/openvic-simulation/modifier/ModifierSum.hpp | 30 | ||||
-rw-r--r-- | src/openvic-simulation/modifier/ModifierValue.cpp | 20 | ||||
-rw-r--r-- | src/openvic-simulation/modifier/ModifierValue.hpp | 6 |
7 files changed, 130 insertions, 33 deletions
diff --git a/src/openvic-simulation/modifier/ModifierEffect.cpp b/src/openvic-simulation/modifier/ModifierEffect.cpp index 8daf563..2ffb9a5 100644 --- a/src/openvic-simulation/modifier/ModifierEffect.cpp +++ b/src/openvic-simulation/modifier/ModifierEffect.cpp @@ -4,6 +4,38 @@ using namespace OpenVic; +std::string ModifierEffect::target_to_string(target_t target) { + using enum target_t; + + if (target == NO_TARGETS) { + return "NO TARGETS"; + } + + if (target == ALL_TARGETS) { + return "ALL TARGETS"; + } + + static constexpr std::string_view SEPARATOR = " | "; + + std::string ret; + + const auto append_target = [target, &ret](target_t check_target, std::string_view target_str) -> void { + if (!ModifierEffect::excludes_targets(target, check_target)) { + if (!ret.empty()) { + ret += SEPARATOR; + } + ret += target_str; + } + }; + + append_target(COUNTRY, "COUNTRY"); + append_target(PROVINCE, "PROVINCE"); + append_target(UNIT, "UNIT"); + append_target(~ALL_TARGETS, "INVALID TARGET"); + + return ret; +} + std::string ModifierEffect::make_default_modifier_effect_localisation_key(std::string_view identifier) { return "MODIFIER_" + StringUtils::string_toupper(identifier); } diff --git a/src/openvic-simulation/modifier/ModifierEffect.hpp b/src/openvic-simulation/modifier/ModifierEffect.hpp index 8eac65b..ff82acf 100644 --- a/src/openvic-simulation/modifier/ModifierEffect.hpp +++ b/src/openvic-simulation/modifier/ModifierEffect.hpp @@ -27,6 +27,10 @@ namespace OpenVic { ALL_TARGETS = (1 << 3) - 1 }; + static constexpr bool excludes_targets(target_t targets, target_t excluded_target); + + static std::string target_to_string(target_t target); + static std::string make_default_modifier_effect_localisation_key(std::string_view identifier); private: @@ -50,4 +54,10 @@ namespace OpenVic { }; template<> struct enable_bitfield<ModifierEffect::target_t> : std::true_type {}; + + constexpr bool ModifierEffect::excludes_targets(target_t targets, target_t excluded_targets) { + using enum target_t; + + return (targets & excluded_targets) == NO_TARGETS; + } } diff --git a/src/openvic-simulation/modifier/ModifierManager.cpp b/src/openvic-simulation/modifier/ModifierManager.cpp index c9072c8..f21712d 100644 --- a/src/openvic-simulation/modifier/ModifierManager.cpp +++ b/src/openvic-simulation/modifier/ModifierManager.cpp @@ -7,11 +7,18 @@ bool ModifierManager::add_modifier_effect( ModifierEffect const*& effect_cache, std::string_view identifier, bool positive_good, ModifierEffect::format_t format, ModifierEffect::target_t targets, std::string_view localisation_key ) { + using enum ModifierEffect::target_t; + if (identifier.empty()) { Logger::error("Invalid modifier effect identifier - empty!"); return false; } + if (targets == NO_TARGETS) { + Logger::error("Invalid targets for modifier effect \"", identifier, "\" - none!"); + return false; + } + if (effect_cache != nullptr) { Logger::error( "Cache variable for modifier effect \"", identifier, "\" is already filled with modifier effect \"", diff --git a/src/openvic-simulation/modifier/ModifierSum.cpp b/src/openvic-simulation/modifier/ModifierSum.cpp index a3b8cd5..676e872 100644 --- a/src/openvic-simulation/modifier/ModifierSum.cpp +++ b/src/openvic-simulation/modifier/ModifierSum.cpp @@ -2,8 +2,27 @@ #include "openvic-simulation/modifier/Modifier.hpp" +#include "openvic-simulation/country/CountryInstance.hpp" +#include "openvic-simulation/map/ProvinceInstance.hpp" + using namespace OpenVic; +std::string_view ModifierSum::source_to_string(modifier_source_t const& source) { + return std::visit( + [](HasGetIdentifier auto const* has_identifier) -> std::string_view { + return has_identifier->get_identifier(); + }, + source + ); +} + +std::string ModifierSum::modifier_entry_t::to_string() const { + return StringUtils::append_string_views( + "[", modifier->get_identifier(), ", ", multiplier.to_string(), ", ", source_to_string(source), ", ", + ModifierEffect::target_to_string(excluded_targets), "]" + ); +} + void ModifierSum::clear() { modifiers.clear(); value_sum.clear(); @@ -26,21 +45,25 @@ bool ModifierSum::has_effect(ModifierEffect const& effect) const { } void ModifierSum::add_modifier( - Modifier const& modifier, modifier_source_t const& source, fixed_point_t multiplier, ModifierEffect::target_t targets + Modifier const& modifier, modifier_source_t const& source, fixed_point_t multiplier, + ModifierEffect::target_t excluded_targets ) { using enum ModifierEffect::target_t; - if (multiplier != fixed_point_t::_0() && targets != NO_TARGETS) { - modifiers.emplace_back(&modifier, multiplier, source, targets); - value_sum.multiply_add_filter(modifier, multiplier, targets); + // We could test that excluded_targets != ALL_TARGETS, but in practice it's always + // called with an explcit/hardcoded value and so won't ever exclude everything. + if (multiplier != fixed_point_t::_0()) { + modifiers.emplace_back(&modifier, multiplier, source, excluded_targets); + value_sum.multiply_add_exclude_targets(modifier, multiplier, excluded_targets); } } void ModifierSum::add_modifier_nullcheck( - Modifier const* modifier, modifier_source_t const& source, fixed_point_t multiplier, ModifierEffect::target_t targets + Modifier const* modifier, modifier_source_t const& source, fixed_point_t multiplier, + ModifierEffect::target_t excluded_targets ) { if (modifier != nullptr) { - add_modifier(*modifier, source, multiplier, targets); + add_modifier(*modifier, source, multiplier, excluded_targets); } } @@ -49,22 +72,25 @@ void ModifierSum::add_modifier_sum(ModifierSum const& modifier_sum) { value_sum += modifier_sum.value_sum; } -void ModifierSum::add_modifier_sum_filter_targets(ModifierSum const& modifier_sum, ModifierEffect::target_t targets) { - using enum ModifierEffect::target_t; - +void ModifierSum::add_modifier_sum_exclude_targets( + ModifierSum const& modifier_sum, ModifierEffect::target_t excluded_targets +) { + // We could test that excluded_targets != ALL_TARGETS, but in practice it's always + // called with an explcit/hardcoded value and so won't ever exclude everything. for (modifier_entry_t const& modifier_entry : modifier_sum.modifiers) { - ModifierEffect::target_t new_targets = modifier_entry.targets & targets; - - if (new_targets != NO_TARGETS) { - add_modifier(*modifier_entry.modifier, modifier_entry.source, modifier_entry.multiplier, new_targets); - } + add_modifier( + *modifier_entry.modifier, modifier_entry.source, modifier_entry.multiplier, + modifier_entry.excluded_targets | excluded_targets + ); } } void ModifierSum::add_modifier_sum_exclude_source(ModifierSum const& modifier_sum, modifier_source_t const& excluded_source) { for (modifier_entry_t const& modifier_entry : modifier_sum.modifiers) { if (modifier_entry.source != excluded_source) { - add_modifier(*modifier_entry.modifier, modifier_entry.source, modifier_entry.multiplier, modifier_entry.targets); + add_modifier( + *modifier_entry.modifier, modifier_entry.source, modifier_entry.multiplier, modifier_entry.excluded_targets + ); } } } @@ -77,7 +103,7 @@ void ModifierSum::push_contributing_modifiers( using enum ModifierEffect::target_t; for (modifier_entry_t const& modifier_entry : modifiers) { - if ((modifier_entry.targets & effect.get_targets()) != NO_TARGETS) { + if (ModifierEffect::excludes_targets(effect.get_targets(), modifier_entry.excluded_targets)) { bool effect_found = false; const fixed_point_t value = modifier_entry.modifier->get_effect(effect, &effect_found); diff --git a/src/openvic-simulation/modifier/ModifierSum.hpp b/src/openvic-simulation/modifier/ModifierSum.hpp index 7c1b238..858ca71 100644 --- a/src/openvic-simulation/modifier/ModifierSum.hpp +++ b/src/openvic-simulation/modifier/ModifierSum.hpp @@ -13,16 +13,32 @@ namespace OpenVic { struct ModifierSum { using modifier_source_t = std::variant<CountryInstance const*, ProvinceInstance const*>; + static std::string_view source_to_string(modifier_source_t const& source); + struct modifier_entry_t { Modifier const* modifier; fixed_point_t multiplier; modifier_source_t source; - ModifierEffect::target_t targets; + ModifierEffect::target_t excluded_targets; constexpr modifier_entry_t( - Modifier const* new_modifier, fixed_point_t new_multiplier, modifier_source_t const& new_source, - ModifierEffect::target_t new_targets - ) : modifier { new_modifier }, multiplier { new_multiplier }, source { new_source }, targets { new_targets } {} + Modifier const* new_modifier, + fixed_point_t new_multiplier, + modifier_source_t const& new_source, + ModifierEffect::target_t new_excluded_targets + ) : modifier { new_modifier }, + multiplier { new_multiplier }, + source { new_source }, + excluded_targets { new_excluded_targets } {} + + constexpr bool operator==(modifier_entry_t const& other) const { + return modifier == other.modifier + && multiplier == other.multiplier + && source_to_string(source) == source_to_string(other.source) + && excluded_targets == other.excluded_targets; + } + + std::string to_string() const; }; private: @@ -45,14 +61,14 @@ namespace OpenVic { void add_modifier( Modifier const& modifier, modifier_source_t const& source, fixed_point_t multiplier = fixed_point_t::_1(), - ModifierEffect::target_t targets = ModifierEffect::target_t::ALL_TARGETS + ModifierEffect::target_t excluded_targets = ModifierEffect::target_t::ALL_TARGETS ); void add_modifier_nullcheck( Modifier const* modifier, modifier_source_t const& source, fixed_point_t multiplier = fixed_point_t::_1(), - ModifierEffect::target_t targets = ModifierEffect::target_t::ALL_TARGETS + ModifierEffect::target_t excluded_targets = ModifierEffect::target_t::ALL_TARGETS ); void add_modifier_sum(ModifierSum const& modifier_sum); - void add_modifier_sum_filter_targets(ModifierSum const& modifier_sum, ModifierEffect::target_t targets); + void add_modifier_sum_exclude_targets(ModifierSum const& modifier_sum, ModifierEffect::target_t excluded_targets); void add_modifier_sum_exclude_source(ModifierSum const& modifier_sum, modifier_source_t const& excluded_source); void push_contributing_modifiers(ModifierEffect const& effect, std::vector<modifier_entry_t>& contributions) const; diff --git a/src/openvic-simulation/modifier/ModifierValue.cpp b/src/openvic-simulation/modifier/ModifierValue.cpp index eec34bb..e3e7b0b 100644 --- a/src/openvic-simulation/modifier/ModifierValue.cpp +++ b/src/openvic-simulation/modifier/ModifierValue.cpp @@ -108,27 +108,31 @@ ModifierValue ModifierValue::operator*(fixed_point_t const& right) const { return copy *= right; } -void ModifierValue::apply_target_filter(ModifierEffect::target_t targets) { +void ModifierValue::apply_exclude_targets(ModifierEffect::target_t excluded_targets) { using enum ModifierEffect::target_t; + // We could test if excluded_targets is NO_TARGETS (and so we do nothing) or ALL_TARGETS (and so we clear everything), + // but so long as this is always called with an explicit/hardcoded value then we'll never have either of those cases. erase_if( values, - [targets](effect_map_t::value_type const& value) -> bool { - return (value.first->get_targets() & targets) == NO_TARGETS; + [excluded_targets](effect_map_t::value_type const& value) -> bool { + return !ModifierEffect::excludes_targets(value.first->get_targets(), excluded_targets); } ); } -void ModifierValue::multiply_add_filter( - ModifierValue const& other, fixed_point_t multiplier, ModifierEffect::target_t targets +void ModifierValue::multiply_add_exclude_targets( + ModifierValue const& other, fixed_point_t multiplier, ModifierEffect::target_t excluded_targets ) { using enum ModifierEffect::target_t; - if (multiplier == fixed_point_t::_1() && targets == ALL_TARGETS) { + if (multiplier == fixed_point_t::_1() && excluded_targets == NO_TARGETS) { *this += other; - } else if (multiplier != fixed_point_t::_0() && targets != NO_TARGETS) { + } else if (multiplier != fixed_point_t::_0()) { + // We could test that excluded_targets != ALL_TARGETS, but in practice it's always + // called with an explcit/hardcoded value and so won't ever exclude everything. for (effect_map_t::value_type const& value : other.values) { - if ((value.first->get_targets() & targets) != NO_TARGETS) { + if (ModifierEffect::excludes_targets(value.first->get_targets(), excluded_targets)) { values[value.first] += value.second * multiplier; } } diff --git a/src/openvic-simulation/modifier/ModifierValue.hpp b/src/openvic-simulation/modifier/ModifierValue.hpp index 23c0ba5..6e6a29b 100644 --- a/src/openvic-simulation/modifier/ModifierValue.hpp +++ b/src/openvic-simulation/modifier/ModifierValue.hpp @@ -40,8 +40,10 @@ namespace OpenVic { ModifierValue& operator*=(fixed_point_t const& right); ModifierValue operator*(fixed_point_t const& right) const; - void apply_target_filter(ModifierEffect::target_t targets); - void multiply_add_filter(ModifierValue const& other, fixed_point_t multiplier, ModifierEffect::target_t targets); + void apply_exclude_targets(ModifierEffect::target_t excluded_targets); + void multiply_add_exclude_targets( + ModifierValue const& other, fixed_point_t multiplier, ModifierEffect::target_t excluded_targets + ); friend std::ostream& operator<<(std::ostream& stream, ModifierValue const& value); }; |