Symphony Of Empires
nation.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 // nation.cpp
20 //
21 // Abstract:
22 // Does some important stuff.
23 // ----------------------------------------------------------------------------
24 
25 #include <cassert>
26 
27 #include "eng3d/log.hpp"
28 #include "eng3d/rand.hpp"
29 
30 #include "nation.hpp"
31 #include "indpobj.hpp"
32 #include "province.hpp"
33 #include "indpobj.hpp"
34 #include "world.hpp"
35 
36 //
37 // Nation
38 //
39 
43 void Nation::declare_war(Nation& nation, std::vector<TreatyClause::BaseClause*> clauses) {
44  auto& world = World::get_instance();
45  //Eng3D::Log::debug("game", ref_name + " has declared war on " + nation.ref_name);
46 
47  // Recollect offenders
48  // - Those who are allied to us
49  std::vector<NationId> attacker_ids;
50  for(auto& other_nation : world.nations) {
51  if(&other_nation == this || &other_nation == &nation) continue;
52 
53  const auto& relation = world.get_relation(other_nation.get_id(), *this);
54  if(relation.is_allied() || other_nation.is_puppeted_by(*this))
55  attacker_ids.push_back(other_nation);
56  }
57  attacker_ids.push_back(*this);
58 
59  // Recollect defender_ids
60  // - Those who are on a defensive pact with the target
61  // - Those who are allied with the target
62  // - And those who aren't already attacking
63  std::vector<NationId> defender_ids;
64  for(auto& other_nation : world.nations) {
65  if(&other_nation == this || &other_nation == &nation) continue;
66 
67  auto it = std::find(attacker_ids.begin(), attacker_ids.end(), other_nation);
68  if(it != attacker_ids.end()) continue;
69 
70  const auto& relation = world.get_relation(other_nation.get_id(), nation);
71  if(relation.is_allied() || other_nation.is_puppeted_by(nation))
72  defender_ids.push_back(other_nation);
73  }
74  defender_ids.push_back(nation);
75 
76  // Attackers are at war with the defender_ids
77  for(auto attacker_id : attacker_ids) {
78  for(auto defender_id : defender_ids) {
79  assert(attacker_id != defender_id);
80 
81  auto& attacker = world.nations[attacker_id];
82  auto& defender = world.nations[defender_id];
83  if(attacker.puppet_master_id == defender_id)
84  attacker.is_puppeted = false;
85  else if(defender.puppet_master_id == attacker_id)
86  defender.is_puppeted = false;
87 
88  // Declare war
89  auto& relation = world.get_relation(defender_id, attacker_id);
90  relation.has_war = true;
91  relation.alliance = 0.f;
92  relation.relation = -1.f;
93  }
94  }
95 
96  Eng3D::Log::debug("game", "Attackers");
97  for(const auto& attacker_id : attacker_ids) {
98  auto& attacker = world.nations[attacker_id];
99  Eng3D::Log::debug("game", attacker.ref_name.get_string());
100  }
101  Eng3D::Log::debug("game", "Defenders");
102  for(const auto& defender_id : defender_ids) {
103  auto& defender = world.nations[defender_id];
104  Eng3D::Log::debug("game", defender.ref_name.get_string());
105  }
106 }
107 
108 bool Nation::is_ally(const Nation& nation) const {
109  const auto& relation = World::get_instance().get_relation(*this, nation);
110  if(relation.has_war) return false;
111  return relation.alliance > 0.f;
112 }
113 
114 bool Nation::is_enemy(const Nation& nation) const {
115  return World::get_instance().get_relation(*this, nation).has_war;
116 }
117 
121  const auto& world = World::get_instance();
122  auto best_candidate = std::max_element(owned_provinces.cbegin(), owned_provinces.cend(), [&world](const auto& lhs, const auto& rhs) {
123  return world.provinces[lhs].total_pops() < world.provinces[rhs].total_pops();
124  });
125  capital_id = *best_candidate;
126 }
127 
130 void Nation::set_policy(const Policies& policies) {
131  // Set new policy
132  this->current_policy = policies;
133 }
134 
136 bool Nation::is_accepted_language(const Language& language) const {
137  return language_acceptance[language] >= 0.5f;
138 }
139 
141 bool Nation::is_accepted_religion(const Religion& religion) const {
142  return religion_discrim[religion] >= 0.5f;
143 }
144 
147 float Nation::get_tax(const Pop&) const {
148  return this->current_policy.pop_tax;
149 }
150 
151 #include "client/game_state.hpp"
152 #include "client/map.hpp"
153 #include "client/map_render.hpp"
154 
157  auto& world = World::get_instance();
158  if(province.owner_id == this->get_id()) return;
159 
160  auto& provinces = world.nations[province.owner_id].owned_provinces;
161  std::erase(provinces, province);
162 
163  this->owned_provinces.push_back(province);
164  province.owner_id = this->get_id();
165  this->control_province(province);
166  // Update the province changed
167  world.province_manager.mark_province_owner_changed(province);
168 }
169 
171  auto& world = World::get_instance();
172  if(province.controller_id == this->get_id()) return;
173 
174  auto& provinces = world.nations[province.controller_id].controlled_provinces;
175  std::erase(provinces, province);
176 
177  this->controlled_provinces.push_back(province);
178  province.controller_id = this->get_id();
179 
180  // Update the province changed
181  world.province_manager.mark_province_control_changed(province);
182 
183  if (province.owner_id != this->get_id()) {
184  // Cancel the unit construction projects
185  province.cancel_construction_project();
186  if(province.controller_id != province.owner_id)
187  for(auto& pop : province.pops)
188  pop.militancy += 0.1f;
189 
190  // All factories lose their money and scale down to 0
191  for(auto& building : province.buildings) {
192  building.budget = 0.f;
193  building.production_scale = 0.f;
194  }
195 
196  // And all pops lose their money too
197  for(auto& pop : province.pops)
198  pop.budget = 0.f;
199  }
200 }
201 
203  return this->client_hints[this->ideology_id];
204 }
205 
207  float new_research = 0.f;
208  for(const auto province_id : this->owned_provinces) {
209  const auto& province = World::get_instance().provinces[province_id];
210  for(const auto& pop : province.pops)
211  new_research += pop.size * pop.literacy;
212  if(new_research && !province.is_populated())
213  new_research /= province.pops.size();
214  }
215  return new_research / 100.f;
216 }
217 
218 bool Nation::can_research(const Technology& technology) const {
219  // All required technologies for this one must be researched
220  for(const auto& req_tech_id : technology.req_technologies)
221  if(research[req_tech_id] < 1.f)
222  return false;
223  return true;
224 }
225 
226 void Nation::change_research_focus(const Technology& technology) {
227  if(!this->research[technology] || !this->can_research(technology))
228  return;
229  this->focus_tech_id = technology;
230 }
231 
232 void Nation::get_allies(std::function<void(const Nation&)> fn) const {
233  const auto& world = World::get_instance();
234  for(const auto& nation : world.nations)
235  if(&nation != this && is_ally(nation))
236  fn(nation);
237 }
238 
240  const auto& world = World::get_instance();
241  return world.ideologies[this->ideology_id].subideologies[this->subideology_id];
242 }
243 
245  const auto& subideology = this->get_subideology();
246  return subideology.economic.capitalism >= 0.f ? true : false;
247 }
TechnologyId focus_tech_id
Definition: nation.hpp:139
Policies current_policy
Definition: nation.hpp:140
std::vector< ProvinceId > controlled_provinces
Definition: nation.hpp:149
float get_tax(const Pop &pop) const
Gets the total tax applied to a POP depending on their "wealth" (not exactly like that,...
Definition: nation.cpp:147
std::vector< Nation::ClientHint > client_hints
Definition: nation.hpp:152
bool is_ally(const Nation &nation) const
Definition: nation.cpp:108
ProvinceId capital_id
Definition: nation.hpp:136
void set_policy(const Policies &policies)
Enacts a policy on a nation.
Definition: nation.cpp:130
void give_province(Province &province)
Gives this nation a specified province (for example on a treaty)
Definition: nation.cpp:156
bool is_accepted_language(const Language &language) const
Checks if a LANGUAGE is part of one of our accepted languages.
Definition: nation.cpp:136
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 > language_acceptance
Definition: nation.hpp:145
std::vector< float > research
Definition: nation.hpp:151
const Ideology::Subideology & get_subideology() const
Definition: nation.cpp:239
void control_province(Province &province)
Definition: nation.cpp:170
float get_research_points() const
Definition: nation.cpp:206
bool is_accepted_religion(const Religion &relgion) const
Checks if a RELIGION is part of one of our accepted relgion.
Definition: nation.cpp:141
void get_allies(std::function< void(const Nation &)> fn) const
Definition: nation.cpp:232
bool can_research(const Technology &tech) const
Definition: nation.cpp:218
std::vector< ProvinceId > owned_provinces
Definition: nation.hpp:148
void change_research_focus(const Technology &tech)
Definition: nation.cpp:226
bool is_enemy(const Nation &nation) const
Definition: nation.cpp:114
void declare_war(Nation &nation, std::vector< TreatyClause::BaseClause * > clauses=std::vector< TreatyClause::BaseClause * >())
Declare war.
Definition: nation.cpp:43
std::vector< float > religion_discrim
Definition: nation.hpp:146
void auto_relocate_capital()
Automatically relocates the capital of a nation to another province Use this when a treaty makes a na...
Definition: nation.cpp:120
const Nation::ClientHint & get_client_hint() const
Definition: nation.cpp:202
Definition: indpobj.hpp:264
A single province, which is used to simulate economy in a "bulk-tiles" way instead of doing economica...
Definition: province.hpp:48
std::array< Pop, 7 > pops
Definition: province.hpp:107
void cancel_construction_project()
Definition: province.cpp:54
NationId controller_id
Definition: province.hpp:104
NationId owner_id
Definition: province.hpp:103
std::vector< Building > buildings
Definition: province.hpp:110
Nation::Relation & get_relation(NationId a, NationId b)
Definition: world.hpp:192
static World & get_instance()
Definition: world.hpp:121
void debug(const std::string_view category, const std::string_view msg)
Definition: log.cpp:58
constexpr Id get_id() const
Definition: entity.hpp:152
Hints for the client on how to display the nation.
Definition: nation.hpp:82
float alliance
Definition: nation.hpp:77
float pop_tax
Definition: indpobj.hpp:40
std::vector< TechnologyId > req_technologies
Definition: indpobj.hpp:310