summaryrefslogtreecommitdiff
path: root/src/map.cpp
diff options
context:
space:
mode:
authorIra Rice <irarice@gmail.com>2008-09-25 00:15:44 +0000
committerIra Rice <irarice@gmail.com>2008-09-25 00:15:44 +0000
commit489a429bea6739dfa25503b9329bd9e33bffb856 (patch)
tree8112f6fd988fdc0610329b6bc14ee3f9d5801092 /src/map.cpp
parent2dc8eadff1e67bb70b1772ecc19c9e1e2e40a5b4 (diff)
downloadmana-489a429bea6739dfa25503b9329bd9e33bffb856.tar.gz
mana-489a429bea6739dfa25503b9329bd9e33bffb856.tar.bz2
mana-489a429bea6739dfa25503b9329bd9e33bffb856.tar.xz
mana-489a429bea6739dfa25503b9329bd9e33bffb856.zip
Merged the Tametomo branch into trunk.
Diffstat (limited to 'src/map.cpp')
-rw-r--r--src/map.cpp226
1 files changed, 117 insertions, 109 deletions
diff --git a/src/map.cpp b/src/map.cpp
index d9d3a319..ef622ad0 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -23,10 +23,11 @@
#include "map.h"
-#include <algorithm>
#include <queue>
+#include <cassert>
#include "beingmanager.h"
+#include "configuration.h"
#include "game.h"
#include "graphics.h"
#include "particle.h"
@@ -40,6 +41,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.
*/
@@ -62,6 +65,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),
@@ -69,23 +146,18 @@ 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];
- 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;
- // clean up tilesets
- for_each(mTilesets.begin(), mTilesets.end(), make_dtor(mTilesets));
- mTilesets.clear();
- // clean up overlays
- for_each(mOverlays.begin(), mOverlays.end(), make_dtor(mOverlays));
+ delete_all(mLayers);
+ delete_all(mTilesets);
+ delete_all(mOverlays);
}
void Map::initializeOverlays()
@@ -99,9 +171,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)
{
@@ -114,6 +186,11 @@ void Map::initializeOverlays()
}
}
+void Map::addLayer(MapLayer *layer)
+{
+ mLayers.push_back(layer);
+}
+
void Map::addTileset(Tileset *tileset)
{
mTilesets.push_back(tileset);
@@ -127,63 +204,32 @@ 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++)
+ Layers::const_iterator layeri = mLayers.begin();
+ for (; layeri != mLayers.end(); ++layeri)
{
- // 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());
- }
- }
+ (*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::drawOverlay(Graphics *graphics,
@@ -226,23 +272,10 @@ void Map::drawOverlay(Graphics *graphics,
};
}
-void Map::setTileWithGid(int x, int y, int layer, int gid)
-{
- if (layer == 3)
- {
- Tileset *set = getTilesetWithGid(gid);
- setWalk(x, y, (!set || (gid - set->getFirstGid() == 0)));
- }
- else if (layer < 3)
- {
- setTile(x, y, layer, getTileWithGid(gid));
- }
-}
-
class ContainsGidFunctor
{
public:
- bool operator() (Tileset* set)
+ bool operator() (Tileset* set) const
{
return (set->getFirstGid() <= gid &&
gid - set->getFirstGid() < (int)set->size());
@@ -255,27 +288,16 @@ Tileset* Map::getTilesetWithGid(int gid) const
containsGid.gid = gid;
Tilesets::const_iterator i = find_if(mTilesets.begin(), mTilesets.end(),
- containsGid);
+ containsGid);
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::setWalk(int x, int y, bool walkable)
{
mMetaTiles[x + y * mWidth].walkable = walkable;
}
-
+
bool Map::occupied(int x, int y) const
{
Beings &beings = beingManager->getAll();
@@ -293,7 +315,7 @@ bool Map::occupied(int x, int y) const
bool Map::tileCollides(int x, int y) const
{
- return !(contains(x, y) && mMetaTiles[x + y * mWidth].walkable);
+ return !(contains(x, y) && mMetaTiles[x + y * mWidth].walkable);
}
bool Map::contains(int x, int y) const
@@ -301,16 +323,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)
-{
- return mTiles[x + y * mWidth + layer * (mWidth * mHeight)];
-}
-
MetaTile* Map::getMetaTile(int x, int y)
{
return &mMetaTiles[x + y * mWidth];
@@ -327,6 +339,8 @@ void Map::removeSprite(SpriteIterator iterator)
mSprites.erase(iterator);
}
+static int const basicCost = 100;
+
Path Map::findPath(int startX, int startY, int destX, int destY)
{
// Path to be built up (empty by default)
@@ -367,8 +381,8 @@ Path Map::findPath(int startX, int startY, int destX, int destY)
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
@@ -379,7 +393,8 @@ Path Map::findPath(int startX, int startY, int destX, int destY)
MetaTile *newTile = getMetaTile(x, y);
- // Skip if the tile is on the closed list or collides unless its the destination tile
+ // Skip if the tile is on the closed list or collides unless
+ // its the destination tile
if (newTile->whichList == mOnClosedList ||
(tileCollides(x, y) && !(x == destX && y == destY)))
{
@@ -404,13 +419,6 @@ Path Map::findPath(int startX, int startY, int destX, int destY)
// 14 for moving diagonal (sqrt(200) = 14.1421...)
int Gcost = curr.tile->Gcost + ((dx == 0 || dy == 0) ? 10 : 14);
- // It costs extra to walk through a being (needs to be enough
- // to make it more attractive to walk around).
- if (occupied(x, y))
- {
- Gcost += 30;
- }
-
// Skip if Gcost becomes too much
// Warning: probably not entirely accurate
if (Gcost > 200)
@@ -430,7 +438,7 @@ Path Map::findPath(int startX, int startY, int destX, int destY)
// 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
@@ -447,7 +455,7 @@ Path Map::findPath(int startX, int startY, int destX, int destY)
// 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;
@@ -488,7 +496,7 @@ Path Map::findPath(int startX, int startY, int destX, int destY)
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;