aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/country/CountryInstance.hpp
blob: 1eaf398b2f938864621cf6fba2b888f3ffecd8a7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#pragma once

#include <vector>

#include <plf_colony.h>

#include "openvic-simulation/military/Leader.hpp"
#include "openvic-simulation/military/UnitInstanceGroup.hpp"
#include "openvic-simulation/research/Invention.hpp"
#include "openvic-simulation/research/Technology.hpp"
#include "openvic-simulation/types/Date.hpp"
#include "openvic-simulation/types/IdentifierRegistry.hpp"
#include "openvic-simulation/types/IndexedMap.hpp"
#include "openvic-simulation/utility/Getters.hpp"

namespace OpenVic {
   struct CountryDefinition;
   struct Culture;
   struct Religion;
   struct CountryParty;
   struct Ideology;
   struct ProvinceDefinition;
   struct GovernmentType;
   struct NationalValue;
   struct Reform;
   struct CountryHistoryEntry;

   /* Representation of an existing country that is currently in-game. */
   struct CountryInstance {
      friend struct CountryInstanceManager;

   private:
      CountryDefinition const* PROPERTY_RW(country_definition);
      Culture const* PROPERTY_RW(primary_culture);
      std::vector<Culture const*> PROPERTY(accepted_cultures);
      Religion const* PROPERTY_RW(religion);
      CountryParty const* PROPERTY_RW(ruling_party);
      Date PROPERTY_RW(last_election);
      IndexedMap<Ideology, fixed_point_t> PROPERTY(upper_house);
      // TODO - should this be ProvinceInstance and/or non-const pointer?
      // Currently ProvinceDefinition as that's what CountryHistoryEntry has (loaded prior to ProvinceInstance generation)
      ProvinceDefinition const* PROPERTY_RW(capital);
      GovernmentType const* PROPERTY_RW(government_type);
      fixed_point_t PROPERTY_RW(plurality);
      NationalValue const* PROPERTY_RW(national_value);
      bool PROPERTY_RW(civilised);
      fixed_point_t PROPERTY_RW(prestige);
      std::vector<Reform const*> PROPERTY(reforms); // TODO: should be map of reform groups to active reforms: must set defaults & validate applied history

      IndexedMap<Technology, bool> PROPERTY(technologies);
      IndexedMap<Invention, bool> PROPERTY(inventions);

      // TODO: Military units + OOBs; will probably need an extensible deployment class

      plf::colony<General> PROPERTY(generals);
      plf::colony<Admiral> PROPERTY(admirals);
      ordered_set<ArmyInstance*> PROPERTY(armies);
      ordered_set<NavyInstance*> PROPERTY(navies);

      UNIT_BRANCHED_GETTER(get_unit_instance_groups, armies, navies);
      UNIT_BRANCHED_GETTER(get_leaders, generals, admirals);

      CountryInstance(
         CountryDefinition const* new_country_definition, decltype(technologies)::keys_t const& technology_keys,
         decltype(inventions)::keys_t const& invention_keys, decltype(upper_house)::keys_t const& ideology_keys
      );

   public:
      std::string_view get_identifier() const;

      bool add_accepted_culture(Culture const* new_accepted_culture);
      bool remove_accepted_culture(Culture const* culture_to_remove);
      /* Set a party's popularity in the upper house. */
      bool set_upper_house(Ideology const* ideology, fixed_point_t popularity);
      bool add_reform(Reform const* new_reform);
      bool remove_reform(Reform const* reform_to_remove);

      template<UnitType::branch_t Branch>
      bool add_unit_instance_group(UnitInstanceGroup<Branch>& group);
      template<UnitType::branch_t Branch>
      bool remove_unit_instance_group(UnitInstanceGroup<Branch>& group);

      template<UnitType::branch_t Branch>
      void add_leader(LeaderBranched<Branch>&& leader);
      template<UnitType::branch_t Branch>
      bool remove_leader(LeaderBranched<Branch> const* leader);

      bool apply_history_to_country(CountryHistoryEntry const* entry);
   };

   struct CountryDefinitionManager;
   struct CountryHistoryManager;
   struct UnitInstanceManager;
   struct MapInstance;

   struct CountryInstanceManager {
   private:
      IdentifierRegistry<CountryInstance> IDENTIFIER_REGISTRY(country_instance);

   public:
      bool generate_country_instances(
         CountryDefinitionManager const& country_definition_manager,
         decltype(CountryInstance::technologies)::keys_t const& technology_keys,
         decltype(CountryInstance::inventions)::keys_t const& invention_keys,
         decltype(CountryInstance::upper_house)::keys_t const& ideology_keys
      );

      bool apply_history_to_countries(
         CountryHistoryManager const& history_manager, Date date, UnitInstanceManager& unit_instance_manager,
         MapInstance& map_instance
      );
   };
}