Adonthell  0.4
landmap.cc
Go to the documentation of this file.
1 /*
2  $Id: landmap.cc,v 1.20 2002/08/09 20:01:26 ksterker Exp $
3 
4  Copyright (C) 1999/2000/2001 Alexandre Courbot
5  Part of the Adonthell Project http://adonthell.linuxgames.com
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.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 
16 /**
17  * @file landmap.cc
18  * Defines the landmap class.
19  */
20 
21 
22 #include "landmap.h"
23 #include "character.h"
24 
25 using namespace std;
26 
27 
29 {
30 }
31 
33 {
34  clear ();
35 }
36 
38 {
39  // Clear all events
41 
42  // Remove all mapcharacters from this map.
43  while (mapchar.size ())
44  mapchar.front ()->remove_from_map ();
45 
46  // Delete all mapobjects
47  vector <mapobject *>::iterator io;
48  for (io = mobj.begin (); io != mobj.end (); io++)
49  delete (*io);
50  mobj.clear ();
51 
52  // Delete all mapobjects filenames
53  mobjsrc.clear ();
54 
55  // Delete all submaps
56  vector <mapsquare_area *>::iterator is;
57  for (is = submap.begin (); is != submap.end (); is++)
58  delete (*is);
59  submap.clear ();
60 
61  // Reset the filename.
62  filename_ = "";
63 }
64 
66 {
67  // Update mapobjects
68  vector <mapobject *>::iterator io;
69  for (io = mobj.begin (); io != mobj.end (); io++)
70  (*io)->update ();
71 
72  // Update mapcharacters
73  vector <mapcharacter *>::iterator ic;
74  for (ic = mapchar.begin (); ic != mapchar.end (); ic++)
75  (*ic)->update ();
76 }
77 
79 {
80  u_int16 i, j;
81  string tstr;
82 
83  clear ();
84 
85  // Load mapobjects
86  i << file;
87  for (; i; i--)
88  {
89  mapobject * tobj = new mapobject;
90  tstr << file;
91  tobj->load (tstr);
92  insert_mapobject (tobj, nbr_of_mapobjects (), tstr.c_str ());
93  }
94 
95  // Load submaps
96  i << file;
97  for (j = 0; j < i; j++)
98  {
100  mapsquare_area * sm = submap[j];
101 
102  u_int16 k, l;
103  k << file;
104  l << file;
105  sm->resize_area (k, l);
106 
107  for (l = 0; l < sm->area_height (); l++)
108  for (k = 0; k < sm->area_length (); k++)
109  {
110  sm->area[k][l].can_use_for_pathfinding << file;
111  u_int16 n, t;
112  // Read the number of mapobjects which have their base tile here
113  n << file;
114  while (n)
115  {
116  // Get the mapobject number
117  t << file;
118  sm->put_mapobject (k, l, mobj[t]);
119  n--;
120  }
121  }
122  }
123 
124  return 0;
125 }
126 
127 s_int8 landmap::load (string fname)
128 {
129  igzstream file;
130  s_int8 retvalue = -1;
131  string fdef (MAPS_DIR);
132 
133  fdef += fname;
134  file.open (fdef);
135  if (!file.is_open ())
136  return -1;
137  if (fileops::get_version (file, 1, 1, fdef))
138  retvalue = get (file);
139  file.close ();
140  filename_ = fname;
141  return retvalue;
142 }
143 
145 {
146  u_int16 i;
147 
148  // Save mapobjects
149  nbr_of_mapobjects () >> file;
150  for (i = 0; i < nbr_of_mapobjects (); i++)
151  {
152  mobjsrc[i] >> file;
153  }
154 
155  // Save submaps
156  nbr_of_submaps () >> file;
157  for (i = 0; i < nbr_of_submaps (); i++)
158  {
159  u_int16 k, l;
160 
161  submap[i]->area_length () >> file;
162  submap[i]->area_height () >> file;
163 
164  for (l = 0; l < submap[i]->area_height (); l++)
165  for (k = 0; k < submap[i]->area_length (); k++)
166  {
167  u_int16 nbr_base = 0;
168  submap[i]->area[k][l].can_use_for_pathfinding >> file;
169  list <mapsquare_tile>::iterator it = submap[i]->area[k][l].tiles.begin ();
170  while (it != submap[i]->area[k][l].tiles.end ())
171  {
172  if (it->is_base) nbr_base++;
173  it++;
174  }
175  nbr_base >> file;
176 
177  it = submap[i]->area[k][l].tiles.begin ();
178  while (it != submap[i]->area[k][l].tiles.end ())
179  {
180  if (it->is_base)
181  {
182  u_int16 y = 0;
183  while (mobj[y] != (*it).mapobj) y++;
184  y >> file;
185  }
186  it++;
187  }
188  }
189  }
190  return 0;
191 }
192 
193 s_int8 landmap::save (string fname)
194 {
195  ogzstream file (MAPS_DIR + fname);
196  u_int8 retvalue;
197 
198  if (!file.is_open ())
199  return -1;
200  fileops::put_version (file, 1);
201  retvalue = put (file);
202  file.close ();
203  filename_ = fname;
204  return retvalue;
205 }
206 
208 {
209  mapcharacter *mc = NULL;
210  u_int16 nbr_of;
211  string id;
212 
213  // try to load event list
214  if (!event_list::get_state (file))
215  return false;
216 
217  // Load the mapcharacters
218  nbr_of << file;
219 
220  for (u_int16 i = 0; i < nbr_of; i++)
221  {
222  id << file;
223 
224  mc = (mapcharacter *) data::characters[id.c_str ()];
225  mc->set_map (this);
226  mc->get_state (file);
227  }
228 
229  return true;
230 }
231 
233 {
234  u_int16 nbr_of = nbr_of_mapcharacters ();
235  string id;
236 
237  // save all events attached to this map
238  event_list::put_state (file);
239 
240  // Save the mapcharacters and their status
241  nbr_of >> file;
242 
243  for (u_int16 i = 0; i < nbr_of; i++)
244  {
245  mapcharacter *mc = mapchar[i];
246 
247  id = mc->get_id ();
248  id >> file;
249 
250  mc->put_state (file);
251  }
252 
253  return 0;
254 }
255 
257  string srcfile)
258 {
259  if (pos > nbr_of_mapobjects ())
260  return -2;
261 
262  vector <mapobject *>::iterator i = mobj.begin ();
263  vector <string>::iterator j = mobjsrc.begin ();
264 
265  while (pos--)
266  {
267  i++;
268  j++;
269  }
270 
271  mobj.insert (i, an);
272  mobjsrc.insert (j, srcfile);
273 
274  return 0;
275 }
276 
278 {
279  mapobject * dptr = mobj[pos];
280 
281  // Update all the submaps to delete any mapsquare_tile that points
282  // to the deleted object.
283  u_int16 k;
284  for (k = 0; k < nbr_of_submaps (); k++)
285  {
286  u_int16 i, j;
287  for (i = 0; i < submap[k]->area_length (); i++)
288  for (j = 0; j < submap[k]->area_height (); j++)
289  {
290  mapsquare & ms = submap[k]->area[i][j];
291  list <mapsquare_tile>::iterator imt;
292  for (imt = ms.tiles.begin (); imt != ms.tiles.end (); imt++)
293  if (imt->mapobj == dptr)
294  {
295  remove_mapobject (k, i, j, pos);
296 
297  // The iterator is invalidated by the delete operation
298  imt = ms.tiles.begin ();
299  }
300  }
301  }
302 
303  vector <mapobject *>::iterator i;
304 
305  if (pos > nbr_of_mapobjects () - 1)
306  return -2;
307 
308  i = mobj.begin ();
309  while (pos--) i++;
310 
311  delete (*i);
312  mobj.erase (i);
313 
314  return 0;
315 }
316 
318 {
319  if (pos > nbr_of_mapobjects ())
320  return -2;
321 
322  // Update the mapcharacters so they are on the same map as before.
323  vector <mapcharacter *>::iterator ic;
324  for (ic = mapchar.begin (); ic != mapchar.end (); ic++)
325  if ((*ic)->submap_ >= pos) (*ic)->submap_++;
326 
327  // Insert the submap
328  vector <mapsquare_area *>::iterator i = submap.begin ();
329  while (pos--) i++;
330 
331  mapsquare_area * t = new mapsquare_area;
332  submap.insert (i, t);
333 
334  return 0;
335 }
336 
338 {
339  // Update the mapcharacters so they are on the same map as before
340  // and remove those who were on the deleted map.
341  vector <mapcharacter *>::iterator ic;
342  for (ic = mapchar.begin (); ic != mapchar.end (); ic++)
343  {
344  if ((*ic)->submap_ > pos) (*ic)->submap_--;
345  else if ((*ic)->submap_ == pos)
346  (*ic)->remove_from_map ();
347  }
348 
349  // Suppress the submap
350  vector <mapsquare_area *>::iterator i;
351 
352  if (pos > nbr_of_submaps () - 1)
353  return -2;
354 
355  i = submap.begin ();
356  while (pos--) i++;
357 
358  delete (*i);
359  submap.erase (i);
360 
361  return 0;
362 }
363 
365  u_int16 mobjnbr)
366 {
367  return submap[smap]->put_mapobject (px, py, mobj[mobjnbr]);
368 }
369 
371  u_int16 mobjnbr)
372 {
373  submap[smap]->remove_mapobject (px, py, mobj[mobjnbr]);
374 }