aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/map/Province.hpp
blob: a62118249ad9d8b88e17e3559cb1eea0298b5798 (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
#pragma once

#include <cassert>

#include "openvic-simulation/map/Building.hpp"
#include "openvic-simulation/pop/Pop.hpp"

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

   /* 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;

      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;
         /* fvec2_t spawn_railway_track; treating as extraneous until proven need */
      };
      

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

   private:
      const index_t index;
      Region* region = nullptr;
      bool has_region = false, water = false;
      life_rating_t life_rating = 0;
      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;
      distribution_t pop_types, cultures, religions;

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

      TerrainType const* terrain_type = nullptr;

      void _set_terrain_type(TerrainType const* type);

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

   public:
      Province(Province&&) = default;

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

      bool add_building(BuildingInstance&& building_instance);
      IDENTIFIER_REGISTRY_ACCESSORS(BuildingInstance, 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;
      distribution_t const& get_pop_type_distribution() const;
      distribution_t const& get_culture_distribution() const;
      distribution_t const& get_religion_distribution() const;
      void update_pops();

      void update_state(Date const& today);
      void tick(Date const& 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;
   };
}