initial commit, lordsawar source, slightly modified
[lordsawar] / src / GameMap.h
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
6 //
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.
11 //
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.
16 //
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 
20 //  02110-1301, USA.
21
22 #ifndef GAMEMAP_H
23 #define GAMEMAP_H
24
25 #include <sigc++/trackable.h>
26
27 #include <vector>
28
29 #include <gtkmm.h>
30 #include "vector.h"
31 #include "rectangle.h"
32 #include "maptile.h"
33 #include "stack.h"
34 #include "Location.h"
35 #include "shieldset.h"
36 #include "cityset.h"
37 #include "stackreflist.h"
38
39 class MapGenerator;
40 class XML_Helper;
41 class Port;
42 class Road;
43 class City;
44 class Temple;
45 class Bridge;
46 class Ruin;
47 class Armyset;
48
49 /** Class representing the map in the game
50   * 
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.
58   */
59
60 class GameMap: public sigc::trackable
61 {
62     public:
63         //! The xml tag of this object in a saved-game file.
64         static std::string d_tag; 
65
66         //! The xml tag of the itemstack subobject in a saved-game file.
67         static std::string d_itemstack_tag; 
68
69         /** Singleton function to get the GameMap instance
70           * 
71           * @return singleton instance
72           */
73         static GameMap* getInstance();
74
75         /** Returns singleton instance or creates a new one using the tileset
76           * 
77           * @param TilesetName      the name of the tileset to be used
78           * @return singleton instance
79           */
80         static GameMap* getInstance(std::string TilesetName,
81                                     std::string Shieldsetname,
82                                     std::string Citysetname);
83
84         /** Creates a new singleton instance from a savegame file
85           * 
86           * @param helper           see XML_Helper for an explanation
87           *
88           * \note This function deletes an existing instance!
89           */
90         static GameMap* getInstance(XML_Helper* helper);
91
92         //! Explicitely deletes the singleton instance
93         static void deleteInstance();
94
95         //! Set the width of the game map
96         static void setWidth(int width){s_width = width;}
97  
98         //! Set the height of the game map
99         static void setHeight(int height){s_height = height;}
100
101         
102         //! Returns the width of the map
103         static int getWidth() {return s_width;}
104  
105         //! Returns the height of the map
106         static int getHeight() {return s_height;}
107
108         static Vector<int> get_dim() { return Vector<int>(s_width, s_height); }
109         
110         static Rectangle get_boundary()
111             { return Rectangle(0, 0, s_width, s_height); }
112
113         //! Returns the tileset in use
114         Tileset* getTileset() const {return d_tileSet;}
115
116         //! Returns the shieldset in use
117         Shieldset* getShieldset() const {return d_shieldSet;}
118
119         //! Returns the tileset in use
120         Cityset* getCityset() const {return d_citySet;}
121
122         //! Sets the tile object at position (x, y)
123         void setTile(int x, int y, Maptile *tile);
124         
125         //! Alternative setting
126         void setTile(Vector<int> p, Maptile *t) {return setTile(p.x, p.y, t);}
127
128         static City* getCity(Vector<int> pos);
129         static City* getCity(Movable *m) {return getCity(m->getPos());}
130
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);
157
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);
161
162         //! Get the tile object at position (x,y)
163         Maptile* getTile(int x, int y) const;
164
165         //! Alternative access
166         Maptile* getTile(Vector<int> p) const {return getTile(p.x, p.y);}
167
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);
172
173         //! Go find a player's planted standard on the map
174         Vector<int> findPlantedStandard(Player *p);
175
176         //! go find the player's stack, the slow way.
177         Vector<int> findStack(guint32 id);
178
179         /** Fill the map using the data supplied by a map generator
180           * 
181           * @param generator        the generator which supplies the data
182           * @return true on success, false on error
183           */
184         bool fill(MapGenerator* generator);
185
186         /** Fills the whole map with a single terrain.
187           *
188           * @param type             the type of the terrain(index in the tileset)
189           * @return true on success, false on error
190           */
191         bool fill(guint32 type);
192
193         /** Save the contents of the map
194           * 
195           * @param helper           see XML_Helper for more information
196           * @return true if saving went well, false otherwise
197           */
198         bool save(XML_Helper* helper) const;
199
200         //! figure out where a non-flying unit can't go
201         void calculateBlockedAvenues();
202         void calculateBlockedAvenue(int i, int j);
203         void updateStackPositions();
204
205         /** Smooth a portion of the map.
206          *
207          * Give each tile in the prescribed area the preferred picture for 
208          * the underlying terrain tile.
209          */
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);
214
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();
218
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);
223
224         void switchArmysets(Armyset *armyset);
225         void switchCityset(Cityset *cityset);
226         void switchShieldset(Shieldset *shieldset);
227         void switchTileset(Tileset *tileset);
228
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);
233
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);
239
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);
256
257         Location *getLocation(Vector<int> pos);
258
259         bool checkCityAccessibility();
260
261         static Vector<int> getCenterOfMap();
262
263         Rectangle putTerrain(Rectangle r, Tile::Type type, 
264                              int tile_style_id = -1, 
265                              bool always_alter_tilestyles = false);
266
267     protected:
268         //! Create the map with the given tileset
269         GameMap(std::string TilesetName, std::string ShieldsetName,
270                 std::string Citysetname);
271
272         //! Load the map using the given XML_Helper
273         GameMap(XML_Helper* helper);
274
275         ~GameMap();
276         
277     private:
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);
285
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);
289
290         int tile_is_connected_to_other_like_tiles (Tile::Type tile, int i, 
291                                                    int j);
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);
296
297         void updateShips(Vector<int> pos);
298
299
300         static std::list<Stack*> getNearbyStacks(Vector<int> pos, int dist, bool friendly);
301
302         static bool offmap(int x, int y);
303
304         // Data
305         static GameMap* s_instance;
306         static int s_width;
307         static int s_height;
308
309         Tileset* d_tileSet;
310         Shieldset* d_shieldSet;
311         Cityset* d_citySet;
312         Maptile** d_map;
313 };
314
315 #endif
316
317 // End of file