00001 #include "MapTile.h"
00002 #include "Display.h"
00003
00004 int MapTile::_width = 80;
00005 int MapTile::_height = 42;
00006 SDL_Surface* MapTile::_highlight = NULL;
00007 SDL_Surface* MapTile::_highlightMove = NULL;
00008 int MapTile::cardinalMoveBase = 15;
00009 int MapTile::diagonalMoveBase = 10;
00010
00011 #define TILE_HIGHLIGHT "images/tile_highlight.png"
00012 #define TILE_MOVEABLE "images/tile_moveable.png"
00013
00014 spMapTile MapTile::makeMapTile(TerrainType type, int x, int y)
00015 {
00016 spMapTile tile(new MapTile(type, x, y));
00017 tile->_weak = tile;
00018 return tile;
00019 }
00020
00021 MapTile::MapTile(TerrainType type, int x, int y) :
00022 _x(x),
00023 _y(y),
00024 _terrain(Terrain(type))
00025 {
00026
00027
00028
00029 _screenX = y*MapTile::_width/2 - (x)*MapTile::_width/2;
00030 _screenY = (y+x) * MapTile::_height/2;
00031
00032 _centerX = y*MapTile::_width/2 - (x-1)*MapTile::_width/2;
00033 _centerY = (y+x+1) * MapTile::_height/2;
00034
00035 if (!_highlight)
00036 {
00037 _highlight = Display::instance().loadImage(TILE_HIGHLIGHT);
00038 _highlightMove = Display::instance().loadImage(TILE_MOVEABLE);
00039 }
00040 }
00041
00042 MapTile::~MapTile()
00043 {
00044 }
00045
00046 int MapTile::getX() const
00047 {
00048 return _x;
00049 }
00050 int MapTile::getY() const
00051 {
00052 return _y;
00053 }
00054 int MapTile::getScreenX() const
00055 {
00056 return _screenX;
00057 }
00058 int MapTile::getScreenY() const
00059 {
00060 return _screenY;
00061 }
00062 int MapTile::getCenterX() const
00063 {
00064 return _centerX;
00065 }
00066 int MapTile::getCenterY() const
00067 {
00068 return _centerY;
00069 }
00070 TerrainType MapTile::getTerrainType()
00071 {
00072 return _terrain.getType();
00073 }
00074 int MapTile::getWidth()
00075 {
00076 return MapTile::_width;
00077 }
00078 int MapTile::getHeight()
00079 {
00080 return MapTile::_height;
00081 }
00082
00083 void MapTile::drawTerrain(Point offset) const
00084 {
00085 _terrain.draw(_screenX - offset.x, _screenY - offset.y);
00086 }
00087
00088 void MapTile::drawObjects(Point offset) const
00089 {
00090 Point dim(_width, _height);
00091 Point position(_screenX - offset.x, _screenY - offset.y);
00092 if (!_objects.empty())
00093 {
00094
00095 list<spMapObject>::const_iterator iter;
00096
00097 for (iter = _objects.begin(); iter != _objects.end(); ++iter)
00098 {
00099 (*iter)->draw(position, dim);
00100 }
00101 }
00102 if (_unit.get())
00103 {
00104 _unit->draw(position, dim);
00105 }
00106 }
00107
00108 void MapTile::highlight(Point offset)
00109 {
00110 Display::instance().draw(_screenX - offset.x, _screenY - offset.y, _highlight);
00111 }
00112
00113 void MapTile::highlightMoveable(Point offset)
00114 {
00115 Display::instance().draw(_screenX - offset.x, _screenY - offset.y, _highlightMove);
00116 }
00117
00118 bool MapTile::isPassable() const
00119 {
00120 bool passable = true;
00121 if (_terrain.isPassable() && !hasUnit())
00122 {
00123 list<spMapObject>::const_iterator iter;
00124 for (iter = _objects.begin(); iter != _objects.end(); ++iter)
00125 {
00126 if (!(*iter)->isPassable())
00127 {
00128 passable = false;
00129 break;
00130 }
00131 }
00132
00133 }
00134 else
00135 {
00136 passable = false;
00137 }
00138
00139 return passable;
00140 }
00141 bool MapTile::isPassable(Direction dir) const
00142 {
00143 if ( hasObstruction(dir) )
00144 return false;
00145 spMapTile t = getTileInDirection(dir);
00146 if ( t.get() )
00147 return !t->hasObstruction(dir.opposite());
00148 return true;
00149 }
00150
00151 bool MapTile::hasObstruction(Direction dir) const
00152 {
00153 if (!_objects.empty())
00154 {
00155 list<spMapObject>::const_iterator iter;
00156 for (iter = _objects.begin(); iter != _objects.end(); ++iter)
00157 {
00158 if ( !(*iter)->isPassable(dir) );
00159 return true;
00160 }
00161 }
00162 return false;
00163 }
00164
00165 bool MapTile::hasUnit() const
00166 {
00167 return _unit.get() != NULL;
00168 }
00169
00170 bool MapTile::addUnit(spUnit unit)
00171 {
00172 if (isPassable())
00173 {
00174 _unit = unit;
00175 return true;
00176 }
00177 else
00178 {
00179 return false;
00180 }
00181 }
00182
00183 spUnit MapTile::getUnit()
00184 {
00185 return _unit;
00186 }
00187
00188 void MapTile::removeUnit()
00189 {
00190 _unit = spUnit();
00191 }
00192
00193 bool MapTile::addObject(spMapObject object)
00194 {
00195
00196
00197
00198
00199
00200
00201
00202
00203 _objects.push_back(object);
00204 return true;
00205 }
00206
00207 void MapTile::removeObject(spMapObject object)
00208 {
00209 _objects.remove(object);
00210 }
00211
00212 void MapTile::addTileInDirection( spMapTile tile, const Direction& dir)
00213 {
00214 directionTileMap[dir] = tile;
00215 tile->directionTileMap[dir.opposite()] = spMapTile(_weak);
00216 }
00217
00218 spMapTile MapTile::getTileInDirection( const Direction& dir) const
00219 {
00220 map<Direction, spMapTile>::const_iterator iter;
00221 iter = directionTileMap.find(dir);
00222 if (iter != directionTileMap.end())
00223 {
00224 return iter->second;
00225 }
00226 else
00227 {
00228 return spMapTile();
00229 }
00230 }
00231
00232 int MapTile::getMoveCost( const Direction& dir) const
00233 {
00234 int baseCost = (dir.isCardinal()) ? cardinalMoveBase : diagonalMoveBase;
00235 return static_cast<int>(getTileInDirection(dir)->_terrain.getMoveMultiplier() * baseCost);
00236 }