diff options
33 files changed, 988 insertions, 930 deletions
diff --git a/src/openvic-simulation/country/CountryInstance.cpp b/src/openvic-simulation/country/CountryInstance.cpp index 417ca0a..6e998e4 100644 --- a/src/openvic-simulation/country/CountryInstance.cpp +++ b/src/openvic-simulation/country/CountryInstance.cpp @@ -951,29 +951,29 @@ void CountryInstance::update_modifier_sum(Date today, StaticModifierCache const& }); // Add static modifiers - modifier_sum.add_modifier_nullcheck(static_modifier_cache.get_base_modifier(), country_source); + modifier_sum.add_modifier(static_modifier_cache.get_base_modifier(), country_source); switch (country_status) { using enum country_status_t; case COUNTRY_STATUS_GREAT_POWER: - modifier_sum.add_modifier_nullcheck(static_modifier_cache.get_great_power(), country_source); + modifier_sum.add_modifier(static_modifier_cache.get_great_power(), country_source); break; case COUNTRY_STATUS_SECONDARY_POWER: - modifier_sum.add_modifier_nullcheck(static_modifier_cache.get_secondary_power(), country_source); + modifier_sum.add_modifier(static_modifier_cache.get_secondary_power(), country_source); break; case COUNTRY_STATUS_CIVILISED: - modifier_sum.add_modifier_nullcheck(static_modifier_cache.get_civilised(), country_source); + modifier_sum.add_modifier(static_modifier_cache.get_civilised(), country_source); break; default: - modifier_sum.add_modifier_nullcheck(static_modifier_cache.get_uncivilised(), country_source); + modifier_sum.add_modifier(static_modifier_cache.get_uncivilised(), country_source); } if (is_disarmed()) { - modifier_sum.add_modifier_nullcheck(static_modifier_cache.get_disarming(), country_source); + modifier_sum.add_modifier(static_modifier_cache.get_disarming(), country_source); } - modifier_sum.add_modifier_nullcheck(static_modifier_cache.get_war_exhaustion(), country_source, war_exhaustion); - modifier_sum.add_modifier_nullcheck(static_modifier_cache.get_infamy(), country_source, infamy); - modifier_sum.add_modifier_nullcheck(static_modifier_cache.get_literacy(), country_source, national_literacy); - modifier_sum.add_modifier_nullcheck(static_modifier_cache.get_plurality(), country_source, plurality); + modifier_sum.add_modifier(static_modifier_cache.get_war_exhaustion(), country_source, war_exhaustion); + modifier_sum.add_modifier(static_modifier_cache.get_infamy(), country_source, infamy); + modifier_sum.add_modifier(static_modifier_cache.get_literacy(), country_source, national_literacy); + modifier_sum.add_modifier(static_modifier_cache.get_plurality(), country_source, plurality); // TODO - difficulty modifiers, war, peace, debt_default_to, bad_debter, generalised_debt_default, // total_occupation, total_blockaded, in_bankrupcy diff --git a/src/openvic-simulation/dataloader/Dataloader.cpp b/src/openvic-simulation/dataloader/Dataloader.cpp index 99a8d68..2b438c7 100644 --- a/src/openvic-simulation/dataloader/Dataloader.cpp +++ b/src/openvic-simulation/dataloader/Dataloader.cpp @@ -778,6 +778,10 @@ bool Dataloader::_load_map_dir(DefinitionManager& definition_manager) const { Logger::error("Failed to load terrain types!"); ret = false; } + if (!map_definition.get_terrain_type_manager().generate_modifiers(definition_manager.get_modifier_manager())) { + Logger::error("Failed to generate terrain-based modifiers!"); + ret = false; + } if (!map_definition.load_map_images( lookup_file(append_string_views(map_directory, provinces)), @@ -964,11 +968,12 @@ bool Dataloader::load_defines(DefinitionManager& definition_manager) { Logger::error("Failed to load rebel types!"); ret = false; } + definition_manager.get_modifier_manager().lock_all_modifier_except_base_country_effects(); if (!_load_technologies(definition_manager)) { Logger::error("Failed to load technologies!"); ret = false; } - definition_manager.get_modifier_manager().lock_modifier_effects(); + definition_manager.get_modifier_manager().lock_base_country_modifier_effects(); if (!definition_manager.get_politics_manager().get_rule_manager().setup_rules( definition_manager.get_economy_manager().get_building_type_manager() )) { @@ -1008,6 +1013,7 @@ bool Dataloader::load_defines(DefinitionManager& definition_manager) { Logger::error("Failed to load crime modifiers!"); ret = false; } + if (!definition_manager.get_modifier_manager().load_event_modifiers( parse_defines(lookup_file(event_modifiers_file)).get_file_node() )) { @@ -1020,6 +1026,8 @@ bool Dataloader::load_defines(DefinitionManager& definition_manager) { Logger::error("Failed to load static modifiers!"); ret = false; } + definition_manager.get_modifier_manager().lock_event_modifiers(); + if (!definition_manager.get_modifier_manager().load_triggered_modifiers( parse_defines_cached(lookup_file(triggered_modifiers_file)).get_file_node() )) { diff --git a/src/openvic-simulation/economy/BuildingType.cpp b/src/openvic-simulation/economy/BuildingType.cpp index a21361f..2801cfa 100644 --- a/src/openvic-simulation/economy/BuildingType.cpp +++ b/src/openvic-simulation/economy/BuildingType.cpp @@ -61,13 +61,10 @@ bool BuildingTypeManager::load_buildings_file( building_types, [this, &good_definition_manager, &production_type_manager, &modifier_manager]( std::string_view key, ast::NodeCPtr value ) -> bool { - using enum Modifier::modifier_type_t; - BuildingType::building_type_args_t building_type_args {}; - bool ret = modifier_manager.expect_modifier_value_and_keys( - move_variable_callback(building_type_args.modifier), - BUILDING, + bool ret = NodeTools::expect_dictionary_keys_and_default( + modifier_manager.expect_base_province_modifier(building_type_args.modifier), "type", ONE_EXACTLY, expect_identifier(assign_variable_callback(building_type_args.type)), "on_completion", ZERO_OR_ONE, expect_identifier(assign_variable_callback(building_type_args.on_completion)), "completion_size", ZERO_OR_ONE, @@ -131,14 +128,14 @@ bool BuildingTypeManager::load_buildings_file( static constexpr std::string_view max_prefix = "max_"; static constexpr std::string_view min_prefix = "min_build_"; - ret &= modifier_manager.add_modifier_effect( + ret &= modifier_manager.register_technology_modifier_effect( this_building_type_effects.max_level, StringUtils::append_string_views(max_prefix, building_type.get_identifier()), - true, INT, PROVINCE, StringUtils::append_string_views("$", building_type.get_identifier(), "$ $TECH_MAX_LEVEL$") + true, INT, 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( + ret &= modifier_manager.register_terrain_modifier_effect( this_building_type_effects.min_level, StringUtils::append_string_views(min_prefix, building_type.get_identifier()), - false, INT, PROVINCE + false, INT ); if (building_type.is_in_province()) { diff --git a/src/openvic-simulation/economy/GoodDefinition.cpp b/src/openvic-simulation/economy/GoodDefinition.cpp index f8bd9b7..7ad5a87 100644 --- a/src/openvic-simulation/economy/GoodDefinition.cpp +++ b/src/openvic-simulation/economy/GoodDefinition.cpp @@ -118,9 +118,9 @@ bool GoodDefinitionManager::generate_modifiers(ModifierManager& modifier_manager ModifierEffect const*& effect_cache, std::string_view name, bool is_positive_good, std::string_view localisation_key ) -> void { - ret &= modifier_manager.add_modifier_effect( + ret &= modifier_manager.register_technology_modifier_effect( effect_cache, ModifierManager::get_flat_identifier(name, good_identifier), is_positive_good, - PROPORTION_DECIMAL, COUNTRY, localisation_key + PROPORTION_DECIMAL, localisation_key ); }; diff --git a/src/openvic-simulation/economy/production/ProductionType.cpp b/src/openvic-simulation/economy/production/ProductionType.cpp index 65f3eba..7c4dfef 100644 --- a/src/openvic-simulation/economy/production/ProductionType.cpp +++ b/src/openvic-simulation/economy/production/ProductionType.cpp @@ -60,7 +60,7 @@ node_callback_t ProductionTypeManager::_expect_job( using enum Job::effect_t; std::string_view pop_type {}; - Job::effect_t effect_type {THROUGHPUT}; + Job::effect_t effect_type { THROUGHPUT }; fixed_point_t effect_multiplier = 1, desired_workforce_share = 1; static const string_map_t<Job::effect_t> effect_map = { diff --git a/src/openvic-simulation/map/Crime.cpp b/src/openvic-simulation/map/Crime.cpp index 176f71b..f52352c 100644 --- a/src/openvic-simulation/map/Crime.cpp +++ b/src/openvic-simulation/map/Crime.cpp @@ -1,5 +1,6 @@ #include "Crime.hpp" +#include "openvic-simulation/dataloader/NodeTools.hpp" #include "openvic-simulation/modifier/ModifierManager.hpp" using namespace OpenVic; @@ -29,16 +30,13 @@ bool CrimeManager::load_crime_modifiers(ModifierManager const& modifier_manager, const bool ret = expect_dictionary_reserve_length( crime_modifiers, [this, &modifier_manager](std::string_view key, ast::NodeCPtr value) -> bool { - using enum Modifier::modifier_type_t; - ModifierValue modifier_value; IconModifier::icon_t icon = 0; ConditionScript trigger { scope_t::PROVINCE, scope_t::NO_SCOPE, scope_t::NO_SCOPE }; bool default_active = false; - bool ret = modifier_manager.expect_modifier_value_and_keys( - move_variable_callback(modifier_value), - CRIME, + bool ret = NodeTools::expect_dictionary_keys_and_default( + modifier_manager.expect_base_province_modifier(modifier_value), "icon", ZERO_OR_ONE, expect_uint(assign_variable_callback(icon)), "trigger", ONE_EXACTLY, trigger.expect_script(), "active", ZERO_OR_ONE, expect_bool(assign_variable_callback(default_active)) diff --git a/src/openvic-simulation/map/MapDefinition.cpp b/src/openvic-simulation/map/MapDefinition.cpp index 5fe7189..faea838 100644 --- a/src/openvic-simulation/map/MapDefinition.cpp +++ b/src/openvic-simulation/map/MapDefinition.cpp @@ -3,6 +3,7 @@ #include <cstdint> #include <vector> +#include "openvic-simulation/dataloader/NodeTools.hpp" #include "openvic-simulation/modifier/ModifierManager.hpp" #include "openvic-simulation/types/Colour.hpp" #include "openvic-simulation/types/OrderedContainers.hpp" @@ -955,11 +956,11 @@ bool MapDefinition::load_climate_file(ModifierManager const& modifier_manager, a bool ret = true; Climate* cur_climate = climates.get_item_by_identifier(identifier); if (cur_climate == nullptr) { - using enum Modifier::modifier_type_t; - ModifierValue values; - ret &= modifier_manager.expect_modifier_value(move_variable_callback(values), CLIMATE)(node); + ret &= NodeTools::expect_dictionary( + modifier_manager.expect_base_province_modifier(values) + )(node); ret &= climates.add_item({ identifier, std::move(values), Modifier::modifier_type_t::CLIMATE }); } else { @@ -1004,7 +1005,6 @@ bool MapDefinition::load_continent_file(ModifierManager const& modifier_manager, bool ret = expect_dictionary_reserve_length( continents, [this, &modifier_manager](std::string_view identifier, ast::NodeCPtr node) -> bool { - using enum Modifier::modifier_type_t; if (identifier.empty()) { Logger::error("Invalid continent identifier - empty!"); @@ -1013,9 +1013,8 @@ bool MapDefinition::load_continent_file(ModifierManager const& modifier_manager, ModifierValue values; std::vector<ProvinceDefinition const*> prov_list; - bool ret = modifier_manager.expect_modifier_value_and_keys( - move_variable_callback(values), - CONTINENT, + bool ret = NodeTools::expect_dictionary_keys_and_default( + modifier_manager.expect_base_province_modifier(values), "provinces", ONE_EXACTLY, expect_list_reserve_length(prov_list, expect_province_definition_identifier( [&prov_list](ProvinceDefinition const& province) -> bool { if (province.continent == nullptr) { diff --git a/src/openvic-simulation/map/ProvinceInstance.cpp b/src/openvic-simulation/map/ProvinceInstance.cpp index 236efd2..5bc798d 100644 --- a/src/openvic-simulation/map/ProvinceInstance.cpp +++ b/src/openvic-simulation/map/ProvinceInstance.cpp @@ -209,17 +209,17 @@ void ProvinceInstance::update_modifier_sum(Date today, StaticModifierCache const // Add static modifiers if (is_owner_core()) { - modifier_sum.add_modifier_nullcheck(static_modifier_cache.get_core(), province_source); + modifier_sum.add_modifier(static_modifier_cache.get_core(), province_source); } if (province_definition.is_water()) { - modifier_sum.add_modifier_nullcheck(static_modifier_cache.get_sea_zone(), province_source); + modifier_sum.add_modifier(static_modifier_cache.get_sea_zone(), province_source); } else { - modifier_sum.add_modifier_nullcheck(static_modifier_cache.get_land_province(), province_source); + modifier_sum.add_modifier(static_modifier_cache.get_land_province(), province_source); if (province_definition.is_coastal()) { - modifier_sum.add_modifier_nullcheck(static_modifier_cache.get_coastal(), province_source); + modifier_sum.add_modifier(static_modifier_cache.get_coastal(), province_source); } else { - modifier_sum.add_modifier_nullcheck(static_modifier_cache.get_non_coastal(), province_source); + modifier_sum.add_modifier(static_modifier_cache.get_non_coastal(), province_source); } // TODO - overseas, blockaded, no_adjacent_controlled, has_siege, occupied, nationalism, infrastructure diff --git a/src/openvic-simulation/map/State.cpp b/src/openvic-simulation/map/State.cpp index 020b6f1..619f97b 100644 --- a/src/openvic-simulation/map/State.cpp +++ b/src/openvic-simulation/map/State.cpp @@ -5,6 +5,7 @@ #include "openvic-simulation/map/MapInstance.hpp" #include "openvic-simulation/map/ProvinceInstance.hpp" #include "openvic-simulation/map/Region.hpp" +#include "openvic-simulation/types/fixed_point/FixedPoint.hpp" #include "openvic-simulation/utility/StringUtils.hpp" using namespace OpenVic; @@ -65,10 +66,16 @@ void State::update_gamestate() { const int32_t potential_workforce_in_state = 0; // sum of worker pops, regardless of employment const int32_t potential_employment_in_state = 0; // sum of (factory level * production method base_workforce_size) - industrial_power = total_factory_levels_in_state * std::clamp( - (fixed_point_t { potential_workforce_in_state } / 100).floor() * 400 / potential_employment_in_state, - fixed_point_t::_0_20(), fixed_point_t::_4() - ); + fixed_point_t unclamped_score_per_factory = fixed_point_t::_0(); + + if (potential_employment_in_state > 0) { + unclamped_score_per_factory = (fixed_point_t { potential_workforce_in_state } / fixed_point_t::_100()).floor() * 400 / potential_employment_in_state; + } else { + industrial_power = total_factory_levels_in_state * std::clamp( + unclamped_score_per_factory, + fixed_point_t::_0_20(), fixed_point_t::_4() + ); + } } /* Whether two provinces in the same region should be grouped into the same state or not. diff --git a/src/openvic-simulation/map/TerrainType.cpp b/src/openvic-simulation/map/TerrainType.cpp index 1531507..011a3c3 100644 --- a/src/openvic-simulation/map/TerrainType.cpp +++ b/src/openvic-simulation/map/TerrainType.cpp @@ -1,5 +1,7 @@ #include "TerrainType.hpp" +#include <string_view> + #include "openvic-simulation/modifier/ModifierManager.hpp" #include "openvic-simulation/types/Colour.hpp" @@ -17,6 +19,38 @@ TerrainTypeMapping::TerrainTypeMapping( ) : HasIdentifier { new_identifier }, type { new_type }, terrain_indices { std::move(new_terrain_indicies) }, priority { new_priority }, has_texture { new_has_texture } {} +bool TerrainTypeManager::generate_modifiers(ModifierManager& modifier_manager) const { + using enum ModifierEffect::format_t; + IndexedMap<TerrainType, ModifierEffectCache::unit_terrain_effects_t>& unit_terrain_effects = + modifier_manager.modifier_effect_cache.unit_terrain_effects; + + unit_terrain_effects.set_keys(&get_terrain_types()); + + constexpr bool has_no_effect = true; + bool ret = true; + for (TerrainType const& terrain_type : get_terrain_types()) { + const std::string_view identifier = terrain_type.get_identifier(); + ModifierEffectCache::unit_terrain_effects_t& this_unit_terrain_effects = unit_terrain_effects[terrain_type]; + ret &= modifier_manager.register_unit_terrain_modifier_effect( + this_unit_terrain_effects.attack, ModifierManager::get_flat_identifier("attack", identifier), true, + PROPORTION_DECIMAL, "UA_ATTACK", has_no_effect + ); + ret &= modifier_manager.register_unit_terrain_modifier_effect( + this_unit_terrain_effects.defence, ModifierManager::get_flat_identifier("defence", identifier), true, + PROPORTION_DECIMAL, "UA_DEFENCE", has_no_effect + ); + ret &= modifier_manager.register_unit_terrain_modifier_effect( + this_unit_terrain_effects.attrition, ModifierManager::get_flat_identifier("attrition", identifier), false, + RAW_DECIMAL, "UA_ATTRITION", has_no_effect + ); + ret &= modifier_manager.register_unit_terrain_modifier_effect( + this_unit_terrain_effects.movement, ModifierManager::get_flat_identifier("movement", identifier), true, + PROPORTION_DECIMAL, "UA_MOVEMENT" + ); + } + return ret; +} + bool TerrainTypeManager::add_terrain_type( std::string_view identifier, colour_t colour, ModifierValue&& values, bool is_water ) { @@ -72,15 +106,12 @@ node_callback_t TerrainTypeManager::_load_terrain_type_categories(ModifierManage return [this, &modifier_manager](ast::NodeCPtr root) -> bool { const bool ret = expect_dictionary_reserve_length(terrain_types, [this, &modifier_manager](std::string_view type_key, ast::NodeCPtr type_node) -> bool { - using enum Modifier::modifier_type_t; - ModifierValue values; colour_t colour = colour_t::null(); bool is_water = false; - bool ret = modifier_manager.expect_modifier_value_and_keys( - move_variable_callback(values), - TERRAIN, + bool ret = NodeTools::expect_dictionary_keys_and_default( + modifier_manager.expect_terrain_modifier(values), "color", ONE_EXACTLY, expect_colour(assign_variable_callback(colour)), "is_water", ZERO_OR_ONE, expect_bool(assign_variable_callback(is_water)) )(type_node); diff --git a/src/openvic-simulation/map/TerrainType.hpp b/src/openvic-simulation/map/TerrainType.hpp index 3a88610..b15e650 100644 --- a/src/openvic-simulation/map/TerrainType.hpp +++ b/src/openvic-simulation/map/TerrainType.hpp @@ -67,5 +67,6 @@ namespace OpenVic { TerrainTypeMapping::index_t get_terrain_texture_limit() const; bool load_terrain_types(ModifierManager const& modifier_manager, ast::NodeCPtr root); + bool generate_modifiers(ModifierManager& modifier_manager) const; }; } diff --git a/src/openvic-simulation/military/Deployment.cpp b/src/openvic-simulation/military/Deployment.cpp index bd176be..27cd124 100644 --- a/src/openvic-simulation/military/Deployment.cpp +++ b/src/openvic-simulation/military/Deployment.cpp @@ -144,7 +144,7 @@ bool DeploymentManager::load_oob_file( return false; } - army_regiments.push_back({regiment_name, *regiment_type, regiment_home}); + army_regiments.push_back({ regiment_name, *regiment_type, regiment_home }); return ret; }, diff --git a/src/openvic-simulation/military/LeaderTrait.cpp b/src/openvic-simulation/military/LeaderTrait.cpp index 7835636..e00deec 100644 --- a/src/openvic-simulation/military/LeaderTrait.cpp +++ b/src/openvic-simulation/military/LeaderTrait.cpp @@ -1,5 +1,6 @@ #include "LeaderTrait.hpp" +#include "openvic-simulation/dataloader/NodeTools.hpp" #include "openvic-simulation/modifier/ModifierManager.hpp" using namespace OpenVic; @@ -32,17 +33,10 @@ bool LeaderTraitManager::load_leader_traits_file(ModifierManager const& modifier return expect_dictionary_reserve_length( leader_traits, [this, &modifier_manager, type](std::string_view trait_identifier, ast::NodeCPtr value) -> bool { - using enum Modifier::modifier_type_t; - - static const string_set_t allowed_modifiers = { - "attack", "defence leader", "morale", "organisation", "reconnaissance", - "speed", "attrition", "experience", "reliability" - }; - ModifierValue modifiers; - bool ret = modifier_manager.expect_whitelisted_modifier_value( - move_variable_callback(modifiers), LEADER, allowed_modifiers + bool ret = NodeTools::expect_dictionary( + modifier_manager.expect_leader_modifier(modifiers) )(value); ret &= add_leader_trait(trait_identifier, type, std::move(modifiers)); diff --git a/src/openvic-simulation/military/UnitType.cpp b/src/openvic-simulation/military/UnitType.cpp index 22e108d..920f28b 100644 --- a/src/openvic-simulation/military/UnitType.cpp +++ b/src/openvic-simulation/military/UnitType.cpp @@ -1,6 +1,7 @@ #include "UnitType.hpp" #include "openvic-simulation/country/CountryInstance.hpp" +#include "openvic-simulation/dataloader/NodeTools.hpp" #include "openvic-simulation/map/TerrainType.hpp" #include "openvic-simulation/modifier/ModifierManager.hpp" @@ -247,11 +248,9 @@ bool UnitTypeManager::load_unit_type_file( TerrainType const* terrain_type = terrain_type_manager.get_terrain_type_by_identifier(default_key); if (terrain_type != nullptr) { - using enum Modifier::modifier_type_t; - - // TODO - restrict what modifier effects can be used here - return modifier_manager.expect_modifier_value( - map_callback(unit_args.terrain_modifier_values, terrain_type), UNIT_TERRAIN + ModifierValue& modifier_value = unit_args.terrain_modifier_values[terrain_type]; + return expect_dictionary( + modifier_manager.expect_unit_terrain_modifier(modifier_value, terrain_type->get_identifier()) )(default_value); } @@ -336,14 +335,13 @@ bool UnitTypeManager::generate_modifiers(ModifierManager& modifier_manager) cons std::derived_from<ModifierEffectCache::unit_type_effects_t> auto unit_type_effects, std::string_view identifier ) -> void { using enum ModifierEffect::format_t; - using enum ModifierEffect::target_t; const auto stat_modifier = [&modifier_manager, &ret, &identifier]( ModifierEffect const*& effect_cache, std::string_view suffix, bool is_positive_good, ModifierEffect::format_t format, std::string_view localisation_key ) -> void { - ret &= modifier_manager.add_modifier_effect( - effect_cache, ModifierManager::get_flat_identifier(identifier, suffix), is_positive_good, format, COUNTRY, + ret &= modifier_manager.register_technology_modifier_effect( + effect_cache, ModifierManager::get_flat_identifier(identifier, suffix), is_positive_good, format, StringUtils::append_string_views("$", identifier, "$: $", localisation_key, "$") ); }; diff --git a/src/openvic-simulation/misc/SoundEffect.cpp b/src/openvic-simulation/misc/SoundEffect.cpp index b32d353..6f64406 100644 --- a/src/openvic-simulation/misc/SoundEffect.cpp +++ b/src/openvic-simulation/misc/SoundEffect.cpp @@ -25,14 +25,14 @@ bool SoundEffectManager::_load_sound_define(std::string_view sfx_identifier, ast return false; } - ret &= sound_effects.add_item({sfx_identifier,file,volume}); + ret &= sound_effects.add_item({ sfx_identifier, file, volume }); return ret; } bool SoundEffectManager::load_sound_defines_file(ast::NodeCPtr root) { return expect_dictionary_reserve_length(sound_effects, [this](std::string_view key, ast::NodeCPtr value) -> bool { - return _load_sound_define(key,value); + return _load_sound_define(key, value); } )(root); } diff --git a/src/openvic-simulation/modifier/Modifier.hpp b/src/openvic-simulation/modifier/Modifier.hpp index 1277c76..f8c28d8 100644 --- a/src/openvic-simulation/modifier/Modifier.hpp +++ b/src/openvic-simulation/modifier/Modifier.hpp @@ -12,6 +12,7 @@ namespace OpenVic { struct Modifier : HasIdentifier, ModifierValue { friend struct ModifierManager; + friend struct StaticModifierCache; friend struct UnitType; enum struct modifier_type_t : uint8_t { diff --git a/src/openvic-simulation/modifier/ModifierEffect.cpp b/src/openvic-simulation/modifier/ModifierEffect.cpp index 2ffb9a5..eadaf58 100644 --- a/src/openvic-simulation/modifier/ModifierEffect.cpp +++ b/src/openvic-simulation/modifier/ModifierEffect.cpp @@ -41,9 +41,9 @@ std::string ModifierEffect::make_default_modifier_effect_localisation_key(std::s } 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 }, + std::string_view new_identifier, bool new_is_positive_good, format_t new_format, target_t new_targets, + std::string_view new_localisation_key, bool new_has_no_effect +) : HasIdentifier { new_identifier }, positive_good { new_is_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 - } {} + }, no_effect { new_has_no_effect } {} diff --git a/src/openvic-simulation/modifier/ModifierEffect.hpp b/src/openvic-simulation/modifier/ModifierEffect.hpp index ff82acf..b6164e0 100644 --- a/src/openvic-simulation/modifier/ModifierEffect.hpp +++ b/src/openvic-simulation/modifier/ModifierEffect.hpp @@ -38,6 +38,7 @@ namespace OpenVic { * If false, the colours will be switced. */ const bool PROPERTY_CUSTOM_PREFIX(positive_good, is); + const bool PROPERTY_CUSTOM_PREFIX(no_effect, has); const format_t PROPERTY(format); const target_t PROPERTY(targets); std::string PROPERTY(localisation_key); @@ -45,8 +46,8 @@ namespace OpenVic { // 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 + std::string_view new_identifier, bool new_is_positive_good, format_t new_format, target_t mew_targets, + std::string_view new_localisation_key, bool new_has_no_effect ); public: diff --git a/src/openvic-simulation/modifier/ModifierEffectCache.cpp b/src/openvic-simulation/modifier/ModifierEffectCache.cpp index 9653d23..0e7141f 100644 --- a/src/openvic-simulation/modifier/ModifierEffectCache.cpp +++ b/src/openvic-simulation/modifier/ModifierEffectCache.cpp @@ -2,6 +2,7 @@ #include "openvic-simulation/economy/BuildingType.hpp" #include "openvic-simulation/economy/GoodDefinition.hpp" +#include "openvic-simulation/map/TerrainType.hpp" #include "openvic-simulation/politics/Rebel.hpp" #include "openvic-simulation/research/Technology.hpp" @@ -48,6 +49,12 @@ ModifierEffectCache::ship_type_effects_t::ship_type_effects_t() evasion { nullptr }, torpedo_attack { nullptr } {} +ModifierEffectCache::unit_terrain_effects_t::unit_terrain_effects_t() + : attack { nullptr }, + defence { nullptr }, + attrition { nullptr }, + movement { nullptr } {} + ModifierEffectCache::strata_effects_t::strata_effects_t() : income_modifier { nullptr }, vote { nullptr }, @@ -113,7 +120,8 @@ ModifierEffectCache::ModifierEffectCache() leadership { nullptr }, leadership_modifier { nullptr }, literacy_con_impact { nullptr }, - loan_interest { nullptr }, + loan_interest_base { nullptr }, + loan_interest_foreign { nullptr }, max_loan_modifier { nullptr }, max_military_spending { nullptr }, max_national_focus { nullptr }, @@ -170,8 +178,11 @@ ModifierEffectCache::ModifierEffectCache() boost_strongest_party { nullptr }, combat_width_percentage_change { nullptr }, defence_terrain { nullptr }, - farm_rgo_eff { nullptr }, - farm_rgo_size { nullptr }, + farm_rgo_throughput_global { nullptr }, + farm_rgo_output_global { nullptr }, + farm_rgo_output_local { nullptr }, + farm_rgo_size_global { nullptr }, + farm_rgo_size_local { nullptr }, immigrant_attract { nullptr }, immigrant_push { nullptr }, life_rating { nullptr }, @@ -187,22 +198,28 @@ ModifierEffectCache::ModifierEffectCache() local_ruling_party_support { nullptr }, local_ship_build { nullptr }, max_attrition { nullptr }, - mine_rgo_eff { nullptr }, - mine_rgo_size { nullptr }, + mine_rgo_throughput_global { nullptr }, + mine_rgo_output_global { nullptr }, + mine_rgo_output_local { nullptr }, + mine_rgo_size_global { nullptr }, + mine_rgo_size_local { nullptr }, movement_cost_base { nullptr }, movement_cost_percentage_change { nullptr }, + movement_cost_percentage_change_fake { nullptr }, number_of_voters { nullptr }, pop_consciousness_modifier { nullptr }, pop_militancy_modifier { nullptr }, population_growth { nullptr }, - supply_limit { nullptr }, + supply_limit_global_percentage_change { nullptr }, + supply_limit_local_base { nullptr }, /* Military Modifier Effects */ - attack { nullptr }, + attack_leader { nullptr }, attrition { nullptr }, defence_leader { nullptr }, experience { nullptr }, - morale { nullptr }, + morale_global { nullptr }, + morale_leader { nullptr }, organisation { nullptr }, reconnaissance { nullptr }, reliability { nullptr }, @@ -219,6 +236,7 @@ ModifierEffectCache::ModifierEffectCache() regiment_type_effects { nullptr }, navy_base_effects {}, ship_type_effects { nullptr }, + unit_terrain_effects { nullptr }, /* Rebel Effects */ rebel_org_gain_all { nullptr }, diff --git a/src/openvic-simulation/modifier/ModifierEffectCache.hpp b/src/openvic-simulation/modifier/ModifierEffectCache.hpp index 261ddde..e88aaea 100644 --- a/src/openvic-simulation/modifier/ModifierEffectCache.hpp +++ b/src/openvic-simulation/modifier/ModifierEffectCache.hpp @@ -18,6 +18,8 @@ namespace OpenVic { struct Strata; struct TechnologyManager; struct TechnologyFolder; + struct TerrainTypeManager; + struct TerrainType; struct ModifierEffectCache { friend struct ModifierManager; @@ -27,6 +29,7 @@ namespace OpenVic { friend struct RebelManager; friend struct PopManager; friend struct TechnologyManager; + friend struct TerrainTypeManager; private: /* Tech/inventions only */ @@ -86,7 +89,8 @@ namespace OpenVic { ModifierEffect const* PROPERTY(leadership); ModifierEffect const* PROPERTY(leadership_modifier); ModifierEffect const* PROPERTY(literacy_con_impact); - ModifierEffect const* PROPERTY(loan_interest); + ModifierEffect const* PROPERTY(loan_interest_base); + ModifierEffect const* PROPERTY(loan_interest_foreign); ModifierEffect const* PROPERTY(max_loan_modifier); ModifierEffect const* PROPERTY(max_military_spending); ModifierEffect const* PROPERTY(max_national_focus); @@ -103,6 +107,7 @@ namespace OpenVic { ModifierEffect const* PROPERTY(mobilisation_economy_impact); ModifierEffect const* PROPERTY(mobilisation_size); ModifierEffect const* PROPERTY(mobilization_impact); + ModifierEffect const* PROPERTY(morale_global); ModifierEffect const* PROPERTY(naval_attack_modifier); ModifierEffect const* PROPERTY(naval_attrition); ModifierEffect const* PROPERTY(naval_defense_modifier); @@ -143,8 +148,11 @@ namespace OpenVic { ModifierEffect const* PROPERTY(boost_strongest_party); ModifierEffect const* PROPERTY(combat_width_percentage_change); ModifierEffect const* PROPERTY(defence_terrain); - ModifierEffect const* PROPERTY(farm_rgo_eff); - ModifierEffect const* PROPERTY(farm_rgo_size); + ModifierEffect const* PROPERTY(farm_rgo_throughput_global); + ModifierEffect const* PROPERTY(farm_rgo_output_global); + ModifierEffect const* PROPERTY(farm_rgo_output_local); + ModifierEffect const* PROPERTY(farm_rgo_size_global); + ModifierEffect const* PROPERTY(farm_rgo_size_local); ModifierEffect const* PROPERTY(immigrant_attract); ModifierEffect const* PROPERTY(immigrant_push); ModifierEffect const* PROPERTY(life_rating); @@ -160,22 +168,28 @@ namespace OpenVic { ModifierEffect const* PROPERTY(local_ruling_party_support); ModifierEffect const* PROPERTY(local_ship_build); ModifierEffect const* PROPERTY(max_attrition); - ModifierEffect const* PROPERTY(mine_rgo_eff); - ModifierEffect const* PROPERTY(mine_rgo_size); + ModifierEffect const* PROPERTY(mine_rgo_throughput_global); + ModifierEffect const* PROPERTY(mine_rgo_output_global); + ModifierEffect const* PROPERTY(mine_rgo_output_local); + ModifierEffect const* PROPERTY(mine_rgo_size_global); + ModifierEffect const* PROPERTY(mine_rgo_size_local); ModifierEffect const* PROPERTY(movement_cost_base); ModifierEffect const* PROPERTY(movement_cost_percentage_change); + ModifierEffect const* PROPERTY(movement_cost_percentage_change_fake); //shows up but does nothing in Victoria 2 ModifierEffect const* PROPERTY(number_of_voters); ModifierEffect const* PROPERTY(pop_consciousness_modifier); ModifierEffect const* PROPERTY(pop_militancy_modifier); ModifierEffect const* PROPERTY(population_growth); - ModifierEffect const* PROPERTY(supply_limit); + ModifierEffect const* PROPERTY(supply_limit_global_percentage_change); + ModifierEffect const* PROPERTY(supply_limit_global_base); + ModifierEffect const* PROPERTY(supply_limit_local_base); /* Military Modifier Effects */ - ModifierEffect const* PROPERTY(attack); + ModifierEffect const* PROPERTY(attack_leader); ModifierEffect const* PROPERTY(attrition); ModifierEffect const* PROPERTY(defence_leader); ModifierEffect const* PROPERTY(experience); - ModifierEffect const* PROPERTY(morale); + ModifierEffect const* PROPERTY(morale_leader); ModifierEffect const* PROPERTY(organisation); ModifierEffect const* PROPERTY(reconnaissance); ModifierEffect const* PROPERTY(reliability); @@ -273,6 +287,24 @@ namespace OpenVic { ship_type_effects_t PROPERTY(navy_base_effects); IndexedMap<ShipType, ship_type_effects_t> PROPERTY(ship_type_effects); + /* Unit terrain Effects */ + public: + struct unit_terrain_effects_t { + friend struct TerrainTypeManager; + + private: + ModifierEffect const* PROPERTY(attack); + ModifierEffect const* PROPERTY(defence); + ModifierEffect const* PROPERTY(attrition); + ModifierEffect const* PROPERTY(movement); + + public: + unit_terrain_effects_t(); + }; + + private: + IndexedMap<TerrainType, unit_terrain_effects_t> PROPERTY(unit_terrain_effects); + /* Rebel Effects */ ModifierEffect const* PROPERTY(rebel_org_gain_all); IndexedMap<RebelType, ModifierEffect const*> PROPERTY(rebel_org_gain_effects); diff --git a/src/openvic-simulation/modifier/ModifierManager.cpp b/src/openvic-simulation/modifier/ModifierManager.cpp index daf186f..cd330fd 100644 --- a/src/openvic-simulation/modifier/ModifierManager.cpp +++ b/src/openvic-simulation/modifier/ModifierManager.cpp @@ -1,11 +1,35 @@ #include "ModifierManager.hpp" +#include <utility> + +#include "openvic-simulation/dataloader/NodeTools.hpp" +#include "openvic-simulation/modifier/Modifier.hpp" +#include "openvic-simulation/modifier/ModifierEffect.hpp" + using namespace OpenVic; using namespace OpenVic::NodeTools; +using namespace OpenVic::StringUtils; + +using enum ModifierEffect::target_t; + +void ModifierManager::lock_all_modifier_except_base_country_effects() { + lock_leader_modifier_effects(); + lock_unit_terrain_modifier_effects(); + lock_shared_tech_country_modifier_effects(); + lock_technology_modifier_effects(); + lock_base_province_modifier_effects(); + lock_terrain_modifier_effects(); +} -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 +bool ModifierManager::_register_modifier_effect( + modifier_effect_registry_t& registry, + ModifierEffect::target_t targets, + ModifierEffect const*& effect_cache, + const std::string_view identifier, + const bool is_positive_good, + const ModifierEffect::format_t format, + const std::string_view localisation_key, + const bool has_no_effect ) { using enum ModifierEffect::target_t; @@ -35,471 +59,496 @@ bool ModifierManager::add_modifier_effect( return false; } - const bool ret = modifier_effects.add_item({ std::move(identifier), positive_good, format, targets, localisation_key }); + const bool ret = registry.add_item({ std::move(identifier), is_positive_good, format, targets, localisation_key, has_no_effect }); if (ret) { - effect_cache = &modifier_effects.get_items().back(); + effect_cache = ®istry.get_items().back(); } return ret; } -bool ModifierManager::setup_modifier_effects() { - // Variant Modifier Effeects - static const std::string combat_width = "combat_width"; - static const std::string movement_cost = "movement_cost"; - static const std::string prestige = "prestige"; - static const std::string defence = "defence"; +#define REGISTER_MODIFIER_EFFECT(MAPPING_TYPE, TARGETS) \ +bool ModifierManager::register_##MAPPING_TYPE##_modifier_effect( \ + ModifierEffect const*& effect_cache, \ + const std::string_view identifier, \ + const bool is_positive_good, \ + const ModifierEffect::format_t format, \ + const std::string_view localisation_key, \ + const bool has_no_effect \ +) { \ + return _register_modifier_effect( \ + MAPPING_TYPE##_modifier_effects, \ + TARGETS, \ + effect_cache, \ + std::move(identifier), \ + is_positive_good, \ + format, \ + localisation_key, \ + has_no_effect \ + ); \ +} + +REGISTER_MODIFIER_EFFECT(leader, UNIT) +REGISTER_MODIFIER_EFFECT(unit_terrain, COUNTRY) +REGISTER_MODIFIER_EFFECT(shared_tech_country, COUNTRY) +REGISTER_MODIFIER_EFFECT(technology, COUNTRY) +REGISTER_MODIFIER_EFFECT(base_country, COUNTRY) +REGISTER_MODIFIER_EFFECT(base_province, PROVINCE) +REGISTER_MODIFIER_EFFECT(terrain, PROVINCE) +#undef REGISTER_MODIFIER_EFFECT + +bool ModifierManager::setup_modifier_effects() { + constexpr bool has_no_effect = true; bool ret = true; using enum ModifierEffect::format_t; - using enum ModifierEffect::target_t; - using enum Modifier::modifier_type_t; /* Tech/inventions only */ - ret &= add_modifier_effect( - modifier_effect_cache.cb_creation_speed, "cb_creation_speed", true, PROPORTION_DECIMAL, COUNTRY, "CB_MANUFACTURE_TECH" + ret &= register_technology_modifier_effect( + modifier_effect_cache.cb_creation_speed, "cb_creation_speed", true, PROPORTION_DECIMAL, "CB_MANUFACTURE_TECH" ); // When applied to countries (army tech/inventions), combat_width is an additive integer value. - ret &= add_modifier_effect( - modifier_effect_cache.combat_width_additive, "combat_width add", false, INT, COUNTRY, - ModifierEffect::make_default_modifier_effect_localisation_key(combat_width) + ret &= register_technology_modifier_effect( + modifier_effect_cache.combat_width_additive, "combat_width", false, INT ); - ret &= register_modifier_effect_variants( - combat_width, modifier_effect_cache.combat_width_additive, { TECHNOLOGY, INVENTION } + ret &= register_technology_modifier_effect( + modifier_effect_cache.plurality, "plurality", true, PERCENTAGE_DECIMAL, "TECH_PLURALITY" ); - ret &= add_modifier_effect( - modifier_effect_cache.plurality, "plurality", true, PERCENTAGE_DECIMAL, COUNTRY, "TECH_PLURALITY" + ret &= register_technology_modifier_effect( + modifier_effect_cache.pop_growth, "pop_growth", true, PROPORTION_DECIMAL, "TECH_POP_GROWTH" ); - ret &= add_modifier_effect( - modifier_effect_cache.pop_growth, "pop_growth", true, PROPORTION_DECIMAL, COUNTRY, "TECH_POP_GROWTH" - ); - ret &= add_modifier_effect( - modifier_effect_cache.prestige_gain_multiplier, "prestige gain_multiplier", true, PROPORTION_DECIMAL, COUNTRY, + ret &= register_technology_modifier_effect( + modifier_effect_cache.prestige_gain_multiplier, "prestige", true, PROPORTION_DECIMAL, "PRESTIGE_MODIFIER_TECH" ); - ret &= register_modifier_effect_variants( - prestige, modifier_effect_cache.prestige_gain_multiplier, { TECHNOLOGY, INVENTION } - ); - ret &= add_modifier_effect( - modifier_effect_cache.regular_experience_level, "regular_experience_level", true, RAW_DECIMAL, COUNTRY, + ret &= register_technology_modifier_effect( + modifier_effect_cache.regular_experience_level, "regular_experience_level", true, RAW_DECIMAL, "REGULAR_EXP_TECH" ); - ret &= add_modifier_effect( - modifier_effect_cache.reinforce_rate, "reinforce_rate", true, PROPORTION_DECIMAL, COUNTRY, "REINFORCE_TECH" + ret &= register_technology_modifier_effect( + modifier_effect_cache.reinforce_rate, "reinforce_rate", true, PROPORTION_DECIMAL, "REINFORCE_TECH" ); - ret &= add_modifier_effect( + ret &= register_technology_modifier_effect( modifier_effect_cache.separatism, "seperatism", // paradox typo - false, PROPORTION_DECIMAL, COUNTRY, "SEPARATISM_TECH" + false, PROPORTION_DECIMAL, "SEPARATISM_TECH" ); - ret &= add_modifier_effect( - modifier_effect_cache.shared_prestige, "shared_prestige", true, RAW_DECIMAL, COUNTRY, "SHARED_PRESTIGE_TECH" + ret &= register_technology_modifier_effect( + modifier_effect_cache.shared_prestige, "shared_prestige", true, RAW_DECIMAL, "SHARED_PRESTIGE_TECH" ); - ret &= add_modifier_effect(modifier_effect_cache.tax_eff, "tax_eff", true, PERCENTAGE_DECIMAL, COUNTRY, "TECH_TAX_EFF"); + ret &= register_technology_modifier_effect(modifier_effect_cache.tax_eff, "tax_eff", true, PERCENTAGE_DECIMAL, "TECH_TAX_EFF"); /* Country Modifier Effects */ - ret &= add_modifier_effect( - modifier_effect_cache.administrative_efficiency, "administrative_efficiency", true, PROPORTION_DECIMAL, COUNTRY + ret &= register_technology_modifier_effect( + modifier_effect_cache.administrative_efficiency, "administrative_efficiency", true, PROPORTION_DECIMAL ); - ret &= add_modifier_effect( + ret &= register_base_country_modifier_effect( modifier_effect_cache.administrative_efficiency_modifier, "administrative_efficiency_modifier", true, - PROPORTION_DECIMAL, COUNTRY, ModifierEffect::make_default_modifier_effect_localisation_key("administrative_efficiency") + PROPORTION_DECIMAL, ModifierEffect::make_default_modifier_effect_localisation_key("administrative_efficiency") ); - ret &= add_modifier_effect(modifier_effect_cache.artisan_input, "artisan_input", false, PROPORTION_DECIMAL, COUNTRY); - ret &= add_modifier_effect(modifier_effect_cache.artisan_output, "artisan_output", true, PROPORTION_DECIMAL, COUNTRY); - ret &= add_modifier_effect( - modifier_effect_cache.artisan_throughput, "artisan_throughput", true, PROPORTION_DECIMAL, COUNTRY + ret &= register_technology_modifier_effect(modifier_effect_cache.artisan_input, "artisan_input", false, PROPORTION_DECIMAL,{},has_no_effect); + ret &= register_technology_modifier_effect(modifier_effect_cache.artisan_output, "artisan_output", true, PROPORTION_DECIMAL,{},has_no_effect); + ret &= register_technology_modifier_effect( modifier_effect_cache.artisan_throughput, "artisan_throughput", true, PROPORTION_DECIMAL,{},has_no_effect); + ret &= register_base_country_modifier_effect(modifier_effect_cache.badboy, "badboy", false, RAW_DECIMAL); + ret &= register_base_country_modifier_effect( + modifier_effect_cache.cb_generation_speed_modifier, "cb_generation_speed_modifier", true, PROPORTION_DECIMAL ); - ret &= add_modifier_effect(modifier_effect_cache.badboy, "badboy", false, RAW_DECIMAL, COUNTRY); - ret &= add_modifier_effect( - modifier_effect_cache.cb_generation_speed_modifier, "cb_generation_speed_modifier", true, PROPORTION_DECIMAL, COUNTRY - ); - ret &= add_modifier_effect( + ret &= register_base_country_modifier_effect( modifier_effect_cache.civilization_progress_modifier, "civilization_progress_modifier", true, PROPORTION_DECIMAL, - COUNTRY, ModifierEffect::make_default_modifier_effect_localisation_key("civilization_progress") + ModifierEffect::make_default_modifier_effect_localisation_key("civilization_progress") ); - ret &= add_modifier_effect( - modifier_effect_cache.colonial_life_rating, "colonial_life_rating", false, INT, COUNTRY, "COLONIAL_LIFE_TECH" + ret &= register_technology_modifier_effect( + modifier_effect_cache.colonial_life_rating, "colonial_life_rating", false, INT, "COLONIAL_LIFE_TECH" ); - ret &= add_modifier_effect( - modifier_effect_cache.colonial_migration, "colonial_migration", true, PROPORTION_DECIMAL, COUNTRY, + ret &= register_technology_modifier_effect( + modifier_effect_cache.colonial_migration, "colonial_migration", true, PROPORTION_DECIMAL, "COLONIAL_MIGRATION_TECH" ); - ret &= add_modifier_effect( - modifier_effect_cache.colonial_points, "colonial_points", true, INT, COUNTRY, "COLONIAL_POINTS_TECH" + ret &= register_technology_modifier_effect( + modifier_effect_cache.colonial_points, "colonial_points", true, INT, "COLONIAL_POINTS_TECH" ); - ret &= add_modifier_effect( - modifier_effect_cache.colonial_prestige, "colonial_prestige", true, PROPORTION_DECIMAL, COUNTRY, + ret &= register_technology_modifier_effect( + modifier_effect_cache.colonial_prestige, "colonial_prestige", true, PROPORTION_DECIMAL, "COLONIAL_PRESTIGE_MODIFIER_TECH" ); - ret &= add_modifier_effect( - modifier_effect_cache.core_pop_consciousness_modifier, "core_pop_consciousness_modifier", false, RAW_DECIMAL, COUNTRY + ret &= register_base_country_modifier_effect( + modifier_effect_cache.core_pop_consciousness_modifier, "core_pop_consciousness_modifier", false, RAW_DECIMAL ); - ret &= add_modifier_effect( - modifier_effect_cache.core_pop_militancy_modifier, "core_pop_militancy_modifier", false, RAW_DECIMAL, COUNTRY + ret &= register_base_country_modifier_effect( + modifier_effect_cache.core_pop_militancy_modifier, "core_pop_militancy_modifier", false, RAW_DECIMAL ); - ret &= add_modifier_effect(modifier_effect_cache.dig_in_cap, "dig_in_cap", true, INT, COUNTRY, "DIGIN_FROM_TECH"); - ret &= add_modifier_effect( - modifier_effect_cache.diplomatic_points, "diplomatic_points", true, PROPORTION_DECIMAL, COUNTRY, + ret &= register_technology_modifier_effect(modifier_effect_cache.dig_in_cap, "dig_in_cap", true, INT, "DIGIN_FROM_TECH"); + ret &= register_technology_modifier_effect( + modifier_effect_cache.diplomatic_points, "diplomatic_points", true, PROPORTION_DECIMAL, "DIPLOMATIC_POINTS_TECH" ); - ret &= add_modifier_effect( - modifier_effect_cache.diplomatic_points_modifier, "diplomatic_points_modifier", true, PROPORTION_DECIMAL, COUNTRY, + ret &= register_base_country_modifier_effect( + modifier_effect_cache.diplomatic_points_modifier, "diplomatic_points_modifier", true, PROPORTION_DECIMAL, ModifierEffect::make_default_modifier_effect_localisation_key("diplopoints_gain") ); - ret &= add_modifier_effect( - modifier_effect_cache.education_efficiency, "education_efficiency", true, PROPORTION_DECIMAL, COUNTRY + ret &= register_technology_modifier_effect( + modifier_effect_cache.education_efficiency, "education_efficiency", true, PROPORTION_DECIMAL ); - ret &= add_modifier_effect( + ret &= register_base_country_modifier_effect( modifier_effect_cache.education_efficiency_modifier, "education_efficiency_modifier", true, PROPORTION_DECIMAL, - COUNTRY, ModifierEffect::make_default_modifier_effect_localisation_key("education_efficiency") + ModifierEffect::make_default_modifier_effect_localisation_key("education_efficiency") ); - ret &= add_modifier_effect(modifier_effect_cache.factory_cost, "factory_cost", false, PROPORTION_DECIMAL, COUNTRY); - ret &= add_modifier_effect(modifier_effect_cache.factory_input, "factory_input", false, PROPORTION_DECIMAL, COUNTRY); - ret &= add_modifier_effect( - modifier_effect_cache.factory_maintenance, "factory_maintenance", false, PROPORTION_DECIMAL, COUNTRY + ret &= register_shared_tech_country_modifier_effect(modifier_effect_cache.factory_cost, "factory_cost", false, PROPORTION_DECIMAL); + ret &= register_shared_tech_country_modifier_effect(modifier_effect_cache.factory_input, "factory_input", false, PROPORTION_DECIMAL); + ret &= register_base_country_modifier_effect( + modifier_effect_cache.factory_maintenance, "factory_maintenance", false, PROPORTION_DECIMAL ); - ret &= add_modifier_effect(modifier_effect_cache.factory_output, "factory_output", true, PROPORTION_DECIMAL, COUNTRY); - ret &= add_modifier_effect( - modifier_effect_cache.factory_owner_cost, "factory_owner_cost", false, PROPORTION_DECIMAL, COUNTRY + ret &= register_shared_tech_country_modifier_effect(modifier_effect_cache.factory_output, "factory_output", true, PROPORTION_DECIMAL); + ret &= register_base_country_modifier_effect( + modifier_effect_cache.factory_owner_cost, "factory_owner_cost", false, PROPORTION_DECIMAL ); - ret &= add_modifier_effect( - modifier_effect_cache.factory_throughput, "factory_throughput", true, PROPORTION_DECIMAL, COUNTRY + ret &= register_shared_tech_country_modifier_effect( + modifier_effect_cache.factory_throughput, "factory_throughput", true, PROPORTION_DECIMAL ); - ret &= add_modifier_effect( - modifier_effect_cache.global_assimilation_rate, "global_assimilation_rate", true, PROPORTION_DECIMAL, COUNTRY, + ret &= register_base_country_modifier_effect( + modifier_effect_cache.global_assimilation_rate, "global_assimilation_rate", true, PROPORTION_DECIMAL, ModifierEffect::make_default_modifier_effect_localisation_key("assimilation_rate") ); - ret &= add_modifier_effect( - modifier_effect_cache.global_immigrant_attract, "global_immigrant_attract", true, PROPORTION_DECIMAL, COUNTRY, + ret &= register_base_country_modifier_effect( + modifier_effect_cache.global_immigrant_attract, "global_immigrant_attract", true, PROPORTION_DECIMAL, ModifierEffect::make_default_modifier_effect_localisation_key("immigant_attract") ); - ret &= add_modifier_effect( - modifier_effect_cache.global_pop_consciousness_modifier, "global_pop_consciousness_modifier", false, RAW_DECIMAL, - COUNTRY + ret &= register_base_country_modifier_effect( + modifier_effect_cache.global_pop_consciousness_modifier, "global_pop_consciousness_modifier", false, RAW_DECIMAL ); - ret &= add_modifier_effect( - modifier_effect_cache.global_pop_militancy_modifier, "global_pop_militancy_modifier", false, RAW_DECIMAL, COUNTRY + ret &= register_base_country_modifier_effect( + modifier_effect_cache.global_pop_militancy_modifier, "global_pop_militancy_modifier", false, RAW_DECIMAL ); - ret &= add_modifier_effect( - modifier_effect_cache.global_population_growth, "global_population_growth", true, PROPORTION_DECIMAL, COUNTRY, + ret &= register_base_country_modifier_effect( + modifier_effect_cache.global_population_growth, "global_population_growth", true, PROPORTION_DECIMAL, ModifierEffect::make_default_modifier_effect_localisation_key("population_growth") ); - ret &= add_modifier_effect(modifier_effect_cache.goods_demand, "goods_demand", false, PROPORTION_DECIMAL, COUNTRY); - ret &= add_modifier_effect(modifier_effect_cache.import_cost, "import_cost", false, PROPORTION_DECIMAL, COUNTRY); - ret &= add_modifier_effect( - modifier_effect_cache.increase_research, "increase_research", true, PROPORTION_DECIMAL, COUNTRY, "INC_RES_TECH" + ret &= register_base_country_modifier_effect(modifier_effect_cache.goods_demand, "goods_demand", false, PROPORTION_DECIMAL); + ret &= register_base_country_modifier_effect(modifier_effect_cache.import_cost, "import_cost", false, PROPORTION_DECIMAL,{},has_no_effect); + ret &= register_technology_modifier_effect( + modifier_effect_cache.increase_research, "increase_research", true, PROPORTION_DECIMAL, "INC_RES_TECH" ); - ret &= add_modifier_effect( - modifier_effect_cache.influence, "influence", true, PROPORTION_DECIMAL, COUNTRY, "TECH_GP_INFLUENCE" + ret &= register_technology_modifier_effect( + modifier_effect_cache.influence, "influence", true, PROPORTION_DECIMAL, "TECH_GP_INFLUENCE" ); - ret &= add_modifier_effect( - modifier_effect_cache.influence_modifier, "influence_modifier", true, PROPORTION_DECIMAL, COUNTRY, + ret &= register_base_country_modifier_effect( + modifier_effect_cache.influence_modifier, "influence_modifier", true, PROPORTION_DECIMAL, ModifierEffect::make_default_modifier_effect_localisation_key("greatpower_influence_gain") ); - ret &= add_modifier_effect( - modifier_effect_cache.issue_change_speed, "issue_change_speed", true, PROPORTION_DECIMAL, COUNTRY + ret &= register_base_country_modifier_effect( + modifier_effect_cache.issue_change_speed, "issue_change_speed", true, PROPORTION_DECIMAL ); - ret &= add_modifier_effect( - modifier_effect_cache.land_attack_modifier, "land_attack_modifier", true, PROPORTION_DECIMAL, COUNTRY, + ret &= register_base_country_modifier_effect( + modifier_effect_cache.land_attack_modifier, "land_attack_modifier", true, PROPORTION_DECIMAL, ModifierEffect::make_default_modifier_effect_localisation_key("land_attack") ); - ret &= add_modifier_effect( - modifier_effect_cache.land_attrition, "land_attrition", false, PROPORTION_DECIMAL, COUNTRY, "LAND_ATTRITION_TECH" + ret &= register_technology_modifier_effect( + modifier_effect_cache.land_attrition, "land_attrition", false, PROPORTION_DECIMAL, "LAND_ATTRITION_TECH" ); - ret &= add_modifier_effect( - modifier_effect_cache.land_defense_modifier, "land_defense_modifier", true, PROPORTION_DECIMAL, COUNTRY, + ret &= register_base_country_modifier_effect( + modifier_effect_cache.land_defense_modifier, "land_defense_modifier", true, PROPORTION_DECIMAL, ModifierEffect::make_default_modifier_effect_localisation_key("land_defense") ); - ret &= add_modifier_effect( - modifier_effect_cache.land_organisation, "land_organisation", true, PROPORTION_DECIMAL, COUNTRY + ret &= register_base_country_modifier_effect( + modifier_effect_cache.land_organisation, "land_organisation", true, PROPORTION_DECIMAL ); - ret &= add_modifier_effect( - modifier_effect_cache.land_unit_start_experience, "land_unit_start_experience", true, RAW_DECIMAL, COUNTRY + ret &= register_base_country_modifier_effect( + modifier_effect_cache.land_unit_start_experience, "land_unit_start_experience", true, RAW_DECIMAL ); - ret &= add_modifier_effect(modifier_effect_cache.leadership, "leadership", true, RAW_DECIMAL, COUNTRY, "LEADERSHIP"); - ret &= add_modifier_effect( - modifier_effect_cache.leadership_modifier, "leadership_modifier", true, PROPORTION_DECIMAL, COUNTRY, + ret &= register_base_country_modifier_effect(modifier_effect_cache.leadership, "leadership", true, RAW_DECIMAL, "LEADERSHIP"); + ret &= register_base_country_modifier_effect( + modifier_effect_cache.leadership_modifier, "leadership_modifier", true, PROPORTION_DECIMAL, ModifierEffect::make_default_modifier_effect_localisation_key("global_leadership_modifier") ); - ret &= add_modifier_effect( - modifier_effect_cache.literacy_con_impact, "literacy_con_impact", false, PROPORTION_DECIMAL, COUNTRY + ret &= register_base_country_modifier_effect( + modifier_effect_cache.literacy_con_impact, "literacy_con_impact", false, PROPORTION_DECIMAL ); - ret &= add_modifier_effect(modifier_effect_cache.loan_interest, "loan_interest", false, PROPORTION_DECIMAL, COUNTRY); - ret &= add_modifier_effect( - modifier_effect_cache.max_loan_modifier, "max_loan_modifier", true, PROPORTION_DECIMAL, COUNTRY, + ret &= register_technology_modifier_effect(modifier_effect_cache.loan_interest_base, "loan_interest", false, PROPORTION_DECIMAL); + ret &= register_base_country_modifier_effect(modifier_effect_cache.loan_interest_foreign, "loan_interest", false, PROPORTION_DECIMAL); + ret &= register_base_country_modifier_effect( + modifier_effect_cache.max_loan_modifier, "max_loan_modifier", true, PROPORTION_DECIMAL, ModifierEffect::make_default_modifier_effect_localisation_key("max_loan_amount") ); - ret &= add_modifier_effect( - modifier_effect_cache.max_military_spending, "max_military_spending", true, PROPORTION_DECIMAL, COUNTRY + ret &= register_base_country_modifier_effect( + modifier_effect_cache.max_military_spending, "max_military_spending", true, PROPORTION_DECIMAL ); - ret &= add_modifier_effect( - modifier_effect_cache.max_national_focus, "max_national_focus", true, INT, COUNTRY, "TECH_MAX_FOCUS" + ret &= register_technology_modifier_effect( + modifier_effect_cache.max_national_focus, "max_national_focus", true, INT, "TECH_MAX_FOCUS" ); - ret &= add_modifier_effect( - modifier_effect_cache.max_social_spending, "max_social_spending", true, PROPORTION_DECIMAL, COUNTRY + ret &= register_base_country_modifier_effect( + modifier_effect_cache.max_social_spending, "max_social_spending", true, PROPORTION_DECIMAL ); - ret &= add_modifier_effect(modifier_effect_cache.max_tariff, "max_tariff", true, PROPORTION_DECIMAL, COUNTRY); - ret &= add_modifier_effect(modifier_effect_cache.max_tax, "max_tax", true, PROPORTION_DECIMAL, COUNTRY); - ret &= add_modifier_effect( - modifier_effect_cache.max_war_exhaustion, "max_war_exhaustion", true, PERCENTAGE_DECIMAL, COUNTRY, "MAX_WAR_EXHAUSTION" + ret &= register_base_country_modifier_effect(modifier_effect_cache.max_tariff, "max_tariff", true, PROPORTION_DECIMAL); + ret &= register_base_country_modifier_effect(modifier_effect_cache.max_tax, "max_tax", true, PROPORTION_DECIMAL); + ret &= register_base_country_modifier_effect( + modifier_effect_cache.max_war_exhaustion, "max_war_exhaustion", true, PERCENTAGE_DECIMAL, "MAX_WAR_EXHAUSTION" ); - ret &= add_modifier_effect( - modifier_effect_cache.military_tactics, "military_tactics", true, PROPORTION_DECIMAL, COUNTRY, "MIL_TACTICS_TECH" + ret &= register_technology_modifier_effect( + modifier_effect_cache.military_tactics, "military_tactics", true, PROPORTION_DECIMAL, "MIL_TACTICS_TECH" ); - ret &= add_modifier_effect( - modifier_effect_cache.min_military_spending, "min_military_spending", true, PROPORTION_DECIMAL, COUNTRY + ret &= register_base_country_modifier_effect( + modifier_effect_cache.min_military_spending, "min_military_spending", true, PROPORTION_DECIMAL ); - ret &= add_modifier_effect( - modifier_effect_cache.min_social_spending, "min_social_spending", true, PROPORTION_DECIMAL, COUNTRY + ret &= register_base_country_modifier_effect( + modifier_effect_cache.min_social_spending, "min_social_spending", true, PROPORTION_DECIMAL ); - ret &= add_modifier_effect(modifier_effect_cache.min_tariff, "min_tariff", true, PROPORTION_DECIMAL, COUNTRY); - ret &= add_modifier_effect(modifier_effect_cache.min_tax, "min_tax", true, PROPORTION_DECIMAL, COUNTRY); - ret &= add_modifier_effect( - modifier_effect_cache.minimum_wage, "minimum_wage", true, PROPORTION_DECIMAL, COUNTRY, + ret &= register_base_country_modifier_effect(modifier_effect_cache.min_tariff, "min_tariff", true, PROPORTION_DECIMAL); + ret &= register_base_country_modifier_effect(modifier_effect_cache.min_tax, "min_tax", true, PROPORTION_DECIMAL); + ret &= register_base_country_modifier_effect( + modifier_effect_cache.minimum_wage, "minimum_wage", true, PROPORTION_DECIMAL, ModifierEffect::make_default_modifier_effect_localisation_key("minimun_wage") ); - ret &= add_modifier_effect( - modifier_effect_cache.mobilisation_economy_impact, "mobilisation_economy_impact", false, PROPORTION_DECIMAL, COUNTRY + ret &= register_shared_tech_country_modifier_effect( + modifier_effect_cache.mobilisation_economy_impact, "mobilisation_economy_impact", false, PROPORTION_DECIMAL ); - ret &= add_modifier_effect( - modifier_effect_cache.mobilisation_size, "mobilisation_size", true, PROPORTION_DECIMAL, COUNTRY + ret &= register_shared_tech_country_modifier_effect( + modifier_effect_cache.mobilisation_size, "mobilisation_size", true, PROPORTION_DECIMAL ); - ret &= add_modifier_effect( - modifier_effect_cache.mobilization_impact, "mobilization_impact", false, PROPORTION_DECIMAL, COUNTRY + ret &= register_base_country_modifier_effect( + modifier_effect_cache.mobilization_impact, "mobilization_impact", false, PROPORTION_DECIMAL ); - ret &= add_modifier_effect( - modifier_effect_cache.naval_attack_modifier, "naval_attack_modifier", true, PROPORTION_DECIMAL, COUNTRY, + ret &= register_technology_modifier_effect(modifier_effect_cache.morale_global, "morale", true, PROPORTION_DECIMAL, "MORALE_TECH"); + ret &= register_base_country_modifier_effect( + modifier_effect_cache.naval_attack_modifier, "naval_attack_modifier", true, PROPORTION_DECIMAL, ModifierEffect::make_default_modifier_effect_localisation_key("naval_attack") ); - ret &= add_modifier_effect( - modifier_effect_cache.naval_attrition, "naval_attrition", false, PROPORTION_DECIMAL, COUNTRY, "NAVAL_ATTRITION_TECH" + ret &= register_technology_modifier_effect( + modifier_effect_cache.naval_attrition, "naval_attrition", false, PROPORTION_DECIMAL, "NAVAL_ATTRITION_TECH" ); - ret &= add_modifier_effect( - modifier_effect_cache.naval_defense_modifier, "naval_defense_modifier", true, PROPORTION_DECIMAL, COUNTRY, + ret &= register_base_country_modifier_effect( + modifier_effect_cache.naval_defense_modifier, "naval_defense_modifier", true, PROPORTION_DECIMAL, ModifierEffect::make_default_modifier_effect_localisation_key("naval_defense") ); - ret &= add_modifier_effect( - modifier_effect_cache.naval_organisation, "naval_organisation", true, PROPORTION_DECIMAL, COUNTRY + ret &= register_base_country_modifier_effect( + modifier_effect_cache.naval_organisation, "naval_organisation", true, PROPORTION_DECIMAL ); - ret &= add_modifier_effect( - modifier_effect_cache.naval_unit_start_experience, "naval_unit_start_experience", true, RAW_DECIMAL, COUNTRY + ret &= register_base_country_modifier_effect( + modifier_effect_cache.naval_unit_start_experience, "naval_unit_start_experience", true, RAW_DECIMAL ); - ret &= add_modifier_effect( + ret &= register_base_country_modifier_effect( modifier_effect_cache.non_accepted_pop_consciousness_modifier, "non_accepted_pop_consciousness_modifier", false, - RAW_DECIMAL, COUNTRY - ); - ret &= add_modifier_effect( - modifier_effect_cache.non_accepted_pop_militancy_modifier, "non_accepted_pop_militancy_modifier", false, RAW_DECIMAL, - COUNTRY + RAW_DECIMAL ); - ret &= add_modifier_effect(modifier_effect_cache.org_regain, "org_regain", true, PROPORTION_DECIMAL, COUNTRY); - ret &= add_modifier_effect(modifier_effect_cache.pension_level, "pension_level", true, PROPORTION_DECIMAL, COUNTRY); - ret &= add_modifier_effect( - modifier_effect_cache.permanent_prestige, "permanent_prestige", true, RAW_DECIMAL, COUNTRY, "PERMANENT_PRESTIGE_TECH" + ret &= register_base_country_modifier_effect( + modifier_effect_cache.non_accepted_pop_militancy_modifier, "non_accepted_pop_militancy_modifier", false, RAW_DECIMAL ); - ret &= add_modifier_effect( - modifier_effect_cache.political_reform_desire, "political_reform_desire", false, PROPORTION_DECIMAL, COUNTRY + ret &= register_base_country_modifier_effect(modifier_effect_cache.org_regain, "org_regain", true, PROPORTION_DECIMAL); + ret &= register_base_country_modifier_effect(modifier_effect_cache.pension_level, "pension_level", true, PROPORTION_DECIMAL); + ret &= register_technology_modifier_effect( + modifier_effect_cache.permanent_prestige, "permanent_prestige", true, RAW_DECIMAL, "PERMANENT_PRESTIGE_TECH" ); - ret &= add_modifier_effect( - modifier_effect_cache.poor_savings_modifier, "poor_savings_modifier", true, PROPORTION_DECIMAL, COUNTRY + ret &= register_shared_tech_country_modifier_effect( + modifier_effect_cache.political_reform_desire, "political_reform_desire", false, PROPORTION_DECIMAL ); - ret &= add_modifier_effect( - modifier_effect_cache.prestige_monthly_gain, "prestige monthly_gain", true, RAW_DECIMAL, COUNTRY, - ModifierEffect::make_default_modifier_effect_localisation_key(prestige) - ); - ret &= register_modifier_effect_variants( - prestige, modifier_effect_cache.prestige_monthly_gain, { EVENT, STATIC, TRIGGERED } + + ret &= register_technology_modifier_effect( modifier_effect_cache.poor_savings_modifier, "poor_savings_modifier", true, PROPORTION_DECIMAL,{},has_no_effect); + ret &= register_base_country_modifier_effect( + modifier_effect_cache.prestige_monthly_gain, "prestige", true, RAW_DECIMAL ); - ret &= add_modifier_effect(modifier_effect_cache.reinforce_speed, "reinforce_speed", true, PROPORTION_DECIMAL, COUNTRY); - ret &= add_modifier_effect(modifier_effect_cache.research_points, "research_points", true, RAW_DECIMAL, COUNTRY); - ret &= add_modifier_effect( - modifier_effect_cache.research_points_modifier, "research_points_modifier", true, PROPORTION_DECIMAL, COUNTRY + ret &= register_base_country_modifier_effect(modifier_effect_cache.reinforce_speed, "reinforce_speed", true, PROPORTION_DECIMAL); + ret &= register_base_country_modifier_effect(modifier_effect_cache.research_points, "research_points", true, RAW_DECIMAL); + ret &= register_base_country_modifier_effect( + modifier_effect_cache.research_points_modifier, "research_points_modifier", true, PROPORTION_DECIMAL ); - ret &= add_modifier_effect( - modifier_effect_cache.research_points_on_conquer, "research_points_on_conquer", true, PROPORTION_DECIMAL, COUNTRY + ret &= register_base_country_modifier_effect( + modifier_effect_cache.research_points_on_conquer, "research_points_on_conquer", true, PROPORTION_DECIMAL ); - ret &= add_modifier_effect(modifier_effect_cache.rgo_output, "rgo_output", true, PROPORTION_DECIMAL, COUNTRY); - ret &= add_modifier_effect(modifier_effect_cache.rgo_throughput, "rgo_throughput", true, PROPORTION_DECIMAL, COUNTRY); - ret &= add_modifier_effect( - modifier_effect_cache.ruling_party_support, "ruling_party_support", true, PROPORTION_DECIMAL, COUNTRY + ret &= register_shared_tech_country_modifier_effect(modifier_effect_cache.rgo_output, "rgo_output", true, PROPORTION_DECIMAL); + ret &= register_shared_tech_country_modifier_effect(modifier_effect_cache.rgo_throughput, "rgo_throughput", true, PROPORTION_DECIMAL); + ret &= register_base_country_modifier_effect( + modifier_effect_cache.ruling_party_support, "ruling_party_support", true, PROPORTION_DECIMAL ); - ret &= add_modifier_effect( - modifier_effect_cache.self_unciv_economic_modifier, "self_unciv_economic_modifier", false, PROPORTION_DECIMAL, COUNTRY, + ret &= register_base_country_modifier_effect( + modifier_effect_cache.self_unciv_economic_modifier, "self_unciv_economic_modifier", false, PROPORTION_DECIMAL, ModifierEffect::make_default_modifier_effect_localisation_key("self_unciv_economic") ); - ret &= add_modifier_effect( - modifier_effect_cache.self_unciv_military_modifier, "self_unciv_military_modifier", false, PROPORTION_DECIMAL, COUNTRY, + ret &= register_base_country_modifier_effect( + modifier_effect_cache.self_unciv_military_modifier, "self_unciv_military_modifier", false, PROPORTION_DECIMAL, ModifierEffect::make_default_modifier_effect_localisation_key("self_unciv_military") ); - ret &= add_modifier_effect( - modifier_effect_cache.social_reform_desire, "social_reform_desire", false, PROPORTION_DECIMAL, COUNTRY + ret &= register_shared_tech_country_modifier_effect( + modifier_effect_cache.social_reform_desire, "social_reform_desire", false, PROPORTION_DECIMAL ); - ret &= add_modifier_effect( - modifier_effect_cache.soldier_to_pop_loss, "soldier_to_pop_loss", true, PROPORTION_DECIMAL, COUNTRY, + ret &= register_technology_modifier_effect( + modifier_effect_cache.soldier_to_pop_loss, "soldier_to_pop_loss", true, PROPORTION_DECIMAL, "SOLDIER_TO_POP_LOSS_TECH" ); - ret &= add_modifier_effect( - modifier_effect_cache.supply_consumption, "supply_consumption", false, PROPORTION_DECIMAL, COUNTRY + ret &= register_base_country_modifier_effect( + modifier_effect_cache.supply_consumption, "supply_consumption", false, PROPORTION_DECIMAL ); - ret &= add_modifier_effect( - modifier_effect_cache.supply_range, "supply_range", true, PROPORTION_DECIMAL, COUNTRY, "SUPPLY_RANGE_TECH" + ret &= register_technology_modifier_effect( + modifier_effect_cache.supply_range, "supply_range", true, PROPORTION_DECIMAL, "SUPPLY_RANGE_TECH" ); - ret &= add_modifier_effect( - modifier_effect_cache.suppression_points_modifier, "suppression_points_modifier", true, PROPORTION_DECIMAL, COUNTRY, + ret &= register_shared_tech_country_modifier_effect( + modifier_effect_cache.suppression_points_modifier, "suppression_points_modifier", true, PROPORTION_DECIMAL, "SUPPRESSION_TECH" ); - ret &= add_modifier_effect( - modifier_effect_cache.tariff_efficiency_modifier, "tariff_efficiency_modifier", true, PROPORTION_DECIMAL, COUNTRY, + ret &= register_base_country_modifier_effect( + modifier_effect_cache.tariff_efficiency_modifier, "tariff_efficiency_modifier", true, PROPORTION_DECIMAL, ModifierEffect::make_default_modifier_effect_localisation_key("tariff_efficiency") ); - ret &= add_modifier_effect(modifier_effect_cache.tax_efficiency, "tax_efficiency", true, PROPORTION_DECIMAL, COUNTRY); - ret &= add_modifier_effect( - modifier_effect_cache.unemployment_benefit, "unemployment_benefit", true, PROPORTION_DECIMAL, COUNTRY + ret &= register_base_country_modifier_effect(modifier_effect_cache.tax_efficiency, "tax_efficiency", true, PROPORTION_DECIMAL); + ret &= register_base_country_modifier_effect( + modifier_effect_cache.unemployment_benefit, "unemployment_benefit", true, PROPORTION_DECIMAL ); - ret &= add_modifier_effect( - modifier_effect_cache.unciv_economic_modifier, "unciv_economic_modifier", false, PROPORTION_DECIMAL, COUNTRY, - ModifierEffect::make_default_modifier_effect_localisation_key("unciv_economic") + ret &= register_base_country_modifier_effect( + modifier_effect_cache.unciv_economic_modifier, "unciv_economic_modifier", false, PROPORTION_DECIMAL, + ModifierEffect::make_default_modifier_effect_localisation_key("unciv_economic"), has_no_effect ); - ret &= add_modifier_effect( - modifier_effect_cache.unciv_military_modifier, "unciv_military_modifier", false, PROPORTION_DECIMAL, COUNTRY, - ModifierEffect::make_default_modifier_effect_localisation_key("unciv_military") + ret &= register_base_country_modifier_effect( + modifier_effect_cache.unciv_military_modifier, "unciv_military_modifier", false, PROPORTION_DECIMAL, + ModifierEffect::make_default_modifier_effect_localisation_key("unciv_military"), has_no_effect ); - ret &= add_modifier_effect( - modifier_effect_cache.unit_recruitment_time, "unit_recruitment_time", false, PROPORTION_DECIMAL, COUNTRY + ret &= register_base_country_modifier_effect( + modifier_effect_cache.unit_recruitment_time, "unit_recruitment_time", false, PROPORTION_DECIMAL ); - ret &= add_modifier_effect( - modifier_effect_cache.war_exhaustion, "war_exhaustion", false, PROPORTION_DECIMAL, COUNTRY, "WAR_EXHAUST_BATTLES" + ret &= register_shared_tech_country_modifier_effect( + modifier_effect_cache.war_exhaustion, "war_exhaustion", false, PROPORTION_DECIMAL, "WAR_EXHAUST_BATTLES" ); /* Province Modifier Effects */ - ret &= add_modifier_effect( - modifier_effect_cache.assimilation_rate, "assimilation_rate", true, PROPORTION_DECIMAL, PROVINCE + ret &= register_base_province_modifier_effect( + modifier_effect_cache.assimilation_rate, "assimilation_rate", true, PROPORTION_DECIMAL ); - ret &= add_modifier_effect( - modifier_effect_cache.boost_strongest_party, "boost_strongest_party", false, PROPORTION_DECIMAL, PROVINCE + ret &= register_base_province_modifier_effect( + modifier_effect_cache.boost_strongest_party, "boost_strongest_party", false, PROPORTION_DECIMAL,{},has_no_effect ); // When applied to provinces (terrain), combat_width is a multiplicative proportional decimal value. - ret &= add_modifier_effect( - modifier_effect_cache.combat_width_percentage_change, "combat_width percentage_change", false, PROPORTION_DECIMAL, - PROVINCE, ModifierEffect::make_default_modifier_effect_localisation_key(combat_width) - ); - ret &= register_modifier_effect_variants(combat_width, modifier_effect_cache.combat_width_percentage_change, { TERRAIN }); - ret &= add_modifier_effect(modifier_effect_cache.defence_terrain, "defence terrain", true, INT, PROVINCE, "TRAIT_DEFEND"); - ret &= register_modifier_effect_variants(defence, modifier_effect_cache.defence_terrain, { TERRAIN }); - ret &= add_modifier_effect( - modifier_effect_cache.farm_rgo_eff, "farm_rgo_eff", true, PROPORTION_DECIMAL, PROVINCE, "TECH_FARM_OUTPUT" - ); - ret &= add_modifier_effect( - modifier_effect_cache.farm_rgo_size, "farm_rgo_size", true, PROPORTION_DECIMAL, PROVINCE, + ret &= register_base_province_modifier_effect( + modifier_effect_cache.combat_width_percentage_change, "combat_width", false, PROPORTION_DECIMAL + ); + ret &= register_terrain_modifier_effect(modifier_effect_cache.defence_terrain, "defence", true, INT, "TRAIT_DEFEND"); + ret &= register_technology_modifier_effect( + modifier_effect_cache.farm_rgo_throughput_global, "farm_rgo_eff", true, PROPORTION_DECIMAL, "TECH_FARM_OUTPUT" + ); + ret &= register_base_country_modifier_effect( + modifier_effect_cache.farm_rgo_output_global, "farm_rgo_eff", true, PROPORTION_DECIMAL, "TECH_FARM_OUTPUT" + ); + ret &= register_base_province_modifier_effect( + modifier_effect_cache.farm_rgo_output_local, "farm_rgo_eff", true, PROPORTION_DECIMAL, "TECH_FARM_OUTPUT" + ); + ret &= register_shared_tech_country_modifier_effect( + modifier_effect_cache.farm_rgo_size_global, "farm_rgo_size", true, PROPORTION_DECIMAL, + ModifierEffect::make_default_modifier_effect_localisation_key("farm_size") + ); + ret &= register_base_province_modifier_effect( + modifier_effect_cache.farm_rgo_size_local, "farm_rgo_size", true, PROPORTION_DECIMAL, ModifierEffect::make_default_modifier_effect_localisation_key("farm_size") ); - ret &= add_modifier_effect( - modifier_effect_cache.immigrant_attract, "immigrant_attract", true, PROPORTION_DECIMAL, PROVINCE, + ret &= register_base_province_modifier_effect( + modifier_effect_cache.immigrant_attract, "immigrant_attract", true, PROPORTION_DECIMAL, ModifierEffect::make_default_modifier_effect_localisation_key("immigant_attract") ); - ret &= add_modifier_effect( - modifier_effect_cache.immigrant_push, "immigrant_push", false, PROPORTION_DECIMAL, PROVINCE, + ret &= register_base_province_modifier_effect( + modifier_effect_cache.immigrant_push, "immigrant_push", false, PROPORTION_DECIMAL, ModifierEffect::make_default_modifier_effect_localisation_key("immigant_push") ); - ret &= add_modifier_effect(modifier_effect_cache.life_rating, "life_rating", true, PROPORTION_DECIMAL, PROVINCE); - ret &= add_modifier_effect( - modifier_effect_cache.local_artisan_input, "local_artisan_input", false, PROPORTION_DECIMAL, PROVINCE, - ModifierEffect::make_default_modifier_effect_localisation_key("artisan_input") + ret &= register_base_province_modifier_effect(modifier_effect_cache.life_rating, "life_rating", true, PROPORTION_DECIMAL); + ret &= register_base_province_modifier_effect( + modifier_effect_cache.local_artisan_input, "local_artisan_input", false, PROPORTION_DECIMAL, + ModifierEffect::make_default_modifier_effect_localisation_key("artisan_input"), + has_no_effect ); - ret &= add_modifier_effect( - modifier_effect_cache.local_artisan_output, "local_artisan_output", true, PROPORTION_DECIMAL, PROVINCE, - ModifierEffect::make_default_modifier_effect_localisation_key("artisan_output") + ret &= register_base_province_modifier_effect( + modifier_effect_cache.local_artisan_output, "local_artisan_output", true, PROPORTION_DECIMAL, + ModifierEffect::make_default_modifier_effect_localisation_key("artisan_output"), + has_no_effect ); - ret &= add_modifier_effect( - modifier_effect_cache.local_artisan_throughput, "local_artisan_throughput", true, PROPORTION_DECIMAL, PROVINCE, - ModifierEffect::make_default_modifier_effect_localisation_key("artisan_throughput") + ret &= register_base_province_modifier_effect( + modifier_effect_cache.local_artisan_throughput, "local_artisan_throughput", true, PROPORTION_DECIMAL, + ModifierEffect::make_default_modifier_effect_localisation_key("artisan_throughput"), + has_no_effect ); - ret &= add_modifier_effect( - modifier_effect_cache.local_factory_input, "local_factory_input", false, PROPORTION_DECIMAL, PROVINCE, + ret &= register_base_province_modifier_effect( + modifier_effect_cache.local_factory_input, "local_factory_input", false, PROPORTION_DECIMAL, ModifierEffect::make_default_modifier_effect_localisation_key("factory_input") ); - ret &= add_modifier_effect( - modifier_effect_cache.local_factory_output, "local_factory_output", true, PROPORTION_DECIMAL, PROVINCE, + ret &= register_base_province_modifier_effect( + modifier_effect_cache.local_factory_output, "local_factory_output", true, PROPORTION_DECIMAL, ModifierEffect::make_default_modifier_effect_localisation_key("factory_output") ); - ret &= add_modifier_effect( - modifier_effect_cache.local_factory_throughput, "local_factory_throughput", true, PROPORTION_DECIMAL, PROVINCE, + ret &= register_base_province_modifier_effect( + modifier_effect_cache.local_factory_throughput, "local_factory_throughput", true, PROPORTION_DECIMAL, ModifierEffect::make_default_modifier_effect_localisation_key("factory_throughput") ); - ret &= add_modifier_effect(modifier_effect_cache.local_repair, "local_repair", true, PROPORTION_DECIMAL, PROVINCE); - ret &= add_modifier_effect( - modifier_effect_cache.local_rgo_output, "local_rgo_output", true, PROPORTION_DECIMAL, PROVINCE, + ret &= register_base_province_modifier_effect(modifier_effect_cache.local_repair, "local_repair", true, PROPORTION_DECIMAL); + ret &= register_base_province_modifier_effect( + modifier_effect_cache.local_rgo_output, "local_rgo_output", true, PROPORTION_DECIMAL, ModifierEffect::make_default_modifier_effect_localisation_key("rgo_output") ); - ret &= add_modifier_effect( - modifier_effect_cache.local_rgo_throughput, "local_rgo_throughput", true, PROPORTION_DECIMAL, PROVINCE, + ret &= register_base_province_modifier_effect( + modifier_effect_cache.local_rgo_throughput, "local_rgo_throughput", true, PROPORTION_DECIMAL, ModifierEffect::make_default_modifier_effect_localisation_key("rgo_throughput") ); - ret &= add_modifier_effect( - modifier_effect_cache.local_ruling_party_support, "local_ruling_party_support", true, PROPORTION_DECIMAL, PROVINCE, + ret &= register_base_province_modifier_effect( + modifier_effect_cache.local_ruling_party_support, "local_ruling_party_support", true, PROPORTION_DECIMAL, ModifierEffect::make_default_modifier_effect_localisation_key("ruling_party_support") ); - ret &= add_modifier_effect( - modifier_effect_cache.local_ship_build, "local_ship_build", false, PROPORTION_DECIMAL, PROVINCE + ret &= register_base_province_modifier_effect( + modifier_effect_cache.local_ship_build, "local_ship_build", false, PROPORTION_DECIMAL ); - ret &= add_modifier_effect(modifier_effect_cache.max_attrition, "max_attrition", false, RAW_DECIMAL, PROVINCE); - ret &= add_modifier_effect( - modifier_effect_cache.mine_rgo_eff, "mine_rgo_eff", true, PROPORTION_DECIMAL, PROVINCE, "TECH_MINE_OUTPUT" + ret &= register_base_province_modifier_effect(modifier_effect_cache.max_attrition, "max_attrition", false, RAW_DECIMAL); + ret &= register_technology_modifier_effect( + modifier_effect_cache.mine_rgo_throughput_global, "mine_rgo_eff", true, PROPORTION_DECIMAL, "TECH_MINE_OUTPUT" ); - ret &= add_modifier_effect( - modifier_effect_cache.mine_rgo_size, "mine_rgo_size", true, PROPORTION_DECIMAL, PROVINCE, + ret &= register_base_country_modifier_effect( + modifier_effect_cache.mine_rgo_output_global, "mine_rgo_eff", true, PROPORTION_DECIMAL, "TECH_MINE_OUTPUT" + ); + ret &= register_base_province_modifier_effect( + modifier_effect_cache.mine_rgo_output_local, "mine_rgo_eff", true, PROPORTION_DECIMAL, "TECH_MINE_OUTPUT" + ); + ret &= register_shared_tech_country_modifier_effect( + modifier_effect_cache.mine_rgo_size_global, "mine_rgo_size", true, PROPORTION_DECIMAL, ModifierEffect::make_default_modifier_effect_localisation_key("mine_size") ); - ret &= add_modifier_effect( - modifier_effect_cache.movement_cost_base, "movement_cost base", true, PROPORTION_DECIMAL, PROVINCE, - ModifierEffect::make_default_modifier_effect_localisation_key(movement_cost) + ret &= register_base_province_modifier_effect( + modifier_effect_cache.mine_rgo_size_local, "mine_rgo_size", true, PROPORTION_DECIMAL, + ModifierEffect::make_default_modifier_effect_localisation_key("mine_size") ); - ret &= register_modifier_effect_variants(movement_cost, modifier_effect_cache.movement_cost_base, { TERRAIN }); - ret &= add_modifier_effect( - modifier_effect_cache.movement_cost_percentage_change, "movement_cost percentage_change", false, PROPORTION_DECIMAL, - PROVINCE, ModifierEffect::make_default_modifier_effect_localisation_key(movement_cost) + ret &= register_terrain_modifier_effect( + modifier_effect_cache.movement_cost_base, "movement_cost", true, PROPORTION_DECIMAL ); - ret &= register_modifier_effect_variants( - movement_cost, modifier_effect_cache.movement_cost_percentage_change, { EVENT, BUILDING } + ret &= register_base_country_modifier_effect( + modifier_effect_cache.movement_cost_percentage_change, "movement_cost", false, PROPORTION_DECIMAL ); - ret &= add_modifier_effect( - modifier_effect_cache.number_of_voters, "number_of_voters", false, PROPORTION_DECIMAL, PROVINCE + ret &= register_base_province_modifier_effect( + modifier_effect_cache.number_of_voters, "number_of_voters", false, PROPORTION_DECIMAL ); - ret &= add_modifier_effect( - modifier_effect_cache.pop_consciousness_modifier, "pop_consciousness_modifier", false, RAW_DECIMAL, PROVINCE + ret &= register_base_province_modifier_effect( + modifier_effect_cache.pop_consciousness_modifier, "pop_consciousness_modifier", false, RAW_DECIMAL ); - ret &= add_modifier_effect( - modifier_effect_cache.pop_militancy_modifier, "pop_militancy_modifier", false, RAW_DECIMAL, PROVINCE + ret &= register_base_province_modifier_effect( + modifier_effect_cache.pop_militancy_modifier, "pop_militancy_modifier", false, RAW_DECIMAL ); - ret &= add_modifier_effect( - modifier_effect_cache.population_growth, "population_growth", true, PROPORTION_DECIMAL, PROVINCE + ret &= register_base_province_modifier_effect( + modifier_effect_cache.population_growth, "population_growth", true, PROPORTION_DECIMAL ); - ret &= add_modifier_effect(modifier_effect_cache.supply_limit, "supply_limit", true, RAW_DECIMAL, PROVINCE); + ret &= register_technology_modifier_effect(modifier_effect_cache.supply_limit_global_percentage_change, "supply_limit", true, RAW_DECIMAL); + ret &= register_base_country_modifier_effect(modifier_effect_cache.supply_limit_global_base, "supply_limit", true, RAW_DECIMAL); + ret &= register_base_province_modifier_effect(modifier_effect_cache.supply_limit_local_base, "supply_limit", true, RAW_DECIMAL); /* Military Modifier Effects */ - ret &= add_modifier_effect(modifier_effect_cache.attack, "attack", true, INT, UNIT, "TRAIT_ATTACK"); - ret &= add_modifier_effect(modifier_effect_cache.attrition, "attrition", false, RAW_DECIMAL, UNIT, "ATTRITION"); - ret &= add_modifier_effect(modifier_effect_cache.defence_leader, "defence leader", true, INT, UNIT, "TRAIT_DEFEND"); - ret &= register_modifier_effect_variants(defence, modifier_effect_cache.defence_leader, { LEADER }); - ret &= add_modifier_effect( - modifier_effect_cache.experience, "experience", true, PROPORTION_DECIMAL, UNIT, "TRAIT_EXPERIENCE" + ret &= register_leader_modifier_effect(modifier_effect_cache.attack_leader, "attack", true, INT, "TRAIT_ATTACK"); + ret &= register_leader_modifier_effect(modifier_effect_cache.attrition, "attrition", false, RAW_DECIMAL, "ATTRITION"); + ret &= register_leader_modifier_effect(modifier_effect_cache.defence_leader, "defence", true, INT, "TRAIT_DEFEND"); + ret &= register_leader_modifier_effect( + modifier_effect_cache.experience, "experience", true, PROPORTION_DECIMAL, "TRAIT_EXPERIENCE" ); - ret &= add_modifier_effect(modifier_effect_cache.morale, "morale", true, PROPORTION_DECIMAL, UNIT, "TRAIT_MORALE"); - ret &= add_modifier_effect( - modifier_effect_cache.organisation, "organisation", true, PROPORTION_DECIMAL, UNIT, "TRAIT_ORGANISATION" + ret &= register_leader_modifier_effect(modifier_effect_cache.morale_leader, "morale", true, PROPORTION_DECIMAL, "TRAIT_MORALE"); + ret &= register_leader_modifier_effect( + modifier_effect_cache.organisation, "organisation", true, PROPORTION_DECIMAL, "TRAIT_ORGANISATION" ); - ret &= add_modifier_effect( - modifier_effect_cache.reconnaissance, "reconnaissance", true, PROPORTION_DECIMAL, UNIT, "TRAIT_RECONAISSANCE" + ret &= register_leader_modifier_effect( + modifier_effect_cache.reconnaissance, "reconnaissance", true, PROPORTION_DECIMAL, "TRAIT_RECONAISSANCE" ); - ret &= add_modifier_effect(modifier_effect_cache.reliability, "reliability", true, RAW_DECIMAL, UNIT, "TRAIT_RELIABILITY"); - ret &= add_modifier_effect(modifier_effect_cache.speed, "speed", true, PROPORTION_DECIMAL, UNIT, "TRAIT_SPEED"); + ret &= register_leader_modifier_effect(modifier_effect_cache.reliability, "reliability", true, RAW_DECIMAL, "TRAIT_RELIABILITY"); + ret &= register_leader_modifier_effect(modifier_effect_cache.speed, "speed", true, PROPORTION_DECIMAL, "TRAIT_SPEED"); return ret; } -bool ModifierManager::register_complex_modifier(std::string_view identifier) { +bool ModifierManager::register_complex_modifier(const std::string_view identifier) { if (complex_modifiers.emplace(identifier).second) { return true; } else { @@ -509,56 +558,18 @@ bool ModifierManager::register_complex_modifier(std::string_view identifier) { } std::string ModifierManager::get_flat_identifier( - std::string_view complex_modifier_identifier, std::string_view variant_identifier + const std::string_view complex_modifier_identifier, + const std::string_view variant_identifier ) { return StringUtils::append_string_views(complex_modifier_identifier, " ", variant_identifier); } -// We use std::string const& identifier instead of std::string_view identifier as the map [] lookup operator only accepts -// strings. In order to use string_views we need to use the find method but that returns an iterator with a const references -// to the key and value (in order to prevent modification of the key), so it's simplest to just use [] with a string. -bool ModifierManager::register_modifier_effect_variants( - std::string const& identifier, ModifierEffect const* effect, std::vector<Modifier::modifier_type_t> const& types +bool ModifierManager::add_event_modifier( + const std::string_view identifier, + ModifierValue&& values, + const IconModifier::icon_t icon, + const Modifier::modifier_type_t type ) { - if (identifier.empty()) { - Logger::error("Invalid modifier effect variants identifier - empty!"); - return false; - } - - if (effect == nullptr) { - Logger::error("Invalid modifier effect variants effect for \"", identifier, "\" - nullptr!"); - return false; - } - - if (types.empty()) { - Logger::error("Invalid modifier effect variants types for \"", identifier, "\" - empty!"); - return false; - } - - effect_variant_map_t& variant_map = modifier_effect_variants[identifier]; - - bool ret = true; - - for (const Modifier::modifier_type_t type : types) { - ModifierEffect const*& variant_effect = variant_map[type]; - - if (variant_effect != nullptr) { - Logger::error( - "Duplicate modifier effect variant for \"", identifier, "\" with type \"", - Modifier::modifier_type_to_string(type), "\" - already registered as \"", - variant_effect->get_identifier(), "\", setting to \"", effect->get_identifier(), "\"" - ); - ret = false; - } - - variant_effect = effect; - } - - return ret; -} - -bool ModifierManager::add_event_modifier(std::string_view identifier, ModifierValue&& values, IconModifier::icon_t icon) { - using enum Modifier::modifier_type_t; if (identifier.empty()) { Logger::error("Invalid event modifier effect identifier - empty!"); @@ -566,22 +577,19 @@ bool ModifierManager::add_event_modifier(std::string_view identifier, ModifierVa } return event_modifiers.add_item( - { identifier, std::move(values), EVENT, icon }, duplicate_warning_callback + { identifier, std::move(values), type, icon }, duplicate_warning_callback ); } -bool ModifierManager::load_event_modifiers(ast::NodeCPtr root) { +bool ModifierManager::load_event_modifiers(const ast::NodeCPtr root) { const bool ret = expect_dictionary_reserve_length( event_modifiers, [this](std::string_view key, ast::NodeCPtr value) -> bool { - using enum Modifier::modifier_type_t; - ModifierValue modifier_value; IconModifier::icon_t icon = 0; - bool ret = expect_modifier_value_and_keys( - move_variable_callback(modifier_value), - EVENT, + bool ret = expect_dictionary_keys_and_default( + expect_province_event_modifier(modifier_value), "icon", ZERO_OR_ONE, expect_uint(assign_variable_callback(icon)) )(value); @@ -591,49 +599,18 @@ bool ModifierManager::load_event_modifiers(ast::NodeCPtr root) { } )(root); - lock_event_modifiers(); - return ret; } -bool ModifierManager::add_static_modifier(std::string_view identifier, ModifierValue&& values) { - using enum Modifier::modifier_type_t; - - if (identifier.empty()) { - Logger::error("Invalid static modifier effect identifier - empty!"); - return false; - } - - return static_modifiers.add_item( - { identifier, std::move(values), STATIC }, duplicate_warning_callback - ); -} - -bool ModifierManager::load_static_modifiers(ast::NodeCPtr root) { - bool ret = expect_dictionary_reserve_length( - static_modifiers, - [this](std::string_view key, ast::NodeCPtr value) -> bool { - using enum Modifier::modifier_type_t; - - ModifierValue modifier_value; - - bool ret = expect_modifier_value(move_variable_callback(modifier_value), STATIC)(value); - - ret &= add_static_modifier(key, std::move(modifier_value)); - - return ret; - } - )(root); - - lock_static_modifiers(); - - ret &= static_modifier_cache.load_static_modifiers(*this); - - return ret; +bool ModifierManager::load_static_modifiers(const ast::NodeCPtr root) { + return static_modifier_cache.load_static_modifiers(*this, root); } bool ModifierManager::add_triggered_modifier( - std::string_view identifier, ModifierValue&& values, IconModifier::icon_t icon, ConditionScript&& trigger + const std::string_view identifier, + ModifierValue&& values, + const IconModifier::icon_t icon, + ConditionScript&& trigger ) { using enum Modifier::modifier_type_t; @@ -648,19 +625,16 @@ bool ModifierManager::add_triggered_modifier( ); } -bool ModifierManager::load_triggered_modifiers(ast::NodeCPtr root) { +bool ModifierManager::load_triggered_modifiers(const ast::NodeCPtr root) { const bool ret = expect_dictionary_reserve_length( triggered_modifiers, - [this](std::string_view key, ast::NodeCPtr value) -> bool { - using enum Modifier::modifier_type_t; - - ModifierValue modifier_value; + [this](const std::string_view key, const ast::NodeCPtr value) -> bool { + ModifierValue modifier_value {}; IconModifier::icon_t icon = 0; ConditionScript trigger { scope_t::COUNTRY, scope_t::COUNTRY, scope_t::NO_SCOPE }; - bool ret = expect_modifier_value_and_keys( - move_variable_callback(modifier_value), - TRIGGERED, + bool ret = expect_dictionary_keys_and_default( + expect_base_country_modifier(modifier_value), "icon", ZERO_OR_ONE, expect_uint(assign_variable_callback(icon)), "trigger", ONE_EXACTLY, trigger.expect_script() )(value); @@ -686,181 +660,140 @@ bool ModifierManager::parse_scripts(DefinitionManager const& definition_manager) return ret; } -key_value_callback_t ModifierManager::_modifier_effect_callback( - ModifierValue& modifier, Modifier::modifier_type_t type, key_value_callback_t default_callback, - ModifierEffectValidator auto effect_validator +bool ModifierManager::_add_flattened_modifier_cb( + ModifierValue& modifier_value, + const std::string_view prefix, + const std::string_view key, + const ast::NodeCPtr value ) const { - const auto add_modifier_cb = [this, &modifier, effect_validator]( - ModifierEffect const* effect, ast::NodeCPtr value - ) -> bool { - if (effect_validator(*effect)) { - static const case_insensitive_string_set_t no_effect_modifiers { - "boost_strongest_party", "poor_savings_modifier", "local_artisan_input", "local_artisan_throughput", - "local_artisan_output", "artisan_input", "artisan_throughput", "artisan_output", - "import_cost", "unciv_economic_modifier", "unciv_military_modifier" - }; - - if (no_effect_modifiers.contains(effect->get_identifier())) { - Logger::warning("This modifier does nothing: ", effect->get_identifier()); - } - - return expect_fixed_point(map_callback(modifier.values, effect))(value); - } else { - Logger::error("Failed to validate modifier effect: ", effect->get_identifier()); - return false; - } - }; - - const auto add_flattened_modifier_cb = [this, add_modifier_cb]( - std::string_view prefix, std::string_view key, ast::NodeCPtr value - ) -> bool { - const std::string flat_identifier = get_flat_identifier(prefix, key); - ModifierEffect const* effect = get_modifier_effect_by_identifier(flat_identifier); - if (effect != nullptr) { - return add_modifier_cb(effect, value); - } else { - Logger::error("Could not find flattened modifier: ", flat_identifier); - return false; - } - }; - - return [this, type, default_callback, add_modifier_cb, add_flattened_modifier_cb]( - std::string_view key, ast::NodeCPtr value - ) -> bool { - - if (dryad::node_has_kind<ast::IdentifierValue>(value)) { - ModifierEffect const* effect = get_modifier_effect_by_identifier(key); - - if (effect != nullptr) { - return add_modifier_cb(effect, value); - } else if (key == "war_exhaustion_effect") { - Logger::warning("war_exhaustion_effect does nothing (vanilla issues have it)."); - return true; - } else { - const decltype(modifier_effect_variants)::const_iterator effect_it = modifier_effect_variants.find(key); - - if (effect_it != modifier_effect_variants.end()) { - effect_variant_map_t const& variants = effect_it->second; - - const effect_variant_map_t::const_iterator variant_it = variants.find(type); - - if (variant_it != variants.end()) { - effect = variant_it->second; - - if (effect != nullptr) { - return add_modifier_cb(effect, value); - } - } - - Logger::error( - "Modifier effect \"", key, "\" does not have a valid variant for use in ", - Modifier::modifier_type_to_string(type), " modifiers." - ); - return false; - } - } - } else if (dryad::node_has_kind<ast::ListValue>(value) && complex_modifiers.contains(key)) { - if (key == "rebel_org_gain") { // because of course there's a special one - std::string_view faction_identifier; - ast::NodeCPtr value_node = nullptr; - - bool ret = expect_dictionary_keys( - "faction", ONE_EXACTLY, expect_identifier(assign_variable_callback(faction_identifier)), - "value", ONE_EXACTLY, assign_variable_callback(value_node) - )(value); - - ret &= add_flattened_modifier_cb(key, faction_identifier, value_node); - - return ret; - } else { - return expect_dictionary(std::bind_front(add_flattened_modifier_cb, key))(value); - } - } - - return default_callback(key, value); - }; -} + const std::string flat_identifier = get_flat_identifier(prefix, key); + ModifierEffect const* effect = technology_modifier_effects.get_item_by_identifier(flat_identifier); + if (effect != nullptr) { + return _add_modifier_cb(modifier_value, effect, value); + } else { + Logger::error("Could not find flattened modifier: ", flat_identifier); + return false; + } +}; -node_callback_t ModifierManager::expect_validated_modifier_value_and_default( - callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, key_value_callback_t default_callback, - ModifierEffectValidator auto effect_validator +bool ModifierManager::_add_modifier_cb( + ModifierValue& modifier_value, + ModifierEffect const* const effect, + const ast::NodeCPtr value ) const { - return [this, modifier_callback, type, default_callback, effect_validator](ast::NodeCPtr root) -> bool { - ModifierValue modifier; - - bool ret = expect_dictionary_reserve_length( - modifier.values, - _modifier_effect_callback(modifier, type, default_callback, effect_validator) - )(root); - - ret &= modifier_callback(std::move(modifier)); - - return ret; - }; + if (effect->has_no_effect()) { + Logger::warning("This modifier does nothing: ", effect->get_identifier()); + } + return expect_fixed_point(map_callback(modifier_value.values, effect))(value); } -node_callback_t ModifierManager::expect_validated_modifier_value( - callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, - ModifierEffectValidator auto effect_validator +NodeTools::key_value_callback_t ModifierManager::_expect_modifier_effect( + modifier_effect_registry_t const& registry, + ModifierValue& modifier_value ) const { - return expect_validated_modifier_value_and_default(modifier_callback, type, key_value_invalid_callback, effect_validator); + return _expect_modifier_effect_with_fallback(registry, modifier_value, key_value_invalid_callback); } - -node_callback_t ModifierManager::expect_modifier_value_and_default( - callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, key_value_callback_t default_callback +NodeTools::key_value_callback_t ModifierManager::_expect_modifier_effect_with_fallback( + modifier_effect_registry_t const& registry, + ModifierValue& modifier_value, + const NodeTools::key_value_callback_t fallback ) const { - return expect_validated_modifier_value_and_default( - modifier_callback, type, default_callback, [](ModifierEffect const&) -> bool { - return true; + return [this, ®istry, &modifier_value, fallback](const std::string_view key, const ast::NodeCPtr value) -> bool { + if (dryad::node_has_kind<ast::ListValue>(value) && complex_modifiers.contains(key)) { + return expect_dictionary([this, &modifier_value, key]( + const std::string_view inner_key, const ast::NodeCPtr inner_value + ) -> bool { + return _add_flattened_modifier_cb(modifier_value, key, inner_key, inner_value); + })(value); } - ); + + ModifierEffect const* effect = registry.get_item_by_identifier(key); + if (effect == nullptr) { + return fallback(key, value); + } + return _add_modifier_cb(modifier_value, effect, value); + }; } - -node_callback_t ModifierManager::expect_modifier_value( - callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type -) const { - return expect_modifier_value_and_default(modifier_callback, type, key_value_invalid_callback); +NodeTools::key_value_callback_t ModifierManager::_expect_shared_tech_country_modifier_effect(ModifierValue& modifier_value) const { + return _expect_modifier_effect(shared_tech_country_modifier_effects, modifier_value); } - -node_callback_t ModifierManager::expect_whitelisted_modifier_value_and_default( - callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, string_set_t const& whitelist, - key_value_callback_t default_callback -) const { - return expect_validated_modifier_value_and_default( - modifier_callback, type, default_callback, - [&whitelist](ModifierEffect const& effect) -> bool { - return whitelist.contains(effect.get_identifier()); - } - ); +NodeTools::key_value_callback_t ModifierManager::expect_leader_modifier(ModifierValue& modifier_value) const { + return _expect_modifier_effect(leader_modifier_effects, modifier_value); } +NodeTools::key_value_callback_t ModifierManager::expect_technology_modifier(ModifierValue& modifier_value) const { + return [this, &modifier_value](const std::string_view key, const ast::NodeCPtr value) { + if (strings_equal_case_insensitive(key, "rebel_org_gain")) { // because of course there's a special one + std::string_view faction_identifier; + ast::NodeCPtr value_node = nullptr; + + bool ret = expect_dictionary_keys( + "faction", ONE_EXACTLY, expect_identifier(assign_variable_callback(faction_identifier)), + "value", ONE_EXACTLY, assign_variable_callback(value_node) + )(value); -node_callback_t ModifierManager::expect_whitelisted_modifier_value( - callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, string_set_t const& whitelist -) const { - return expect_whitelisted_modifier_value_and_default(modifier_callback, type, whitelist, key_value_invalid_callback); -} + ret &= _add_flattened_modifier_cb(modifier_value, key, faction_identifier, value_node); -node_callback_t ModifierManager::expect_modifier_value_and_key_map_and_default( - callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, key_value_callback_t default_callback, - key_map_t&& key_map -) const { - return [this, modifier_callback, type, default_callback, key_map = std::move(key_map)]( - ast::NodeCPtr node - ) mutable -> bool { - bool ret = expect_modifier_value_and_default( - modifier_callback, type, dictionary_keys_callback(key_map, default_callback) - )(node); + return ret; + } - ret &= check_key_map_counts(key_map); + if (strings_equal_case_insensitive(key, "farm_rgo_eff")) { + return _add_modifier_cb(modifier_value, modifier_effect_cache.farm_rgo_throughput_global, value) + && _add_modifier_cb(modifier_value, modifier_effect_cache.farm_rgo_output_global, value); + } + + if (strings_equal_case_insensitive(key, "mine_rgo_eff")) { + return _add_modifier_cb(modifier_value, modifier_effect_cache.mine_rgo_throughput_global, value) + && _add_modifier_cb(modifier_value, modifier_effect_cache.mine_rgo_output_global, value); + } - return ret; + return _expect_modifier_effect_with_fallback( + technology_modifier_effects, + modifier_value, + _expect_shared_tech_country_modifier_effect(modifier_value) + )(key, value); }; } - -node_callback_t ModifierManager::expect_modifier_value_and_key_map( - callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, key_map_t&& key_map +NodeTools::key_value_callback_t ModifierManager::expect_unit_terrain_modifier( + ModifierValue& modifier_value, + const std::string_view terrain_type_identifier ) const { - return expect_modifier_value_and_key_map_and_default( - modifier_callback, type, key_value_invalid_callback, std::move(key_map) + return [this, &modifier_value, terrain_type_identifier](const std::string_view key, const ast::NodeCPtr value) -> bool { + const std::string flat_identifier = get_flat_identifier(key, terrain_type_identifier); + ModifierEffect const* effect = unit_terrain_modifier_effects.get_item_by_identifier(flat_identifier); + if (effect == nullptr) { + return key_value_invalid_callback(flat_identifier, value); + } + return _add_modifier_cb(modifier_value, effect, value); + }; +} +NodeTools::key_value_callback_t ModifierManager::expect_base_country_modifier(ModifierValue& modifier_value) const { + return _expect_modifier_effect_with_fallback( + base_country_modifier_effects, + modifier_value, + _expect_shared_tech_country_modifier_effect(modifier_value) ); } +NodeTools::key_value_callback_t ModifierManager::expect_base_province_modifier(ModifierValue& modifier_value) const { + return _expect_modifier_effect_with_fallback( + base_province_modifier_effects, + modifier_value, + expect_base_country_modifier(modifier_value) + ); +} +NodeTools::key_value_callback_t ModifierManager::expect_province_event_modifier(ModifierValue& modifier_value) const { + return [this, &modifier_value](const std::string_view key, const ast::NodeCPtr value) -> bool { + if (strings_equal_case_insensitive(key, "movement_cost")) { + return _add_modifier_cb(modifier_value, modifier_effect_cache.movement_cost_percentage_change, value); + } + else { + return expect_base_province_modifier(modifier_value)(key, value); + } + }; +} +NodeTools::key_value_callback_t ModifierManager::expect_terrain_modifier(ModifierValue& modifier_value) const { + return _expect_modifier_effect_with_fallback( + terrain_modifier_effects, + modifier_value, + expect_base_province_modifier(modifier_value) + ); +}
\ No newline at end of file diff --git a/src/openvic-simulation/modifier/ModifierManager.hpp b/src/openvic-simulation/modifier/ModifierManager.hpp index 51f89ae..49e3559 100644 --- a/src/openvic-simulation/modifier/ModifierManager.hpp +++ b/src/openvic-simulation/modifier/ModifierManager.hpp @@ -1,15 +1,13 @@ #pragma once +#include <string_view> + #include "openvic-simulation/modifier/Modifier.hpp" #include "openvic-simulation/modifier/ModifierEffectCache.hpp" #include "openvic-simulation/modifier/StaticModifierCache.hpp" #include "openvic-simulation/types/IdentifierRegistry.hpp" namespace OpenVic { - - template<typename Fn> - concept ModifierEffectValidator = std::predicate<Fn, ModifierEffect const&>; - struct ModifierManager { friend struct StaticModifierCache; friend struct BuildingTypeManager; @@ -18,127 +16,123 @@ namespace OpenVic { friend struct RebelManager; friend struct PopManager; friend struct TechnologyManager; + friend struct TerrainTypeManager; - using effect_variant_map_t = ordered_map<Modifier::modifier_type_t, ModifierEffect const*>; + using modifier_effect_registry_t = CaseInsensitiveIdentifierRegistry<ModifierEffect, RegistryStorageInfoDeque>; /* Some ModifierEffects are generated mid-load, such as max/min count modifiers for each building, so * we can't lock it until loading is over. This means we can't rely on locking for pointer stability, * so instead we store the effects in a deque which doesn't invalidate pointers on insert. */ private: - CaseInsensitiveIdentifierRegistry<ModifierEffect, RegistryStorageInfoDeque> IDENTIFIER_REGISTRY(modifier_effect); + modifier_effect_registry_t IDENTIFIER_REGISTRY(leader_modifier_effect); + modifier_effect_registry_t IDENTIFIER_REGISTRY(unit_terrain_modifier_effect); + modifier_effect_registry_t IDENTIFIER_REGISTRY(shared_tech_country_modifier_effect); + modifier_effect_registry_t IDENTIFIER_REGISTRY(technology_modifier_effect); + modifier_effect_registry_t IDENTIFIER_REGISTRY(base_country_modifier_effect); + modifier_effect_registry_t IDENTIFIER_REGISTRY(base_province_modifier_effect); + modifier_effect_registry_t IDENTIFIER_REGISTRY(terrain_modifier_effect); case_insensitive_string_set_t complex_modifiers; - string_map_t<effect_variant_map_t> modifier_effect_variants; IdentifierRegistry<IconModifier> IDENTIFIER_REGISTRY(event_modifier); - IdentifierRegistry<Modifier> IDENTIFIER_REGISTRY(static_modifier); IdentifierRegistry<TriggeredModifier> IDENTIFIER_REGISTRY(triggered_modifier); ModifierEffectCache PROPERTY(modifier_effect_cache); StaticModifierCache PROPERTY(static_modifier_cache); - - /* effect_validator takes in ModifierEffect const& */ - NodeTools::key_value_callback_t _modifier_effect_callback( - ModifierValue& modifier, Modifier::modifier_type_t type, NodeTools::key_value_callback_t default_callback, - ModifierEffectValidator auto effect_validator - ) const; - - public: - bool add_modifier_effect( - ModifierEffect const*& effect_cache, - std::string_view identifier, - bool positive_good, - ModifierEffect::format_t format, + + bool _register_modifier_effect( + modifier_effect_registry_t& registry, ModifierEffect::target_t targets, - std::string_view localisation_key = {} + ModifierEffect const*& effect_cache, + const std::string_view identifier, + const bool is_positive_good, + const ModifierEffect::format_t format, + const std::string_view localisation_key, + const bool has_no_effect ); - bool register_complex_modifier(std::string_view identifier); - static std::string get_flat_identifier( - std::string_view complex_modifier_identifier, std::string_view variant_identifier + +#define REGISTER_MODIFIER_EFFECT_DEFINITION(MAPPING_TYPE) \ + bool register_##MAPPING_TYPE##_modifier_effect( \ + ModifierEffect const*& effect_cache, \ + std::string_view identifier, \ + bool is_positive_good, \ + ModifierEffect::format_t format, \ + std::string_view localisation_key = {}, \ + bool has_no_effect = false \ ); - bool register_modifier_effect_variants( - std::string const& identifier, ModifierEffect const* effect, std::vector<Modifier::modifier_type_t> const& types - ); + REGISTER_MODIFIER_EFFECT_DEFINITION(leader) + REGISTER_MODIFIER_EFFECT_DEFINITION(unit_terrain) + REGISTER_MODIFIER_EFFECT_DEFINITION(shared_tech_country) + REGISTER_MODIFIER_EFFECT_DEFINITION(technology) + REGISTER_MODIFIER_EFFECT_DEFINITION(base_country) + REGISTER_MODIFIER_EFFECT_DEFINITION(base_province) + REGISTER_MODIFIER_EFFECT_DEFINITION(terrain) +#undef REGISTER_MODIFIER_EFFECT_DEFINITION + + bool _add_flattened_modifier_cb( + ModifierValue& modifier_value, + const std::string_view prefix, + const std::string_view key, + const ast::NodeCPtr value + ) const; + + bool _add_modifier_cb( + ModifierValue& modifier_value, + ModifierEffect const* const effect, + const ast::NodeCPtr value + ) const; + + NodeTools::key_value_callback_t _expect_modifier_effect( + modifier_effect_registry_t const& registry, + ModifierValue& modifier_value + ) const; + + NodeTools::key_value_callback_t _expect_modifier_effect_with_fallback( + modifier_effect_registry_t const& registry, + ModifierValue& modifier_value, + const NodeTools::key_value_callback_t fallback + ) const; + + NodeTools::key_value_callback_t _expect_shared_tech_country_modifier_effect(ModifierValue& modifier_value) const; + public: + + bool register_complex_modifier(const std::string_view identifier); + static std::string get_flat_identifier(const std::string_view complex_modifier_identifier, const std::string_view variant_identifier); bool setup_modifier_effects(); - bool add_event_modifier(std::string_view identifier, ModifierValue&& values, IconModifier::icon_t icon); - bool load_event_modifiers(ast::NodeCPtr root); + bool add_event_modifier( + const std::string_view identifier, + ModifierValue&& values, + const IconModifier::icon_t icon, + const Modifier::modifier_type_t type = Modifier::modifier_type_t::EVENT + ); + bool load_event_modifiers(const ast::NodeCPtr root); - bool add_static_modifier(std::string_view identifier, ModifierValue&& values); - bool load_static_modifiers(ast::NodeCPtr root); + bool load_static_modifiers(const ast::NodeCPtr root); bool add_triggered_modifier( - std::string_view identifier, ModifierValue&& values, IconModifier::icon_t icon, ConditionScript&& trigger + const std::string_view identifier, + ModifierValue&& values, + const IconModifier::icon_t icon, + ConditionScript&& trigger ); - bool load_triggered_modifiers(ast::NodeCPtr root); + bool load_triggered_modifiers(const ast::NodeCPtr root); bool parse_scripts(DefinitionManager const& definition_manager); + void lock_all_modifier_except_base_country_effects(); - NodeTools::node_callback_t expect_validated_modifier_value_and_default( - NodeTools::callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, - NodeTools::key_value_callback_t default_callback, ModifierEffectValidator auto effect_validator - ) const; - NodeTools::node_callback_t expect_validated_modifier_value( - NodeTools::callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, - ModifierEffectValidator auto effect_validator - ) const; - - NodeTools::node_callback_t expect_modifier_value_and_default( - NodeTools::callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, - NodeTools::key_value_callback_t default_callback + NodeTools::key_value_callback_t expect_leader_modifier(ModifierValue& modifier_value) const; + NodeTools::key_value_callback_t expect_technology_modifier(ModifierValue& modifier_value) const; + NodeTools::key_value_callback_t expect_unit_terrain_modifier( + ModifierValue& modifier_value, + const std::string_view terrain_type_identifier ) const; - NodeTools::node_callback_t expect_modifier_value( - NodeTools::callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type - ) const; - - NodeTools::node_callback_t expect_whitelisted_modifier_value_and_default( - NodeTools::callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, - string_set_t const& whitelist, NodeTools::key_value_callback_t default_callback - ) const; - NodeTools::node_callback_t expect_whitelisted_modifier_value( - NodeTools::callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, - string_set_t const& whitelist - ) const; - - // In the functions below, key_map refers to a map from identifier strings to NodeTools::dictionary_entry_t, - // allowing any non-modifier effect keys found to be parsed in a custom way, similar to expect_dictionary_keys. - NodeTools::node_callback_t expect_modifier_value_and_key_map_and_default( - NodeTools::callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, - NodeTools::key_value_callback_t default_callback, NodeTools::key_map_t&& key_map - ) const; - NodeTools::node_callback_t expect_modifier_value_and_key_map( - NodeTools::callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, - NodeTools::key_map_t&& key_map - ) const; - - template<typename... Args> - NodeTools::node_callback_t expect_modifier_value_and_key_map_and_default( - NodeTools::callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, - NodeTools::key_value_callback_t default_callback, NodeTools::key_map_t&& key_map, Args... args - ) const { - NodeTools::add_key_map_entries(key_map, args...); - return expect_modifier_value_and_key_map_and_default( - modifier_callback, type, default_callback, std::move(key_map) - ); - } - - template<typename... Args> - NodeTools::node_callback_t expect_modifier_value_and_keys_and_default( - NodeTools::callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, - NodeTools::key_value_callback_t default_callback, Args... args - ) const { - return expect_modifier_value_and_key_map_and_default(modifier_callback, type, default_callback, {}, args...); - } - template<typename... Args> - NodeTools::node_callback_t expect_modifier_value_and_keys( - NodeTools::callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, Args... args - ) const { - return expect_modifier_value_and_key_map_and_default( - modifier_callback, type, NodeTools::key_value_invalid_callback, {}, args... - ); - } + NodeTools::key_value_callback_t expect_base_country_modifier(ModifierValue& modifier_value) const; + NodeTools::key_value_callback_t expect_base_province_modifier(ModifierValue& modifier_value) const; + NodeTools::key_value_callback_t expect_province_event_modifier(ModifierValue& modifier_value) const; + NodeTools::key_value_callback_t expect_terrain_modifier(ModifierValue& modifier_value) const; }; } diff --git a/src/openvic-simulation/modifier/StaticModifierCache.cpp b/src/openvic-simulation/modifier/StaticModifierCache.cpp index b03d827..953b49b 100644 --- a/src/openvic-simulation/modifier/StaticModifierCache.cpp +++ b/src/openvic-simulation/modifier/StaticModifierCache.cpp @@ -1,115 +1,171 @@ #include "StaticModifierCache.hpp" +#include <string_view> + +#include "openvic-simulation/dataloader/NodeTools.hpp" +#include "openvic-simulation/modifier/Modifier.hpp" #include "openvic-simulation/modifier/ModifierManager.hpp" using namespace OpenVic; +using namespace OpenVic::NodeTools; +using enum Modifier::modifier_type_t; StaticModifierCache::StaticModifierCache() : // Country modifiers - very_easy_player { nullptr }, - easy_player { nullptr }, - hard_player { nullptr }, - very_hard_player { nullptr }, - very_easy_ai { nullptr }, - easy_ai { nullptr }, - hard_ai { nullptr }, - very_hard_ai { nullptr }, - base_modifier { nullptr }, - war { nullptr }, - peace { nullptr }, - disarming { nullptr }, - war_exhaustion { nullptr }, - infamy { nullptr }, - debt_default_to { nullptr }, - bad_debter { nullptr }, - great_power { nullptr }, - secondary_power { nullptr }, - civilised { nullptr }, - uncivilised { nullptr }, - literacy { nullptr }, - plurality { nullptr }, - generalised_debt_default { nullptr }, - total_occupation { nullptr }, - total_blockaded { nullptr }, + very_easy_player { "very_easy_player", {}, STATIC }, + easy_player { "easy_player", {}, STATIC }, + hard_player { "hard_player", {}, STATIC }, + very_hard_player { "very_hard_player", {}, STATIC }, + very_easy_ai { "very_easy_ai", {}, STATIC }, + easy_ai { "easy_ai", {}, STATIC }, + hard_ai { "hard_ai", {}, STATIC }, + very_hard_ai { "very_hard_ai", {}, STATIC }, + base_modifier { "base_values", {}, STATIC }, + war { "war", {}, STATIC }, + peace { "peace", {}, STATIC }, + disarming { "disarming", {}, STATIC }, + war_exhaustion { "war_exhaustion", {}, STATIC }, + infamy { "badboy", {}, STATIC }, + debt_default_to { "debt_default_to", {}, STATIC }, + great_power { "great_power", {}, STATIC }, + secondary_power { "second_power", {}, STATIC }, + civilised { "civ_nation", {}, STATIC }, + uncivilised { "unciv_nation", {}, STATIC }, + literacy { "average_literacy", {}, STATIC }, + plurality { "plurality", {}, STATIC }, + total_occupation { "total_occupation", {}, STATIC }, + total_blockaded { "total_blockaded", {}, STATIC }, in_bankruptcy { nullptr }, + bad_debtor { nullptr }, + generalised_debt_default { nullptr }, // Province modifiers - overseas { nullptr }, - coastal { nullptr }, - non_coastal { nullptr }, - coastal_sea { nullptr }, - sea_zone { nullptr }, - land_province { nullptr }, - blockaded { nullptr }, - no_adjacent_controlled { nullptr }, - core { nullptr }, - has_siege { nullptr }, - occupied { nullptr }, - nationalism { nullptr }, - infrastructure { nullptr } {} - -bool StaticModifierCache::load_static_modifiers(ModifierManager& modifier_manager) { + overseas { "overseas", {}, STATIC }, + coastal { "coastal", {}, STATIC }, + non_coastal { "non_coastal", {}, STATIC }, + coastal_sea { "coastal_sea", {}, STATIC }, + sea_zone { "sea_zone", {}, STATIC }, + land_province { "land_province", {}, STATIC }, + blockaded { "blockaded", {}, STATIC }, + no_adjacent_controlled { "no_adjacent_controlled", {}, STATIC }, + core { "core", {}, STATIC }, + has_siege { "has_siege", {}, STATIC }, + occupied { "occupied", {}, STATIC }, + nationalism { "nationalism", {}, STATIC }, + infrastructure { "infrastructure", {}, STATIC } {} + +bool StaticModifierCache::load_static_modifiers(ModifierManager& modifier_manager, const ast::NodeCPtr root) { bool ret = true; + key_map_t key_map {}; - const auto set_static_modifier = [&modifier_manager, &ret]( - Modifier const*& modifier, std::string_view name, fixed_point_t multiplier = 1 + const auto set_static_country_modifier = [&key_map, &modifier_manager, &ret]( + Modifier& modifier ) -> void { - Modifier* mutable_modifier = modifier_manager.static_modifiers.get_item_by_identifier(name); + ret &= add_key_map_entry( + key_map, modifier.get_identifier(), ONE_EXACTLY, + expect_dictionary(modifier_manager.expect_base_country_modifier(modifier)) + ); + }; + + const auto set_country_event_modifier = [&key_map, &modifier_manager, &ret]( + const std::string_view identifier, const IconModifier::icon_t icon + ) -> void { + ret &= add_key_map_entry( + key_map, identifier, ONE_EXACTLY, + [&modifier_manager, identifier, icon](const ast::NodeCPtr value) -> bool { + if (modifier_manager.get_event_modifier_by_identifier(identifier) != nullptr) { + return true; //an event modifier overrides a static modifier with the same identifier. + } - if (mutable_modifier != nullptr) { - if (multiplier != fixed_point_t::_1()) { - *mutable_modifier *= multiplier; + ModifierValue modifier_value {}; + bool has_parsed_modifier = expect_dictionary(modifier_manager.expect_base_country_modifier(modifier_value))(value); + has_parsed_modifier &= modifier_manager.add_event_modifier(identifier, std::move(modifier_value), icon, STATIC); + return has_parsed_modifier; } + ); + + }; - modifier = mutable_modifier; - } else { - Logger::error("Failed to set static modifier: ", name); - ret = false; - } + const auto set_static_province_modifier = [&key_map, &modifier_manager, &ret]( + Modifier& modifier + ) -> void { + ret &= add_key_map_entry( + key_map, modifier.get_identifier(), ONE_EXACTLY, + expect_dictionary(modifier_manager.expect_base_province_modifier(modifier)) + ); }; // Country modifiers - set_static_modifier(very_easy_player, "very_easy_player"); - set_static_modifier(easy_player, "easy_player"); - set_static_modifier(hard_player, "hard_player"); - set_static_modifier(very_hard_player, "very_hard_player"); - set_static_modifier(very_easy_ai, "very_easy_ai"); - set_static_modifier(easy_ai, "easy_ai"); - set_static_modifier(hard_ai, "hard_ai"); - set_static_modifier(very_hard_ai, "very_hard_ai"); - - set_static_modifier(base_modifier, "base_values"); - set_static_modifier(war, "war"); - set_static_modifier(peace, "peace"); - set_static_modifier(disarming, "disarming"); - set_static_modifier(war_exhaustion, "war_exhaustion"); - set_static_modifier(infamy, "badboy"); - set_static_modifier(debt_default_to, "debt_default_to"); - set_static_modifier(bad_debter, "bad_debter"); - set_static_modifier(great_power, "great_power"); - set_static_modifier(secondary_power, "second_power"); - set_static_modifier(civilised, "civ_nation"); - set_static_modifier(uncivilised, "unciv_nation"); - set_static_modifier(literacy, "average_literacy"); - set_static_modifier(plurality, "plurality"); - set_static_modifier(generalised_debt_default, "generalised_debt_default"); - set_static_modifier(total_occupation, "total_occupation", 100); - set_static_modifier(total_blockaded, "total_blockaded"); - set_static_modifier(in_bankruptcy, "in_bankrupcy"); + set_static_country_modifier(very_easy_player); + set_static_country_modifier(easy_player); + set_static_country_modifier(hard_player); + set_static_country_modifier(very_hard_player); + set_static_country_modifier(very_easy_ai); + set_static_country_modifier(easy_ai); + set_static_country_modifier(hard_ai); + set_static_country_modifier(very_hard_ai); + + ret &= add_key_map_entry( + key_map, base_modifier.get_identifier(), ONE_EXACTLY, + expect_dictionary_keys_and_default( + modifier_manager.expect_base_country_modifier(base_modifier), + "supply_limit", ZERO_OR_ONE, [this, &modifier_manager](const ast::NodeCPtr value) -> bool { + return modifier_manager._add_modifier_cb( + base_modifier, + modifier_manager.get_modifier_effect_cache().get_supply_limit_global_base(), + value + ); + } + ) + ); + + set_static_country_modifier(war); + set_static_country_modifier(peace); + set_static_country_modifier(disarming); + set_static_country_modifier(war_exhaustion); + set_static_country_modifier(infamy); + set_static_country_modifier(debt_default_to); + set_static_country_modifier(great_power); + set_static_country_modifier(secondary_power); + set_static_country_modifier(civilised); + set_static_country_modifier(uncivilised); + set_static_country_modifier(literacy); + set_static_country_modifier(plurality); + set_static_country_modifier(total_occupation); + set_static_country_modifier(total_blockaded); + + // Country Event modifiers + static constexpr IconModifier::icon_t default_icon = 0; + static constexpr std::string_view bad_debtor_id = "bad_debter"; //paradox typo + static constexpr std::string_view in_bankruptcy_id = "in_bankrupcy"; //paradox typo + static constexpr std::string_view generalised_debt_default_id = "generalised_debt_default"; + set_country_event_modifier(bad_debtor_id, default_icon); + set_country_event_modifier(in_bankruptcy_id, default_icon); + set_country_event_modifier(generalised_debt_default_id, default_icon); // Province modifiers - set_static_modifier(overseas, "overseas"); - set_static_modifier(coastal, "coastal"); - set_static_modifier(non_coastal, "non_coastal"); - set_static_modifier(coastal_sea, "coastal_sea"); - set_static_modifier(sea_zone, "sea_zone"); - set_static_modifier(land_province, "land_province"); - set_static_modifier(blockaded, "blockaded"); - set_static_modifier(no_adjacent_controlled, "no_adjacent_controlled"); - set_static_modifier(core, "core"); - set_static_modifier(has_siege, "has_siege"); - set_static_modifier(occupied, "occupied"); - set_static_modifier(nationalism, "nationalism"); - set_static_modifier(infrastructure, "infrastructure"); + set_static_province_modifier(overseas); + set_static_province_modifier(coastal); + set_static_province_modifier(non_coastal); + set_static_province_modifier(coastal_sea); + set_static_province_modifier(sea_zone); + set_static_province_modifier(land_province); + set_static_province_modifier(blockaded); + set_static_province_modifier(no_adjacent_controlled); + set_static_province_modifier(core); + set_static_province_modifier(has_siege); + set_static_province_modifier(occupied); + set_static_province_modifier(nationalism); + set_static_province_modifier(infrastructure); + + + ret &= expect_dictionary_key_map_and_default(key_map, key_value_invalid_callback)(root); + + if (ret) { + bad_debtor = modifier_manager.get_event_modifier_by_identifier(bad_debtor_id); + in_bankruptcy = modifier_manager.get_event_modifier_by_identifier(in_bankruptcy_id); + generalised_debt_default = modifier_manager.get_event_modifier_by_identifier(generalised_debt_default_id); + total_occupation *= 100; + } return ret; } diff --git a/src/openvic-simulation/modifier/StaticModifierCache.hpp b/src/openvic-simulation/modifier/StaticModifierCache.hpp index 4b17b82..b31e127 100644 --- a/src/openvic-simulation/modifier/StaticModifierCache.hpp +++ b/src/openvic-simulation/modifier/StaticModifierCache.hpp @@ -1,9 +1,10 @@ #pragma once +#include "openvic-simulation/dataloader/NodeTools.hpp" +#include "openvic-simulation/modifier/Modifier.hpp" #include "openvic-simulation/utility/Getters.hpp" namespace OpenVic { - struct Modifier; struct ModifierManager; struct StaticModifierCache { @@ -11,52 +12,54 @@ namespace OpenVic { private: // Country modifiers - Modifier const* PROPERTY(very_easy_player); - Modifier const* PROPERTY(easy_player); - Modifier const* PROPERTY(hard_player); - Modifier const* PROPERTY(very_hard_player); - Modifier const* PROPERTY(very_easy_ai); - Modifier const* PROPERTY(easy_ai); - Modifier const* PROPERTY(hard_ai); - Modifier const* PROPERTY(very_hard_ai); + Modifier PROPERTY(very_easy_player); + Modifier PROPERTY(easy_player); + Modifier PROPERTY(hard_player); + Modifier PROPERTY(very_hard_player); + Modifier PROPERTY(very_easy_ai); + Modifier PROPERTY(easy_ai); + Modifier PROPERTY(hard_ai); + Modifier PROPERTY(very_hard_ai); - Modifier const* PROPERTY(base_modifier); - Modifier const* PROPERTY(war); - Modifier const* PROPERTY(peace); - Modifier const* PROPERTY(disarming); - Modifier const* PROPERTY(war_exhaustion); - Modifier const* PROPERTY(infamy); - Modifier const* PROPERTY(debt_default_to); - Modifier const* PROPERTY(bad_debter); - Modifier const* PROPERTY(great_power); - Modifier const* PROPERTY(secondary_power); - Modifier const* PROPERTY(civilised); - Modifier const* PROPERTY(uncivilised); - Modifier const* PROPERTY(literacy); - Modifier const* PROPERTY(plurality); - Modifier const* PROPERTY(generalised_debt_default); - Modifier const* PROPERTY(total_occupation); - Modifier const* PROPERTY(total_blockaded); + Modifier PROPERTY(base_modifier); + Modifier PROPERTY(war); + Modifier PROPERTY(peace); + Modifier PROPERTY(disarming); + Modifier PROPERTY(war_exhaustion); + Modifier PROPERTY(infamy); + Modifier PROPERTY(debt_default_to); + Modifier PROPERTY(great_power); + Modifier PROPERTY(secondary_power); + Modifier PROPERTY(civilised); + Modifier PROPERTY(uncivilised); + Modifier PROPERTY(literacy); + Modifier PROPERTY(plurality); + Modifier PROPERTY(total_occupation); + Modifier PROPERTY(total_blockaded); + + // Country event modifiers Modifier const* PROPERTY(in_bankruptcy); + Modifier const* PROPERTY(bad_debtor); + Modifier const* PROPERTY(generalised_debt_default); //possibly, as it's used to trigger gunboat CB // Province modifiers - Modifier const* PROPERTY(overseas); - Modifier const* PROPERTY(coastal); - Modifier const* PROPERTY(non_coastal); - Modifier const* PROPERTY(coastal_sea); - Modifier const* PROPERTY(sea_zone); - Modifier const* PROPERTY(land_province); - Modifier const* PROPERTY(blockaded); - Modifier const* PROPERTY(no_adjacent_controlled); - Modifier const* PROPERTY(core); - Modifier const* PROPERTY(has_siege); - Modifier const* PROPERTY(occupied); - Modifier const* PROPERTY(nationalism); - Modifier const* PROPERTY(infrastructure); + Modifier PROPERTY(overseas); + Modifier PROPERTY(coastal); + Modifier PROPERTY(non_coastal); + Modifier PROPERTY(coastal_sea); + Modifier PROPERTY(sea_zone); + Modifier PROPERTY(land_province); + Modifier PROPERTY(blockaded); + Modifier PROPERTY(no_adjacent_controlled); + Modifier PROPERTY(core); + Modifier PROPERTY(has_siege); + Modifier PROPERTY(occupied); + Modifier PROPERTY(nationalism); + Modifier PROPERTY(infrastructure); StaticModifierCache(); - bool load_static_modifiers(ModifierManager& registry); + bool load_static_modifiers(ModifierManager& modifier_manager, const ast::NodeCPtr root); public: StaticModifierCache(StaticModifierCache&&) = default; diff --git a/src/openvic-simulation/politics/Issue.cpp b/src/openvic-simulation/politics/Issue.cpp index 1faa345..8da09fc 100644 --- a/src/openvic-simulation/politics/Issue.cpp +++ b/src/openvic-simulation/politics/Issue.cpp @@ -1,6 +1,7 @@ #include "Issue.hpp" #include "openvic-simulation/modifier/ModifierManager.hpp" +#include "openvic-simulation/types/fixed_point/FixedPoint.hpp" using namespace OpenVic; using namespace OpenVic::NodeTools; @@ -178,17 +179,18 @@ bool IssueManager::_load_issue( ModifierManager const& modifier_manager, RuleManager const& rule_manager, std::string_view identifier, IssueGroup const* group, ast::NodeCPtr node ) { - using enum Modifier::modifier_type_t; - ModifierValue values; RuleSet rules; bool jingoism = false; - bool ret = modifier_manager.expect_modifier_value_and_keys( - move_variable_callback(values), - ISSUE, + bool ret = NodeTools::expect_dictionary_keys_and_default( + modifier_manager.expect_base_country_modifier(values), "is_jingoism", ZERO_OR_ONE, expect_bool(assign_variable_callback(jingoism)), - "rules", ZERO_OR_ONE, rule_manager.expect_rule_set(move_variable_callback(rules)) + "rules", ZERO_OR_ONE, rule_manager.expect_rule_set(move_variable_callback(rules)), + "war_exhaustion_effect", ZERO_OR_ONE, [](const ast::NodeCPtr _) -> bool { + Logger::warning("war_exhaustion_effect does nothing (vanilla issues have it)."); + return true; + } )(node); ret &= add_issue( @@ -219,8 +221,6 @@ bool IssueManager::_load_reform( ModifierManager const& modifier_manager, RuleManager const& rule_manager, size_t ordinal, std::string_view identifier, ReformGroup const* group, ast::NodeCPtr node ) { - using enum Modifier::modifier_type_t; - ModifierValue values; RuleSet rules; fixed_point_t administrative_multiplier = 0; @@ -229,9 +229,8 @@ bool IssueManager::_load_reform( ConditionScript on_execute_trigger { scope_t::COUNTRY, scope_t::COUNTRY, scope_t::NO_SCOPE }; EffectScript on_execute_effect; - bool ret = modifier_manager.expect_modifier_value_and_keys( - move_variable_callback(values), - REFORM, + bool ret = NodeTools::expect_dictionary_keys_and_default( + modifier_manager.expect_base_country_modifier(values), "administrative_multiplier", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(administrative_multiplier)), "technology_cost", ZERO_OR_ONE, expect_uint(assign_variable_callback(technology_cost)), "allow", ZERO_OR_ONE, allow.expect_script(), diff --git a/src/openvic-simulation/politics/NationalFocus.cpp b/src/openvic-simulation/politics/NationalFocus.cpp index 4d1546c..2427d7c 100644 --- a/src/openvic-simulation/politics/NationalFocus.cpp +++ b/src/openvic-simulation/politics/NationalFocus.cpp @@ -117,8 +117,6 @@ bool NationalFocusManager::load_national_foci_file( [this, &group, &pop_manager, &ideology_manager, &good_definition_manager, &modifier_manager]( std::string_view identifier, ast::NodeCPtr node ) -> bool { - using enum Modifier::modifier_type_t; - uint8_t icon = 0; bool has_flashpoint = false, own_provinces = true, outliner_show_as_percent = false; fixed_point_t flashpoint_tension = 0; @@ -132,10 +130,9 @@ bool NationalFocusManager::load_national_foci_file( scope_t::PROVINCE | scope_t::COUNTRY, scope_t::PROVINCE | scope_t::COUNTRY, scope_t::NO_SCOPE }; - bool ret = modifier_manager.expect_modifier_value_and_keys_and_default( - move_variable_callback(modifiers), - NATIONAL_FOCUS, - [&good_definition_manager, &encourage_goods, &pop_manager, &encourage_pop_types]( + const auto expect_base_province_modifier_cb = modifier_manager.expect_base_province_modifier(modifiers); + bool ret = NodeTools::expect_dictionary_keys_and_default( + [&good_definition_manager, &encourage_goods, &pop_manager, &encourage_pop_types, &expect_base_province_modifier_cb]( std::string_view key, ast::NodeCPtr value ) -> bool { GoodDefinition const* good = good_definition_manager.get_good_definition_by_identifier(key); @@ -148,7 +145,7 @@ bool NationalFocusManager::load_national_foci_file( return expect_fixed_point(map_callback(encourage_pop_types, pop_type))(value); } - return key_value_invalid_callback(key, value); + return expect_base_province_modifier_cb(key, value) || key_value_invalid_callback(key, value); }, "icon", ONE_EXACTLY, expect_uint(assign_variable_callback(icon)), "ideology", ZERO_OR_ONE, diff --git a/src/openvic-simulation/politics/NationalValue.cpp b/src/openvic-simulation/politics/NationalValue.cpp index 16f723b..9a30fa1 100644 --- a/src/openvic-simulation/politics/NationalValue.cpp +++ b/src/openvic-simulation/politics/NationalValue.cpp @@ -21,11 +21,10 @@ bool NationalValueManager::load_national_values_file(ModifierManager const& modi bool ret = expect_dictionary_reserve_length( national_values, [this, &modifier_manager](std::string_view national_value_identifier, ast::NodeCPtr value) -> bool { - using enum Modifier::modifier_type_t; - ModifierValue modifiers; - - bool ret = modifier_manager.expect_modifier_value(move_variable_callback(modifiers), NATIONAL_VALUE)(value); + bool ret = NodeTools::expect_dictionary( + modifier_manager.expect_base_country_modifier(modifiers) + )(value); ret &= add_national_value(national_value_identifier, std::move(modifiers)); diff --git a/src/openvic-simulation/politics/Rebel.cpp b/src/openvic-simulation/politics/Rebel.cpp index 9bba1b9..9b2927c 100644 --- a/src/openvic-simulation/politics/Rebel.cpp +++ b/src/openvic-simulation/politics/Rebel.cpp @@ -186,9 +186,9 @@ bool RebelManager::generate_modifiers(ModifierManager& modifier_manager) const { ret &= modifier_manager.register_complex_modifier(identifier); - ret &= modifier_manager.add_modifier_effect( + ret &= modifier_manager.register_technology_modifier_effect( modifier_manager.modifier_effect_cache.rebel_org_gain_all, ModifierManager::get_flat_identifier(identifier, "all"), - is_positive_good, PROPORTION_DECIMAL, COUNTRY, "TECH_REBEL_ORG_GAIN" + is_positive_good, PROPORTION_DECIMAL, "TECH_REBEL_ORG_GAIN" ); IndexedMap<RebelType, ModifierEffect const*>& rebel_org_gain_effects = @@ -197,9 +197,9 @@ bool RebelManager::generate_modifiers(ModifierManager& modifier_manager) const { rebel_org_gain_effects.set_keys(&get_rebel_types()); for (RebelType const& rebel_type : get_rebel_types()) { - ret &= modifier_manager.add_modifier_effect( + ret &= modifier_manager.register_technology_modifier_effect( rebel_org_gain_effects[rebel_type], ModifierManager::get_flat_identifier(identifier, rebel_type.get_identifier()), - is_positive_good, PROPORTION_DECIMAL, COUNTRY, + is_positive_good, PROPORTION_DECIMAL, 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 885903a..4b81e5d 100644 --- a/src/openvic-simulation/pop/Pop.cpp +++ b/src/openvic-simulation/pop/Pop.cpp @@ -668,9 +668,9 @@ bool PopManager::generate_modifiers(ModifierManager& modifier_manager) const { const auto strata_modifier = [&modifier_manager, &ret, &strata]( ModifierEffect const*& effect_cache, std::string_view suffix, bool is_positive_good ) -> void { - ret &= modifier_manager.add_modifier_effect( + ret &= modifier_manager.register_base_country_modifier_effect( effect_cache, StringUtils::append_string_views(strata.get_identifier(), suffix), is_positive_good, - PROPORTION_DECIMAL, COUNTRY + PROPORTION_DECIMAL ); }; diff --git a/src/openvic-simulation/research/Invention.cpp b/src/openvic-simulation/research/Invention.cpp index 808dad4..1076a62 100644 --- a/src/openvic-simulation/research/Invention.cpp +++ b/src/openvic-simulation/research/Invention.cpp @@ -62,8 +62,6 @@ bool InventionManager::load_inventions_file( inventions, [this, &modifier_manager, &unit_type_manager, &building_type_manager, &crime_manager]( std::string_view identifier, ast::NodeCPtr value ) -> bool { - using enum Modifier::modifier_type_t; - // TODO - use the same variable for all modifiers rather than combining them at the end? ModifierValue loose_modifiers; ModifierValue modifiers; @@ -79,15 +77,13 @@ bool InventionManager::load_inventions_file( ConditionScript limit { scope_t::COUNTRY, scope_t::COUNTRY, scope_t::NO_SCOPE }; ConditionalWeight chance { scope_t::COUNTRY, scope_t::COUNTRY, scope_t::NO_SCOPE }; - bool ret = modifier_manager.expect_modifier_value_and_keys( - move_variable_callback(loose_modifiers), - INVENTION, + bool ret = NodeTools::expect_dictionary_keys_and_default( + modifier_manager.expect_base_country_modifier(loose_modifiers), "news", ZERO_OR_ONE, expect_bool(assign_variable_callback(news)), "limit", ONE_EXACTLY, limit.expect_script(), "chance", ONE_EXACTLY, chance.expect_conditional_weight(ConditionalWeight::BASE), - "effect", ZERO_OR_ONE, modifier_manager.expect_modifier_value_and_keys( - move_variable_callback(modifiers), - INVENTION, + "effect", ZERO_OR_ONE, NodeTools::expect_dictionary_keys_and_default( + modifier_manager.expect_technology_modifier(modifiers), "gas_attack", ZERO_OR_ONE, expect_bool(assign_variable_callback(unlock_gas_attack)), "gas_defence", ZERO_OR_ONE, expect_bool(assign_variable_callback(unlock_gas_defence)), "activate_unit", ZERO_OR_MORE, diff --git a/src/openvic-simulation/research/Technology.cpp b/src/openvic-simulation/research/Technology.cpp index a770a40..9a1cf27 100644 --- a/src/openvic-simulation/research/Technology.cpp +++ b/src/openvic-simulation/research/Technology.cpp @@ -142,12 +142,10 @@ bool TechnologyManager::load_technology_file_schools( const bool ret = expect_dictionary_reserve_length( technology_schools, [this, &modifier_manager](std::string_view school_key, ast::NodeCPtr school_value) -> bool { - using enum Modifier::modifier_type_t; - ModifierValue modifiers; - bool ret = modifier_manager.expect_modifier_value( - move_variable_callback(modifiers), TECH_SCHOOL + bool ret = NodeTools::expect_dictionary( + modifier_manager.expect_base_country_modifier(modifiers) )(school_value); ret &= add_technology_school(school_key, std::move(modifiers)); @@ -170,8 +168,6 @@ bool TechnologyManager::load_technologies_file( return expect_dictionary_reserve_length(technologies, [this, &modifier_manager, &unit_type_manager, &building_type_manager]( std::string_view tech_key, ast::NodeCPtr tech_value ) -> bool { - using enum Modifier::modifier_type_t; - ModifierValue modifiers; TechnologyArea const* area = nullptr; Date::year_t year = 0; @@ -182,9 +178,8 @@ bool TechnologyManager::load_technologies_file( Technology::building_set_t activated_buildings; ConditionalWeight ai_chance { scope_t::COUNTRY, scope_t::COUNTRY, scope_t::NO_SCOPE }; - bool ret = modifier_manager.expect_modifier_value_and_keys( - move_variable_callback(modifiers), - TECHNOLOGY, + bool ret = NodeTools::expect_dictionary_keys_and_default( + modifier_manager.expect_technology_modifier(modifiers), "area", ONE_EXACTLY, expect_technology_area_identifier(assign_variable_callback_pointer(area)), "year", ONE_EXACTLY, expect_uint(assign_variable_callback(year)), "cost", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(cost)), @@ -219,8 +214,8 @@ bool TechnologyManager::generate_modifiers(ModifierManager& modifier_manager) co 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( - research_bonus_effects[folder], modifier_identifier, true, PROPORTION_DECIMAL, COUNTRY, modifier_identifier + ret &= modifier_manager.register_base_country_modifier_effect( + research_bonus_effects[folder], modifier_identifier, true, PROPORTION_DECIMAL, modifier_identifier ); } diff --git a/src/openvic-simulation/scripts/Condition.cpp b/src/openvic-simulation/scripts/Condition.cpp index 7abd717..fd1f4fa 100644 --- a/src/openvic-simulation/scripts/Condition.cpp +++ b/src/openvic-simulation/scripts/Condition.cpp @@ -155,7 +155,7 @@ bool ConditionManager::setup_conditions(DefinitionManager const& definition_mana ret &= add_condition("great_wars_enabled", BOOLEAN, COUNTRY); ret &= add_condition("have_core_in", IDENTIFIER, COUNTRY, NO_SCOPE, NO_IDENTIFIER, COUNTRY_TAG); ret &= add_condition("has_country_flag", IDENTIFIER, COUNTRY, NO_SCOPE, NO_IDENTIFIER, COUNTRY_FLAG); - ret &= add_condition("has_country_modifier", IDENTIFIER, COUNTRY, NO_SCOPE, NO_IDENTIFIER, MODIFIER); + ret &= add_condition("has_country_modifier", IDENTIFIER, COUNTRY, NO_SCOPE, NO_IDENTIFIER, COUNTRY_EVENT_MODIFIER); ret &= add_condition("has_cultural_sphere", BOOLEAN, COUNTRY); ret &= add_condition("has_leader", STRING, COUNTRY); ret &= add_condition("has_pop_culture", IDENTIFIER, COUNTRY, NO_SCOPE, NO_IDENTIFIER, CULTURE); @@ -299,7 +299,7 @@ bool ConditionManager::setup_conditions(DefinitionManager const& definition_mana ret &= add_condition("has_empty_adjacent_state", BOOLEAN, PROVINCE); ret &= add_condition("has_national_minority", BOOLEAN, PROVINCE); ret &= add_condition("has_province_flag", IDENTIFIER, PROVINCE, NO_SCOPE, NO_IDENTIFIER, PROVINCE_FLAG); - ret &= add_condition("has_province_modifier", IDENTIFIER, PROVINCE, NO_SCOPE, NO_IDENTIFIER, MODIFIER); + ret &= add_condition("has_province_modifier", IDENTIFIER, PROVINCE, NO_SCOPE, NO_IDENTIFIER, PROVINCE_EVENT_MODIFIER); ret &= add_condition("has_recent_imigration", INTEGER, PROVINCE); //paradox typo ret &= add_condition("is_blockaded", BOOLEAN, PROVINCE); ret &= add_condition("is_accepted_culture", IDENTIFIER | BOOLEAN, PROVINCE, NO_SCOPE, NO_IDENTIFIER, COUNTRY_TAG); @@ -505,9 +505,8 @@ callback_t<std::string_view> ConditionManager::expect_parse_identifier( EXPECT_CALL(BUILDING, building_type, definition_manager.get_economy_manager().get_building_type_manager(), "FACTORY"); EXPECT_CALL(CASUS_BELLI, wargoal_type, definition_manager.get_military_manager().get_wargoal_type_manager()); EXPECT_CALL(GOVERNMENT_TYPE, government_type, definition_manager.get_politics_manager().get_government_type_manager()); - EXPECT_CALL(MODIFIER, event_modifier, definition_manager.get_modifier_manager()); - EXPECT_CALL(MODIFIER, triggered_modifier, definition_manager.get_modifier_manager()); - EXPECT_CALL(MODIFIER, static_modifier, definition_manager.get_modifier_manager()); + EXPECT_CALL(COUNTRY_EVENT_MODIFIER | PROVINCE_EVENT_MODIFIER, event_modifier, definition_manager.get_modifier_manager()); + EXPECT_CALL(COUNTRY_EVENT_MODIFIER, triggered_modifier, definition_manager.get_modifier_manager()); EXPECT_CALL(NATIONAL_VALUE, national_value, definition_manager.get_politics_manager().get_national_value_manager()); EXPECT_CALL( CULTURE_UNION, country_definition, definition_manager.get_country_definition_manager(), "THIS", "FROM", "THIS_UNION" diff --git a/src/openvic-simulation/scripts/Condition.hpp b/src/openvic-simulation/scripts/Condition.hpp index 748453f..8d4d246 100644 --- a/src/openvic-simulation/scripts/Condition.hpp +++ b/src/openvic-simulation/scripts/Condition.hpp @@ -63,12 +63,13 @@ namespace OpenVic { BUILDING = 1 << 20, CASUS_BELLI = 1 << 21, GOVERNMENT_TYPE = 1 << 22, - MODIFIER = 1 << 23, - NATIONAL_VALUE = 1 << 24, - CULTURE_UNION = 1 << 25, // same as COUNTRY_TAG but also accepts scope this_union - CONTINENT = 1 << 26, - CRIME = 1 << 27, - TERRAIN = 1 << 28, + COUNTRY_EVENT_MODIFIER = 1 << 23, + PROVINCE_EVENT_MODIFIER = 1 << 24, + NATIONAL_VALUE = 1 << 25, + CULTURE_UNION = 1 << 26, // same as COUNTRY_TAG but also accepts scope this_union + CONTINENT = 1 << 27, + CRIME = 1 << 28, + TERRAIN = 1 << 29 }; /* Allows enum types to be used with bitwise operators. */ @@ -175,7 +176,8 @@ namespace OpenVic { BUILD_STRING(BUILDING); BUILD_STRING(CASUS_BELLI); BUILD_STRING(GOVERNMENT_TYPE); - BUILD_STRING(MODIFIER); + BUILD_STRING(COUNTRY_EVENT_MODIFIER); + BUILD_STRING(PROVINCE_EVENT_MODIFIER); BUILD_STRING(NATIONAL_VALUE); BUILD_STRING(CULTURE_UNION); BUILD_STRING(CONTINENT); |