diff options
Diffstat (limited to 'src/map.cpp')
-rw-r--r-- | src/map.cpp | 143 |
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; } } |