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, 2010, 2012, 2014, 2015, 2017,
6 // 2020 Ben Asselstine
7 // Copyright (C) 2007 Ole Laursen
8 //
9 //  This program is free software; you can redistribute it and/or modify
10 //  it under the terms of the GNU General Public License as published by
11 //  the Free Software Foundation; either version 3 of the License, or
12 //  (at your option) any later version.
13 //
14 //  This program is distributed in the hope that it will be useful,
15 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 //  GNU Library General Public License for more details.
18 //
19 //  You should have received a copy of the GNU General Public License
20 //  along with this program; if not, write to the Free Software
21 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 //  02110-1301, USA.
23 
24 #include <iostream>
25 #include <sstream>
26 #include <sigc++/functors/mem_fun.h>
27 
28 #include "CreateScenario.h"
29 #include "GameScenario.h"
30 #include "army.h"
31 #include "GameMap.h"
32 #include "counter.h"
33 #include "player.h"
34 #include "playerlist.h"
35 #include "stacklist.h"
36 #include "citylist.h"
37 #include "city.h"
38 #include "ruinlist.h"
39 #include "ruin.h"
40 #include "SightMap.h"
41 #include "rewardlist.h"
42 #include "Itemlist.h"
43 #include "templelist.h"
44 #include "temple.h"
45 #include "signpostlist.h"
46 #include "signpost.h"
47 #include "portlist.h"
48 #include "port.h"
49 #include "bridgelist.h"
50 #include "bridge.h"
51 #include "roadlist.h"
52 #include "road.h"
53 #include "stonelist.h"
54 #include "stone.h"
55 #include "armysetlist.h"
56 #include "citysetlist.h"
57 #include "tilesetlist.h"
58 #include "shieldsetlist.h"
59 #include "real_player.h"
60 #include "AI_Analysis.h"
61 #include "AI_Diplomacy.h"
62 #include "ai_fast.h"
63 #include "ai_smart.h"
64 #include "ai_dummy.h"
65 #include "File.h"
66 #include "MapGenerator.h"
67 #include "QuestsManager.h"
68 #include "Configuration.h"
69 #include "FogMap.h"
70 #include "history.h"
71 #include "game-parameters.h"
72 #include "rnd.h"
73 #include "keeper.h"
74 
75 //#define debug(x) {std::cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<std::endl<<std::flush;}
76 #define debug(x)
77 
CreateScenario(int width,int height)78 CreateScenario::CreateScenario(int width, int height)
79     :d_scenario(0), d_generator(0)
80 {
81     debug("CreateScenario::CreateScenario")
82 
83     //make sure that objects are deleted
84     GameMap::deleteInstance();
85     Playerlist::deleteInstance();
86     Templelist::deleteInstance();
87     Ruinlist::deleteInstance();
88     Rewardlist::deleteInstance();
89     Portlist::deleteInstance();
90     Bridgelist::deleteInstance();
91     Citylist::deleteInstance();
92     Itemlist::deleteInstance();
93 
94     QuestsManager::deleteInstance();
95 
96     fl_counter = new FL_Counter();
97 
98     setWidth(width);
99     setHeight(height);
100 
101     d_generator = new MapGenerator();
102     d_generator->progress.connect
103       (sigc::hide(sigc::mem_fun(*this, &CreateScenario::on_progress)));
104 }
105 
~CreateScenario()106 CreateScenario::~CreateScenario()
107 {
108     debug("CreateScenario::~CreateScenario")
109 
110     if (d_generator)
111         delete d_generator;
112 
113     if (d_scenario)
114         delete d_scenario;
115     cleanup();
116 }
117 
on_progress()118 void CreateScenario::on_progress()
119 {
120   progress.emit();
121 }
122 
setPercentages(int pgrass,int pwater,int pforest,int pswamp,int phills,int pmountains)123 void CreateScenario::setPercentages(int pgrass, int pwater, int pforest,
124                                     int pswamp, int phills, int pmountains)
125 {
126     debug("CreateScenario::setPercentages")
127 
128     //handle input with !=100% sum
129     int sum = pgrass + pwater + pforest + pswamp +phills + pmountains;
130 
131     if (sum != 100)
132     {
133         double factor = 100 / static_cast<double>(sum);
134 
135         pwater = static_cast<int>(pwater * factor);
136         pforest = static_cast<int>(pforest * factor);
137         pswamp = static_cast<int>(pswamp * factor);
138         phills = static_cast<int>(phills * factor);
139         pmountains = static_cast<int>(pmountains * factor);
140     }
141 
142     //the multiplication doesn't round up, so the figures should be OK now, the
143     //missing percentage is implicitely added to the grass part.
144     d_generator->setPercentages(pwater, pforest, pswamp, phills, pmountains);
145 }
146 
setMapTiles(Glib::ustring tilesname)147 void CreateScenario::setMapTiles(Glib::ustring tilesname)
148 {
149     debug("CreateScenario::setMapTiles")
150     d_tilesname = tilesname;
151     GameMap::getInstance()->setTileset(tilesname);
152 }
153 
setShieldset(Glib::ustring shieldset)154 void CreateScenario::setShieldset(Glib::ustring shieldset)
155 {
156     debug("CreateScenario::setShieldset")
157     d_shieldsname = shieldset;
158     GameMap::getInstance()->setShieldset(shieldset);
159 }
160 
setCityset(Glib::ustring citysetname)161 void CreateScenario::setCityset(Glib::ustring citysetname)
162 {
163     debug("CreateScenario::setCityset")
164     d_citysetname = citysetname;
165     Cityset *cs = Citysetlist::getInstance()->get(citysetname);
166     d_generator->setCityset(cs);
167     GameMap::getInstance()->setCityset(citysetname);
168 }
169 
setNoCities(int nocities)170 void CreateScenario::setNoCities(int nocities)
171 {
172     debug("CreateScenario::setNoCities")
173 
174     d_generator->setNoCities(nocities);
175 }
176 
setNoRuins(int noruins)177 void CreateScenario::setNoRuins(int noruins)
178 {
179     debug("CreateScenario::setNoRuins")
180 
181     d_generator->setNoRuins(noruins);
182 }
183 
setNoSignposts(int nosignposts)184 void CreateScenario::setNoSignposts (int nosignposts)
185 {
186     debug("CreateScenario::setNoSignposts")
187 
188     d_generator->setNoSignposts(nosignposts);
189 }
190 
setNoStones(int nostones)191 void CreateScenario::setNoStones (int nostones)
192 {
193     debug("CreateScenario::setNoStones")
194 
195     d_generator->setNoStones(nostones);
196 }
197 
setNoTemples(int notemples)198 void CreateScenario::setNoTemples(int notemples)
199 {
200     debug("CreateScenario::setNoTemples")
201 
202     d_generator->setNoTemples(notemples);
203 }
204 
setWidth(int width)205 void CreateScenario::setWidth(int width)
206 {
207     debug("CreateScenario::setWidth")
208 
209     if (width < 0)
210     {
211         std::cerr << "CreateScenario:: wrong width given\n";
212         return;
213     }
214 
215     d_width = width;
216 
217     //IMPORTANT!!
218     GameMap::setWidth(width);
219 }
setHeight(int height)220 void CreateScenario::setHeight(int height)
221 {
222     debug("CreateScenario::setHeight")
223 
224     if (height < 0)
225     {
226         std::cerr << "CreateScenario:: wrong height given\n";
227         return;
228     }
229 
230     d_height = height;
231 
232     //IMPORTANT!!
233     GameMap::setHeight(height);
234 }
235 
addPlayer(Glib::ustring name,guint32 armyset,Gdk::RGBA color,int type)236 Player* CreateScenario::addPlayer(Glib::ustring name, guint32 armyset,
237                                 Gdk::RGBA color, int type)
238 {
239     debug("CreateScenario::addPlayer")
240 
241     Player* p = Player::create(name, armyset, color, d_width, d_height,
242 			       Player::Type(type));
243     Playerlist::getInstance()->add(p);
244 
245     return p;
246 }
247 
addNeutral(Glib::ustring name,guint32 armyset,Gdk::RGBA color,int type)248 bool CreateScenario::addNeutral(Glib::ustring name, guint32 armyset,
249                                 Gdk::RGBA color, int type)
250 {
251     // for consistency, we only allow exactly one neutral player
252     if (Playerlist::getInstance()->getNeutral() != 0)
253         return false;
254 
255     Player* p = addPlayer(name, armyset, color, Player::Type(type));
256     Playerlist::getInstance()->setNeutral(p);
257     return true;
258 }
259 
create(const GameParameters & g)260 bool CreateScenario::create(const GameParameters &g)
261 {
262   debug("CreateScenario::create");
263 
264   d_scenario = new GameScenario("AutoGenerated", "AutoGenerated");
265 
266   GameScenario::s_see_opponents_stacks = g.see_opponents_stacks;
267   GameScenario::s_see_opponents_production = g.see_opponents_production;
268   GameScenario::s_play_with_quests = g.play_with_quests;
269   GameScenario::s_vectoring_mode = g.vectoring_mode;
270   GameScenario::s_build_production_mode = g.build_production_mode;
271   GameScenario::s_sacking_mode = g.sacking_mode;
272   GameScenario::s_hidden_map = g.hidden_map;
273   GameScenario::s_diplomacy = g.diplomacy;
274   GameScenario::s_cusp_of_war = g.cusp_of_war;
275   GameScenario::s_neutral_cities = g.neutral_cities;
276   GameScenario::s_razing_cities = g.razing_cities;
277   GameScenario::s_military_advisor= g.military_advisor;
278   GameScenario::s_random_turns = g.random_turns;
279   GameScenario::s_intense_combat = g.intense_combat;
280 
281   if (!createMap())
282     return false;
283 
284   // fog it up
285   if (GameScenario::s_hidden_map)
286     {
287       Playerlist::iterator pit = Playerlist::getInstance()->begin();
288       for (; pit != Playerlist::getInstance()->end(); pit++)
289         (*pit)->getFogMap()->fill(FogMap::CLOSED);
290     }
291 
292   if (!setupTemples())
293     return false;
294 
295   int sage_factor;
296   int no_guardian_factor;
297   int stronghold_factor;
298 
299   getRuinDifficulty (g.difficulty, &sage_factor, &no_guardian_factor,
300                      &stronghold_factor);
301   if (!setupRuins(GameScenario::s_play_with_quests != GameParameters::NO_QUESTING, 20, 10, 6))
302     return false;
303 
304   int base_gold;
305   getBaseGold (g.difficulty, &base_gold);
306   if (!setupPlayers(g.random_turns, base_gold))
307     return false;
308 
309   if (!setupItems())
310     return false;
311 
312   if (!setupRoads())
313     return false;
314 
315   if (!setupBridges())
316     return false;
317 
318   if (!setupStandingStones(d_generator->getRoadStones ()))
319     return false;
320 
321   if (!distributePlayers())
322     return false;
323 
324   int number_of_armies_factor;
325   getCityDifficulty(g.difficulty, &number_of_armies_factor);
326   if (!setupCities(g.cities_can_produce_allies, number_of_armies_factor))
327     return false;
328 
329   int signpost_ratio;
330   getSignpostDifficulty (g.difficulty, g.hidden_map, &signpost_ratio);
331   if (!setupSignposts(signpost_ratio))
332     return false;
333 
334   return true;
335 }
336 
dump(Glib::ustring filename) const337 bool CreateScenario::dump(Glib::ustring filename) const
338 {
339     debug("CreateScenario::dump")
340 
341     if (d_scenario)
342         return d_scenario->dump(filename, "map");
343 
344     return false;
345 }
346 
createMap()347 bool CreateScenario::createMap()
348 {
349     debug("CreateScenario::createMap")
350 
351     const Maptile::Building* map;
352 
353     Rewardlist::getInstance();
354 
355     //have the generator make the map...
356     d_generator->makeMap(d_width, d_height, true);
357 
358     //...fill the terrain...
359     GameMap::getInstance(d_tilesname, d_shieldsname,
360 			 d_citysetname)->fill(d_generator);
361 
362     //...and create cities, temples, ruins ,signposts
363     map = d_generator->getBuildings(d_width, d_height);
364     Cityset *cityset = Citysetlist::getInstance()->get(d_citysetname);
365 
366     for (int y = 0; y < d_height; y++)
367         for (int x = 0; x < d_width; x++)
368         {
369             switch (map[y*d_width + x])
370             {
371                 case Maptile::SIGNPOST:
372                     Signpostlist::getInstance()->add(new Signpost(Vector<int>(x,y)));
373                     break;
374                 case Maptile::TEMPLE:
375                     Templelist::getInstance()->add
376 		      (new Temple(Vector<int>(x,y),
377 				  cityset->getTempleTileWidth(),
378 				  popRandomTempleName()));
379                     break;
380                 case Maptile::RUIN:
381 		    Ruinlist::getInstance()->add
382 		      (new Ruin(Vector<int>(x,y),
383 				cityset->getRuinTileWidth(),
384 				popRandomRuinName()));
385 		    break;
386                 case Maptile::CITY:
387                     Citylist::getInstance()->add
388 		      (new City(Vector<int>(x,y), cityset->getCityTileWidth()));
389                     break;
390                 case Maptile::ROAD:
391                     Roadlist::getInstance()->add(new Road(Vector<int>(x,y)));
392                     break;
393                 case Maptile::PORT:
394                     Portlist::getInstance()->add(new Port(Vector<int>(x,y)));
395                     break;
396                 case Maptile::BRIDGE:
397                     Bridgelist::getInstance()->add(new Bridge(Vector<int>(x,y)));
398                     break;
399                 case Maptile::STONE:
400                     Stonelist::getInstance()->add(new Stone(Vector<int>(x,y)));
401                     break;
402                 case Maptile::NONE:
403 		    break;
404             }
405         }
406     //the other details such as giving names are done later
407 
408     return true;
409 }
410 
createCapitalCity(Player * player,City * city)411 void CreateScenario::createCapitalCity(Player *player, City *city)
412 {
413   // distribute capitals for the players
414   city->conquer(player);
415   city->setCapitalOwner(player);
416   city->setCapital(true);
417 
418   player->conquerCity(city, NULL);
419 }
420 
tooNearToOtherCapitalCities(City * c,std::list<City * > capitals,guint32 distance)421 bool CreateScenario::tooNearToOtherCapitalCities(City *c, std::list<City*> capitals, guint32 distance)
422 {
423   for (std::list<City*>::iterator it = capitals.begin(); it != capitals.end();
424        it++)
425     {
426       int d = dist(c->getPos(), (*it)->getPos());
427       if ((guint32) d < distance)
428 	return true;
429     }
430   return false;
431 }
432 
distributePlayers()433 bool CreateScenario::distributePlayers()
434 {
435   debug("CreateScenario::distributePlayers")
436 
437   //okay, everyone starts out as neutral.
438   for (auto c: *Citylist::getInstance())
439     if (c->isBurnt() == false)
440       c->setOwner(Playerlist::getInstance()->getNeutral());
441 
442   std::list<City*> capitals;
443   //now pick some equidistant cities for capitals, that aren't too close.
444   for (auto pit: *Playerlist::getInstance())
445     {
446       int tries = 0;
447       if (pit == Playerlist::getInstance()->getNeutral())
448         continue;
449       while (1)
450         {
451           Vector<int> pos =
452             Vector<int>(Rnd::rand() % d_width, Rnd::rand() % d_height);
453           City *city = Citylist::getInstance()->getNearestCity(pos);
454           if (city->isBurnt() == false && city->isCapital() == false)
455             {
456               if (tooNearToOtherCapitalCities(city, capitals, 30) == false ||
457                   tries > 50)
458                 {
459                   createCapitalCity(pit, city);
460                   capitals.push_back(city);
461                   break;
462                 }
463               else
464                 tries++;
465             }
466           else
467             tries++;
468           if (tries > 100)
469             break;
470         }
471     }
472 
473   return true;
474 }
475 
setupCities(bool cities_can_produce_allies,int number_of_armies_factor)476 bool CreateScenario::setupCities(bool cities_can_produce_allies,
477 				 int number_of_armies_factor)
478 {
479   debug("CreateScenario::setupCities")
480 
481   for (auto c: *Citylist::getInstance())
482     {
483       //1. set a reasonable cityname
484       c->setName(popRandomCityName());
485 
486       //2. distribute the income a bit (TBD)
487 
488       //3. set the city production
489       c->setRandomArmytypes(cities_can_produce_allies,
490                             number_of_armies_factor);
491 
492       c->setGold(getRandomCityIncome(c->isCapital()));
493     }
494 
495   return true;
496 }
497 
setupRoads()498 bool CreateScenario::setupRoads()
499 {
500   for (auto it: *Roadlist::getInstance())
501     it->setType(calculateRoadType(it->getPos()));
502   return true;
503 }
504 
setupBridges()505 bool CreateScenario::setupBridges()
506 {
507   for (auto it: *Bridgelist::getInstance())
508     it->setType(Bridgelist::getInstance()->calculateType(it->getPos()));
509   return true;
510 }
511 
setupTemples()512 bool CreateScenario::setupTemples()
513 {
514   for (auto it: *Templelist::getInstance())
515     {
516       // set a random temple type
517       int type= (int) ((TEMPLE_TYPES*1.0) * (Rnd::rand() / (RAND_MAX + 1.0)));
518       it->setType(type);
519 
520     }
521   return true;
522 }
523 
setupRuins(bool strongholds_invisible,int sage_factor,int no_guardian_factor,int stronghold_factor)524 bool CreateScenario::setupRuins(bool strongholds_invisible, int sage_factor,
525 				int no_guardian_factor, int stronghold_factor)
526 {
527     debug("CreateScenario::setupRuins")
528 
529     //The aim of this function is to put a strong stack as sentinel in all
530     //ruins.
531 
532     for (Ruinlist::iterator it = Ruinlist::getInstance()->begin();
533         it != Ruinlist::getInstance()->end(); it++)
534     {
535         // set a random ruin type
536         if (Rnd::rand() % stronghold_factor == 0) //one in six ruins is a stronghold
537           {
538             (*it)->setType(Ruin::STRONGHOLD);
539             if (strongholds_invisible == true)
540               {
541                 (*it)->setHidden(true);
542                 (*it)->setOwner(NULL);
543               }
544           }
545         else
546           (*it)->setType(Ruin::RUIN);
547 
548         //one in twenty ruins is a sage
549         if (Rnd::rand() % sage_factor == 0 &&
550            ((*it)->getType() == Ruin::RUIN ||
551             (*it)->getType() == Ruin::STRONGHOLD))
552 
553           {
554             (*it)->setSage (true);
555             continue;
556           }
557 
558         // and set a guardian / occupant / keeper / lone defender, etc
559         // but one in ten ruins doesn't have a guardian
560         if (Rnd::rand() % no_guardian_factor == 0 &&
561             (*it)->getType() == Ruin::RUIN)
562           (*it)->setOccupant (new Keeper (NULL, (*it)->getPos ()));
563         else
564           (*it)->setOccupant (getRandomRuinKeeper ((*it)->getPos ()));
565     }
566 
567     return true;
568 }
569 
setupSignposts(int ratio)570 bool CreateScenario::setupSignposts(int ratio)
571 {
572   int randno;
573   int dynamicPercent = static_cast<int>(1.0 / ratio * 100);
574   debug("CreateScenario::setupSignposts")
575 
576   for (auto it: *Signpostlist::getInstance())
577     {
578       if (randomSignpostsEmpty())
579         randno = dynamicPercent;
580       else
581         randno = Rnd::rand() % 100;
582       if (randno < dynamicPercent) // set up a signpost from the list of signposts
583         it->setName(popRandomSignpost());
584       else
585         it->setName(getDynamicSignpost(it));
586     }
587 
588   return true;
589 }
590 
setupStandingStones(std::vector<Vector<int>> road_stones)591 bool CreateScenario::setupStandingStones(std::vector<Vector<int> > road_stones)
592 {
593   for (auto s : *Stonelist::getInstance ())
594     s->setType (CreateScenario::calculateStoneType(s->getPos ()));
595 
596   for (auto pos : road_stones)
597     {
598       Road *r = Roadlist::getInstance()->getObjectAt (pos);
599       if (r)
600         {
601           int type = CreateScenario::calculateStoneType(r->getPos ());
602           Stonelist::getInstance ()->add (new Stone (pos, type));
603         }
604     }
605   return true;
606 }
607 
608 
setupPlayers(bool random_turns,int base_gold)609 bool CreateScenario::setupPlayers(bool random_turns,
610 				  int base_gold)
611 {
612   debug("CreateScenario::setupPlayers");
613   for (auto pit: *Playerlist::getInstance())
614     pit->setGold(adjustBaseGold(base_gold));
615 
616 
617   if (random_turns)
618     Playerlist::getInstance()->randomizeOrder();
619   return true;
620 }
621 
setupItems()622 bool CreateScenario::setupItems()
623 {
624   Itemlist::createStandardInstance();
625   return true;
626 }
627 
getRuinDifficulty(int difficulty,int * sage_factor,int * no_guardian_factor,int * stronghold_factor)628 void CreateScenario::getRuinDifficulty (int difficulty, int *sage_factor,
629 					int *no_guardian_factor,
630 					int *stronghold_factor)
631 {
632   if (difficulty < 50)
633     {
634       *sage_factor = 3;
635       *no_guardian_factor = 5;
636       *stronghold_factor = 12;
637     }
638   else if (difficulty < 60)
639     {
640       *sage_factor = 9;
641       *no_guardian_factor = 6;
642       *stronghold_factor = 10;
643     }
644   else if (difficulty < 70)
645     {
646       *sage_factor = 14;
647       *no_guardian_factor = 8;
648       *stronghold_factor = 9;
649     }
650   else if (difficulty < 80)
651     {
652       *sage_factor = 20;
653       *no_guardian_factor = 10;
654       *stronghold_factor = 6;
655     }
656   else if (difficulty < 90)
657     {
658       *sage_factor = 22;
659       *no_guardian_factor = 12;
660       *stronghold_factor = 4;
661     }
662   else
663     {
664       *sage_factor = 24;
665       *no_guardian_factor = 15;
666       *stronghold_factor = 3;
667     }
668 }
669 
getSignpostDifficulty(int difficulty,bool hidden_map,int * signpost_ratio)670 void CreateScenario::getSignpostDifficulty (int difficulty, bool hidden_map,
671 					    int *signpost_ratio)
672 {
673   //the idea here is that we're on a hidden map, and if it's harder
674   //difficulty, then we don't get as many signs directing us to cities.
675   if (hidden_map)
676     {
677       if (difficulty < 60)
678 	*signpost_ratio = 2; //50% of signs point to cities
679       else if (difficulty < 70)
680 	*signpost_ratio = 3; //33% of signs point to cities
681       else if (difficulty < 80)
682 	*signpost_ratio = 6; //16% of signs point to cities
683       else if (difficulty < 90)
684 	*signpost_ratio = 9; //11% of signs point to cities
685       else
686 	*signpost_ratio = 15; //6% of signs point to cities
687     }
688   else
689     *signpost_ratio = 6;
690 }
691 
getCityDifficulty(int difficulty,int * number_of_armies_factor)692 void CreateScenario::getCityDifficulty(int difficulty,
693 				       int *number_of_armies_factor)
694 {
695   if (difficulty < 50)
696     *number_of_armies_factor = 3;
697   else if (difficulty < 60)
698     *number_of_armies_factor = 2;
699   else if (difficulty < 70)
700     *number_of_armies_factor = 1;
701   else
702     *number_of_armies_factor = 0;
703 }
704 
calculateStoneType(Vector<int> t)705 int CreateScenario::calculateStoneType (Vector<int> t)
706 {
707   Road *r = Roadlist::getInstance()->getObjectAt(t);
708   if (r)
709     return Stone::getRandomType(Road::Type(r->getType()));
710   else
711     return Stone::getRandomType();
712 }
713 
calculateBridgeType(Vector<int> t)714 int CreateScenario::calculateBridgeType (Vector<int> t)
715 {
716   return Bridgelist::getInstance()->calculateType(t);
717 }
718 
calculateRoadType(Vector<int> t)719 int CreateScenario::calculateRoadType (Vector<int> t)
720 {
721     // examine neighbour tiles to discover whether there's a road or
722     // bridge on them
723     bool u = false; //up
724     bool b = false; //bottom
725     bool l = false; //left
726     bool r = false; //right
727 
728     if (t.y > 0)
729       u = Roadlist::getInstance()->getObjectAt(t + Vector<int>(0, -1));
730     if (t.y < GameMap::getHeight() - 1)
731       b = Roadlist::getInstance()->getObjectAt(t + Vector<int>(0, 1));
732     if (t.x > 0)
733       l = Roadlist::getInstance()->getObjectAt(t + Vector<int>(-1, 0));
734     if (t.x < GameMap::getWidth() - 1)
735       r = Roadlist::getInstance()->getObjectAt(t + Vector<int>(1, 0));
736 
737     if (!u && t.y > 0)
738       u = Bridgelist::getInstance()->getObjectAt(t + Vector<int>(0, -1));
739     if (!b && t.y < GameMap::getHeight() - 1)
740       b = Bridgelist::getInstance()->getObjectAt(t + Vector<int>(0, 1));
741     if (!l && t.x > 0)
742       l = Bridgelist::getInstance()->getObjectAt(t + Vector<int>(-1, 0));
743     if (!r && t.x < GameMap::getWidth() - 1)
744       r = Bridgelist::getInstance()->getObjectAt(t + Vector<int>(1, 0));
745 
746     // then translate this to the type
747     int type = 2;
748     //show road type 2 when no other road tiles are around
749     if (!u && !b && !l && !r)
750 	type = 2;
751     else if (u && b && l && r)
752 	type = 2;
753     else if (!u && b && l && r)
754 	type = 9;
755     else if (u && !b && l && r)
756 	type = 8;
757     else if (u && b && !l && r)
758 	type = 7;
759     else if (u && b && l && !r)
760 	type = 10;
761     else if (u && b && !l && !r)
762 	type = 1;
763     else if (!u && !b && l && r)
764 	type = 0;
765     else if (u && !b && l && !r)
766 	type = 3;
767     else if (u && !b && !l && r)
768 	type = 4;
769     else if (!u && b && l && !r)
770 	type = 6;
771     else if (!u && b && !l && r)
772 	type = 5;
773     else if (u && !b && !l && !r)
774 	type = Road::CONNECTS_NORTH;
775     else if (!u && b && !l && !r)
776 	type = Road::CONNECTS_SOUTH;
777     else if (!u && !b && l && !r)
778 	type = Road::CONNECTS_WEST;
779     else if (!u && !b && !l && r)
780 	type = Road::CONNECTS_EAST;
781     return type;
782 }
783 
calculateNumberOfSignposts(int width,int height,int grass)784 int CreateScenario::calculateNumberOfSignposts(int width, int height, int grass)
785 {
786   int area = width * height;
787   return int(area * (grass / 100.0) * SIGNPOST_FREQUENCY);
788 }
789 
updateRoadsBridgesAndStones()790 void CreateScenario::updateRoadsBridgesAndStones()
791 {
792   for (auto i : *Roadlist::getInstance ())
793     i->setType(CreateScenario::calculateRoadType(i->getPos()));
794   for (auto i : *Bridgelist::getInstance ())
795     i->setType(CreateScenario::calculateBridgeType(i->getPos()));
796   for (auto i : *Stonelist::getInstance ())
797     i->setType(CreateScenario::calculateStoneType(i->getPos()));
798 }
799 
800