1 /*
2    Copyright (C) 2001   Alexandre Courbot
3    Part of the Adonthell Project <http://adonthell.nongnu.org>
4 
5    Adonthell is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9 
10    Adonthell is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14 
15    You should have received a copy of the GNU General Public License
16    along with Adonthell.  If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 
20 /**
21  * @file   mapsquare.h
22  * @author Alexandre Courbot <alexandrecourbot@linuxgames.com>
23  *
24  * @brief  Declares the mapsquare and mapsquare_area classes.
25  *
26  *
27  */
28 
29 
30 #ifndef MAPSQUARE_H_
31 #define MAPSQUARE_H_
32 
33 #include <list>
34 
35 #include "mapsquare_walkable.h"
36 
37 class mapobject;
38 class mapcharacter;
39 
40 /**
41  * Contains informations about the position of an object on a map.
42  *
43  * Objects of this class has no reason to exist outside of a mapsquare.
44  * You'll NEVER want to manipulate this class directly - only mapsquare,
45  * mapsquare_area and landmap will.
46  */
47 class mapsquare_tile
48 {
49 public:
50     /**
51      * Default constructor.
52      */
53     mapsquare_tile ();
54 
55     /**
56      * Destructor.
57      */
58     ~mapsquare_tile ();
59 
60 #ifndef SWIG
61     /**
62      * Compare the location on the landsubmap of two mapsquare_tiles.
63      * A mapsquare_tile is < to another if it's Y position is < to the other
64      * one's or if it's Y position == the other one's and it's X position is
65      * < to the other one's.
66      *
67      * @attention Not available from Python.
68      *
69      * @sa operator <=  ()
70      * @sa operator ==  ()
71      */
72     bool operator < (const mapsquare_tile & mt) const
73     {
74         return (mt.y > y || (mt.y == y && mt.x > x));
75     }
76 
77     /**
78      * Compare the location on the landsubmap of two mapsquare_tiles.
79      * A mapsquare_tile is <= to another if it's Y position is < to the other
80      * one's or if it's Y position == the other one's and it's X position is
81      * <=  to the other one's.
82      *
83      * @attention Not available from Python.
84      *
85      * @sa operator < ()
86      * @sa operator == ()
87      */
88     bool operator <= (const mapsquare_tile & mt) const
89     {
90         return (mt.y > y || (mt.y == y && mt.x >= x));
91     }
92 
93     /**
94      * Compare the location on the landsubmap of two mapsquare_tiles.
95      * A mapsquare_tile is ==  to another if their X and Y position are
96      * equal.
97      *
98      * @attention Not available from Python.
99      *
100      * @sa operator < ()
101      * @sa operator <= ()
102      */
103     bool operator == (const mapsquare_tile & mt) const
104     {
105         return (mt.y == y && mt.x == x);
106     }
107 #endif
108 
109 
110 private:
111     /// Pointer to the object here.
112     mapobject * mapobj;
113 
114     /// Is this mapsquare_tile a base square?
115     bool is_base;
116 
117 #ifndef SWIG
118     /// Iterator to the base tile of this mapsquare_tile.
119     list <mapsquare_tile>::iterator base_tile;
120 #endif
121 
122     /// x and y positions.
123     u_int16 x, y;
124 
125 #ifndef SWIG
126     friend class mapsquare;
127     friend class mapsquare_area;
128     friend class landmap;
129     friend class mapview;
130 #endif
131 };
132 
133 
134 /**
135  * Contains informations about the position of a character on a map.
136  *
137  * Objects of this class has no reason to exist outside of a mapsquare.
138  * You'll NEVER want to manipulate this class directly - only mapsquare,
139  * mapsquare_area and landmap will.
140  */
141 class mapsquare_char
142 {
143 public:
144     /**
145      * Default constructor.
146      */
147     mapsquare_char ();
148 
149     /**
150      * Destructor.
151      */
152     ~mapsquare_char ();
153 
154 #ifndef SWIG
155     /**
156      * Compare the location on the landsubmap of two mapsquare_chars.
157      * A mapsquare_char is < to another if it's Y position is < to the other
158      * one's or if it's Y position == the other one's and it's X position is
159      * < to the other one's.
160      * @sa operator <=  ()
161      * @sa operator ==  ()
162      */
163     bool operator < (const mapsquare_char & mt) const
164     {
165         return (mt.y > y || (mt.y == y && mt.x > x));
166     }
167 
168     /**
169      * Compare the location on the landsubmap of two mapsquare_chars.
170      * A mapsquare_char is <= to another if it's Y position is < to the other
171      * one's or if it's Y position == the other one's and it's X position is
172      * <=  to the other one's.
173      * @sa operator < ()
174      * @sa operator == ()
175      */
176     bool operator <= (const mapsquare_char & mt) const
177     {
178         return (mt.y > y || (mt.y == y && mt.x >= x));
179     }
180 
181     /**
182      * Compare the location on the landsubmap of two mapsquare_chars.
183      * A mapsquare_char is ==  to another if their X and Y position are
184      * equal.
185      * @sa operator < ()
186      * @sa operator <= ()
187      */
188     bool operator == (const mapsquare_char & mt) const
189     {
190         return (mt.y == y && mt.x == x);
191     }
192 #endif
193 
194 private:
195     /// Pointer to the mapcharacter concerned by this mapchar_square.
196     mapcharacter *mchar;
197 
198     /// Is it the base tile?
199     bool is_base;
200 
201     /// Is this mapsquare_tile walkable?
202     bool walkable;
203 
204 #ifndef SWIG
205     /// Iterator to the base tile of this mapsquare_char.
206     list <mapsquare_char>::iterator base_tile;
207 #endif
208 
209     /// x and y positions.
210     u_int16 x, y;
211 
212 #ifndef SWIG
213     friend class mapcharacter;
214     friend class mapsquare;
215     friend class landmap;
216     friend class mapview;
217 #endif
218 };
219 
220 
221 /**
222  * Base unit of a landsubmap, where you can place mapobjects or mapcharacters.
223  * A landsubmap is a 2 dimensionnal array of mapsquares. When a mapobject is
224  * placed on a landsubmap, it belongs to one or several mapsquares. A mapsquare
225  * is made of a list of mapsquare_tiles, containing informations about the objects
226  * that are on it, and a list of mapsquare_char, which informs about the mapcharacters
227  * here. This make it possible to have several mapobjects
228  * and mapcharacters on the same mapsquare.
229  *
230  * These two lists are sorted by the position of the object or mapcharacter's base square
231  * on the map. This make it fast to iterate through the lists during drawing, as we always
232  * want to iterate the list in this order.
233  */
234 class mapsquare : public mapsquare_walkable
235 {
236 public:
237     /**
238      * Default constructor.
239      *
240      */
241     mapsquare ();
242 
243 #ifndef SWIG
244     /**
245      * Copy constructor.
246      *
247      */
248     mapsquare (const mapsquare& src);
249 #endif
250 
251     /**
252      * Destructor.
253      *
254      */
255     ~mapsquare ();
256 
257     /**
258      * Returns the X position of this mapsquare.
259      *
260      *
261      * @return X position of this mapsquare.
262      */
x()263     u_int16 x ()
264     {
265         return x_;
266     }
267 
268     /**
269      * Returns the Y position of this mapsquare.
270      *
271      *
272      * @return Y position of this mapsquare.
273      */
y()274     u_int16 y ()
275     {
276         return y_;
277     }
278 
279     /**
280      * Returns whether the mapsquare is free for a character to go on or not.
281      * It only checks if a mapcharacter is already here. It doesn't deal with the
282      * walkable problem.
283      * @return
284      *         - false if the mapsquare isn't free.
285      *         - true if the mapsquare is free.
286      */
287     bool is_free ();
288 
289     /**
290      * Return a pointer to the mapcharacter that occupies this mapsquare.
291      *
292      * @return pointer to the mapcharacter that occupies the mapsquare, NULL if none.
293      */
294     mapcharacter *whoshere ();
295 
296     /**
297      * @name Pathfinding data members.
298      *
299      * These members are here to allow faster and more efficient
300      * pathfinding. Though they can as well be used for something else,
301      * but their value isn't guaranteed to stay constant. It is safe
302      * to modify them however, so they are public and uninitialised.
303      *
304      */
305     //@{
306 
307     /**
308      * Distance from the source square.
309      *
310      */
311     u_int16 g;
312 
313     /**
314      * Estimated distance to the goal square.
315      *
316      */
317     u_int16 h;
318 
319     /**
320      * Sum of g + h.
321      *
322      */
323     u_int16 f;
324 
325     /**
326      * Parent square for the path
327      *
328      */
329     mapsquare * parent;
330 
331     /**
332      * If == false, then this square will never be considered
333      * as walkable by pathfinding functions.
334      *
335      */
336     bool can_use_for_pathfinding;
337 
338     //@}
339 
340 private:
341 #ifndef SWIG
342     /// List of mapsquare_tiles.
343     list <mapsquare_tile> tiles;
344 
345     /// Iterator to where the base tiles begin.
346     /// This serves as an "accelerator" for mapview::draw () which
347     /// can go directly to the base tiles of a squares with this
348     /// iterator.
349     list <mapsquare_tile>::iterator base_begin;
350 
351     /// List of mapsquare_chars.
352     list <mapsquare_char> mapchars;
353 
354     /// Coordinates of the square.
355     u_int16 x_, y_;
356 
357     friend class mapcharacter;
358     friend class mapsquare_area;
359     friend class landmap;
360     friend class mapview;
361 #endif
362 };	  // mapsquare
363 
364 /**
365  * Area of mapsquares, for use with landmap.
366  *
367  * This class has no reason to exist is not belonging
368  * to a landmap. You'll NEVER use this class directly -
369  * anyway you can't do anything usefull with it alone.
370  *
371  */
372 class mapsquare_area
373 {
374 public:
375     /**
376      * Default constructor.
377      *
378      */
379     mapsquare_area ();
380 
381     /**
382      * Destructor.
383      *
384      */
385     ~mapsquare_area ();
386 
387     /**
388      * Totally clears the area.
389      *
390      */
391     void clear ();
392 
393     /**
394      * @name Area settings
395      *
396      */
397     //@{
398 
399     /**
400      * Returns the length of the area.
401      *
402      * @return length (in number of squares) of the area.
403      *
404      */
area_length()405     u_int16 area_length () const
406     {
407         return area.size ();
408     }
409 
410     /**
411      * Returns the height of the area.
412      *
413      * @return height (in number of squares) of the area.
414      *
415      */
area_height()416     u_int16 area_height () const
417     {
418         if (area.size ()) return area[0].size ();
419         else return 0;
420     }
421 
422     /**
423      * Returns a pointer to a desired square.
424      *
425      * @param x X position of the square to get.
426      * @param y Y position of the square to get.
427      *
428      * @return pointer to the (x,y) square.
429      */
get_square(u_int16 x,u_int16 y)430     mapsquare * get_square (u_int16 x, u_int16 y) const
431     {
432         return &(area[x][y]);
433     }
434 
435     /**
436      * Resize the area.
437      *
438      * @param nl new length (in number of squares) of the area.
439      * @param nh new height (in number of squares) of the area.
440      */
441     void resize_area (u_int16 nl, u_int16 nh);
442 
443     //@}
444 
445 private:
446     /**
447      * Forbids value passing.
448      *
449      */
450     mapsquare_area (const mapsquare_area& src);
451 
452 #ifndef SWIG
453     /**
454      * Forbids mapsquare_area copy.
455      *
456      */
457     mapsquare_area & operator = (const mapsquare_area & mo);
458 #endif
459 
460     /**
461      * Place a mapobject on the submap.
462      *
463      * @param px X position of the base square of the object.
464      * @param py Y position of the base square of the object.
465      * @param mobj pointer to the mapobject to remove.
466      */
467      s_int8 put_mapobject (u_int16 px, u_int16 py, mapobject * mobj);
468 
469     /**
470      * Remove a mapobject from the submap.
471      *
472      * @param px X position of the base square of the object.
473      * @param py Y position of the base square of the object.
474      * @param mobj pointer to the mapobject to remove.
475      */
476     void remove_mapobject (u_int16 px, u_int16 py, mapobject * mobj);
477 
478     /**
479      * 2 dimensionnal array of mapsquares - the actual map
480      *
481      */
482 #ifndef SWIG
483     mutable vector <vector<mapsquare> > area;
484 
485     friend class mapcharacter;
486     friend class mapview;
487     friend class landmap;
488 #endif
489 };
490 
491 #endif
492