Adonthell
0.4
|
00001 /* 00002 $Id: mapsquare.cc,v 1.8 2001/08/29 07:40:33 gnurou Exp $ 00003 00004 Copyright (C) 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 mapsquare.cc 00018 * @author Alexandre Courbot <alexandrecourbot@linuxgames.com> 00019 * 00020 * @brief Defines the mapsquare and mapsquare_area classes. 00021 * 00022 * 00023 */ 00024 00025 00026 #include "mapsquare.h" 00027 #include "mapobject.h" 00028 #include "mapcharacter.h" 00029 00030 mapsquare_tile::mapsquare_tile () 00031 { 00032 mapobj = NULL; 00033 is_base = false; 00034 } 00035 00036 mapsquare_tile::~mapsquare_tile () 00037 { 00038 } 00039 00040 mapsquare_char::mapsquare_char () 00041 { 00042 mchar = NULL; 00043 is_base = false; 00044 } 00045 00046 mapsquare_char::~mapsquare_char () 00047 { 00048 } 00049 00050 mapsquare::mapsquare () : mapsquare_walkable () 00051 { 00052 base_begin = tiles.end (); 00053 can_use_for_pathfinding = true; 00054 } 00055 00056 mapsquare::mapsquare (const mapsquare& src) : mapsquare_walkable () 00057 { 00058 tiles = src.tiles; 00059 mapchars = src.mapchars; 00060 00061 // Correctly place the base tile square's base tile pointer. 00062 list <mapsquare_tile>::iterator it; 00063 for (it = tiles.begin (); 00064 it != tiles.end () && *(it->base_tile) < *it; it++); 00065 base_begin = it; 00066 can_use_for_pathfinding = src.can_use_for_pathfinding; 00067 } 00068 00069 mapsquare::~mapsquare () 00070 { 00071 } 00072 00073 bool mapsquare::is_free () 00074 { 00075 list <mapsquare_char>::iterator i; 00076 for (i = mapchars.begin (); i != mapchars.end (); i++) 00077 if (i->is_base) 00078 return false; 00079 return true; 00080 } 00081 00082 mapcharacter * mapsquare::whoshere () 00083 { 00084 list <mapsquare_char>::iterator i; 00085 for (i = mapchars.begin (); i != mapchars.end (); i++) 00086 if (i->is_base) 00087 return i->mchar; 00088 return NULL; 00089 } 00090 00091 mapsquare_area::mapsquare_area () 00092 { 00093 } 00094 00095 mapsquare_area::~mapsquare_area () 00096 { 00097 } 00098 00099 void mapsquare_area::clear () 00100 { 00101 area.clear (); 00102 } 00103 00104 s_int8 mapsquare_area::put_mapobject (u_int16 px, u_int16 py, mapobject * mobj) 00105 { 00106 u_int16 i, j; 00107 mapsquare_tile t; 00108 list <mapsquare_tile>::iterator it; 00109 00110 // Calculating where the object will start and end on the map. 00111 u_int16 i0 = px - mobj->base_x () < 0 ? 0 : px - mobj->base_x (); 00112 u_int16 j0 = py - mobj->base_y () < 0 ? 0 : py - mobj->base_y (); 00113 00114 u_int16 ie = px + (mobj->area_length ()) - mobj->base_x () > area_length () ? 00115 area_length () : px + (mobj->area_length ()) - mobj->base_x (); 00116 u_int16 je = py + (mobj->area_height ()) - mobj->base_y () > area_height () ? 00117 area_height () : py + (mobj->area_height ()) - mobj->base_y (); 00118 00119 // Offset between square's position on the map and on the object. 00120 s_int16 xoff = mobj->base_x () - px; 00121 s_int16 yoff = mobj->base_y () - py; 00122 00123 00124 // First place the base tile, as others refers to it... 00125 t.mapobj = mobj; 00126 t.is_base = true; 00127 t.x = px; 00128 t.y = py; 00129 00130 // The iterator will be inserted AFTER all the others base tiles. 00131 // Doing so, this object will be drawn last on this square. 00132 for (it = area[px][py].tiles.begin (); 00133 it != area[px][py].tiles.end () && *(it->base_tile) <= t; it++); 00134 area[px][py].tiles.insert (it, t); 00135 it--; 00136 it->base_tile = it; 00137 00138 // Update t so it refers to the base tile 00139 t.base_tile = it; 00140 t.is_base = false; 00141 00142 // Now place the others tiles. 00143 for (j = j0; j < je; j++) 00144 for (i = i0; i < ie; i++) 00145 { 00146 mapsquare & s = area[i][j]; 00147 t.x = i; 00148 t.y = j; 00149 s.set_walkable (s.get_walkable () & 00150 mobj->get_square (i + xoff, j + yoff)->get_walkable ()); 00151 00152 if (i != px || j != py) 00153 { 00154 for (it = s.tiles.begin (); 00155 it != s.tiles.end () && 00156 *(it->base_tile) <= *(t.base_tile); it++); 00157 s.tiles.insert (it, t); 00158 } 00159 } 00160 00161 // Correctly place the base tile square's base tile pointer. 00162 for (it = area[px][py].tiles.begin (); 00163 it != area[px][py].tiles.end () && *(it->base_tile) < *it; it++); 00164 area[px][py].base_begin = it; 00165 00166 return 0; 00167 } 00168 00169 void mapsquare_area::remove_mapobject (u_int16 px, u_int16 py, mapobject * mobj) 00170 { 00171 u_int16 i, j; 00172 list <mapsquare_tile>::iterator it; 00173 00174 // Calculating where the object will start and end on the map. 00175 u_int16 i0 = px - mobj->base_x () < 0 ? 0 : px - mobj->base_x (); 00176 u_int16 j0 = py - mobj->base_y () < 0 ? 0 : py - mobj->base_y (); 00177 00178 u_int16 ie = px + (mobj->area_length ()) - mobj->base_x () > area_length () ? 00179 area_length () : px + (mobj->area_length ()) - mobj->base_x (); 00180 u_int16 je = py + (mobj->area_height ()) - mobj->base_y () > area_height () ? 00181 area_height () : py + (mobj->area_height ()) - mobj->base_y (); 00182 00183 // Find the base tile, get it's reference (to remove others). 00184 for (it = area[px][py].tiles.begin (); it != area[px][py].tiles.end () && 00185 !(it->is_base == true && it->mapobj == mobj); it++); 00186 00187 // Base tile not found - better to return now... 00188 if (it == area[px][py].tiles.end ()) return; 00189 00190 // Keep the iterator available for further comparison 00191 list <mapsquare_tile>::iterator the_base = it; 00192 00193 // And now erase all the others tiles of this object. 00194 for (j = j0; j < je; j++) 00195 for (i = i0; i < ie; i++) 00196 { 00197 if (i != px || j != py) 00198 { 00199 mapsquare & s = area[i][j]; 00200 00201 for (it = s.tiles.begin (); it != s.tiles.end () && it->base_tile != the_base; it++); 00202 00203 // Not found?? Weird - let's not mess with it then! 00204 if (it == s.tiles.end ()) continue; 00205 00206 s.tiles.erase (it); 00207 00208 // Recalculate the walkability of this square. 00209 s.set_walkable (ALL_WALKABLE); 00210 for (it = s.tiles.begin (); it != s.tiles.end (); it++) 00211 { 00212 u_int16 wx = it->x - (it->base_tile->x - it->mapobj->base_x ()); 00213 u_int16 wy = it->y - (it->base_tile->y - it->mapobj->base_y ()); 00214 s.set_walkable (s.get_walkable () & 00215 it->mapobj->get_square (wx, wy)->get_walkable ()); 00216 } 00217 } 00218 } 00219 mapsquare & s = area[px][py]; 00220 // Erase the base tile 00221 s.tiles.erase (the_base); 00222 // Recalculate the walkability of this square. 00223 s.set_walkable (ALL_WALKABLE); 00224 for (it = s.tiles.begin (); it != s.tiles.end (); it++) 00225 { 00226 u_int16 wx = it->x - (it->base_tile->x - it->mapobj->base_x ()); 00227 u_int16 wy = it->y - (it->base_tile->y - it->mapobj->base_y ()); 00228 s.set_walkable (s.get_walkable () & 00229 it->mapobj->get_square (wx, wy)->get_walkable ()); 00230 } 00231 } 00232 00233 void mapsquare_area::resize_area (u_int16 nl, u_int16 nh) 00234 { 00235 vector <vector<mapsquare> >::iterator i; 00236 00237 area.resize (nl); 00238 for (i = area.begin (); i != area.end (); i++) 00239 i->resize (nh); 00240 00241 u_int16 j, k; 00242 for (j = 0; j < nl; j++) 00243 for (k = 0; k < nh; k++) 00244 { 00245 area[j][k].x_ = j; 00246 area[j][k].y_ = k; 00247 } 00248 }