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
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 3 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Library General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
27 #include <sigc++/functors/mem_fun.h>
30 #include "ucompose.hpp"
33 #include "bridgelist.h"
42 #include "playerlist.h"
43 #include "stacklist.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"
58 #include "armysetlist.h"
59 #include "CreateScenario.h"
61 std::string GameMap::d_tag = "map";
62 std::string GameMap::d_itemstack_tag = "itemstack";
65 //#define debug(x) {std::cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<std::endl<<flush;}
68 GameMap* GameMap::s_instance = 0;
70 int GameMap::s_width = 112;
71 int GameMap::s_height = 112;
73 GameMap* GameMap::getInstance()
81 GameMap* GameMap::getInstance(std::string TilesetName,
82 std::string ShieldsetName,
83 std::string CitysetName)
87 s_instance = new GameMap(TilesetName, ShieldsetName, CitysetName);
93 GameMap* GameMap::getInstance(XML_Helper* helper)
98 s_instance = new GameMap(helper);
103 void GameMap::deleteInstance()
110 GameMap::GameMap(std::string TilesetName, std::string ShieldsetName,
111 std::string CitysetName)
113 d_tileSet = Tilesetlist::getInstance()->getTileset(TilesetName);
114 d_shieldSet = Shieldsetlist::getInstance()->getShieldset(ShieldsetName);
115 d_citySet = Citysetlist::getInstance()->getCityset(CitysetName);
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;
125 bool GameMap::offmap(int x, int y)
127 if (y<0||y>=GameMap::s_height||x<0||x>=GameMap::s_width)
132 void GameMap::processStyles(std::string styles, int chars_per_style)
134 int c = chars_per_style;
136 for (int j = 0; j < s_height; j++)
138 // remove newline and carriage return lines
139 char test = styles[j*s_width*c + offset];
140 while (test == '\n' || test == '\r')
143 test = styles[j*s_width*c + offset];
146 for (int i = 0; i < s_width; i++)
149 //due to the circumstances, styles is a long stream of
150 //hex digit pairs, so read it character for character
153 memcpy (&hexstr[2], &styles[j*s_width*c + (i * c) + offset], c);
154 hexstr[2 + c + 1 - 1] = '\0';
156 unsigned long int val = 0;
158 val = strtoul (hexstr, &end, 16);
159 guint32 id = (guint32) val;
160 TileStyle *style = d_tileSet->getTileStyle(id);
162 style = d_tileSet->getTileStyle(0);
163 d_map[j*s_width + i]->setTileStyle(style);
168 int GameMap::determineCharsPerStyle(std::string styles)
170 return styles.length() / (s_width * s_height);
173 GameMap::GameMap(XML_Helper* helper)
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");
189 d_tileSet = Tilesetlist::getInstance()->getTileset(t_dir);
190 d_shieldSet = Shieldsetlist::getInstance()->getShieldset(s_dir);
191 d_citySet = Citysetlist::getInstance()->getCityset(c_dir);
193 Vector<int>::setMaximumWidth(s_width);
195 d_map = new Maptile*[s_width*s_height];
198 for (int j = 0; j < s_height; j++)
200 // remove newline and carriage return lines
201 char test = types[j*s_width + offset];
202 while (test == '\n' || test == '\r')
205 test = types[j*s_width + offset];
208 for (int i = 0; i < s_width; i++)
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];
214 //the chars now hold the ascii representation of the numbers, which
217 d_map[j*s_width + i] = new Maptile(d_tileSet, i, j, type, NULL);
221 int chars_per_style = determineCharsPerStyle(styles);
222 processStyles(styles, chars_per_style);
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));
235 for (int i = 0; i < s_width; i++)
237 for (int j = 0; j < s_height; j++)
239 if (d_map[j*s_width + i])
240 delete d_map[j*s_width + i];
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.
253 const Tile::Type* terrain = generator->getMap(width, height);
256 //the sizes should definitely match, else we have a problem here
257 if (width != s_width || height != s_height)
259 std::cerr << "Error in GameMap::fillMap: sizes don't match!! Exiting.\n";
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++)
269 int index = d_tileSet->getIndex(terrain[j*width + i]);
271 d_map[j*s_width + i] = new Maptile(d_tileSet, i, j,
272 (guint32)index, NULL);
275 applyTileStyles(0, 0, height, width, true);
279 bool GameMap::fill(guint32 type)
281 for (int i = 0; i < s_width; i++)
282 for (int j = 0; j < s_height; j++)
284 d_map[j*s_width + i] = new Maptile(d_tileSet, i, j, type, NULL);
287 applyTileStyles(0, 0, s_height, s_width, false);
291 bool GameMap::save(XML_Helper* helper) const
295 std::stringstream types;
298 for (int i = 0; i < s_height; i++)
300 for (int j = 0; j < s_width; j++)
301 types << getTile(j, i)->getType();
305 std::stringstream styles;
308 int largest_style_id = d_tileSet->getLargestTileStyleId();
309 for (int i = 0; i < s_height; i++)
311 for (int j = 0; j < s_width; j++)
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()));
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());
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);
344 retval &= helper->closeTag();
348 bool GameMap::loadItems(std::string tag, XML_Helper* helper)
353 if (tag == GameMap::d_itemstack_tag)
355 helper->getData(x, "x");
356 helper->getData(y, "y");
359 if (tag == Item::d_tag)
361 Item* item = new Item(helper);
362 getTile(x, y)->getBackpack()->addToBackpack(item);
368 void GameMap::setTile(int x, int y, Maptile *tile)
370 delete d_map[y*s_width + x];
371 d_map[y*s_width + x] = tile;
372 applyTileStyle (y, x);
375 Maptile* GameMap::getTile(int x, int y) const
377 assert(x >= 0 && x < s_width && y >= 0 && y < s_height);
379 return d_map[y*s_width + x];
382 Stack* GameMap::addArmy(Vector<int> pos, Army *a)
384 City *c = getCity(pos);
388 return addArmyAtPos(pos, a);
390 return addArmy(c, a);
392 Temple *t = getTemple(pos);
394 return addArmy(t, a);
395 Ruin *r = getRuin(pos);
397 return addArmy(r, a);
398 return addArmyAtPos(pos, a);
401 Stack* GameMap::addArmyAtPos(Vector<int> pos, Army *a)
404 bool added_army = false;
409 if (s_height > s_width)
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
425 if (getTile(pos.x, pos.y)->getType() == Tile::WATER)
428 //d is the distance from Pos where our box starts
429 for (d = 1; d < max; d++)
431 for (i = 0; i < (d * 2) + 1; i++)
433 for (j = 0; j < (d * 2) + 1; j++)
435 if ((i == 0 || i == (d * 2) + 1) &&
436 (j == 0 || j == (d * 2) + 1))
444 //is there somebody else's city here?
445 City *c = getCity(Vector<int>(x, y));
446 if (c && c->getOwner() != a->getOwner())
448 if (c->isBurnt() == false)
451 //is this an unsuitable tile?
452 if (land && getTile(x, y)->getType() == Tile::WATER)
454 if (!land && getTile(x, y)->getType() != Tile::WATER)
456 if (land && getTile(x, y)->getType() == Tile::VOID)
458 if (land && getTile(x, y)->getType() == Tile::MOUNTAIN &&
459 (a->getStat(Army::MOVE_BONUS) & Tile::MOUNTAIN) == 0)
461 //do we already have a nifty stack here?
462 s = getFriendlyStack(Vector<int>(x,y));
465 if (canAddArmy(Vector<int>(x,y)) == false)
467 //is our stack too full?
472 Vector<int> pos(x, y);
473 //hmm. no nifty stacks here. anybody else's?
474 s = getEnemyStack(pos);
477 //okay, no stacks here at all. make one.
478 s = new Stack(a->getOwner(), pos);
480 a->getOwner()->addStack(s);
495 s->setDefending(false);
503 Stack* GameMap::addArmy(Location *l, Army *a)
509 return addArmyAtPos(l->getPos(), a);
512 bool GameMap::isDock(Vector<int> pos)
514 if (getBuilding(pos) == Maptile::CITY)
516 if (getBuilding(pos) == Maptile::PORT)
518 if (getBuilding(pos) == Maptile::BRIDGE)
523 bool GameMap::isBlockedAvenue(int x, int y, int destx, int desty)
525 if (offmap(destx, desty))
527 if (Citylist::getInstance()->empty())
529 int diffx = destx - x;
530 int diffy = desty - y;
531 if (diffx >= -1 && diffx <= 1 && diffy >= -1 && diffy <= 1)
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);
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 &&
545 //am i on water going towards land from a port?
546 //if (from->getMaptileType() == Tile::WATER &&
547 //to->getMaptileType() != Tile::WATER &&
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)
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)
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)
570 //am i on a mountain without a road?
571 if (from->getMaptileType() == Tile::MOUNTAIN &&
572 getRoad(Vector<int>(x, y)) == NULL)
575 if (from->getMaptileType() == Tile::VOID)
577 if (to->getMaptileType() == Tile::VOID)
583 void GameMap::calculateBlockedAvenue(int i, int j)
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++)
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;
603 if (offmap (destx, desty))
605 maptile->d_blocked[k] = true;
608 maptile->d_blocked[k] = isBlockedAvenue(i, j, destx, desty);
611 void GameMap::calculateBlockedAvenues()
613 for (int i = 0; i < s_width; i++)
614 for (int j = 0; j < s_height; j++)
615 calculateBlockedAvenue(i, j);
618 Vector<int> GameMap::findStack(guint32 id)
621 Vector<int> pos = Vector<int>(-1,-1);
622 for (int x = 0; x < getWidth(); x++)
624 for (int y = 0; y < getHeight(); y++)
626 StackTile *stile = getTile(x,y)->getStacks();
627 if (stile->contains(id) == true)
629 pos = Vector<int>(x,y);
638 Vector<int> GameMap::findPlantedStandard(Player *p)
644 for (int x = 0; x < getWidth(); x++)
646 for (int y = 0; y < getHeight(); y++)
648 MapBackpack *backpack = getTile(x, y)->getBackpack();
649 found = backpack->getPlantedItem(p) != NULL;
661 TileStyle *GameMap::calculatePreferredStyle(int i, int j)
663 Tileset *tileset = getTileset();
664 Maptile *mtile = getTile(j, i);
666 for (int k = -1; k <= +1; k++)
667 for (int l = -1; l <= +1; l++)
670 if (offmap(j+l, i+k))
672 box[k+1][l+1] = are_those_tiles_similar(getTile(j+l, i+k)->getMaptileType(), mtile->getMaptileType(), false);
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);
752 void GameMap::close_circles (int minx, int miny, int maxx, int maxy)
754 Tileset *tileset = getTileset();
755 for (int i = minx; i < maxx; i++)
757 for (int j = miny; j < maxy; j++)
761 Maptile *tile = getTile(j, i);
762 TileStyle *tilestyle = tile->getTileStyle();
765 Maptile *nexttile = getTile(j + 1, i);
766 TileStyle *nextstyle = nexttile->getTileStyle();
767 if (tilestyle->getType() == TileStyle::OUTERTOPCENTER &&
768 nextstyle->getType() == TileStyle::OUTERBOTTOMCENTER)
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);
778 if (tilestyle->getType() == TileStyle::OUTERBOTTOMCENTER &&
779 nextstyle->getType() == TileStyle::OUTERTOPCENTER)
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);
790 if (i + 1 < s_height)
792 Maptile *nexttile = getTile(j, i + 1);
793 TileStyle *nextstyle = nexttile->getTileStyle();
794 if (tilestyle->getType() == TileStyle::OUTERMIDDLERIGHT&&
795 nextstyle->getType() == TileStyle::OUTERMIDDLELEFT)
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);
805 if (tilestyle->getType() == TileStyle::OUTERMIDDLELEFT&&
806 nextstyle->getType() == TileStyle::OUTERMIDDLERIGHT)
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);
821 bool GameMap::are_those_tiles_similar(Tile::Type outer_tile,Tile::Type inner_tile, bool checking_loneliness)
823 if(checking_loneliness || inner_tile == Tile::HILLS)
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
831 // There never should be a lone mountain in grass (not surrounded by hills).
832 // Mountain surrounded by hills is perfectly correct.
834 return outer_tile == inner_tile;
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;
843 int GameMap::tile_is_connected_to_other_like_tiles (Tile::Type tile, int i, int j)
846 memset (box, 0, sizeof (box));
847 for (int k = -1; k <= +1; k++)
848 for (int l = -1; l <= +1; l++)
852 box[k+1][l+1] = are_those_tiles_similar(getTile(j+l, i+k)->getMaptileType(), tile, true);
854 if (box[0][0] && box[0][1] && box[1][0] && box[1][1])
856 if (box[0][1] && box[0][2] && box[1][1] && box[1][2])
858 if (box[1][0] && box[1][1] && box[2][0] && box[2][1])
860 if (box[1][1] && box[1][2] && box[2][1] && box[2][2])
865 void GameMap::demote_lone_tile(int minx, int miny, int maxx, int maxy,
866 Tile::Type intype, Tile::Type outtype)
870 for (i = minx; i < maxx; i++)
871 for (j = miny; j < maxy; j++)
875 Tile::Type tile = getTile(j, i)->getMaptileType();
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)
882 //okay, this is a lone tile.
884 int idx = d_tileSet->getIndex(outtype);
886 setTile(j, i, new Maptile (d_tileSet, j, i,
887 (guint32)idx, NULL));
894 void GameMap::applyTileStyles (Rectangle r, bool smooth_terrain)
896 applyTileStyles (r.y, r.x, r.y + r.h, r.x + r.w, smooth_terrain);
899 void GameMap::applyTileStyles (int minx, int miny, int maxx, int maxy,
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);
912 for (int i = minx; i < maxx; i++)
914 for (int j = miny; j < maxy; j++)
918 applyTileStyle(i, j);
921 close_circles(minx, miny, maxx, maxy);
924 std::vector<Vector<int> > GameMap::getItems()
926 std::vector<Vector<int> > items;
927 for (int j = 0; j < s_height; j++)
928 for (int i = 0; i < s_width; i++)
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));
939 void GameMap::surroundMountains(int minx, int miny, int maxx, int maxy)
941 for(int j = miny; j < maxy; j++)
942 for(int i = minx; i < maxx; i++)
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))
952 int idx = d_tileSet->getIndex(Tile::HILLS);
953 if(getTile((j+J), (i+I))->getMaptileType() != Tile::WATER)
957 new Maptile (d_tileSet, j+J, i+I,
958 (guint32)idx, NULL));
962 // water has priority here, there was some work done to conenct bodies of water
963 // so don't break those connections.
965 new Maptile (d_tileSet, j, i, (guint32)idx, NULL));
971 void GameMap::applyTileStyle (int i, int j)
973 Maptile *mtile = getTile(j, i);
974 Tileset *tileset = getTileset();
975 TileStyle *style = calculatePreferredStyle(i, j);
977 style = tileset->getRandomTileStyle(mtile->getType(),
980 style = tileset->getRandomTileStyle(mtile->getType(),
981 TileStyle::INNERMIDDLECENTER);
983 printf ("applying null tile style at %d,%d for tile of kind %d\n", i, j,
984 mtile->getMaptileType());
985 mtile->setTileStyle(style);
988 Vector<int> GameMap::findNearestObjectInDir(Vector<int> pos, Vector<int> dir)
990 std::vector<Vector<int> > objects;
991 Road *road = Roadlist::getInstance()->getNearestObjectInDir(pos, dir);
993 objects.push_back(road->getPos());
994 Bridge *bridge = Bridgelist::getInstance()->getNearestObjectInDir(pos, dir);
996 objects.push_back(bridge->getPos());
997 City *city = Citylist::getInstance()->getNearestObjectInDir(pos, dir);
999 objects.push_back(city->getPos());
1000 Temple *temple = Templelist::getInstance()->getNearestObjectInDir(pos, dir);
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);
1009 int min_distance = -1;
1010 Vector<int> closest = Vector<int>(-1,-1);
1011 for (unsigned int i = 0; i < objects.size(); i++)
1013 int distance = dist(pos, objects[i]);
1014 if (min_distance == -1 || distance < min_distance)
1016 min_distance = distance;
1017 closest = objects[i];
1023 Vector<int> GameMap::findNearestObjectToTheNorth(Vector<int> pos)
1025 Vector<int> dir = Vector<int>(0, -1);
1026 return findNearestObjectInDir(pos, dir);
1029 Vector<int> GameMap::findNearestObjectToTheSouth(Vector<int> pos)
1031 Vector<int> dir = Vector<int>(0, 1);
1032 return findNearestObjectInDir(pos, dir);
1035 Vector<int> GameMap::findNearestObjectToTheEast(Vector<int> pos)
1037 Vector<int> dir = Vector<int>(1, 0);
1038 return findNearestObjectInDir(pos, dir);
1041 Vector<int> GameMap::findNearestObjectToTheWest(Vector<int> pos)
1043 Vector<int> dir = Vector<int>(-1, 0);
1044 return findNearestObjectInDir(pos, dir);
1046 City* GameMap::getCity(Vector<int> pos)
1048 return Citylist::getInstance()->getObjectAt(pos);
1050 City* GameMap::getEnemyCity(Vector<int> pos)
1052 City *c = Citylist::getInstance()->getObjectAt(pos);
1053 if (c && c->getOwner() != Playerlist::getActiveplayer())
1057 Ruin* GameMap::getRuin(Vector<int> pos)
1059 return Ruinlist::getInstance()->getObjectAt(pos);
1061 Temple* GameMap::getTemple(Vector<int> pos)
1063 return Templelist::getInstance()->getObjectAt(pos);
1065 Port* GameMap::getPort(Vector<int> pos)
1067 return Portlist::getInstance()->getObjectAt(pos);
1069 Road* GameMap::getRoad(Vector<int> pos)
1071 return Roadlist::getInstance()->getObjectAt(pos);
1073 Bridge* GameMap::getBridge(Vector<int> pos)
1075 return Bridgelist::getInstance()->getObjectAt(pos);
1077 Signpost* GameMap::getSignpost(Vector<int> pos)
1079 return Signpostlist::getInstance()->getObjectAt(pos);
1081 Stack* GameMap::getFriendlyStack(Vector<int> pos)
1083 return getStacks(pos)->getFriendlyStack(Playerlist::getActiveplayer());
1086 //StackReflist GameMap::getFriendlyStacks(Vector<int> pos, Player *player)
1088 //if (player == NULL)
1089 //player = Playerlist::getActiveplayer();
1090 //return StackReflist(getStacks(pos)->getFriendlyStacks(player));
1092 std::list<Stack*> GameMap::getFriendlyStacks(Vector<int> pos, Player *player)
1095 player = Playerlist::getActiveplayer();
1096 return getStacks(pos)->getFriendlyStacks(player);
1099 Stack* GameMap::getEnemyStack(Vector<int> pos)
1101 return getStacks(pos)->getEnemyStack(Playerlist::getActiveplayer());
1104 std::list<Stack*> GameMap::getEnemyStacks(std::list<Vector<int> > positions)
1106 std::list<Stack*> enemy_stacks;
1107 std::list<Vector<int> >::iterator it = positions.begin();
1108 for (; it != positions.end(); it++)
1110 Stack *enemy = getEnemyStack(*it);
1112 enemy_stacks.push_back(enemy);
1114 return enemy_stacks;
1117 std::list<Stack*> GameMap::getEnemyStacks(Vector<int> pos, Player *player)
1120 player = Playerlist::getActiveplayer();
1121 return getStacks(pos)->getEnemyStacks(player);
1123 Stack* GameMap::getStack(Vector<int> pos)
1125 return getStacks(pos)->getStack();
1128 StackTile* GameMap::getStacks(Vector<int> pos)
1130 return getInstance()->getTile(pos)->getStacks();
1132 Stack *GameMap::groupStacks(Vector<int> pos)
1134 return getStacks(pos)->group(Playerlist::getActiveplayer());
1137 void GameMap::groupStacks(Stack *stack)
1139 getStacks(stack->getPos())->group(Playerlist::getActiveplayer(), stack);
1142 void GameMap::updateStackPositions()
1144 Playerlist *plist = Playerlist::getInstance();
1145 for (Playerlist::iterator i = plist->begin(); i != plist->end(); i++)
1147 Stacklist *sl = (*i)->getStacklist();
1148 for (Stacklist::iterator s = sl->begin(); s != sl->end(); s++)
1149 getStacks((*s)->getPos())->add(*s);
1153 bool GameMap::canJoin(const Stack *src, Vector<int> dest)
1155 return getStacks(dest)->canAdd(src);
1157 bool GameMap::canJoin(const Stack *src, Stack *dest)
1159 return canJoin (src, dest->getPos());
1162 bool GameMap::canAddArmy(Vector<int> dest)
1164 if (countArmyUnits(dest) < MAX_ARMIES_ON_A_SINGLE_TILE)
1168 bool GameMap::canAddArmies(Vector<int> dest, guint32 stackSize)
1170 if (countArmyUnits(dest) + stackSize <= MAX_ARMIES_ON_A_SINGLE_TILE)
1175 void GameMap::switchTileset(Tileset *tileset)
1177 d_tileSet = tileset;
1178 applyTileStyles (0, 0, s_width, s_height, false);
1181 void GameMap::switchShieldset(Shieldset *shieldset)
1183 d_shieldSet = shieldset;
1186 void GameMap::switchCityset(Cityset *cityset)
1188 d_citySet = cityset;
1191 void GameMap::switchArmysets(Armyset *armyset)
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++)
1199 Stack *s = (*i)->getOccupant();
1202 for (Stack::iterator j = s->begin(); j != s->end(); j++)
1203 Armyset::switchArmysetForRuinKeeper(*j, armyset);
1205 for (Playerlist::iterator i = pl->begin(); i != pl->end(); i++)
1208 Armysetlist::getInstance()->getArmyset((*i)->getArmyset());
1212 //change the armyprodbases in cities.
1213 for (Citylist::iterator j = cl->begin(); j != cl->end(); j++)
1216 for (unsigned int k = 0; c->getSize(); k++)
1218 ArmyProdBase *prodbase = (*c)[k]->getArmyProdBase();
1220 Armyset::switchArmyset(prodbase, armyset);
1224 //change the armies in the stacklist
1225 Stacklist *sl = (*i)->getStacklist();
1226 for (Stacklist::iterator j = sl->begin(); j != sl->end(); j++)
1229 for (Stack::iterator k = s->begin(); k != s->end(); k++)
1230 Armyset::switchArmyset(*k,armyset);
1233 //finally, change the player's armyset.
1234 (*i)->setArmyset(armyset->getId());
1235 //where else are armyset ids hanging around?
1239 bool GameMap::canPutBuilding(Maptile::Building bldg, guint32 size, Vector<int> to, bool making_islands)
1241 bool can_move = true;
1242 //gotta have a building to move
1243 if (bldg == Maptile::NONE)
1245 //there can't be another building in the way.
1247 for (unsigned int i = 0; i < size; i++)
1248 for (unsigned int j = 0; j < size; j++)
1250 Vector<int> pos = to + Vector<int>(i,j);
1251 if (offmap(pos.x, pos.y))
1253 if (getBuilding(pos) != Maptile::NONE)
1258 //ok different objects have different rules wrt the kinds of tiles they
1264 case Maptile::TEMPLE:
1265 case Maptile::SIGNPOST:
1266 //gotta be on grass.
1270 for (unsigned int i = 0; i < size; i++)
1271 for (unsigned int j = 0; j < size; j++)
1273 Vector<int> pos = to + Vector<int>(i, j);
1274 if (getTerrainType(pos) != Tile::GRASS)
1280 //can't be in the water
1281 if (getTerrainType(to) == Tile::WATER ||
1282 getTerrainType(to) == Tile::VOID)
1286 if (getTerrainType(to) == Tile::WATER &&
1287 getTile(to)->getTileStyle()->getType() !=
1288 TileStyle::INNERMIDDLECENTER)
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 ))
1307 case Maptile::NONE: break;
1312 bool GameMap::moveBuilding(Vector<int> from, Vector<int> to)
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.
1319 guint32 size = getBuildingSize(from);
1323 if (canPutBuilding(getBuilding(from), size, to) == false)
1325 if (getLocation(from)->contains(to) == false &&
1326 LocationBox(to, size).contains(from) == false)
1330 switch (getBuilding(from))
1334 case Maptile::SIGNPOST:
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);
1344 Port *old_port = getPort(getPort(from)->getPos());
1345 Port *new_port = new Port(*old_port, to);
1346 removePort(old_port->getPos());
1350 case Maptile::BRIDGE:
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);
1360 Road *old_road = getRoad(getRoad(from)->getPos());
1361 Road *new_road = new Road(*old_road, to);
1362 removeRoad(old_road->getPos());
1368 Ruin* old_ruin = getRuin(getRuin(from)->getPos());
1369 Ruin *new_ruin = new Ruin(*old_ruin, to);
1370 removeRuin(old_ruin->getPos());
1374 case Maptile::TEMPLE:
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);
1384 City* old_city = getCity(getCity(from)->getPos());
1385 City* new_city = new City(*old_city, to);
1386 removeCity(old_city->getPos());
1394 Tile::Type GameMap::getTerrainType(Vector<int> tile)
1396 guint32 idx = getTile(tile)->getType();
1397 return (*d_tileSet)[idx]->getType();
1400 Maptile::Building GameMap::getBuilding(Vector<int> tile)
1402 return getTile(tile)->getBuilding();
1405 void GameMap::setBuilding(Vector<int> tile, Maptile::Building building)
1407 getTile(tile)->setBuilding(building);
1410 guint32 GameMap::getBuildingSize(Vector<int> tile)
1412 switch (getTile(tile)->getBuilding())
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;
1427 bool GameMap::canPutStack(guint32 size, Player *p, Vector<int> to)
1429 StackTile *stile = GameMap::getInstance()->getStacks(to);
1432 if (stile->canAdd(size, p) == true)
1438 bool GameMap::moveStack(Stack *stack, Vector<int> to)
1441 if (stack->getPos() == to)
1443 if (canPutStack(stack->size(), stack->getOwner(), to) == false)
1447 getStacks(stack->getPos())->leaving(stack);
1449 //Stack *new_stack = new Stack(*stack);
1450 //new_stack->setPos(to);
1451 //getStacks(stack->getPos())->leaving(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);
1459 if (getTerrainType(stack->getPos()) == Tile::WATER &&
1460 getBuilding(stack->getPos()) != Maptile::PORT &&
1461 getBuilding(stack->getPos()) != Maptile::BRIDGE)
1463 updateShips(stack->getPos());
1468 MapBackpack *GameMap::getBackpack(Vector<int> pos)
1470 return getInstance()->getTile(pos)->getBackpack();
1473 void GameMap::moveBackpack(Vector<int> from, Vector<int> to)
1475 getBackpack(to)->add(getBackpack(from));
1476 getBackpack(from)->clear();
1479 bool GameMap::removeRuin(Vector<int> pos)
1481 Ruin *r = GameMap::getRuin(pos);
1485 Ruinlist::getInstance()->subtract(r);
1490 bool GameMap::putRuin(Ruin *r)
1492 Ruinlist::getInstance()->add(r);
1493 putTerrain(r->getArea(), Tile::GRASS);
1494 putBuilding(r, Maptile::RUIN);
1498 bool GameMap::removeTemple(Vector<int> pos)
1500 Temple *t = GameMap::getTemple(pos);
1504 Templelist::getInstance()->subtract(t);
1510 bool GameMap::putTemple(Temple *t)
1512 Templelist::getInstance()->add(t);
1513 putTerrain(t->getArea(), Tile::GRASS);
1514 putBuilding(t, Maptile::TEMPLE);
1518 bool GameMap::removePort(Vector<int> pos)
1520 Port *p = GameMap::getPort(pos);
1524 Portlist::getInstance()->subtract(p);
1530 bool GameMap::putPort(Port *p)
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());
1540 bool GameMap::removeSignpost(Vector<int> pos)
1542 Signpost *s = GameMap::getSignpost(pos);
1546 Signpostlist::getInstance()->subtract(s);
1552 bool GameMap::putSignpost(Signpost *s)
1554 Signpostlist::getInstance()->add(s);
1555 putTerrain(s->getArea(), Tile::GRASS);
1556 putBuilding(s, Maptile::SIGNPOST);
1560 bool GameMap::removeRoad(Vector<int> pos)
1562 Road *r = GameMap::getRoad(pos);
1566 Roadlist::getInstance()->subtract(r);
1572 bool GameMap::putRoad(Road *r)
1574 Roadlist::getInstance()->add(r);
1575 setBuilding(r->getPos(), Maptile::ROAD);
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)
1582 if ((x < 0 || x >= GameMap::getWidth()) &&
1583 (y < 0 || y >= GameMap::getHeight()))
1586 Vector<int> pos(x, y);
1587 if (Road *r = Roadlist::getInstance()->getObjectAt(pos))
1589 int newtype = CreateScenario::calculateRoadType(pos);
1590 r->setType(newtype);
1596 bool GameMap::removeBridge(Vector<int> pos)
1598 Bridge *b = GameMap::getBridge(pos);
1602 Bridgelist::getInstance()->subtract(b);
1608 bool GameMap::putBridge(Bridge *b)
1610 Bridgelist::getInstance()->add(b);
1611 setBuilding(b->getPos(), Maptile::BRIDGE);
1612 if (GameMap::getStack(b->getPos()) != NULL)
1613 updateShips(b->getPos());
1617 Rectangle GameMap::putTerrain(Rectangle r, Tile::Type type, int tile_style_id, bool always_alter_tilestyles)
1619 bool replaced = false;
1620 int index = getTileset()->getIndex(type);
1623 for (int x = r.x; x < r.x + r.w; ++x)
1624 for (int y = r.y; y < r.y + r.h; ++y)
1628 Maptile* t = getTile(Vector<int>(x, y));
1629 if (t->getMaptileType() != type)
1632 calculateBlockedAvenue(x, y);
1633 updateShips(Vector<int>(x,y));
1637 if (tile_style_id == -1)
1639 if (replaced || always_alter_tilestyles)
1642 r.pos -= Vector<int>(border, border);
1643 r.dim += Vector<int>(border * 2, border * 2);
1644 applyTileStyles(r, true);
1649 for (int x = r.x; x < r.x + r.w; ++x)
1650 for (int y = r.y; y < r.y + r.h; ++y)
1654 TileStyle *style = getTileset()->getTileStyle(tile_style_id);
1655 getTile(x, y)->setTileStyle(style);
1662 void GameMap::putBuilding(LocationBox *b, Maptile::Building building)
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)
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);
1676 void GameMap::removeBuilding(LocationBox *b)
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)
1682 Maptile* t = getTile(Vector<int>(x, y));
1683 t->setBuilding(Maptile::NONE);
1687 bool GameMap::removeCity(Vector<int> pos)
1689 City *c = GameMap::getCity(pos);
1693 Citylist::getInstance()->subtract(c);
1698 bool GameMap::putCity(City *c)
1700 Player *active = Playerlist::getActiveplayer();
1703 c->setOwner(active);
1704 Citylist::getInstance()->add(c);
1706 putTerrain(c->getArea(), Tile::GRASS);
1707 // notify the maptiles that a city has been placed here
1708 putBuilding(c, Maptile::CITY);
1710 //change allegiance of stacks under this city
1711 for (unsigned int x = 0; x < c->getSize(); x++)
1713 for (unsigned int y = 0; y < c->getSize(); y++)
1715 Stack *s = getStack(c->getPos() + Vector<int>(x,y));
1718 if (c->getOwner() == active && s->getFortified() == true)
1719 s->setFortified(false);
1720 if (s->getOwner() != c->getOwner())
1721 Stacklist::changeOwnership(s, c->getOwner());
1728 //the ground changed, and now we need all stacks on a tile to react.
1729 void GameMap::updateShips(Vector<int> pos)
1731 std::list<Stack*> stks = getStacks(pos)->getStacks();
1732 for (std::list<Stack *>::iterator it = stks.begin(); it != stks.end(); it++)
1734 for (Stack::iterator sit = (*it)->begin(); sit != (*it)->end(); sit++)
1736 if (((*sit)->getStat(Army::MOVE_BONUS) & Tile::WATER) == 0 &&
1737 getTerrainType(pos) == Tile::WATER)
1739 if (getBridge(pos) || getPort(pos))
1740 (*sit)->setInShip(false);
1742 (*sit)->setInShip(true);
1745 (*sit)->setInShip(false);
1750 Location *GameMap::getLocation(Vector<int> tile)
1752 switch (getBuilding(tile))
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;
1766 bool GameMap::putStack(Stack *s)
1768 Playerlist::getActiveplayer()->addStack(s);
1769 getStacks(s->getPos())->add(s);
1770 updateShips(s->getPos());
1774 void GameMap::removeStack(Stack *s)
1776 getStacks(s->getPos())->leaving(s);
1777 Playerlist::getActiveplayer()->deleteStack(s);
1780 guint32 GameMap::countArmyUnits(Vector<int> pos)
1782 return getStacks(pos)->countNumberOfArmies(Playerlist::getActiveplayer());
1785 std::list<Stack*> GameMap::getNearbyFriendlyStacks(Vector<int> pos, int dist)
1787 return getNearbyStacks(pos, dist, true);
1790 std::list<Stack*> GameMap::getNearbyEnemyStacks(Vector<int> pos, int dist)
1792 return getNearbyStacks(pos, dist, false);
1795 std::list<Stack*> GameMap::getNearbyStacks(Vector<int> pos, int dist, bool friendly)
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++)
1804 stks = GameMap::getFriendlyStacks(*it);
1806 stks = GameMap::getEnemyStacks(*it);
1814 std::list<Vector<int> > GameMap::getNearbyPoints(Vector<int> pos, int dist)
1816 std::list<Vector<int> > points;
1822 points.push_back(pos);
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++)
1829 for (i = 0; i < (d * 2) + 1; i++)
1831 for (j = 0; j < (d * 2) + 1; j++)
1833 if ((i == 0 || i == (d * 2)) ||
1834 (j == 0 || j == (d * 2)))
1836 x = pos.x + (i - d);
1837 y = pos.y + (j - d);
1840 points.push_back(Vector<int>(x,y));
1848 bool GameMap::checkCityAccessibility()
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)
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);
1862 PathCalculator pc(&s, true, 10, 10);
1864 for (Citylist::iterator it = cl->begin(); it != cl->end(); it++)
1869 int mp = pc.calculate((*it)->getPos());
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());
1880 Vector<int> GameMap::getCenterOfMap()
1882 return Vector<int>(GameMap::s_width/2, GameMap::s_height/2);