diff options
Diffstat (limited to 'src/map.cpp')
-rw-r--r-- | src/map.cpp | 208 |
1 files changed, 108 insertions, 100 deletions
diff --git a/src/map.cpp b/src/map.cpp index c7d1d3b8..28d07022 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -28,6 +28,7 @@ #include <cassert> #include "beingmanager.h" +#include "configuration.h" #include "game.h" #include "graphics.h" #include "particle.h" @@ -41,6 +42,8 @@ #include "utils/dtor.h" #include "utils/tostring.h" +extern volatile int tick_time; + /** * A location on a tile map. Used for pathfinding, open list. */ @@ -63,6 +66,80 @@ struct Location MetaTile *tile; }; +MapLayer::MapLayer(int x, int y, int width, int height, bool isFringeLayer): + mX(x), mY(y), + mWidth(width), mHeight(height), + mIsFringeLayer(isFringeLayer) +{ + const int size = mWidth * mHeight; + mTiles = new Image*[size]; + std::fill_n(mTiles, size, (Image*) 0); +} + +MapLayer::~MapLayer() +{ + delete[] mTiles; +} + +void MapLayer::setTile(int x, int y, Image *img) +{ + mTiles[x + y * mWidth] = img; +} + +Image* MapLayer::getTile(int x, int y) const +{ + return mTiles[x + y * mWidth]; +} + +void MapLayer::draw(Graphics *graphics, + int startX, int startY, + int endX, int endY, + int scrollX, int scrollY, + const Sprites &sprites) const +{ + startX -= mX; + startY -= mY; + endX -= mX; + endY -= mY; + + if (startX < 0) startX = 0; + if (startY < 0) startY = 0; + if (endX > mWidth) endX = mWidth; + if (endY > mHeight) endY = mHeight; + + Sprites::const_iterator si = sprites.begin(); + + for (int y = startY; y < endY; y++) + { + // If drawing the fringe layer, make sure all sprites above this row of + // tiles have been drawn + if (mIsFringeLayer) { + while (si != sprites.end() && (*si)->getPixelY() <= y * 32 - 32) { + (*si)->draw(graphics, -scrollX, -scrollY); + si++; + } + } + + for (int x = startX; x < endX; x++) + { + Image *img = getTile(x, y); + if (img) { + const int px = (x + mX) * 32 - scrollX; + const int py = (y + mY) * 32 - scrollY + 32 - img->getHeight(); + graphics->drawImage(img, px, py); + } + } + } + + // Draw any remaining sprites + if (mIsFringeLayer) { + while (si != sprites.end()) { + (*si)->draw(graphics, -scrollX, -scrollY); + si++; + } + } +} + Map::Map(int width, int height, int tileWidth, int tileHeight): mWidth(width), mHeight(height), mTileWidth(tileWidth), mTileHeight(tileHeight), @@ -70,31 +147,26 @@ Map::Map(int width, int height, int tileWidth, int tileHeight): mOnClosedList(1), mOnOpenList(2), mLastScrollX(0.0f), mLastScrollY(0.0f) { - int size = mWidth * mHeight; + const int size = mWidth * mHeight; mMetaTiles = new MetaTile[size]; - for (int i=0; i < NB_BLOCKTYPES; i++) + for (int i = 0; i < NB_BLOCKTYPES; i++) { mOccupation[i] = new int[size]; memset(mOccupation[i], 0, size * sizeof(int)); } - mTiles = new Image*[size * 3]; - std::fill_n(mTiles, size * 3, (Image*)0); } Map::~Map() { - // clean up map data + // delete metadata, layers, tilesets and overlays delete[] mMetaTiles; - delete[] mTiles; for (int i=0; i < NB_BLOCKTYPES; i++) { delete[] mOccupation[i]; } - // clean up tilesets + for_each(mLayers.begin(), mLayers.end(), make_dtor(mLayers)); for_each(mTilesets.begin(), mTilesets.end(), make_dtor(mTilesets)); - mTilesets.clear(); - // clean up overlays for_each(mOverlays.begin(), mOverlays.end(), make_dtor(mOverlays)); } @@ -109,9 +181,9 @@ void Map::initializeOverlays() const std::string name = "overlay" + toString(i); Image *img = resman->getImage(getProperty(name + "image")); - float speedX = getFloatProperty(name + "scrollX"); - float speedY = getFloatProperty(name + "scrollY"); - float parallax = getFloatProperty(name + "parallax"); + const float speedX = getFloatProperty(name + "scrollX"); + const float speedY = getFloatProperty(name + "scrollY"); + const float parallax = getFloatProperty(name + "parallax"); if (img) { @@ -124,6 +196,11 @@ void Map::initializeOverlays() } } +void Map::addLayer(MapLayer *layer) +{ + mLayers.push_back(layer); +} + void Map::addTileset(Tileset *tileset) { mTilesets.push_back(tileset); @@ -137,63 +214,31 @@ bool spriteCompare(const Sprite *a, const Sprite *b) return a->getPixelY() < b->getPixelY(); } -void Map::draw(Graphics *graphics, int scrollX, int scrollY, int layer) +void Map::draw(Graphics *graphics, int scrollX, int scrollY) { int endPixelY = graphics->getHeight() + scrollY + mTileHeight - 1; - // If drawing the fringe layer, make sure sprites are sorted - SpriteIterator si; - if (layer == 1) - { - mSprites.sort(spriteCompare); - si = mSprites.begin(); - endPixelY += mMaxTileHeight - mTileHeight; - } + // TODO: Do this per-layer + endPixelY += mMaxTileHeight - mTileHeight; int startX = scrollX / mTileWidth; int startY = scrollY / mTileHeight; int endX = (graphics->getWidth() + scrollX + mTileWidth - 1) / mTileWidth; int endY = endPixelY / mTileHeight; - if (startX < 0) startX = 0; - if (startY < 0) startY = 0; - if (endX > mWidth) endX = mWidth; - if (endY > mHeight) endY = mHeight; + // Make sure sprites are sorted + mSprites.sort(spriteCompare); - for (int y = startY; y < endY; y++) - { - // If drawing the fringe layer, make sure all sprites above this row of - // tiles have been drawn - if (layer == 1) - { - while (si != mSprites.end() && (*si)->getPixelY() <= y * 32 - 32) - { - (*si)->draw(graphics, -scrollX, -scrollY); - si++; - } - } - - for (int x = startX; x < endX; x++) - { - Image *img = getTile(x, y, layer); - if (img) { - graphics->drawImage(img, - x * mTileWidth - scrollX, - y * mTileHeight - scrollY + - mTileHeight - img->getHeight()); - } - } + Layers::const_iterator layeri = mLayers.begin(); + for (; layeri != mLayers.end(); ++layeri) { + (*layeri)->draw(graphics, + startX, startY, endX, endY, + scrollX, scrollY, + mSprites); } - // Draw any remaining sprites - if (layer == 1) - { - while (si != mSprites.end()) - { - (*si)->draw(graphics, -scrollX, -scrollY); - si++; - } - } + drawOverlay(graphics, scrollX, scrollY, + (int) config.getValue("OverlayDetail", 2)); } void Map::drawCollision(Graphics *graphics, int scrollX, int scrollY) @@ -289,26 +334,10 @@ void Map::drawOverlay(Graphics *graphics, }; } -void Map::setTileWithGid(int x, int y, int layer, int gid) -{ - if (layer == 3) - { - Tileset *set = getTilesetWithGid(gid); - if (set && (gid - set->getFirstGid() != 0)) - { - blockTile(x, y, BLOCKTYPE_WALL); - } - } - else if (layer < 3) - { - setTile(x, y, layer, getTileWithGid(gid)); - } -} - class ContainsGidFunctor { public: - bool operator() (Tileset* set) + bool operator() (const Tileset* set) const { return (set->getFirstGid() <= gid && gid - set->getFirstGid() < (int)set->size()); @@ -326,17 +355,6 @@ Tileset* Map::getTilesetWithGid(int gid) const return (i == mTilesets.end()) ? NULL : *i; } -Image* Map::getTileWithGid(int gid) const -{ - Tileset *set = getTilesetWithGid(gid); - - if (set) { - return set->get(gid - set->getFirstGid()); - } - - return NULL; -} - void Map::blockTile(int x, int y, BlockType type) { if (type == BLOCKTYPE_NONE || x < 0 || y < 0 || x >= mWidth || y >= mHeight) @@ -412,16 +430,6 @@ bool Map::contains(int x, int y) const return x >= 0 && y >= 0 && x < mWidth && y < mHeight; } -void Map::setTile(int x, int y, int layer, Image *img) -{ - mTiles[x + y * mWidth + layer * (mWidth * mHeight)] = img; -} - -Image* Map::getTile(int x, int y, int layer) const -{ - return mTiles[x + y * mWidth + layer * (mWidth * mHeight)]; -} - MetaTile* Map::getMetaTile(int x, int y) const { return &mMetaTiles[x + y * mWidth]; @@ -484,8 +492,8 @@ Path Map::findPath(int startX, int startY, int destX, int destY, unsigned char w for (int dx = -1; dx <= 1; dx++) { // Calculate location of tile to check - int x = curr.x + dx; - int y = curr.y + dy; + const int x = curr.x + dx; + const int y = curr.y + dy; // Skip if if we're checking the same tile we're leaving from, // or if the new location falls outside of the map boundaries @@ -559,7 +567,7 @@ Path Map::findPath(int startX, int startY, int destX, int destY, unsigned char w // Update Gcost and Fcost of new tile newTile->Gcost = Gcost; - newTile->Fcost = newTile->Gcost + newTile->Hcost; + newTile->Fcost = Gcost + newTile->Hcost; if (x != destX || y != destY) { // Add this tile to the open list @@ -576,7 +584,7 @@ Path Map::findPath(int startX, int startY, int destX, int destY, unsigned char w // Found a shorter route. // Update Gcost and Fcost of the new tile newTile->Gcost = Gcost; - newTile->Fcost = newTile->Gcost + newTile->Hcost; + newTile->Fcost = Gcost + newTile->Hcost; // Set the current tile as the parent of the new tile newTile->parentX = curr.x; @@ -617,7 +625,7 @@ Path Map::findPath(int startX, int startY, int destX, int destY, unsigned char w return path; } -void Map::addParticleEffect (std::string effectFile, int x, int y) +void Map::addParticleEffect(const std::string &effectFile, int x, int y) { ParticleEffectData newEffect; newEffect.file = effectFile; |