aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/map/Province.hpp
blob: 21a974fcfdf8200a34a6634fe74cdd15cd68ab17 (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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#pragma once

#include <cassert>

#include "openvic-simulation/economy/Building.hpp"
#include "openvic-simulation/politics/Ideology.hpp"
#include "openvic-simulation/pop/Pop.hpp"
#include "openvic-simulation/country/Country.hpp"

namespace OpenVic {
   struct Map;
   struct Region;
   struct Good;
   struct TerrainType;
   struct TerrainTypeMapping;
   struct ProvinceHistoryMap;

   /* REQUIREMENTS:
    * MAP-5, MAP-7, MAP-8, MAP-43, MAP-47
    * POP-22
    */
   struct Province : HasIdentifierAndColour {
      friend struct Map;

      using index_t = uint16_t;
      using life_rating_t = int8_t;
      using distance_t = uint16_t;
      using flags_t = uint16_t;

      enum struct colony_status_t : int8_t { STATE, PROTECTORATE, COLONY };

      struct adjacency_t {
         friend struct Province;

      private:
         Province const* const province;
         const distance_t distance;
         flags_t flags;

         adjacency_t(Province const* province, distance_t distance, flags_t flags);

      public:
         distance_t get_distance() const;
         flags_t get_flags() const;
      };

      struct province_positions_t {
         fvec2_t text;
         fixed_point_t text_rotation;
         fixed_point_t text_scale;
         fvec2_t unit;
         fvec2_t city;
         fvec2_t factory;
         fvec2_t building_construction;
         fvec2_t military_construction;
         fvec2_t fort;
         fixed_point_t fort_rotation;
         fvec2_t railroad;
         fixed_point_t railroad_rotation;
         fvec2_t navalbase;
         fixed_point_t navalbase_rotation;
      };

      static constexpr index_t NULL_INDEX = 0, MAX_INDEX = std::numeric_limits<index_t>::max();

   private:
      const index_t index;
      Region const* region = nullptr;
      bool on_map = false, has_region = false, water = false;
      life_rating_t life_rating = 0;
      colony_status_t colony_status = colony_status_t::STATE;
      IdentifierRegistry<BuildingInstance> buildings;
      // TODO - change this into a factory-like structure
      Good const* rgo = nullptr;

      std::vector<Pop> pops;
      Pop::pop_size_t total_population;
      fixed_point_map_t<PopType const*> PROPERTY(pop_type_distribution);
      fixed_point_map_t<Ideology const*> PROPERTY(ideology_distribution);
      fixed_point_map_t<Culture const*> PROPERTY(culture_distribution);
      fixed_point_map_t<Religion const*> PROPERTY(religion_distribution);

      std::vector<adjacency_t> adjacencies;
      province_positions_t positions;

      TerrainType const* terrain_type = nullptr;

      void _set_terrain_type(TerrainType const* type);

      Country const* owner = nullptr;
      Country const* controller = nullptr;
      std::vector<Country const*> cores;
      bool slave = false;

      Province(std::string_view new_identifier, colour_t new_colour, index_t new_index);

   public:
      Province(Province&&) = default;

      index_t get_index() const;
      Region const* get_region() const;
      bool get_on_map() const;
      bool get_has_region() const;
      bool get_water() const;
      TerrainType const* get_terrain_type() const;
      life_rating_t get_life_rating() const;
      colony_status_t get_colony_status() const;
      bool load_positions(BuildingManager const& building_manager, ast::NodeCPtr root);

      bool add_building(BuildingInstance&& building_instance);
      IDENTIFIER_REGISTRY_ACCESSORS(building)
      void reset_buildings();
      bool expand_building(std::string_view building_type_identifier);
      Good const* get_rgo() const;
      std::string to_string() const;

      bool load_pop_list(PopManager const& pop_manager, ast::NodeCPtr root);
      bool add_pop(Pop&& pop);
      void clear_pops();
      size_t get_pop_count() const;
      std::vector<Pop> const& get_pops() const;
      Pop::pop_size_t get_total_population() const;
      void update_pops();

      void update_state(Date today);
      void tick(Date today);

      bool is_adjacent_to(Province const* province);
      bool add_adjacency(Province const* province, distance_t distance, flags_t flags);
      std::vector<adjacency_t> const& get_adjacencies() const;

      Country const* get_owner() const;
      Country const* get_controller() const;
      std::vector<Country const*> const& get_cores() const;
      bool is_slave() const;

      void apply_history_to_province(ProvinceHistoryMap const& history, Date date);
   };
}