diff options
Diffstat (limited to 'src/openvic-simulation/country')
-rw-r--r-- | src/openvic-simulation/country/CountryInstance.cpp | 163 | ||||
-rw-r--r-- | src/openvic-simulation/country/CountryInstance.hpp | 37 |
2 files changed, 182 insertions, 18 deletions
diff --git a/src/openvic-simulation/country/CountryInstance.cpp b/src/openvic-simulation/country/CountryInstance.cpp index 5ba8782..4fab010 100644 --- a/src/openvic-simulation/country/CountryInstance.cpp +++ b/src/openvic-simulation/country/CountryInstance.cpp @@ -20,7 +20,9 @@ CountryInstance::CountryInstance( decltype(inventions)::keys_t const& invention_keys, decltype(upper_house)::keys_t const& ideology_keys, decltype(government_flag_overrides)::keys_t const& government_type_keys, - decltype(pop_type_distribution)::keys_t const& pop_type_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 ) : /* Main attributes */ country_definition { new_country_definition }, colour { ERROR_COLOUR }, @@ -90,18 +92,43 @@ CountryInstance::CountryInstance( /* Military */ military_power { 0 }, + military_power_from_land { 0 }, + military_power_from_sea { 0 }, + military_power_from_leaders { 0 }, military_rank { 0 }, generals {}, admirals {}, armies {}, navies {}, regiment_count { 0 }, - mobilisation_regiment_potential { 0 }, + max_supported_regiment_count { 0 }, + mobilisation_potential_regiment_count { 0 }, + mobilisation_max_regiment_count { 0 }, + mobilisation_impact { 0 }, + supply_consumption { 1 }, ship_count { 0 }, total_consumed_ship_supply { 0 }, max_ship_supply { 0 }, leadership_points { 0 }, - war_exhaustion { 0 } {} + war_exhaustion { 0 }, + mobilised { false }, + disarmed { false }, + unlocked_regiment_types { &unlocked_regiment_types_keys }, + allowed_regiment_cultures { RegimentType::allowed_cultures_t::NO_CULTURES }, + unlocked_ship_types { &unlocked_ship_types_keys } { + + for (RegimentType const& regiment_type : *unlocked_regiment_types.get_keys()) { + if (regiment_type.is_active()) { + unlock_unit_type(regiment_type); + } + } + + for (ShipType const& ship_type : *unlocked_ship_types.get_keys()) { + if (ship_type.is_active()) { + unlock_unit_type(ship_type); + } + } +} std::string_view CountryInstance::get_identifier() const { return country_definition->get_identifier(); @@ -273,6 +300,44 @@ template void CountryInstance::add_leader(LeaderBranched<UnitType::branch_t::NAV template bool CountryInstance::remove_leader(LeaderBranched<UnitType::branch_t::LAND> const*); template bool CountryInstance::remove_leader(LeaderBranched<UnitType::branch_t::NAVAL> const*); +template<UnitType::branch_t Branch> +void CountryInstance::unlock_unit_type(UnitTypeBranched<Branch> const& unit_type) { + IndexedMap<UnitTypeBranched<Branch>, bool>& unlocked_unit_types = get_unlocked_unit_types<Branch>(); + + decltype(unlocked_regiment_types)::value_ref_t unlock_value = unlocked_unit_types[unit_type]; + + if (unlock_value) { + Logger::warning( + "Attempted to unlock already-unlocked unit type \"", unit_type.get_identifier(), + "\" for country ", get_identifier() + ); + return; + } + + unlock_value = true; + + if constexpr (Branch == UnitType::branch_t::LAND) { + allowed_regiment_cultures = RegimentType::allowed_cultures_get_most_permissive( + allowed_regiment_cultures, unit_type.get_allowed_cultures() + ); + } +} + +template void CountryInstance::unlock_unit_type(UnitTypeBranched<UnitType::branch_t::LAND> const&); +template void CountryInstance::unlock_unit_type(UnitTypeBranched<UnitType::branch_t::NAVAL> const&); + +bool CountryInstance::is_primary_culture(Culture const& culture) const { + return &culture == primary_culture; +} + +bool CountryInstance::is_accepted_culture(Culture const& culture) const { + return accepted_cultures.contains(&culture); +} + +bool CountryInstance::is_primary_or_accepted_culture(Culture const& culture) const { + return is_primary_culture(culture) || is_accepted_culture(culture); +} + void CountryInstance::apply_foreign_investments( fixed_point_map_t<CountryDefinition const*> const& investments, CountryInstanceManager const& country_instance_manager ) { @@ -401,7 +466,7 @@ void CountryInstance::_update_population() { national_militancy = 0; pop_type_distribution.clear(); - for (auto const& state : states) { + for (State const* state : states) { total_population += state->get_total_population(); // TODO - change casting if Pop::pop_size_t changes type @@ -431,7 +496,7 @@ void CountryInstance::_update_diplomacy() { // TODO - update diplomatic points and colonial power } -void CountryInstance::_update_military() { +void CountryInstance::_update_military(DefineManager const& define_manager, UnitTypeManager const& unit_type_manager) { regiment_count = 0; for (ArmyInstance const* army : armies) { @@ -446,10 +511,79 @@ void CountryInstance::_update_military() { total_consumed_ship_supply += navy->get_total_consumed_supply(); } - // TODO - update mobilisation_regiment_potential, max_ship_supply, leadership_points, war_exhaustion + // Calculate military power from land, sea, and leaders + + size_t deployed_non_mobilised_regiments = 0; + for (ArmyInstance const* army : armies) { + for (RegimentInstance const* regiment : army->get_units()) { + if (!regiment->is_mobilised()) { + deployed_non_mobilised_regiments++; + } + } + } + + max_supported_regiment_count = 0; + for (State const* state : states) { + max_supported_regiment_count += state->get_max_supported_regiments(); + } + + // TODO - apply country/tech modifiers to supply consumption + supply_consumption = 1; + + const size_t regular_army_size = std::min(4 * deployed_non_mobilised_regiments, max_supported_regiment_count); + + fixed_point_t sum_of_regiment_type_stats = 0; + for (RegimentType const& regiment_type : unit_type_manager.get_regiment_types()) { + // TODO - apply country/tech modifiers to regiment stats + sum_of_regiment_type_stats += ( + regiment_type.get_attack() + regiment_type.get_defence() /*+ land_attack_modifier + land_defense_modifier*/ + ) * regiment_type.get_discipline(); + } + + military_power_from_land = supply_consumption * fixed_point_t::parse(regular_army_size) * sum_of_regiment_type_stats + / fixed_point_t::parse(7 * (1 + unit_type_manager.get_regiment_type_count())); + + if (disarmed) { + military_power_from_land *= define_manager.get_disarmed_penalty(); + } + + military_power_from_sea = 0; + for (NavyInstance const* navy : navies) { + for (ShipInstance const* ship : navy->get_units()) { + ShipType const& ship_type = ship->get_unit_type(); + + if (ship_type.is_capital()) { + + // TODO - include gun power and hull modifiers + naval attack and defense modifiers + + military_power_from_sea += (ship_type.get_gun_power() /*+ naval_attack_modifier*/) + * (ship_type.get_hull() /* + naval_defense_modifier*/); + } + } + } + military_power_from_sea /= 250; + + military_power_from_leaders = fixed_point_t::parse( + std::min(generals.size() + admirals.size(), deployed_non_mobilised_regiments) + ); + + military_power = military_power_from_land + military_power_from_sea + military_power_from_leaders; + + // Mobilisation calculations + mobilisation_impact = 0; // TODO - apply ruling party's war policy + + mobilisation_max_regiment_count = + ((fixed_point_t::_1() + mobilisation_impact) * fixed_point_t::parse(regiment_count)).to_int64_t(); + + mobilisation_potential_regiment_count = 0; // TODO - calculate max regiments from poor citizens + if (mobilisation_potential_regiment_count > mobilisation_max_regiment_count) { + mobilisation_potential_regiment_count = mobilisation_max_regiment_count; + } + + // TODO - update max_ship_supply, leadership_points, war_exhaustion } -void CountryInstance::update_gamestate(DefineManager const& define_manager) { +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); _update_budget(); @@ -458,7 +592,7 @@ void CountryInstance::update_gamestate(DefineManager const& define_manager) { _update_population(); _update_trade(); _update_diplomacy(); - _update_military(); + _update_military(define_manager, unit_type_manager); total_score = prestige + industrial_power + military_power; @@ -621,13 +755,16 @@ bool CountryInstanceManager::generate_country_instances( decltype(CountryInstance::inventions)::keys_t const& invention_keys, decltype(CountryInstance::upper_house)::keys_t const& ideology_keys, decltype(CountryInstance::government_flag_overrides)::keys_t const& government_type_keys, - decltype(CountryInstance::pop_type_distribution)::keys_t const& pop_type_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 ) { reserve_more(country_instances, country_definition_manager.get_country_definition_count()); for (CountryDefinition const& country_definition : country_definition_manager.get_country_definitions()) { country_instances.add_item({ - &country_definition, technology_keys, invention_keys, ideology_keys, government_type_keys, pop_type_keys + &country_definition, technology_keys, invention_keys, ideology_keys, government_type_keys, pop_type_keys, + unlocked_regiment_types_keys, unlocked_ship_types_keys }); } @@ -676,9 +813,11 @@ bool CountryInstanceManager::apply_history_to_countries( return ret; } -void CountryInstanceManager::update_gamestate(Date today, DefineManager const& define_manager) { +void CountryInstanceManager::update_gamestate( + Date today, DefineManager const& define_manager, UnitTypeManager const& unit_type_manager +) { for (CountryInstance& country : country_instances.get_items()) { - country.update_gamestate(define_manager); + country.update_gamestate(define_manager, unit_type_manager); } update_rankings(today, define_manager); diff --git a/src/openvic-simulation/country/CountryInstance.hpp b/src/openvic-simulation/country/CountryInstance.hpp index 0e8d493..c43f0cd 100644 --- a/src/openvic-simulation/country/CountryInstance.hpp +++ b/src/openvic-simulation/country/CountryInstance.hpp @@ -136,21 +136,34 @@ namespace OpenVic { /* Military */ fixed_point_t PROPERTY(military_power); + fixed_point_t PROPERTY(military_power_from_land); + fixed_point_t PROPERTY(military_power_from_sea); + fixed_point_t PROPERTY(military_power_from_leaders); size_t PROPERTY(military_rank); plf::colony<General> PROPERTY(generals); plf::colony<Admiral> PROPERTY(admirals); ordered_set<ArmyInstance*> PROPERTY(armies); ordered_set<NavyInstance*> PROPERTY(navies); size_t PROPERTY(regiment_count); - size_t PROPERTY(mobilisation_regiment_potential); + size_t PROPERTY(max_supported_regiment_count); + size_t PROPERTY(mobilisation_potential_regiment_count); + size_t PROPERTY(mobilisation_max_regiment_count); + fixed_point_t PROPERTY(mobilisation_impact); + fixed_point_t PROPERTY(supply_consumption); size_t PROPERTY(ship_count); 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); + bool PROPERTY_CUSTOM_PREFIX(mobilised, is); + bool PROPERTY_CUSTOM_PREFIX(disarmed, is); + IndexedMap<RegimentType, bool> PROPERTY(unlocked_regiment_types); + RegimentType::allowed_cultures_t PROPERTY(allowed_regiment_cultures); + IndexedMap<ShipType, bool> PROPERTY(unlocked_ship_types); 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); CountryInstance( CountryDefinition const* new_country_definition, @@ -158,7 +171,9 @@ namespace OpenVic { decltype(inventions)::keys_t const& invention_keys, decltype(upper_house)::keys_t const& ideology_keys, decltype(government_flag_overrides)::keys_t const& government_type_keys, - decltype(pop_type_distribution)::keys_t const& pop_type_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 ); public: @@ -198,6 +213,14 @@ namespace OpenVic { template<UnitType::branch_t Branch> bool remove_leader(LeaderBranched<Branch> const* leader); + template<UnitType::branch_t Branch> + void unlock_unit_type(UnitTypeBranched<Branch> const& unit_type); + + bool is_primary_culture(Culture const& culture) const; + // This only checks the accepted cultures list, ignoring the primary culture. + bool is_accepted_culture(Culture const& culture) const; + bool is_primary_or_accepted_culture(Culture const& culture) const; + // Sets the investment of each country in the map (rather than adding to them), leaving the rest unchanged. void apply_foreign_investments( fixed_point_map_t<CountryDefinition const*> const& investments, @@ -216,11 +239,11 @@ namespace OpenVic { void _update_population(); void _update_trade(); void _update_diplomacy(); - void _update_military(); + void _update_military(DefineManager const& define_manager, UnitTypeManager const& unit_type_manager); public: - void update_gamestate(DefineManager const& define_manager); + void update_gamestate(DefineManager const& define_manager, UnitTypeManager const& unit_type_manager); void tick(); }; @@ -252,7 +275,9 @@ namespace OpenVic { decltype(CountryInstance::inventions)::keys_t const& invention_keys, decltype(CountryInstance::upper_house)::keys_t const& ideology_keys, decltype(CountryInstance::government_flag_overrides)::keys_t const& government_type_keys, - decltype(CountryInstance::pop_type_distribution)::keys_t const& pop_type_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 ); bool apply_history_to_countries( @@ -260,7 +285,7 @@ namespace OpenVic { MapInstance& map_instance ); - void update_gamestate(Date today, DefineManager const& define_manager); + void update_gamestate(Date today, DefineManager const& define_manager, UnitTypeManager const& unit_type_manager); void tick(); }; } |