1 // Copyright (C) 2003 Michael Bartl
2 // Copyright (C) 2003, 2004, 2005, 2006 Ulf Lorenz
3 // Copyright (C) 2003, 2006 Andrea Paternesi
4 // Copyright (C) 2006, 2007, 2008, 2009 Ben Asselstine
5 // Copyright (C) 2008 Janek Kozicki
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 3 of the License, or
10 // (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Library General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 #include <sigc++/trackable.h>
31 #include "rectangle.h"
35 #include "shieldset.h"
37 #include "stackreflist.h"
49 /** Class representing the map in the game
51 * GameMap represents a single map. In most cases this will be the map that is
52 * currently played, but it might be used to preview a map in a mapeditor too.
53 * Notes: GameMap was prefered over Map, because of the potential confusion
54 * with the std::map from the STL.
55 * In a previous design this has been a global variable, now it's a singleton.
56 * So if you need access to the game map, use one of the getInstance functions
57 * to get the singleton instance.
60 class GameMap: public sigc::trackable
63 //! The xml tag of this object in a saved-game file.
64 static std::string d_tag;
66 //! The xml tag of the itemstack subobject in a saved-game file.
67 static std::string d_itemstack_tag;
69 /** Singleton function to get the GameMap instance
71 * @return singleton instance
73 static GameMap* getInstance();
75 /** Returns singleton instance or creates a new one using the tileset
77 * @param TilesetName the name of the tileset to be used
78 * @return singleton instance
80 static GameMap* getInstance(std::string TilesetName,
81 std::string Shieldsetname,
82 std::string Citysetname);
84 /** Creates a new singleton instance from a savegame file
86 * @param helper see XML_Helper for an explanation
88 * \note This function deletes an existing instance!
90 static GameMap* getInstance(XML_Helper* helper);
92 //! Explicitely deletes the singleton instance
93 static void deleteInstance();
95 //! Set the width of the game map
96 static void setWidth(int width){s_width = width;}
98 //! Set the height of the game map
99 static void setHeight(int height){s_height = height;}
102 //! Returns the width of the map
103 static int getWidth() {return s_width;}
105 //! Returns the height of the map
106 static int getHeight() {return s_height;}
108 static Vector<int> get_dim() { return Vector<int>(s_width, s_height); }
110 static Rectangle get_boundary()
111 { return Rectangle(0, 0, s_width, s_height); }
113 //! Returns the tileset in use
114 Tileset* getTileset() const {return d_tileSet;}
116 //! Returns the shieldset in use
117 Shieldset* getShieldset() const {return d_shieldSet;}
119 //! Returns the tileset in use
120 Cityset* getCityset() const {return d_citySet;}
122 //! Sets the tile object at position (x, y)
123 void setTile(int x, int y, Maptile *tile);
125 //! Alternative setting
126 void setTile(Vector<int> p, Maptile *t) {return setTile(p.x, p.y, t);}
128 static City* getCity(Vector<int> pos);
129 static City* getCity(Movable *m) {return getCity(m->getPos());}
131 static City* getEnemyCity(Vector<int> pos);
132 static Ruin* getRuin(Vector<int> pos);
133 static Ruin* getRuin(Movable *m) {return getRuin(m->getPos());}
134 static Temple* getTemple(Vector<int> pos);
135 static Temple* getTemple(Movable *m) {return getTemple(m->getPos());}
136 static Port* getPort(Vector<int> pos);
137 static Road* getRoad(Vector<int> pos);
138 static Bridge* getBridge(Vector<int> pos);
139 static Signpost* getSignpost(Vector<int> pos);
140 static Signpost* getSignpost(Movable *m) {return getSignpost(m->getPos());}
141 static Stack* getStack(Vector<int> pos);
142 static StackTile* getStacks(Vector<int> pos);
143 static Stack *groupStacks(Vector<int> pos);
144 static void groupStacks(Stack *s);
145 static bool canJoin(const Stack *src, Stack *dest);
146 static bool canJoin(const Stack *stack, Vector<int> pos);
147 static bool canAddArmy(Vector<int> pos);
148 static bool canAddArmies(Vector<int> dest, guint32 stackSize);
149 static Stack* getFriendlyStack(Vector<int> pos);
150 //static StackReflist getFriendlyStacks(Vector<int> pos, Player *player = NULL);
151 static std::list<Stack*> getFriendlyStacks(Vector<int> pos, Player *player = NULL);
152 static Stack* getEnemyStack(Vector<int> pos);
153 static std::list<Stack*> getEnemyStacks(std::list<Vector<int> > posns);
154 static std::list<Stack*> getEnemyStacks(Vector<int> pos, Player *player = NULL);
155 static std::list<Stack*> getNearbyFriendlyStacks(Vector<int> pos, int dist);
156 static std::list<Stack*> getNearbyEnemyStacks(Vector<int> pos, int dist);
158 static std::list<Vector<int> > getNearbyPoints(Vector<int> pos, int dist);
159 static guint32 countArmyUnits(Vector<int> pos);
160 static MapBackpack *getBackpack(Vector<int> pos);
162 //! Get the tile object at position (x,y)
163 Maptile* getTile(int x, int y) const;
165 //! Alternative access
166 Maptile* getTile(Vector<int> p) const {return getTile(p.x, p.y);}
168 //! Add an army to this location on the map
169 Stack* addArmy(Location *l, Army *a);
170 Stack* addArmy(Vector<int> pos, Army *a);
171 Stack* addArmyAtPos(Vector<int> pos, Army *a);
173 //! Go find a player's planted standard on the map
174 Vector<int> findPlantedStandard(Player *p);
176 //! go find the player's stack, the slow way.
177 Vector<int> findStack(guint32 id);
179 /** Fill the map using the data supplied by a map generator
181 * @param generator the generator which supplies the data
182 * @return true on success, false on error
184 bool fill(MapGenerator* generator);
186 /** Fills the whole map with a single terrain.
188 * @param type the type of the terrain(index in the tileset)
189 * @return true on success, false on error
191 bool fill(guint32 type);
193 /** Save the contents of the map
195 * @param helper see XML_Helper for more information
196 * @return true if saving went well, false otherwise
198 bool save(XML_Helper* helper) const;
200 //! figure out where a non-flying unit can't go
201 void calculateBlockedAvenues();
202 void calculateBlockedAvenue(int i, int j);
203 void updateStackPositions();
205 /** Smooth a portion of the map.
207 * Give each tile in the prescribed area the preferred picture for
208 * the underlying terrain tile.
210 void applyTileStyles (Rectangle r, bool smooth_terrain);
211 void applyTileStyles (int minx, int miny, int maxx, int maxy,
212 bool smooth_terrain);
213 void applyTileStyle (int i, int j);
215 void surroundMountains(int minx, int miny, int maxx, int maxy);
216 //! Get the positions of all of the items on the game map (in bags).
217 std::vector<Vector<int> > getItems();
219 Vector<int> findNearestObjectToTheNorth(Vector<int> pos);
220 Vector<int> findNearestObjectToTheSouth(Vector<int> pos);
221 Vector<int> findNearestObjectToTheEast(Vector<int> pos);
222 Vector<int> findNearestObjectToTheWest(Vector<int> pos);
224 void switchArmysets(Armyset *armyset);
225 void switchCityset(Cityset *cityset);
226 void switchShieldset(Shieldset *shieldset);
227 void switchTileset(Tileset *tileset);
229 bool moveBuilding(Vector<int> from, Vector<int> to);
230 bool canPutBuilding(Maptile::Building bldg, guint32 size, Vector<int> to, bool making_islands = true);
231 bool canPutStack(guint32 size, Player *p, Vector<int> to);
232 bool moveStack(Stack *stack, Vector<int> to);
234 void moveBackpack(Vector<int> from, Vector<int> to);
235 guint32 getBuildingSize(Vector<int> tile);
236 Maptile::Building getBuilding(Vector<int> tile);
237 Tile::Type getTerrainType(Vector<int> tile);
238 void setBuilding(Vector<int> tile, Maptile::Building building);
240 bool putCity(City *c);
241 bool removeCity(Vector<int> pos);
242 bool putRuin(Ruin *r);
243 bool removeRuin(Vector<int> pos);
244 bool putTemple(Temple *t);
245 bool removeTemple(Vector<int> pos);
246 bool putRoad(Road *r);
247 bool removeRoad(Vector<int> pos);
248 bool putBridge(Bridge *b);
249 bool removeBridge(Vector<int> pos);
250 bool putSignpost(Signpost *s);
251 bool removeSignpost(Vector<int> pos);
252 bool putPort(Port *p);
253 bool removePort(Vector<int> pos);
254 bool putStack(Stack *s);
255 void removeStack(Stack *s);
257 Location *getLocation(Vector<int> pos);
259 bool checkCityAccessibility();
261 static Vector<int> getCenterOfMap();
263 Rectangle putTerrain(Rectangle r, Tile::Type type,
264 int tile_style_id = -1,
265 bool always_alter_tilestyles = false);
268 //! Create the map with the given tileset
269 GameMap(std::string TilesetName, std::string ShieldsetName,
270 std::string Citysetname);
272 //! Load the map using the given XML_Helper
273 GameMap(XML_Helper* helper);
278 //! Callback for item loading used during loading.
279 bool loadItems(std::string tag, XML_Helper* helper);
280 bool isBlockedAvenue(int x, int y, int destx, int desty);
281 bool isDock(Vector<int> pos);
282 void close_circles (int minx, int miny, int maxx, int maxy);
283 void processStyles(std::string styles, int chars_per_style);
284 int determineCharsPerStyle(std::string styles);
286 TileStyle *calculatePreferredStyle(int i, int j);
287 void demote_lone_tile(int minx, int miny, int maxx, int maxy,
288 Tile::Type intype, Tile::Type outtype);
290 int tile_is_connected_to_other_like_tiles (Tile::Type tile, int i,
292 bool are_those_tiles_similar(Tile::Type outer_tile,Tile::Type inner_tile, bool checking_loneliness);
293 Vector<int> findNearestObjectInDir(Vector<int> pos, Vector<int> dir);
294 void putBuilding(LocationBox *b, Maptile::Building building);
295 void removeBuilding(LocationBox *b);
297 void updateShips(Vector<int> pos);
300 static std::list<Stack*> getNearbyStacks(Vector<int> pos, int dist, bool friendly);
302 static bool offmap(int x, int y);
305 static GameMap* s_instance;
310 Shieldset* d_shieldSet;