summaryrefslogtreecommitdiff
path: root/src/map.cpp
diff options
context:
space:
mode:
authorBjørn Lindeijer <bjorn@lindeijer.nl>2008-04-08 18:43:44 +0000
committerBjørn Lindeijer <bjorn@lindeijer.nl>2008-04-08 18:43:44 +0000
commit720f716ba8d98a85266b8e81a534737c6fcdcf5f (patch)
tree192c702c463db0661f42fa34addf8f957e19e169 /src/map.cpp
parentf25d5640eba5b1a0bbbc050a858aa4cdbdffdc7f (diff)
downloadmana-client-720f716ba8d98a85266b8e81a534737c6fcdcf5f.tar.gz
mana-client-720f716ba8d98a85266b8e81a534737c6fcdcf5f.tar.bz2
mana-client-720f716ba8d98a85266b8e81a534737c6fcdcf5f.tar.xz
mana-client-720f716ba8d98a85266b8e81a534737c6fcdcf5f.zip
Implemented support for an arbitrary number of map layers. The only layer
requirement for map layers are now that the fringe layer is called "Fringe" and that the collision layer is called "Collision".
Diffstat (limited to 'src/map.cpp')
-rw-r--r--src/map.cpp208
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;