1 /***************************************************************************
2 * Mechanized Assault and Exploration Reloaded Projectfile *
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 2 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, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
19
20 #include <algorithm>
21 #include <cctype>
22 #include <cassert>
23
24 #include "ui/graphical/menu/windows/windowgamesettings/gamesettings.h"
25 #include "utility/tounderlyingtype.h"
26 #include "utility/string/iequals.h"
27 #include "main.h"
28 #include "netmessage.h"
29
30 const std::chrono::seconds cGameSettings::defaultTurnLimitOption0 (60);
31 const std::chrono::seconds cGameSettings::defaultTurnLimitOption1 (120);
32 const std::chrono::seconds cGameSettings::defaultTurnLimitOption2 (180);
33 const std::chrono::seconds cGameSettings::defaultTurnLimitOption3 (240);
34 const std::chrono::seconds cGameSettings::defaultTurnLimitOption4 (300);
35 const std::chrono::seconds cGameSettings::defaultTurnLimitOption5 (350);
36
37 const std::chrono::seconds cGameSettings::defaultEndTurnDeadlineOption0 (15);
38 const std::chrono::seconds cGameSettings::defaultEndTurnDeadlineOption1 (30);
39 const std::chrono::seconds cGameSettings::defaultEndTurnDeadlineOption2 (45);
40 const std::chrono::seconds cGameSettings::defaultEndTurnDeadlineOption3 (60);
41 const std::chrono::seconds cGameSettings::defaultEndTurnDeadlineOption4 (75);
42 const std::chrono::seconds cGameSettings::defaultEndTurnDeadlineOption5 (90);
43
44 //------------------------------------------------------------------------------
gameSettingsResourceAmountToString(eGameSettingsResourceAmount amount,bool translated)45 std::string gameSettingsResourceAmountToString (eGameSettingsResourceAmount amount, bool translated)
46 {
47 if (translated)
48 {
49 switch (amount)
50 {
51 case eGameSettingsResourceAmount::Limited:
52 return lngPack.i18n ("Text~Option~Limited");
53 case eGameSettingsResourceAmount::Normal:
54 return lngPack.i18n ("Text~Option~Normal");
55 case eGameSettingsResourceAmount::High:
56 return lngPack.i18n ("Text~Option~High");
57 case eGameSettingsResourceAmount::TooMuch:
58 return lngPack.i18n ("Text~Option~TooMuch");
59 }
60 }
61 else
62 {
63 switch (amount)
64 {
65 case eGameSettingsResourceAmount::Limited:
66 return "limited";
67 case eGameSettingsResourceAmount::Normal:
68 return "normal";
69 case eGameSettingsResourceAmount::High:
70 return "high";
71 case eGameSettingsResourceAmount::TooMuch:
72 return "toomuch";
73 }
74 }
75 assert (false);
76 return "";
77 }
78
79 //------------------------------------------------------------------------------
gameSettingsResourceAmountFromString(const std::string & string)80 eGameSettingsResourceAmount gameSettingsResourceAmountFromString (const std::string& string)
81 {
82 if (iequals (string, "limited")) return eGameSettingsResourceAmount::Limited;
83 else if (iequals (string, "normal")) return eGameSettingsResourceAmount::Normal;
84 else if (iequals (string, "high")) return eGameSettingsResourceAmount::High;
85 else if (iequals (string, "toomuch")) return eGameSettingsResourceAmount::TooMuch;
86 else throw std::runtime_error ("Invalid resource amount string '" + string + "'");
87 }
88
89 //------------------------------------------------------------------------------
gameSettingsResourceDensityToString(eGameSettingsResourceDensity density,bool translated)90 std::string gameSettingsResourceDensityToString (eGameSettingsResourceDensity density, bool translated)
91 {
92 if (translated)
93 {
94 switch (density)
95 {
96 case eGameSettingsResourceDensity::Sparse:
97 return lngPack.i18n ("Text~Option~Sparse");
98 case eGameSettingsResourceDensity::Normal:
99 return lngPack.i18n ("Text~Option~Normal");
100 case eGameSettingsResourceDensity::Dense:
101 return lngPack.i18n ("Text~Option~Dense");
102 case eGameSettingsResourceDensity::TooMuch:
103 return lngPack.i18n ("Text~Option~TooMuch");
104 }
105 }
106 else
107 {
108 switch (density)
109 {
110 case eGameSettingsResourceDensity::Sparse:
111 return "sparse";
112 case eGameSettingsResourceDensity::Normal:
113 return "normal";
114 case eGameSettingsResourceDensity::Dense:
115 return "dense";
116 case eGameSettingsResourceDensity::TooMuch:
117 return "toomuch";
118 }
119 }
120 assert (false);
121 return "";
122 }
123
124 //------------------------------------------------------------------------------
gameSettingsResourceDensityFromString(const std::string & string)125 eGameSettingsResourceDensity gameSettingsResourceDensityFromString (const std::string& string)
126 {
127 if (iequals (string, "sparse")) return eGameSettingsResourceDensity::Sparse;
128 else if (iequals (string, "normal")) return eGameSettingsResourceDensity::Normal;
129 else if (iequals (string, "dense")) return eGameSettingsResourceDensity::Dense;
130 else if (iequals (string, "toomuch")) return eGameSettingsResourceDensity::TooMuch;
131 else throw std::runtime_error ("Invalid resource density string '" + string + "'");
132 }
133
134 //------------------------------------------------------------------------------
gameSettingsBridgeheadTypeToString(eGameSettingsBridgeheadType type,bool translated)135 std::string gameSettingsBridgeheadTypeToString (eGameSettingsBridgeheadType type, bool translated)
136 {
137 if (translated)
138 {
139 switch (type)
140 {
141 case eGameSettingsBridgeheadType::Definite:
142 return lngPack.i18n ("Text~Option~Definite");
143 case eGameSettingsBridgeheadType::Mobile:
144 return lngPack.i18n ("Text~Option~Mobile");
145 }
146 }
147 else
148 {
149 switch (type)
150 {
151 case eGameSettingsBridgeheadType::Definite:
152 return "definite";
153 case eGameSettingsBridgeheadType::Mobile:
154 return "mobile";
155 }
156 }
157 assert (false);
158 return "";
159 }
160
161 //------------------------------------------------------------------------------
gameSettingsBridgeheadTypeFromString(const std::string & string)162 eGameSettingsBridgeheadType gameSettingsBridgeheadTypeFromString (const std::string& string)
163 {
164 if (iequals (string, "definite")) return eGameSettingsBridgeheadType::Definite;
165 else if (iequals (string, "mobile")) return eGameSettingsBridgeheadType::Mobile;
166 else throw std::runtime_error ("Invalid bridgehead type string '" + string + "'");
167 }
168
169 //------------------------------------------------------------------------------
gameSettingsGameTypeToString(eGameSettingsGameType type,bool translated)170 std::string gameSettingsGameTypeToString (eGameSettingsGameType type, bool translated)
171 {
172 if (translated)
173 {
174 switch (type)
175 {
176 case eGameSettingsGameType::Simultaneous:
177 return lngPack.i18n ("Text~Option~Type_Simu");
178 case eGameSettingsGameType::Turns:
179 return lngPack.i18n ("Text~Option~Type_Turns");
180 case eGameSettingsGameType::HotSeat:
181 return "Hot Seat"; // TODO: translation?!
182 }
183 }
184 else
185 {
186 switch (type)
187 {
188 case eGameSettingsGameType::Simultaneous:
189 return "simultaneous";
190 case eGameSettingsGameType::Turns:
191 return "turns";
192 case eGameSettingsGameType::HotSeat:
193 return "hotseat";
194 }
195 }
196 assert (false);
197 return "";
198 }
199
200 //------------------------------------------------------------------------------
gameSettingsGameTypeString(const std::string & string)201 eGameSettingsGameType gameSettingsGameTypeString (const std::string& string)
202 {
203 if (iequals (string, "simultaneous")) return eGameSettingsGameType::Simultaneous;
204 else if (iequals (string, "turns")) return eGameSettingsGameType::Turns;
205 else if (iequals (string, "hotseat")) return eGameSettingsGameType::HotSeat;
206 else throw std::runtime_error ("Invalid game type string '" + string + "'");
207 }
208
209 //------------------------------------------------------------------------------
gameSettingsVictoryConditionToString(eGameSettingsVictoryCondition condition,bool translated)210 std::string gameSettingsVictoryConditionToString (eGameSettingsVictoryCondition condition, bool translated)
211 {
212 if (translated)
213 {
214 switch (condition)
215 {
216 case eGameSettingsVictoryCondition::Turns:
217 return lngPack.i18n ("Text~Comp~Turns");
218 case eGameSettingsVictoryCondition::Points:
219 return lngPack.i18n ("Text~Comp~Points");
220 case eGameSettingsVictoryCondition::Death:
221 return lngPack.i18n ("Text~Comp~NoLimit");
222 }
223 }
224 else
225 {
226 switch (condition)
227 {
228 case eGameSettingsVictoryCondition::Turns:
229 return "turns";
230 case eGameSettingsVictoryCondition::Points:
231 return "points";
232 case eGameSettingsVictoryCondition::Death:
233 return "death";
234 }
235 }
236 assert (false);
237 return "";
238 }
239
240 //------------------------------------------------------------------------------
gameSettingsVictoryConditionFromString(const std::string & string)241 eGameSettingsVictoryCondition gameSettingsVictoryConditionFromString (const std::string& string)
242 {
243 if (iequals (string, "turns")) return eGameSettingsVictoryCondition::Turns;
244 else if (iequals (string, "points")) return eGameSettingsVictoryCondition::Points;
245 else if (iequals (string, "death")) return eGameSettingsVictoryCondition::Death;
246 else throw std::runtime_error ("Invalid victory condition string '" + string + "'");
247 }
248
249 //------------------------------------------------------------------------------
cGameSettings()250 cGameSettings::cGameSettings() :
251 metalAmount (eGameSettingsResourceAmount::Normal),
252 oilAmount (eGameSettingsResourceAmount::Normal),
253 goldAmount (eGameSettingsResourceAmount::Normal),
254 resourceDensity (eGameSettingsResourceDensity::Normal),
255 bridgeheadType (eGameSettingsBridgeheadType::Definite),
256 gameType (eGameSettingsGameType::Simultaneous),
257 clansEnabled (true),
258 startCredits (defaultCreditsNormal),
259 victoryConditionType (eGameSettingsVictoryCondition::Death),
260 victoryTurns (defaultVictoryTurnsOption2),
261 victoryPoints (defaultVictoryPointsOption2),
262 turnEndDeadline (defaultEndTurnDeadlineOption5),
263 turnEndDeadlineActive (true),
264 turnLimit (defaultTurnLimitOption5),
265 turnLimitActive (false)
266 {}
267
268 //------------------------------------------------------------------------------
cGameSettings(const cGameSettings & other)269 cGameSettings::cGameSettings (const cGameSettings& other) :
270 metalAmount (other.metalAmount),
271 oilAmount (other.oilAmount),
272 goldAmount (other.goldAmount),
273 resourceDensity (other.resourceDensity),
274 bridgeheadType (other.bridgeheadType),
275 gameType (other.gameType),
276 clansEnabled (other.clansEnabled),
277 startCredits (other.startCredits),
278 victoryConditionType (other.victoryConditionType),
279 victoryTurns (other.victoryTurns),
280 victoryPoints (other.victoryPoints),
281 turnEndDeadline (other.turnEndDeadline),
282 turnEndDeadlineActive (other.turnEndDeadlineActive),
283 turnLimit (other.turnLimit),
284 turnLimitActive (other.turnLimitActive)
285 {}
286
287 //------------------------------------------------------------------------------
operator =(const cGameSettings & other)288 cGameSettings& cGameSettings::operator= (const cGameSettings& other)
289 {
290 metalAmount = other.metalAmount;
291 oilAmount = other.oilAmount;
292 goldAmount = other.goldAmount;
293 resourceDensity = other.resourceDensity;
294 bridgeheadType = other.bridgeheadType;
295 gameType = other.gameType;
296 clansEnabled = other.clansEnabled;
297 startCredits = other.startCredits;
298 victoryConditionType = other.victoryConditionType;
299 victoryTurns = other.victoryTurns;
300 victoryPoints = other.victoryPoints;
301 turnEndDeadline = other.turnEndDeadline;
302 turnEndDeadlineActive = other.turnEndDeadlineActive;
303 turnLimit = other.turnLimit;
304 turnLimitActive = other.turnLimitActive;
305
306 return *this;
307 }
308
309 //------------------------------------------------------------------------------
getMetalAmount() const310 eGameSettingsResourceAmount cGameSettings::getMetalAmount() const
311 {
312 return metalAmount;
313 }
314
315 //------------------------------------------------------------------------------
setMetalAmount(eGameSettingsResourceAmount value)316 void cGameSettings::setMetalAmount (eGameSettingsResourceAmount value)
317 {
318 std::swap (metalAmount, value);
319 if (metalAmount != value) metalAmountChanged();
320 }
321
322 //------------------------------------------------------------------------------
getOilAmount() const323 eGameSettingsResourceAmount cGameSettings::getOilAmount() const
324 {
325 return oilAmount;
326 }
327
328 //------------------------------------------------------------------------------
setOilAmount(eGameSettingsResourceAmount value)329 void cGameSettings::setOilAmount (eGameSettingsResourceAmount value)
330 {
331 std::swap (oilAmount, value);
332 if (oilAmount != value) oilAmountChanged();
333 }
334
335 //------------------------------------------------------------------------------
getGoldAmount() const336 eGameSettingsResourceAmount cGameSettings::getGoldAmount() const
337 {
338 return goldAmount;
339 }
340
341 //------------------------------------------------------------------------------
setGoldAmount(eGameSettingsResourceAmount value)342 void cGameSettings::setGoldAmount (eGameSettingsResourceAmount value)
343 {
344 std::swap (goldAmount, value);
345 if (goldAmount != value) goldAmountChanged();
346 }
347
348 //------------------------------------------------------------------------------
getResourceDensity() const349 eGameSettingsResourceDensity cGameSettings::getResourceDensity() const
350 {
351 return resourceDensity;
352 }
353
354 //------------------------------------------------------------------------------
setResourceDensity(eGameSettingsResourceDensity value)355 void cGameSettings::setResourceDensity (eGameSettingsResourceDensity value)
356 {
357 std::swap (resourceDensity, value);
358 if (resourceDensity != value) resourceDensityChanged();
359 }
360
361 //------------------------------------------------------------------------------
getBridgeheadType() const362 eGameSettingsBridgeheadType cGameSettings::getBridgeheadType() const
363 {
364 return bridgeheadType;
365 }
366
367 //------------------------------------------------------------------------------
setBridgeheadType(eGameSettingsBridgeheadType value)368 void cGameSettings::setBridgeheadType (eGameSettingsBridgeheadType value)
369 {
370 std::swap (bridgeheadType, value);
371 if (bridgeheadType != value) bridgeheadTypeChanged();
372 }
373
374 //------------------------------------------------------------------------------
getGameType() const375 eGameSettingsGameType cGameSettings::getGameType() const
376 {
377 return gameType;
378 }
379
380 //------------------------------------------------------------------------------
setGameType(eGameSettingsGameType value)381 void cGameSettings::setGameType (eGameSettingsGameType value)
382 {
383 std::swap (gameType, value);
384 if (gameType != value) gameTypeChanged();
385 }
386
387 //------------------------------------------------------------------------------
getClansEnabled() const388 bool cGameSettings::getClansEnabled() const
389 {
390 return clansEnabled;
391 }
392
393 //------------------------------------------------------------------------------
setClansEnabled(bool value)394 void cGameSettings::setClansEnabled (bool value)
395 {
396 std::swap (clansEnabled, value);
397 if (clansEnabled != value) clansEnabledChanged();
398 }
399
400 //------------------------------------------------------------------------------
getStartCredits() const401 unsigned int cGameSettings::getStartCredits() const
402 {
403 return startCredits;
404 }
405
406 //------------------------------------------------------------------------------
setStartCredits(unsigned int value)407 void cGameSettings::setStartCredits (unsigned int value)
408 {
409 std::swap (startCredits, value);
410 if (startCredits != value) startCreditsChanged();
411 }
412
413 //------------------------------------------------------------------------------
getVictoryCondition() const414 eGameSettingsVictoryCondition cGameSettings::getVictoryCondition() const
415 {
416 return victoryConditionType;
417 }
418
419 //------------------------------------------------------------------------------
setVictoryCondition(eGameSettingsVictoryCondition value)420 void cGameSettings::setVictoryCondition (eGameSettingsVictoryCondition value)
421 {
422 std::swap (victoryConditionType, value);
423 if (victoryConditionType != value) victoryConditionTypeChanged();
424 }
425
426 //------------------------------------------------------------------------------
getVictoryTurns() const427 unsigned int cGameSettings::getVictoryTurns() const
428 {
429 return victoryTurns;
430 }
431
432 //------------------------------------------------------------------------------
setVictoryTurns(unsigned int value)433 void cGameSettings::setVictoryTurns (unsigned int value)
434 {
435 std::swap (victoryTurns, value);
436 if (victoryTurns != value) victoryTurnsChanged();
437 }
438
439 //------------------------------------------------------------------------------
getVictoryPoints() const440 unsigned int cGameSettings::getVictoryPoints() const
441 {
442 return victoryPoints;
443 }
444
445 //------------------------------------------------------------------------------
setVictoryPoints(unsigned int value)446 void cGameSettings::setVictoryPoints (unsigned int value)
447 {
448 std::swap (victoryPoints, value);
449 if (victoryPoints != value) victoryPointsChanged();
450 }
451
452 //------------------------------------------------------------------------------
getTurnEndDeadline() const453 const std::chrono::seconds& cGameSettings::getTurnEndDeadline() const
454 {
455 return turnEndDeadline;
456 }
457
458 //------------------------------------------------------------------------------
setTurnEndDeadline(const std::chrono::seconds & value)459 void cGameSettings::setTurnEndDeadline (const std::chrono::seconds& value)
460 {
461 const auto oldValue = turnEndDeadline;
462 turnEndDeadline = value;
463 if (oldValue != turnEndDeadline) turnEndDeadlineChanged();
464 }
465
466 //------------------------------------------------------------------------------
isTurnEndDeadlineActive() const467 bool cGameSettings::isTurnEndDeadlineActive() const
468 {
469 return turnEndDeadlineActive;
470 }
471
472 //------------------------------------------------------------------------------
setTurnEndDeadlineActive(bool value)473 void cGameSettings::setTurnEndDeadlineActive (bool value)
474 {
475 std::swap (turnEndDeadlineActive, value);
476 if (turnEndDeadlineActive != value) turnEndDeadlineActiveChanged();
477 }
478
479 //------------------------------------------------------------------------------
getTurnLimit() const480 const std::chrono::seconds& cGameSettings::getTurnLimit() const
481 {
482 return turnLimit;
483 }
484
485 //------------------------------------------------------------------------------
setTurnLimit(const std::chrono::seconds & value)486 void cGameSettings::setTurnLimit (const std::chrono::seconds& value)
487 {
488 const auto oldValue = turnLimit;
489 turnLimit = value;
490 if (oldValue != turnLimit) turnLimitChanged();
491 }
492
493 //------------------------------------------------------------------------------
isTurnLimitActive() const494 bool cGameSettings::isTurnLimitActive() const
495 {
496 return turnLimitActive;
497 }
498
499 //------------------------------------------------------------------------------
setTurnLimitActive(bool value)500 void cGameSettings::setTurnLimitActive (bool value)
501 {
502 std::swap (turnLimitActive, value);
503 if (turnLimitActive != value) turnLimitActiveChanged();
504 }
505
506 //------------------------------------------------------------------------------
pushInto(cNetMessage & message) const507 void cGameSettings::pushInto (cNetMessage& message) const
508 {
509 message.pushInt32 (toUnderlyingType (metalAmount));
510 message.pushInt32 (toUnderlyingType (oilAmount));
511 message.pushInt32 (toUnderlyingType (goldAmount));
512
513 message.pushInt32 (toUnderlyingType (resourceDensity));
514
515 message.pushInt32 (toUnderlyingType (bridgeheadType));
516
517 message.pushInt32 (toUnderlyingType (gameType));
518
519 message.pushBool (clansEnabled);
520
521 message.pushInt32 (startCredits);
522
523 message.pushInt32 (toUnderlyingType (victoryConditionType));
524 message.pushInt32 (victoryTurns);
525 message.pushInt32 (victoryPoints);
526
527 message.pushInt32 (turnEndDeadline.count());
528 message.pushBool (turnEndDeadlineActive);
529
530 message.pushInt32 (turnLimit.count());
531 message.pushBool (turnLimitActive);
532 }
533
534 //------------------------------------------------------------------------------
popFrom(cNetMessage & message)535 void cGameSettings::popFrom (cNetMessage& message)
536 {
537 setTurnLimitActive (message.popBool());
538 setTurnLimit (std::chrono::seconds (message.popInt32()));
539
540 setTurnEndDeadlineActive (message.popBool());
541 setTurnEndDeadline (std::chrono::seconds (message.popInt32()));
542
543 setVictoryPoints (message.popInt32());
544 setVictoryTurns (message.popInt32());
545 setVictoryCondition (static_cast<eGameSettingsVictoryCondition> (message.popInt32()));
546
547 setStartCredits (message.popInt32());
548
549 setClansEnabled (message.popBool());
550
551 setGameType (static_cast<eGameSettingsGameType> (message.popInt32()));
552
553 setBridgeheadType (static_cast<eGameSettingsBridgeheadType> (message.popInt32()));
554
555 setResourceDensity (static_cast<eGameSettingsResourceDensity> (message.popInt32()));
556
557 setGoldAmount (static_cast<eGameSettingsResourceAmount> (message.popInt32()));
558 setOilAmount (static_cast<eGameSettingsResourceAmount> (message.popInt32()));
559 setMetalAmount (static_cast<eGameSettingsResourceAmount> (message.popInt32()));
560 }
561