Adonthell
0.4
|
00001 /* 00002 $Id: landmap.cc,v 1.20 2002/08/09 20:01:26 ksterker Exp $ 00003 00004 Copyright (C) 1999/2000/2001 Alexandre Courbot 00005 Part of the Adonthell Project http://adonthell.linuxgames.com 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License. 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY. 00011 00012 See the COPYING file for more details. 00013 */ 00014 00015 00016 /** 00017 * @file landmap.cc 00018 * Defines the landmap class. 00019 */ 00020 00021 00022 #include "landmap.h" 00023 #include "character.h" 00024 00025 using namespace std; 00026 00027 00028 landmap::landmap () : event_list () 00029 { 00030 } 00031 00032 landmap::~landmap () 00033 { 00034 clear (); 00035 } 00036 00037 void landmap::clear () 00038 { 00039 // Clear all events 00040 event_list::clear (); 00041 00042 // Remove all mapcharacters from this map. 00043 while (mapchar.size ()) 00044 mapchar.front ()->remove_from_map (); 00045 00046 // Delete all mapobjects 00047 vector <mapobject *>::iterator io; 00048 for (io = mobj.begin (); io != mobj.end (); io++) 00049 delete (*io); 00050 mobj.clear (); 00051 00052 // Delete all mapobjects filenames 00053 mobjsrc.clear (); 00054 00055 // Delete all submaps 00056 vector <mapsquare_area *>::iterator is; 00057 for (is = submap.begin (); is != submap.end (); is++) 00058 delete (*is); 00059 submap.clear (); 00060 00061 // Reset the filename. 00062 filename_ = ""; 00063 } 00064 00065 void landmap::update () 00066 { 00067 // Update mapobjects 00068 vector <mapobject *>::iterator io; 00069 for (io = mobj.begin (); io != mobj.end (); io++) 00070 (*io)->update (); 00071 00072 // Update mapcharacters 00073 vector <mapcharacter *>::iterator ic; 00074 for (ic = mapchar.begin (); ic != mapchar.end (); ic++) 00075 (*ic)->update (); 00076 } 00077 00078 s_int8 landmap::get (igzstream& file) 00079 { 00080 u_int16 i, j; 00081 string tstr; 00082 00083 clear (); 00084 00085 // Load mapobjects 00086 i << file; 00087 for (; i; i--) 00088 { 00089 mapobject * tobj = new mapobject; 00090 tstr << file; 00091 tobj->load (tstr); 00092 insert_mapobject (tobj, nbr_of_mapobjects (), tstr.c_str ()); 00093 } 00094 00095 // Load submaps 00096 i << file; 00097 for (j = 0; j < i; j++) 00098 { 00099 insert_submap (nbr_of_submaps ()); 00100 mapsquare_area * sm = submap[j]; 00101 00102 u_int16 k, l; 00103 k << file; 00104 l << file; 00105 sm->resize_area (k, l); 00106 00107 for (l = 0; l < sm->area_height (); l++) 00108 for (k = 0; k < sm->area_length (); k++) 00109 { 00110 sm->area[k][l].can_use_for_pathfinding << file; 00111 u_int16 n, t; 00112 // Read the number of mapobjects which have their base tile here 00113 n << file; 00114 while (n) 00115 { 00116 // Get the mapobject number 00117 t << file; 00118 sm->put_mapobject (k, l, mobj[t]); 00119 n--; 00120 } 00121 } 00122 } 00123 00124 return 0; 00125 } 00126 00127 s_int8 landmap::load (string fname) 00128 { 00129 igzstream file; 00130 s_int8 retvalue = -1; 00131 string fdef (MAPS_DIR); 00132 00133 fdef += fname; 00134 file.open (fdef); 00135 if (!file.is_open ()) 00136 return -1; 00137 if (fileops::get_version (file, 1, 1, fdef)) 00138 retvalue = get (file); 00139 file.close (); 00140 filename_ = fname; 00141 return retvalue; 00142 } 00143 00144 s_int8 landmap::put (ogzstream& file) const 00145 { 00146 u_int16 i; 00147 00148 // Save mapobjects 00149 nbr_of_mapobjects () >> file; 00150 for (i = 0; i < nbr_of_mapobjects (); i++) 00151 { 00152 mobjsrc[i] >> file; 00153 } 00154 00155 // Save submaps 00156 nbr_of_submaps () >> file; 00157 for (i = 0; i < nbr_of_submaps (); i++) 00158 { 00159 u_int16 k, l; 00160 00161 submap[i]->area_length () >> file; 00162 submap[i]->area_height () >> file; 00163 00164 for (l = 0; l < submap[i]->area_height (); l++) 00165 for (k = 0; k < submap[i]->area_length (); k++) 00166 { 00167 u_int16 nbr_base = 0; 00168 submap[i]->area[k][l].can_use_for_pathfinding >> file; 00169 list <mapsquare_tile>::iterator it = submap[i]->area[k][l].tiles.begin (); 00170 while (it != submap[i]->area[k][l].tiles.end ()) 00171 { 00172 if (it->is_base) nbr_base++; 00173 it++; 00174 } 00175 nbr_base >> file; 00176 00177 it = submap[i]->area[k][l].tiles.begin (); 00178 while (it != submap[i]->area[k][l].tiles.end ()) 00179 { 00180 if (it->is_base) 00181 { 00182 u_int16 y = 0; 00183 while (mobj[y] != (*it).mapobj) y++; 00184 y >> file; 00185 } 00186 it++; 00187 } 00188 } 00189 } 00190 return 0; 00191 } 00192 00193 s_int8 landmap::save (string fname) 00194 { 00195 ogzstream file (MAPS_DIR + fname); 00196 u_int8 retvalue; 00197 00198 if (!file.is_open ()) 00199 return -1; 00200 fileops::put_version (file, 1); 00201 retvalue = put (file); 00202 file.close (); 00203 filename_ = fname; 00204 return retvalue; 00205 } 00206 00207 s_int8 landmap::get_state (igzstream& file) 00208 { 00209 mapcharacter *mc = NULL; 00210 u_int16 nbr_of; 00211 string id; 00212 00213 // try to load event list 00214 if (!event_list::get_state (file)) 00215 return false; 00216 00217 // Load the mapcharacters 00218 nbr_of << file; 00219 00220 for (u_int16 i = 0; i < nbr_of; i++) 00221 { 00222 id << file; 00223 00224 mc = (mapcharacter *) data::characters[id.c_str ()]; 00225 mc->set_map (this); 00226 mc->get_state (file); 00227 } 00228 00229 return true; 00230 } 00231 00232 s_int8 landmap::put_state (ogzstream& file) const 00233 { 00234 u_int16 nbr_of = nbr_of_mapcharacters (); 00235 string id; 00236 00237 // save all events attached to this map 00238 event_list::put_state (file); 00239 00240 // Save the mapcharacters and their status 00241 nbr_of >> file; 00242 00243 for (u_int16 i = 0; i < nbr_of; i++) 00244 { 00245 mapcharacter *mc = mapchar[i]; 00246 00247 id = mc->get_id (); 00248 id >> file; 00249 00250 mc->put_state (file); 00251 } 00252 00253 return 0; 00254 } 00255 00256 s_int8 landmap::insert_mapobject (mapobject * an, u_int16 pos, 00257 string srcfile) 00258 { 00259 if (pos > nbr_of_mapobjects ()) 00260 return -2; 00261 00262 vector <mapobject *>::iterator i = mobj.begin (); 00263 vector <string>::iterator j = mobjsrc.begin (); 00264 00265 while (pos--) 00266 { 00267 i++; 00268 j++; 00269 } 00270 00271 mobj.insert (i, an); 00272 mobjsrc.insert (j, srcfile); 00273 00274 return 0; 00275 } 00276 00277 s_int8 landmap::delete_mapobject (u_int16 pos) 00278 { 00279 mapobject * dptr = mobj[pos]; 00280 00281 // Update all the submaps to delete any mapsquare_tile that points 00282 // to the deleted object. 00283 u_int16 k; 00284 for (k = 0; k < nbr_of_submaps (); k++) 00285 { 00286 u_int16 i, j; 00287 for (i = 0; i < submap[k]->area_length (); i++) 00288 for (j = 0; j < submap[k]->area_height (); j++) 00289 { 00290 mapsquare & ms = submap[k]->area[i][j]; 00291 list <mapsquare_tile>::iterator imt; 00292 for (imt = ms.tiles.begin (); imt != ms.tiles.end (); imt++) 00293 if (imt->mapobj == dptr) 00294 { 00295 remove_mapobject (k, i, j, pos); 00296 00297 // The iterator is invalidated by the delete operation 00298 imt = ms.tiles.begin (); 00299 } 00300 } 00301 } 00302 00303 vector <mapobject *>::iterator i; 00304 00305 if (pos > nbr_of_mapobjects () - 1) 00306 return -2; 00307 00308 i = mobj.begin (); 00309 while (pos--) i++; 00310 00311 delete (*i); 00312 mobj.erase (i); 00313 00314 return 0; 00315 } 00316 00317 s_int8 landmap::insert_submap (u_int16 pos) 00318 { 00319 if (pos > nbr_of_mapobjects ()) 00320 return -2; 00321 00322 // Update the mapcharacters so they are on the same map as before. 00323 vector <mapcharacter *>::iterator ic; 00324 for (ic = mapchar.begin (); ic != mapchar.end (); ic++) 00325 if ((*ic)->submap_ >= pos) (*ic)->submap_++; 00326 00327 // Insert the submap 00328 vector <mapsquare_area *>::iterator i = submap.begin (); 00329 while (pos--) i++; 00330 00331 mapsquare_area * t = new mapsquare_area; 00332 submap.insert (i, t); 00333 00334 return 0; 00335 } 00336 00337 s_int8 landmap::delete_submap (u_int16 pos) 00338 { 00339 // Update the mapcharacters so they are on the same map as before 00340 // and remove those who were on the deleted map. 00341 vector <mapcharacter *>::iterator ic; 00342 for (ic = mapchar.begin (); ic != mapchar.end (); ic++) 00343 { 00344 if ((*ic)->submap_ > pos) (*ic)->submap_--; 00345 else if ((*ic)->submap_ == pos) 00346 (*ic)->remove_from_map (); 00347 } 00348 00349 // Suppress the submap 00350 vector <mapsquare_area *>::iterator i; 00351 00352 if (pos > nbr_of_submaps () - 1) 00353 return -2; 00354 00355 i = submap.begin (); 00356 while (pos--) i++; 00357 00358 delete (*i); 00359 submap.erase (i); 00360 00361 return 0; 00362 } 00363 00364 s_int8 landmap::put_mapobject (u_int16 smap, u_int16 px, u_int16 py, 00365 u_int16 mobjnbr) 00366 { 00367 return submap[smap]->put_mapobject (px, py, mobj[mobjnbr]); 00368 } 00369 00370 void landmap::remove_mapobject (u_int16 smap, u_int16 px, u_int16 py, 00371 u_int16 mobjnbr) 00372 { 00373 submap[smap]->remove_mapobject (px, py, mobj[mobjnbr]); 00374 }