• Main Page
  • Related Pages
  • Classes
  • Files
  • File List
  • File Members

mapsquare.cc

Go to the documentation of this file.
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 }

Generated on Fri Mar 18 2011 for Adonthell by  doxygen 1.7.1