Skip to content

Update Modifiers dp #399

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions src/openvic-simulation/country/CountryInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1326,7 +1326,8 @@ void CountryInstance::_update_military(

// Mobilisation calculations
mobilisation_impact = get_modifier_effect_value(*modifier_effect_cache.get_mobilization_impact());
mobilisation_economy_impact = get_modifier_effect_value(*modifier_effect_cache.get_mobilisation_economy_impact());
mobilisation_economy_impact = get_modifier_effect_value(*modifier_effect_cache.get_mobilisation_economy_impact_tech()) +
get_modifier_effect_value(*modifier_effect_cache.get_mobilisation_economy_impact_country());

// TODO - use country_defines.get_min_mobilize_limit(); (wiki: "lowest maximum of brigades you can mobilize. (by default 3)")

Expand Down Expand Up @@ -1849,7 +1850,7 @@ void CountryInstance::request_salaries_and_welfare(Pop& pop) const {
pop.add_government_salary_administration(administration_salary);
}
}

if (actual_education_spending > fixed_point_t::_0()) {
const fixed_point_t education_salary = fixed_point_t::mul_div(
pop_size * calculate_education_salary_base(pop_type_values, corruption_cost_multiplier),
Expand All @@ -1860,7 +1861,7 @@ void CountryInstance::request_salaries_and_welfare(Pop& pop) const {
pop.add_government_salary_education(education_salary);
}
}

if (actual_military_spending > fixed_point_t::_0()) {
const fixed_point_t military_salary = fixed_point_t::mul_div(
pop_size * calculate_military_salary_base(pop_type_values, corruption_cost_multiplier),
Expand All @@ -1871,7 +1872,7 @@ void CountryInstance::request_salaries_and_welfare(Pop& pop) const {
pop.add_government_salary_military(military_salary);
}
}

if (actual_social_spending > fixed_point_t::_0()) {
const fixed_point_t projected_social_spending_unscaled_by_slider =
projected_pensions_spending_unscaled_by_slider
Expand Down Expand Up @@ -2242,6 +2243,6 @@ void CountryInstanceManager::country_manager_tick_after_map(InstanceManager& ins
for (CountryInstance& country : country_instances.get_items()) {
country.country_tick_after_map(instance_manager);
}

shared_country_values.update_costs(instance_manager.get_good_instance_manager());
}
4 changes: 2 additions & 2 deletions src/openvic-simulation/economy/BuildingType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,12 @@ bool BuildingTypeManager::load_buildings_file(
static constexpr std::string_view min_prefix = "min_build_";
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, StringUtils::append_string_views("$", building_type.get_identifier(), "$ $TECH_MAX_LEVEL$")
FORMAT_x1_0DP_POS, StringUtils::append_string_views("$", building_type.get_identifier(), "$ $TECH_MAX_LEVEL$")
);
// TODO - add custom localisation for "min_build_$building_type$" modifiers
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
FORMAT_x1_0DP_NEG
);

if (building_type.is_in_province()) {
Expand Down
52 changes: 29 additions & 23 deletions src/openvic-simulation/economy/GoodDefinition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@ bool GoodDefinitionManager::load_goods_file(ast::NodeCPtr root) {
}

bool GoodDefinitionManager::generate_modifiers(ModifierManager& modifier_manager) const {
constexpr bool has_no_effect = true;
static constexpr bool HAS_NO_EFFECT = true;

using enum ModifierEffect::format_t;
using enum ModifierEffect::target_t;

Expand All @@ -142,27 +143,28 @@ bool GoodDefinitionManager::generate_modifiers(ModifierManager& modifier_manager

bool ret = true;

ret &= modifier_manager.register_complex_modifier("artisan_goods_input");
ret &= modifier_manager.register_complex_modifier("artisan_goods_output");
ret &= modifier_manager.register_complex_modifier("artisan_goods_throughput");
ret &= modifier_manager.register_complex_modifier("rgo_goods_input");
ret &= modifier_manager.register_complex_modifier("rgo_goods_output");
ret &= modifier_manager.register_complex_modifier("rgo_goods_throughput");
ret &= modifier_manager.register_complex_modifier("factory_goods_input");
ret &= modifier_manager.register_complex_modifier("factory_goods_output");
ret &= modifier_manager.register_complex_modifier("factory_goods_throughput");
ret &= modifier_manager.register_complex_modifier("rgo_goods_output");
ret &= modifier_manager.register_complex_modifier("rgo_goods_throughput");
ret &= modifier_manager.register_complex_modifier("artisan_goods_input");
ret &= modifier_manager.register_complex_modifier("artisan_goods_output");
ret &= modifier_manager.register_complex_modifier("artisan_goods_throughput");
ret &= modifier_manager.register_complex_modifier("rgo_size");

for (GoodDefinition const& good : get_good_definitions()) {
const std::string_view good_identifier = good.get_identifier();
ModifierEffectCache::good_effects_t& this_good_effects = good_effects[good];

const auto good_modifier = [&modifier_manager, &ret, &good_identifier](
ModifierEffect const*& effect_cache, std::string_view name, bool is_positive_good,
ModifierEffect const*& effect_cache, std::string_view name, ModifierEffect::format_t format,
std::string_view localisation_key, bool has_no_effect = false
) -> void {
ret &= modifier_manager.register_technology_modifier_effect(
effect_cache, ModifierManager::get_flat_identifier(name, good_identifier), is_positive_good,
PROPORTION_DECIMAL, localisation_key, has_no_effect
effect_cache, ModifierManager::get_flat_identifier(name, good_identifier),
format, localisation_key, has_no_effect
);
};

Expand All @@ -173,39 +175,43 @@ bool GoodDefinitionManager::generate_modifiers(ModifierManager& modifier_manager
};

good_modifier(
this_good_effects.artisan_goods_input, "artisan_goods_input", false,
make_production_localisation_suffix("TECH_INPUT"), has_no_effect
this_good_effects.rgo_goods_input, "rgo_goods_input", FORMAT_x100_1DP_PC_NEG,
make_production_localisation_suffix("TECH_INPUT"), HAS_NO_EFFECT
);
good_modifier(
this_good_effects.artisan_goods_output, "artisan_goods_output", true,
make_production_localisation_suffix("TECH_OUTPUT"), has_no_effect
this_good_effects.rgo_goods_output, "rgo_goods_output", FORMAT_x100_1DP_PC_POS,
make_production_localisation_suffix("TECH_OUTPUT")
);
good_modifier(
this_good_effects.artisan_goods_throughput, "artisan_goods_throughput", true,
make_production_localisation_suffix("TECH_THROUGHPUT"), has_no_effect
this_good_effects.rgo_goods_throughput, "rgo_goods_throughput", FORMAT_x100_1DP_PC_POS,
make_production_localisation_suffix("TECH_THROUGHPUT")
);
good_modifier(
this_good_effects.factory_goods_input, "factory_goods_input", false,
this_good_effects.factory_goods_input, "factory_goods_input", FORMAT_x100_1DP_PC_NEG,
make_production_localisation_suffix("TECH_INPUT")
);
good_modifier(
this_good_effects.factory_goods_output, "factory_goods_output", true,
this_good_effects.factory_goods_output, "factory_goods_output", FORMAT_x100_1DP_PC_POS,
make_production_localisation_suffix("TECH_OUTPUT")
);
good_modifier(
this_good_effects.factory_goods_throughput, "factory_goods_throughput", true,
this_good_effects.factory_goods_throughput, "factory_goods_throughput", FORMAT_x100_1DP_PC_POS,
make_production_localisation_suffix("TECH_THROUGHPUT")
);
good_modifier(
this_good_effects.rgo_goods_output, "rgo_goods_output", true,
make_production_localisation_suffix("TECH_OUTPUT")
this_good_effects.artisan_goods_input, "artisan_goods_input", FORMAT_x100_1DP_PC_NEG,
make_production_localisation_suffix("TECH_INPUT"), HAS_NO_EFFECT
);
good_modifier(
this_good_effects.rgo_goods_throughput, "rgo_goods_throughput", true,
make_production_localisation_suffix("TECH_THROUGHPUT")
this_good_effects.artisan_goods_output, "artisan_goods_output", FORMAT_x100_1DP_PC_POS,
make_production_localisation_suffix("TECH_OUTPUT"), HAS_NO_EFFECT
);
good_modifier(
this_good_effects.artisan_goods_throughput, "artisan_goods_throughput", FORMAT_x100_1DP_PC_POS,
make_production_localisation_suffix("TECH_THROUGHPUT"), HAS_NO_EFFECT
);
good_modifier(
this_good_effects.rgo_size, "rgo_size", true,
this_good_effects.rgo_size, "rgo_size", FORMAT_x100_2DP_PC_POS,
StringUtils::append_string_views(good_identifier, "_RGO_SIZE")
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,9 +260,13 @@ fixed_point_t ResourceGatheringOperation::produce() {
}
}

throughput_multiplier += location.get_modifier_effect_value(*modifier_effect_cache.get_rgo_throughput())
// TODO - work out how best to avoid repeated lookups of the same effects,
// e.g. by caching total non-local effect values at the CountryInstance level
throughput_multiplier += location.get_modifier_effect_value(*modifier_effect_cache.get_rgo_throughput_tech())
+ location.get_modifier_effect_value(*modifier_effect_cache.get_rgo_throughput_country())
+ location.get_modifier_effect_value(*modifier_effect_cache.get_local_rgo_throughput());
output_multiplier += location.get_modifier_effect_value(*modifier_effect_cache.get_rgo_output())
output_multiplier += location.get_modifier_effect_value(*modifier_effect_cache.get_rgo_output_tech())
+ location.get_modifier_effect_value(*modifier_effect_cache.get_rgo_output_country())
+ location.get_modifier_effect_value(*modifier_effect_cache.get_local_rgo_output());

if (production_type.get_is_farm_for_tech()) {
Expand Down
17 changes: 8 additions & 9 deletions src/openvic-simulation/map/TerrainType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,26 +42,25 @@ bool TerrainTypeManager::generate_modifiers(ModifierManager& modifier_manager) c

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
this_unit_terrain_effects.attack, ModifierManager::get_flat_identifier("attack", identifier),
FORMAT_x100_1DP_PC_POS, "UA_ATTACK"
);
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
this_unit_terrain_effects.defence, ModifierManager::get_flat_identifier("defence", identifier),
FORMAT_x100_1DP_PC_POS, "UA_DEFENCE"
);
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
this_unit_terrain_effects.movement, ModifierManager::get_flat_identifier("movement", identifier),
FORMAT_x100_1DP_PC_POS, "UA_MOVEMENT"
);
ret &= modifier_manager.register_unit_terrain_modifier_effect(
this_unit_terrain_effects.movement, ModifierManager::get_flat_identifier("movement", identifier), true,
PROPORTION_DECIMAL, "UA_MOVEMENT"
this_unit_terrain_effects.attrition, ModifierManager::get_flat_identifier("attrition", identifier),
FORMAT_x1_1DP_PC_NEG, "UA_ATTRITION"
);
}
return ret;
Expand Down
59 changes: 33 additions & 26 deletions src/openvic-simulation/military/UnitType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -316,43 +316,50 @@ bool UnitTypeManager::generate_modifiers(ModifierManager& modifier_manager) cons
using enum ModifierEffect::format_t;

const auto stat_modifier = [&modifier_manager, &ret, &identifier](
ModifierEffect const*& effect_cache, std::string_view suffix, bool is_positive_good,
ModifierEffect const*& effect_cache, std::string_view suffix,
ModifierEffect::format_t format, std::string_view localisation_key
) -> void {
ret &= modifier_manager.register_technology_modifier_effect(
effect_cache, ModifierManager::get_flat_identifier(identifier, suffix), is_positive_good, format,
effect_cache, ModifierManager::get_flat_identifier(identifier, suffix), format,
StringUtils::append_string_views("$", identifier, "$: $", localisation_key, "$")
);
};

ret &= modifier_manager.register_complex_modifier(identifier);

stat_modifier(unit_type_effects.attack, "attack", true, RAW_DECIMAL, "ATTACK");
stat_modifier(unit_type_effects.defence, "defence", true, RAW_DECIMAL, "DEFENCE");
stat_modifier(unit_type_effects.default_organisation, "default_organisation", true, RAW_DECIMAL, "DEFAULT_ORG");
stat_modifier(unit_type_effects.maximum_speed, "maximum_speed", true, RAW_DECIMAL, "MAXIMUM_SPEED");
stat_modifier(unit_type_effects.build_time, "build_time", false, INT, "BUILD_TIME");
// These are ordered following how they appear in the base game, hence the broken up land effects.
stat_modifier(unit_type_effects.default_organisation, "default_organisation", FORMAT_x1_1DP_POS, "DEFAULT_ORG");
stat_modifier(unit_type_effects.build_time, "build_time", FORMAT_x1_0DP_DAYS_NEG, "BUILD_TIME");
if constexpr (std::same_as<decltype(unit_type_effects), ModifierEffectCache::regiment_type_effects_t>) {
stat_modifier(
unit_type_effects.reconnaissance, "reconnaissance", FORMAT_x1_2DP_POS, "RECONAISSANCE" // paradox typo
);
stat_modifier(unit_type_effects.siege, "siege", FORMAT_x1_2DP_POS, "SIEGE");
}
stat_modifier(unit_type_effects.attack, "attack", FORMAT_x1_2DP_POS, "ATTACK");
stat_modifier(unit_type_effects.defence, "defence", FORMAT_x1_2DP_POS, "DEFENCE");
if constexpr (std::same_as<decltype(unit_type_effects), ModifierEffectCache::regiment_type_effects_t>) {
stat_modifier(unit_type_effects.discipline, "discipline", FORMAT_x100_0DP_PC_POS, "DISCIPLINE");
stat_modifier(unit_type_effects.support, "support", FORMAT_x100_0DP_PC_POS, "SUPPORT");
stat_modifier(unit_type_effects.maneuver, "maneuver", FORMAT_x1_0DP_POS, "Maneuver");
}
stat_modifier(unit_type_effects.maximum_speed, "maximum_speed", FORMAT_x1_2DP_SPEED_POS, "MAXIMUM_SPEED");
if constexpr(std::same_as<decltype(unit_type_effects), ModifierEffectCache::ship_type_effects_t>) {
stat_modifier(unit_type_effects.gun_power, "gun_power", FORMAT_x1_2DP_POS, "GUN_POWER");
stat_modifier(unit_type_effects.torpedo_attack, "torpedo_attack", FORMAT_x1_2DP_POS, "TORPEDO_ATTACK");
stat_modifier(unit_type_effects.hull, "hull", FORMAT_x1_2DP_POS, "HULL");
stat_modifier(unit_type_effects.fire_range, "fire_range", FORMAT_x100_0DP_POS, "FIRE_RANGE");
stat_modifier(unit_type_effects.evasion, "evasion", FORMAT_x100_0DP_PC_POS, "EVASION");
}
stat_modifier(
unit_type_effects.supply_consumption, "supply_consumption", false, PROPORTION_DECIMAL, "SUPPLY_CONSUMPTION"
unit_type_effects.supply_consumption, "supply_consumption", FORMAT_x100_0DP_PC_NEG, "SUPPLY_CONSUMPTION"
);

if constexpr (std::same_as<decltype(unit_type_effects), ModifierEffectCache::regiment_type_effects_t>) {
stat_modifier(unit_type_effects.reconnaissance, "reconnaissance", true, RAW_DECIMAL, "RECONAISSANCE"); // paradox typo
stat_modifier(unit_type_effects.discipline, "discipline", true, PROPORTION_DECIMAL, "DISCIPLINE");
stat_modifier(unit_type_effects.support, "support", true, PROPORTION_DECIMAL, "SUPPORT");
stat_modifier(unit_type_effects.maneuver, "maneuver", true, INT, "Maneuver");
stat_modifier(unit_type_effects.siege, "siege", true, RAW_DECIMAL, "SIEGE");
} else if constexpr(std::same_as<decltype(unit_type_effects), ModifierEffectCache::ship_type_effects_t>) {
stat_modifier(unit_type_effects.colonial_points, "colonial_points", true, INT, "COLONIAL_POINTS_TECH");
stat_modifier(unit_type_effects.supply_consumption_score, "supply_consumption_score", false, INT, "SUPPLY_LOAD");
stat_modifier(unit_type_effects.hull, "hull", true, RAW_DECIMAL, "HULL");
stat_modifier(unit_type_effects.gun_power, "gun_power", true, RAW_DECIMAL, "GUN_POWER");
stat_modifier(unit_type_effects.fire_range, "fire_range", true, RAW_DECIMAL, "FIRE_RANGE");
stat_modifier(unit_type_effects.evasion, "evasion", true, PROPORTION_DECIMAL, "EVASION");
stat_modifier(unit_type_effects.torpedo_attack, "torpedo_attack", true, RAW_DECIMAL, "TORPEDO_ATTACK");
} else {
/* Unreachable - unit types are only added via add_regiment_type or add_ship_type which set branch to LAND or NAVAL. */
Logger::error("Invalid branch for unit ", identifier, " - not LAND or NAVAL!");
if constexpr(std::same_as<decltype(unit_type_effects), ModifierEffectCache::ship_type_effects_t>) {
stat_modifier(
unit_type_effects.supply_consumption_score, "supply_consumption_score", FORMAT_x1_0DP_NEG, "SUPPLY_LOAD"
);
// Works but doesn't appear in tooltips in the base game
stat_modifier(unit_type_effects.colonial_points, "colonial_points", FORMAT_x1_0DP_POS, "COLONIAL_POINTS_TECH");
}
};

Expand Down
4 changes: 2 additions & 2 deletions src/openvic-simulation/modifier/ModifierEffect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ std::string ModifierEffect::make_default_modifier_effect_localisation_key(std::s
}

ModifierEffect::ModifierEffect(
std::string_view new_identifier, bool new_is_positive_good, format_t new_format, target_t new_targets,
std::string_view new_identifier, 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 },
) : HasIdentifier { new_identifier }, 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 } {}
Loading