aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/map/ProvinceInstance.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvic-simulation/map/ProvinceInstance.cpp')
-rw-r--r--src/openvic-simulation/map/ProvinceInstance.cpp187
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