1 // Copyright (C) 2003, 2004, 2005, 2006 Ulf Lorenz
2 // Copyright (C) 2003 Michael Bartl
3 // Copyright (C) 2004 John Farrell
4 // Copyright (C) 2004, 2005, 2006 Andrea Paternesi
5 // Copyright (C) 2006, 2007, 2008, 2009 Ben Asselstine
6 // Copyright (C) 2007 Ole Laursen
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 3 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Library General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24 #include <sigc++/functors/mem_fun.h>
26 #include "CreateScenario.h"
27 #include "GameScenario.h"
32 #include "playerlist.h"
33 #include "stacklist.h"
38 #include "rewardlist.h"
40 #include "templelist.h"
42 #include "signpostlist.h"
46 #include "bridgelist.h"
50 #include "armysetlist.h"
51 #include "citysetlist.h"
52 #include "real_player.h"
57 #include "MapGenerator.h"
58 #include "QuestsManager.h"
59 #include "Configuration.h"
65 #define debug(x) {cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<endl<<flush;}
68 CreateScenario::CreateScenario(int width, int height)
69 :d_scenario(0), d_generator(0)
71 debug("CreateScenario::CreateScenario")
73 //make sure that objects are deleted
74 GameMap::deleteInstance();
75 Playerlist::deleteInstance();
76 Templelist::deleteInstance();
77 Ruinlist::deleteInstance();
78 Rewardlist::deleteInstance();
79 Portlist::deleteInstance();
80 Bridgelist::deleteInstance();
81 Citylist::deleteInstance();
82 Itemlist::deleteInstance();
84 QuestsManager::deleteInstance();
86 fl_counter = new FL_Counter();
91 d_generator = new MapGenerator();
92 d_generator->progress.connect (sigc::mem_fun(*this, &CreateScenario::on_progress));
95 CreateScenario::~CreateScenario()
97 debug("CreateScenario::~CreateScenario")
106 void CreateScenario::on_progress(double percent, std::string description)
111 void CreateScenario::setPercentages(int pgrass, int pwater, int pforest,
112 int pswamp, int phills, int pmountains)
114 debug("CreateScenario::setPercentages")
116 //handle input with !=100% sum
117 int sum = pgrass + pwater + pforest + pswamp +phills + pmountains;
121 double factor = 100 / static_cast<double>(sum);
123 pwater = static_cast<int>(pwater * factor);
124 pforest = static_cast<int>(pforest * factor);
125 pswamp = static_cast<int>(pswamp * factor);
126 phills = static_cast<int>(phills * factor);
127 pmountains = static_cast<int>(pmountains * factor);
130 //the multiplication doesn't round up, so the figures should be OK now, the
131 //missing percentage is implicitely added to the grass part.
132 d_generator->setPercentages(pwater, pforest, pswamp, phills, pmountains);
135 void CreateScenario::setMapTiles(std::string tilesname)
137 debug("CreateScenario::setMapTiles")
138 d_tilesname = tilesname;
141 void CreateScenario::setShieldset(std::string shieldset)
143 debug("CreateScenario::setShieldset")
144 d_shieldsname = shieldset;
147 void CreateScenario::setCityset(std::string citysetname)
149 debug("CreateScenario::setCityset")
150 d_citysetname = citysetname;
151 d_generator->setCityset(Citysetlist::getInstance()->getCityset(citysetname));
154 void CreateScenario::setNoCities(int nocities)
156 debug("CreateScenario::setNoCities")
158 d_generator->setNoCities(nocities);
161 void CreateScenario::setNoRuins(int noruins)
163 debug("CreateScenario::setNoRuins")
165 d_generator->setNoRuins(noruins);
168 void CreateScenario::setNoSignposts (int nosignposts)
170 debug("CreateScenario::setNoSignposts")
172 d_generator->setNoSignposts(nosignposts);
175 void CreateScenario::setNoTemples(int notemples)
177 debug("CreateScenario::setNoTemples")
179 d_generator->setNoTemples(notemples);
182 void CreateScenario::setWidth(int width)
184 debug("CreateScenario::setWidth")
188 std::cerr << "CreateScenario:: wrong width given\n";
195 GameMap::setWidth(width);
197 void CreateScenario::setHeight(int height)
199 debug("CreateScenario::setHeight")
203 std::cerr << "CreateScenario:: wrong height given\n";
210 GameMap::setHeight(height);
213 Player* CreateScenario::addPlayer(std::string name, guint32 armyset,
214 Gdk::Color color, int type)
216 debug("CreateScenario::addPlayer")
218 Player* p = Player::create(name, armyset, color, d_width, d_height,
220 Playerlist::getInstance()->add(p);
225 bool CreateScenario::addNeutral(std::string name, guint32 armyset,
226 Gdk::Color color, int type)
228 // for consistency, we only allow exactly one neutral player
229 if (Playerlist::getInstance()->getNeutral() != 0)
232 Player* p = addPlayer(name, armyset, color, Player::Type(type));
233 Playerlist::getInstance()->setNeutral(p);
237 int CreateScenario::getNoPlayers() const
239 return Playerlist::getInstance()->size();
242 Player* CreateScenario::getPlayer(int number) const
244 debug("CreateScenario::getPlayer")
246 if (number >= static_cast<int>(Playerlist::getInstance()->size()))
249 Playerlist::iterator it;
250 for (it = Playerlist::getInstance()->begin(); number > 0; number--)
256 int CreateScenario::getNoCities() const
261 return d_generator->getNoCities();
264 int CreateScenario::getNoRuins() const
269 return d_generator->getNoRuins();
272 int CreateScenario::getNoTemples() const
277 return d_generator->getNoTemples();
280 bool CreateScenario::create(const GameParameters &g)
282 debug("CreateScenario::create")
284 d_scenario = new GameScenario("AutoGenerated", "AutoGenerated", d_turnmode);
286 GameScenario::s_see_opponents_stacks = g.see_opponents_stacks;
287 GameScenario::s_see_opponents_production = g.see_opponents_production;
288 GameScenario::s_play_with_quests = g.play_with_quests;
289 GameScenario::s_hidden_map = g.hidden_map;
290 GameScenario::s_diplomacy = g.diplomacy;
291 GameScenario::s_cusp_of_war = g.cusp_of_war;
292 GameScenario::s_neutral_cities = g.neutral_cities;
293 GameScenario::s_razing_cities = g.razing_cities;
294 GameScenario::s_military_advisor= g.military_advisor;
295 GameScenario::s_random_turns = g.random_turns;
296 GameScenario::s_intense_combat = g.intense_combat;
302 if (GameScenario::s_hidden_map)
304 Playerlist::iterator pit = Playerlist::getInstance()->begin();
305 for (; pit != Playerlist::getInstance()->end(); pit++)
306 (*pit)->getFogMap()->fill(FogMap::CLOSED);
313 int no_guardian_factor;
314 int stronghold_factor;
316 getRuinDifficulty (g.difficulty, &sage_factor, &no_guardian_factor,
318 if (!setupRuins(GameScenario::s_play_with_quests != GameParameters::NO_QUESTING, 20, 10, 6))
322 getBaseGold (g.difficulty, &base_gold);
323 if (!setupPlayers(g.random_turns, base_gold))
335 if (!distributePlayers())
338 int number_of_armies_factor;
339 getCityDifficulty(g.difficulty, &number_of_armies_factor);
340 if (!setupCities(g.cities_can_produce_allies, number_of_armies_factor))
344 getSignpostDifficulty (g.difficulty, g.hidden_map, &signpost_ratio);
345 if (!setupSignposts(signpost_ratio))
351 bool CreateScenario::dump(std::string filename) const
353 debug("CreateScenario::dump")
356 return d_scenario->saveGame(filename, "map");
361 bool CreateScenario::createMap()
363 debug("CreateScenario::createMap")
365 const Maptile::Building* map;
367 Rewardlist::getInstance();
369 //have the generator make the map...
370 d_generator->makeMap(d_width, d_height, true);
372 //...fill the terrain...
373 GameMap::getInstance(d_tilesname, d_shieldsname,
374 d_citysetname)->fill(d_generator);
376 //...and create cities, temples, ruins ,signposts
377 map = d_generator->getBuildings(d_width, d_height);
378 Cityset *cityset = Citysetlist::getInstance()->getCityset(d_citysetname);
380 for (int y = 0; y < d_height; y++)
381 for (int x = 0; x < d_width; x++)
383 switch (map[y*d_width + x])
385 case Maptile::SIGNPOST:
386 Signpostlist::getInstance()->add(new Signpost(Vector<int>(x,y)));
388 case Maptile::TEMPLE:
389 Templelist::getInstance()->add
390 (new Temple(Vector<int>(x,y),
391 cityset->getTempleTileWidth(),
392 popRandomTempleName()));
395 Ruinlist::getInstance()->add
396 (new Ruin(Vector<int>(x,y),
397 cityset->getRuinTileWidth(),
398 popRandomRuinName()));
401 Citylist::getInstance()->add
402 (new City(Vector<int>(x,y), cityset->getCityTileWidth()));
405 Roadlist::getInstance()->add(new Road(Vector<int>(x,y)));
408 Portlist::getInstance()->add(new Port(Vector<int>(x,y)));
410 case Maptile::BRIDGE:
411 Bridgelist::getInstance()->add(new Bridge(Vector<int>(x,y)));
417 //the other details such as giving names are done later
422 void CreateScenario::createCapitalCity(Player *player, City *city)
424 // distribute capitals for the players
425 city->conquer(player);
426 city->setCapitalOwner(player);
427 city->setCapital(true);
429 History_CityWon *item = new History_CityWon();
430 item->fillData(city);
431 player->addHistory(item);
434 bool CreateScenario::tooNearToOtherCapitalCities(City *c, std::list<City*> capitals, guint32 distance)
436 for (std::list<City*>::iterator it = capitals.begin(); it != capitals.end();
439 int d = dist(c->getPos(), (*it)->getPos());
440 if ((guint32) d < distance)
446 bool CreateScenario::distributePlayers()
448 debug("CreateScenario::distributePlayers")
450 Citylist* cl = Citylist::getInstance();
451 const Playerlist* pl = Playerlist::getInstance();
453 //okay, everyone starts out as neutral.
454 for (Citylist::iterator cit = cl->begin(); cit != cl->end(); cit++)
457 if (c->isBurnt() == false)
458 c->setOwner(pl->getNeutral());
461 std::list<City*> capitals;
462 //now pick some equidistant cities for capitals, that aren't too close.
463 for (Playerlist::const_iterator pit = pl->begin(); pit != pl->end(); pit++)
466 if (*pit == pl->getNeutral())
470 Vector<int> pos = Vector<int>(rand() % d_width, rand() % d_height);
471 City *city = Citylist::getInstance()->getNearestCity(pos);
472 if (city->isBurnt() == false && city->isCapital() == false)
474 if (tooNearToOtherCapitalCities(city, capitals, 30) == false ||
477 createCapitalCity(*pit, city);
478 capitals.push_back(city);
494 bool CreateScenario::setupCities(bool cities_can_produce_allies,
495 int number_of_armies_factor)
497 debug("CreateScenario::setupCities")
499 for (Citylist::iterator it = Citylist::getInstance()->begin();
500 it != Citylist::getInstance()->end(); it++)
503 //1. set a reasonable cityname
504 c->setName(popRandomCityName());
506 //2. distribute the income a bit (TBD)
508 //3. set the city production
509 c->setRandomArmytypes(cities_can_produce_allies,
510 number_of_armies_factor);
512 c->setGold(getRandomCityIncome(c->isCapital()));
519 bool CreateScenario::setupRoads()
521 Roadlist* rl = Roadlist::getInstance();
522 for (Roadlist::iterator it = rl->begin(); it != rl->end(); it++)
523 (*it)->setType(calculateRoadType((*it)->getPos()));
527 bool CreateScenario::setupBridges()
529 Bridgelist* bl = Bridgelist::getInstance();
530 for (Bridgelist::iterator it = bl->begin(); it != bl->end(); it++)
531 (*it)->setType(Bridgelist::getInstance()->calculateType((*it)->getPos()));
535 bool CreateScenario::setupTemples()
537 Templelist* tl = Templelist::getInstance();
538 for (Templelist::iterator it = tl->begin(); it != tl->end(); it++)
540 // set a random temple type
541 int type= (int) ((TEMPLE_TYPES*1.0) * (rand() / (RAND_MAX + 1.0)));
542 (*it)->setType(type);
548 bool CreateScenario::setupRuins(bool strongholds_invisible, int sage_factor,
549 int no_guardian_factor, int stronghold_factor)
551 debug("CreateScenario::setupRuins")
553 //The aim of this function is to put a strong stack as sentinel in all
556 for (Ruinlist::iterator it = Ruinlist::getInstance()->begin();
557 it != Ruinlist::getInstance()->end(); it++)
559 // set a random ruin type
560 if (rand() % stronghold_factor == 0) //one in six ruins is a stronghold
562 (*it)->setType(Ruin::STRONGHOLD);
563 if (strongholds_invisible == true)
565 (*it)->setHidden(true);
566 (*it)->setOwner(NULL);
570 (*it)->setType(Ruin::RUIN);
572 //one in twenty ruins is a sage
573 if (rand() % sage_factor == 0 && (*it)->getType() == Ruin::RUIN)
575 (*it)->setSage (true);
580 //one in ten ruins doesn't have a guardian
581 if (rand() % no_guardian_factor == 0 && (*it)->getType() == Ruin::RUIN)
584 // and set a guardian
587 Vector<int> pos = (*it)->getPos();
589 a = getRandomRuinKeeper(Playerlist::getInstance()->getNeutral());
593 s = new Stack(0, pos);
598 //now mark this stack as guard
599 (*it)->setOccupant(s);
606 bool CreateScenario::setupSignposts(int ratio)
609 int dynamicPercent = static_cast<int>(1.0 / ratio * 100);
610 debug("CreateScenario::setupSignposts")
611 Signpostlist *sl = Signpostlist::getInstance();
613 for (Signpostlist::iterator it = sl->begin(); it != sl->end(); it++)
615 if (randomSignpostsEmpty())
616 randno = dynamicPercent;
618 randno = rand() % 100;
619 if (randno < dynamicPercent)
621 // set up a signpost from the list of signposts
622 (*it)->setName(popRandomSignpost());
626 (*it)->setName(getDynamicSignpost(*it));
633 bool CreateScenario::setupPlayers(bool random_turns,
636 debug("CreateScenario::setupPlayers")
638 Playerlist *pl = Playerlist::getInstance();
640 // Give players some gold to start with
641 for (Playerlist::iterator pit = pl->begin(); pit != pl->end(); pit++)
642 (*pit)->setGold(adjustBaseGold(base_gold));
646 pl->randomizeOrder();
650 bool CreateScenario::setupItems()
652 Itemlist::createStandardInstance();
656 void CreateScenario::getRuinDifficulty (int difficulty, int *sage_factor,
657 int *no_guardian_factor,
658 int *stronghold_factor)
663 *no_guardian_factor = 5;
664 *stronghold_factor = 12;
666 else if (difficulty < 60)
669 *no_guardian_factor = 6;
670 *stronghold_factor = 10;
672 else if (difficulty < 70)
675 *no_guardian_factor = 8;
676 *stronghold_factor = 9;
678 else if (difficulty < 80)
681 *no_guardian_factor = 10;
682 *stronghold_factor = 6;
684 else if (difficulty < 90)
687 *no_guardian_factor = 12;
688 *stronghold_factor = 4;
693 *no_guardian_factor = 15;
694 *stronghold_factor = 3;
698 void CreateScenario::getSignpostDifficulty (int difficulty, bool hidden_map,
701 //the idea here is that we're on a hidden map, and if it's harder
702 //difficulty, then we don't get as many signs directing us to cities.
706 *signpost_ratio = 2; //50% of signs point to cities
707 else if (difficulty < 70)
708 *signpost_ratio = 3; //33% of signs point to cities
709 else if (difficulty < 80)
710 *signpost_ratio = 6; //16% of signs point to cities
711 else if (difficulty < 90)
712 *signpost_ratio = 9; //11% of signs point to cities
714 *signpost_ratio = 15; //6% of signs point to cities
721 void CreateScenario::getCityDifficulty(int difficulty,
722 int *number_of_armies_factor)
725 *number_of_armies_factor = 3;
726 else if (difficulty < 60)
727 *number_of_armies_factor = 2;
728 else if (difficulty < 70)
729 *number_of_armies_factor = 1;
731 *number_of_armies_factor = 0;
734 int CreateScenario::calculateRoadType (Vector<int> t)
736 Roadlist *rl = Roadlist::getInstance();
737 Bridgelist *bl = Bridgelist::getInstance();
739 // examine neighbour tiles to discover whether there's a road or
742 bool b = false; //bottom
743 bool l = false; //left
744 bool r = false; //right
747 u = rl->getObjectAt(t + Vector<int>(0, -1));
748 if (t.y < GameMap::getHeight() - 1)
749 b = rl->getObjectAt(t + Vector<int>(0, 1));
751 l = rl->getObjectAt(t + Vector<int>(-1, 0));
752 if (t.x < GameMap::getWidth() - 1)
753 r = rl->getObjectAt(t + Vector<int>(1, 0));
756 u = bl->getObjectAt(t + Vector<int>(0, -1));
757 if (!b && t.y < GameMap::getHeight() - 1)
758 b = bl->getObjectAt(t + Vector<int>(0, 1));
760 l = bl->getObjectAt(t + Vector<int>(-1, 0));
761 if (!r && t.x < GameMap::getWidth() - 1)
762 r = bl->getObjectAt(t + Vector<int>(1, 0));
764 // then translate this to the type
766 //show road type 2 when no other road tiles are around
767 if (!u && !b && !l && !r)
769 else if (u && b && l && r)
771 else if (!u && b && l && r)
773 else if (u && !b && l && r)
775 else if (u && b && !l && r)
777 else if (u && b && l && !r)
779 else if (u && b && !l && !r)
781 else if (!u && !b && l && r)
783 else if (u && !b && l && !r)
785 else if (u && !b && !l && r)
787 else if (!u && b && l && !r)
789 else if (!u && b && !l && r)
791 else if (u && !b && !l && !r)
792 type = Road::CONNECTS_NORTH;
793 else if (!u && b && !l && !r)
794 type = Road::CONNECTS_SOUTH;
795 else if (!u && !b && l && !r)
796 type = Road::CONNECTS_WEST;
797 else if (!u && !b && !l && r)
798 type = Road::CONNECTS_EAST;
802 int CreateScenario::calculateNumberOfSignposts(int width, int height, int grass)
804 int area = width * height;
805 return int(area * (grass / 100.0) * SIGNPOST_FREQUENCY);