PageRenderTime 42ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/adonthell-0.3.5/src/landmap.cc

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