Symphony Of Empires
policies.cpp
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 // client/interface/policies.cpp
20 //
21 // Abstract:
22 // Does some important stuff.
23 // ----------------------------------------------------------------------------
24 
25 #include "eng3d/serializer.hpp"
26 #include "eng3d/ui/components.hpp"
27 #include "eng3d/ui/table.hpp"
28 #include "eng3d/texture.hpp"
31 #include "action.hpp"
32 
33 using namespace Interface;
34 
36  : UI::Window(0, 0, 512, 400, nullptr),
37  gs{ _gs }
38 {
39  this->padding.x = 0;
40  this->padding.y = 48;
41 
42  this->current_texture = this->gs.tex_man.load(this->gs.package_man.get_unique("gfx/policies_screen.png"));
43  this->width = this->current_texture->width;
44  this->height = this->current_texture->height;
45  this->set_text("Laws and goverment");
46  this->is_scroll = false;
47  this->new_policy = gs.curr_nation->current_policy;
48  this->set_close_btn_function([this](Widget&) {
49  this->kill();
50  });
51 
53  auto& ideology_lab = this->make_widget<UI::Label>(0, 0, "");
54  ideology_lab.set_on_each_tick([this](UI::Widget& w) {
55  const auto& ideology = this->gs.world->ideologies[this->gs.curr_nation->ideology_id];
56  const auto& subideology = ideology.subideologies[this->gs.curr_nation->subideology_id];
57  w.set_text(translate_format("%s (%s)", subideology.name.c_str(), ideology.name.c_str()));
59  "Distributism %.2f\nMercantilist %.2f\nCapitalism %.2f\nIndividualism %.2f\nState power %.2f\nEqualitarianism %.2f\nSecular %.2f\nPluralism %.2f\n", subideology.economic.distributism, subideology.economic.mercantilist, subideology.economic.capitalism, subideology.political.individualism, subideology.political.state_power, subideology.political.equalitarianism, subideology.political.secular, subideology.political.pluralism));
60  });
61  ideology_lab.on_each_tick(ideology_lab);
62 
63  auto& ideology_img = this->make_widget<UI::Image>(6, 38, 32, 32);
64  ideology_img.set_on_each_tick([this](UI::Widget& w) {
65  const auto& ideology = this->gs.world->ideologies[this->gs.curr_nation->ideology_id];
66  w.current_texture = this->gs.tex_man.load(this->gs.package_man.get_unique(ideology.get_icon_path()));
67  });
68  ideology_img.on_each_tick(ideology_img);
69 
70  auto& ideology_pie_lab = this->make_widget<UI::Label>(0, 82, "House");
71  auto& ideology_pie = this->make_widget<UI::PieChart>(0, 0, 128, 128);
72  ideology_pie.below_of(ideology_pie_lab);
73  ideology_pie.set_on_each_tick([this](UI::Widget& w) {
74  if(this->gs.world->time % this->gs.world->ticks_per_month) return;
75 
76  std::vector<UI::ChartData> ideology_data;
77  for(const auto& ideology : this->gs.world->ideologies)
78  ideology_data.emplace_back(1.f, ideology.name, ideology.color);
79 
80  /*
81  for(const auto province_id : this->gs.curr_nation->owned_provinces)
82  for(const auto& pop : this->gs.world->provinces[province_id].pops)
83  for(const auto& ideology : this->gs.world->ideologies)
84  ideology_data[ideology].num += pop.ideology_approval[ideology] * pop.size;
85  */
86  static_cast<UI::PieChart&>(w).set_data(ideology_data);
87  });
88  ideology_pie.on_each_tick(ideology_pie);
89 
90  auto& militancy_lab = this->make_widget<UI::Label>(0, 290, " ");
91  militancy_lab.set_on_each_tick([this](UI::Widget& w) {
92  if(this->gs.world->time % this->gs.world->ticks_per_month) return;
93 
94  auto num = 0.f;
95  for(const auto province_id : this->gs.curr_nation->owned_provinces)
96  for(const auto& pop : this->gs.world->provinces[province_id].pops)
97  num += pop.militancy;
98  num /= this->gs.curr_nation->owned_provinces.size();
99  w.set_text(translate_format("Militancy: %.2f%%", num * 100.f));
100  });
101  militancy_lab.on_each_tick(militancy_lab);
102 
103  //
104  // Taxes
105  //
106  auto& tax_grp = this->make_widget<UI::Group>(207, 38, 196, this->height - (this->padding.y + 38 + 48));
107  tax_grp.flex = UI::Flex::COLUMN;
108  tax_grp.is_scroll = true;
109 
110  tax_grp.make_widget<UI::Label>(0, 0, "Burgeoise income tax");
111  auto& burgeoise_tax_sld = tax_grp.make_widget<UI::Slider>(0, 0, 128, 24, -1.f, 1.f);
112  burgeoise_tax_sld.set_value(this->new_policy.burgeoise_tax);
113  burgeoise_tax_sld.set_on_click([this](UI::Widget& w) {
114  this->new_policy.burgeoise_tax = static_cast<UI::Slider&>(w).get_value();
115  w.set_text(string_format("%.2f%%", this->new_policy.burgeoise_tax * 100.f));
116  });
117  burgeoise_tax_sld.set_tooltip("% of tax taken from the income of the higher class population");
118  burgeoise_tax_sld.on_click(burgeoise_tax_sld);
119 
120  tax_grp.make_widget<UI::Label>(0, 0, "Population income tax");
121  auto& pop_tax_sld = tax_grp.make_widget<UI::Slider>(0, 0, 128, 24, -1.f, 1.f);
122  pop_tax_sld.set_value(this->new_policy.pop_tax);
123  pop_tax_sld.set_on_click([this](UI::Widget& w) {
124  this->new_policy.pop_tax = static_cast<UI::Slider&>(w).get_value();
125  w.set_text(string_format("%.2f%%", this->new_policy.pop_tax * 100.f));
126  });
127  pop_tax_sld.set_tooltip("% of tax taken from the income of the lower and middle class population");
128  pop_tax_sld.on_click(pop_tax_sld);
129 
130  tax_grp.make_widget<UI::Label>(0, 0, "Minimum wage");
131  auto& min_wage_sld = tax_grp.make_widget<UI::Slider>(0, 0, 128, 24, -1.f, 100.f);
132  min_wage_sld.set_value(this->new_policy.min_wage);
133  min_wage_sld.set_on_click([this](UI::Widget& w) {
134  this->new_policy.min_wage = static_cast<UI::Slider&>(w).get_value();
135  w.set_text(string_format("%.2f", this->new_policy.min_wage));
136  });
137  min_wage_sld.set_tooltip("Minimum wage (fixed) that factories are required to pay to workers");
138  min_wage_sld.on_click(min_wage_sld);
139  // TODO: Allow minimum wage to be a relative amount to the required price for buying
140  // and satisfying all life needs
141 
142  tax_grp.make_widget<UI::Label>(0, 0, "Industry profit tax");
143  auto& industry_profit_tax_sld = tax_grp.make_widget<UI::Slider>(0, 0, 128, 24, -1.f, 1.f);
144  industry_profit_tax_sld.set_value(this->new_policy.industry_profit_tax);
145  industry_profit_tax_sld.set_on_click([this](UI::Widget& w) {
146  this->new_policy.industry_profit_tax = static_cast<UI::Slider&>(w).get_value();
147  w.set_text(string_format("%.2f%%", this->new_policy.industry_profit_tax * 100.f));
148  });
149  industry_profit_tax_sld.set_tooltip("% of profits taken by the goverment from the industry's profits");
150  industry_profit_tax_sld.on_click(industry_profit_tax_sld);
151 
152  //
153  // Investments
154  //
155  auto& investment_grp = this->make_widget<UI::Group>(207 + 196, 38, 196, this->height - (this->padding.y + 38 + 48));
156  investment_grp.flex = UI::Flex::COLUMN;
157  investment_grp.is_scroll = true;
158 
159  investment_grp.make_widget<UI::Label>(0, 0, "Industry subsidies");
160  auto& industry_subsidies_budget_tax_sld = investment_grp.make_widget<UI::Slider>(0, 0, 128, 24, -1.f, 1.f);
161  industry_subsidies_budget_tax_sld.set_value(this->new_policy.industry_subsidies_budget);
162  industry_subsidies_budget_tax_sld.set_on_click([this](UI::Widget& w) {
163  this->new_policy.industry_subsidies_budget = static_cast<UI::Slider&>(w).get_value();
164  w.set_text(string_format("%.2f%%", this->new_policy.industry_subsidies_budget * 100.f));
165  });
166  industry_subsidies_budget_tax_sld.set_tooltip("% of the national budget dedicated to subsidizing factories");
167  industry_subsidies_budget_tax_sld.on_click(industry_subsidies_budget_tax_sld);
168 
169  investment_grp.make_widget<UI::Label>(0, 0, "Education budget");
170  auto& education_budget_tax_sld = investment_grp.make_widget<UI::Slider>(0, 0, 128, 24, -1.f, 1.f);
171  education_budget_tax_sld.set_value(this->new_policy.education_budget);
172  education_budget_tax_sld.set_on_click([this](UI::Widget& w) {
173  this->new_policy.education_budget = static_cast<UI::Slider&>(w).get_value();
174  w.set_text(string_format("%.2f%%", this->new_policy.education_budget * 100.f));
175  });
176  education_budget_tax_sld.set_tooltip("% of the national budget dedicated to education");
177  education_budget_tax_sld.on_click(education_budget_tax_sld);
178 
179  investment_grp.make_widget<UI::Label>(0, 0, "Private ownership");
180  auto& private_ownership_sld = investment_grp.make_widget<UI::Slider>(0, 0, 128, 24, -1.f, 1.f);
181  private_ownership_sld.set_value(this->new_policy.private_ownership);
182  private_ownership_sld.set_on_click([this](UI::Widget& w) {
183  this->new_policy.private_ownership = static_cast<UI::Slider&>(w).get_value();
184  w.set_text(string_format("%.2f%%", this->new_policy.private_ownership * 100.f));
185  });
186  private_ownership_sld.set_tooltip("Maximum allowed private ownership stake % for factories\nAllows private ownership of factories, where the burgeoise would profit from it instead of the industry itself");
187  private_ownership_sld.on_click(private_ownership_sld);
188 
189  investment_grp.make_widget<UI::Label>(0, 0, "Foreign ownership");
190  auto& foreign_ownership_sld = investment_grp.make_widget<UI::Slider>(0, 0, 128, 24, -1.f, 1.f);
191  foreign_ownership_sld.set_value(this->new_policy.foreign_ownership);
192  foreign_ownership_sld.set_on_click([this](UI::Widget& w) {
193  this->new_policy.foreign_ownership = static_cast<UI::Slider&>(w).get_value();
194  w.set_text(string_format("%.2f%%", this->new_policy.foreign_ownership * 100.f));
195  });
196  foreign_ownership_sld.set_tooltip("Maximum allowed foreign ownership stake % for factories\nAllows foreign investment for the construction of factories");
197  foreign_ownership_sld.on_click(foreign_ownership_sld);
198 
199  investment_grp.make_widget<UI::Label>(0, 0, "Collective ownership");
200  auto& collective_ownership_sld = investment_grp.make_widget<UI::Slider>(0, 0, 128, 24, -1.f, 1.f);
201  collective_ownership_sld.set_value(this->new_policy.collective_ownership);
202  collective_ownership_sld.set_on_click([this](UI::Widget& w) {
203  this->new_policy.collective_ownership = static_cast<UI::Slider&>(w).get_value();
204  w.set_text(string_format("%.2f%%", this->new_policy.collective_ownership * 100.f));
205  });
206  collective_ownership_sld.set_tooltip("Maximum allowed collective ownership stake % for factories\nA collective represents the workers that work on the industry itself; allowing laborers to profit from the industry");
207  collective_ownership_sld.on_click(collective_ownership_sld);
208 
209  investment_grp.make_widget<UI::Label>(0, 0, "Individual ownership");
210  auto& individual_ownership_sld = investment_grp.make_widget<UI::Slider>(0, 0, 128, 24, -1.f, 1.f);
211  individual_ownership_sld.set_value(this->new_policy.individual_ownership);
212  individual_ownership_sld.set_on_click([this](UI::Widget& w) {
213  this->new_policy.individual_ownership = static_cast<UI::Slider&>(w).get_value();
214  w.set_text(string_format("%.2f%%", this->new_policy.individual_ownership * 100.f));
215  });
216  individual_ownership_sld.set_tooltip("Maximum allowed individual ownership stake % for factories\nIndividual ownership pertains to stakes of a industry owned by POPs, and allowing them to profit from factories with an incurred efficiency penalty");
217  individual_ownership_sld.on_click(individual_ownership_sld);
218 
219  //
220  // State economy
221  //
222  auto& state_economy_grp = this->make_widget<UI::Group>(207 + 196 + 196, 38, 196, this->height - (this->padding.y + 38 + 48));
223  state_economy_grp.flex = UI::Flex::COLUMN;
224  state_economy_grp.is_scroll = true;
225 
226  std::vector<int> sizes{ 120, 128 };
227  std::vector<std::string> header{ "Commodity", "Scale" };
228  auto& commodity_table = state_economy_grp.make_widget<UI::Table<uint32_t>>(0, 0, state_economy_grp.height, 32, sizes, header);
229  commodity_table.reserve(1);
230  this->commodity_production = this->gs.curr_nation->commodity_production;
231  for(const auto& commodity : this->gs.world->commodities) {
232  auto& row = commodity_table.get_row(commodity.get_id());
233  auto* commodity_row = row.get_element(0);
234  commodity_row->set_key(commodity.name.c_str());
235  auto& commodity_img = commodity_row->make_widget<UI::Image>(0, 0, 35, 35, commodity.get_icon_path(), true);
236  commodity_img.set_tooltip(commodity.name);
237 
238  auto* scale = row.get_element(1);
239  scale->set_key(commodity.name.c_str());
240  auto& scale_sld = scale->make_widget<UI::Slider>(0, 0, 128, 24, 0.f, 1.f);
241  scale_sld.set_value(this->commodity_production[commodity]);
242  scale_sld.set_on_click([this, &commodity](UI::Widget& w) {
243  this->commodity_production[commodity] = static_cast<UI::Slider&>(w).get_value();
244  w.set_text(string_format("%.2f%%", this->commodity_production[commodity] * 100.f));
246  w.set_tooltip("Scale the production of this product (only applies to factories with a state stake on them)");
247  } else {
248  w.set_tooltip("Scale the production of this product (applies to all factories regardless of stake)");
249  }
250  });
251  scale_sld.on_click(scale_sld);
252  }
253 
254  auto& enact_btn = this->make_widget<UI::Button>(207, 0, 128, 24);
255  enact_btn.below_of(tax_grp);
256  enact_btn.set_text("Enact policy");
257  enact_btn.set_on_click([this](UI::Widget&) {
258  Eng3D::Networking::Packet packet{};
260  Eng3D::Deser::serialize<ActionType>(ar, ActionType::NATION_ENACT_POLICY);
261  Eng3D::Deser::serialize(ar, this->new_policy); // PoliciesObj
262  Eng3D::Deser::serialize(ar, this->commodity_production); // VectorFloatObj
263  packet.data(ar.get_buffer(), ar.size());
264  if(this->gs.client)
265  this->gs.client->send(packet);
266  else {
267  this->gs.curr_nation->set_policy(this->new_policy);
268  this->gs.curr_nation->commodity_production = this->commodity_production;
269  }
270  this->gs.ui_ctx.prompt("Policy", "New policy enacted!");
271  });
272 }
@ NATION_ENACT_POLICY
Definition: action.hpp:44
std::shared_ptr< Eng3D::IO::Asset::Base > get_unique(const Eng3D::IO::Path &path)
Obtaining an unique asset means the "first-found" policy applies.
Definition: io.cpp:146
UI::Context ui_ctx
Definition: state.hpp:128
Eng3D::TextureManager tex_man
Definition: state.hpp:124
Eng3D::IO::PackageManager package_man
Definition: state.hpp:122
std::shared_ptr< Eng3D::Texture > load(const std::string &path, TextureOptions options=default_options)
Finds a texture in the list of a texture manager if the texture is already in the list we load the sa...
Definition: texture.cpp:432
std::unique_ptr< Client > client
Definition: game_state.hpp:143
Nation * curr_nation
Definition: game_state.hpp:158
World * world
Definition: game_state.hpp:156
PoliciesView(GameState &gs)
Definition: policies.cpp:35
Policies current_policy
Definition: nation.hpp:140
void set_policy(const Policies &policies)
Enacts a policy on a nation.
Definition: nation.cpp:130
SubideologyId subideology_id
Definition: nation.hpp:138
IdeologyId ideology_id
Definition: nation.hpp:137
bool can_directly_control_factories() const
Definition: nation.cpp:244
std::vector< float > commodity_production
Definition: nation.hpp:141
void prompt(const std::string &title, const std::string &text)
Definition: ui.cpp:183
Image widget, can display pictures or effects on the screen.
Definition: image.hpp:43
Simple widget for drawing text on the screen, no multiline support.
Definition: label.hpp:40
Piechart widget.
Definition: piechart.hpp:43
void set_data(std::vector< ChartData > data)
Definition: piechart.cpp:52
void set_value(const float _value)
Slider widget.
Definition: slider.hpp:38
A dynamic/smart table that can sort elements by ascending/descending order.
Definition: table.hpp:87
void reserve(size_t _size)
Definition: table.hpp:119
The master widget all the other widgets inherit from, do not use directly instead use one of the many...
Definition: widget.hpp:176
std::function< void(UI::Widget &)> on_click
Definition: widget.hpp:350
T & make_widget(Targs &&...args)
Definition: widget.hpp:222
virtual void set_on_click(std::function< void(UI::Widget &)> _on_click)
Sets the on_click function of this widget.
Definition: widget.hpp:259
virtual void set_tooltip(UI::Tooltip *tooltip)
Set the tooltip to be shown when this widget is hovered, overrides the previous tooltip.
Definition: widget.cpp:458
bool is_scroll
Definition: widget.hpp:306
size_t width
Definition: widget.hpp:325
std::shared_ptr< Eng3D::Texture > current_texture
Definition: widget.hpp:327
void kill()
Kills the current widget, setting it up for deletion when dead widgets are cleared by the UI context.
Definition: widget.hpp:283
glm::ivec2 padding
Definition: widget.hpp:323
Widget()=default
virtual void set_text(const std::string &text)
Generates text for the widget and overrides the current text texture.
Definition: widget.cpp:445
size_t height
Definition: widget.hpp:325
void set_close_btn_function(std::function< void(Widget &)> on_click)
Definition: window.cpp:65
int time
Definition: world.hpp:221
void serialize(Eng3D::Deser::Archive &ar, const T &obj)
Definition: serializer.hpp:144
std::string string_format(const std::string_view format, Args &&... args)
String formatter.
Definition: string.hpp:100
std::string translate_format(const std::string_view format, Args &&... args)
String formatter, with translation.
Definition: string.hpp:128
Base class that serves as archiver, stores (in memory) the data required for serialization/deserializ...
Definition: serializer.hpp:64
float collective_ownership
Definition: indpobj.hpp:44
float pop_tax
Definition: indpobj.hpp:40
float industry_profit_tax
Definition: indpobj.hpp:38
float burgeoise_tax
Definition: indpobj.hpp:39
float min_wage
Definition: indpobj.hpp:36
float foreign_ownership
Definition: indpobj.hpp:43
float individual_ownership
Definition: indpobj.hpp:45
float industry_subsidies_budget
Definition: indpobj.hpp:48
float private_ownership
Definition: indpobj.hpp:42
float education_budget
Definition: indpobj.hpp:47