Logo Search packages:      
Sourcecode: adonthell version File versions  Download package

mapsquare.cc

Go to the documentation of this file.
/*
   $Id: mapsquare.cc,v 1.8 2001/08/29 07:40:33 gnurou Exp $

   Copyright (C) 2001   Alexandre Courbot
   Part of the Adonthell Project http://adonthell.linuxgames.com

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License.
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY.

   See the COPYING file for more details.
*/


/**
 * @file   mapsquare.cc
 * @author Alexandre Courbot <alexandrecourbot@linuxgames.com>
 * 
 * @brief  Defines the mapsquare and mapsquare_area classes.
 * 
 * 
 */


#include "mapsquare.h"
#include "mapobject.h"
#include "mapcharacter.h"

00030 mapsquare_tile::mapsquare_tile ()
{
    mapobj = NULL; 
    is_base = false;
}

00036 mapsquare_tile::~mapsquare_tile ()
{
}

00040 mapsquare_char::mapsquare_char ()
{
    mchar = NULL;
    is_base = false;
}

00046 mapsquare_char::~mapsquare_char ()
{
}

00050 mapsquare::mapsquare () : mapsquare_walkable () 
{
    base_begin = tiles.end ();
    can_use_for_pathfinding = true; 
}

00056 mapsquare::mapsquare (const mapsquare& src) : mapsquare_walkable () 
{
    tiles = src.tiles;
    mapchars = src.mapchars; 

    // Correctly place the base tile square's base tile pointer.
    list <mapsquare_tile>::iterator it; 
    for (it = tiles.begin ();
         it != tiles.end () && *(it->base_tile) < *it; it++);
    base_begin = it;
    can_use_for_pathfinding = src.can_use_for_pathfinding; 
}

00069 mapsquare::~mapsquare ()
{
}

00073 bool mapsquare::is_free () 
{
    list <mapsquare_char>::iterator i;
    for (i = mapchars.begin (); i != mapchars.end (); i++)
        if (i->is_base)
            return false;
    return true;
}

00082 mapcharacter * mapsquare::whoshere () 
{
    list <mapsquare_char>::iterator i;
    for (i = mapchars.begin (); i != mapchars.end (); i++)
        if (i->is_base)
            return i->mchar;
    return NULL;
}

00091 mapsquare_area::mapsquare_area ()
{
}

00095 mapsquare_area::~mapsquare_area ()
{
}

00099 void mapsquare_area::clear ()
{
    area.clear ();      
} 
 
00104 s_int8 mapsquare_area::put_mapobject (u_int16 px, u_int16 py, mapobject * mobj)
{ 
    u_int16 i, j;
    mapsquare_tile t;
    list <mapsquare_tile>::iterator it;
    
    // Calculating where the object will start and end on the map.
    u_int16 i0 = px - mobj->base_x () < 0 ? 0 : px - mobj->base_x (); 
    u_int16 j0 = py - mobj->base_y () < 0 ? 0 : py - mobj->base_y (); 
    
    u_int16 ie = px + (mobj->area_length ()) - mobj->base_x () > area_length () ?
        area_length () : px + (mobj->area_length ()) - mobj->base_x ();  
    u_int16 je = py + (mobj->area_height ()) - mobj->base_y () > area_height () ?
        area_height () : py + (mobj->area_height ()) - mobj->base_y (); 
    
    // Offset between square's position on the map and on the object.
    s_int16 xoff = mobj->base_x () - px; 
    s_int16 yoff = mobj->base_y () - py; 

    
    // First place the base tile, as others refers to it...
    t.mapobj = mobj; 
    t.is_base = true;
    t.x = px;
    t.y = py;
    
    // The iterator will be inserted AFTER all the others base tiles.
    // Doing so, this object will be drawn last on this square.
    for (it = area[px][py].tiles.begin ();
         it != area[px][py].tiles.end () && *(it->base_tile) <= t; it++);
    area[px][py].tiles.insert (it, t);
    it--;
    it->base_tile = it;

    // Update t so it refers to the base tile
    t.base_tile = it;
    t.is_base = false;

    // Now place the others tiles.
    for (j = j0; j < je; j++)
        for (i = i0; i < ie; i++)
        {
            mapsquare & s = area[i][j];
            t.x = i;
            t.y = j;
            s.set_walkable (s.get_walkable () &
                            mobj->get_square (i + xoff, j + yoff)->get_walkable ());
            
            if (i != px || j != py)
            { 
                for (it = s.tiles.begin ();
                     it != s.tiles.end () &&
                         *(it->base_tile) <= *(t.base_tile); it++);
                s.tiles.insert (it, t);
            }
        }
    
    // Correctly place the base tile square's base tile pointer.
    for (it = area[px][py].tiles.begin ();
         it != area[px][py].tiles.end () && *(it->base_tile) < *it; it++);
    area[px][py].base_begin = it;
    
    return 0;
}

