aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/economy/Building.hpp
blob: cbf5bfd5b7d8afdf76d9cd19f55de6faf2046671 (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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#pragma once

#include "openvic-simulation/types/Date.hpp"
#include "openvic-simulation/types/fixed_point/FixedPoint.hpp"
#include "openvic-simulation/types/IdentifierRegistry.hpp"
#include "openvic-simulation/economy/Good.hpp"
#include "openvic-simulation/economy/ProductionType.hpp"
#include "openvic-simulation/Modifier.hpp"

#define ARGS \
   ModifierValue&& modifier, std::string_view on_completion, fixed_point_t completion_size, level_t max_level, \
   Good::good_map_t&& goods_cost, fixed_point_t cost, Timespan build_time, bool visibility, bool on_map, bool default_enabled, \
   ProductionType const* production_type, bool pop_build_factory, bool strategic_factory, bool advanced_factory, level_t fort_level, \
   uint64_t naval_capacity, std::vector<fixed_point_t>&& colonial_points, bool in_province, bool one_per_state, fixed_point_t colonial_range, \
   fixed_point_t infrastructure, bool spawn_railway_track, bool sail, bool steam, \
   bool capital, bool port

namespace OpenVic {

   struct BuildingManager;
   struct BuildingType;

   /* REQUIREMENTS:
    * MAP-11, MAP-72, MAP-73
    * MAP-12, MAP-75, MAP-76
    * MAP-13, MAP-78, MAP-79
    */
   struct Building : HasIdentifier {
      friend struct BuildingManager;

      using level_t = int16_t;

   private:
      BuildingType const& type;
      ModifierValue modifier;
      const std::string on_completion; //probably sound played on completion
      const fixed_point_t completion_size;
      const level_t max_level;
      const Good::good_map_t goods_cost;
      const fixed_point_t cost;
      const Timespan build_time; //time
      const bool visibility;
      const bool on_map; //onmap

      const bool default_enabled;
      ProductionType const* production_type;
      const bool pop_build_factory;
      const bool strategic_factory;
      const bool advanced_factory;

      const level_t fort_level; //probably the step-per-level

      const uint64_t naval_capacity;
      const std::vector<fixed_point_t> colonial_points;
      const bool in_province; //province
      const bool one_per_state;
      const fixed_point_t colonial_range;

      const fixed_point_t infrastructure;
      const bool spawn_railway_track;

      const bool sail; //only in clipper shipyard
      const bool steam; //only in steamer shipyard
      const bool capital; //only in naval base
      const bool port; //only in naval base

      Building(std::string_view identifier, BuildingType const& type, ARGS);

   public:
      Building(Building&&) = default;

      BuildingType const& get_type() const;
      ModifierValue const& get_modifier() const;
      std::string_view get_on_completion() const;
      fixed_point_t get_completion_size() const;
      level_t get_max_level() const;
      Good::good_map_t const& get_goods_cost() const;
      fixed_point_t get_cost() const;
      Timespan get_build_time() const;
      bool has_visibility() const;
      bool is_on_map() const;

      bool is_default_enabled() const;
      ProductionType const* get_production_type() const;
      bool is_pop_built_factory() const;
      bool is_strategic_factory() const;
      bool is_advanced_factory() const;

      level_t get_fort_level() const;

      uint64_t get_naval_capacity() const;
      std::vector<fixed_point_t> const& get_colonial_points() const;
      bool is_in_province() const;
      bool is_one_per_state() const;
      fixed_point_t get_colonial_range() const;

      fixed_point_t get_infrastructure() const;
      bool spawned_railway_track() const;
   };

   struct BuildingType : HasIdentifier {
      friend struct BuildingManager;

   private:
      BuildingType(std::string_view new_identifier);

   public:
      BuildingType(BuildingType&&) = default;
   };

   enum class ExpansionState {
      CannotExpand,
      CanExpand,
      Preparing,
      Expanding
   };

   struct BuildingInstance : HasIdentifier { //used in the actual game
      friend struct BuildingManager;
      using level_t = Building::level_t;

   private:
      Building const& building;

      level_t level = 0;
      ExpansionState expansion_state = ExpansionState::CannotExpand;
      Date start, end;
      float expansion_progress;

      bool _can_expand() const;

      BuildingInstance(Building const& building);

   public:
      BuildingInstance(BuildingInstance&&) = default;

      Building const& get_building() const;

      level_t get_current_level() const;
      ExpansionState get_expansion_state() const;
      Date const& get_start_date() const;
      Date const& get_end_date() const;
      float get_expansion_progress() const;

      bool expand();
      void update_state(Date const& today);
      void tick(Date const& today);

   };

   struct Province;

   struct BuildingManager {
      using level_t = Building::level_t; //this is getting ridiculous

   private:
      IdentifierRegistry<BuildingType> building_types;
      IdentifierRegistry<Building> buildings;

   public:
      BuildingManager();

      bool add_building_type(std::string_view identifier);
      IDENTIFIER_REGISTRY_ACCESSORS(building_type)

      bool add_building(std::string_view identifier, BuildingType const* type, ARGS);
      IDENTIFIER_REGISTRY_ACCESSORS(building)

      bool load_buildings_file(GoodManager const& good_manager, ProductionTypeManager const& production_type_manager, ModifierManager const& modifier_manager, ast::NodeCPtr root);

      bool generate_province_buildings(Province& province) const;
   };
}