Adonthell  0.4
mapsquare.cc
Go to the documentation of this file.
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.cc
22  * @author Alexandre Courbot <alexandrecourbot@linuxgames.com>
23  *
24  * @brief Defines the mapsquare and mapsquare_area classes.
25  *
26  *
27  */
28 
29 
30 #include "mapsquare.h"
31 #include "mapobject.h"
32 #include "mapcharacter.h"
33 
35 {
36  mapobj = NULL;
37  is_base = false;
38 }
39 
41 {
42 }
43 
45 {
46  mchar = NULL;
47  is_base = false;
48 }
49 
51 {
52 }
53 
55 {
56  base_begin = tiles.end ();
58 }
59 
61 {
62  tiles = src.tiles;
63  mapchars = src.mapchars;
64 
65  // Correctly place the base tile square's base tile pointer.
66  list <mapsquare_tile>::iterator it;
67  for (it = tiles.begin ();
68  it != tiles.end () && *(it->base_tile) < *it; it++);
69  base_begin = it;
71 }
72 
74 {
75 }
76 
78 {
79  list <mapsquare_char>::iterator i;
80  for (i = mapchars.begin (); i != mapchars.end (); i++)
81  if (i->is_base)
82  return false;
83  return true;
84 }
85 
87 {
88  list <mapsquare_char>::iterator i;
89  for (i = mapchars.begin (); i != mapchars.end (); i++)
90  if (i->is_base)
91  return i->mchar;
92  return NULL;
93 }
94 
96 {
97 }
98 
100 {
101 }
102 
104 {
105  area.clear ();
106 }
107 
108 s_int8 mapsquare_area::put_mapobject (u_int16 px, u_int16 py, mapobject * mobj)
109 {
110  u_int16 i, j;
111  mapsquare_tile t;
112  list <mapsquare_tile>::iterator it;
113 
114  // Calculating where the object will start and end on the map.
115  u_int16 i0 = px - mobj->base_x () < 0 ? 0 : px - mobj->base_x ();
116  u_int16 j0 = py - mobj->base_y () < 0 ? 0 : py - mobj->base_y ();
117 
118  u_int16 ie = px + (mobj->area_length ()) - mobj->base_x () > area_length () ?
119  area_length () : px + (mobj->area_length ()) - mobj->base_x ();
120  u_int16 je = py + (mobj->area_height ()) - mobj->base_y () > area_height () ?
121  area_height () : py + (mobj->area_height ()) - mobj->base_y ();
122 
123  // Offset between square's position on the map and on the object.
124  s_int16 xoff = mobj->base_x () - px;
125  s_int16 yoff = mobj->base_y () - py;
126 
127 
128  // First place the base tile, as others refers to it...
129  t.mapobj = mobj;
130  t.is_base = true;
131  t.x = px;
132  t.y = py;
133 
134  // The iterator will be inserted AFTER all the others base tiles.
135  // Doing so, this object will be drawn last on this square.
136  for (it = area[px][py].tiles.begin ();
137  it != area[px][py].tiles.end () && *(it->base_tile) <= t; it++);
138  area[px][py].tiles.insert (it, t);
139  it--;
140  it->base_tile = it;
141 
142  // Update t so it refers to the base tile
143  t.base_tile = it;
144  t.is_base = false;
145 
146  // Now place the others tiles.
147  for (j = j0; j < je; j++)
148  for (i = i0; i < ie; i++)
149  {
150  mapsquare & s = area[i][j];
151  t.x = i;
152  t.y = j;
153  s.set_walkable (s.get_walkable () &
154  mobj->get_square (i + xoff, j + yoff)->get_walkable ());
155 
156  if (i != px || j != py)
157  {
158  for (it = s.tiles.begin ();
159  it != s.tiles.end () &&
160  *(it->base_tile) <= *(t.base_tile); it++);
161  s.tiles.insert (it, t);
162  }
163  }
164 
165  // Correctly place the base tile square's base tile pointer.
166  for (it = area[px][py].tiles.begin ();
167  it != area[px][py].tiles.end () && *(it->base_tile) < *it; it++);
168  area[px][py].base_begin = it;
169 
170  return 0;
171 }
172 
173 void mapsquare_area::remove_mapobject (u_int16 px, u_int16 py, mapobject * mobj)
174 {
175  u_int16 i, j;
176  list <mapsquare_tile>::iterator it;
177 
178  // Calculating where the object will start and end on the map.
179  u_int16 i0 = px - mobj->base_x () < 0 ? 0 : px - mobj->base_x ();
180  u_int16 j0 = py - mobj->base_y () < 0 ? 0 : py - mobj->base_y ();
181 
182  u_int16 ie = px + (mobj->area_length ()) - mobj->base_x () > area_length () ?
183  area_length () : px + (mobj->area_length ()) - mobj->base_x ();
184  u_int16 je = py + (mobj->area_height ()) - mobj->base_y () > area_height () ?
185  area_height () : py + (mobj->area_height ()) - mobj->base_y ();
186 
187  // Find the base tile, get it's reference (to remove others).
188  for (it = area[px][py].tiles.begin (); it != area[px][py].tiles.end () &&
189  !(it->is_base == true && it->mapobj == mobj); it++);
190 
191  // Base tile not found - better to return now...
192  if (it == area[px][py].tiles.end ()) return;
193 
194  // Keep the iterator available for further comparison
195  list <mapsquare_tile>::iterator the_base = it;
196 
197  // And now erase all the others tiles of this object.
198  for (j = j0; j < je; j++)
199  for (i = i0; i < ie; i++)
200  {
201  if (i != px || j != py)
202  {
203  mapsquare & s = area[i][j];
204 
205  for (it = s.tiles.begin (); it != s.tiles.end () && it->base_tile != the_base; it++);
206 
207  // Not found?? Weird - let's not mess with it then!
208  if (it == s.tiles.end ()) continue;
209 
210  s.tiles.erase (it);
211 
212  // Recalculate the walkability of this square.
214  for (it = s.tiles.begin (); it != s.tiles.end (); it++)
215  {
216  u_int16 wx = it->x - (it->base_tile->x - it->mapobj->base_x ());
217  u_int16 wy = it->y - (it->base_tile->y - it->mapobj->base_y ());
218  s.set_walkable (s.get_walkable () &
219  it->mapobj->get_square (wx, wy)->get_walkable ());
220  }
221  }
222  }
223  mapsquare & s = area[px][py];
224  // Erase the base tile
225  s.tiles.erase (the_base);
226  // Recalculate the walkability of this square.
228  for (it = s.tiles.begin (); it != s.tiles.end (); it++)
229  {
230  u_int16 wx = it->x - (it->base_tile->x - it->mapobj->base_x ());
231  u_int16 wy = it->y - (it->base_tile->y - it->mapobj->base_y ());
232  s.set_walkable (s.get_walkable () &
233  it->mapobj->get_square (wx, wy)->get_walkable ());
234  }
235 }
236 
238 {
239  vector <vector<mapsquare> >::iterator i;
240 
241  area.resize (nl);
242  for (i = area.begin (); i != area.end (); i++)
243  i->resize (nh);
244 
245  u_int16 j, k;
246  for (j = 0; j < nl; j++)
247  for (k = 0; k < nh; k++)
248  {
249  area[j][k].x_ = j;
250  area[j][k].y_ = k;
251  }
252 }
Declares the mapobject class.
u_int16 area_height() const
Returns the height of the area.
~mapsquare_char()
Destructor.
Definition: mapsquare.cc:50
bool is_free()
Returns whether the mapsquare is free for a character to go on or not.
Definition: mapsquare.cc:77
#define u_int16
16 bits long unsigned integer
Definition: types.h:38
Contains informations about the position of an object on a map.
Definition: mapsquare.h:47
~mapsquare_area()
Destructor.
Definition: mapsquare.cc:99
u_int16 area_length() const
Returns the length of the area.
u_int16 area_length() const
Returns the length of the area.
Definition: mapsquare.h:405
bool can_use_for_pathfinding
If == false, then this square will never be considered as walkable by pathfinding functions...
Definition: mapsquare.h:336
mapsquare()
Default constructor.
Definition: mapsquare.cc:54
~mapsquare_tile()
Destructor.
Definition: mapsquare.cc:40
mapcharacter * whoshere()
Return a pointer to the mapcharacter that occupies this mapsquare.
Definition: mapsquare.cc:86
u_int8 get_walkable() const
Gets the raw walkable parameter of a mapsquare.
Contains information about the walkability of a mapsquare.
mapsquare_area()
Default constructor.
Definition: mapsquare.cc:95
Base unit of a landsubmap, where you can place mapobjects or mapcharacters.
Definition: mapsquare.h:234
#define ALL_WALKABLE
Walkable from every side.
~mapsquare()
Destructor.
Definition: mapsquare.cc:73
#define s_int16
16 bits long signed integer
Definition: types.h:47
void resize_area(u_int16 nl, u_int16 nh)
Resize the area.
Definition: mapsquare.cc:237
void set_walkable(u_int8 w)
Sets the walkable parameter of a mapsquare.
mapsquare_walkable * get_square(u_int16 x, u_int16 y) const
Returns a pointer to a desired square.
u_int16 base_x() const
Returns the X offset of the base square of this object.
void clear()
Totally clears the area.
Definition: mapsquare.cc:103
Representation of characters on a landmap.
Definition: mapcharacter.h:139
Declares the mapsquare and mapsquare_area classes.
mapsquare_char()
Default constructor.
Definition: mapsquare.cc:44
Declares the mapcharacter class.
u_int16 area_height() const
Returns the height of the area.
Definition: mapsquare.h:416
u_int16 base_y() const
Returns the Y offset of the base square of this object.
#define s_int8
8 bits long signed integer
Definition: types.h:44
mapsquare_tile()
Default constructor.
Definition: mapsquare.cc:34
Objects that can be placed on a landmap.
Definition: mapobject.h:50