1 // _________ __ __
2 // / _____// |_____________ _/ |______ ____ __ __ ______
3 // \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
4 // / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
5 // /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
6 // \/ \/ \//_____/ \/
7 // ______________________ ______________________
8 // T H E W A R B E G I N S
9 // Stratagus - A free fantasy real time strategy game engine
10 //
11 /**@name civilization.cpp - The civilization source file. */
12 //
13 // (c) Copyright 2018-2019 by Andrettin
14 //
15 // This program is free software; you can redistribute it and/or modify
16 // it under the terms of the GNU General Public License as published by
17 // the Free Software Foundation; only version 2 of the License.
18 //
19 // This program is distributed in the hope that it will be useful,
20 // but WITHOUT ANY WARRANTY; without even the implied warranty of
21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 // GNU General Public License for more details.
23 //
24 // You should have received a copy of the GNU General Public License
25 // along with this program; if not, write to the Free Software
26 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 // 02111-1307, USA.
28 //
29
30 //@{
31
32 /*----------------------------------------------------------------------------
33 -- Includes
34 ----------------------------------------------------------------------------*/
35
36 #include "stratagus.h"
37
38 #include "civilization.h"
39
40 #include "player.h"
41 #include "time/calendar.h"
42
43 /*----------------------------------------------------------------------------
44 -- Variables
45 ----------------------------------------------------------------------------*/
46
47 std::vector<CCivilization *> CCivilization::Civilizations;
48 std::map<std::string, CCivilization *> CCivilization::CivilizationsByIdent;
49
50 /*----------------------------------------------------------------------------
51 -- Functions
52 ----------------------------------------------------------------------------*/
53
54 /**
55 ** @brief Get a civilization
56 **
57 ** @param ident The civilization's string identifier
58 ** @param should_find Whether it is an error if the civilization could not be found; this is true by default
59 **
60 ** @return The civilization if found, or null otherwise
61 */
GetCivilization(const std::string & ident,const bool should_find)62 CCivilization *CCivilization::GetCivilization(const std::string &ident, const bool should_find)
63 {
64 if (CivilizationsByIdent.find(ident) != CivilizationsByIdent.end()) {
65 return CivilizationsByIdent.find(ident)->second;
66 }
67
68 if (should_find) {
69 fprintf(stderr, "Invalid civilization: \"%s\".\n", ident.c_str());
70 }
71
72 return nullptr;
73 }
74
75 /**
76 ** @brief Get or add a civilization
77 **
78 ** @param ident The civilization's string identifier
79 **
80 ** @return The civilization if found, or a newly-created one otherwise
81 */
GetOrAddCivilization(const std::string & ident)82 CCivilization *CCivilization::GetOrAddCivilization(const std::string &ident)
83 {
84 CCivilization *civilization = GetCivilization(ident, false);
85
86 if (!civilization) {
87 civilization = new CCivilization;
88 civilization->Ident = ident;
89 civilization->ID = Civilizations.size();
90 Civilizations.push_back(civilization);
91 CivilizationsByIdent[ident] = civilization;
92
93 PlayerRaces.Name[civilization->ID] = ident;
94 PlayerRaces.Playable[civilization->ID] = true; //civilizations are playable by default
95 }
96
97 return civilization;
98 }
99
100 /**
101 ** @brief Remove the existing civilizations
102 */
ClearCivilizations()103 void CCivilization::ClearCivilizations()
104 {
105 for (size_t i = 0; i < Civilizations.size(); ++i) {
106 delete Civilizations[i];
107 }
108 Civilizations.clear();
109 }
110
111 /**
112 ** @brief Destructor
113 */
~CCivilization()114 CCivilization::~CCivilization()
115 {
116 for (std::map<int, std::vector<CForceTemplate *>>::iterator iterator = this->ForceTemplates.begin(); iterator != this->ForceTemplates.end(); ++iterator) {
117 for (size_t i = 0; i < iterator->second.size(); ++i) {
118 delete iterator->second[i];
119 }
120 }
121
122 for (size_t i = 0; i < this->AiBuildingTemplates.size(); ++i) {
123 delete this->AiBuildingTemplates[i];
124 }
125 }
126
GetUpgradePriority(const CUpgrade * upgrade) const127 int CCivilization::GetUpgradePriority(const CUpgrade *upgrade) const
128 {
129 if (!upgrade) {
130 fprintf(stderr, "Error in CCivilization::GetUpgradePriority: the upgrade is null.\n");
131 }
132
133 if (this->UpgradePriorities.find(upgrade) != this->UpgradePriorities.end()) {
134 return this->UpgradePriorities.find(upgrade)->second;
135 }
136
137 return 100;
138 }
139
GetForceTypeWeight(int force_type) const140 int CCivilization::GetForceTypeWeight(int force_type) const
141 {
142 if (force_type == -1) {
143 fprintf(stderr, "Error in CCivilization::GetForceTypeWeight: the force_type is -1.\n");
144 }
145
146 if (this->ForceTypeWeights.find(force_type) != this->ForceTypeWeights.end()) {
147 return this->ForceTypeWeights.find(force_type)->second;
148 }
149
150 if (this->ParentCivilization) {
151 return this->ParentCivilization->GetForceTypeWeight(force_type);
152 }
153
154 return 1;
155 }
156
157 /**
158 ** @brief Get the calendar for the civilization
159 **
160 ** @return The civilization's calendar
161 */
GetCalendar() const162 CCalendar *CCivilization::GetCalendar() const
163 {
164 if (this->Calendar) {
165 return this->Calendar;
166 }
167
168 if (this->ParentCivilization) {
169 return this->ParentCivilization->GetCalendar();
170 }
171
172 return CCalendar::BaseCalendar;
173 }
174
175 /**
176 ** @brief Get the civilization's currency
177 **
178 ** @return The civilization's currency
179 */
GetCurrency() const180 CCurrency *CCivilization::GetCurrency() const
181 {
182 if (this->Currency) {
183 return this->Currency;
184 }
185
186 if (this->ParentCivilization) {
187 return this->ParentCivilization->GetCurrency();
188 }
189
190 return nullptr;
191 }
192
GetForceTemplates(int force_type) const193 std::vector<CForceTemplate *> CCivilization::GetForceTemplates(int force_type) const
194 {
195 if (force_type == -1) {
196 fprintf(stderr, "Error in CCivilization::GetForceTemplates: the force_type is -1.\n");
197 }
198
199 if (this->ForceTemplates.find(force_type) != this->ForceTemplates.end()) {
200 return this->ForceTemplates.find(force_type)->second;
201 }
202
203 if (this->ParentCivilization) {
204 return this->ParentCivilization->GetForceTemplates(force_type);
205 }
206
207 return std::vector<CForceTemplate *>();
208 }
209
GetAiBuildingTemplates() const210 std::vector<CAiBuildingTemplate *> CCivilization::GetAiBuildingTemplates() const
211 {
212 if (this->AiBuildingTemplates.size() > 0) {
213 return this->AiBuildingTemplates;
214 }
215
216 if (this->ParentCivilization) {
217 return this->ParentCivilization->GetAiBuildingTemplates();
218 }
219
220 return std::vector<CAiBuildingTemplate *>();
221 }
222
GetPersonalNames()223 std::map<int, std::vector<std::string>> &CCivilization::GetPersonalNames()
224 {
225 if (this->PersonalNames.size() > 0) {
226 return this->PersonalNames;
227 }
228
229 if (this->ParentCivilization) {
230 return this->ParentCivilization->GetPersonalNames();
231 }
232
233 return this->PersonalNames;
234 }
235
GetUnitClassNames(int class_id)236 std::vector<std::string> &CCivilization::GetUnitClassNames(int class_id)
237 {
238 if (this->UnitClassNames[class_id].size() > 0) {
239 return this->UnitClassNames[class_id];
240 }
241
242 if (this->ParentCivilization) {
243 return this->ParentCivilization->GetUnitClassNames(class_id);
244 }
245
246 return this->UnitClassNames[class_id];
247 }
248
GetShipNames()249 std::vector<std::string> &CCivilization::GetShipNames()
250 {
251 if (this->ShipNames.size() > 0) {
252 return this->ShipNames;
253 }
254
255 if (this->ParentCivilization) {
256 return this->ParentCivilization->GetShipNames();
257 }
258
259 return this->ShipNames;
260 }
261
262 //@}
263