diff options
-rw-r--r-- | src/openvic-simulation/InstanceManager.cpp | 5 | ||||
-rw-r--r-- | src/openvic-simulation/country/CountryInstance.cpp | 184 | ||||
-rw-r--r-- | src/openvic-simulation/country/CountryInstance.hpp | 54 | ||||
-rw-r--r-- | src/openvic-simulation/map/MapInstance.cpp | 6 | ||||
-rw-r--r-- | src/openvic-simulation/map/MapInstance.hpp | 1 | ||||
-rw-r--r-- | src/openvic-simulation/map/ProvinceInstance.cpp | 64 | ||||
-rw-r--r-- | src/openvic-simulation/map/ProvinceInstance.hpp | 10 |
7 files changed, 264 insertions, 60 deletions
diff --git a/src/openvic-simulation/InstanceManager.cpp b/src/openvic-simulation/InstanceManager.cpp index c9ce24a..7f8a804 100644 --- a/src/openvic-simulation/InstanceManager.cpp +++ b/src/openvic-simulation/InstanceManager.cpp @@ -39,6 +39,11 @@ void InstanceManager::update_gamestate() { Logger::info("Update: ", today); + map_instance.update_modifier_sums(today, definition_manager.get_modifier_manager().get_static_modifier_cache()); + country_instance_manager.update_modifier_sums( + today, definition_manager.get_modifier_manager().get_static_modifier_cache() + ); + // Update gamestate... map_instance.update_gamestate(today, definition_manager.get_define_manager()); country_instance_manager.update_gamestate( diff --git a/src/openvic-simulation/country/CountryInstance.cpp b/src/openvic-simulation/country/CountryInstance.cpp index 55ceb23..b3df096 100644 --- a/src/openvic-simulation/country/CountryInstance.cpp +++ b/src/openvic-simulation/country/CountryInstance.cpp @@ -17,16 +17,16 @@ static constexpr colour_t ERROR_COLOUR = colour_t::from_integer(0xFF0000); CountryInstance::CountryInstance( CountryDefinition const* new_country_definition, - decltype(unlocked_building_types)::keys_t const& building_type_keys, - decltype(unlocked_technologies)::keys_t const& technology_keys, - decltype(unlocked_inventions)::keys_t const& invention_keys, + decltype(building_type_unlock_levels)::keys_t const& building_type_keys, + decltype(technology_unlock_levels)::keys_t const& technology_keys, + decltype(invention_unlock_levels)::keys_t const& invention_keys, decltype(upper_house)::keys_t const& ideology_keys, decltype(reforms)::keys_t const& reform_keys, decltype(government_flag_overrides)::keys_t const& government_type_keys, - decltype(unlocked_crimes)::keys_t const& crime_keys, + decltype(crime_unlock_levels)::keys_t const& crime_keys, decltype(pop_type_distribution)::keys_t const& pop_type_keys, - decltype(unlocked_regiment_types)::keys_t const& unlocked_regiment_types_keys, - decltype(unlocked_ship_types)::keys_t const& unlocked_ship_types_keys + decltype(regiment_type_unlock_levels)::keys_t const& regiment_type_unlock_levels_keys, + decltype(ship_type_unlock_levels)::keys_t const& ship_type_unlock_levels_keys ) : /* Main attributes */ country_definition { new_country_definition }, colour { ERROR_COLOUR }, @@ -41,6 +41,8 @@ CountryInstance::CountryInstance( controlled_provinces {}, core_provinces {}, states {}, + modifier_sum {}, + event_modifiers {}, /* Production */ industrial_power { 0 }, @@ -48,14 +50,14 @@ CountryInstance::CountryInstance( industrial_power_from_investments {}, industrial_rank { 0 }, foreign_investments {}, - unlocked_building_types { &building_type_keys }, + building_type_unlock_levels { &building_type_keys }, /* Budget */ cash_stockpile { 0 }, /* Technology */ - unlocked_technologies { &technology_keys }, - unlocked_inventions { &invention_keys }, + technology_unlock_levels { &technology_keys }, + invention_unlock_levels { &invention_keys }, current_research { nullptr }, invested_research_points { 0 }, expected_completion_date {}, @@ -79,7 +81,7 @@ CountryInstance::CountryInstance( infamy { 0 }, plurality { 0 }, revanchism { 0 }, - unlocked_crimes { &crime_keys }, + crime_unlock_levels { &crime_keys }, /* Population */ primary_culture { nullptr }, @@ -121,32 +123,32 @@ CountryInstance::CountryInstance( war_exhaustion { 0 }, mobilised { false }, disarmed { false }, - unlocked_regiment_types { &unlocked_regiment_types_keys }, + regiment_type_unlock_levels { ®iment_type_unlock_levels_keys }, allowed_regiment_cultures { RegimentType::allowed_cultures_t::NO_CULTURES }, - unlocked_ship_types { &unlocked_ship_types_keys }, + ship_type_unlock_levels { &ship_type_unlock_levels_keys }, gas_attack_unlock_level { 0 }, gas_defence_unlock_level { 0 }, unit_variant_unlock_levels {} { - for (BuildingType const& building_type : *unlocked_building_types.get_keys()) { + for (BuildingType const& building_type : *building_type_unlock_levels.get_keys()) { if (building_type.is_default_enabled()) { unlock_building_type(building_type); } } - for (Crime const& crime : *unlocked_crimes.get_keys()) { + for (Crime const& crime : *crime_unlock_levels.get_keys()) { if (crime.is_default_active()) { unlock_crime(crime); } } - for (RegimentType const& regiment_type : *unlocked_regiment_types.get_keys()) { + for (RegimentType const& regiment_type : *regiment_type_unlock_levels.get_keys()) { if (regiment_type.is_active()) { unlock_unit_type(regiment_type); } } - for (ShipType const& ship_type : *unlocked_ship_types.get_keys()) { + for (ShipType const& ship_type : *ship_type_unlock_levels.get_keys()) { if (ship_type.is_active()) { unlock_unit_type(ship_type); } @@ -335,7 +337,7 @@ template bool CountryInstance::remove_leader(LeaderBranched<UnitType::branch_t:: template<UnitType::branch_t Branch> bool CountryInstance::modify_unit_type_unlock(UnitTypeBranched<Branch> const& unit_type, unlock_level_t unlock_level_change) { - IndexedMap<UnitTypeBranched<Branch>, unlock_level_t>& unlocked_unit_types = get_unlocked_unit_types<Branch>(); + IndexedMap<UnitTypeBranched<Branch>, unlock_level_t>& unlocked_unit_types = get_unit_type_unlock_levels<Branch>(); typename IndexedMap<UnitTypeBranched<Branch>, unlock_level_t>::value_ref_t unlock_level = unlocked_unit_types[unit_type]; @@ -384,9 +386,9 @@ bool CountryInstance::is_unit_type_unlocked(UnitType const& unit_type) const { switch (unit_type.get_branch()) { case LAND: - return unlocked_regiment_types[static_cast<UnitTypeBranched<LAND> const&>(unit_type)] > 0; + return regiment_type_unlock_levels[static_cast<UnitTypeBranched<LAND> const&>(unit_type)] > 0; case NAVAL: - return unlocked_ship_types[static_cast<UnitTypeBranched<NAVAL> const&>(unit_type)] > 0; + return ship_type_unlock_levels[static_cast<UnitTypeBranched<NAVAL> const&>(unit_type)] > 0; default: Logger::error( "Attempted to check if unit type \"", unit_type.get_identifier(), "\" with invalid branch ", @@ -397,7 +399,7 @@ bool CountryInstance::is_unit_type_unlocked(UnitType const& unit_type) const { } bool CountryInstance::modify_building_type_unlock(BuildingType const& building_type, unlock_level_t unlock_level_change) { - decltype(unlocked_building_types)::value_ref_t unlock_level = unlocked_building_types[building_type]; + decltype(building_type_unlock_levels)::value_ref_t unlock_level = building_type_unlock_levels[building_type]; // This catches subtracting below 0 or adding above the int types maximum value if (unlock_level + unlock_level_change < 0) { @@ -420,11 +422,11 @@ bool CountryInstance::unlock_building_type(BuildingType const& building_type) { } bool CountryInstance::is_building_type_unlocked(BuildingType const& building_type) const { - return unlocked_building_types[building_type] > 0; + return building_type_unlock_levels[building_type] > 0; } bool CountryInstance::modify_crime_unlock(Crime const& crime, unlock_level_t unlock_level_change) { - decltype(unlocked_crimes)::value_ref_t unlock_level = unlocked_crimes[crime]; + decltype(crime_unlock_levels)::value_ref_t unlock_level = crime_unlock_levels[crime]; // This catches subtracting below 0 or adding above the int types maximum value if (unlock_level + unlock_level_change < 0) { @@ -447,7 +449,7 @@ bool CountryInstance::unlock_crime(Crime const& crime) { } bool CountryInstance::is_crime_unlocked(Crime const& crime) const { - return unlocked_crimes[crime] > 0; + return crime_unlock_levels[crime] > 0; } bool CountryInstance::modify_gas_attack_unlock(unlock_level_t unlock_level_change) { @@ -543,7 +545,7 @@ CountryInstance::unit_variant_t CountryInstance::get_max_unlocked_unit_variant() } bool CountryInstance::modify_technology_unlock(Technology const& technology, unlock_level_t unlock_level_change) { - decltype(unlocked_technologies)::value_ref_t unlock_level = unlocked_technologies[technology]; + decltype(technology_unlock_levels)::value_ref_t unlock_level = technology_unlock_levels[technology]; // This catches subtracting below 0 or adding above the int types maximum value if (unlock_level + unlock_level_change < 0) { @@ -576,7 +578,7 @@ bool CountryInstance::modify_technology_unlock(Technology const& technology, unl } bool CountryInstance::set_technology_unlock_level(Technology const& technology, unlock_level_t unlock_level) { - const unlock_level_t unlock_level_change = unlock_level - unlocked_technologies[technology]; + const unlock_level_t unlock_level_change = unlock_level - technology_unlock_levels[technology]; return unlock_level_change != 0 ? modify_technology_unlock(technology, unlock_level_change) : true; } @@ -585,11 +587,11 @@ bool CountryInstance::unlock_technology(Technology const& technology) { } bool CountryInstance::is_technology_unlocked(Technology const& technology) const { - return unlocked_technologies[technology] > 0; + return technology_unlock_levels[technology] > 0; } bool CountryInstance::modify_invention_unlock(Invention const& invention, unlock_level_t unlock_level_change) { - decltype(unlocked_inventions)::value_ref_t unlock_level = unlocked_inventions[invention]; + decltype(invention_unlock_levels)::value_ref_t unlock_level = invention_unlock_levels[invention]; // This catches subtracting below 0 or adding above the int types maximum value if (unlock_level + unlock_level_change < 0) { @@ -628,7 +630,7 @@ bool CountryInstance::modify_invention_unlock(Invention const& invention, unlock } bool CountryInstance::set_invention_unlock_level(Invention const& invention, unlock_level_t unlock_level) { - const unlock_level_t unlock_level_change = unlock_level - unlocked_inventions[invention]; + const unlock_level_t unlock_level_change = unlock_level - invention_unlock_levels[invention]; return unlock_level_change != 0 ? modify_invention_unlock(invention, unlock_level_change) : true; } @@ -637,7 +639,7 @@ bool CountryInstance::unlock_invention(Invention const& invention) { } bool CountryInstance::is_invention_unlocked(Invention const& invention) const { - return unlocked_inventions[invention] > 0; + return invention_unlock_levels[invention] > 0; } bool CountryInstance::is_primary_culture(Culture const& culture) const { @@ -671,7 +673,7 @@ bool CountryInstance::apply_history_to_country( bool ret = true; - set_optional(primary_culture, entry.get_primary_culture()); + set_optional(primary_culture, entry.get_primary_culture()); for (auto const& [culture, add] : entry.get_accepted_cultures()) { if (add) { ret &= add_accepted_culture(*culture); @@ -927,6 +929,106 @@ bool CountryInstance::update_rule_set() { return rule_set.trim_and_resolve_conflicts(true); } +void CountryInstance::update_modifier_sum(Date today, StaticModifierCache const& static_modifier_cache) { + // Update sum of national modifiers + modifier_sum.clear(); + + const ModifierSum::modifier_source_t country_source { this }; + + // Erase expired event modifiers and add non-expired ones to the sum + std::erase_if(event_modifiers, [this, today, &country_source](ModifierInstance const& modifier) -> bool { + if (today <= modifier.get_expiry_date()) { + modifier_sum.add_modifier(*modifier.get_modifier(), country_source); + return false; + } else { + return true; + } + }); + + // Add static modifiers + modifier_sum.add_modifier_nullcheck(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); + break; + case COUNTRY_STATUS_SECONDARY_POWER: + modifier_sum.add_modifier_nullcheck(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); + break; + default: + modifier_sum.add_modifier_nullcheck(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_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); + // TODO - difficulty modifiers, war, peace, debt_default_to, bad_debter, generalised_debt_default, + // total_occupation, total_blockaded, in_bankrupcy + + // TODO - handle triggered modifiers + + if (ruling_party != nullptr) { + for (Issue const* issue : ruling_party->get_policies()) { + // The ruling party's issues here could be null as they're stored in an IndexedMap which has + // values for every IssueGroup regardless of whether or not they have a policy set. + modifier_sum.add_modifier_nullcheck(issue, country_source); + } + } + + for (Reform const* reform : reforms) { + // The country's reforms here could be null as they're stored in an IndexedMap which has + // values for every ReformGroup regardless of whether or not they have a reform set. + modifier_sum.add_modifier_nullcheck(reform, country_source); + } + + modifier_sum.add_modifier_nullcheck(national_value, country_source); + + modifier_sum.add_modifier_nullcheck(tech_school, country_source); + + for (Technology const& technology : *technology_unlock_levels.get_keys()) { + if (is_technology_unlocked(technology)) { + modifier_sum.add_modifier(technology, country_source); + } + } + + for (Invention const& invention : *invention_unlock_levels.get_keys()) { + if (is_invention_unlocked(invention)) { + modifier_sum.add_modifier(invention, country_source); + } + } + + // Add province base modifiers (with local province modifier effects removed) + using enum ModifierEffect::target_t; + static constexpr ModifierEffect::target_t NOT_PROVINCE = ALL_TARGETS & ~PROVINCE; + + for (ProvinceInstance const* province : owned_provinces) { + modifier_sum.add_modifier_sum_filter_targets(province->get_modifier_sum(), NOT_PROVINCE); + } + + // This has to be done after adding all province modifiers to the country's sum, otherwise provinces earlier in the list + // wouldn't be affected by modifiers from provinces later in the list. + for (ProvinceInstance* province : owned_provinces) { + province->contribute_country_modifier_sum(modifier_sum); + } + + // TODO - calculate stats for each unit type (locked and unlocked) +} + +fixed_point_t CountryInstance::get_modifier_effect_value(ModifierEffect const& effect) const { + return modifier_sum.get_effect(effect); +} + +fixed_point_t CountryInstance::get_modifier_effect_value_nullcheck(ModifierEffect const* effect) const { + return modifier_sum.get_effect_nullcheck(effect); +} + void CountryInstance::update_gamestate(DefineManager const& define_manager, UnitTypeManager const& unit_type_manager) { // Order of updates might need to be changed/functions split up to account for dependencies _update_production(define_manager); @@ -1095,16 +1197,16 @@ CountryInstance const& CountryInstanceManager::get_country_instance_from_definit bool CountryInstanceManager::generate_country_instances( CountryDefinitionManager const& country_definition_manager, - decltype(CountryInstance::unlocked_building_types)::keys_t const& building_type_keys, - decltype(CountryInstance::unlocked_technologies)::keys_t const& technology_keys, - decltype(CountryInstance::unlocked_inventions)::keys_t const& invention_keys, + decltype(CountryInstance::building_type_unlock_levels)::keys_t const& building_type_keys, + decltype(CountryInstance::technology_unlock_levels)::keys_t const& technology_keys, + decltype(CountryInstance::invention_unlock_levels)::keys_t const& invention_keys, decltype(CountryInstance::upper_house)::keys_t const& ideology_keys, decltype(CountryInstance::reforms)::keys_t const& reform_keys, decltype(CountryInstance::government_flag_overrides)::keys_t const& government_type_keys, - decltype(CountryInstance::unlocked_crimes)::keys_t const& crime_keys, + decltype(CountryInstance::crime_unlock_levels)::keys_t const& crime_keys, decltype(CountryInstance::pop_type_distribution)::keys_t const& pop_type_keys, - decltype(CountryInstance::unlocked_regiment_types)::keys_t const& unlocked_regiment_types_keys, - decltype(CountryInstance::unlocked_ship_types)::keys_t const& unlocked_ship_types_keys + decltype(CountryInstance::regiment_type_unlock_levels)::keys_t const& regiment_type_unlock_levels_keys, + decltype(CountryInstance::ship_type_unlock_levels)::keys_t const& ship_type_unlock_levels_keys ) { reserve_more(country_instances, country_definition_manager.get_country_definition_count()); @@ -1121,8 +1223,8 @@ bool CountryInstanceManager::generate_country_instances( government_type_keys, crime_keys, pop_type_keys, - unlocked_regiment_types_keys, - unlocked_ship_types_keys + regiment_type_unlock_levels_keys, + ship_type_unlock_levels_keys }); } @@ -1171,6 +1273,12 @@ bool CountryInstanceManager::apply_history_to_countries( return ret; } +void CountryInstanceManager::update_modifier_sums(Date today, StaticModifierCache const& static_modifier_cache) { + for (CountryInstance& country : country_instances.get_items()) { + country.update_modifier_sum(today, static_modifier_cache); + } +} + void CountryInstanceManager::update_gamestate( Date today, DefineManager const& define_manager, UnitTypeManager const& unit_type_manager ) { diff --git a/src/openvic-simulation/country/CountryInstance.hpp b/src/openvic-simulation/country/CountryInstance.hpp index a7128aa..c9b61e3 100644 --- a/src/openvic-simulation/country/CountryInstance.hpp +++ b/src/openvic-simulation/country/CountryInstance.hpp @@ -6,6 +6,7 @@ #include "openvic-simulation/military/Leader.hpp" #include "openvic-simulation/military/UnitInstanceGroup.hpp" +#include "openvic-simulation/modifier/ModifierSum.hpp" #include "openvic-simulation/politics/Rule.hpp" #include "openvic-simulation/pop/Pop.hpp" #include "openvic-simulation/types/Date.hpp" @@ -80,13 +81,17 @@ namespace OpenVic { ordered_set<ProvinceInstance*> PROPERTY(core_provinces); ordered_set<State*> PROPERTY(states); + // The total/resultant modifier affecting this country, including owned province contributions. + ModifierSum PROPERTY(modifier_sum); + std::vector<ModifierInstance> PROPERTY(event_modifiers); + /* Production */ fixed_point_t PROPERTY(industrial_power); std::vector<std::pair<State const*, fixed_point_t>> PROPERTY(industrial_power_from_states); std::vector<std::pair<CountryInstance const*, fixed_point_t>> PROPERTY(industrial_power_from_investments); size_t PROPERTY(industrial_rank); fixed_point_map_t<CountryInstance const*> PROPERTY(foreign_investments); - IndexedMap<BuildingType, unlock_level_t> PROPERTY(unlocked_building_types); + IndexedMap<BuildingType, unlock_level_t> PROPERTY(building_type_unlock_levels); // TODO - total amount of each good produced /* Budget */ @@ -94,8 +99,8 @@ namespace OpenVic { // TODO - cash stockpile change over last 30 days /* Technology */ - IndexedMap<Technology, unlock_level_t> PROPERTY(unlocked_technologies); - IndexedMap<Invention, unlock_level_t> PROPERTY(unlocked_inventions); + IndexedMap<Technology, unlock_level_t> PROPERTY(technology_unlock_levels); + IndexedMap<Invention, unlock_level_t> PROPERTY(invention_unlock_levels); Technology const* PROPERTY(current_research); fixed_point_t PROPERTY(invested_research_points); Date PROPERTY(expected_completion_date); @@ -118,10 +123,10 @@ namespace OpenVic { IndexedMap<GovernmentType, GovernmentType const*> PROPERTY(government_flag_overrides); GovernmentType const* PROPERTY(flag_government_type); fixed_point_t PROPERTY(suppression_points); - fixed_point_t PROPERTY(infamy); - fixed_point_t PROPERTY(plurality); + fixed_point_t PROPERTY(infamy); // in 0-25+ range + fixed_point_t PROPERTY(plurality); // in 0-100 range fixed_point_t PROPERTY(revanchism); - IndexedMap<Crime, unlock_level_t> PROPERTY(unlocked_crimes); + IndexedMap<Crime, unlock_level_t> PROPERTY(crime_unlock_levels); // TODO - rebel movements /* Population */ @@ -165,32 +170,32 @@ namespace OpenVic { fixed_point_t PROPERTY(total_consumed_ship_supply); fixed_point_t PROPERTY(max_ship_supply); fixed_point_t PROPERTY(leadership_points); - fixed_point_t PROPERTY(war_exhaustion); + fixed_point_t PROPERTY(war_exhaustion); // in 0-100 range bool PROPERTY_CUSTOM_PREFIX(mobilised, is); bool PROPERTY_CUSTOM_PREFIX(disarmed, is); - IndexedMap<RegimentType, unlock_level_t> PROPERTY(unlocked_regiment_types); + IndexedMap<RegimentType, unlock_level_t> PROPERTY(regiment_type_unlock_levels); RegimentType::allowed_cultures_t PROPERTY(allowed_regiment_cultures); - IndexedMap<ShipType, unlock_level_t> PROPERTY(unlocked_ship_types); + IndexedMap<ShipType, unlock_level_t> PROPERTY(ship_type_unlock_levels); unlock_level_t PROPERTY(gas_attack_unlock_level); unlock_level_t PROPERTY(gas_defence_unlock_level); std::vector<unlock_level_t> PROPERTY(unit_variant_unlock_levels); UNIT_BRANCHED_GETTER(get_unit_instance_groups, armies, navies); UNIT_BRANCHED_GETTER(get_leaders, generals, admirals); - UNIT_BRANCHED_GETTER(get_unlocked_unit_types, unlocked_regiment_types, unlocked_ship_types); + UNIT_BRANCHED_GETTER(get_unit_type_unlock_levels, regiment_type_unlock_levels, ship_type_unlock_levels); CountryInstance( CountryDefinition const* new_country_definition, - decltype(unlocked_building_types)::keys_t const& building_type_keys, - decltype(unlocked_technologies)::keys_t const& technology_keys, - decltype(unlocked_inventions)::keys_t const& invention_keys, + decltype(building_type_unlock_levels)::keys_t const& building_type_keys, + decltype(technology_unlock_levels)::keys_t const& technology_keys, + decltype(invention_unlock_levels)::keys_t const& invention_keys, decltype(upper_house)::keys_t const& ideology_keys, decltype(reforms)::keys_t const& reform_keys, decltype(government_flag_overrides)::keys_t const& government_type_keys, - decltype(unlocked_crimes)::keys_t const& crime_keys, + decltype(crime_unlock_levels)::keys_t const& crime_keys, decltype(pop_type_distribution)::keys_t const& pop_type_keys, - decltype(unlocked_regiment_types)::keys_t const& unlocked_regiment_types_keys, - decltype(unlocked_ship_types)::keys_t const& unlocked_ship_types_keys + decltype(regiment_type_unlock_levels)::keys_t const& regiment_type_unlock_levels_keys, + decltype(ship_type_unlock_levels)::keys_t const& ship_type_unlock_levels_keys ); public: @@ -296,6 +301,10 @@ namespace OpenVic { public: + void update_modifier_sum(Date today, StaticModifierCache const& static_modifier_cache); + fixed_point_t get_modifier_effect_value(ModifierEffect const& effect) const; + fixed_point_t get_modifier_effect_value_nullcheck(ModifierEffect const* effect) const; + void update_gamestate(DefineManager const& define_manager, UnitTypeManager const& unit_type_manager); void tick(); }; @@ -324,16 +333,16 @@ namespace OpenVic { bool generate_country_instances( CountryDefinitionManager const& country_definition_manager, - decltype(CountryInstance::unlocked_building_types)::keys_t const& building_type_keys, - decltype(CountryInstance::unlocked_technologies)::keys_t const& technology_keys, - decltype(CountryInstance::unlocked_inventions)::keys_t const& invention_keys, + decltype(CountryInstance::building_type_unlock_levels)::keys_t const& building_type_keys, + decltype(CountryInstance::technology_unlock_levels)::keys_t const& technology_keys, + decltype(CountryInstance::invention_unlock_levels)::keys_t const& invention_keys, decltype(CountryInstance::upper_house)::keys_t const& ideology_keys, decltype(CountryInstance::reforms)::keys_t const& reform_keys, decltype(CountryInstance::government_flag_overrides)::keys_t const& government_type_keys, - decltype(CountryInstance::unlocked_crimes)::keys_t const& crime_keys, + decltype(CountryInstance::crime_unlock_levels)::keys_t const& crime_keys, decltype(CountryInstance::pop_type_distribution)::keys_t const& pop_type_keys, - decltype(CountryInstance::unlocked_regiment_types)::keys_t const& unlocked_regiment_types_keys, - decltype(CountryInstance::unlocked_ship_types)::keys_t const& unlocked_ship_types_keys + decltype(CountryInstance::regiment_type_unlock_levels)::keys_t const& regiment_type_unlock_levels_keys, + decltype(CountryInstance::ship_type_unlock_levels)::keys_t const& ship_type_unlock_levels_keys ); bool apply_history_to_countries( @@ -341,6 +350,7 @@ namespace OpenVic { MapInstance& map_instance ); + void update_modifier_sums(Date today, StaticModifierCache const& static_modifier_cache); void update_gamestate(Date today, DefineManager const& define_manager, UnitTypeManager const& unit_type_manager); void tick(); }; diff --git a/src/openvic-simulation/map/MapInstance.cpp b/src/openvic-simulation/map/MapInstance.cpp index 0ce8cea..d8ec2fb 100644 --- a/src/openvic-simulation/map/MapInstance.cpp +++ b/src/openvic-simulation/map/MapInstance.cpp @@ -118,6 +118,12 @@ bool MapInstance::apply_history_to_provinces( return ret; } +void MapInstance::update_modifier_sums(Date today, StaticModifierCache const& static_modifier_cache) { + for (ProvinceInstance& province : province_instances.get_items()) { + province.update_modifier_sum(today, static_modifier_cache); + } +} + void MapInstance::update_gamestate(Date today, DefineManager const& define_manager) { for (ProvinceInstance& province : province_instances.get_items()) { province.update_gamestate(today, define_manager); diff --git a/src/openvic-simulation/map/MapInstance.hpp b/src/openvic-simulation/map/MapInstance.hpp index 99c13d3..e7c623e 100644 --- a/src/openvic-simulation/map/MapInstance.hpp +++ b/src/openvic-simulation/map/MapInstance.hpp @@ -52,6 +52,7 @@ namespace OpenVic { IssueManager const& issue_manager ); + void update_modifier_sums(Date today, StaticModifierCache const& static_modifier_cache); void update_gamestate(Date today, DefineManager const& define_manager); void tick(Date today); }; diff --git a/src/openvic-simulation/map/ProvinceInstance.cpp b/src/openvic-simulation/map/ProvinceInstance.cpp index 06b3f1e..e85c576 100644 --- a/src/openvic-simulation/map/ProvinceInstance.cpp +++ b/src/openvic-simulation/map/ProvinceInstance.cpp @@ -2,7 +2,10 @@ #include "openvic-simulation/country/CountryInstance.hpp" #include "openvic-simulation/history/ProvinceHistory.hpp" +#include "openvic-simulation/map/Crime.hpp" #include "openvic-simulation/map/ProvinceDefinition.hpp" +#include "openvic-simulation/map/Region.hpp" +#include "openvic-simulation/map/TerrainType.hpp" #include "openvic-simulation/military/UnitInstanceGroup.hpp" #include "openvic-simulation/misc/Define.hpp" #include "openvic-simulation/politics/Ideology.hpp" @@ -21,6 +24,8 @@ ProvinceInstance::ProvinceInstance( owner { nullptr }, controller { nullptr }, cores {}, + modifier_sum {}, + event_modifiers {}, slave { false }, crime { nullptr }, rgo { nullptr }, @@ -185,6 +190,65 @@ void ProvinceInstance::_update_pops(DefineManager const& define_manager) { } } +void ProvinceInstance::update_modifier_sum(Date today, StaticModifierCache const& static_modifier_cache) { + // Update sum of direct province modifiers + modifier_sum.clear(); + + const ModifierSum::modifier_source_t province_source { this }; + + // Erase expired event modifiers and add non-expired ones to the sum + std::erase_if(event_modifiers, [this, today, &province_source](ModifierInstance const& modifier) -> bool { + if (today <= modifier.get_expiry_date()) { + modifier_sum.add_modifier(*modifier.get_modifier(), province_source); + return false; + } else { + return true; + } + }); + + // Add static modifiers + if (is_owner_core()) { + modifier_sum.add_modifier_nullcheck(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); + } else { + modifier_sum.add_modifier_nullcheck(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); + } else { + modifier_sum.add_modifier_nullcheck(static_modifier_cache.get_non_coastal(), province_source); + } + + // TODO - overseas, blockaded, no_adjacent_controlled, has_siege, occupied, nationalism, infrastructure + } + + for (BuildingInstance const& building : buildings.get_items()) { + modifier_sum.add_modifier(building.get_building_type(), province_source); + } + + modifier_sum.add_modifier_nullcheck(crime, province_source); + + modifier_sum.add_modifier_nullcheck(province_definition.get_continent(), province_source); + + modifier_sum.add_modifier_nullcheck(province_definition.get_climate(), province_source); + + modifier_sum.add_modifier_nullcheck(terrain_type, province_source); +} + +void ProvinceInstance::contribute_country_modifier_sum(ModifierSum const& owner_modifier_sum) { + modifier_sum.add_modifier_sum_exclude_source(owner_modifier_sum, this); +} + +fixed_point_t ProvinceInstance::get_modifier_effect_value(ModifierEffect const& effect) const { + return modifier_sum.get_effect(effect); +} + +fixed_point_t ProvinceInstance::get_modifier_effect_value_nullcheck(ModifierEffect const* effect) const { + return modifier_sum.get_effect_nullcheck(effect); +} + void ProvinceInstance::update_gamestate(Date today, DefineManager const& define_manager) { for (BuildingInstance& building : buildings.get_items()) { building.update_gamestate(today); diff --git a/src/openvic-simulation/map/ProvinceInstance.hpp b/src/openvic-simulation/map/ProvinceInstance.hpp index fa0be98..0b02c41 100644 --- a/src/openvic-simulation/map/ProvinceInstance.hpp +++ b/src/openvic-simulation/map/ProvinceInstance.hpp @@ -5,6 +5,7 @@ #include "openvic-simulation/economy/BuildingInstance.hpp" #include "openvic-simulation/military/UnitInstance.hpp" #include "openvic-simulation/military/UnitType.hpp" +#include "openvic-simulation/modifier/ModifierSum.hpp" #include "openvic-simulation/pop/Pop.hpp" #include "openvic-simulation/types/fixed_point/FixedPointMap.hpp" #include "openvic-simulation/types/HasIdentifier.hpp" @@ -68,6 +69,10 @@ namespace OpenVic { CountryInstance* PROPERTY(controller); ordered_set<CountryInstance*> PROPERTY(cores); + // The total/resultant modifier affecting this province, including owner country contributions. + ModifierSum PROPERTY(modifier_sum); + std::vector<ModifierInstance> PROPERTY(event_modifiers); + bool PROPERTY(slave); Crime const* PROPERTY_RW(crime); // TODO - change this into a factory-like structure @@ -124,6 +129,11 @@ namespace OpenVic { bool add_pop_vec(std::vector<PopBase> const& pop_vec); size_t get_pop_count() const; + void update_modifier_sum(Date today, StaticModifierCache const& static_modifier_cache); + void contribute_country_modifier_sum(ModifierSum const& owner_modifier_sum); + fixed_point_t get_modifier_effect_value(ModifierEffect const& effect) const; + fixed_point_t get_modifier_effect_value_nullcheck(ModifierEffect const* effect) const; + void update_gamestate(Date today, DefineManager const& define_manager); void tick(Date today); |