Symphony Of Empires
building.hpp
Go to the documentation of this file.
1 // Symphony of Empires
2 // Copyright (C) 2021, Symphony of Empires contributors
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <https://www.gnu.org/licenses/>.
16 //
17 // ----------------------------------------------------------------------------
18 // Name:
19 // building.hpp
20 //
21 // Abstract:
22 // Does some important stuff.
23 // ----------------------------------------------------------------------------
24 
25 #pragma once
26 
27 #include <vector>
28 #include <bitset>
29 #include <unordered_set>
30 #include "objects.hpp"
31 #include "product.hpp"
32 
33 struct Technology;
34 class Unit;
35 struct UnitType;
36 
38 struct BuildingType : RefnameEntity<BuildingTypeId> {
39  bool can_plot_on_sea() const { return flags[0]; }
40  bool can_plot_on_land() const { return flags[1]; }
41  bool can_build_land_units() const { return flags[2]; }
42  bool can_build_naval_units() const { return flags[3]; }
43  bool can_build_air_units() const { return flags[4]; }
44 
46  bool can_build_military() const {
48  }
49 
50  void can_plot_on_sea(bool b) { flags[0] = b; }
51  void can_plot_on_land(bool b) { flags[1] = b; }
52  void can_build_land_units(bool b) { flags[2] = b; }
53  void can_build_naval_units(bool b) { flags[3] = b; }
54  void can_build_air_units(bool b) { flags[4] = b; }
55 
57  std::bitset<4> flags;
58  // We used to calculate these per each economical tick but now we can just store them
59  // and multiply it by the level of the industry - this is the **minimum** amount of employed
60  // people we should have at a time
61  float num_req_workers = 0.f;
62  CommodityId output_id; // Commodity that this building creates
63  std::vector<CommodityId> input_ids; // Goods required to create output
64  // Required commodities, first describes the id of the commodity and the second describes how many
65  std::vector<std::pair<CommodityId, float>> req_goods;
66  std::vector<TechnologyId> req_technologies; // Required technologies to build
67 };
68 template<>
70  template<bool is_const>
72 
73  template<bool is_serialize>
74  static inline void deser_dynamic(Eng3D::Deser::Archive& ar, type<is_serialize>& obj) {
75  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.cached_id);
76  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.ref_name);
77  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.name);
78  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.flags);
79  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.input_ids);
80  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.output_id);
81  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.req_goods);
82  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.req_technologies);
83  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.num_req_workers);
84  }
85 };
86 
87 class Province;
90 struct Building : Entity<BuildingId> {
91  bool can_do_output(const Province& province, const std::vector<CommodityId>& inputs) const;
92 
93  bool can_build_unit() const {
94  for(const auto& [k, v] : req_goods_for_unit)
95  if(v) return false;
96  return this->level > 0.f;
97  }
98 
99  float get_upgrade_cost() const {
100  constexpr auto base_cost = 1000.f;
101  return this->level * base_cost;
102  }
103 
104  float get_profit() const {
105  return this->revenue.get_total() - this->expenses.get_total();
106  }
107 
108  float get_operating_ratio() const {
109  const auto total_revenue = this->revenue.get_total();
110  if(total_revenue == 0.f) return 0.f;
111  const auto total_expenses = this->expenses.get_total();
112  if(total_expenses == 0.f) return 0.f;
113  return total_revenue / total_expenses;
114  }
115 
116  static constexpr auto industry_production_rate = 1.f;
117  float get_output_amount() const {
118  return this->production_scale * this->workers * industry_production_rate;
119  }
120 
121  float get_max_output_amount(float max_workers) const {
122  return this->level * max_workers * industry_production_rate;
123  }
124 
125  bool is_working_on_unit() const {
126  return this->_is_wrking_on_unit;
127  }
128 
129  void work_on_unit(const UnitType& unit_type);
130 
132  this->_is_wrking_on_unit = false;
133  }
134 
135  struct Investment {
136  float total = 0.f;
137 
138  void invest(float amount) {
139  total += amount;
140  }
141 
142  float get_ownership(float total_investments) const {
143  return total_investments / total;
144  }
145 
146  float get_dividends(float profit, float ownership) const {
147  assert(ownership >= 0.f && ownership <= 1.f);
148  return profit * ownership;
149  }
150  };
155  std::vector<Investment> estate_foreign;
156  float get_total_investment() const {
157  auto sum = estate_private.total;
158  sum += estate_state.total;
159  sum += estate_collective.total;
160  sum += estate_individual.total;
161  for(const auto& foreign : estate_foreign)
162  sum += foreign.total;
163  return sum;
164  }
165 
166  float budget = 1000.f; // Total money that the industry has
167  float level = 0.f; // Level/Capacity scale of the building
168  float workers = 1.f; // Amount of workers
169  float production_scale = 1.f; // How much of the industry is being used. From 0-1
170  bool _is_wrking_on_unit = false;
171  UnitTypeId working_unit_type_id; // Unit that is currently being built here (nullptr indicates no unit)
172  // Required commodities for building the working unit
173  // change this to a struct instead of a pair for readablity
174  std::vector<std::pair<CommodityId, float>> req_goods_for_unit;
175  // Required commodities for construction or for repairs
176  std::vector<std::pair<CommodityId, float>> req_goods;
177 
178  // Bookkeeping
179  struct {
180  float outputs = 0.f;
181  float get_total() const {
182  return outputs;
183  }
185  struct {
186  float wages = 0.f;
187  float inputs_cost = 0.f;
188  float state_taxes = 0.f;
189  float state_dividends = 0.f;
190  float pop_dividends = 0.f;
191  float private_dividends = 0.f;
192 
193  float get_dividends() const {
195  }
196 
197  float get_total() const {
198  return wages + inputs_cost + state_taxes + get_dividends();
199  }
201 };
202 template<>
203 struct Eng3D::Deser::Serializer<Building::Investment> {
204  template<bool is_const>
206 
207  template<bool is_serialize>
209  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.total);
210  }
211 };
212 
213 template<>
215  template<bool is_const>
217 
218  template<bool is_serialize>
220  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.estate_private);
221  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.estate_state);
222  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.estate_collective);
223  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.estate_individual);
224  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.estate_foreign);
225  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.budget);
226  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.level);
227  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.production_scale);
228  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.workers);
229  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.req_goods);
230  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.req_goods_for_unit);
231  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj._is_wrking_on_unit);
232  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.revenue.outputs);
233  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.expenses.wages);
234  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.expenses.inputs_cost);
235  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.expenses.state_taxes);
236  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.expenses.state_dividends);
237  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.expenses.pop_dividends);
238  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.expenses.private_dividends);
239  }
240 };
A single province, which is used to simulate economy in a "bulk-tiles" way instead of doing economica...
Definition: province.hpp:48
Roughly a batallion, consisting of approximately 500 soldiers each.
Definition: unit.hpp:80
void invest(float amount)
Definition: building.hpp:138
float get_ownership(float total_investments) const
Definition: building.hpp:142
float get_dividends(float profit, float ownership) const
Definition: building.hpp:146
A military outpost, on land serves as a "spawn" place for units When adjacent to a water tile this se...
Definition: building.hpp:90
bool is_working_on_unit() const
Definition: building.hpp:125
std::vector< Investment > estate_foreign
Definition: building.hpp:155
struct Building::@1 expenses
float get_profit() const
Definition: building.hpp:104
float production_scale
Definition: building.hpp:169
static constexpr auto industry_production_rate
Definition: building.hpp:116
float get_operating_ratio() const
Definition: building.hpp:108
float private_dividends
Definition: building.hpp:191
Investment estate_state
Definition: building.hpp:152
float inputs_cost
Definition: building.hpp:187
float level
Definition: building.hpp:167
Investment estate_private
Definition: building.hpp:151
float outputs
Definition: building.hpp:180
float get_upgrade_cost() const
Definition: building.hpp:99
float get_output_amount() const
Definition: building.hpp:117
bool _is_wrking_on_unit
Definition: building.hpp:170
float workers
Definition: building.hpp:168
bool can_build_unit() const
Definition: building.hpp:93
std::vector< std::pair< CommodityId, float > > req_goods_for_unit
Definition: building.hpp:174
float pop_dividends
Definition: building.hpp:190
Investment estate_individual
Definition: building.hpp:154
struct Building::@0 revenue
float get_max_output_amount(float max_workers) const
Definition: building.hpp:121
std::vector< std::pair< CommodityId, float > > req_goods
Definition: building.hpp:176
float budget
Definition: building.hpp:166
float state_taxes
Definition: building.hpp:188
void stop_working_on_unit()
Definition: building.hpp:131
UnitTypeId working_unit_type_id
Definition: building.hpp:171
Investment estate_collective
Definition: building.hpp:153
void work_on_unit(const UnitType &unit_type)
Definition: building.cpp:43
float state_dividends
Definition: building.hpp:189
bool can_do_output(const Province &province, const std::vector< CommodityId > &inputs) const
Checks if the building can produce output (if it has enough input)
Definition: building.cpp:33
float get_total_investment() const
Definition: building.hpp:156
float wages
Definition: building.hpp:186
Type for military outposts.
Definition: building.hpp:38
void can_plot_on_land(bool b)
Definition: building.hpp:51
Eng3D::StringRef name
Definition: building.hpp:56
std::vector< std::pair< CommodityId, float > > req_goods
Definition: building.hpp:65
bool can_build_naval_units() const
Definition: building.hpp:42
void can_plot_on_sea(bool b)
Definition: building.hpp:50
void can_build_air_units(bool b)
Definition: building.hpp:54
float num_req_workers
Definition: building.hpp:61
bool can_build_land_units() const
Definition: building.hpp:41
bool can_build_military() const
Can this building type build a military unit.
Definition: building.hpp:46
std::vector< CommodityId > input_ids
Definition: building.hpp:63
bool can_plot_on_land() const
Definition: building.hpp:40
void can_build_land_units(bool b)
Definition: building.hpp:52
std::vector< TechnologyId > req_technologies
Definition: building.hpp:66
bool can_build_air_units() const
Definition: building.hpp:43
bool can_plot_on_sea() const
Definition: building.hpp:39
CommodityId output_id
Definition: building.hpp:62
void can_build_naval_units(bool b)
Definition: building.hpp:53
std::bitset< 4 > flags
Definition: building.hpp:57
Base class that serves as archiver, stores (in memory) the data required for serialization/deserializ...
Definition: serializer.hpp:64
static void deser_dynamic(Eng3D::Deser::Archive &ar, type< is_serialize > &obj)
Definition: building.hpp:219
typename Eng3D::Deser::CondConstType< is_const, Building >::type type
Definition: building.hpp:216
static void deser_dynamic(Eng3D::Deser::Archive &ar, type< is_serialize > &obj)
Definition: building.hpp:208
typename Eng3D::Deser::CondConstType< is_const, Building::Investment >::type type
Definition: building.hpp:205
static void deser_dynamic(Eng3D::Deser::Archive &ar, type< is_serialize > &obj)
Definition: building.hpp:74
typename Eng3D::Deser::CondConstType< is_const, BuildingType >::type type
Definition: building.hpp:71
A serializer (base class) which can be used to serialize objects and create per-object optimized clas...
Definition: serializer.hpp:111
A reference to a string on the global string pool.
Definition: string.hpp:39
An entity which can only be referenced by an (presumably) unique Id this is the base class for the ot...
Definition: entity.hpp:94
An entity which can be referenced via a ref_name and also via id.
Definition: entity.hpp:160
Defines a type of unit, it can be a tank, garrison, infantry, etc this is moddable via a lua script a...
Definition: unit.hpp:44