00169 void mapsquare_area::remove_mapobject (u_int16 px, u_int16 py, mapobject * mobj)
{
    u_int16 i, j;      
    list <mapsquare_tile>::iterator it;

    // Calculating where the object will start and end on the map.
    u_int16 i0 = px - mobj->base_x () < 0 ? 0 : px - mobj->base_x (); 
    u_int16 j0 = py - mobj->base_y () < 0 ? 0 : py - mobj->base_y (); 
    
    u_int16 ie = px + (mobj->area_length ()) - mobj->base_x () > area_length () ?
        area_length () : px + (mobj->area_length ()) - mobj->base_x ();  
    u_int16 je = py + (mobj->area_height ()) - mobj->base_y () > area_height () ?
        area_height () : py + (mobj->area_height ()) - mobj->base_y (); 
    
    // Find the base tile, get it's reference (to remove others).
    for (it = area[px][py].tiles.begin (); it != area[px][py].tiles.end () &&
           !(it->is_base == true && it->mapobj == mobj); it++); 
    
    // Base tile not found - better to return now...
    if (it == area[px][py].tiles.end ()) return;
    
    // Keep the iterator available for further comparison
    list <mapsquare_tile>::iterator the_base = it;
     
    // And now erase all the others tiles of this object. 
    for (j = j0; j < je; j++)
        for (i = i0; i < ie; i++)
        {
            if (i != px || j != py)
            {
                mapsquare & s = area[i][j]; 
                
                for (it = s.tiles.begin (); it != s.tiles.end () && it->base_tile != the_base; it++); 

                // Not found?? Weird - let's not mess with it then!
                if (it == s.tiles.end ()) continue; 

                s.tiles.erase (it);
                
                // Recalculate the walkability of this square.
                s.set_walkable (ALL_WALKABLE);
                for (it = s.tiles.begin (); it != s.tiles.end (); it++)
                {
                    u_int16 wx = it->x - (it->base_tile->x - it->mapobj->base_x ());
                    u_int16 wy = it->y - (it->base_tile->y - it->mapobj->base_y ());
                    s.set_walkable (s.get_walkable () &
                                    it->mapobj->get_square (wx, wy)->get_walkable ());                     
                }
            }
        } 
    mapsquare & s = area[px][py]; 
    // Erase the base tile
    s.tiles.erase (the_base);
    // Recalculate the walkability of this square.
    s.set_walkable (ALL_WALKABLE);
    for (it = s.tiles.begin (); it != s.tiles.end (); it++)
    {
      u_int16 wx = it->x - (it->base_tile->x - it->mapobj->base_x ());
      u_int16 wy = it->y - (it->base_tile->y - it->mapobj->base_y ());
      s.set_walkable (s.get_walkable () &
                  it->mapobj->get_square (wx, wy)->get_walkable ());                     
    }
}

00233 void mapsquare_area::resize_area (u_int16 nl, u_int16 nh)
{
    vector <vector<mapsquare> >::iterator i;

    area.resize (nl);
    for (i = area.begin (); i !=  area.end (); i++)
        i->resize (nh);

    u_int16 j, k;
    for (j = 0; j < nl; j++)
        for (k = 0; k < nh; k++)
        {
            area[j][k].x_ = j; 
            area[j][k].y_ = k;
        }
}

Generated by  Doxygen 1.6.0   Back to index