initial commit, lordsawar source, slightly modified
[lordsawar] / src / GameMap.cpp
1 // Copyright (C) 2003 Michael Bartl
2 // Copyright (C) 2003, 2004, 2005, 2006 Ulf Lorenz
3 // Copyright (C) 2003, 2005, 2006 Andrea Paternesi
4 // Copyright (C) 2006, 2007, 2008, 2009 Ben Asselstine
5 // Copyright (C) 2007 Ole Laursen
6 // Copyright (C) 2008 Janek Kozicki
7 //
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.
12 //
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.
17 //
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 
21 //  02110-1301, USA.
22
23 #include <sstream>
24 #include <iostream>
25 #include <iomanip>
26 #include <assert.h>
27 #include <sigc++/functors/mem_fun.h>
28 #include <string.h>
29
30 #include "ucompose.hpp"
31 #include "GameMap.h"
32 #include "citylist.h"
33 #include "bridgelist.h"
34 #include "bridge.h"
35 #include "portlist.h"
36 #include "port.h"
37 #include "roadlist.h"
38 #include "road.h"
39 #include "city.h"
40 #include "ruin.h"
41 #include "temple.h"
42 #include "playerlist.h"
43 #include "stacklist.h"
44 #include "ruinlist.h"
45 #include "templelist.h"
46 #include "signpostlist.h"
47 #include "xmlhelper.h"
48 #include "MapGenerator.h"
49 #include "tilesetlist.h"
50 #include "shieldsetlist.h"
51 #include "citysetlist.h"
52 #include "GraphicsCache.h"
53 #include "MapBackpack.h"
54 #include "stacktile.h"
55 #include "armyprodbase.h"
56 #include "stack.h"
57 #include "armyset.h"
58 #include "armysetlist.h"
59 #include "CreateScenario.h"
60
61 std::string GameMap::d_tag = "map";
62 std::string GameMap::d_itemstack_tag = "itemstack";
63 using namespace std;
64
65 //#define debug(x) {std::cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<std::endl<<flush;}
66 #define debug(x)
67
68 GameMap* GameMap::s_instance = 0;
69
70 int GameMap::s_width = 112;
71 int GameMap::s_height = 112;
72
73 GameMap* GameMap::getInstance()
74 {
75     if (s_instance != 0)
76       return s_instance;
77     else return 0;
78 }
79
80
81 GameMap* GameMap::getInstance(std::string TilesetName, 
82                               std::string ShieldsetName, 
83                               std::string CitysetName)
84 {
85     if (s_instance == 0)
86     {
87         s_instance = new GameMap(TilesetName, ShieldsetName, CitysetName);
88
89     }
90     return s_instance;
91 }
92
93 GameMap* GameMap::getInstance(XML_Helper* helper)
94 {
95     if (s_instance)
96         deleteInstance();
97
98     s_instance = new GameMap(helper);
99
100     return s_instance;
101 }
102
103 void GameMap::deleteInstance()
104 {
105     if (s_instance)
106         delete s_instance;
107     s_instance = 0;
108 }
109
110 GameMap::GameMap(std::string TilesetName, std::string ShieldsetName,
111                  std::string CitysetName)
112 {
113     d_tileSet = Tilesetlist::getInstance()->getTileset(TilesetName);
114     d_shieldSet = Shieldsetlist::getInstance()->getShieldset(ShieldsetName);
115     d_citySet = Citysetlist::getInstance()->getCityset(CitysetName);
116
117     Vector<int>::setMaximumWidth(s_width);
118     d_map = new Maptile*[s_width*s_height];
119     for (int j = 0; j < s_height; j++)
120         for (int i = 0; i < s_width; i++)
121             d_map[j*s_width + i] = 0;
122
123 }
124
125 bool GameMap::offmap(int x, int y)
126 {
127   if (y<0||y>=GameMap::s_height||x<0||x>=GameMap::s_width)
128     return true;
129   return false;
130 }
131
132 void GameMap::processStyles(std::string styles, int chars_per_style)
133 {
134   int c = chars_per_style;
135     int offset = 0;
136     for (int j = 0; j < s_height; j++)
137     {
138         // remove newline and carriage return lines
139         char test = styles[j*s_width*c + offset];
140         while (test == '\n' || test == '\r')
141         {
142             offset++;
143             test = styles[j*s_width*c + offset];
144         }
145
146         for (int i = 0; i < s_width; i++)
147         {
148             char hexstr[15];
149             //due to the circumstances, styles is a long stream of
150             //hex digit pairs, so read it character for character
151             hexstr[0] = '0';
152             hexstr[1] = 'x';
153             memcpy (&hexstr[2], &styles[j*s_width*c + (i * c) + offset], c);
154             hexstr[2 + c + 1 - 1] = '\0';
155
156             unsigned long int val = 0;
157             char *end = NULL;
158             val = strtoul (hexstr, &end, 16);
159             guint32 id = (guint32) val;
160             TileStyle *style = d_tileSet->getTileStyle(id);
161             if (!style)
162               style = d_tileSet->getTileStyle(0);
163             d_map[j*s_width + i]->setTileStyle(style);
164         }
165     }
166 }
167     
168 int GameMap::determineCharsPerStyle(std::string styles)
169 {
170   return styles.length() / (s_width * s_height);
171 }
172
173 GameMap::GameMap(XML_Helper* helper)
174 {
175     std::string types;
176     std::string styles;
177     std::string t_dir;
178     std::string s_dir;
179     std::string c_dir;
180
181     helper->getData(s_width, "width");
182     helper->getData(s_height, "height");
183     helper->getData(t_dir,"tileset");
184     helper->getData(s_dir,"shieldset");
185     helper->getData(c_dir,"cityset");
186     helper->getData(types, "types");
187     helper->getData(styles, "styles");
188
189     d_tileSet = Tilesetlist::getInstance()->getTileset(t_dir);
190     d_shieldSet = Shieldsetlist::getInstance()->getShieldset(s_dir);
191     d_citySet = Citysetlist::getInstance()->getCityset(c_dir);
192
193     Vector<int>::setMaximumWidth(s_width);
194     //create the map
195     d_map = new Maptile*[s_width*s_height];
196
197     int offset = 0;
198     for (int j = 0; j < s_height; j++)
199     {
200         // remove newline and carriage return lines
201         char test = types[j*s_width + offset];
202         while (test == '\n' || test == '\r')
203         {
204             offset++;
205             test = types[j*s_width + offset];
206         }
207
208         for (int i = 0; i < s_width; i++)
209         {
210             //due to the circumstances, types is a long stream of
211             //numbers, so read it character for character (no \n's or so)
212             char type = types[j*s_width + i + offset];  
213
214             //the chars now hold the ascii representation of the numbers, which
215             //we don't want
216             type -= '0';
217             d_map[j*s_width + i] = new Maptile(d_tileSet, i, j, type, NULL);
218         }
219     }
220
221     int chars_per_style = determineCharsPerStyle(styles);
222     processStyles(styles, chars_per_style);
223
224     //add some callbacks for item loading
225     helper->registerTag(GameMap::d_itemstack_tag, 
226                         sigc::mem_fun(this, &GameMap::loadItems));
227     helper->registerTag(Item::d_tag, sigc::mem_fun(this, &GameMap::loadItems));
228 }
229
230
231 GameMap::~GameMap()
232 {
233     //delete d_tileSet;
234
235     for (int i = 0; i < s_width; i++)
236     {
237         for (int j = 0; j < s_height; j++)
238         {
239             if (d_map[j*s_width + i])
240                 delete d_map[j*s_width + i];
241         }
242     }
243
244     delete[] d_map;
245 }
246
247 bool GameMap::fill(MapGenerator* generator)
248 //basically, this does the same as the former random function, but you don't
249 //need to go the whole way via dumping the map in a file etc.
250 {
251     int width;
252     int height;
253     const Tile::Type* terrain = generator->getMap(width, height);
254
255
256     //the sizes should definitely match, else we have a problem here
257     if (width != s_width || height != s_height)
258     {
259         std::cerr << "Error in GameMap::fillMap: sizes don't match!! Exiting.\n";
260         exit(-1);
261     }
262
263     // create tiles; there is a hack here: The map generator outputs tile types,
264     // but we supply the index of the tile types in the tileset to Maptile. Was
265     // the easiest version when rewriting this.
266     for (int j = 0; j < height; j++)
267         for (int i = 0; i < width; i++)
268         {
269             int index = d_tileSet->getIndex(terrain[j*width + i]);
270             if (index != -1)
271               d_map[j*s_width + i] = new Maptile(d_tileSet, i, j, 
272                                                  (guint32)index, NULL);
273         }
274
275     applyTileStyles(0, 0, height, width, true);
276     return true;
277 }
278
279 bool GameMap::fill(guint32 type)
280 {
281     for (int i = 0; i < s_width; i++)
282         for (int j = 0; j < s_height; j++)
283           {
284             d_map[j*s_width + i] = new Maptile(d_tileSet, i, j, type, NULL);
285           }
286
287     applyTileStyles(0, 0, s_height, s_width, false);
288     return true;
289 }
290
291 bool GameMap::save(XML_Helper* helper) const
292 {
293     bool retval = true;
294
295     std::stringstream types;
296
297     types <<endl;
298     for (int i = 0; i < s_height; i++)
299     {
300         for (int j = 0; j < s_width; j++)
301             types << getTile(j, i)->getType();
302         types <<endl;
303     }
304
305     std::stringstream styles;
306     styles <<endl;
307             
308     int largest_style_id = d_tileSet->getLargestTileStyleId();
309     for (int i = 0; i < s_height; i++)
310     {
311         for (int j = 0; j < s_width; j++)
312           {
313             Glib::ustring hexstr;
314             TileStyle *style = getTile(j, i)->getTileStyle();
315             assert (style != NULL);
316             if (largest_style_id < 256)
317               hexstr = String::ucompose ("%1", Glib::ustring::format(std::hex, std::setfill(L'0'), std::setw(2), style->getId()));
318             else if (largest_style_id < 4096)
319               hexstr = String::ucompose ("%1", Glib::ustring::format(std::hex, std::setfill(L'0'), std::setw(3), style->getId()));
320             else if (largest_style_id < 65536)
321               hexstr = String::ucompose ("%1", Glib::ustring::format(std::hex, std::setfill(L'0'), std::setw(4), style->getId()));
322
323             styles << hexstr;
324           }
325         styles <<endl;
326     }
327
328
329     retval &= helper->openTag(GameMap::d_tag);
330     retval &= helper->saveData("width", s_width);
331     retval &= helper->saveData("height", s_height);
332     retval &= helper->saveData("tileset", d_tileSet->getSubDir());
333     retval &= helper->saveData("shieldset", d_shieldSet->getSubDir());
334     retval &= helper->saveData("cityset", d_citySet->getSubDir());
335     retval &= helper->saveData("types", types.str());
336     retval &= helper->saveData("styles", styles.str());
337
338     // last, save all items lying around somewhere
339     for (int i = 0; i < s_width; i++)
340       for (int j = 0; j < s_height; j++)
341         if (!getTile(i,j)->getBackpack()->empty())
342           retval &= getTile(i,j)->getBackpack()->save(helper);
343      
344     retval &= helper->closeTag();
345     return retval;
346 }
347
348 bool GameMap::loadItems(std::string tag, XML_Helper* helper)
349 {
350     static int x = 0;
351     static int y = 0;
352     
353     if (tag == GameMap::d_itemstack_tag)
354     {
355         helper->getData(x, "x");
356         helper->getData(y, "y");
357     }
358
359     if (tag == Item::d_tag)
360     {
361         Item* item = new Item(helper);
362         getTile(x, y)->getBackpack()->addToBackpack(item);
363     }
364
365     return true;
366 }
367
368 void GameMap::setTile(int x, int y, Maptile *tile)
369 {
370     delete d_map[y*s_width + x];
371     d_map[y*s_width + x] = tile;
372     applyTileStyle (y, x);
373 }
374
375 Maptile* GameMap::getTile(int x, int y) const
376 {
377     assert(x >= 0 && x < s_width && y >= 0 && y < s_height);
378
379     return d_map[y*s_width + x];
380 }
381
382 Stack* GameMap::addArmy(Vector<int> pos, Army *a)
383 {
384   City *c = getCity(pos);
385   if (c)
386     {
387       if (c->isBurnt())
388         return addArmyAtPos(pos, a);
389       else
390         return addArmy(c, a);
391     }
392   Temple *t = getTemple(pos);
393   if (t)
394     return addArmy(t, a);
395   Ruin *r = getRuin(pos);
396   if (r)
397     return addArmy(r, a);
398   return addArmyAtPos(pos, a);
399 }
400
401 Stack* GameMap::addArmyAtPos(Vector<int> pos, Army *a)
402 {
403   Stack *s = NULL;
404   bool added_army = false;
405   guint32 i, j;
406   guint32 d;
407   guint32 max;
408   int x, y;
409   if (s_height > s_width)
410     max = s_height;
411   else
412     max = s_width;
413   max--;
414
415   Location l(pos, 1);
416   s = l.addArmy(a);
417   if (s)
418     return s;
419
420   // we couldn't add the army to the square(s) identified by location,
421   // so the idea is to go around in ever widening boxes until we find a
422   // suitable tile.
423
424   bool land = true;
425   if (getTile(pos.x, pos.y)->getType() == Tile::WATER)
426     land = false;
427
428   //d is the distance from Pos where our box starts
429   for (d = 1; d < max; d++)
430     {
431       for (i = 0; i < (d * 2) + 1; i++)
432         {
433           for (j = 0; j < (d * 2) + 1; j++)
434             {
435               if ((i == 0 || i == (d * 2) + 1) && 
436                   (j == 0 || j == (d * 2) + 1))
437                 {
438                   x = pos.x + (i - d);
439                   y = pos.y + (j - d);
440                   if (x < 0 || y < 0)
441                     continue;
442                   if (offmap(x, y))
443                     continue;
444                   //is there somebody else's city here?
445                   City *c = getCity(Vector<int>(x, y));
446                   if (c && c->getOwner() != a->getOwner())
447                     {
448                       if (c->isBurnt() == false)
449                         continue;
450                     }
451                   //is this an unsuitable tile?
452                   if (land && getTile(x, y)->getType() == Tile::WATER)
453                     continue;
454                   if (!land && getTile(x, y)->getType() != Tile::WATER)
455                     continue;
456                   if (land && getTile(x, y)->getType() == Tile::VOID)
457                     continue;
458                   if (land && getTile(x, y)->getType() == Tile::MOUNTAIN &&
459                       (a->getStat(Army::MOVE_BONUS) & Tile::MOUNTAIN) == 0)
460                     continue;
461                   //do we already have a nifty stack here?
462                   s = getFriendlyStack(Vector<int>(x,y));
463                   if (s)
464                     {
465                       if (canAddArmy(Vector<int>(x,y)) == false)
466                         continue;
467                       //is our stack too full?
468                       s->add(a);
469                     }
470                   else 
471                     {
472                       Vector<int> pos(x, y);
473                       //hmm. no nifty stacks here.  anybody else's?
474                       s = getEnemyStack(pos);
475                       if (s)
476                         continue;
477                       //okay, no stacks here at all.  make one.
478                       s = new Stack(a->getOwner(), pos);
479                       s->add(a);
480                       a->getOwner()->addStack(s);
481                     }
482                   added_army = true;
483                   break;
484                 }
485             }
486           if (added_army)
487             break;
488         }
489       if (added_army)
490         break;
491     }
492
493   if (added_army)
494     {
495       s->setDefending(false);
496       s->setParked(false);
497       return s;
498     }
499   else
500     return NULL;
501 }
502
503 Stack* GameMap::addArmy(Location *l, Army *a)
504 {
505   Stack *s;
506   s = l->addArmy(a);
507   if (s)
508     return s;
509   return addArmyAtPos(l->getPos(), a);
510 }
511
512 bool GameMap::isDock(Vector<int> pos)
513 {
514   if (getBuilding(pos) == Maptile::CITY)
515     return true;
516   if (getBuilding(pos) == Maptile::PORT)
517     return true;
518   if (getBuilding(pos) == Maptile::BRIDGE)
519     return true;
520   return false;
521 }
522
523 bool GameMap::isBlockedAvenue(int x, int y, int destx, int desty)
524 {
525   if (offmap(destx, desty))
526     return true;
527   if (Citylist::getInstance()->empty())
528       return false;
529   int diffx = destx - x;
530   int diffy = desty - y;
531   if (diffx >= -1 && diffx <= 1 && diffy >= -1 && diffy <= 1)
532     {
533       assert (Citylist::getInstance()->size());
534       bool from_dock = isDock(Vector<int>(x,y));
535       bool to_dock = isDock(Vector<int>(destx,desty));
536       Maptile *from = getTile(x, y);
537       Maptile *to = getTile(destx, desty);
538       if (from == to)
539         return false;
540       //am i on land, going towards water that has a port on it?
541       //if (from->getMaptileType() != Tile::WATER &&
542           //to->getMaptileType() == Tile::WATER &&
543           //to_dock)
544         //return false;
545       //am i on water going towards land from a port?
546       //if (from->getMaptileType() == Tile::WATER &&
547           //to->getMaptileType() != Tile::WATER &&
548           //from_dock)
549         //return false;
550
551       //am i on water going towards land that isn't a city,
552       //and i'm not coming from a port
553       if (from->getMaptileType() == Tile::WATER &&
554           to->getMaptileType() != Tile::WATER &&
555           !to_dock && !from_dock)
556         return true;
557
558       //am i on land, going towards water from a tile that isn't a
559       //city, or a port and i'm not going to a port?
560       if (from->getMaptileType() != Tile::WATER &&
561           to->getMaptileType() == Tile::WATER &&
562           !from_dock && !to_dock)
563         return true;
564
565       //is the tile i'm going to a mountain that doesn't have a road?
566       if (to->getMaptileType() == Tile::MOUNTAIN &&
567           getRoad(Vector<int>(destx, desty)) == NULL)
568         return true;
569
570       //am i on a mountain without a road?
571       if (from->getMaptileType() == Tile::MOUNTAIN &&
572           getRoad(Vector<int>(x, y)) == NULL)
573         return true;
574
575       if (from->getMaptileType() == Tile::VOID)
576         return true;
577       if (to->getMaptileType() == Tile::VOID)
578         return true;
579     }
580  return false;
581 }
582
583 void GameMap::calculateBlockedAvenue(int i, int j)
584 {
585   int diffx = 0, diffy = 0;
586   int destx = 0, desty = 0;
587   Maptile *maptile = getTile(i, j);
588   for (int k = 0; k < 8; k++)
589     {
590       switch (k)
591         {
592         case 0: diffx = -1;  diffy = -1; break;
593         case 1: diffx = -1; diffy = 0; break;
594         case 2: diffx = -1; diffy = 1; break;
595         case 3: diffx = 0; diffy = 1; break;
596         case 4: diffx = 0; diffy = -1; break;
597         case 5: diffx = 1; diffy = -1; break;
598         case 6: diffx = 1; diffy = 0; break;
599         case 7: diffx = 1; diffy = 1; break;
600         }
601       destx = i + diffx;
602       desty = j + diffy;
603       if (offmap (destx, desty))
604         {
605           maptile->d_blocked[k] = true;
606           continue;
607         }
608       maptile->d_blocked[k] = isBlockedAvenue(i, j, destx, desty);
609     }
610 }
611 void GameMap::calculateBlockedAvenues()
612 {
613   for (int i = 0; i < s_width; i++)
614     for (int j = 0; j < s_height; j++)
615       calculateBlockedAvenue(i, j);
616 }
617
618 Vector<int> GameMap::findStack(guint32 id)
619 {
620     bool found = false;
621     Vector<int> pos = Vector<int>(-1,-1);
622     for (int x = 0; x < getWidth(); x++)
623       {
624         for (int y = 0; y < getHeight(); y++)
625           {
626             StackTile *stile = getTile(x,y)->getStacks();
627             if (stile->contains(id) == true)
628               {
629                 pos = Vector<int>(x,y);
630                 found = true;
631                 break;
632               }
633           }
634       }
635   return pos;
636 }
637
638 Vector<int> GameMap::findPlantedStandard(Player *p)
639 {
640     bool found = false;
641     Vector<int> pos;
642     pos.x = -1;
643     pos.y = -1;
644     for (int x = 0; x < getWidth(); x++)
645       {
646         for (int y = 0; y < getHeight(); y++)
647           {
648             MapBackpack *backpack = getTile(x, y)->getBackpack();
649             found = backpack->getPlantedItem(p) != NULL;
650             if (found)
651               {
652                 pos.x = x;
653                 pos.y = y;
654                 break;
655               }
656           }
657       }
658   return pos;
659 }
660
661 TileStyle *GameMap::calculatePreferredStyle(int i, int j)
662 {
663   Tileset *tileset = getTileset();
664   Maptile *mtile = getTile(j, i);
665   int box[3][3];
666   for (int k = -1; k <= +1; k++)
667     for (int l = -1; l <= +1; l++)
668       {
669         box[k+1][l+1] = 1;
670         if (offmap(j+l, i+k))
671           continue;
672         box[k+1][l+1] = are_those_tiles_similar(getTile(j+l, i+k)->getMaptileType(), mtile->getMaptileType(), false);
673       }
674   if (box[0][0] && box[0][1] && box[0][2] &&
675       box[1][0] && box[1][1] && box[1][2] &&
676       box[2][0] && box[2][1] && box[2][2])
677     return tileset->getRandomTileStyle(mtile->getType(), 
678                                        TileStyle::INNERMIDDLECENTER);
679   else if (box[0][0] && box[0][1] && !box[0][2] && 
680            box[1][0] && box[1][1] && box[1][2] &&
681            !box[2][0] && box[2][1] && box[2][2])
682     return tileset->getRandomTileStyle(mtile->getType(), 
683                                        TileStyle::TOPLEFTTOBOTTOMRIGHTDIAGONAL);
684   else if (!box[0][0] && box[0][1] && box[0][2] && 
685            box[1][0] && box[1][1] && box[1][2] &&
686            box[2][0] && box[2][1] && !box[2][2])
687     return tileset->getRandomTileStyle(mtile->getType(), 
688                                        TileStyle::BOTTOMLEFTTOTOPRIGHTDIAGONAL);
689   else if (/*box[0][0] &&*/ !box[0][1] && /*box[0][2] &&*/
690            !box[1][0] && box[1][1] && box[1][2] &&
691            /*!box[2][0] &&*/ box[2][1] && box[2][2])
692     return tileset->getRandomTileStyle(mtile->getType(), 
693                                        TileStyle::OUTERTOPLEFT);
694   else if (/*box[0][0] &&*/ !box[0][1] && /*box[0][2] &&*/
695            box[1][0] && box[1][1] && !box[1][2] &&
696            box[2][0] && box[2][1] /*&& !box[2][2] */)
697     return tileset->getRandomTileStyle(mtile->getType(), 
698                                        TileStyle::OUTERTOPRIGHT);
699   else if (/*box[0][0] &&*/ box[0][1] && box[0][2] &&
700            !box[1][0] && box[1][1] && box[1][2] &&
701            /*box[2][0] &&*/ !box[2][1] /*&& box[2][2]*/)
702     return tileset->getRandomTileStyle(mtile->getType(), 
703                                        TileStyle::OUTERBOTTOMLEFT);
704   else if (box[0][0] && box[0][1] && /*!box[0][2] &&*/
705            box[1][0] && box[1][1] && !box[1][2] && 
706            /*box[2][0] &&*/ !box[2][1] /*&& box[2][2]*/)
707     return tileset->getRandomTileStyle(mtile->getType(), 
708                                        TileStyle::OUTERBOTTOMRIGHT);
709   else if (/*box[0][0] &&*/ box[0][1] && /*box[0][2] && */
710            !box[1][0] && box[1][1] && box[1][2] &&
711            /*box[2][0] &&*/ box[2][1] /*&& box[2][2]*/)
712     return tileset->getRandomTileStyle(mtile->getType(), 
713                                        TileStyle::OUTERMIDDLELEFT);
714   else if (/*box[0][0] &&*/ box[0][1] && /*box[0][2] && */
715            box[1][0] && box[1][1] && !box[1][2] &&
716            /*box[2][0] &&*/ box[2][1] /*&& box[2][2] */)
717     return tileset->getRandomTileStyle(mtile->getType(), 
718                                        TileStyle::OUTERMIDDLERIGHT);
719   else if (box[0][0] && box[0][1] && /*box[0][2] && */
720            box[1][0] && box[1][1] && box[1][2] &&
721            box[2][0] && box[2][1] && !box[2][2])
722     return tileset->getRandomTileStyle(mtile->getType(), 
723                                        TileStyle::INNERTOPLEFT);
724   else if (/*box[0][0] &&*/ box[0][1] && box[0][2] && 
725            box[1][0] && box[1][1] && box[1][2] &&
726            !box[2][0] && box[2][1] && box[2][2])
727     return tileset->getRandomTileStyle(mtile->getType(), 
728                                        TileStyle::INNERTOPRIGHT);
729   else if (box[0][0] && box[0][1] && !box[0][2] && 
730            box[1][0] && box[1][1] && box[1][2] &&
731            box[2][0] && box[2][1] /*&& box[2][2]*/)
732     return tileset->getRandomTileStyle(mtile->getType(), 
733                                        TileStyle::INNERBOTTOMLEFT);
734   else if (!box[0][0] && box[0][1] && box[0][2] && 
735            box[1][0] && box[1][1] && box[1][2] &&
736            /*box[2][0] &&*/ box[2][1] && box[2][2])
737     return tileset->getRandomTileStyle(mtile->getType(), 
738                                        TileStyle::INNERBOTTOMRIGHT);
739   else if (/*!box[0][0] &&*/ !box[0][1] && /*!box[0][2] &&*/
740            box[1][0] && box[1][1] && box[1][2] &&
741            /*!box[2][0] &&*/ box[2][1] /*&& box[2][2]*/)
742     return tileset->getRandomTileStyle(mtile->getType(), 
743                                        TileStyle::OUTERTOPCENTER);
744   else if (/*box[0][0] &&*/ box[0][1] && /*box[0][2] &&*/
745            box[1][0] && box[1][1] && box[1][2] &&
746            /*!box[2][0] &&*/ !box[2][1] /*&& !box[2][2]*/)
747     return tileset->getRandomTileStyle(mtile->getType(), 
748                                        TileStyle::OUTERBOTTOMCENTER);
749   return NULL;
750 }
751
752 void GameMap::close_circles (int minx, int miny, int maxx, int maxy)
753 {
754   Tileset *tileset = getTileset();
755   for (int i = minx; i < maxx; i++)
756     {
757       for (int j = miny; j < maxy; j++)
758         {
759           if (offmap(j, i))
760             continue;
761           Maptile *tile = getTile(j, i);
762           TileStyle *tilestyle = tile->getTileStyle();
763           if (j + 1 < s_width)
764             {
765               Maptile *nexttile = getTile(j + 1, i);
766               TileStyle *nextstyle = nexttile->getTileStyle();
767               if (tilestyle->getType() == TileStyle::OUTERTOPCENTER &&
768                   nextstyle->getType() == TileStyle::OUTERBOTTOMCENTER)
769                 {
770                   TileStyle *style;
771                   style = tileset->getRandomTileStyle(tile->getType(),
772                                                       TileStyle::OUTERTOPRIGHT);
773                   tile->setTileStyle(style);
774                   style = tileset->getRandomTileStyle(nexttile->getType(),
775                                                       TileStyle::OUTERBOTTOMLEFT);
776                   nexttile->setTileStyle(style);
777                 }
778               if (tilestyle->getType() == TileStyle::OUTERBOTTOMCENTER &&
779                   nextstyle->getType() == TileStyle::OUTERTOPCENTER)
780                 {
781                   TileStyle *style;
782                   style = tileset->getRandomTileStyle(tile->getType(),
783                                                       TileStyle::OUTERBOTTOMRIGHT);
784                   tile->setTileStyle(style);
785                   style = tileset->getRandomTileStyle(nexttile->getType(),
786                                                       TileStyle::OUTERTOPLEFT);
787                   nexttile->setTileStyle(style);
788                 }
789               }
790           if (i + 1 < s_height)
791             {
792               Maptile *nexttile = getTile(j, i + 1);
793               TileStyle *nextstyle = nexttile->getTileStyle();
794               if (tilestyle->getType() == TileStyle::OUTERMIDDLERIGHT&&
795                   nextstyle->getType() == TileStyle::OUTERMIDDLELEFT)
796                 {
797                   TileStyle *style;
798                   style = tileset->getRandomTileStyle(tile->getType(),
799                                                       TileStyle::OUTERBOTTOMRIGHT);
800                   tile->setTileStyle(style);
801                   style = tileset->getRandomTileStyle(nexttile->getType(),
802                                                       TileStyle::OUTERTOPLEFT);
803                   nexttile->setTileStyle(style);
804                 }
805               if (tilestyle->getType() == TileStyle::OUTERMIDDLELEFT&&
806                   nextstyle->getType() == TileStyle::OUTERMIDDLERIGHT)
807                 {
808                   TileStyle *style;
809                   style = tileset->getRandomTileStyle(tile->getType(),
810                                                       TileStyle::OUTERBOTTOMLEFT);
811                   tile->setTileStyle(style);
812                   style = tileset->getRandomTileStyle(nexttile->getType(),
813                                                       TileStyle::OUTERTOPRIGHT);
814                   nexttile->setTileStyle(style);
815                 }
816               }
817         }
818     }
819 }
820
821 bool GameMap::are_those_tiles_similar(Tile::Type outer_tile,Tile::Type inner_tile, bool checking_loneliness)
822 {
823     if(checking_loneliness || inner_tile == Tile::HILLS)
824     {
825         if( (outer_tile == Tile::MOUNTAIN && inner_tile == Tile::HILLS) ||
826             (inner_tile == Tile::MOUNTAIN && outer_tile == Tile::HILLS))
827             // Mountains and hills are similar, MapGenerator::surroundMountains()
828             // makes sure that mountains are surrounded by hills. So a hill tile
829             // with only a mountain neighbour is not a lone tile
830             //
831             // There never should be a lone mountain in grass (not surrounded by hills).
832             // Mountain surrounded by hills is perfectly correct.
833             return true;
834         return outer_tile == inner_tile;
835     } 
836     else 
837     { // to pick correct tile picture for a mountain we treat hills as a tile
838       // different than mountain.
839         return outer_tile == inner_tile;
840     }
841 }
842
843 int GameMap::tile_is_connected_to_other_like_tiles (Tile::Type tile, int i, int j)
844 {
845   int box[3][3];
846   memset (box, 0, sizeof (box));
847   for (int k = -1; k <= +1; k++)
848     for (int l = -1; l <= +1; l++)
849       {
850         if (offmap(j+l,i+k))
851           continue;
852         box[k+1][l+1] = are_those_tiles_similar(getTile(j+l, i+k)->getMaptileType(), tile, true);
853       }
854   if (box[0][0] && box[0][1] && box[1][0] && box[1][1])
855     return 1;
856   if (box[0][1] && box[0][2] && box[1][1] && box[1][2])
857     return 1;
858   if (box[1][0] && box[1][1] && box[2][0] && box[2][1])
859     return 1;
860   if (box[1][1] && box[1][2] && box[2][1] && box[2][2])
861     return 1;
862   return 0;
863 }
864
865 void GameMap::demote_lone_tile(int minx, int miny, int maxx, int maxy, 
866                                Tile::Type intype, Tile::Type outtype)
867 {
868   int i;
869   int j;
870   for (i = minx; i < maxx; i++)
871     for (j = miny; j < maxy; j++)
872       {
873         if (offmap(j, i))
874           continue;
875         Tile::Type tile = getTile(j, i)->getMaptileType();
876         if (tile == intype)
877           {
878             //if we're not connected in a square of
879             //same types, then we're a lone tile.
880             if (tile_is_connected_to_other_like_tiles(tile, i, j) == 0)
881               {
882                 //okay, this is a lone tile.
883                 //downgrade it
884                 int idx = d_tileSet->getIndex(outtype);
885                 if (idx != -1)
886                   setTile(j, i, new Maptile (d_tileSet, j, i, 
887                                              (guint32)idx, NULL));
888               }
889           }
890       }
891
892 }
893
894 void GameMap::applyTileStyles (Rectangle r, bool smooth_terrain)
895 {
896   applyTileStyles (r.y, r.x, r.y + r.h, r.x + r.w, smooth_terrain);
897 }
898
899 void GameMap::applyTileStyles (int minx, int miny, int maxx, int maxy, 
900                                bool smooth_terrain)
901 {
902
903   if (smooth_terrain)
904     {
905       demote_lone_tile(minx, miny, maxx, maxy, Tile::FOREST, Tile::GRASS);
906       demote_lone_tile(minx, miny, maxx, maxy, Tile::MOUNTAIN, Tile::HILLS);
907       demote_lone_tile(minx, miny, maxx, maxy, Tile::HILLS, Tile::GRASS);
908       demote_lone_tile(minx, miny, maxx, maxy, Tile::WATER, Tile::SWAMP);
909       surroundMountains(minx, miny, maxx, maxy);
910     }
911
912   for (int i = minx; i < maxx; i++)
913     {
914       for (int j = miny; j < maxy; j++)
915         {
916           if (offmap(j, i))
917             continue;
918           applyTileStyle(i, j);
919         }
920     }
921   close_circles(minx, miny, maxx, maxy);
922 }
923
924 std::vector<Vector<int> > GameMap::getItems()
925 {
926   std::vector<Vector<int> > items;
927   for (int j = 0; j < s_height; j++)
928     for (int i = 0; i < s_width; i++)
929       {
930         if (d_map[j*s_width + i])
931           if (d_map[j*s_width + i]->getBackpack()->empty() == false)
932             items.push_back(Vector<int>(i, j));
933
934       }
935   return items;
936 }
937
938
939 void GameMap::surroundMountains(int minx, int miny, int maxx, int maxy)
940 {
941   for(int j = miny; j < maxy; j++)
942     for(int i = minx; i < maxx; i++)
943       {
944         if (offmap(j, i))
945           continue;
946         if(getTile(j, i)->getMaptileType() == Tile::MOUNTAIN)
947           for(int J = -1; J <= +1; ++J)
948             for(int I = -1; I <= +1; ++I)
949               if((!(offmap(j+J,i+I))) &&
950                  (getTile((j+J),(i+I))->getMaptileType() != Tile::MOUNTAIN))
951                 {
952                   int idx = d_tileSet->getIndex(Tile::HILLS);
953                   if(getTile((j+J), (i+I))->getMaptileType() != Tile::WATER)
954                     {
955                       if (idx != -1)
956                         setTile(j+J, i+I, 
957                                 new Maptile (d_tileSet, j+J, i+I, 
958                                              (guint32)idx, NULL));
959                     }
960                   else 
961                     {
962                     // water has priority here, there was some work done to conenct bodies of water
963                     // so don't break those connections.
964                       setTile(j, i, 
965                             new Maptile (d_tileSet, j, i, (guint32)idx, NULL));
966                     }
967                 }
968       }
969 }
970
971 void GameMap::applyTileStyle (int i, int j)
972 {
973   Maptile *mtile = getTile(j, i);
974   Tileset *tileset = getTileset();
975   TileStyle *style = calculatePreferredStyle(i, j);
976   if (!style)
977     style = tileset->getRandomTileStyle(mtile->getType(), 
978                                         TileStyle::LONE);
979   if (!style)
980     style = tileset->getRandomTileStyle(mtile->getType(), 
981                                         TileStyle::INNERMIDDLECENTER);
982   if (!style)
983     printf ("applying null tile style at %d,%d for tile of kind %d\n", i, j,
984             mtile->getMaptileType());
985   mtile->setTileStyle(style);
986 }
987
988 Vector<int> GameMap::findNearestObjectInDir(Vector<int> pos, Vector<int> dir)
989 {
990   std::vector<Vector<int> > objects;
991   Road *road = Roadlist::getInstance()->getNearestObjectInDir(pos, dir);
992   if (road)
993     objects.push_back(road->getPos());
994   Bridge *bridge = Bridgelist::getInstance()->getNearestObjectInDir(pos, dir);
995   if (bridge)
996     objects.push_back(bridge->getPos());
997   City *city = Citylist::getInstance()->getNearestObjectInDir(pos, dir);
998   if (city)
999     objects.push_back(city->getPos());
1000   Temple *temple = Templelist::getInstance()->getNearestObjectInDir(pos, dir);
1001   if (temple)
1002     objects.push_back(temple->getPos());
1003   Ruin *ruin = Ruinlist::getInstance()->getNearestObjectInDir(pos, dir);
1004   if (ruin && ruin->isHidden() == false)
1005     objects.push_back(ruin->getPos());
1006   if (objects.size() == 0)
1007     return Vector<int>(-1,-1);
1008
1009   int min_distance = -1;
1010   Vector<int> closest = Vector<int>(-1,-1);
1011   for (unsigned int i = 0; i < objects.size(); i++)
1012     {
1013       int distance = dist(pos, objects[i]);
1014       if (min_distance == -1 || distance < min_distance)
1015         {
1016           min_distance = distance;
1017           closest = objects[i];
1018         }
1019     }
1020   return closest;
1021 }
1022
1023 Vector<int> GameMap::findNearestObjectToTheNorth(Vector<int> pos)
1024 {
1025   Vector<int> dir = Vector<int>(0, -1);
1026   return findNearestObjectInDir(pos, dir);
1027 }
1028
1029 Vector<int> GameMap::findNearestObjectToTheSouth(Vector<int> pos)
1030 {
1031   Vector<int> dir = Vector<int>(0, 1);
1032   return findNearestObjectInDir(pos, dir);
1033 }
1034
1035 Vector<int> GameMap::findNearestObjectToTheEast(Vector<int> pos)
1036 {
1037   Vector<int> dir = Vector<int>(1, 0);
1038   return findNearestObjectInDir(pos, dir);
1039 }
1040
1041 Vector<int> GameMap::findNearestObjectToTheWest(Vector<int> pos)
1042 {
1043   Vector<int> dir = Vector<int>(-1, 0);
1044   return findNearestObjectInDir(pos, dir);
1045 }
1046 City* GameMap::getCity(Vector<int> pos)
1047 {
1048   return Citylist::getInstance()->getObjectAt(pos);
1049 }
1050 City* GameMap::getEnemyCity(Vector<int> pos)
1051 {
1052   City *c = Citylist::getInstance()->getObjectAt(pos);
1053   if (c && c->getOwner() != Playerlist::getActiveplayer())
1054     return c;
1055   return NULL;
1056 }
1057 Ruin* GameMap::getRuin(Vector<int> pos)
1058 {
1059   return Ruinlist::getInstance()->getObjectAt(pos);
1060 }
1061 Temple* GameMap::getTemple(Vector<int> pos)
1062 {
1063   return Templelist::getInstance()->getObjectAt(pos);
1064 }
1065 Port* GameMap::getPort(Vector<int> pos)
1066 {
1067   return Portlist::getInstance()->getObjectAt(pos);
1068 }
1069 Road* GameMap::getRoad(Vector<int> pos)
1070 {
1071   return Roadlist::getInstance()->getObjectAt(pos);
1072 }
1073 Bridge* GameMap::getBridge(Vector<int> pos)
1074 {
1075   return Bridgelist::getInstance()->getObjectAt(pos);
1076 }
1077 Signpost* GameMap::getSignpost(Vector<int> pos)
1078 {
1079   return Signpostlist::getInstance()->getObjectAt(pos);
1080 }
1081 Stack* GameMap::getFriendlyStack(Vector<int> pos)
1082 {
1083   return getStacks(pos)->getFriendlyStack(Playerlist::getActiveplayer());
1084 }
1085
1086 //StackReflist GameMap::getFriendlyStacks(Vector<int> pos, Player *player)
1087 //{
1088   //if (player == NULL)
1089     //player = Playerlist::getActiveplayer();
1090   //return StackReflist(getStacks(pos)->getFriendlyStacks(player));
1091 //}
1092 std::list<Stack*> GameMap::getFriendlyStacks(Vector<int> pos, Player *player)
1093 {
1094   if (player == NULL)
1095     player = Playerlist::getActiveplayer();
1096   return getStacks(pos)->getFriendlyStacks(player);
1097 }
1098         
1099 Stack* GameMap::getEnemyStack(Vector<int> pos)
1100 {
1101   return getStacks(pos)->getEnemyStack(Playerlist::getActiveplayer());
1102 }
1103         
1104 std::list<Stack*> GameMap::getEnemyStacks(std::list<Vector<int> > positions)
1105 {
1106   std::list<Stack*> enemy_stacks;
1107   std::list<Vector<int> >::iterator it = positions.begin();
1108   for (; it != positions.end(); it++)
1109     {
1110       Stack *enemy = getEnemyStack(*it);
1111       if (enemy)
1112         enemy_stacks.push_back(enemy);
1113     }
1114   return enemy_stacks;
1115 }
1116
1117 std::list<Stack*> GameMap::getEnemyStacks(Vector<int> pos, Player *player)
1118 {
1119   if (player == NULL)
1120     player = Playerlist::getActiveplayer();
1121   return getStacks(pos)->getEnemyStacks(player);
1122 }
1123 Stack* GameMap::getStack(Vector<int> pos)
1124 {
1125   return getStacks(pos)->getStack();
1126 }
1127         
1128 StackTile* GameMap::getStacks(Vector<int> pos)
1129 {
1130   return getInstance()->getTile(pos)->getStacks();
1131 }
1132 Stack *GameMap::groupStacks(Vector<int> pos)
1133 {
1134   return getStacks(pos)->group(Playerlist::getActiveplayer());
1135 }
1136   
1137 void GameMap::groupStacks(Stack *stack)
1138 {
1139   getStacks(stack->getPos())->group(Playerlist::getActiveplayer(), stack);
1140 }
1141   
1142 void GameMap::updateStackPositions()
1143 {
1144   Playerlist *plist = Playerlist::getInstance();
1145   for (Playerlist::iterator i = plist->begin(); i != plist->end(); i++)
1146     {
1147       Stacklist *sl = (*i)->getStacklist();
1148       for (Stacklist::iterator s = sl->begin(); s != sl->end(); s++)
1149         getStacks((*s)->getPos())->add(*s);
1150     }
1151 }
1152
1153 bool GameMap::canJoin(const Stack *src, Vector<int> dest)
1154 {
1155   return getStacks(dest)->canAdd(src);
1156 }
1157 bool GameMap::canJoin(const Stack *src, Stack *dest)
1158 {
1159   return canJoin (src, dest->getPos());
1160 }
1161
1162 bool GameMap::canAddArmy(Vector<int> dest)
1163 {
1164   if (countArmyUnits(dest) < MAX_ARMIES_ON_A_SINGLE_TILE)
1165     return true;
1166   return false;
1167 }
1168 bool GameMap::canAddArmies(Vector<int> dest, guint32 stackSize)
1169 {
1170   if (countArmyUnits(dest) + stackSize <= MAX_ARMIES_ON_A_SINGLE_TILE)
1171     return true;
1172   return false;
1173 }
1174
1175 void GameMap::switchTileset(Tileset *tileset)
1176 {
1177   d_tileSet = tileset;
1178   applyTileStyles (0, 0, s_width, s_height,  false);
1179 }
1180
1181 void GameMap::switchShieldset(Shieldset *shieldset)
1182 {
1183   d_shieldSet = shieldset;
1184 }
1185
1186 void GameMap::switchCityset(Cityset *cityset)
1187 {
1188   d_citySet = cityset;
1189 }
1190
1191 void GameMap::switchArmysets(Armyset *armyset)
1192 {
1193   Playerlist *pl= Playerlist::getInstance();
1194   Ruinlist *rl= Ruinlist::getInstance();
1195   Citylist *cl= Citylist::getInstance();
1196   //change the keepers in ruins
1197   for (Ruinlist::iterator i = rl->begin(); i != rl->end(); i++)
1198     {
1199       Stack *s = (*i)->getOccupant();
1200       if (s == NULL)
1201         continue;
1202       for (Stack::iterator j = s->begin(); j != s->end(); j++)
1203         Armyset::switchArmysetForRuinKeeper(*j, armyset);
1204     }
1205   for (Playerlist::iterator i = pl->begin(); i != pl->end(); i++)
1206     {
1207       Armyset *a = 
1208         Armysetlist::getInstance()->getArmyset((*i)->getArmyset());
1209       if (armyset == a)
1210         continue;
1211
1212       //change the armyprodbases in cities.
1213       for (Citylist::iterator j = cl->begin(); j != cl->end(); j++)
1214         {
1215           City *c = *j;
1216           for (unsigned int k = 0; c->getSize(); k++)
1217             {
1218               ArmyProdBase *prodbase = (*c)[k]->getArmyProdBase();
1219               if (prodbase)
1220                 Armyset::switchArmyset(prodbase, armyset);
1221             }
1222         }
1223
1224       //change the armies in the stacklist
1225       Stacklist *sl = (*i)->getStacklist();
1226       for (Stacklist::iterator j = sl->begin(); j != sl->end(); j++)
1227         {
1228           Stack *s = (*j);
1229           for (Stack::iterator k = s->begin(); k != s->end(); k++)
1230             Armyset::switchArmyset(*k,armyset);
1231         }
1232
1233       //finally, change the player's armyset.
1234       (*i)->setArmyset(armyset->getId());
1235       //where else are armyset ids hanging around?
1236     }
1237 }
1238
1239 bool GameMap::canPutBuilding(Maptile::Building bldg, guint32 size, Vector<int> to, bool making_islands)
1240 {
1241   bool can_move = true;
1242   //gotta have a building to move
1243   if (bldg == Maptile::NONE)
1244     return false;
1245   //there can't be another building in the way.
1246   bool found = false;
1247   for (unsigned int i = 0; i < size; i++)
1248     for (unsigned int j = 0; j < size; j++)
1249       {
1250         Vector<int> pos = to + Vector<int>(i,j);
1251         if (offmap(pos.x, pos.y))
1252           return false;
1253         if (getBuilding(pos) != Maptile::NONE)
1254           found = true;
1255       }
1256   if (found)
1257     return false;
1258   //ok different objects have different rules wrt the kinds of tiles they 
1259   //can be on.
1260   switch (bldg)
1261     {
1262       case Maptile::CITY: 
1263       case Maptile::RUIN: 
1264       case Maptile::TEMPLE: 
1265       case Maptile::SIGNPOST:
1266         //gotta be on grass.
1267           {
1268             if (making_islands)
1269               return true;
1270             for (unsigned int i = 0; i < size; i++)
1271               for (unsigned int j = 0; j < size; j++)
1272                 {
1273                   Vector<int> pos = to + Vector<int>(i, j);
1274                   if (getTerrainType(pos) != Tile::GRASS)
1275                     return false;
1276                 }
1277           }
1278         break;
1279       case Maptile::ROAD: 
1280         //can't be in the water
1281         if (getTerrainType(to) == Tile::WATER ||
1282             getTerrainType(to) == Tile::VOID)
1283           return false;
1284         break;
1285       case Maptile::PORT: 
1286         if (getTerrainType(to) == Tile::WATER &&
1287             getTile(to)->getTileStyle()->getType() != 
1288             TileStyle::INNERMIDDLECENTER)
1289           return can_move;
1290         else
1291           return false;
1292         break;
1293       case Maptile::BRIDGE: 
1294         if (getTerrainType(to) == Tile::WATER &&
1295             (getTile(to)->getTileStyle()->getType() == 
1296              TileStyle::OUTERTOPCENTER || 
1297             getTile(to)->getTileStyle()->getType() == 
1298             TileStyle::OUTERBOTTOMCENTER || 
1299             getTile(to)->getTileStyle()->getType() == 
1300             TileStyle::OUTERMIDDLELEFT || 
1301             getTile(to)->getTileStyle()->getType() == 
1302             TileStyle::OUTERMIDDLERIGHT ))
1303           return can_move;
1304         else
1305           return false;
1306         break;
1307       case Maptile::NONE: break;
1308     }
1309   return can_move;
1310 }
1311
1312 bool GameMap::moveBuilding(Vector<int> from, Vector<int> to)
1313 {
1314   //move a game object located at FROM, and move it to TO.
1315   //watch out for overlaps.
1316   //return true if we moved something.
1317   bool moved = true;
1318     
1319   guint32 size = getBuildingSize(from);
1320   if (size == 0)
1321     return false;
1322
1323   if (canPutBuilding(getBuilding(from), size, to) == false)
1324     {
1325       if (getLocation(from)->contains(to) == false &&
1326           LocationBox(to, size).contains(from) == false)
1327         return false;
1328     }
1329           
1330   switch (getBuilding(from))
1331     {
1332     case Maptile::NONE:
1333       break;
1334     case Maptile::SIGNPOST:
1335         {
1336           Signpost *old_signpost = getSignpost(getSignpost(from)->getPos());
1337           Signpost *new_signpost = new Signpost(*old_signpost, to);
1338           removeSignpost(old_signpost->getPos());
1339           putSignpost(new_signpost);
1340           break;
1341         }
1342     case Maptile::PORT:
1343         {
1344           Port *old_port = getPort(getPort(from)->getPos());
1345           Port *new_port = new Port(*old_port, to);
1346           removePort(old_port->getPos());
1347           putPort(new_port);
1348           break;
1349         }
1350     case Maptile::BRIDGE:
1351         {
1352           Bridge *old_bridge = getBridge(getBridge(from)->getPos());
1353           Bridge *new_bridge = new Bridge(*old_bridge, to);
1354           removeBridge(old_bridge->getPos());
1355           putBridge(new_bridge);
1356           break;
1357         }
1358     case Maptile::ROAD:
1359         {
1360           Road *old_road = getRoad(getRoad(from)->getPos());
1361           Road *new_road = new Road(*old_road, to);
1362           removeRoad(old_road->getPos());
1363           putRoad(new_road);
1364           break;
1365         }
1366     case Maptile::RUIN:
1367         {
1368           Ruin* old_ruin = getRuin(getRuin(from)->getPos());
1369           Ruin *new_ruin = new Ruin(*old_ruin, to);
1370           removeRuin(old_ruin->getPos());
1371           putRuin(new_ruin);
1372           break;
1373         }
1374     case Maptile::TEMPLE:
1375         {
1376           Temple* old_temple = getTemple(getTemple(from)->getPos());
1377           Temple* new_temple = new Temple(*old_temple, to);
1378           removeTemple(old_temple->getPos());
1379           putTemple(new_temple);
1380           break;
1381         }
1382     case Maptile::CITY:
1383         {
1384           City* old_city = getCity(getCity(from)->getPos());
1385           City* new_city = new City(*old_city, to);
1386           removeCity(old_city->getPos());
1387           putCity(new_city);
1388           break;
1389         }
1390     }
1391   return moved;
1392 }
1393
1394 Tile::Type GameMap::getTerrainType(Vector<int> tile)
1395 {
1396   guint32 idx = getTile(tile)->getType();
1397   return (*d_tileSet)[idx]->getType();
1398 }
1399
1400 Maptile::Building GameMap::getBuilding(Vector<int> tile)
1401 {
1402   return getTile(tile)->getBuilding();
1403 }
1404
1405 void GameMap::setBuilding(Vector<int> tile, Maptile::Building building)
1406 {
1407   getTile(tile)->setBuilding(building);
1408 }
1409
1410 guint32 GameMap::getBuildingSize(Vector<int> tile)
1411 {
1412   switch (getTile(tile)->getBuilding())
1413     {
1414     case Maptile::CITY: return getCity(tile)->getSize(); break;
1415     case Maptile::RUIN: return getRuin(tile)->getSize(); break;
1416     case Maptile::TEMPLE: return getTemple(tile)->getSize(); break;
1417     case Maptile::ROAD: return getRoad(tile)->getSize(); break;
1418     case Maptile::BRIDGE: return getBridge(tile)->getSize(); break;
1419     case Maptile::SIGNPOST: return getSignpost(tile)->getSize(); break;
1420     case Maptile::PORT: return getPort(tile)->getSize(); break;
1421     case Maptile::NONE: break;
1422     }
1423
1424   return 0;
1425 }
1426         
1427 bool GameMap::canPutStack(guint32 size, Player *p, Vector<int> to)
1428 {
1429   StackTile *stile = GameMap::getInstance()->getStacks(to);
1430   if (!stile)
1431     return true;
1432   if (stile->canAdd(size, p) == true)
1433     return true;
1434   return false;
1435
1436 }
1437
1438 bool GameMap::moveStack(Stack *stack, Vector<int> to)
1439 {
1440   bool moved = true;
1441   if (stack->getPos() == to)
1442     return true;
1443   if (canPutStack(stack->size(), stack->getOwner(), to) == false)
1444     return false;
1445
1446
1447   getStacks(stack->getPos())->leaving(stack);
1448   stack->setPos(to);
1449   //Stack *new_stack = new Stack(*stack);
1450   //new_stack->setPos(to);
1451   //getStacks(stack->getPos())->leaving(stack);
1452   //delete stack;
1453   //if we dropped it on a city, then change the ownership.
1454   City *c = GameMap::getCity(to);
1455   if (c != NULL && stack->getOwner() != c->getOwner())
1456     Stacklist::changeOwnership(stack, c->getOwner());
1457   getStacks(stack->getPos())->arriving(stack);
1458   bool ship = false;
1459   if (getTerrainType(stack->getPos()) == Tile::WATER &&
1460       getBuilding(stack->getPos()) != Maptile::PORT &&
1461       getBuilding(stack->getPos()) != Maptile::BRIDGE)
1462     ship = true;
1463   updateShips(stack->getPos());
1464
1465   return moved;
1466 }
1467         
1468 MapBackpack *GameMap::getBackpack(Vector<int> pos)
1469 {
1470   return getInstance()->getTile(pos)->getBackpack();
1471 }
1472                     
1473 void GameMap::moveBackpack(Vector<int> from, Vector<int> to)
1474 {
1475   getBackpack(to)->add(getBackpack(from));
1476   getBackpack(from)->clear();
1477 }
1478
1479 bool GameMap::removeRuin(Vector<int> pos)
1480 {
1481   Ruin *r = GameMap::getRuin(pos);
1482   if (r)
1483     {
1484       removeBuilding(r);
1485       Ruinlist::getInstance()->subtract(r);
1486       return true;
1487     }
1488   return false;
1489 }
1490 bool GameMap::putRuin(Ruin *r)
1491 {
1492   Ruinlist::getInstance()->add(r);
1493   putTerrain(r->getArea(), Tile::GRASS);
1494   putBuilding(r, Maptile::RUIN);
1495   return true;
1496 }
1497
1498 bool GameMap::removeTemple(Vector<int> pos)
1499 {
1500   Temple *t = GameMap::getTemple(pos);
1501   if (t)
1502     {
1503       removeBuilding(t);
1504       Templelist::getInstance()->subtract(t);
1505       return true;
1506     }
1507   return false;
1508 }
1509
1510 bool GameMap::putTemple(Temple *t)
1511 {
1512   Templelist::getInstance()->add(t);
1513   putTerrain(t->getArea(), Tile::GRASS);
1514   putBuilding(t, Maptile::TEMPLE);
1515   return true;
1516 }
1517
1518 bool GameMap::removePort(Vector<int> pos)
1519 {
1520   Port *p = GameMap::getPort(pos);
1521   if (p)
1522     {
1523       removeBuilding(p);
1524       Portlist::getInstance()->subtract(p);
1525       return true;
1526     }
1527   return false;
1528 }
1529
1530 bool GameMap::putPort(Port *p)
1531 {
1532   Portlist::getInstance()->add(p);
1533   putBuilding(p, Maptile::PORT);
1534   //is there a stack here?
1535   if (GameMap::getStack(p->getPos()) != NULL)
1536     updateShips(p->getPos());
1537   return true;
1538 }
1539
1540 bool GameMap::removeSignpost(Vector<int> pos)
1541 {
1542   Signpost *s = GameMap::getSignpost(pos);
1543   if (s)
1544     {
1545       removeBuilding(s);
1546       Signpostlist::getInstance()->subtract(s);
1547       return true;
1548     }
1549   return false;
1550 }
1551
1552 bool GameMap::putSignpost(Signpost *s)
1553 {
1554   Signpostlist::getInstance()->add(s);
1555   putTerrain(s->getArea(), Tile::GRASS);
1556   putBuilding(s, Maptile::SIGNPOST);
1557   return true;
1558 }
1559
1560 bool GameMap::removeRoad(Vector<int> pos)
1561 {
1562   Road *r = GameMap::getRoad(pos);
1563   if (r)
1564     {
1565       removeBuilding(r);
1566       Roadlist::getInstance()->subtract(r);
1567       return true;
1568     }
1569   return false;
1570 }
1571
1572 bool GameMap::putRoad(Road *r)
1573 {
1574   Roadlist::getInstance()->add(r);
1575   setBuilding(r->getPos(), Maptile::ROAD);
1576
1577   // now reconfigure all roads in the surroundings
1578   Vector<int> tile = r->getPos();
1579   for (int x = tile.x - 1; x <= tile.x + 1; ++x)
1580     for (int y = tile.y - 1; y <= tile.y + 1; ++y)
1581       {
1582         if ((x < 0 || x >= GameMap::getWidth()) &&
1583             (y < 0 || y >= GameMap::getHeight()))
1584           continue;
1585
1586         Vector<int> pos(x, y);
1587         if (Road *r = Roadlist::getInstance()->getObjectAt(pos))
1588           {
1589             int newtype = CreateScenario::calculateRoadType(pos);
1590             r->setType(newtype);
1591           }
1592       }
1593   return true;
1594 }
1595
1596 bool GameMap::removeBridge(Vector<int> pos)
1597 {
1598   Bridge *b = GameMap::getBridge(pos);
1599   if (b)
1600     {
1601       removeBuilding(b);
1602       Bridgelist::getInstance()->subtract(b);
1603       return true;
1604     }
1605   return false;
1606 }
1607
1608 bool GameMap::putBridge(Bridge *b)
1609 {
1610   Bridgelist::getInstance()->add(b);
1611   setBuilding(b->getPos(), Maptile::BRIDGE);
1612   if (GameMap::getStack(b->getPos()) != NULL)
1613     updateShips(b->getPos());
1614   return true;
1615 }
1616
1617 Rectangle GameMap::putTerrain(Rectangle r, Tile::Type type, int tile_style_id, bool always_alter_tilestyles)
1618 {
1619   bool replaced = false;
1620   int index = getTileset()->getIndex(type);
1621   if (index == -1)
1622     return r;
1623   for (int x = r.x; x < r.x + r.w; ++x)
1624     for (int y = r.y; y < r.y + r.h; ++y)
1625       {
1626         if (offmap(x,y))
1627           continue;
1628         Maptile* t = getTile(Vector<int>(x, y));
1629         if (t->getMaptileType() != type)
1630           {
1631             t->setType(index);
1632             calculateBlockedAvenue(x, y);
1633             updateShips(Vector<int>(x,y));
1634             replaced = true;
1635           }
1636       }
1637   if (tile_style_id == -1)
1638     {
1639       if (replaced || always_alter_tilestyles)
1640         {
1641           guint32 border = 1;
1642           r.pos -= Vector<int>(border, border);
1643           r.dim += Vector<int>(border * 2, border * 2);
1644           applyTileStyles(r, true);
1645         }
1646     }
1647   else
1648     {
1649       for (int x = r.x; x < r.x + r.w; ++x)
1650         for (int y = r.y; y < r.y + r.h; ++y)
1651           {
1652             if (offmap(x,y))
1653               continue;
1654             TileStyle *style = getTileset()->getTileStyle(tile_style_id);
1655             getTile(x, y)->setTileStyle(style);
1656           }
1657     }
1658
1659   return r;
1660 }
1661
1662 void GameMap::putBuilding(LocationBox *b, Maptile::Building building)
1663 {
1664   Rectangle r = b->getArea();
1665   for (int x = r.x; x < r.x + r.w; ++x)
1666     for (int y = r.y; y < r.y + r.h; ++y)
1667       {
1668         Maptile* t = getTile(Vector<int>(x, y));
1669         t->setBuilding(building);
1670         if (building == Maptile::CITY || building == Maptile::PORT || 
1671             building == Maptile::BRIDGE)
1672           GameMap::getInstance()->calculateBlockedAvenue(x, y);
1673       }
1674 }
1675
1676 void GameMap::removeBuilding(LocationBox *b)
1677 {
1678   Rectangle r = b->getArea();
1679   for (int x = r.x; x < r.x + r.w; ++x)
1680     for (int y = r.y; y < r.y + r.h; ++y)
1681       {
1682         Maptile* t = getTile(Vector<int>(x, y));
1683         t->setBuilding(Maptile::NONE);
1684       }
1685 }
1686
1687 bool GameMap::removeCity(Vector<int> pos)
1688 {
1689   City *c = GameMap::getCity(pos);
1690   if (c)
1691     {
1692       removeBuilding(c);
1693       Citylist::getInstance()->subtract(c);
1694       return true;
1695     }
1696   return false;
1697 }
1698 bool GameMap::putCity(City *c)
1699 {
1700   Player *active = Playerlist::getActiveplayer();
1701
1702   // create the city
1703   c->setOwner(active);
1704   Citylist::getInstance()->add(c);
1705
1706   putTerrain(c->getArea(), Tile::GRASS);
1707   // notify the maptiles that a city has been placed here
1708   putBuilding(c, Maptile::CITY);
1709
1710   //change allegiance of stacks under this city
1711   for (unsigned int x = 0; x < c->getSize(); x++)
1712     {
1713       for (unsigned int y = 0; y < c->getSize(); y++)
1714         {
1715           Stack *s = getStack(c->getPos() + Vector<int>(x,y));
1716           if (s)
1717             {
1718               if (c->getOwner() == active && s->getFortified() == true)
1719                 s->setFortified(false);
1720               if (s->getOwner() != c->getOwner())
1721                 Stacklist::changeOwnership(s, c->getOwner());
1722             }
1723         }
1724     }
1725   return true;
1726 }
1727
1728 //the ground changed, and now we need all stacks on a tile to react.
1729 void GameMap::updateShips(Vector<int> pos)
1730 {
1731   std::list<Stack*> stks = getStacks(pos)->getStacks();
1732   for (std::list<Stack *>::iterator it = stks.begin(); it != stks.end(); it++)
1733     {
1734       for (Stack::iterator sit = (*it)->begin(); sit != (*it)->end(); sit++)
1735         {
1736           if (((*sit)->getStat(Army::MOVE_BONUS) & Tile::WATER) == 0 &&
1737               getTerrainType(pos) == Tile::WATER)
1738             {
1739               if (getBridge(pos) || getPort(pos))
1740                 (*sit)->setInShip(false);
1741               else
1742                 (*sit)->setInShip(true);
1743             }
1744           else
1745             (*sit)->setInShip(false);
1746
1747         }
1748     }
1749 }
1750 Location *GameMap::getLocation(Vector<int> tile)
1751 {
1752   switch (getBuilding(tile))
1753     {
1754     case Maptile::CITY: return getCity(tile);
1755     case Maptile::RUIN: return getRuin(tile);
1756     case Maptile::TEMPLE: return getTemple(tile);
1757     case Maptile::ROAD: return getRoad(tile);
1758     case Maptile::BRIDGE: return getBridge(tile);
1759     case Maptile::SIGNPOST: return getSignpost(tile);
1760     case Maptile::PORT: return getPort(tile);
1761     case Maptile::NONE: break;
1762     }
1763   return NULL;
1764 }
1765         
1766 bool GameMap::putStack(Stack *s)
1767 {
1768   Playerlist::getActiveplayer()->addStack(s);
1769   getStacks(s->getPos())->add(s);
1770   updateShips(s->getPos());
1771   return true;
1772 }
1773
1774 void GameMap::removeStack(Stack *s)
1775 {
1776   getStacks(s->getPos())->leaving(s);
1777   Playerlist::getActiveplayer()->deleteStack(s);
1778 }
1779         
1780 guint32 GameMap::countArmyUnits(Vector<int> pos)
1781 {
1782   return getStacks(pos)->countNumberOfArmies(Playerlist::getActiveplayer());
1783 }
1784
1785 std::list<Stack*> GameMap::getNearbyFriendlyStacks(Vector<int> pos, int dist)
1786 {
1787   return getNearbyStacks(pos, dist, true);
1788 }
1789
1790 std::list<Stack*> GameMap::getNearbyEnemyStacks(Vector<int> pos, int dist)
1791 {
1792   return getNearbyStacks(pos, dist, false);
1793 }
1794
1795 std::list<Stack*> GameMap::getNearbyStacks(Vector<int> pos, int dist, bool friendly)
1796 {
1797   std::list<Vector<int> > points = getNearbyPoints(pos, dist);
1798   std::list<Stack*> stks;
1799   std::list<Stack *> stacks;
1800   for (std::list<Vector<int> >::iterator it = points.begin(); 
1801        it != points.end(); it++)
1802     {
1803       if (friendly)
1804         stks = GameMap::getFriendlyStacks(*it);
1805       else
1806         stks = GameMap::getEnemyStacks(*it);
1807       stacks.merge(stks);
1808     }
1809
1810   return stacks;
1811 }
1812
1813
1814 std::list<Vector<int> > GameMap::getNearbyPoints(Vector<int> pos, int dist)
1815 {
1816   std::list<Vector<int> > points;
1817   guint32 i, j;
1818   guint32 d;
1819   guint32 max = dist;
1820   int x, y;
1821
1822   points.push_back(pos);
1823
1824   //d is the distance from Pos where our box starts
1825   //instead of a regular loop around a box of dist large, we're going to add
1826   //the nearer stacks first.
1827   for (d = 1; d <= max; d++)
1828     {
1829       for (i = 0; i < (d * 2) + 1; i++)
1830         {
1831           for (j = 0; j < (d * 2) + 1; j++)
1832             {
1833               if ((i == 0 || i == (d * 2)) ||
1834                   (j == 0 || j == (d * 2)))
1835                 {
1836                   x = pos.x + (i - d);
1837                   y = pos.y + (j - d);
1838                   if (offmap(x, y))
1839                     continue;
1840                   points.push_back(Vector<int>(x,y));
1841                 }
1842             }
1843         }
1844     }
1845
1846   return points;
1847 }
1848 bool GameMap::checkCityAccessibility()
1849 {
1850   //check to see if all cities are accessible
1851   //check if all cities are accessible
1852   Citylist *cl = Citylist::getInstance();
1853   if (cl->size() <= 1)
1854     return true;
1855   Vector<int> pos = GameMap::getCenterOfMap();
1856   City *center = Citylist::getInstance()->getNearestCity(pos);
1857   Stack s(NULL, center->getPos());
1858   ArmyProto *basearmy = ArmyProto::createScout();
1859   Army *a = Army::createNonUniqueArmy(*basearmy);
1860   delete basearmy;
1861   s.push_back(a);
1862   PathCalculator pc(&s, true, 10, 10);
1863
1864   for (Citylist::iterator it = cl->begin(); it != cl->end(); it++)
1865     {
1866       if (center == *it)
1867         continue;
1868
1869       int mp = pc.calculate((*it)->getPos());
1870       if (mp <= 0)
1871         {
1872           printf("we made a map that has an inaccessible city (%d)\n", mp);
1873           printf("can't get from %s to %s\n", (*it)->getName().c_str(), center->getName().c_str());
1874           return false;
1875         }
1876     }
1877   return true;
1878 }
1879
1880 Vector<int> GameMap::getCenterOfMap()
1881 {
1882   return Vector<int>(GameMap::s_width/2, GameMap::s_height/2);
1883 }
1884