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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
14 changes: 11 additions & 3 deletions src/openvic-simulation/country/CountryInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -946,7 +946,9 @@ bool CountryInstance::apply_history_to_country(CountryHistoryEntry const& entry,
return ret;
}

void CountryInstance::_update_production(DefineManager const& define_manager) {
void CountryInstance::_update_production(
DefineManager const& define_manager, ModifierEffectCache const& modifier_effect_cache
) {
// Calculate industrial power from states and foreign investments
industrial_power = 0;
industrial_power_from_states.clear();
Expand Down Expand Up @@ -983,6 +985,11 @@ void CountryInstance::_update_production(DefineManager const& define_manager) {
industrial_power_from_investments.begin(), industrial_power_from_investments.end(),
[](auto const& a, auto const& b) -> bool { return a.second > b.second; }
);

total_rgo_throughput_effect_value = get_modifier_effect_value(*modifier_effect_cache.get_rgo_throughput_tech()) +
get_modifier_effect_value(*modifier_effect_cache.get_rgo_throughput_country());
total_rgo_output_effect_value = get_modifier_effect_value(*modifier_effect_cache.get_rgo_output_tech()) +
get_modifier_effect_value(*modifier_effect_cache.get_rgo_output_country());
}

static inline constexpr fixed_point_t nonzero_or_one(fixed_point_t const& value) {
Expand Down Expand Up @@ -1243,7 +1250,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 @@ -1514,7 +1522,7 @@ void CountryInstance::update_gamestate(InstanceManager& instance_manager) {
// Updates population stats (including research and leadership points from pops)
_update_population();
// Calculates industrial power
_update_production(define_manager);
_update_production(define_manager, modifier_effect_cache);
// Calculates daily research points and predicts research completion date
_update_technology(instance_manager);
// Calculates national military modifiers, army and navy stats, daily leadership points
Expand Down
4 changes: 3 additions & 1 deletion src/openvic-simulation/country/CountryInstance.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ namespace OpenVic {
size_t PROPERTY(industrial_rank, 0);
fixed_point_map_t<CountryInstance const*> PROPERTY(foreign_investments);
IndexedMap<BuildingType, unlock_level_t> PROPERTY(building_type_unlock_levels);
fixed_point_t PROPERTY(total_rgo_throughput_effect_value);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not total if you still have to add the local modifiers....

fixed_point_t PROPERTY(total_rgo_output_effect_value);
// TODO - total amount of each good produced

/* Budget */
Expand Down Expand Up @@ -522,7 +524,7 @@ namespace OpenVic {
bool apply_history_to_country(CountryHistoryEntry const& entry, InstanceManager& instance_manager);

private:
void _update_production(DefineManager const& define_manager);
void _update_production(DefineManager const& define_manager, ModifierEffectCache const& modifier_effect_cache);
void _update_budget(DefineManager const& define_manager, ModifierEffectCache const& modifier_effect_cache);
// Expects current_research to be non-null
void _update_current_tech(InstanceManager const& instance_manager);
Expand Down
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
57 changes: 30 additions & 27 deletions src/openvic-simulation/economy/GoodDefinition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,11 @@ bool GoodDefinitionManager::load_goods_file(ast::NodeCPtr root) {
return ret;
}

// Must be declared outside of any function for GCC to accept it as a default argument in a lambda function
static constexpr bool HAS_NO_EFFECT = true, HAS_EFFECT = false;

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

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

Expand All @@ -142,27 +145,27 @@ 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_output");
ret &= modifier_manager.register_complex_modifier("rgo_goods_throughput");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is also an rgo_goods_input but that has no effect as rgo's don't have inputs.

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,
std::string_view localisation_key, bool has_no_effect = false
ModifierEffect const*& effect_cache, std::string_view name, ModifierEffect::format_t format,
std::string_view localisation_key, bool has_no_effect = HAS_EFFECT
) -> 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,40 +176,40 @@ 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
);
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,
StringUtils::append_string_views(good_identifier, "_RGO_SIZE")
this_good_effects.rgo_size, "rgo_size", FORMAT_x100_2DP_PC_POS,
StringUtils::append_string_views(good_identifier, "_RGO_SIZE"), HAS_EFFECT
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,10 +260,14 @@ fixed_point_t ResourceGatheringOperation::produce() {
}
}

throughput_multiplier += location.get_modifier_effect_value(*modifier_effect_cache.get_rgo_throughput())
+ 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())
+ location.get_modifier_effect_value(*modifier_effect_cache.get_local_rgo_output());
throughput_multiplier += location.get_modifier_effect_value(*modifier_effect_cache.get_local_rgo_throughput());
output_multiplier += location.get_modifier_effect_value(*modifier_effect_cache.get_local_rgo_output());

CountryInstance const* location_owner = location.get_owner();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use country_to_report_economy
Also this is worse than the previous implementation.
Now consumers have to gather modifiers themselves :(

if (location_owner != nullptr) {
throughput_multiplier += location_owner->get_total_rgo_throughput_effect_value();
output_multiplier += location_owner->get_total_rgo_output_effect_value();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the rgo_goods_throughput & _output?
Currently the code only gets it from location.

}

if (production_type.get_is_farm_for_tech()) {
const fixed_point_t farm_rgo_throughput_and_output =
Expand Down
16 changes: 8 additions & 8 deletions src/openvic-simulation/map/TerrainType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,20 @@ bool TerrainTypeManager::generate_modifiers(ModifierManager& modifier_manager) c
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", 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
this_unit_terrain_effects.defence, ModifierManager::get_flat_identifier("defence", identifier),
FORMAT_x100_1DP_PC_POS, "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
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", has_no_effect
);
}
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