summaryrefslogtreecommitdiff
path: root/src/map.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/map.cpp')
-rw-r--r--src/map.cpp143
1 files changed, 106 insertions, 37 deletions
diff --git a/src/map.cpp b/src/map.cpp
index 5c2290d6..e7646fd2 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -1,43 +1,42 @@
/*
* The Mana World
- * Copyright 2004 The Mana World Development Team
+ * Copyright (C) 2004 The Mana World Development Team
*
* This file is part of The Mana World.
*
- * The Mana World is free software; you can redistribute it and/or modify
+ * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
- * The Mana World is distributed in the hope that it will be useful,
+ * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with The Mana World; if not, write to the Free Software
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "map.h"
-
#include <queue>
-#include <cassert>
#include "beingmanager.h"
#include "configuration.h"
#include "game.h"
#include "graphics.h"
+#include "map.h"
#include "particle.h"
+#include "simpleanimation.h"
#include "sprite.h"
#include "tileset.h"
-#include "resources/resourcemanager.h"
#include "resources/ambientoverlay.h"
#include "resources/image.h"
+#include "resources/resourcemanager.h"
#include "utils/dtor.h"
-#include "utils/tostring.h"
+#include "utils/stringutils.h"
extern volatile int tick_time;
@@ -63,6 +62,38 @@ struct Location
MetaTile *tile;
};
+TileAnimation::TileAnimation(Animation *ani):
+ mLastImage(NULL)
+{
+ mAnimation = new SimpleAnimation(ani);
+}
+
+TileAnimation::~TileAnimation()
+{
+ delete mAnimation;
+}
+
+void TileAnimation::update()
+{
+ if (!mAnimation)
+ return;
+
+ //update animation
+ mAnimation->update(1);
+
+ // exchange images
+ Image *img = mAnimation->getCurrentImage();
+ if (img != mLastImage)
+ {
+ for (std::list<std::pair<MapLayer*, int> >::iterator i =
+ mAffected.begin(); i != mAffected.end(); i++)
+ {
+ i->first->setTile(i->second, img);
+ }
+ mLastImage = img;
+ }
+}
+
MapLayer::MapLayer(int x, int y, int width, int height, bool isFringeLayer):
mX(x), mY(y),
mWidth(width), mHeight(height),
@@ -80,7 +111,7 @@ MapLayer::~MapLayer()
void MapLayer::setTile(int x, int y, Image *img)
{
- mTiles[x + y * mWidth] = img;
+ setTile(x + y * mWidth, img);
}
Image* MapLayer::getTile(int x, int y) const
@@ -110,8 +141,14 @@ void MapLayer::draw(Graphics *graphics,
{
// 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) {
+ if (mIsFringeLayer)
+ {
+#ifdef TMWSERV_SUPPORT
+ while (si != sprites.end() && (*si)->getPixelY() <= y * 32)
+#else
+ while (si != sprites.end() && (*si)->getPixelY() <= y * 32 - 32)
+#endif
+ {
(*si)->draw(graphics, -scrollX, -scrollY);
si++;
}
@@ -120,7 +157,8 @@ void MapLayer::draw(Graphics *graphics,
for (int x = startX; x < endX; x++)
{
Image *img = getTile(x, y);
- if (img) {
+ if (img)
+ {
const int px = (x + mX) * 32 - scrollX;
const int py = (y + mY) * 32 - scrollY + 32 - img->getHeight();
graphics->drawImage(img, px, py);
@@ -165,6 +203,7 @@ Map::~Map()
delete_all(mLayers);
delete_all(mTilesets);
delete_all(mOverlays);
+ delete_all(mTileAnimations);
}
void Map::initializeOverlays()
@@ -211,6 +250,17 @@ bool spriteCompare(const Sprite *a, const Sprite *b)
return a->getPixelY() < b->getPixelY();
}
+void Map::update()
+{
+ //update animated tiles
+ for (std::map<int, TileAnimation*>::iterator iAni = mTileAnimations.begin();
+ iAni != mTileAnimations.end();
+ iAni++)
+ {
+ iAni->second->update();
+ }
+}
+
void Map::draw(Graphics *graphics, int scrollX, int scrollY)
{
int endPixelY = graphics->getHeight() + scrollY + mTileHeight - 1;
@@ -226,8 +276,10 @@ void Map::draw(Graphics *graphics, int scrollX, int scrollY)
// Make sure sprites are sorted
mSprites.sort(spriteCompare);
+ // draw the game world
Layers::const_iterator layeri = mLayers.begin();
- for (; layeri != mLayers.end(); ++layeri) {
+ for (; layeri != mLayers.end(); ++layeri)
+ {
(*layeri)->draw(graphics,
startX, startY, endX, endY,
scrollX, scrollY,
@@ -354,10 +406,8 @@ Tileset* Map::getTilesetWithGid(int gid) const
void Map::blockTile(int x, int y, BlockType type)
{
- if (type == BLOCKTYPE_NONE || x < 0 || y < 0 || x >= mWidth || y >= mHeight)
- {
+ if (type == BLOCKTYPE_NONE || !contains(x, y))
return;
- }
int tileNum = x + y * mWidth;
@@ -384,10 +434,8 @@ void Map::blockTile(int x, int y, BlockType type)
bool Map::getWalk(int x, int y, char walkmask) const
{
// You can't walk outside of the map
- if (x < 0 || y < 0 || x >= mWidth || y >= mHeight)
- {
+ if (!contains(x, y))
return false;
- }
// Check if the tile is walkable
return !(mMetaTiles[x + y * mWidth].blockmask & walkmask);
@@ -419,7 +467,7 @@ static int const basicCost = 100;
Path Map::findPath(int startX, int startY, int destX, int destY, unsigned char walkmask, int maxCost)
{
// Path to be built up (empty by default)
- std::list<Position> path;
+ Path path;
// Declare open list, a list with open tiles sorted on F cost
std::priority_queue<Location> openList;
@@ -439,20 +487,19 @@ Path Map::findPath(int startX, int startY, int destX, int destY, unsigned char w
// Keep trying new open tiles until no more tiles to try or target found
while (!openList.empty() && !foundPath)
{
- // Take the location with the lowest F cost from the open list, and
- // add it to the closed list.
+ // Take the location with the lowest F cost from the open list.
Location curr = openList.top();
openList.pop();
// If the tile is already on the closed list, this means it has already
// been processed with a shorter path to the start point (lower G cost)
- if (curr.tile->whichList == onClosedList)
+ if (curr.tile->whichList == mOnClosedList)
{
continue;
}
// Put the current tile on the closed list
- curr.tile->whichList = onClosedList;
+ curr.tile->whichList = mOnClosedList;
// Check the adjacent tiles
for (int dy = -1; dy <= 1; dy++)
@@ -465,8 +512,7 @@ Path Map::findPath(int startX, int startY, int destX, int destY, unsigned char w
// Skip if if we're checking the same tile we're leaving from,
// or if the new location falls outside of the map boundaries
- if ((dx == 0 && dy == 0) ||
- (x < 0 || y < 0 || x >= mWidth || y >= mHeight))
+ if ((dx == 0 && dy == 0) || !contains(x, y))
{
continue;
}
@@ -474,7 +520,9 @@ Path Map::findPath(int startX, int startY, int destX, int destY, unsigned char w
MetaTile *newTile = getMetaTile(x, y);
// Skip if the tile is on the closed list or is not walkable
- if (newTile->whichList == onClosedList || newTile->blockmask & walkmask)
+ // unless its the destination tile
+ if (newTile->whichList == mOnClosedList ||
+ ((newTile->blockmask & walkmask) && !(x == destX && y == destY)))
{
continue;
}
@@ -510,6 +558,13 @@ Path Map::findPath(int startX, int startY, int destX, int destY, unsigned char w
++Gcost;
}
+ // It costs extra to walk through a being (needs to be enough
+ // to make it more attractive to walk around).
+ if (!getWalk(x, y, BLOCKMASK_CHARACTER | BLOCKMASK_MONSTER))
+ {
+ Gcost += 3 * basicCost;
+ }
+
// Skip if Gcost becomes too much
// Warning: probably not entirely accurate
if (Gcost > maxCost * basicCost)
@@ -517,7 +572,7 @@ Path Map::findPath(int startX, int startY, int destX, int destY, unsigned char w
continue;
}
- if (newTile->whichList != onOpenList)
+ if (newTile->whichList != mOnOpenList)
{
// Found a new tile (not on open nor on closed list)
@@ -539,7 +594,7 @@ Path Map::findPath(int startX, int startY, int destX, int destY, unsigned char w
if (x != destX || y != destY) {
// Add this tile to the open list
- newTile->whichList = onOpenList;
+ newTile->whichList = mOnOpenList;
openList.push(Location(x, y, newTile));
}
else {
@@ -568,8 +623,8 @@ Path Map::findPath(int startX, int startY, int destX, int destY, unsigned char w
// Two new values to indicate whether a tile is on the open or closed list,
// this way we don't have to clear all the values between each pathfinding.
- onClosedList += 2;
- onOpenList += 2;
+ mOnClosedList += 2;
+ mOnOpenList += 2;
// If a path has been found, iterate backwards using the parent locations
// to extract it.
@@ -604,11 +659,25 @@ void Map::addParticleEffect(const std::string &effectFile, int x, int y)
void Map::initializeParticleEffects(Particle* particleEngine)
{
- for (std::list<ParticleEffectData>::iterator i = particleEffects.begin();
- i != particleEffects.end();
- i++
- )
+ if (config.getValue("particleeffects", 1))
+ {
+ for (std::list<ParticleEffectData>::iterator i = particleEffects.begin();
+ i != particleEffects.end();
+ i++
+ )
+ {
+ particleEngine->addEffect(i->file, i->x, i->y);
+ }
+ }
+}
+
+TileAnimation* Map::getAnimationForGid(int gid)
+{
+ std::map<int, TileAnimation*>::iterator i = mTileAnimations.find(gid);
+ if (i == mTileAnimations.end())
{
- particleEngine->addEffect(i->file, i->x, i->y);
+ return NULL;
+ } else {
+ return i->second;
}
}