From 2bfd651778bff970991f3bd320a78a4008959b4a Mon Sep 17 00:00:00 2001 From: hop311 Date: Sat, 21 Sep 2024 14:23:58 +0100 Subject: Store sources in ModifierSum --- src/openvic-simulation/modifier/ModifierSum.cpp | 30 ++++++++++++------------- 1 file changed, 14 insertions(+), 16 deletions(-) (limited to 'src/openvic-simulation/modifier/ModifierSum.cpp') diff --git a/src/openvic-simulation/modifier/ModifierSum.cpp b/src/openvic-simulation/modifier/ModifierSum.cpp index 8e5ce48..f603a5b 100644 --- a/src/openvic-simulation/modifier/ModifierSum.cpp +++ b/src/openvic-simulation/modifier/ModifierSum.cpp @@ -19,38 +19,36 @@ 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; +void ModifierSum::add_modifier(Modifier const& modifier, modifier_source_t source, fixed_point_t multiplier) { + modifiers.emplace_back(&modifier, multiplier, source); value_sum.multiply_add(modifier, multiplier); } void ModifierSum::add_modifier_sum(ModifierSum const& modifier_sum) { - modifiers += modifier_sum.modifiers; + modifiers.insert(modifiers.end(), modifier_sum.modifiers.begin(), modifier_sum.modifiers.end()); 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; +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); + } + } } // TODO - include value_sum[effect] in result? Early return if lookup in value_sum fails? -std::vector> ModifierSum::get_contributing_modifiers( +std::vector ModifierSum::get_contributing_modifiers( ModifierEffect const& effect ) const { - std::vector> ret; + std::vector ret; - for (auto const& [modifier, multiplier] : modifiers) { + for (modifier_entry_t const& modifier_entry : modifiers) { bool effect_found = false; - const fixed_point_t value = modifier->get_effect(effect, &effect_found); + const fixed_point_t value = modifier_entry.modifier->get_effect(effect, &effect_found); if (effect_found) { - ret.emplace_back(modifier, value * multiplier); + ret.push_back(modifier_entry); } } -- cgit v1.2.3-56-ga3b1 From 4f9fd8a327b6de5fb32792a07453e9a2e245dc84 Mon Sep 17 00:00:00 2001 From: hop311 Date: Wed, 25 Sep 2024 22:10:21 +0100 Subject: Add ModifierEffect targets --- src/openvic-simulation/economy/BuildingType.cpp | 5 +- src/openvic-simulation/economy/GoodDefinition.cpp | 3 +- src/openvic-simulation/military/UnitType.cpp | 7 +- src/openvic-simulation/modifier/Modifier.cpp | 346 ++++++++++++---------- src/openvic-simulation/modifier/Modifier.hpp | 20 +- src/openvic-simulation/modifier/ModifierSum.cpp | 38 ++- src/openvic-simulation/modifier/ModifierSum.hpp | 18 +- src/openvic-simulation/politics/Rebel.cpp | 7 +- src/openvic-simulation/pop/Pop.cpp | 6 +- src/openvic-simulation/research/Technology.cpp | 5 +- 10 files changed, 273 insertions(+), 182 deletions(-) (limited to 'src/openvic-simulation/modifier/ModifierSum.cpp') diff --git a/src/openvic-simulation/economy/BuildingType.cpp b/src/openvic-simulation/economy/BuildingType.cpp index e7c0d59..d75f1b2 100644 --- a/src/openvic-simulation/economy/BuildingType.cpp +++ b/src/openvic-simulation/economy/BuildingType.cpp @@ -114,16 +114,17 @@ bool BuildingTypeManager::load_buildings_file( for (BuildingType const& building_type : building_types.get_items()) { using enum ModifierEffect::format_t; + using enum ModifierEffect::target_t; static constexpr std::string_view max_prefix = "max_"; static constexpr std::string_view min_prefix = "min_build_"; ret &= modifier_manager.add_modifier_effect( - StringUtils::append_string_views(max_prefix, building_type.get_identifier()), true, INT, + StringUtils::append_string_views(max_prefix, building_type.get_identifier()), true, INT, PROVINCE, StringUtils::append_string_views("$", building_type.get_identifier(), "$ $TECH_MAX_LEVEL$") ); // TODO - add custom localisation for "min_build_$building_type$" modifiers ret &= modifier_manager.add_modifier_effect( - StringUtils::append_string_views(min_prefix, building_type.get_identifier()), false, INT + StringUtils::append_string_views(min_prefix, building_type.get_identifier()), false, INT, PROVINCE ); if (building_type.is_in_province()) { diff --git a/src/openvic-simulation/economy/GoodDefinition.cpp b/src/openvic-simulation/economy/GoodDefinition.cpp index ed24549..97396f2 100644 --- a/src/openvic-simulation/economy/GoodDefinition.cpp +++ b/src/openvic-simulation/economy/GoodDefinition.cpp @@ -89,6 +89,7 @@ bool GoodDefinitionManager::load_goods_file(ast::NodeCPtr root) { bool GoodDefinitionManager::generate_modifiers(ModifierManager& modifier_manager) const { using enum ModifierEffect::format_t; + using enum ModifierEffect::target_t; bool ret = true; @@ -100,7 +101,7 @@ bool GoodDefinitionManager::generate_modifiers(ModifierManager& modifier_manager for (GoodDefinition const& good : get_good_definitions()) { ret &= modifier_manager.add_modifier_effect( ModifierManager::get_flat_identifier(name, good.get_identifier()), is_positive_good, PROPORTION_DECIMAL, - make_localisation_suffix(good.get_identifier()) + COUNTRY, make_localisation_suffix(good.get_identifier()) ); } }; diff --git a/src/openvic-simulation/military/UnitType.cpp b/src/openvic-simulation/military/UnitType.cpp index 71bc5c3..bb227fb 100644 --- a/src/openvic-simulation/military/UnitType.cpp +++ b/src/openvic-simulation/military/UnitType.cpp @@ -321,17 +321,18 @@ bool UnitTypeManager::generate_modifiers(ModifierManager& modifier_manager) cons const auto generate_stat_modifiers = [&modifier_manager, &ret]( std::string_view identifier, UnitType::branch_t branch ) -> void { + using enum ModifierEffect::format_t; + using enum ModifierEffect::target_t; + const auto stat_modifier = [&modifier_manager, &ret, &identifier]( std::string_view suffix, bool is_positive_good, ModifierEffect::format_t format, std::string_view localisation_key ) -> void { ret &= modifier_manager.add_modifier_effect( - ModifierManager::get_flat_identifier(identifier, suffix), is_positive_good, format, + ModifierManager::get_flat_identifier(identifier, suffix), is_positive_good, format, COUNTRY, StringUtils::append_string_views("$", identifier, "$: $", localisation_key, "$") ); }; - using enum ModifierEffect::format_t; - ret &= modifier_manager.register_complex_modifier(identifier); stat_modifier("attack", true, RAW_DECIMAL, "ATTACK"); diff --git a/src/openvic-simulation/modifier/Modifier.cpp b/src/openvic-simulation/modifier/Modifier.cpp index 10e32a4..73b30ce 100644 --- a/src/openvic-simulation/modifier/Modifier.cpp +++ b/src/openvic-simulation/modifier/Modifier.cpp @@ -17,8 +17,9 @@ static std::string make_default_modifier_effect_localisation_key(std::string_vie } ModifierEffect::ModifierEffect( - std::string_view new_identifier, bool new_positive_good, format_t new_format, std::string_view new_localisation_key -) : HasIdentifier { new_identifier }, positive_good { new_positive_good }, format { new_format }, + std::string_view new_identifier, bool new_positive_good, format_t new_format, target_t new_targets, + std::string_view new_localisation_key +) : HasIdentifier { new_identifier }, positive_good { new_positive_good }, format { new_format }, targets { new_targets }, localisation_key { new_localisation_key.empty() ? make_default_modifier_effect_localisation_key(new_identifier) : new_localisation_key } {} @@ -115,12 +116,29 @@ ModifierValue ModifierValue::operator*(fixed_point_t const& right) const { return copy *= right; } -void ModifierValue::multiply_add(ModifierValue const& other, fixed_point_t multiplier) { - if (multiplier == fixed_point_t::_1()) { +void ModifierValue::apply_target_filter(ModifierEffect::target_t targets) { + using enum ModifierEffect::target_t; + + erase_if( + values, + [targets](effect_map_t::value_type const& value) -> bool { + return (value.first->get_targets() & targets) == NO_TARGETS; + } + ); +} + +void ModifierValue::multiply_add_filter( + ModifierValue const& other, fixed_point_t multiplier, ModifierEffect::target_t targets +) { + using enum ModifierEffect::target_t; + + if (multiplier == fixed_point_t::_1() && targets == ALL_TARGETS) { *this += other; - } else if (multiplier != fixed_point_t::_0()) { + } else if (multiplier != fixed_point_t::_0() && targets != NO_TARGETS) { for (effect_map_t::value_type const& value : other.values) { - values[value.first] += value.second * multiplier; + if ((value.first->get_targets() & targets) != NO_TARGETS) { + values[value.first] += value.second * multiplier; + } } } } @@ -145,247 +163,261 @@ ModifierInstance::ModifierInstance(Modifier const& new_modifier, Date new_expiry : 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 + std::string_view identifier, bool positive_good, ModifierEffect::format_t format, ModifierEffect::target_t targets, + std::string_view localisation_key ) { if (identifier.empty()) { Logger::error("Invalid modifier effect identifier - empty!"); return false; } - return modifier_effects.add_item({ std::move(identifier), positive_good, format, localisation_key }); + return modifier_effects.add_item({ std::move(identifier), positive_good, format, targets, localisation_key }); } bool ModifierManager::setup_modifier_effects() { bool ret = true; using enum ModifierEffect::format_t; + using enum ModifierEffect::target_t; /* Tech/inventions only */ - ret &= add_modifier_effect("cb_creation_speed", true, PROPORTION_DECIMAL, "CB_MANUFACTURE_TECH"); - ret &= add_modifier_effect("combat_width", false, PROPORTION_DECIMAL); - ret &= add_modifier_effect("plurality", true, PERCENTAGE_DECIMAL, "TECH_PLURALITY"); - ret &= add_modifier_effect("pop_growth", true, PROPORTION_DECIMAL, "TECH_POP_GROWTH"); - ret &= add_modifier_effect("regular_experience_level", true, RAW_DECIMAL, "REGULAR_EXP_TECH"); - ret &= add_modifier_effect("reinforce_rate", true, PROPORTION_DECIMAL, "REINFORCE_TECH"); - ret &= add_modifier_effect("seperatism", false, PROPORTION_DECIMAL, "SEPARATISM_TECH"); // paradox typo - ret &= add_modifier_effect("shared_prestige", true, RAW_DECIMAL, "SHARED_PRESTIGE_TECH"); - ret &= add_modifier_effect("tax_eff", true, PROPORTION_DECIMAL, "TECH_TAX_EFF"); + ret &= add_modifier_effect("cb_creation_speed", true, PROPORTION_DECIMAL, COUNTRY, "CB_MANUFACTURE_TECH"); + ret &= add_modifier_effect("combat_width", false, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("plurality", true, PERCENTAGE_DECIMAL, COUNTRY, "TECH_PLURALITY"); + ret &= add_modifier_effect("pop_growth", true, PROPORTION_DECIMAL, COUNTRY, "TECH_POP_GROWTH"); + ret &= add_modifier_effect("regular_experience_level", true, RAW_DECIMAL, COUNTRY, "REGULAR_EXP_TECH"); + ret &= add_modifier_effect("reinforce_rate", true, PROPORTION_DECIMAL, COUNTRY, "REINFORCE_TECH"); + ret &= add_modifier_effect("seperatism", false, PROPORTION_DECIMAL, COUNTRY, "SEPARATISM_TECH"); // paradox typo + ret &= add_modifier_effect("shared_prestige", true, RAW_DECIMAL, COUNTRY, "SHARED_PRESTIGE_TECH"); + ret &= add_modifier_effect("tax_eff", true, PERCENTAGE_DECIMAL, COUNTRY, "TECH_TAX_EFF"); /* Country Modifier Effects */ - ret &= add_modifier_effect("administrative_efficiency", true, PROPORTION_DECIMAL); + ret &= add_modifier_effect("administrative_efficiency", true, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect( - "administrative_efficiency_modifier", true, PROPORTION_DECIMAL, + "administrative_efficiency_modifier", true, PROPORTION_DECIMAL, COUNTRY, make_default_modifier_effect_localisation_key("administrative_efficiency") ); - ret &= add_modifier_effect("artisan_input", false, PROPORTION_DECIMAL); - ret &= add_modifier_effect("artisan_output", true, PROPORTION_DECIMAL); - ret &= add_modifier_effect("artisan_throughput", true, PROPORTION_DECIMAL); - ret &= add_modifier_effect("badboy", false, RAW_DECIMAL); - ret &= add_modifier_effect("cb_generation_speed_modifier", true, PROPORTION_DECIMAL); + ret &= add_modifier_effect("artisan_input", false, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("artisan_output", true, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("artisan_throughput", true, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("badboy", false, RAW_DECIMAL, COUNTRY); + ret &= add_modifier_effect("cb_generation_speed_modifier", true, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect( - "civilization_progress_modifier", true, PROPORTION_DECIMAL, + "civilization_progress_modifier", true, PROPORTION_DECIMAL, COUNTRY, make_default_modifier_effect_localisation_key("civilization_progress") ); - ret &= add_modifier_effect("colonial_life_rating", false, INT, "COLONIAL_LIFE_TECH"); - ret &= add_modifier_effect("colonial_migration", true, PROPORTION_DECIMAL, "COLONIAL_MIGRATION_TECH"); - ret &= add_modifier_effect("colonial_points", true, INT, "COLONIAL_POINTS_TECH"); - ret &= add_modifier_effect("colonial_prestige", true, PROPORTION_DECIMAL, "COLONIAL_PRESTIGE_MODIFIER_TECH"); - ret &= add_modifier_effect("core_pop_consciousness_modifier", false, RAW_DECIMAL); - ret &= add_modifier_effect("core_pop_militancy_modifier", false, RAW_DECIMAL); - ret &= add_modifier_effect("dig_in_cap", true, INT, "DIGIN_FROM_TECH"); - ret &= add_modifier_effect("diplomatic_points", true, PROPORTION_DECIMAL, "DIPLOMATIC_POINTS_TECH"); + ret &= add_modifier_effect("colonial_life_rating", false, INT, COUNTRY, "COLONIAL_LIFE_TECH"); + ret &= add_modifier_effect("colonial_migration", true, PROPORTION_DECIMAL, COUNTRY, "COLONIAL_MIGRATION_TECH"); + ret &= add_modifier_effect("colonial_points", true, INT, COUNTRY, "COLONIAL_POINTS_TECH"); + ret &= add_modifier_effect("colonial_prestige", true, PROPORTION_DECIMAL, COUNTRY, "COLONIAL_PRESTIGE_MODIFIER_TECH"); + ret &= add_modifier_effect("core_pop_consciousness_modifier", false, RAW_DECIMAL, COUNTRY); + ret &= add_modifier_effect("core_pop_militancy_modifier", false, RAW_DECIMAL, COUNTRY); + ret &= add_modifier_effect("dig_in_cap", true, INT, COUNTRY, "DIGIN_FROM_TECH"); + ret &= add_modifier_effect("diplomatic_points", true, PROPORTION_DECIMAL, COUNTRY, "DIPLOMATIC_POINTS_TECH"); ret &= add_modifier_effect( - "diplomatic_points_modifier", true, PROPORTION_DECIMAL, + "diplomatic_points_modifier", true, PROPORTION_DECIMAL, COUNTRY, make_default_modifier_effect_localisation_key("diplopoints_gain") ); - ret &= add_modifier_effect("education_efficiency", true, PROPORTION_DECIMAL); + ret &= add_modifier_effect("education_efficiency", true, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect( - "education_efficiency_modifier", true, PROPORTION_DECIMAL, + "education_efficiency_modifier", true, PROPORTION_DECIMAL, COUNTRY, make_default_modifier_effect_localisation_key("education_efficiency") ); - ret &= add_modifier_effect("factory_cost", false, PROPORTION_DECIMAL); - ret &= add_modifier_effect("factory_input", false, PROPORTION_DECIMAL); - ret &= add_modifier_effect("factory_maintenance", false, PROPORTION_DECIMAL); - ret &= add_modifier_effect("factory_output", true, PROPORTION_DECIMAL); - ret &= add_modifier_effect("factory_owner_cost", false, PROPORTION_DECIMAL); - ret &= add_modifier_effect("factory_throughput", true, PROPORTION_DECIMAL); + ret &= add_modifier_effect("factory_cost", false, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("factory_input", false, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("factory_maintenance", false, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("factory_output", true, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("factory_owner_cost", false, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("factory_throughput", true, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect( - "global_assimilation_rate", true, PROPORTION_DECIMAL, + "global_assimilation_rate", true, PROPORTION_DECIMAL, COUNTRY, make_default_modifier_effect_localisation_key("assimilation_rate") ); ret &= add_modifier_effect( - "global_immigrant_attract", true, PROPORTION_DECIMAL, + "global_immigrant_attract", true, PROPORTION_DECIMAL, COUNTRY, make_default_modifier_effect_localisation_key("immigant_attract") ); - ret &= add_modifier_effect("global_pop_consciousness_modifier", false, RAW_DECIMAL); - ret &= add_modifier_effect("global_pop_militancy_modifier", false, RAW_DECIMAL); + ret &= add_modifier_effect("global_pop_consciousness_modifier", false, RAW_DECIMAL, COUNTRY); + ret &= add_modifier_effect("global_pop_militancy_modifier", false, RAW_DECIMAL, COUNTRY); ret &= add_modifier_effect( - "global_population_growth", true, PROPORTION_DECIMAL, + "global_population_growth", true, PROPORTION_DECIMAL, COUNTRY, make_default_modifier_effect_localisation_key("population_growth") ); - ret &= add_modifier_effect("goods_demand", false, PROPORTION_DECIMAL); - ret &= add_modifier_effect("import_cost", false, PROPORTION_DECIMAL); - ret &= add_modifier_effect("increase_research", true, PROPORTION_DECIMAL, "INC_RES_TECH"); - ret &= add_modifier_effect("influence", true, PROPORTION_DECIMAL, "TECH_GP_INFLUENCE"); + ret &= add_modifier_effect("goods_demand", false, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("import_cost", false, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("increase_research", true, PROPORTION_DECIMAL, COUNTRY, "INC_RES_TECH"); + ret &= add_modifier_effect("influence", true, PROPORTION_DECIMAL, COUNTRY, "TECH_GP_INFLUENCE"); ret &= add_modifier_effect( - "influence_modifier", true, PROPORTION_DECIMAL, + "influence_modifier", true, PROPORTION_DECIMAL, COUNTRY, make_default_modifier_effect_localisation_key("greatpower_influence_gain") ); - ret &= add_modifier_effect("issue_change_speed", true, PROPORTION_DECIMAL); + ret &= add_modifier_effect("issue_change_speed", true, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect( - "land_attack_modifier", true, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("land_attack") + "land_attack_modifier", true, PROPORTION_DECIMAL, COUNTRY, make_default_modifier_effect_localisation_key("land_attack") ); - ret &= add_modifier_effect("land_attrition", false, PROPORTION_DECIMAL, "LAND_ATTRITION_TECH"); + ret &= add_modifier_effect("land_attrition", false, PROPORTION_DECIMAL, COUNTRY, "LAND_ATTRITION_TECH"); ret &= add_modifier_effect( - "land_defense_modifier", true, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("land_defense") + "land_defense_modifier", true, PROPORTION_DECIMAL, COUNTRY, + make_default_modifier_effect_localisation_key("land_defense") ); - ret &= add_modifier_effect("land_organisation", true, PROPORTION_DECIMAL); - ret &= add_modifier_effect("land_unit_start_experience", true, RAW_DECIMAL); - ret &= add_modifier_effect("leadership", true, RAW_DECIMAL, "LEADERSHIP"); + ret &= add_modifier_effect("land_organisation", true, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("land_unit_start_experience", true, RAW_DECIMAL, COUNTRY); + ret &= add_modifier_effect("leadership", true, RAW_DECIMAL, COUNTRY, "LEADERSHIP"); ret &= add_modifier_effect( - "leadership_modifier", true, PROPORTION_DECIMAL, + "leadership_modifier", true, PROPORTION_DECIMAL, COUNTRY, make_default_modifier_effect_localisation_key("global_leadership_modifier") ); - ret &= add_modifier_effect("literacy_con_impact", false, PROPORTION_DECIMAL); - ret &= add_modifier_effect("loan_interest", false, PROPORTION_DECIMAL); - ret &= add_modifier_effect( - "max_loan_modifier", true, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("max_loan_amount") - ); - ret &= add_modifier_effect("max_military_spending", true, PROPORTION_DECIMAL); - ret &= add_modifier_effect("max_national_focus", true, INT, "TECH_MAX_FOCUS"); - ret &= add_modifier_effect("max_social_spending", true, PROPORTION_DECIMAL); - ret &= add_modifier_effect("max_tariff", true, PROPORTION_DECIMAL); - ret &= add_modifier_effect("max_tax", true, PROPORTION_DECIMAL); - ret &= add_modifier_effect("max_war_exhaustion", true, PERCENTAGE_DECIMAL, "MAX_WAR_EXHAUSTION"); - ret &= add_modifier_effect("military_tactics", true, PROPORTION_DECIMAL, "MIL_TACTICS_TECH"); - ret &= add_modifier_effect("min_military_spending", true, PROPORTION_DECIMAL); - ret &= add_modifier_effect("min_social_spending", true, PROPORTION_DECIMAL); - ret &= add_modifier_effect("min_tariff", true, PROPORTION_DECIMAL); - ret &= add_modifier_effect("min_tax", true, PROPORTION_DECIMAL); - ret &= add_modifier_effect( - "minimum_wage", true, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("minimun_wage") - ); - ret &= add_modifier_effect("mobilisation_economy_impact", false, PROPORTION_DECIMAL); - ret &= add_modifier_effect("mobilisation_size", true, PROPORTION_DECIMAL); - ret &= add_modifier_effect("mobilization_impact", false, PROPORTION_DECIMAL); - ret &= add_modifier_effect( - "naval_attack_modifier", true, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("naval_attack") - ); - ret &= add_modifier_effect("naval_attrition", false, PROPORTION_DECIMAL, "NAVAL_ATTRITION_TECH"); - ret &= add_modifier_effect( - "naval_defense_modifier", true, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("naval_defense") - ); - ret &= add_modifier_effect("naval_organisation", true, PROPORTION_DECIMAL); - ret &= add_modifier_effect("naval_unit_start_experience", true, RAW_DECIMAL); - ret &= add_modifier_effect("non_accepted_pop_consciousness_modifier", false, RAW_DECIMAL); - ret &= add_modifier_effect("non_accepted_pop_militancy_modifier", false, RAW_DECIMAL); - ret &= add_modifier_effect("org_regain", true, PROPORTION_DECIMAL); - ret &= add_modifier_effect("pension_level", true, PROPORTION_DECIMAL); - ret &= add_modifier_effect("permanent_prestige", true, RAW_DECIMAL, "PERMANENT_PRESTIGE_TECH"); - ret &= add_modifier_effect("political_reform_desire", false, PROPORTION_DECIMAL); - ret &= add_modifier_effect("poor_savings_modifier", true, PROPORTION_DECIMAL); - ret &= add_modifier_effect("prestige", true, RAW_DECIMAL); - ret &= add_modifier_effect("reinforce_speed", true, PROPORTION_DECIMAL); - ret &= add_modifier_effect("research_points", true, RAW_DECIMAL); - ret &= add_modifier_effect("research_points_modifier", true, PROPORTION_DECIMAL); - ret &= add_modifier_effect("research_points_on_conquer", true, PROPORTION_DECIMAL); - ret &= add_modifier_effect("rgo_output", true, PROPORTION_DECIMAL); - ret &= add_modifier_effect("rgo_throughput", true, PROPORTION_DECIMAL); - ret &= add_modifier_effect("ruling_party_support", true, PROPORTION_DECIMAL); - ret &= add_modifier_effect( - "self_unciv_economic_modifier", false, PROPORTION_DECIMAL, + ret &= add_modifier_effect("literacy_con_impact", false, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("loan_interest", false, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect( + "max_loan_modifier", true, PROPORTION_DECIMAL, COUNTRY, + make_default_modifier_effect_localisation_key("max_loan_amount") + ); + ret &= add_modifier_effect("max_military_spending", true, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("max_national_focus", true, INT, COUNTRY, "TECH_MAX_FOCUS"); + ret &= add_modifier_effect("max_social_spending", true, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("max_tariff", true, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("max_tax", true, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("max_war_exhaustion", true, PERCENTAGE_DECIMAL, COUNTRY, "MAX_WAR_EXHAUSTION"); + ret &= add_modifier_effect("military_tactics", true, PROPORTION_DECIMAL, COUNTRY, "MIL_TACTICS_TECH"); + ret &= add_modifier_effect("min_military_spending", true, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("min_social_spending", true, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("min_tariff", true, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("min_tax", true, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect( + "minimum_wage", true, PROPORTION_DECIMAL, COUNTRY, make_default_modifier_effect_localisation_key("minimun_wage") + ); + ret &= add_modifier_effect("mobilisation_economy_impact", false, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("mobilisation_size", true, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("mobilization_impact", false, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect( + "naval_attack_modifier", true, PROPORTION_DECIMAL, COUNTRY, + make_default_modifier_effect_localisation_key("naval_attack") + ); + ret &= add_modifier_effect("naval_attrition", false, PROPORTION_DECIMAL, COUNTRY, "NAVAL_ATTRITION_TECH"); + ret &= add_modifier_effect( + "naval_defense_modifier", true, PROPORTION_DECIMAL, COUNTRY, + make_default_modifier_effect_localisation_key("naval_defense") + ); + ret &= add_modifier_effect("naval_organisation", true, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("naval_unit_start_experience", true, RAW_DECIMAL, COUNTRY); + ret &= add_modifier_effect("non_accepted_pop_consciousness_modifier", false, RAW_DECIMAL, COUNTRY); + ret &= add_modifier_effect("non_accepted_pop_militancy_modifier", false, RAW_DECIMAL, COUNTRY); + ret &= add_modifier_effect("org_regain", true, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("pension_level", true, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("permanent_prestige", true, RAW_DECIMAL, COUNTRY, "PERMANENT_PRESTIGE_TECH"); + ret &= add_modifier_effect("political_reform_desire", false, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("poor_savings_modifier", true, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("prestige", true, RAW_DECIMAL, COUNTRY); + ret &= add_modifier_effect("reinforce_speed", true, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("research_points", true, RAW_DECIMAL, COUNTRY); + ret &= add_modifier_effect("research_points_modifier", true, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("research_points_on_conquer", true, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("rgo_output", true, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("rgo_throughput", true, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("ruling_party_support", true, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect( + "self_unciv_economic_modifier", false, PROPORTION_DECIMAL, COUNTRY, make_default_modifier_effect_localisation_key("self_unciv_economic") ); ret &= add_modifier_effect( - "self_unciv_military_modifier", false, PROPORTION_DECIMAL, + "self_unciv_military_modifier", false, PROPORTION_DECIMAL, COUNTRY, make_default_modifier_effect_localisation_key("self_unciv_military") ); - ret &= add_modifier_effect("social_reform_desire", false, PROPORTION_DECIMAL); - ret &= add_modifier_effect("soldier_to_pop_loss", true, PROPORTION_DECIMAL, "SOLDIER_TO_POP_LOSS_TECH"); - ret &= add_modifier_effect("supply_consumption", false, PROPORTION_DECIMAL); - ret &= add_modifier_effect("supply_range", true, PROPORTION_DECIMAL, "SUPPLY_RANGE_TECH"); - ret &= add_modifier_effect("suppression_points_modifier", true, PROPORTION_DECIMAL, "SUPPRESSION_TECH"); + ret &= add_modifier_effect("social_reform_desire", false, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("soldier_to_pop_loss", true, PROPORTION_DECIMAL, COUNTRY, "SOLDIER_TO_POP_LOSS_TECH"); + ret &= add_modifier_effect("supply_consumption", false, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("supply_range", true, PROPORTION_DECIMAL, COUNTRY, "SUPPLY_RANGE_TECH"); + ret &= add_modifier_effect("suppression_points_modifier", true, PROPORTION_DECIMAL, COUNTRY, "SUPPRESSION_TECH"); ret &= add_modifier_effect( - "tariff_efficiency_modifier", true, PROPORTION_DECIMAL, + "tariff_efficiency_modifier", true, PROPORTION_DECIMAL, COUNTRY, make_default_modifier_effect_localisation_key("tariff_efficiency") ); - ret &= add_modifier_effect("tax_efficiency", true, PROPORTION_DECIMAL); - ret &= add_modifier_effect("unemployment_benefit", true, PROPORTION_DECIMAL); + ret &= add_modifier_effect("tax_efficiency", true, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("unemployment_benefit", true, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect( - "unciv_economic_modifier", false, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("unciv_economic") + "unciv_economic_modifier", false, PROPORTION_DECIMAL, COUNTRY, + make_default_modifier_effect_localisation_key("unciv_economic") ); ret &= add_modifier_effect( - "unciv_military_modifier", false, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("unciv_military") + "unciv_military_modifier", false, PROPORTION_DECIMAL, COUNTRY, + make_default_modifier_effect_localisation_key("unciv_military") ); - ret &= add_modifier_effect("unit_recruitment_time", false, PROPORTION_DECIMAL); - ret &= add_modifier_effect("war_exhaustion", false, PROPORTION_DECIMAL, "WAR_EXHAUST_BATTLES"); + ret &= add_modifier_effect("unit_recruitment_time", false, PROPORTION_DECIMAL, COUNTRY); + ret &= add_modifier_effect("war_exhaustion", false, PROPORTION_DECIMAL, COUNTRY, "WAR_EXHAUST_BATTLES"); /* Province Modifier Effects */ - ret &= add_modifier_effect("assimilation_rate", true, PROPORTION_DECIMAL); - ret &= add_modifier_effect("boost_strongest_party", false, PROPORTION_DECIMAL); - ret &= add_modifier_effect("farm_rgo_eff", true, PROPORTION_DECIMAL, "TECH_FARM_OUTPUT"); + ret &= add_modifier_effect("assimilation_rate", true, PROPORTION_DECIMAL, PROVINCE); + ret &= add_modifier_effect("boost_strongest_party", false, PROPORTION_DECIMAL, PROVINCE); + ret &= add_modifier_effect("farm_rgo_eff", true, PROPORTION_DECIMAL, PROVINCE, "TECH_FARM_OUTPUT"); ret &= add_modifier_effect( - "farm_rgo_size", true, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("farm_size") + "farm_rgo_size", true, PROPORTION_DECIMAL, PROVINCE, make_default_modifier_effect_localisation_key("farm_size") ); ret &= add_modifier_effect( - "immigrant_attract", true, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("immigant_attract") + "immigrant_attract", true, PROPORTION_DECIMAL, PROVINCE, + make_default_modifier_effect_localisation_key("immigant_attract") ); ret &= add_modifier_effect( - "immigrant_push", false, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("immigant_push") + "immigrant_push", false, PROPORTION_DECIMAL, PROVINCE, make_default_modifier_effect_localisation_key("immigant_push") ); - ret &= add_modifier_effect("life_rating", true, PROPORTION_DECIMAL); + ret &= add_modifier_effect("life_rating", true, PROPORTION_DECIMAL, PROVINCE); ret &= add_modifier_effect( - "local_artisan_input", false, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("artisan_input") + "local_artisan_input", false, PROPORTION_DECIMAL, PROVINCE, + make_default_modifier_effect_localisation_key("artisan_input") ); ret &= add_modifier_effect( - "local_artisan_output", true, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("artisan_output") + "local_artisan_output", true, PROPORTION_DECIMAL, PROVINCE, + make_default_modifier_effect_localisation_key("artisan_output") ); ret &= add_modifier_effect( - "local_artisan_throughput", true, PROPORTION_DECIMAL, + "local_artisan_throughput", true, PROPORTION_DECIMAL, PROVINCE, make_default_modifier_effect_localisation_key("artisan_throughput") ); ret &= add_modifier_effect( - "local_factory_input", false, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("factory_input") + "local_factory_input", false, PROPORTION_DECIMAL, PROVINCE, + make_default_modifier_effect_localisation_key("factory_input") ); ret &= add_modifier_effect( - "local_factory_output", true, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("factory_output") + "local_factory_output", true, PROPORTION_DECIMAL, PROVINCE, + make_default_modifier_effect_localisation_key("factory_output") ); ret &= add_modifier_effect( - "local_factory_throughput", true, PROPORTION_DECIMAL, + "local_factory_throughput", true, PROPORTION_DECIMAL, PROVINCE, make_default_modifier_effect_localisation_key("factory_throughput") ); - ret &= add_modifier_effect("local_repair", true, PROPORTION_DECIMAL); + ret &= add_modifier_effect("local_repair", true, PROPORTION_DECIMAL, PROVINCE); ret &= add_modifier_effect( - "local_rgo_output", true, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("rgo_output") + "local_rgo_output", true, PROPORTION_DECIMAL, PROVINCE, make_default_modifier_effect_localisation_key("rgo_output") ); ret &= add_modifier_effect( - "local_rgo_throughput", true, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("rgo_throughput") + "local_rgo_throughput", true, PROPORTION_DECIMAL, PROVINCE, + make_default_modifier_effect_localisation_key("rgo_throughput") ); ret &= add_modifier_effect( - "local_ruling_party_support", true, PROPORTION_DECIMAL, + "local_ruling_party_support", true, PROPORTION_DECIMAL, PROVINCE, make_default_modifier_effect_localisation_key("ruling_party_support") ); - ret &= add_modifier_effect("local_ship_build", false, PROPORTION_DECIMAL); - ret &= add_modifier_effect("max_attrition", false, RAW_DECIMAL); - ret &= add_modifier_effect("mine_rgo_eff", true, PROPORTION_DECIMAL, "TECH_MINE_OUTPUT"); + ret &= add_modifier_effect("local_ship_build", false, PROPORTION_DECIMAL, PROVINCE); + ret &= add_modifier_effect("max_attrition", false, RAW_DECIMAL, PROVINCE); + ret &= add_modifier_effect("mine_rgo_eff", true, PROPORTION_DECIMAL, PROVINCE, "TECH_MINE_OUTPUT"); ret &= add_modifier_effect( - "mine_rgo_size", true, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("mine_size") + "mine_rgo_size", true, PROPORTION_DECIMAL, PROVINCE, make_default_modifier_effect_localisation_key("mine_size") ); - ret &= add_modifier_effect("movement_cost", false, PROPORTION_DECIMAL); - ret &= add_modifier_effect("number_of_voters", false, PROPORTION_DECIMAL); - ret &= add_modifier_effect("pop_consciousness_modifier", false, RAW_DECIMAL); - ret &= add_modifier_effect("pop_militancy_modifier", false, RAW_DECIMAL); - ret &= add_modifier_effect("population_growth", true, PROPORTION_DECIMAL); - ret &= add_modifier_effect("supply_limit", true, RAW_DECIMAL); + ret &= add_modifier_effect("movement_cost", false, PROPORTION_DECIMAL, PROVINCE); + ret &= add_modifier_effect("number_of_voters", false, PROPORTION_DECIMAL, PROVINCE); + ret &= add_modifier_effect("pop_consciousness_modifier", false, RAW_DECIMAL, PROVINCE); + ret &= add_modifier_effect("pop_militancy_modifier", false, RAW_DECIMAL, PROVINCE); + ret &= add_modifier_effect("population_growth", true, PROPORTION_DECIMAL, PROVINCE); + ret &= add_modifier_effect("supply_limit", true, RAW_DECIMAL, PROVINCE); /* Military Modifier Effects */ - ret &= add_modifier_effect("attack", true, INT, "TRAIT_ATTACK"); - ret &= add_modifier_effect("attrition", false, RAW_DECIMAL, "ATTRITION"); - ret &= add_modifier_effect("defence", true, INT, "TRAIT_DEFEND"); - ret &= add_modifier_effect("experience", true, PROPORTION_DECIMAL, "TRAIT_EXPERIENCE"); - ret &= add_modifier_effect("morale", true, PROPORTION_DECIMAL, "TRAIT_MORALE"); - ret &= add_modifier_effect("organisation", true, PROPORTION_DECIMAL, "TRAIT_ORGANISATION"); - ret &= add_modifier_effect("reconnaissance", true, PROPORTION_DECIMAL, "TRAIT_RECONAISSANCE"); - ret &= add_modifier_effect("reliability", true, RAW_DECIMAL, "TRAIT_RELIABILITY"); - ret &= add_modifier_effect("speed", true, PROPORTION_DECIMAL, "TRAIT_SPEED"); + ret &= add_modifier_effect("attack", true, INT, UNIT, "TRAIT_ATTACK"); + ret &= add_modifier_effect("attrition", false, RAW_DECIMAL, UNIT, "ATTRITION"); + ret &= add_modifier_effect("defence", true, INT, UNIT, "TRAIT_DEFEND"); + ret &= add_modifier_effect("experience", true, PROPORTION_DECIMAL, UNIT, "TRAIT_EXPERIENCE"); + ret &= add_modifier_effect("morale", true, PROPORTION_DECIMAL, UNIT, "TRAIT_MORALE"); + ret &= add_modifier_effect("organisation", true, PROPORTION_DECIMAL, UNIT, "TRAIT_ORGANISATION"); + ret &= add_modifier_effect("reconnaissance", true, PROPORTION_DECIMAL, UNIT, "TRAIT_RECONAISSANCE"); + ret &= add_modifier_effect("reliability", true, RAW_DECIMAL, UNIT, "TRAIT_RELIABILITY"); + ret &= add_modifier_effect("speed", true, PROPORTION_DECIMAL, UNIT, "TRAIT_SPEED"); return ret; } diff --git a/src/openvic-simulation/modifier/Modifier.hpp b/src/openvic-simulation/modifier/Modifier.hpp index 4b032c0..a848cb8 100644 --- a/src/openvic-simulation/modifier/Modifier.hpp +++ b/src/openvic-simulation/modifier/Modifier.hpp @@ -10,31 +10,43 @@ namespace OpenVic { struct ModifierEffect : HasIdentifier { friend struct ModifierManager; - enum class format_t { + enum class format_t : uint8_t { PROPORTION_DECIMAL, /* An unscaled fraction/ratio, with 1 being "full"/"whole" */ PERCENTAGE_DECIMAL, /* A fraction/ratio scaled so that 100 is "full"/"whole" */ RAW_DECIMAL, /* A continuous quantity, e.g. attack strength */ INT /* A discrete quantity, e.g. building count limit */ }; + enum class target_t : uint8_t { + NO_TARGETS = 0, + COUNTRY = 1 << 0, + PROVINCE = 1 << 1, + UNIT = 1 << 2, + ALL_TARGETS = (1 << 3) - 1 + }; + private: /* If true, positive values will be green and negative values will be red. * If false, the colours will be switced. */ const bool PROPERTY_CUSTOM_PREFIX(positive_good, is); const format_t PROPERTY(format); + const target_t PROPERTY(targets); std::string PROPERTY(localisation_key); // TODO - format/precision, e.g. 80% vs 0.8 vs 0.800, 2 vs 2.0 vs 200% ModifierEffect( - std::string_view new_identifier, bool new_positive_good, format_t new_format, std::string_view new_localisation_key + std::string_view new_identifier, bool new_positive_good, format_t new_format, target_t mew_targets, + std::string_view new_localisation_key ); public: ModifierEffect(ModifierEffect&&) = default; }; + template<> struct enable_bitfield : std::true_type {}; + struct ModifierValue { friend struct ModifierManager; @@ -70,7 +82,8 @@ namespace OpenVic { ModifierValue& operator*=(fixed_point_t const& right); ModifierValue operator*(fixed_point_t const& right) const; - void multiply_add(ModifierValue const& other, fixed_point_t multiplier); + void apply_target_filter(ModifierEffect::target_t targets); + void multiply_add_filter(ModifierValue const& other, fixed_point_t multiplier, ModifierEffect::target_t targets); friend std::ostream& operator<<(std::ostream& stream, ModifierValue const& value); }; @@ -167,6 +180,7 @@ namespace OpenVic { bool add_modifier_effect( std::string_view identifier, bool positive_good, ModifierEffect::format_t format, + ModifierEffect::target_t targets, std::string_view localisation_key = {} ); diff --git a/src/openvic-simulation/modifier/ModifierSum.cpp b/src/openvic-simulation/modifier/ModifierSum.cpp index f603a5b..312432a 100644 --- a/src/openvic-simulation/modifier/ModifierSum.cpp +++ b/src/openvic-simulation/modifier/ModifierSum.cpp @@ -19,9 +19,15 @@ bool ModifierSum::has_effect(ModifierEffect const& effect) const { return value_sum.has_effect(effect); } -void ModifierSum::add_modifier(Modifier const& modifier, modifier_source_t source, fixed_point_t multiplier) { - modifiers.emplace_back(&modifier, multiplier, source); - value_sum.multiply_add(modifier, multiplier); +void ModifierSum::add_modifier( + Modifier const& modifier, modifier_source_t const& source, fixed_point_t multiplier, ModifierEffect::target_t 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); + } } void ModifierSum::add_modifier_sum(ModifierSum const& modifier_sum) { @@ -29,10 +35,22 @@ 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; + + 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); + } + } +} + 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); + add_modifier(*modifier_entry.modifier, modifier_entry.source, modifier_entry.multiplier, modifier_entry.targets); } } } @@ -41,14 +59,18 @@ void ModifierSum::add_modifier_sum_exclude_source(ModifierSum const& modifier_su std::vector ModifierSum::get_contributing_modifiers( ModifierEffect const& effect ) const { + using enum ModifierEffect::target_t; + std::vector ret; for (modifier_entry_t const& modifier_entry : modifiers) { - bool effect_found = false; - const fixed_point_t value = modifier_entry.modifier->get_effect(effect, &effect_found); + if ((modifier_entry.targets & effect.get_targets()) != NO_TARGETS) { + bool effect_found = false; + const fixed_point_t value = modifier_entry.modifier->get_effect(effect, &effect_found); - if (effect_found) { - ret.push_back(modifier_entry); + if (effect_found) { + ret.push_back(modifier_entry); + } } } diff --git a/src/openvic-simulation/modifier/ModifierSum.hpp b/src/openvic-simulation/modifier/ModifierSum.hpp index 81ae871..b982ed1 100644 --- a/src/openvic-simulation/modifier/ModifierSum.hpp +++ b/src/openvic-simulation/modifier/ModifierSum.hpp @@ -1,6 +1,9 @@ #pragma once +#include + #include "openvic-simulation/modifier/Modifier.hpp" +#include "openvic-simulation/types/fixed_point/FixedPoint.hpp" namespace OpenVic { struct CountryInstance; @@ -13,10 +16,12 @@ namespace OpenVic { Modifier const* modifier; fixed_point_t multiplier; modifier_source_t source; + ModifierEffect::target_t targets; constexpr modifier_entry_t( - Modifier const* new_modifier, fixed_point_t new_multiplier, modifier_source_t const& new_source - ) : modifier { new_modifier }, multiplier { new_multiplier }, source { new_source } {} + 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 } {} }; private: @@ -25,7 +30,10 @@ namespace OpenVic { public: ModifierSum() = default; + ModifierSum(ModifierSum const&) = default; ModifierSum(ModifierSum&&) = default; + ModifierSum& operator=(ModifierSum const&) = default; + ModifierSum& operator=(ModifierSum&&) = default; void clear(); bool empty(); @@ -33,8 +41,12 @@ namespace OpenVic { 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, modifier_source_t source, fixed_point_t multiplier = fixed_point_t::_1()); + 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 + ); 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_source(ModifierSum const& modifier_sum, modifier_source_t const& excluded_source); std::vector get_contributing_modifiers(ModifierEffect const& effect) const; diff --git a/src/openvic-simulation/politics/Rebel.cpp b/src/openvic-simulation/politics/Rebel.cpp index fef61c0..395df49 100644 --- a/src/openvic-simulation/politics/Rebel.cpp +++ b/src/openvic-simulation/politics/Rebel.cpp @@ -175,6 +175,7 @@ bool RebelManager::load_rebels_file( bool RebelManager::generate_modifiers(ModifierManager& modifier_manager) const { using enum ModifierEffect::format_t; + using enum ModifierEffect::target_t; bool ret = true; @@ -184,12 +185,14 @@ bool RebelManager::generate_modifiers(ModifierManager& modifier_manager) const { ret &= modifier_manager.register_complex_modifier(identifier); ret &= modifier_manager.add_modifier_effect( - ModifierManager::get_flat_identifier(identifier, "all"), is_positive_good, PROPORTION_DECIMAL, "TECH_REBEL_ORG_GAIN" + ModifierManager::get_flat_identifier(identifier, "all"), is_positive_good, PROPORTION_DECIMAL, COUNTRY, + "TECH_REBEL_ORG_GAIN" ); for (RebelType const& rebel_type : get_rebel_types()) { ret &= modifier_manager.add_modifier_effect( - ModifierManager::get_flat_identifier(identifier, rebel_type.get_identifier()), is_positive_good, PROPORTION_DECIMAL, + ModifierManager::get_flat_identifier(identifier, rebel_type.get_identifier()), is_positive_good, + PROPORTION_DECIMAL, COUNTRY, StringUtils::append_string_views("$", rebel_type.get_identifier(), "_title$ $TECH_REBEL_ORG_GAIN$") ); } diff --git a/src/openvic-simulation/pop/Pop.cpp b/src/openvic-simulation/pop/Pop.cpp index e89d510..aeaeef5 100644 --- a/src/openvic-simulation/pop/Pop.cpp +++ b/src/openvic-simulation/pop/Pop.cpp @@ -654,6 +654,7 @@ bool PopManager::load_pop_bases_into_vector( bool PopManager::generate_modifiers(ModifierManager& modifier_manager) const { using enum ModifierEffect::format_t; + using enum ModifierEffect::target_t; bool ret = true; @@ -662,11 +663,12 @@ bool PopManager::generate_modifiers(ModifierManager& modifier_manager) const { std::string_view suffix, bool is_positive_good ) -> void { ret &= modifier_manager.add_modifier_effect( - StringUtils::append_string_views(strata.get_identifier(), suffix), is_positive_good, PROPORTION_DECIMAL + StringUtils::append_string_views(strata.get_identifier(), suffix), is_positive_good, PROPORTION_DECIMAL, + COUNTRY ); }; - strata_modifier("_income_modifier", true); + strata_modifier("_income_modifier", true); // Has no effect in game strata_modifier("_vote", true); strata_modifier("_life_needs", false); diff --git a/src/openvic-simulation/research/Technology.cpp b/src/openvic-simulation/research/Technology.cpp index a5256f3..3284193 100644 --- a/src/openvic-simulation/research/Technology.cpp +++ b/src/openvic-simulation/research/Technology.cpp @@ -197,13 +197,16 @@ bool TechnologyManager::load_technologies_file( bool TechnologyManager::generate_modifiers(ModifierManager& modifier_manager) const { using enum ModifierEffect::format_t; + using enum ModifierEffect::target_t; bool ret = true; for (TechnologyFolder const& folder : get_technology_folders()) { const std::string modifier_identifier = StringUtils::append_string_views(folder.get_identifier(), "_research_bonus"); - ret &= modifier_manager.add_modifier_effect(modifier_identifier, true, PROPORTION_DECIMAL, modifier_identifier); + ret &= modifier_manager.add_modifier_effect( + modifier_identifier, true, PROPORTION_DECIMAL, COUNTRY, modifier_identifier + ); } return ret; -- cgit v1.2.3-56-ga3b1 From 6c23b7ff2e8bc733699ef9b29aee80719001acf2 Mon Sep 17 00:00:00 2001 From: hop311 Date: Sat, 5 Oct 2024 19:08:55 +0100 Subject: Add nullcheck fuction variants accepting pointer arguments to ModifierValue and ModifierSum --- src/openvic-simulation/modifier/Modifier.cpp | 12 ++++++++++++ src/openvic-simulation/modifier/Modifier.hpp | 1 + src/openvic-simulation/modifier/ModifierSum.cpp | 12 ++++++++++++ src/openvic-simulation/modifier/ModifierSum.hpp | 5 +++++ 4 files changed, 30 insertions(+) (limited to 'src/openvic-simulation/modifier/ModifierSum.cpp') diff --git a/src/openvic-simulation/modifier/Modifier.cpp b/src/openvic-simulation/modifier/Modifier.cpp index 73b30ce..c7c8087 100644 --- a/src/openvic-simulation/modifier/Modifier.cpp +++ b/src/openvic-simulation/modifier/Modifier.cpp @@ -58,6 +58,18 @@ fixed_point_t ModifierValue::get_effect(ModifierEffect const& effect, bool* effe } return it->second; } + + if (effect_found != nullptr) { + *effect_found = false; + } + return fixed_point_t::_0(); +} + +fixed_point_t ModifierValue::get_effect_nullcheck(ModifierEffect const* effect, bool* effect_found) const { + if (effect != nullptr) { + return get_effect(*effect, effect_found); + } + if (effect_found != nullptr) { *effect_found = false; } diff --git a/src/openvic-simulation/modifier/Modifier.hpp b/src/openvic-simulation/modifier/Modifier.hpp index a848cb8..f52f126 100644 --- a/src/openvic-simulation/modifier/Modifier.hpp +++ b/src/openvic-simulation/modifier/Modifier.hpp @@ -71,6 +71,7 @@ namespace OpenVic { bool empty() const; fixed_point_t get_effect(ModifierEffect const& effect, bool* effect_found = nullptr) const; + fixed_point_t get_effect_nullcheck(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); diff --git a/src/openvic-simulation/modifier/ModifierSum.cpp b/src/openvic-simulation/modifier/ModifierSum.cpp index 312432a..4051d64 100644 --- a/src/openvic-simulation/modifier/ModifierSum.cpp +++ b/src/openvic-simulation/modifier/ModifierSum.cpp @@ -15,6 +15,10 @@ fixed_point_t ModifierSum::get_effect(ModifierEffect const& effect, bool* effect return value_sum.get_effect(effect, effect_found); } +fixed_point_t ModifierSum::get_effect_nullcheck(ModifierEffect const* effect, bool* effect_found) const { + return value_sum.get_effect_nullcheck(effect, effect_found); +} + bool ModifierSum::has_effect(ModifierEffect const& effect) const { return value_sum.has_effect(effect); } @@ -30,6 +34,14 @@ void ModifierSum::add_modifier( } } +void ModifierSum::add_modifier_nullcheck( + Modifier const* modifier, modifier_source_t const& source, fixed_point_t multiplier, ModifierEffect::target_t targets +) { + if (modifier != nullptr) { + add_modifier(*modifier, source, multiplier, targets); + } +} + void ModifierSum::add_modifier_sum(ModifierSum const& modifier_sum) { modifiers.insert(modifiers.end(), modifier_sum.modifiers.begin(), modifier_sum.modifiers.end()); value_sum += modifier_sum.value_sum; diff --git a/src/openvic-simulation/modifier/ModifierSum.hpp b/src/openvic-simulation/modifier/ModifierSum.hpp index b982ed1..406c52b 100644 --- a/src/openvic-simulation/modifier/ModifierSum.hpp +++ b/src/openvic-simulation/modifier/ModifierSum.hpp @@ -39,12 +39,17 @@ namespace OpenVic { bool empty(); fixed_point_t get_effect(ModifierEffect const& effect, bool* effect_found = nullptr) const; + fixed_point_t get_effect_nullcheck(ModifierEffect const* effect, bool* effect_found = nullptr) const; bool has_effect(ModifierEffect const& effect) const; 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 ); + 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 + ); 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_source(ModifierSum const& modifier_sum, modifier_source_t const& excluded_source); -- cgit v1.2.3-56-ga3b1 From f3f364f08cc8f1c80a5dfce689183c2f8f75bbd4 Mon Sep 17 00:00:00 2001 From: hop311 Date: Mon, 30 Sep 2024 21:10:01 +0100 Subject: Move ModifierEffect and ModifierValue into their own files --- src/openvic-simulation/economy/GoodDefinition.cpp | 2 + src/openvic-simulation/economy/GoodDefinition.hpp | 3 +- src/openvic-simulation/military/UnitType.hpp | 2 +- src/openvic-simulation/modifier/Modifier.cpp | 216 ++++----------------- src/openvic-simulation/modifier/Modifier.hpp | 86 +------- src/openvic-simulation/modifier/ModifierEffect.cpp | 17 ++ src/openvic-simulation/modifier/ModifierEffect.hpp | 53 +++++ src/openvic-simulation/modifier/ModifierSum.cpp | 2 + src/openvic-simulation/modifier/ModifierSum.hpp | 3 +- src/openvic-simulation/modifier/ModifierValue.cpp | 136 +++++++++++++ src/openvic-simulation/modifier/ModifierValue.hpp | 48 +++++ src/openvic-simulation/politics/Rebel.cpp | 2 + src/openvic-simulation/politics/Rebel.hpp | 3 +- 13 files changed, 308 insertions(+), 265 deletions(-) create mode 100644 src/openvic-simulation/modifier/ModifierEffect.cpp create mode 100644 src/openvic-simulation/modifier/ModifierEffect.hpp create mode 100644 src/openvic-simulation/modifier/ModifierValue.cpp create mode 100644 src/openvic-simulation/modifier/ModifierValue.hpp (limited to 'src/openvic-simulation/modifier/ModifierSum.cpp') diff --git a/src/openvic-simulation/economy/GoodDefinition.cpp b/src/openvic-simulation/economy/GoodDefinition.cpp index 97396f2..fcaae11 100644 --- a/src/openvic-simulation/economy/GoodDefinition.cpp +++ b/src/openvic-simulation/economy/GoodDefinition.cpp @@ -1,5 +1,7 @@ #include "GoodDefinition.hpp" +#include "openvic-simulation/modifier/Modifier.hpp" + using namespace OpenVic; using namespace OpenVic::NodeTools; diff --git a/src/openvic-simulation/economy/GoodDefinition.hpp b/src/openvic-simulation/economy/GoodDefinition.hpp index bc231cb..823c1a3 100644 --- a/src/openvic-simulation/economy/GoodDefinition.hpp +++ b/src/openvic-simulation/economy/GoodDefinition.hpp @@ -1,6 +1,5 @@ #pragma once -#include "openvic-simulation/modifier/Modifier.hpp" #include "openvic-simulation/types/IdentifierRegistry.hpp" namespace OpenVic { @@ -51,6 +50,8 @@ namespace OpenVic { GoodDefinition(GoodDefinition&&) = default; }; + struct ModifierManager; + struct GoodDefinitionManager { private: IdentifierRegistry IDENTIFIER_REGISTRY_CUSTOM_PLURAL(good_category, good_categories); diff --git a/src/openvic-simulation/military/UnitType.hpp b/src/openvic-simulation/military/UnitType.hpp index 3fa9af5..980a119 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/modifier/Modifier.hpp" +#include "openvic-simulation/modifier/ModifierValue.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/modifier/Modifier.cpp b/src/openvic-simulation/modifier/Modifier.cpp index c7c8087..0867c1b 100644 --- a/src/openvic-simulation/modifier/Modifier.cpp +++ b/src/openvic-simulation/modifier/Modifier.cpp @@ -7,154 +7,10 @@ #include #include "openvic-simulation/types/OrderedContainers.hpp" -#include "openvic-simulation/utility/TslHelper.hpp" using namespace OpenVic; using namespace OpenVic::NodeTools; -static std::string make_default_modifier_effect_localisation_key(std::string_view identifier) { - return "MODIFIER_" + StringUtils::string_toupper(identifier); -} - -ModifierEffect::ModifierEffect( - std::string_view new_identifier, bool new_positive_good, format_t new_format, target_t new_targets, - std::string_view new_localisation_key -) : HasIdentifier { new_identifier }, positive_good { new_positive_good }, format { new_format }, targets { new_targets }, - localisation_key { - new_localisation_key.empty() ? make_default_modifier_effect_localisation_key(new_identifier) : new_localisation_key - } {} - -ModifierValue::ModifierValue() = default; -ModifierValue::ModifierValue(effect_map_t&& new_values) : values { std::move(new_values) } {} -ModifierValue::ModifierValue(ModifierValue const&) = default; -ModifierValue::ModifierValue(ModifierValue&&) = default; - -ModifierValue& ModifierValue::operator=(ModifierValue const&) = default; -ModifierValue& ModifierValue::operator=(ModifierValue&&) = default; - -void ModifierValue::trim() { - erase_if(values, [](effect_map_t::value_type const& value) -> bool { - return value.second == fixed_point_t::_0(); - }); -} - -size_t ModifierValue::get_effect_count() const { - return values.size(); -} - -void ModifierValue::clear() { - values.clear(); -} - -bool ModifierValue::empty() const { - return values.empty(); -} - -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 (effect_found != nullptr) { - *effect_found = true; - } - return it->second; - } - - if (effect_found != nullptr) { - *effect_found = false; - } - return fixed_point_t::_0(); -} - -fixed_point_t ModifierValue::get_effect_nullcheck(ModifierEffect const* effect, bool* effect_found) const { - if (effect != nullptr) { - return get_effect(*effect, effect_found); - } - - if (effect_found != nullptr) { - *effect_found = false; - } - return fixed_point_t::_0(); -} - -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) { - for (effect_map_t::value_type const& value : right.values) { - values[value.first] += value.second; - } - return *this; -} - -ModifierValue ModifierValue::operator+(ModifierValue const& right) const { - ModifierValue copy = *this; - return copy += right; -} - -ModifierValue ModifierValue::operator-() const { - ModifierValue copy = *this; - for (auto value : mutable_iterator(copy.values)) { - value.second = -value.second; - } - return copy; -} - -ModifierValue& ModifierValue::operator-=(ModifierValue const& right) { - for (effect_map_t::value_type const& value : right.values) { - values[value.first] -= value.second; - } - return *this; -} - -ModifierValue ModifierValue::operator-(ModifierValue const& right) const { - 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; -} - -void ModifierValue::apply_target_filter(ModifierEffect::target_t targets) { - using enum ModifierEffect::target_t; - - erase_if( - values, - [targets](effect_map_t::value_type const& value) -> bool { - return (value.first->get_targets() & targets) == NO_TARGETS; - } - ); -} - -void ModifierValue::multiply_add_filter( - ModifierValue const& other, fixed_point_t multiplier, ModifierEffect::target_t targets -) { - using enum ModifierEffect::target_t; - - if (multiplier == fixed_point_t::_1() && targets == ALL_TARGETS) { - *this += other; - } else if (multiplier != fixed_point_t::_0() && targets != NO_TARGETS) { - for (effect_map_t::value_type const& value : other.values) { - if ((value.first->get_targets() & targets) != NO_TARGETS) { - values[value.first] += value.second * multiplier; - } - } - } -} - Modifier::Modifier(std::string_view new_identifier, ModifierValue&& new_values, modifier_type_t new_type) : HasIdentifier { new_identifier }, ModifierValue { std::move(new_values) }, type { new_type } {} @@ -205,7 +61,7 @@ bool ModifierManager::setup_modifier_effects() { ret &= add_modifier_effect("administrative_efficiency", true, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect( "administrative_efficiency_modifier", true, PROPORTION_DECIMAL, COUNTRY, - make_default_modifier_effect_localisation_key("administrative_efficiency") + ModifierEffect::make_default_modifier_effect_localisation_key("administrative_efficiency") ); ret &= add_modifier_effect("artisan_input", false, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect("artisan_output", true, PROPORTION_DECIMAL, COUNTRY); @@ -214,7 +70,7 @@ bool ModifierManager::setup_modifier_effects() { ret &= add_modifier_effect("cb_generation_speed_modifier", true, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect( "civilization_progress_modifier", true, PROPORTION_DECIMAL, COUNTRY, - make_default_modifier_effect_localisation_key("civilization_progress") + ModifierEffect::make_default_modifier_effect_localisation_key("civilization_progress") ); ret &= add_modifier_effect("colonial_life_rating", false, INT, COUNTRY, "COLONIAL_LIFE_TECH"); ret &= add_modifier_effect("colonial_migration", true, PROPORTION_DECIMAL, COUNTRY, "COLONIAL_MIGRATION_TECH"); @@ -226,12 +82,12 @@ bool ModifierManager::setup_modifier_effects() { ret &= add_modifier_effect("diplomatic_points", true, PROPORTION_DECIMAL, COUNTRY, "DIPLOMATIC_POINTS_TECH"); ret &= add_modifier_effect( "diplomatic_points_modifier", true, PROPORTION_DECIMAL, COUNTRY, - make_default_modifier_effect_localisation_key("diplopoints_gain") + ModifierEffect::make_default_modifier_effect_localisation_key("diplopoints_gain") ); ret &= add_modifier_effect("education_efficiency", true, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect( "education_efficiency_modifier", true, PROPORTION_DECIMAL, COUNTRY, - make_default_modifier_effect_localisation_key("education_efficiency") + ModifierEffect::make_default_modifier_effect_localisation_key("education_efficiency") ); ret &= add_modifier_effect("factory_cost", false, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect("factory_input", false, PROPORTION_DECIMAL, COUNTRY); @@ -241,17 +97,17 @@ bool ModifierManager::setup_modifier_effects() { ret &= add_modifier_effect("factory_throughput", true, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect( "global_assimilation_rate", true, PROPORTION_DECIMAL, COUNTRY, - make_default_modifier_effect_localisation_key("assimilation_rate") + ModifierEffect::make_default_modifier_effect_localisation_key("assimilation_rate") ); ret &= add_modifier_effect( "global_immigrant_attract", true, PROPORTION_DECIMAL, COUNTRY, - make_default_modifier_effect_localisation_key("immigant_attract") + ModifierEffect::make_default_modifier_effect_localisation_key("immigant_attract") ); ret &= add_modifier_effect("global_pop_consciousness_modifier", false, RAW_DECIMAL, COUNTRY); ret &= add_modifier_effect("global_pop_militancy_modifier", false, RAW_DECIMAL, COUNTRY); ret &= add_modifier_effect( "global_population_growth", true, PROPORTION_DECIMAL, COUNTRY, - make_default_modifier_effect_localisation_key("population_growth") + ModifierEffect::make_default_modifier_effect_localisation_key("population_growth") ); ret &= add_modifier_effect("goods_demand", false, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect("import_cost", false, PROPORTION_DECIMAL, COUNTRY); @@ -259,29 +115,30 @@ bool ModifierManager::setup_modifier_effects() { ret &= add_modifier_effect("influence", true, PROPORTION_DECIMAL, COUNTRY, "TECH_GP_INFLUENCE"); ret &= add_modifier_effect( "influence_modifier", true, PROPORTION_DECIMAL, COUNTRY, - make_default_modifier_effect_localisation_key("greatpower_influence_gain") + ModifierEffect::make_default_modifier_effect_localisation_key("greatpower_influence_gain") ); ret &= add_modifier_effect("issue_change_speed", true, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect( - "land_attack_modifier", true, PROPORTION_DECIMAL, COUNTRY, make_default_modifier_effect_localisation_key("land_attack") + "land_attack_modifier", true, PROPORTION_DECIMAL, COUNTRY, + ModifierEffect::make_default_modifier_effect_localisation_key("land_attack") ); ret &= add_modifier_effect("land_attrition", false, PROPORTION_DECIMAL, COUNTRY, "LAND_ATTRITION_TECH"); ret &= add_modifier_effect( "land_defense_modifier", true, PROPORTION_DECIMAL, COUNTRY, - make_default_modifier_effect_localisation_key("land_defense") + ModifierEffect::make_default_modifier_effect_localisation_key("land_defense") ); ret &= add_modifier_effect("land_organisation", true, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect("land_unit_start_experience", true, RAW_DECIMAL, COUNTRY); ret &= add_modifier_effect("leadership", true, RAW_DECIMAL, COUNTRY, "LEADERSHIP"); ret &= add_modifier_effect( "leadership_modifier", true, PROPORTION_DECIMAL, COUNTRY, - make_default_modifier_effect_localisation_key("global_leadership_modifier") + ModifierEffect::make_default_modifier_effect_localisation_key("global_leadership_modifier") ); ret &= add_modifier_effect("literacy_con_impact", false, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect("loan_interest", false, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect( "max_loan_modifier", true, PROPORTION_DECIMAL, COUNTRY, - make_default_modifier_effect_localisation_key("max_loan_amount") + ModifierEffect::make_default_modifier_effect_localisation_key("max_loan_amount") ); ret &= add_modifier_effect("max_military_spending", true, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect("max_national_focus", true, INT, COUNTRY, "TECH_MAX_FOCUS"); @@ -295,19 +152,20 @@ bool ModifierManager::setup_modifier_effects() { ret &= add_modifier_effect("min_tariff", true, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect("min_tax", true, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect( - "minimum_wage", true, PROPORTION_DECIMAL, COUNTRY, make_default_modifier_effect_localisation_key("minimun_wage") + "minimum_wage", true, PROPORTION_DECIMAL, COUNTRY, + ModifierEffect::make_default_modifier_effect_localisation_key("minimun_wage") ); ret &= add_modifier_effect("mobilisation_economy_impact", false, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect("mobilisation_size", true, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect("mobilization_impact", false, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect( "naval_attack_modifier", true, PROPORTION_DECIMAL, COUNTRY, - make_default_modifier_effect_localisation_key("naval_attack") + ModifierEffect::make_default_modifier_effect_localisation_key("naval_attack") ); ret &= add_modifier_effect("naval_attrition", false, PROPORTION_DECIMAL, COUNTRY, "NAVAL_ATTRITION_TECH"); ret &= add_modifier_effect( "naval_defense_modifier", true, PROPORTION_DECIMAL, COUNTRY, - make_default_modifier_effect_localisation_key("naval_defense") + ModifierEffect::make_default_modifier_effect_localisation_key("naval_defense") ); ret &= add_modifier_effect("naval_organisation", true, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect("naval_unit_start_experience", true, RAW_DECIMAL, COUNTRY); @@ -328,11 +186,11 @@ bool ModifierManager::setup_modifier_effects() { ret &= add_modifier_effect("ruling_party_support", true, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect( "self_unciv_economic_modifier", false, PROPORTION_DECIMAL, COUNTRY, - make_default_modifier_effect_localisation_key("self_unciv_economic") + ModifierEffect::make_default_modifier_effect_localisation_key("self_unciv_economic") ); ret &= add_modifier_effect( "self_unciv_military_modifier", false, PROPORTION_DECIMAL, COUNTRY, - make_default_modifier_effect_localisation_key("self_unciv_military") + ModifierEffect::make_default_modifier_effect_localisation_key("self_unciv_military") ); ret &= add_modifier_effect("social_reform_desire", false, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect("soldier_to_pop_loss", true, PROPORTION_DECIMAL, COUNTRY, "SOLDIER_TO_POP_LOSS_TECH"); @@ -341,17 +199,17 @@ bool ModifierManager::setup_modifier_effects() { ret &= add_modifier_effect("suppression_points_modifier", true, PROPORTION_DECIMAL, COUNTRY, "SUPPRESSION_TECH"); ret &= add_modifier_effect( "tariff_efficiency_modifier", true, PROPORTION_DECIMAL, COUNTRY, - make_default_modifier_effect_localisation_key("tariff_efficiency") + ModifierEffect::make_default_modifier_effect_localisation_key("tariff_efficiency") ); ret &= add_modifier_effect("tax_efficiency", true, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect("unemployment_benefit", true, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect( "unciv_economic_modifier", false, PROPORTION_DECIMAL, COUNTRY, - make_default_modifier_effect_localisation_key("unciv_economic") + ModifierEffect::make_default_modifier_effect_localisation_key("unciv_economic") ); ret &= add_modifier_effect( "unciv_military_modifier", false, PROPORTION_DECIMAL, COUNTRY, - make_default_modifier_effect_localisation_key("unciv_military") + ModifierEffect::make_default_modifier_effect_localisation_key("unciv_military") ); ret &= add_modifier_effect("unit_recruitment_time", false, PROPORTION_DECIMAL, COUNTRY); ret &= add_modifier_effect("war_exhaustion", false, PROPORTION_DECIMAL, COUNTRY, "WAR_EXHAUST_BATTLES"); @@ -361,57 +219,61 @@ bool ModifierManager::setup_modifier_effects() { ret &= add_modifier_effect("boost_strongest_party", false, PROPORTION_DECIMAL, PROVINCE); ret &= add_modifier_effect("farm_rgo_eff", true, PROPORTION_DECIMAL, PROVINCE, "TECH_FARM_OUTPUT"); ret &= add_modifier_effect( - "farm_rgo_size", true, PROPORTION_DECIMAL, PROVINCE, make_default_modifier_effect_localisation_key("farm_size") + "farm_rgo_size", true, PROPORTION_DECIMAL, PROVINCE, + ModifierEffect::make_default_modifier_effect_localisation_key("farm_size") ); ret &= add_modifier_effect( "immigrant_attract", true, PROPORTION_DECIMAL, PROVINCE, - make_default_modifier_effect_localisation_key("immigant_attract") + ModifierEffect::make_default_modifier_effect_localisation_key("immigant_attract") ); ret &= add_modifier_effect( - "immigrant_push", false, PROPORTION_DECIMAL, PROVINCE, make_default_modifier_effect_localisation_key("immigant_push") + "immigrant_push", false, PROPORTION_DECIMAL, PROVINCE, + ModifierEffect::make_default_modifier_effect_localisation_key("immigant_push") ); ret &= add_modifier_effect("life_rating", true, PROPORTION_DECIMAL, PROVINCE); ret &= add_modifier_effect( "local_artisan_input", false, PROPORTION_DECIMAL, PROVINCE, - make_default_modifier_effect_localisation_key("artisan_input") + ModifierEffect::make_default_modifier_effect_localisation_key("artisan_input") ); ret &= add_modifier_effect( "local_artisan_output", true, PROPORTION_DECIMAL, PROVINCE, - make_default_modifier_effect_localisation_key("artisan_output") + ModifierEffect::make_default_modifier_effect_localisation_key("artisan_output") ); ret &= add_modifier_effect( "local_artisan_throughput", true, PROPORTION_DECIMAL, PROVINCE, - make_default_modifier_effect_localisation_key("artisan_throughput") + ModifierEffect::make_default_modifier_effect_localisation_key("artisan_throughput") ); ret &= add_modifier_effect( "local_factory_input", false, PROPORTION_DECIMAL, PROVINCE, - make_default_modifier_effect_localisation_key("factory_input") + ModifierEffect::make_default_modifier_effect_localisation_key("factory_input") ); ret &= add_modifier_effect( "local_factory_output", true, PROPORTION_DECIMAL, PROVINCE, - make_default_modifier_effect_localisation_key("factory_output") + ModifierEffect::make_default_modifier_effect_localisation_key("factory_output") ); ret &= add_modifier_effect( "local_factory_throughput", true, PROPORTION_DECIMAL, PROVINCE, - make_default_modifier_effect_localisation_key("factory_throughput") + ModifierEffect::make_default_modifier_effect_localisation_key("factory_throughput") ); ret &= add_modifier_effect("local_repair", true, PROPORTION_DECIMAL, PROVINCE); ret &= add_modifier_effect( - "local_rgo_output", true, PROPORTION_DECIMAL, PROVINCE, make_default_modifier_effect_localisation_key("rgo_output") + "local_rgo_output", true, PROPORTION_DECIMAL, PROVINCE, + ModifierEffect::make_default_modifier_effect_localisation_key("rgo_output") ); ret &= add_modifier_effect( "local_rgo_throughput", true, PROPORTION_DECIMAL, PROVINCE, - make_default_modifier_effect_localisation_key("rgo_throughput") + ModifierEffect::make_default_modifier_effect_localisation_key("rgo_throughput") ); ret &= add_modifier_effect( "local_ruling_party_support", true, PROPORTION_DECIMAL, PROVINCE, - make_default_modifier_effect_localisation_key("ruling_party_support") + ModifierEffect::make_default_modifier_effect_localisation_key("ruling_party_support") ); ret &= add_modifier_effect("local_ship_build", false, PROPORTION_DECIMAL, PROVINCE); ret &= add_modifier_effect("max_attrition", false, RAW_DECIMAL, PROVINCE); ret &= add_modifier_effect("mine_rgo_eff", true, PROPORTION_DECIMAL, PROVINCE, "TECH_MINE_OUTPUT"); ret &= add_modifier_effect( - "mine_rgo_size", true, PROPORTION_DECIMAL, PROVINCE, make_default_modifier_effect_localisation_key("mine_size") + "mine_rgo_size", true, PROPORTION_DECIMAL, PROVINCE, + ModifierEffect::make_default_modifier_effect_localisation_key("mine_size") ); ret &= add_modifier_effect("movement_cost", false, PROPORTION_DECIMAL, PROVINCE); ret &= add_modifier_effect("number_of_voters", false, PROPORTION_DECIMAL, PROVINCE); diff --git a/src/openvic-simulation/modifier/Modifier.hpp b/src/openvic-simulation/modifier/Modifier.hpp index f52f126..28e56cd 100644 --- a/src/openvic-simulation/modifier/Modifier.hpp +++ b/src/openvic-simulation/modifier/Modifier.hpp @@ -1,94 +1,12 @@ #pragma once +#include "openvic-simulation/modifier/ModifierEffect.hpp" +#include "openvic-simulation/modifier/ModifierValue.hpp" #include "openvic-simulation/modifier/StaticModifierCache.hpp" #include "openvic-simulation/scripts/ConditionScript.hpp" #include "openvic-simulation/types/IdentifierRegistry.hpp" namespace OpenVic { - struct ModifierManager; - - struct ModifierEffect : HasIdentifier { - friend struct ModifierManager; - - enum class format_t : uint8_t { - PROPORTION_DECIMAL, /* An unscaled fraction/ratio, with 1 being "full"/"whole" */ - PERCENTAGE_DECIMAL, /* A fraction/ratio scaled so that 100 is "full"/"whole" */ - RAW_DECIMAL, /* A continuous quantity, e.g. attack strength */ - INT /* A discrete quantity, e.g. building count limit */ - }; - - enum class target_t : uint8_t { - NO_TARGETS = 0, - COUNTRY = 1 << 0, - PROVINCE = 1 << 1, - UNIT = 1 << 2, - ALL_TARGETS = (1 << 3) - 1 - }; - - private: - /* If true, positive values will be green and negative values will be red. - * If false, the colours will be switced. - */ - const bool PROPERTY_CUSTOM_PREFIX(positive_good, is); - const format_t PROPERTY(format); - const target_t PROPERTY(targets); - std::string PROPERTY(localisation_key); - - // TODO - format/precision, e.g. 80% vs 0.8 vs 0.800, 2 vs 2.0 vs 200% - - ModifierEffect( - std::string_view new_identifier, bool new_positive_good, format_t new_format, target_t mew_targets, - std::string_view new_localisation_key - ); - - public: - ModifierEffect(ModifierEffect&&) = default; - }; - - template<> struct enable_bitfield : std::true_type {}; - - struct ModifierValue { - friend struct ModifierManager; - - using effect_map_t = fixed_point_map_t; - - private: - effect_map_t PROPERTY(values); - - public: - ModifierValue(); - ModifierValue(effect_map_t&& new_values); - ModifierValue(ModifierValue const&); - ModifierValue(ModifierValue&&); - - ModifierValue& operator=(ModifierValue const&); - ModifierValue& operator=(ModifierValue&&); - - /* Removes effect entries with a value of zero. */ - void trim(); - size_t get_effect_count() const; - void clear(); - bool empty() const; - - fixed_point_t get_effect(ModifierEffect const& effect, bool* effect_found = nullptr) const; - fixed_point_t get_effect_nullcheck(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; - - void apply_target_filter(ModifierEffect::target_t targets); - void multiply_add_filter(ModifierValue const& other, fixed_point_t multiplier, ModifierEffect::target_t targets); - - friend std::ostream& operator<<(std::ostream& stream, ModifierValue const& value); - }; - struct Modifier : HasIdentifier, ModifierValue { friend struct ModifierManager; diff --git a/src/openvic-simulation/modifier/ModifierEffect.cpp b/src/openvic-simulation/modifier/ModifierEffect.cpp new file mode 100644 index 0000000..8daf563 --- /dev/null +++ b/src/openvic-simulation/modifier/ModifierEffect.cpp @@ -0,0 +1,17 @@ +#include "ModifierEffect.hpp" + +#include "openvic-simulation/utility/StringUtils.hpp" + +using namespace OpenVic; + +std::string ModifierEffect::make_default_modifier_effect_localisation_key(std::string_view identifier) { + return "MODIFIER_" + StringUtils::string_toupper(identifier); +} + +ModifierEffect::ModifierEffect( + std::string_view new_identifier, bool new_positive_good, format_t new_format, target_t new_targets, + std::string_view new_localisation_key +) : HasIdentifier { new_identifier }, positive_good { new_positive_good }, format { new_format }, targets { new_targets }, + localisation_key { + new_localisation_key.empty() ? make_default_modifier_effect_localisation_key(new_identifier) : new_localisation_key + } {} diff --git a/src/openvic-simulation/modifier/ModifierEffect.hpp b/src/openvic-simulation/modifier/ModifierEffect.hpp new file mode 100644 index 0000000..8eac65b --- /dev/null +++ b/src/openvic-simulation/modifier/ModifierEffect.hpp @@ -0,0 +1,53 @@ +#pragma once + +#include +#include + +#include "openvic-simulation/types/EnumBitfield.hpp" +#include "openvic-simulation/types/HasIdentifier.hpp" + +namespace OpenVic { + struct ModifierManager; + + struct ModifierEffect : HasIdentifier { + friend struct ModifierManager; + + enum class format_t : uint8_t { + PROPORTION_DECIMAL, /* An unscaled fraction/ratio, with 1 being "full"/"whole" */ + PERCENTAGE_DECIMAL, /* A fraction/ratio scaled so that 100 is "full"/"whole" */ + RAW_DECIMAL, /* A continuous quantity, e.g. attack strength */ + INT /* A discrete quantity, e.g. building count limit */ + }; + + enum class target_t : uint8_t { + NO_TARGETS = 0, + COUNTRY = 1 << 0, + PROVINCE = 1 << 1, + UNIT = 1 << 2, + ALL_TARGETS = (1 << 3) - 1 + }; + + static std::string make_default_modifier_effect_localisation_key(std::string_view identifier); + + private: + /* If true, positive values will be green and negative values will be red. + * If false, the colours will be switced. + */ + const bool PROPERTY_CUSTOM_PREFIX(positive_good, is); + const format_t PROPERTY(format); + const target_t PROPERTY(targets); + std::string PROPERTY(localisation_key); + + // TODO - format/precision, e.g. 80% vs 0.8 vs 0.800, 2 vs 2.0 vs 200% + + ModifierEffect( + std::string_view new_identifier, bool new_positive_good, format_t new_format, target_t mew_targets, + std::string_view new_localisation_key + ); + + public: + ModifierEffect(ModifierEffect&&) = default; + }; + + template<> struct enable_bitfield : std::true_type {}; +} diff --git a/src/openvic-simulation/modifier/ModifierSum.cpp b/src/openvic-simulation/modifier/ModifierSum.cpp index 4051d64..09cb36d 100644 --- a/src/openvic-simulation/modifier/ModifierSum.cpp +++ b/src/openvic-simulation/modifier/ModifierSum.cpp @@ -1,5 +1,7 @@ #include "ModifierSum.hpp" +#include "openvic-simulation/modifier/Modifier.hpp" + using namespace OpenVic; void ModifierSum::clear() { diff --git a/src/openvic-simulation/modifier/ModifierSum.hpp b/src/openvic-simulation/modifier/ModifierSum.hpp index 406c52b..0ca8caa 100644 --- a/src/openvic-simulation/modifier/ModifierSum.hpp +++ b/src/openvic-simulation/modifier/ModifierSum.hpp @@ -2,12 +2,13 @@ #include -#include "openvic-simulation/modifier/Modifier.hpp" +#include "openvic-simulation/modifier/ModifierValue.hpp" #include "openvic-simulation/types/fixed_point/FixedPoint.hpp" namespace OpenVic { struct CountryInstance; struct ProvinceInstance; + struct Modifier; struct ModifierSum { using modifier_source_t = std::variant; diff --git a/src/openvic-simulation/modifier/ModifierValue.cpp b/src/openvic-simulation/modifier/ModifierValue.cpp new file mode 100644 index 0000000..51d41bc --- /dev/null +++ b/src/openvic-simulation/modifier/ModifierValue.cpp @@ -0,0 +1,136 @@ +#include "ModifierValue.hpp" + +#include "openvic-simulation/utility/TslHelper.hpp" + +using namespace OpenVic; + +ModifierValue::ModifierValue() = default; +ModifierValue::ModifierValue(effect_map_t&& new_values) : values { std::move(new_values) } {} +ModifierValue::ModifierValue(ModifierValue const&) = default; +ModifierValue::ModifierValue(ModifierValue&&) = default; + +ModifierValue& ModifierValue::operator=(ModifierValue const&) = default; +ModifierValue& ModifierValue::operator=(ModifierValue&&) = default; + +void ModifierValue::trim() { + erase_if(values, [](effect_map_t::value_type const& value) -> bool { + return value.second == fixed_point_t::_0(); + }); +} + +size_t ModifierValue::get_effect_count() const { + return values.size(); +} + +void ModifierValue::clear() { + values.clear(); +} + +bool ModifierValue::empty() const { + return values.empty(); +} + +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 (effect_found != nullptr) { + *effect_found = true; + } + return it->second; + } + + if (effect_found != nullptr) { + *effect_found = false; + } + return fixed_point_t::_0(); +} + +fixed_point_t ModifierValue::get_effect_nullcheck(ModifierEffect const* effect, bool* effect_found) const { + if (effect != nullptr) { + return get_effect(*effect, effect_found); + } + + if (effect_found != nullptr) { + *effect_found = false; + } + return fixed_point_t::_0(); +} + +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) { + for (effect_map_t::value_type const& value : right.values) { + values[value.first] += value.second; + } + return *this; +} + +ModifierValue ModifierValue::operator+(ModifierValue const& right) const { + ModifierValue copy = *this; + return copy += right; +} + +ModifierValue ModifierValue::operator-() const { + ModifierValue copy = *this; + for (auto value : mutable_iterator(copy.values)) { + value.second = -value.second; + } + return copy; +} + +ModifierValue& ModifierValue::operator-=(ModifierValue const& right) { + for (effect_map_t::value_type const& value : right.values) { + values[value.first] -= value.second; + } + return *this; +} + +ModifierValue ModifierValue::operator-(ModifierValue const& right) const { + 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; +} + +void ModifierValue::apply_target_filter(ModifierEffect::target_t targets) { + using enum ModifierEffect::target_t; + + erase_if( + values, + [targets](effect_map_t::value_type const& value) -> bool { + return (value.first->get_targets() & targets) == NO_TARGETS; + } + ); +} + +void ModifierValue::multiply_add_filter( + ModifierValue const& other, fixed_point_t multiplier, ModifierEffect::target_t targets +) { + using enum ModifierEffect::target_t; + + if (multiplier == fixed_point_t::_1() && targets == ALL_TARGETS) { + *this += other; + } else if (multiplier != fixed_point_t::_0() && targets != NO_TARGETS) { + for (effect_map_t::value_type const& value : other.values) { + if ((value.first->get_targets() & targets) != NO_TARGETS) { + values[value.first] += value.second * multiplier; + } + } + } +} diff --git a/src/openvic-simulation/modifier/ModifierValue.hpp b/src/openvic-simulation/modifier/ModifierValue.hpp new file mode 100644 index 0000000..23c0ba5 --- /dev/null +++ b/src/openvic-simulation/modifier/ModifierValue.hpp @@ -0,0 +1,48 @@ +#pragma once + +#include "openvic-simulation/modifier/ModifierEffect.hpp" +#include "openvic-simulation/types/fixed_point/FixedPointMap.hpp" + +namespace OpenVic { + struct ModifierValue { + friend struct ModifierManager; + + using effect_map_t = fixed_point_map_t; + + private: + effect_map_t PROPERTY(values); + + public: + ModifierValue(); + ModifierValue(effect_map_t&& new_values); + ModifierValue(ModifierValue const&); + ModifierValue(ModifierValue&&); + + ModifierValue& operator=(ModifierValue const&); + ModifierValue& operator=(ModifierValue&&); + + /* Removes effect entries with a value of zero. */ + void trim(); + size_t get_effect_count() const; + void clear(); + bool empty() const; + + fixed_point_t get_effect(ModifierEffect const& effect, bool* effect_found = nullptr) const; + fixed_point_t get_effect_nullcheck(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; + + void apply_target_filter(ModifierEffect::target_t targets); + void multiply_add_filter(ModifierValue const& other, fixed_point_t multiplier, ModifierEffect::target_t targets); + + friend std::ostream& operator<<(std::ostream& stream, ModifierValue const& value); + }; +} diff --git a/src/openvic-simulation/politics/Rebel.cpp b/src/openvic-simulation/politics/Rebel.cpp index 395df49..ea443db 100644 --- a/src/openvic-simulation/politics/Rebel.cpp +++ b/src/openvic-simulation/politics/Rebel.cpp @@ -2,6 +2,8 @@ #include +#include "openvic-simulation/modifier/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 fc82c84..b47bcbb 100644 --- a/src/openvic-simulation/politics/Rebel.hpp +++ b/src/openvic-simulation/politics/Rebel.hpp @@ -2,7 +2,6 @@ #include -#include "openvic-simulation/modifier/Modifier.hpp" #include "openvic-simulation/politics/Government.hpp" #include "openvic-simulation/politics/Ideology.hpp" #include "openvic-simulation/scripts/ConditionalWeight.hpp" @@ -79,6 +78,8 @@ namespace OpenVic { RebelType(RebelType&&) = default; }; + struct ModifierManager; + struct RebelManager { private: IdentifierRegistry IDENTIFIER_REGISTRY(rebel_type); -- cgit v1.2.3-56-ga3b1 From 6181851281876730d7db4bed18791fdbbe3cfbbc Mon Sep 17 00:00:00 2001 From: hop311 Date: Sun, 6 Oct 2024 00:08:44 +0100 Subject: Add alternative modifier calculation (keeping country modifiers out of their owned provinces' modifier sums) --- src/openvic-simulation/InstanceManager.cpp | 28 ++++++++-- src/openvic-simulation/country/CountryInstance.cpp | 39 +++++++++---- src/openvic-simulation/country/CountryInstance.hpp | 5 ++ src/openvic-simulation/map/ProvinceInstance.cpp | 65 +++++++++++++++++++++- src/openvic-simulation/map/ProvinceInstance.hpp | 11 +++- src/openvic-simulation/modifier/ModifierSum.cpp | 17 ++++-- src/openvic-simulation/modifier/ModifierSum.hpp | 1 + 7 files changed, 142 insertions(+), 24 deletions(-) (limited to 'src/openvic-simulation/modifier/ModifierSum.cpp') diff --git a/src/openvic-simulation/InstanceManager.cpp b/src/openvic-simulation/InstanceManager.cpp index 9c7804c..a33acdb 100644 --- a/src/openvic-simulation/InstanceManager.cpp +++ b/src/openvic-simulation/InstanceManager.cpp @@ -39,10 +39,30 @@ void InstanceManager::update_gamestate() { Logger::info("Update: ", today); - map_instance.update_modifier_sums(today, definition_manager.get_modifier_manager().get_static_modifier_cache()); - country_instance_manager.update_modifier_sums( - today, definition_manager.get_modifier_manager().get_static_modifier_cache() - ); + if constexpr (ProvinceInstance::ADD_OWNER_CONTRIBUTION) { + // Calculate local province modifier sums first, then national country modifier sums, then loop over owned provinces + // adding their contributions to the owner country's modifier sum and loop over them again to add the country's total + // (including province contributions) to the provinces' modifier sum. This results in every country and province + // having a full copy of all the modifiers affecting them in their modifier sum. + map_instance.update_modifier_sums( + today, definition_manager.get_modifier_manager().get_static_modifier_cache() + ); + country_instance_manager.update_modifier_sums( + today, definition_manager.get_modifier_manager().get_static_modifier_cache() + ); + } else { + // Calculate national country modifier sums first, then local province modifier sums, adding province contributions + // to owner countries' modifier sums if each province has an owner. This results in every country having a full copy + // of all the modifiers affecting them in their modifier sum, but provinces only having their directly/locally applied + // modifiers in their modifier sum, hence requiring both province and owner country modifier effect values to be looked + // up and added together to get the full effect on the province. + country_instance_manager.update_modifier_sums( + today, definition_manager.get_modifier_manager().get_static_modifier_cache() + ); + map_instance.update_modifier_sums( + today, definition_manager.get_modifier_manager().get_static_modifier_cache() + ); + } // Update gamestate... map_instance.update_gamestate(today, definition_manager.get_define_manager()); diff --git a/src/openvic-simulation/country/CountryInstance.cpp b/src/openvic-simulation/country/CountryInstance.cpp index be62fda..f04dfc6 100644 --- a/src/openvic-simulation/country/CountryInstance.cpp +++ b/src/openvic-simulation/country/CountryInstance.cpp @@ -1007,23 +1007,30 @@ void CountryInstance::update_modifier_sum(Date today, StaticModifierCache const& } } - // Add province base modifiers (with local province modifier effects removed) - using enum ModifierEffect::target_t; - static constexpr ModifierEffect::target_t NOT_PROVINCE = ALL_TARGETS & ~PROVINCE; - - for (ProvinceInstance const* province : owned_provinces) { - modifier_sum.add_modifier_sum_filter_targets(province->get_modifier_sum(), NOT_PROVINCE); - } + if constexpr (ProvinceInstance::ADD_OWNER_CONTRIBUTION) { + // Add province base modifiers (with local province modifier effects removed) + for (ProvinceInstance const* province : owned_provinces) { + contribute_province_modifier_sum(province->get_modifier_sum()); + } - // This has to be done after adding all province modifiers to the country's sum, otherwise provinces earlier in the list - // wouldn't be affected by modifiers from provinces later in the list. - for (ProvinceInstance* province : owned_provinces) { - province->contribute_country_modifier_sum(modifier_sum); + // This has to be done after adding all province modifiers to the country's sum, otherwise provinces + // earlier in the list wouldn't be affected by modifiers from provinces later in the list. + for (ProvinceInstance* province : owned_provinces) { + province->contribute_country_modifier_sum(modifier_sum); + } } // TODO - calculate stats for each unit type (locked and unlocked) } +void CountryInstance::contribute_province_modifier_sum(ModifierSum const& province_modifier_sum) { + using enum ModifierEffect::target_t; + + static constexpr ModifierEffect::target_t NOT_PROVINCE = ALL_TARGETS & ~PROVINCE; + + modifier_sum.add_modifier_sum_filter_targets(province_modifier_sum, NOT_PROVINCE); +} + fixed_point_t CountryInstance::get_modifier_effect_value(ModifierEffect const& effect) const { return modifier_sum.get_effect(effect); } @@ -1032,6 +1039,16 @@ fixed_point_t CountryInstance::get_modifier_effect_value_nullcheck(ModifierEffec return modifier_sum.get_effect_nullcheck(effect); } +void CountryInstance::push_contributing_modifiers( + ModifierEffect const& effect, std::vector& contributions +) const { + modifier_sum.push_contributing_modifiers(effect, contributions); +} + +std::vector CountryInstance::get_contributing_modifiers(ModifierEffect const& effect) const { + return modifier_sum.get_contributing_modifiers(effect); +} + void CountryInstance::update_gamestate( DefineManager const& define_manager, UnitTypeManager const& unit_type_manager, ModifierEffectCache const& modifier_effect_cache diff --git a/src/openvic-simulation/country/CountryInstance.hpp b/src/openvic-simulation/country/CountryInstance.hpp index 8a5d234..5e42f1d 100644 --- a/src/openvic-simulation/country/CountryInstance.hpp +++ b/src/openvic-simulation/country/CountryInstance.hpp @@ -305,8 +305,13 @@ namespace OpenVic { public: void update_modifier_sum(Date today, StaticModifierCache const& static_modifier_cache); + void contribute_province_modifier_sum(ModifierSum const& province_modifier_sum); fixed_point_t get_modifier_effect_value(ModifierEffect const& effect) const; fixed_point_t get_modifier_effect_value_nullcheck(ModifierEffect const* effect) const; + void push_contributing_modifiers( + ModifierEffect const& effect, std::vector& contributions + ) const; + std::vector get_contributing_modifiers(ModifierEffect const& effect) const; void update_gamestate( DefineManager const& define_manager, UnitTypeManager const& unit_type_manager, diff --git a/src/openvic-simulation/map/ProvinceInstance.cpp b/src/openvic-simulation/map/ProvinceInstance.cpp index e85c576..949a2a3 100644 --- a/src/openvic-simulation/map/ProvinceInstance.cpp +++ b/src/openvic-simulation/map/ProvinceInstance.cpp @@ -235,6 +235,12 @@ void ProvinceInstance::update_modifier_sum(Date today, StaticModifierCache const modifier_sum.add_modifier_nullcheck(province_definition.get_climate(), province_source); modifier_sum.add_modifier_nullcheck(terrain_type, province_source); + + if constexpr (!ADD_OWNER_CONTRIBUTION) { + if (owner != nullptr) { + owner->contribute_province_modifier_sum(modifier_sum); + } + } } void ProvinceInstance::contribute_country_modifier_sum(ModifierSum const& owner_modifier_sum) { @@ -242,11 +248,66 @@ void ProvinceInstance::contribute_country_modifier_sum(ModifierSum const& owner_ } fixed_point_t ProvinceInstance::get_modifier_effect_value(ModifierEffect const& effect) const { - return modifier_sum.get_effect(effect); + if constexpr (ADD_OWNER_CONTRIBUTION) { + return modifier_sum.get_effect(effect); + } else { + using enum ModifierEffect::target_t; + + if (owner != nullptr) { + if ((effect.get_targets() & PROVINCE) == NO_TARGETS) { + // Non-province targeted effects are already added to the country modifier sum + return owner->get_modifier_effect_value(effect); + } else { + // Province-targeted effects aren't passed to the country modifier sum + return owner->get_modifier_effect_value(effect) + modifier_sum.get_effect(effect); + } + } else { + return modifier_sum.get_effect(effect); + } + } } fixed_point_t ProvinceInstance::get_modifier_effect_value_nullcheck(ModifierEffect const* effect) const { - return modifier_sum.get_effect_nullcheck(effect); + if (effect != nullptr) { + return get_modifier_effect_value(*effect); + } else { + return fixed_point_t::_0(); + } +} + +void ProvinceInstance::push_contributing_modifiers( + ModifierEffect const& effect, std::vector& contributions +) const { + if constexpr (ADD_OWNER_CONTRIBUTION) { + modifier_sum.push_contributing_modifiers(effect, contributions); + } else { + using enum ModifierEffect::target_t; + + if (owner != nullptr) { + if ((effect.get_targets() & PROVINCE) == NO_TARGETS) { + // Non-province targeted effects are already added to the country modifier sum + owner->push_contributing_modifiers(effect, contributions); + } else { + // Province-targeted effects aren't passed to the country modifier sum + modifier_sum.push_contributing_modifiers(effect, contributions); + owner->push_contributing_modifiers(effect, contributions); + } + } else { + modifier_sum.push_contributing_modifiers(effect, contributions); + } + } +} + +std::vector ProvinceInstance::get_contributing_modifiers(ModifierEffect const& effect) const { + if constexpr (ADD_OWNER_CONTRIBUTION) { + return modifier_sum.get_contributing_modifiers(effect); + } else { + std::vector contributions; + + push_contributing_modifiers(effect, contributions); + + return contributions; + } } void ProvinceInstance::update_gamestate(Date today, DefineManager const& define_manager) { diff --git a/src/openvic-simulation/map/ProvinceInstance.hpp b/src/openvic-simulation/map/ProvinceInstance.hpp index 0b02c41..91e8ee1 100644 --- a/src/openvic-simulation/map/ProvinceInstance.hpp +++ b/src/openvic-simulation/map/ProvinceInstance.hpp @@ -69,7 +69,12 @@ namespace OpenVic { CountryInstance* PROPERTY(controller); ordered_set PROPERTY(cores); - // The total/resultant modifier affecting this province, including owner country contributions. + public: + static constexpr bool ADD_OWNER_CONTRIBUTION = true; + + private: + // The total/resultant modifier affecting this province, including owner country contributions if + // ADD_OWNER_CONTRIBUTION is true. ModifierSum PROPERTY(modifier_sum); std::vector PROPERTY(event_modifiers); @@ -133,6 +138,10 @@ namespace OpenVic { void contribute_country_modifier_sum(ModifierSum const& owner_modifier_sum); fixed_point_t get_modifier_effect_value(ModifierEffect const& effect) const; fixed_point_t get_modifier_effect_value_nullcheck(ModifierEffect const* effect) const; + void push_contributing_modifiers( + ModifierEffect const& effect, std::vector& contributions + ) const; + std::vector get_contributing_modifiers(ModifierEffect const& effect) const; void update_gamestate(Date today, DefineManager const& define_manager); void tick(Date today); diff --git a/src/openvic-simulation/modifier/ModifierSum.cpp b/src/openvic-simulation/modifier/ModifierSum.cpp index 09cb36d..a3b8cd5 100644 --- a/src/openvic-simulation/modifier/ModifierSum.cpp +++ b/src/openvic-simulation/modifier/ModifierSum.cpp @@ -70,23 +70,28 @@ void ModifierSum::add_modifier_sum_exclude_source(ModifierSum const& modifier_su } // TODO - include value_sum[effect] in result? Early return if lookup in value_sum fails? -std::vector ModifierSum::get_contributing_modifiers( - ModifierEffect const& effect + +void ModifierSum::push_contributing_modifiers( + ModifierEffect const& effect, std::vector& contributions ) const { using enum ModifierEffect::target_t; - std::vector ret; - for (modifier_entry_t const& modifier_entry : modifiers) { if ((modifier_entry.targets & effect.get_targets()) != NO_TARGETS) { bool effect_found = false; const fixed_point_t value = modifier_entry.modifier->get_effect(effect, &effect_found); if (effect_found) { - ret.push_back(modifier_entry); + contributions.push_back(modifier_entry); } } } +} + +std::vector ModifierSum::get_contributing_modifiers(ModifierEffect const& effect) const { + std::vector contributions; + + push_contributing_modifiers(effect, contributions); - return ret; + return contributions; } diff --git a/src/openvic-simulation/modifier/ModifierSum.hpp b/src/openvic-simulation/modifier/ModifierSum.hpp index 0ca8caa..7c1b238 100644 --- a/src/openvic-simulation/modifier/ModifierSum.hpp +++ b/src/openvic-simulation/modifier/ModifierSum.hpp @@ -55,6 +55,7 @@ namespace OpenVic { void add_modifier_sum_filter_targets(ModifierSum const& modifier_sum, ModifierEffect::target_t 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& contributions) const; std::vector get_contributing_modifiers(ModifierEffect const& effect) const; }; } -- cgit v1.2.3-56-ga3b1 From 35909d6e79d524f19f9b69dffd02fcf162be5093 Mon Sep 17 00:00:00 2001 From: hop311 Date: Sat, 19 Oct 2024 11:31:40 +0100 Subject: Switch to excluding given modifier effect targets rather than using a positive filter --- src/openvic-simulation/country/CountryInstance.cpp | 4 +- src/openvic-simulation/map/ProvinceInstance.cpp | 4 +- src/openvic-simulation/modifier/ModifierEffect.cpp | 32 ++++++++++++ src/openvic-simulation/modifier/ModifierEffect.hpp | 10 ++++ .../modifier/ModifierManager.cpp | 7 +++ src/openvic-simulation/modifier/ModifierSum.cpp | 58 ++++++++++++++++------ src/openvic-simulation/modifier/ModifierSum.hpp | 30 ++++++++--- src/openvic-simulation/modifier/ModifierValue.cpp | 20 +++++--- src/openvic-simulation/modifier/ModifierValue.hpp | 6 ++- 9 files changed, 133 insertions(+), 38 deletions(-) (limited to 'src/openvic-simulation/modifier/ModifierSum.cpp') diff --git a/src/openvic-simulation/country/CountryInstance.cpp b/src/openvic-simulation/country/CountryInstance.cpp index aceae11..417ca0a 100644 --- a/src/openvic-simulation/country/CountryInstance.cpp +++ b/src/openvic-simulation/country/CountryInstance.cpp @@ -1028,9 +1028,7 @@ void CountryInstance::update_modifier_sum(Date today, StaticModifierCache const& void CountryInstance::contribute_province_modifier_sum(ModifierSum const& province_modifier_sum) { using enum ModifierEffect::target_t; - static constexpr ModifierEffect::target_t NOT_PROVINCE = ALL_TARGETS & ~PROVINCE; - - modifier_sum.add_modifier_sum_filter_targets(province_modifier_sum, NOT_PROVINCE); + modifier_sum.add_modifier_sum_exclude_targets(province_modifier_sum, PROVINCE); } fixed_point_t CountryInstance::get_modifier_effect_value(ModifierEffect const& effect) const { diff --git a/src/openvic-simulation/map/ProvinceInstance.cpp b/src/openvic-simulation/map/ProvinceInstance.cpp index 57a33a4..236efd2 100644 --- a/src/openvic-simulation/map/ProvinceInstance.cpp +++ b/src/openvic-simulation/map/ProvinceInstance.cpp @@ -255,7 +255,7 @@ fixed_point_t ProvinceInstance::get_modifier_effect_value(ModifierEffect const& using enum ModifierEffect::target_t; if (owner != nullptr) { - if ((effect.get_targets() & PROVINCE) == NO_TARGETS) { + if (ModifierEffect::excludes_targets(effect.get_targets(), PROVINCE)) { // Non-province targeted effects are already added to the country modifier sum return owner->get_modifier_effect_value(effect); } else { @@ -285,7 +285,7 @@ void ProvinceInstance::push_contributing_modifiers( using enum ModifierEffect::target_t; if (owner != nullptr) { - if ((effect.get_targets() & PROVINCE) == NO_TARGETS) { + if (ModifierEffect::excludes_targets(effect.get_targets(), PROVINCE)) { // Non-province targeted effects are already added to the country modifier sum owner->push_contributing_modifiers(effect, contributions); } else { 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 : 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; + 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& 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); }; -- cgit v1.2.3-56-ga3b1