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