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