1 // Copyright (C) 2000, 2001, 2002, 2003 Michael Bartl
2 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Ulf Lorenz
3 // Copyright (C) 2004, 2006 Andrea Paternesi
4 // Copyright (C) 2006, 2007, 2008 Ben Asselstine
5 // Copyright (C) 2007, 2008 Ole Laursen
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 3 of the License, or
10 // (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Library General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
27 #include <sigc++/functors/mem_fun.h>
30 #include "ucompose.hpp"
31 #include "GameScenario.h"
32 #include "MapGenerator.h"
33 #include "playerlist.h"
37 #include "rewardlist.h"
38 #include "templelist.h"
39 #include "bridgelist.h"
42 #include "signpostlist.h"
46 #include "armysetlist.h"
47 #include "tilesetlist.h"
48 #include "citysetlist.h"
49 #include "shieldsetlist.h"
50 #include "stacklist.h"
54 #include "Configuration.h"
55 #include "real_player.h"
60 #include "QuestsManager.h"
63 #include "vectoredunitlist.h"
65 #include "xmlhelper.h"
66 #include "tarhelper.h"
67 #include "stacktile.h"
68 #include "GraphicsCache.h"
70 std::string GameScenario::d_tag = "scenario";
73 #define debug(x) {cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<endl<<flush;}
76 GameScenario::GameScenario(std::string name,std::string comment, bool turnmode,
77 GameScenario::PlayMode playmode)
78 :d_name(name),d_comment(comment), d_copyright(""), d_license(""),
79 d_turnmode(turnmode), d_playmode(playmode), inhibit_autosave_removal(false)
81 Armysetlist::getInstance();
82 Tilesetlist::getInstance();
83 Shieldsetlist::getInstance();
86 fl_counter = new FL_Counter();
91 //savegame has an absolute path
92 GameScenario::GameScenario(string savegame, bool& broken)
93 :d_turnmode(true), d_playmode(GameScenario::HOTSEAT),
94 inhibit_autosave_removal(false)
96 Tar_Helper t(savegame, std::ios::in);
101 std::string filename = t.getFirstFile(broken);
102 XML_Helper helper(filename, std::ios::in, Configuration::s_zipfiles);
103 broken = loadWithHelper(helper);
104 File::erase(filename);
109 bool GameScenario::loadArmysets(Tar_Helper *t)
112 std::list<std::string> armysets;
113 armysets = t->getFilenamesWithExtension(Armyset::file_extension);
114 for (std::list<std::string>::iterator it = armysets.begin();
115 it != armysets.end(); it++)
117 Armyset *armyset = Armysetlist::getInstance()->import(t, *it, broken);
119 Armysetlist::getInstance()->getArmyset(armyset->getId())->instantiateImages();
124 bool GameScenario::loadTilesets(Tar_Helper *t)
127 std::list<std::string> tilesets;
128 tilesets = t->getFilenamesWithExtension(Tileset::file_extension);
129 for (std::list<std::string>::iterator it = tilesets.begin();
130 it != tilesets.end(); it++)
132 std::string filename = t->getFile(*it, broken);
133 Tileset *tileset = Tileset::create(filename);
134 tileset->setSubDir(File::get_basename(*it));
136 //extract all the files and remember where we extracted them
137 std::list<std::string> delfiles;
138 delfiles.push_back(filename);
139 std::list<std::string> files;
140 tileset->getFilenames(files);
141 for (std::list<std::string>::iterator i = files.begin(); i != files.end(); i++)
142 delfiles.push_back (t->getFile(*i + ".png", broken));
144 std::string subdir = "";
146 Tilesetlist::getInstance()->addToPersonalCollection(tileset, subdir, id);
148 for (std::list<std::string>::iterator it = delfiles.begin(); it != delfiles.end(); it++)
151 Tilesetlist::getInstance()->getTileset(tileset->getId())->instantiateImages();
156 bool GameScenario::loadCitysets(Tar_Helper *t)
159 std::list<std::string> citysets;
160 citysets = t->getFilenamesWithExtension(Cityset::file_extension);
161 for (std::list<std::string>::iterator it = citysets.begin();
162 it != citysets.end(); it++)
164 std::string filename = t->getFile(*it, broken);
165 Cityset *cityset = Cityset::create(filename);
166 cityset->setSubDir(File::get_basename(*it));
168 //extract all the files and remember where we extracted them
169 std::list<std::string> delfiles;
170 delfiles.push_back(filename);
171 std::list<std::string> files;
172 cityset->getFilenames(files);
173 for (std::list<std::string>::iterator i = files.begin(); i != files.end(); i++)
174 delfiles.push_back (t->getFile(*i + ".png", broken));
176 std::string subdir = "";
178 Citysetlist::getInstance()->addToPersonalCollection(cityset, subdir, id);
180 for (std::list<std::string>::iterator it = delfiles.begin(); it != delfiles.end(); it++)
183 Citysetlist::getInstance()->getCityset(cityset->getId())->instantiateImages();
188 bool GameScenario::loadShieldsets(Tar_Helper *t)
191 std::list<std::string> shieldsets;
192 shieldsets = t->getFilenamesWithExtension(Shieldset::file_extension);
193 for (std::list<std::string>::iterator it = shieldsets.begin();
194 it != shieldsets.end(); it++)
196 std::string filename = t->getFile(*it, broken);
197 Shieldset *shieldset = Shieldset::create(filename);
198 shieldset->setSubDir(File::get_basename(*it));
200 //extract all the files and remember where we extracted them
201 std::list<std::string> delfiles;
202 delfiles.push_back(filename);
203 std::list<std::string> files;
204 shieldset->getFilenames(files);
205 for (std::list<std::string>::iterator i = files.begin(); i != files.end(); i++)
206 delfiles.push_back (t->getFile(*i + ".png", broken));
208 std::string subdir = "";
210 Shieldsetlist::getInstance()->addToPersonalCollection(shieldset, subdir, id);
212 for (std::list<std::string>::iterator it = delfiles.begin(); it != delfiles.end(); it++)
216 Shieldsetlist::getInstance()->getShieldset(shieldset->getId())->instantiateImages();
221 GameScenario::GameScenario(XML_Helper &helper, bool& broken)
222 : d_turnmode(true), d_playmode(GameScenario::HOTSEAT),
223 inhibit_autosave_removal(false)
225 broken = loadWithHelper(helper);
228 void GameScenario::quickStartEvenlyDivided()
230 Playerlist *plist = Playerlist::getInstance();
231 Citylist *clist = Citylist::getInstance();
234 // divvy up the neutral cities among other non-neutral players
235 int cities_left = clist->size() - plist->size() + 1;
236 unsigned int citycount[MAX_PLAYERS];
237 memset (citycount, 0, sizeof (citycount));
238 Playerlist::iterator pit = plist->begin();
240 while (cities_left > 0)
242 if (*pit != plist->getNeutral())
244 citycount[(*pit)->getId()]++;
249 if (pit == plist->end())
250 pit = plist->begin();
253 for (unsigned int i = 0; i < MAX_PLAYERS; i++)
255 for (unsigned int j = 0; j < citycount[i]; j++)
257 Player *p = plist->getPlayer(i);
260 if (p == plist->getNeutral())
262 pos = clist->getFirstCity(p)->getPos();
263 City *c = clist->getNearestNeutralCity(pos);
266 //does the city contain any stacks yet?
267 //change their allegience to us.
268 for (unsigned int x = 0 ; x < c->getSize(); x++)
270 for (unsigned int y = 0; y < c->getSize(); y++)
273 GameMap::getStacks(c->getPos() + Vector<int>(x,y));
274 std::list<Stack*> stks = stile->getStacks();
275 for (std::list<Stack *>::iterator i = stks.begin();
276 i != stks.end(); i++)
277 Stacklist::changeOwnership(*i, p);
281 //now give the city to us.
283 History_CityWon *item = new History_CityWon();
291 void GameScenario::quickStartAIHeadStart()
293 float head_start_factor = 0.05;
294 //each AI player gets this percent of total cities.
296 Playerlist *plist = Playerlist::getInstance();
297 Citylist *clist = Citylist::getInstance();
300 unsigned int citycount = clist->size() * head_start_factor;
303 for (unsigned int i = 0; i < MAX_PLAYERS; i++)
305 for (unsigned int j = 0; j < citycount; j++)
307 Player *p = plist->getPlayer(i);
310 if (p == plist->getNeutral())
312 if (p->getType() == Player::HUMAN)
314 pos = clist->getFirstCity(p)->getPos();
315 City *c = clist->getNearestNeutralCity(pos);
318 //does the city contain any stacks yet?
319 //change their allegience to us.
320 for (unsigned int x = 0 ; x < c->getSize(); x++)
322 for (unsigned int y = 0; y < c->getSize(); y++)
325 GameMap::getStacks(c->getPos() + Vector<int>(x,y));
326 std::list<Stack*> stks = stile->getStacks();
327 for (std::list<Stack *>::iterator i = stks.begin();
328 i != stks.end(); i++)
329 Stacklist::changeOwnership(*i, p);
333 //now give the city to us.
335 History_CityWon *item = new History_CityWon();
343 bool GameScenario::setupFog(bool hidden_map)
345 Playerlist *pl = Playerlist::getInstance();
346 Playerlist::iterator it = pl->begin();
347 for (; it != pl->end(); it++)
350 (*it)->getFogMap()->fill(FogMap::CLOSED);
352 (*it)->getFogMap()->fill(FogMap::OPEN);
357 bool GameScenario::setupStacks(bool hidden_map)
361 for (Playerlist::iterator it = Playerlist::getInstance()->begin();
362 it != Playerlist::getInstance()->end(); it++)
364 if ((*it) == Playerlist::getInstance()->getNeutral())
366 for (Stacklist::iterator sit = (*it)->getStacklist()->begin();
367 sit != (*it)->getStacklist()->end(); sit++)
373 bool GameScenario::setupMapRewards()
375 debug("GameScenario::setupMapRewards")
376 //okay, let's make some maps
377 //split the terrain into a 3x3 grid
378 Vector<int> step = Vector<int>(GameMap::getWidth() / 3,
379 GameMap::getHeight() / 3);
380 Reward_Map *reward = new Reward_Map(Vector<int>(step.x * 0, 0),
381 _("Northwestern map"), step.x, step.y);
382 Rewardlist::getInstance()->push_back(reward);
383 reward = new Reward_Map(Vector<int>(step.x * 1, 0),
384 _("Northern map"), step.x, step.y);
385 Rewardlist::getInstance()->push_back(reward);
386 reward = new Reward_Map(Vector<int>(step.x * 2, 0),
387 _("Northeastern map"), step.x, step.y);
388 Rewardlist::getInstance()->push_back(reward);
389 reward = new Reward_Map(Vector<int>(step.x * 0, step.y * 1),
390 _("Western map"), step.x, step.y);
391 Rewardlist::getInstance()->push_back(reward);
392 reward = new Reward_Map(Vector<int>(step.x * 1, step.y * 1),
393 _("Central map"), step.x, step.y);
394 Rewardlist::getInstance()->push_back(reward);
395 reward = new Reward_Map(Vector<int>(step.x * 2, step.y * 1),
396 _("Eastern map"), step.x, step.y);
397 Rewardlist::getInstance()->push_back(reward);
398 reward = new Reward_Map(Vector<int>(step.x * 0, step.y * 2),
399 _("Southwestern map"), step.x, step.y);
400 Rewardlist::getInstance()->push_back(reward);
401 reward = new Reward_Map(Vector<int>(step.x * 1, step.y * 2),
402 _("Southern map"), step.x, step.y);
403 Rewardlist::getInstance()->push_back(reward);
404 reward = new Reward_Map(Vector<int>(step.x * 2, step.y * 2),
405 _("Southeastern map"), step.x, step.y);
406 Rewardlist::getInstance()->push_back(reward);
410 bool GameScenario::setupRuinRewards()
412 debug("GameScenario::setupRuinRewards")
413 for (Ruinlist::iterator it = Ruinlist::getInstance()->begin();
414 it != Ruinlist::getInstance()->end(); it++)
416 if ((*it)->isHidden() == true)
418 //add it to the reward list
419 Reward_Ruin *newReward = new Reward_Ruin((*it)); //make a reward
420 newReward->setName(newReward->getDescription());
421 Rewardlist::getInstance()->push_back(newReward); //add it
425 if ((*it)->hasSage() == false && (*it)->getReward() == NULL)
426 (*it)->populateWithRandomReward();
432 bool GameScenario::setupItemRewards()
434 debug("GameScenario::setupItemRewards")
435 Itemlist *il = Itemlist::getInstance();
436 Itemlist::iterator iter;
437 for (iter = il->begin(); iter != il->end(); iter++)
439 Item templateItem = *iter->second;
440 Item *newItem = new Item(templateItem); //instantiate it
441 Reward_Item *newReward = new Reward_Item(newItem); //make a reward
442 newReward->setName(newReward->getDescription());
443 Rewardlist::getInstance()->push_back(newReward); //add it
449 bool GameScenario::setupRewards(bool hidden_map)
451 if (Rewardlist::getInstance()->size() != 0)
460 bool GameScenario::setupCities(GameParameters::QuickStartPolicy quick_start)
462 debug("GameScenario::setupCities")
464 for (Playerlist::iterator it = Playerlist::getInstance()->begin();
465 it != Playerlist::getInstance()->end(); it++)
467 if ((*it) == Playerlist::getInstance()->getNeutral())
469 City *city = Citylist::getInstance()->getFirstCity(*it);
472 city->deFog(city->getOwner());
473 History_CityWon *item = new History_CityWon();
474 item->fillData(city);
475 city->getOwner()->addHistory(item);
479 if (quick_start == GameParameters::EVENLY_DIVIDED)
480 quickStartEvenlyDivided();
481 else if (quick_start == GameParameters::AI_HEAD_START)
482 quickStartAIHeadStart();
484 for (Citylist::iterator it = Citylist::getInstance()->begin();
485 it != Citylist::getInstance()->end(); it++)
487 if ((*it)->getOwner() == Playerlist::getInstance()->getNeutral())
489 switch (GameScenario::s_neutral_cities)
491 case GameParameters::AVERAGE:
492 (*it)->produceScout();
494 case GameParameters::STRONG:
495 (*it)->produceStrongestProductionBase();
497 case GameParameters::ACTIVE:
498 if (rand () % 100 > 20)
499 (*it)->produceStrongestProductionBase();
501 (*it)->produceWeakestProductionBase();
503 case GameParameters::DEFENSIVE:
504 (*it)->produceScout();
505 (*it)->produceScout();
508 (*it)->setActiveProductionSlot(-1);
512 if ((*it)->isCapital())
513 (*it)->produceStrongestProductionBase();
515 (*it)->produceWeakestProductionBase();
517 (*it)->setActiveProductionSlot(0);
524 void GameScenario::setupDiplomacy(bool diplomacy)
526 Playerlist *pl = Playerlist::getInstance();
528 for (Playerlist::iterator pit = pl->begin(); pit != pl->end(); pit++)
530 if (pl->getNeutral() == (*pit))
532 for (Playerlist::iterator it = pl->begin(); it != pl->end(); it++)
534 if (pl->getNeutral() == (*it))
538 if (diplomacy == false)
540 (*pit)->proposeDiplomacy(Player::PROPOSE_WAR, *it);
541 (*pit)->declareDiplomacy(Player::AT_WAR, *it);
545 (*pit)->proposeDiplomacy(Player::NO_PROPOSAL, *it);
546 (*pit)->declareDiplomacy(Player::AT_PEACE, *it);
551 pl->calculateDiplomaticRankings();
554 bool GameScenario::loadWithHelper(XML_Helper& helper)
556 Armysetlist::getInstance();
557 Tilesetlist::getInstance();
558 Shieldsetlist::getInstance();
562 helper.registerTag(d_tag, sigc::mem_fun(this, &GameScenario::load));
563 helper.registerTag(Itemlist::d_tag, sigc::mem_fun(this, &GameScenario::load));
564 helper.registerTag(Playerlist::d_tag, sigc::mem_fun(this, &GameScenario::load));
565 helper.registerTag(GameMap::d_tag, sigc::mem_fun(this, &GameScenario::load));
566 helper.registerTag(Citylist::d_tag, sigc::mem_fun(this, &GameScenario::load));
567 helper.registerTag(Templelist::d_tag, sigc::mem_fun(this, &GameScenario::load));
568 helper.registerTag(Ruinlist::d_tag, sigc::mem_fun(this, &GameScenario::load));
569 helper.registerTag(Rewardlist::d_tag, sigc::mem_fun(this, &GameScenario::load));
570 helper.registerTag(Signpostlist::d_tag, sigc::mem_fun(this, &GameScenario::load));
571 helper.registerTag(Roadlist::d_tag, sigc::mem_fun(this, &GameScenario::load));
572 helper.registerTag(FL_Counter::d_tag, sigc::mem_fun(this, &GameScenario::load));
573 helper.registerTag(QuestsManager::d_tag, sigc::mem_fun(this, &GameScenario::load));
574 helper.registerTag(Bridgelist::d_tag, sigc::mem_fun(this, &GameScenario::load));
575 helper.registerTag(Portlist::d_tag, sigc::mem_fun(this, &GameScenario::load));
576 helper.registerTag(VectoredUnitlist::d_tag, sigc::mem_fun(this, &GameScenario::load));
581 GameMap::getInstance()->updateStackPositions();
582 GameMap::getInstance()->calculateBlockedAvenues();
588 GameScenario::~GameScenario()
590 // GameMap is a Singleton so we need a function to delete it
591 GameMap::deleteInstance();
592 Itemlist::deleteInstance();
593 Playerlist::deleteInstance();
594 Citylist::deleteInstance();
595 Templelist::deleteInstance();
596 Ruinlist::deleteInstance();
597 Rewardlist::deleteInstance();
598 Signpostlist::deleteInstance();
599 Portlist::deleteInstance();
600 Bridgelist::deleteInstance();
601 Roadlist::deleteInstance();
602 QuestsManager::deleteInstance();
603 VectoredUnitlist::deleteInstance();
610 if (Configuration::s_autosave_policy == 1 &&
611 inhibit_autosave_removal == false)
613 std::string filename = File::getSavePath() + "autosave.sav";
614 File::erase(filename);
616 GameScenarioOptions::s_round = 0;
619 std::string GameScenario::getName(bool translate) const
627 std::string GameScenario::getComment(bool translate) const
630 return __(d_comment);
635 bool GameScenario::saveGame(string filename, string extension) const
638 string goodfilename=filename;
640 if (File::nameEndsWith(filename, extension) == false)
641 goodfilename += "." + extension;
643 std::string tmpfile = "lw.XXXX";
644 int fd = Glib::file_open_tmp(tmpfile, "lw.XXXX");
646 XML_Helper helper(tmpfile, ios::out, Configuration::s_zipfiles);
647 retval &= saveWithHelper(helper);
653 Tar_Helper t(goodfilename, std::ios::out);
654 t.saveFile(tmpfile, File::get_basename(goodfilename, true));
655 File::erase(tmpfile);
656 std::list<std::string> files;
658 Cityset *cs = GameMap::getInstance()->getCityset();
659 cs->getFilenames(files);
660 t.saveFile(cs->getConfigurationFile());
661 for (std::list<std::string>::iterator it = files.begin(); it !=files.end();
663 t.saveFile(cs->getFile(*it));
666 Shieldset *ss = GameMap::getInstance()->getShieldset();
667 ss->getFilenames(files);
668 t.saveFile(ss->getConfigurationFile());
669 for (std::list<std::string>::iterator it = files.begin(); it !=files.end();
671 t.saveFile(ss->getFile(*it));
674 Tileset *ts = GameMap::getInstance()->getTileset();
675 ts->getFilenames(files);
676 t.saveFile(ts->getConfigurationFile());
677 for (std::list<std::string>::iterator it = files.begin(); it !=files.end();
679 t.saveFile(ts->getFile(*it));
681 Playerlist *plist = Playerlist::getInstance();
682 std::list<guint32> armysets;
683 for (Playerlist::iterator it = plist->begin(); it != plist->end(); it++)
685 guint32 armyset = (*it)->getArmyset();
686 if (std::find(armysets.begin(), armysets.end(), armyset) ==
688 armysets.push_back(armyset);
690 for (std::list<guint32>::iterator it = armysets.begin(); it!= armysets.end();
694 Armyset *as = Armysetlist::getInstance()->getArmyset(*it);
695 t.saveFile(as->getConfigurationFile());
696 as->getFilenames(files);
697 for (std::list<std::string>::iterator i = files.begin();
698 i != files.end(); i++)
699 t.saveFile(as->getFile(*i));
707 bool GameScenario::saveWithHelper(XML_Helper &helper) const
712 retval &= helper.begin(LORDSAWAR_SAVEGAME_VERSION);
713 retval &= helper.openTag("lordsawar");
715 //if retval is still true it propably doesn't change throughout the rest
716 //now save the single object's data
717 retval &= fl_counter->save(&helper);
718 retval &= Itemlist::getInstance()->save(&helper);
719 retval &= Playerlist::getInstance()->save(&helper);
720 retval &= GameMap::getInstance()->save(&helper);
721 retval &= Citylist::getInstance()->save(&helper);
722 retval &= Templelist::getInstance()->save(&helper);
723 retval &= Ruinlist::getInstance()->save(&helper);
724 retval &= Rewardlist::getInstance()->save(&helper);
725 retval &= Signpostlist::getInstance()->save(&helper);
726 retval &= Roadlist::getInstance()->save(&helper);
727 retval &= Portlist::getInstance()->save(&helper);
728 retval &= Bridgelist::getInstance()->save(&helper);
729 retval &= QuestsManager::getInstance()->save(&helper);
730 retval &= VectoredUnitlist::getInstance()->save(&helper);
732 //save the private GameScenario data last due to dependencies
733 retval &= helper.openTag(GameScenario::d_tag);
734 retval &= helper.saveData("id", d_id);
735 retval &= helper.saveData("name", d_name);
736 retval &= helper.saveData("comment", d_comment);
737 retval &= helper.saveData("copyright", d_copyright);
738 retval &= helper.saveData("license", d_license);
739 retval &= helper.saveData("turn", s_round);
740 retval &= helper.saveData("turnmode", d_turnmode);
741 retval &= helper.saveData("view_enemies", s_see_opponents_stacks);
742 retval &= helper.saveData("view_production", s_see_opponents_production);
743 std::string quest_policy_str = Configuration::questPolicyToString(GameParameters::QuestPolicy(s_play_with_quests));
744 retval &= helper.saveData("quests", quest_policy_str);
745 retval &= helper.saveData("hidden_map", s_hidden_map);
746 retval &= helper.saveData("diplomacy", s_diplomacy);
747 retval &= helper.saveData("cusp_of_war", s_cusp_of_war);
748 std::string neutral_cities_str = Configuration::neutralCitiesToString(GameParameters::NeutralCities(s_neutral_cities));
749 retval &= helper.saveData("neutral_cities", neutral_cities_str);
750 std::string razing_cities_str = Configuration::razingCitiesToString(GameParameters::RazingCities(s_razing_cities));
751 retval &= helper.saveData("razing_cities", razing_cities_str);
752 retval &= helper.saveData("intense_combat", s_intense_combat);
753 retval &= helper.saveData("military_advisor", s_military_advisor);
754 retval &= helper.saveData("random_turns", s_random_turns);
755 retval &= helper.saveData("surrender_already_offered",
756 s_surrender_already_offered);
757 std::string playmode_str = playModeToString(GameScenario::PlayMode(d_playmode));
758 retval &= helper.saveData("playmode", playmode_str);
760 retval &= helper.closeTag();
762 retval &= helper.closeTag();
767 bool GameScenario::load(std::string tag, XML_Helper* helper)
769 if (tag == GameScenario::d_tag)
771 if (helper->getVersion() != LORDSAWAR_SAVEGAME_VERSION)
773 cerr << "savefile has wrong version, we want ";
774 std::cerr <<LORDSAWAR_SAVEGAME_VERSION <<",\n";
775 cerr << "savefile offers " <<helper->getVersion() <<".\n";
779 debug("loading scenario")
781 helper->getData(d_id, "id");
782 helper->getData(d_turnmode, "turnmode");
783 helper->getData(d_name, "name");
784 helper->getData(d_comment, "comment");
785 helper->getData(d_copyright, "copyright");
786 helper->getData(d_license, "license");
787 helper->getData(s_round, "turn");
788 helper->getData(s_see_opponents_stacks, "view_enemies");
789 helper->getData(s_see_opponents_production, "view_production");
790 std::string quest_policy_str;
791 helper->getData(quest_policy_str, "quests");
792 s_play_with_quests = Configuration::questPolicyFromString(quest_policy_str);
793 helper->getData(s_hidden_map, "hidden_map");
794 helper->getData(s_diplomacy, "diplomacy");
795 helper->getData(s_cusp_of_war, "cusp_of_war");
796 std::string neutral_cities_str;
797 helper->getData(neutral_cities_str, "neutral_cities");
798 s_neutral_cities = Configuration::neutralCitiesFromString(neutral_cities_str);
799 std::string razing_cities_str;
800 helper->getData(razing_cities_str, "razing_cities");
801 s_razing_cities = Configuration::razingCitiesFromString(razing_cities_str);
802 helper->getData(s_intense_combat, "intense_combat");
803 helper->getData(s_military_advisor, "military_advisor");
804 helper->getData(s_random_turns, "random_turns");
805 helper->getData(s_surrender_already_offered,
806 "surrender_already_offered");
807 std::string playmode_str;
808 helper->getData(playmode_str, "playmode");
809 d_playmode = GameScenario::playModeFromString(playmode_str);
814 if (tag == FL_Counter::d_tag)
816 debug("loading counter")
817 fl_counter = new FL_Counter(helper);
821 if (tag == Itemlist::d_tag)
823 debug("loading items");
824 Itemlist::getInstance(helper);
828 if (tag == Playerlist::d_tag)
830 debug("loading players");
831 Playerlist::getInstance(helper);
835 if (tag == GameMap::d_tag)
838 GameMap::getInstance(helper);
842 if (tag == Citylist::d_tag)
844 debug("loading cities")
846 Citylist::getInstance(helper);
850 if (tag == Templelist::d_tag)
852 debug("loading temples")
853 Templelist::getInstance(helper);
857 if (tag == Ruinlist::d_tag)
859 debug("loading ruins")
860 Ruinlist::getInstance(helper);
864 if (tag == Rewardlist::d_tag)
866 debug("loading rewards")
867 Rewardlist::getInstance(helper);
871 if (tag == Signpostlist::d_tag)
873 debug("loading signposts")
874 Signpostlist::getInstance(helper);
878 if (tag == Roadlist::d_tag)
880 debug("loading roads")
881 Roadlist::getInstance(helper);
885 if (tag == QuestsManager::d_tag)
887 debug("loading quests")
888 QuestsManager::getInstance(helper);
892 if (tag == VectoredUnitlist::d_tag)
894 debug("loading vectored units")
895 VectoredUnitlist::getInstance(helper);
899 if (tag == Portlist::d_tag)
901 debug("loading ports")
902 Portlist::getInstance(helper);
906 if (tag == Bridgelist::d_tag)
908 debug("loading bridges")
909 Bridgelist::getInstance(helper);
916 bool GameScenario::autoSave()
918 Glib::ustring filename = "";
919 if (Configuration::s_autosave_policy == 2)
920 filename = String::ucompose("autosave-%1.sav", Glib::ustring::format(std::setfill(L'0'), std::setw(3), s_round - 1));
921 else if (Configuration::s_autosave_policy == 1)
922 filename = "autosave.sav";
925 // autosave to the file "autosave.sav". This is crude, but should work
927 // As a more enhanced version: autosave to a temporary file, then rename
928 // the file. Avoids screwing up the autosave if something goes wrong
929 // (and we have a savefile for debugging)
930 if (!saveGame(File::getSavePath() + "tmp.sav"))
932 std::cerr<< "Autosave failed.\n";
935 if (rename(std::string(File::getSavePath() + "tmp.sav").c_str(),
936 std::string(File::getSavePath() + filename).c_str()))
938 char* err = strerror(errno);
939 std::cerr << "Error while trying to rename the temporary file to autosave.sav\n";
940 std::cerr << "Error: " <<err <<std::endl;
946 void GameScenario::nextRound()
952 std::string GameScenario::playModeToString(const GameScenario::PlayMode mode)
956 case GameScenario::HOTSEAT:
957 return "GameScenario::HOTSEAT";
959 case GameScenario::NETWORKED:
960 return "GameScenario::NETWORKED";
962 case GameScenario::PLAY_BY_MAIL:
963 return "GameScenario::PLAY_BY_MAIL";
966 return "GameScenario::HOTSEAT";
969 GameScenario::PlayMode GameScenario::playModeFromString(const std::string str)
971 if (str.size() > 0 && isdigit(str.c_str()[0]))
972 return GameScenario::PlayMode(atoi(str.c_str()));
973 if (str == "GameScenario::HOTSEAT")
974 return GameScenario::HOTSEAT;
975 else if (str == "GameScenario::NETWORKED")
976 return GameScenario::NETWORKED;
977 else if (str == "GameScenario::PLAY_BY_MAIL")
978 return GameScenario::PLAY_BY_MAIL;
979 return GameScenario::HOTSEAT;
982 void GameScenario::setNewRandomId()
984 d_id = String::ucompose("%1%2%3", time(NULL), getpid(), rand());
987 bool GameScenario::validate(std::list<std::string> &errors, std::list<std::string> &warnings)
990 Playerlist *pl = Playerlist::getInstance();
991 guint32 num = pl->countPlayersAlive();
993 errors.push_back(_("There must be at least 2 players in the scenario."));
995 num = Citylist::getInstance()->countCities();
997 errors.push_back(_("There must be at least 2 cities in the scenario."));
999 for (Playerlist::iterator it = pl->begin(); it != pl->end(); it++)
1001 if (*it == pl->getNeutral())
1003 if ((*it)->isDead() == true)
1005 if (Citylist::getInstance()->getFirstCity(*it) == NULL)
1007 s = String::ucompose
1008 (_("The player called `%1' lacks a starting city."),
1009 (*it)->getName().c_str());
1010 errors.push_back(s);
1016 Citylist *cl = Citylist::getInstance();
1017 for (Citylist::iterator it = cl->begin(); it != cl->end(); it++)
1019 if ((*it)->isUnnamed() == true)
1024 s = String::ucompose(ngettext("There is %1 unnamed city", "There are %1 unnamed cities", count), count);
1025 warnings.push_back(s);
1029 Ruinlist *rl = Ruinlist::getInstance();
1030 for (Ruinlist::iterator it = rl->begin(); it != rl->end(); it++)
1032 if ((*it)->isUnnamed() == true)
1038 s = String::ucompose(ngettext("There is %1 unnamed ruin", "There are %1 unnamed ruins", count), count);
1039 warnings.push_back(s);
1043 Templelist *tl = Templelist::getInstance();
1044 for (Templelist::iterator it = tl->begin(); it != tl->end(); it++)
1046 if ((*it)->isUnnamed() == true)
1052 s = String::ucompose(ngettext("There is %1 unnamed temple", "There are %1 unnamed temples", count), count);
1053 warnings.push_back(s);
1057 Stacklist *sl = Playerlist::getInstance()->getNeutral()->getStacklist();
1058 for (Stacklist::iterator it = sl->begin(); it != sl->end(); it++)
1060 if (Citylist::getInstance()->getObjectAt((*it)->getPos()) == NULL)
1066 s = String::ucompose(ngettext("There is %1 neutral stack not in a city", "There are %1 neutral stacks not in cities", count), count);
1067 warnings.push_back(s);
1071 if (GameMap::getInstance()->checkCityAccessibility() == false)
1072 errors.push_back(_("Not all cities are reachable by a non-flying unit."));
1074 if (errors.size() == 0)
1079 void GameScenario::initialize(GameParameters g)
1081 setupFog(g.hidden_map);
1082 setupCities(g.quick_start);
1083 setupStacks(g.hidden_map);
1084 setupRewards(g.hidden_map);
1085 setupDiplomacy(g.diplomacy);
1087 Playerlist::getInstance()->randomizeOrder();
1089 if (d_playmode == GameScenario::NETWORKED)
1090 Playerlist::getInstance()->turnHumansIntoNetworkPlayers();
1093 GameMap::getInstance()->updateStackPositions();
1095 if (d_name == "AutoGenerated")
1097 if (GameMap::getInstance()->checkCityAccessibility() == false)
1105 ParamLoader(std::string filename, bool &broken) {
1106 Tar_Helper t(filename, std::ios::in);
1107 std::string tmpfile = t.getFirstFile(broken);
1108 XML_Helper helper(tmpfile, std::ios::in, Configuration::s_zipfiles);
1109 helper.registerTag(GameMap::d_tag,
1110 sigc::mem_fun(this, &ParamLoader::loadParam));
1111 helper.registerTag(GameScenario::d_tag,
1112 sigc::mem_fun(this, &ParamLoader::loadParam));
1113 helper.registerTag(Playerlist::d_tag,
1114 sigc::mem_fun(this, &ParamLoader::loadParam));
1115 helper.registerTag(Player::d_tag,
1116 sigc::mem_fun(this, &ParamLoader::loadParam));
1117 bool retval = helper.parse();
1118 File::erase(tmpfile);
1119 if (broken == false)
1123 bool loadParam(std::string tag, XML_Helper* helper)
1125 if (tag == Playerlist::d_tag)
1127 helper->getData(d_neutral, "neutral");
1130 if (tag == Player::d_tag)
1135 GameParameters::Player p;
1136 helper->getData(id, "id");
1138 helper->getData(type, "type");
1139 switch (Player::Type(type))
1142 p.type = GameParameters::Player::HUMAN;
1144 case Player::AI_FAST:
1145 p.type = GameParameters::Player::EASY;
1147 case Player::AI_DUMMY:
1148 p.type = GameParameters::Player::EASY;
1150 case Player::AI_SMART:
1151 p.type = GameParameters::Player::HARD;
1153 case Player::NETWORKED:
1154 p.type = GameParameters::Player::HUMAN;
1157 helper->getData(name, "name");
1159 if (p.id != d_neutral) //is not neutral
1160 game_params.players.push_back(p);
1164 helper->getData(armyset_id, "armyset");
1165 Armysetlist *al = Armysetlist::getInstance();
1166 Armyset *armyset = al->getArmyset(armyset_id);
1167 game_params.army_theme = armyset->getSubDir();
1172 if (tag == GameMap::d_tag)
1174 helper->getData(game_params.shield_theme, "shieldset");
1175 helper->getData(game_params.tile_theme, "tileset");
1176 helper->getData(game_params.city_theme, "cityset");
1179 if (tag == GameScenario::d_tag)
1181 helper->getData(game_params.see_opponents_stacks,
1183 helper->getData(game_params.see_opponents_production,
1185 std::string quest_policy_str;
1186 helper->getData(quest_policy_str, "quests");
1187 game_params.play_with_quests =
1188 Configuration::questPolicyFromString(quest_policy_str);
1189 helper->getData(game_params.hidden_map, "hidden_map");
1190 helper->getData(game_params.diplomacy, "diplomacy");
1191 helper->getData(game_params.cusp_of_war, "cusp_of_war");
1192 std::string neutral_cities_str;
1193 helper->getData(neutral_cities_str, "neutral_cities");
1194 game_params.neutral_cities =
1195 Configuration::neutralCitiesFromString(neutral_cities_str);
1196 std::string razing_cities_str;
1197 helper->getData(razing_cities_str, "razing_cities");
1198 game_params.razing_cities =
1199 Configuration::razingCitiesFromString(razing_cities_str);
1200 helper->getData(game_params.intense_combat,
1202 helper->getData(game_params.military_advisor,
1203 "military_advisor");
1204 helper->getData(game_params.random_turns, "random_turns");
1209 GameParameters game_params;
1212 GameParameters GameScenario::loadGameParameters(std::string filename, bool &broken)
1214 ParamLoader loader(filename, broken);
1216 return loader.game_params;
1219 class PlayModeLoader
1222 PlayModeLoader(std::string filename, bool broken) {
1223 play_mode = GameScenario::HOTSEAT;
1224 Tar_Helper t(filename, std::ios::in);
1225 std::string file = File::get_basename(filename, true);
1226 std::string tmpfile = t.getFirstFile(broken);
1227 XML_Helper helper(tmpfile, std::ios::in, Configuration::s_zipfiles);
1228 helper.registerTag(GameScenario::d_tag,
1229 sigc::mem_fun(this, &PlayModeLoader::loadParam));
1230 bool retval = helper.parse();
1231 File::erase(tmpfile);
1232 if (broken == false)
1236 bool loadParam(std::string tag, XML_Helper* helper)
1238 if (tag == GameScenario::d_tag)
1240 std::string playmode_str;
1241 helper->getData(playmode_str, "playmode");
1242 play_mode = GameScenario::playModeFromString(playmode_str);
1247 GameScenario::PlayMode play_mode;
1250 GameScenario::PlayMode GameScenario::loadPlayMode(std::string filename, bool &broken)
1252 PlayModeLoader loader(filename, broken);
1253 return loader.play_mode;
1259 DetailsLoader(std::string filename, bool &broken) {
1260 player_count = 0; city_count = 0; name = ""; comment = "";
1261 Tar_Helper t(filename, std::ios::in);
1262 std::string tmpfile = t.getFirstFile(broken);
1263 XML_Helper helper(tmpfile, std::ios::in, Configuration::s_zipfiles);
1264 helper.registerTag(GameScenario::d_tag,
1265 sigc::mem_fun(this, &DetailsLoader::loadDetails));
1266 helper.registerTag(Player::d_tag,
1267 sigc::mem_fun(this, &DetailsLoader::loadDetails));
1268 helper.registerTag(City::d_tag,
1269 sigc::mem_fun(this, &DetailsLoader::loadDetails));
1270 bool retval = helper.parse();
1273 File::erase(tmpfile);
1276 bool loadDetails(std::string tag, XML_Helper* helper)
1278 if (tag == GameScenario::d_tag)
1280 helper->getData(name, "name");
1281 helper->getData(comment, "comment");
1284 if (tag == Player::d_tag)
1289 if (tag == City::d_tag)
1297 std::string name, comment;
1298 guint32 player_count, city_count;
1300 void GameScenario::loadDetails(std::string filename, bool &broken, guint32 &player_count, guint32 &city_count, std::string &name, std::string &comment)
1302 DetailsLoader loader(filename, broken);
1303 if (broken == false)
1305 player_count = loader.player_count;
1306 city_count = loader.city_count;
1308 comment = loader.comment;