diff options
Diffstat (limited to 'src/openvic-simulation/map/ProvinceInstance.cpp')
-rw-r--r-- | src/openvic-simulation/map/ProvinceInstance.cpp | 187 |
1 files changed, 147 insertions, 40 deletions
diff --git a/src/openvic-simulation/map/ProvinceInstance.cpp b/src/openvic-simulation/map/ProvinceInstance.cpp index 4efcfee..64a104b 100644 --- a/src/openvic-simulation/map/ProvinceInstance.cpp +++ b/src/openvic-simulation/map/ProvinceInstance.cpp @@ -1,16 +1,19 @@ #include "ProvinceInstance.hpp" -#include <cstddef> #include "openvic-simulation/country/CountryInstance.hpp" #include "openvic-simulation/economy/production/ProductionType.hpp" +#include "openvic-simulation/economy/production/ResourceGatheringOperation.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/modifier/StaticModifierCache.hpp" #include "openvic-simulation/politics/Ideology.hpp" -#include "openvic-simulation/economy/production/ResourceGatheringOperation.hpp" #include "openvic-simulation/pop/Pop.hpp" -#include "openvic-simulation/types/fixed_point/FixedPoint.hpp" +#include "openvic-simulation/utility/Logger.hpp" using namespace OpenVic; @@ -26,9 +29,11 @@ ProvinceInstance::ProvinceInstance( owner { nullptr }, controller { nullptr }, cores {}, + modifier_sum {}, + event_modifiers {}, slave { false }, crime { nullptr }, - rgo { ResourceGatheringOperation {} }, + rgo { pop_type_keys }, buildings { "buildings", false }, armies {}, navies {}, @@ -41,15 +46,22 @@ ProvinceInstance::ProvinceInstance( max_supported_regiments { 0 } {} GoodDefinition const* ProvinceInstance::get_rgo_good() const { - if(!rgo.is_valid()) { return nullptr; } - return &(rgo.get_production_type()->get_output_good()); + if (!rgo.is_valid()) { return nullptr; } + return &(rgo.get_production_type_nullable()->get_output_good()); } -void ProvinceInstance::set_rgo_production_type(ProductionType const& rgo_production_type) { - if(rgo_production_type.get_template_type() != ProductionType::template_type_t::RGO) { - //error +bool ProvinceInstance::set_rgo_production_type_nullable(ProductionType const* rgo_production_type_nullable) { + bool is_valid_operation = true; + if (rgo_production_type_nullable != nullptr) { + ProductionType const& rgo_production_type = *rgo_production_type_nullable; + if (rgo_production_type.get_template_type() != ProductionType::template_type_t::RGO) { + Logger::error("Tried setting province ", get_identifier(), " rgo to ", rgo_production_type.get_identifier(), " which is not of template_type RGO."); + is_valid_operation = false; + } + is_valid_operation&=convert_rgo_worker_pops_to_equivalent(rgo_production_type); } - convert_rgo_worker_pops_to_equivalent(rgo_production_type); - rgo.set_production_type(&rgo_production_type); + + rgo.set_production_type_nullable(rgo_production_type_nullable); + return is_valid_operation; } bool ProvinceInstance::set_owner(CountryInstance* new_owner) { @@ -202,49 +214,142 @@ void ProvinceInstance::_update_pops(DefineManager const& define_manager) { } } -fixed_point_t ProvinceInstance::calculate_rgo_size(ProductionType const& production_type) const { - std::vector<Job> const& jobs = production_type.get_jobs(); - fixed_point_t total_worker_count_in_province = 0; //not counting equivalents - for(Pop const& pop : pops) { - bool is_worker_pop_type = false; - for(Job const& job : jobs) { - if(job.get_pop_type() == pop.get_type()) { - is_worker_pop_type = true; - break; +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(static_modifier_cache.get_core(), province_source); + } + if (province_definition.is_water()) { + modifier_sum.add_modifier(static_modifier_cache.get_sea_zone(), province_source); + } else { + modifier_sum.add_modifier(static_modifier_cache.get_land_province(), province_source); + + if (province_definition.is_coastal()) { + modifier_sum.add_modifier(static_modifier_cache.get_coastal(), province_source); + } else { + modifier_sum.add_modifier(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); + + if constexpr (!ADD_OWNER_CONTRIBUTION) { + if (controller != nullptr) { + controller->contribute_province_modifier_sum(modifier_sum); + } + } +} + +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 { + if constexpr (ADD_OWNER_CONTRIBUTION) { + return modifier_sum.get_effect(effect); + } else { + using enum ModifierEffect::target_t; + + if (owner != nullptr) { + if (ModifierEffect::excludes_targets(effect.get_targets(), PROVINCE)) { + // Non-province targeted effects are already added to the country modifier sum + return owner->get_modifier_effect_value(effect); + } else { + // Province-targeted effects aren't passed to the country modifier sum + return owner->get_modifier_effect_value(effect) + modifier_sum.get_effect(effect); } + } else { + return modifier_sum.get_effect(effect); } + } +} + +fixed_point_t ProvinceInstance::get_modifier_effect_value_nullcheck(ModifierEffect const* effect) const { + if (effect != nullptr) { + return get_modifier_effect_value(*effect); + } else { + return fixed_point_t::_0(); + } +} - if(is_worker_pop_type) { - total_worker_count_in_province += pop.get_size(); +void ProvinceInstance::push_contributing_modifiers( + ModifierEffect const& effect, std::vector<ModifierSum::modifier_entry_t>& contributions +) const { + if constexpr (ADD_OWNER_CONTRIBUTION) { + modifier_sum.push_contributing_modifiers(effect, contributions); + } else { + using enum ModifierEffect::target_t; + + if (owner != nullptr) { + if (ModifierEffect::excludes_targets(effect.get_targets(), PROVINCE)) { + // Non-province targeted effects are already added to the country modifier sum + owner->push_contributing_modifiers(effect, contributions); + } else { + // Province-targeted effects aren't passed to the country modifier sum + modifier_sum.push_contributing_modifiers(effect, contributions); + owner->push_contributing_modifiers(effect, contributions); + } + } else { + modifier_sum.push_contributing_modifiers(effect, contributions); } } +} - const fixed_point_t base_workforce_size = production_type.get_base_workforce_size(); - //TODO: if is_farm add farm size bonus - //TODO: if is_mine add mine size bonus - return ((total_worker_count_in_province / base_workforce_size).ceil() * fixed_point_t::_1_50()).floor(); +std::vector<ModifierSum::modifier_entry_t> ProvinceInstance::get_contributing_modifiers(ModifierEffect const& effect) const { + if constexpr (ADD_OWNER_CONTRIBUTION) { + return modifier_sum.get_contributing_modifiers(effect); + } else { + std::vector<ModifierSum::modifier_entry_t> contributions; + + push_contributing_modifiers(effect, contributions); + + return contributions; + } } -void ProvinceInstance::convert_rgo_worker_pops_to_equivalent(ProductionType const& production_type) { +bool ProvinceInstance::convert_rgo_worker_pops_to_equivalent(ProductionType const& production_type) { + bool is_valid_operation = true; std::vector<Job> const& jobs = production_type.get_jobs(); - fixed_point_t total_worker_count_in_province = 0; //not counting equivalents for(Pop& pop : pops) { - bool is_worker_pop_type = false; for(Job const& job : jobs) { PopType const* const job_pop_type = job.get_pop_type(); PopType const* old_pop_type = pop.get_type(); - if(job_pop_type != old_pop_type) { + if (job_pop_type != old_pop_type) { PopType const* const equivalent = old_pop_type->get_equivalent(); - if(job_pop_type == equivalent) { - pop.convert_to_equivalent(); + if (job_pop_type == equivalent) { + is_valid_operation&=pop.convert_to_equivalent(); } } } - - if(is_worker_pop_type) { - total_worker_count_in_province += pop.get_size(); - } } + return is_valid_operation; } void ProvinceInstance::update_gamestate(Date today, DefineManager const& define_manager) { @@ -361,10 +466,8 @@ bool ProvinceInstance::apply_history_to_province(ProvinceHistoryEntry const& ent return ret; } -void ProvinceInstance::setup_rgo(ProductionType const& rgo_production_type) { - convert_rgo_worker_pops_to_equivalent(rgo_production_type); - rgo.set_size_multiplier(calculate_rgo_size(rgo_production_type)); - rgo.set_production_type(&rgo_production_type); +void ProvinceInstance::initialise_for_new_game(ModifierEffectCache const& modifier_effect_cache) { + rgo.initialise_for_new_game(*this, modifier_effect_cache); } void ProvinceInstance::setup_pop_test_values(IssueManager const& issue_manager) { @@ -372,3 +475,7 @@ void ProvinceInstance::setup_pop_test_values(IssueManager const& issue_manager) pop.setup_pop_test_values(issue_manager); } } + +plf::colony<Pop>& ProvinceInstance::get_mutable_pops() { + return pops; +}
\ No newline at end of file |