summaryrefslogtreecommitdiff
path: root/src/map.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/map.h')
-rw-r--r--src/map.h611
1 files changed, 611 insertions, 0 deletions
diff --git a/src/map.h b/src/map.h
new file mode 100644
index 000000000..a51ecab6c
--- /dev/null
+++ b/src/map.h
@@ -0,0 +1,611 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * 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.
+ *
+ * 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAP_H
+#define MAP_H
+
+#include "actor.h"
+#include "configlistener.h"
+#include "position.h"
+#include "properties.h"
+
+#include <list>
+#include <string>
+#include <vector>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class Animation;
+class AmbientLayer;
+class Graphics;
+class MapLayer;
+class Particle;
+class SimpleAnimation;
+class Tileset;
+class SpecialLayer;
+class MapItem;
+
+typedef std::vector<Tileset*> Tilesets;
+typedef std::vector<MapLayer*> Layers;
+
+/**
+ * A meta tile stores additional information about a location on a tile map.
+ * This is information that doesn't need to be repeated for each tile in each
+ * layer of the map.
+ */
+struct MetaTile
+{
+ /**
+ * Constructor.
+ */
+ MetaTile() : Fcost(0), Gcost(0), Hcost(0), whichList(0),
+ parentX(0), parentY(0), blockmask(0)
+ {}
+
+ // Pathfinding members
+ int Fcost; /**< Estimation of total path cost */
+ int Gcost; /**< Cost from start to this location */
+ int Hcost; /**< Estimated cost to goal */
+ int whichList; /**< No list, open list or closed list */
+ int parentX; /**< X coordinate of parent tile */
+ int parentY; /**< Y coordinate of parent tile */
+ unsigned char blockmask; /**< Blocking properties of this tile */
+};
+
+/*
+struct MapBox
+{
+ MapBox() : name(""), x(0), y(0)
+ {
+ }
+
+ MapBox(std::string name1, int x1, int y1):
+ name(name1), x(x1), y(y1)
+ {
+ }
+
+ std::string name;
+ int x;
+ int y;
+};
+*/
+
+/**
+ * Animation cycle of a tile image which changes the map accordingly.
+ */
+class TileAnimation
+{
+ public:
+ TileAnimation(Animation *ani);
+ ~TileAnimation();
+ void update(int ticks = 1);
+ void addAffectedTile(MapLayer *layer, int index)
+ { mAffected.push_back(std::make_pair(layer, index)); }
+ private:
+ std::list<std::pair<MapLayer*, int> > mAffected;
+ SimpleAnimation *mAnimation;
+ Image *mLastImage;
+};
+
+/**
+ * A map layer. Stores a grid of tiles and their offset, and implements layer
+ * rendering.
+ */
+class MapLayer: public ConfigListener
+{
+ public:
+ /**
+ * Constructor, taking layer origin, size and whether this layer is the
+ * fringe layer. The fringe layer is the layer that draws the actors.
+ * There can be only one fringe layer per map.
+ */
+ MapLayer(int x, int y, int width, int height, bool isFringeLayer);
+
+ /**
+ * Destructor.
+ */
+ ~MapLayer();
+
+ /**
+ * Set tile image, with x and y in layer coordinates.
+ */
+ void setTile(int x, int y, Image *img);
+
+ /**
+ * Set tile image with x + y * width already known.
+ */
+ void setTile(int index, Image *img) { mTiles[index] = img; }
+
+ /**
+ * Get tile image, with x and y in layer coordinates.
+ */
+ Image *getTile(int x, int y) const;
+
+ /**
+ * Draws this layer to the given graphics context. The coordinates are
+ * expected to be in map range and will be translated to local layer
+ * coordinates and clipped to the layer's dimensions.
+ *
+ * The given actors are only drawn when this layer is the fringe
+ * layer.
+ */
+ void draw(Graphics *graphics,
+ int startX, int startY,
+ int endX, int endY,
+ int scrollX, int scrollY,
+ const Actors &actors,
+ int mDebugFlags) const;
+
+ bool isFringeLayer()
+ { return mIsFringeLayer; }
+
+ void setSpecialLayer(SpecialLayer *val)
+ { mSpecialLayer = val; }
+
+ void setTempLayer(SpecialLayer *val)
+ { mTempLayer = val; }
+
+ int getWidth()
+ { return mWidth; }
+
+ int getHeight()
+ { return mHeight; }
+
+// void setTileInfo(int x, int y, int width, int cnt);
+
+// void getTileInfo(int x, int y, int &width, int &cnt) const;
+
+ void optionChanged(const std::string &value);
+
+ int getTileDrawWidth(int tilePtr, int endX, int &width) const;
+
+// void initTileInfo();
+
+ private:
+ int mX, mY;
+ int mWidth, mHeight;
+ bool mIsFringeLayer; /**< Whether the actors are drawn. */
+ bool mHighlightAttackRange;
+ Image **mTiles;
+// int *mTilesWidth;
+// int *mTilesCount;
+ SpecialLayer *mSpecialLayer;
+ SpecialLayer *mTempLayer;
+};
+
+/**
+ * A tile map.
+ */
+class Map : public Properties, public ConfigListener
+{
+ public:
+ enum BlockType
+ {
+ BLOCKTYPE_NONE = -1,
+ BLOCKTYPE_WALL,
+ BLOCKTYPE_CHARACTER,
+ BLOCKTYPE_MONSTER,
+ NB_BLOCKTYPES
+ };
+
+ enum BlockMask
+ {
+ BLOCKMASK_WALL = 0x80, // = bin 1000 0000
+ BLOCKMASK_CHARACTER = 0x01, // = bin 0000 0001
+ BLOCKMASK_MONSTER = 0x02 // = bin 0000 0010
+ };
+
+ enum DebugType
+ {
+ MAP_NORMAL = 0,
+ MAP_DEBUG = 1,
+ MAP_SPECIAL = 2,
+ MAP_SPECIAL2 = 3,
+ MAP_SPECIAL3 = 4,
+ MAP_BLACKWHITE = 5
+ };
+
+ /**
+ * Constructor, taking map and tile size as parameters.
+ */
+ Map(int width, int height, int tileWidth, int tileHeight);
+
+ /**
+ * Destructor.
+ */
+ ~Map();
+
+ /**
+ * Initialize ambient layers. Has to be called after all the properties
+ * are set.
+ */
+ void initializeAmbientLayers();
+
+ /**
+ * Updates animations. Called as needed.
+ */
+ void update(int ticks = 1);
+
+ /**
+ * Draws the map to the given graphics output. This method draws all
+ * layers, actors and overlay effects.
+ *
+ * TODO: For efficiency reasons, this method could take into account
+ * the clipping rectangle set on the Graphics object. However,
+ * currently the map is always drawn full-screen.
+ */
+ void draw(Graphics *graphics, int scrollX, int scrollY);
+
+ /**
+ * Visualizes collision layer for debugging
+ */
+ void drawCollision(Graphics *graphics, int scrollX, int scrollY,
+ int debugFlags);
+
+ /**
+ * Adds a layer to this map. The map takes ownership of the layer.
+ */
+ void addLayer(MapLayer *layer);
+
+ /**
+ * Adds a tileset to this map. The map takes ownership of the tileset.
+ */
+ void addTileset(Tileset *tileset);
+
+ /**
+ * Finds the tile set that a tile with the given global id is part of.
+ */
+ Tileset *getTilesetWithGid(int gid) const;
+
+ /**
+ * Get tile reference.
+ */
+ MetaTile *getMetaTile(int x, int y) const;
+
+ /**
+ * Marks a tile as occupied.
+ */
+ void blockTile(int x, int y, BlockType type);
+
+ /**
+ * Gets walkability for a tile with a blocking bitmask. When called
+ * without walkmask, only blocks against colliding tiles.
+ */
+ bool getWalk(int x, int y,
+ unsigned char walkmask = BLOCKMASK_WALL) const;
+
+ /**
+ * Tells whether a tile is occupied by a being.
+ */
+ bool occupied(int x, int y) const;
+
+ /**
+ * Returns the width of this map in tiles.
+ */
+ int getWidth() const { return mWidth; }
+
+ /**
+ * Returns the height of this map in tiles.
+ */
+ int getHeight() const { return mHeight; }
+
+ /**
+ * Returns the tile width of this map.
+ */
+ int getTileWidth() const
+ { return mTileWidth; }
+
+ /**
+ * Returns the tile height used by this map.
+ */
+ int getTileHeight() const
+ { return mTileHeight; }
+
+ const std::string getMusicFile() const;
+ const std::string getName() const;
+
+ /**
+ * Gives the map id based on filepath (ex: 009-1)
+ */
+ const std::string getFilename() const;
+
+ /**
+ * Check the current position against surrounding blocking tiles, and
+ * correct the position offset within tile when needed.
+ */
+ Position checkNodeOffsets(int radius, unsigned char walkMask,
+ const Position &position) const;
+
+ Position checkNodeOffsets(int radius, unsigned char walkMask,
+ int x, int y) const
+ { return checkNodeOffsets(radius, walkMask, Position(x, y)); }
+
+ /**
+ * Find a pixel path from one location to the next.
+ */
+ Path findPixelPath(int startPixelX, int startPixelY,
+ int destPixelX, int destPixelY,
+ int radius, unsigned char walkmask,
+ int maxCost = 20);
+
+ /**
+ * Find a path from one location to the next.
+ */
+ Path findPath(int startX, int startY, int destX, int destY,
+ unsigned char walkmask, int maxCost = 20);
+
+ /**
+ * Adds a particle effect
+ */
+ void addParticleEffect(const std::string &effectFile,
+ int x, int y, int w = 0, int h = 0);
+
+ /**
+ * Initializes all added particle effects
+ */
+ void initializeParticleEffects(Particle* particleEngine);
+
+ /**
+ * Adds a tile animation to the map
+ */
+ void addAnimation(int gid, TileAnimation *animation)
+ { mTileAnimations[gid] = animation; }
+
+ void setDebugFlags(int n)
+ { mDebugFlags = n; }
+
+ int getDebugFlags() const
+ { return mDebugFlags; }
+
+ void addExtraLayer();
+
+ void saveExtraLayer();
+
+ SpecialLayer *getTempLayer()
+ { return mTempLayer; }
+
+ SpecialLayer *getSpecialLayer()
+ { return mSpecialLayer; }
+
+ void setHasWarps(bool n)
+ { mHasWarps = n; }
+
+ bool getHasWarps()
+ { return mHasWarps; }
+
+ std::string getUserMapDirectory() const;
+
+ void addPortal(const std::string &name, int type,
+ int x, int y, int dx, int dy);
+
+ void addPortalTile(const std::string &name, int type, int x, int y);
+
+ void updatePortalTile(const std::string &name, int type,
+ int x, int y, bool addNew = true);
+
+ std::list<MapItem*> &getPortals()
+ { return mMapPortals; }
+
+ /**
+ * Gets the tile animation for a specific gid
+ */
+ TileAnimation *getAnimationForGid(int gid) const;
+
+ void optionChanged(const std::string &value);
+
+ MapItem *findPortalXY(int x, int y);
+
+ int getActorsCount() const
+ { return mActors.size(); }
+
+ void setPvpMode(int mode);
+
+ protected:
+ friend class Actor;
+
+ /**
+ * Adds an actor to the map.
+ */
+ Actors::iterator addActor(Actor *actor);
+
+ /**
+ * Removes an actor from the map.
+ */
+ void removeActor(Actors::iterator iterator);
+
+ private:
+
+ enum LayerType
+ {
+ FOREGROUND_LAYERS = 0,
+ BACKGROUND_LAYERS
+ };
+
+ /**
+ * Updates scrolling of ambient layers. Has to be called each game tick.
+ */
+ void updateAmbientLayers(float scrollX, float scrollY);
+
+ /**
+ * Draws the foreground or background layers to the given graphics output.
+ */
+ void drawAmbientLayers(Graphics *graphics, LayerType type,
+ int detail);
+
+ /**
+ * Tells whether the given coordinates fall within the map boundaries.
+ */
+ bool contains(int x, int y) const;
+
+ /**
+ * Blockmasks for different entities
+ */
+ int *mOccupation[NB_BLOCKTYPES];
+
+ int mWidth, mHeight;
+ int mTileWidth, mTileHeight;
+ int mMaxTileHeight;
+ MetaTile *mMetaTiles;
+ Layers mLayers;
+ Tilesets mTilesets;
+ Actors mActors;
+ bool mHasWarps;
+
+ // debug flags
+ int mDebugFlags;
+
+ // Pathfinding members
+ int mOnClosedList, mOnOpenList;
+
+ // Overlay data
+ std::list<AmbientLayer*> mBackgrounds;
+ std::list<AmbientLayer*> mForegrounds;
+ float mLastScrollX;
+ float mLastScrollY;
+// bool mSpritesUpdated;
+
+ // Particle effect data
+ struct ParticleEffectData
+ {
+ std::string file;
+ int x;
+ int y;
+ int w;
+ int h;
+ };
+ std::list<ParticleEffectData> particleEffects;
+
+ std::list<MapItem*> mMapPortals;
+
+ std::map<int, TileAnimation*> mTileAnimations;
+
+ int mOverlayDetail;
+ float mOpacity;
+ int mOpenGL;
+ int mPvp;
+
+ SpecialLayer *mSpecialLayer;
+ SpecialLayer *mTempLayer;
+};
+
+
+class SpecialLayer
+{
+ public:
+ friend class Map;
+ friend class MapLayer;
+
+ SpecialLayer(int width, int height, bool drawSprites = false);
+
+ ~SpecialLayer();
+
+ void draw(Graphics *graphics, int startX, int startY,
+ int endX, int endY, int scrollX, int scrollY);
+
+ MapItem* getTile(int x, int y) const;
+
+ void setTile(int x, int y, MapItem* item);
+
+ void setTile(int x, int y, int type);
+
+ void addRoad(Path road);
+
+ void clean();
+
+ void itemDraw(Graphics *graphics, int x, int y,
+ int scrollX, int scrollY);
+
+ private:
+ int mWidth, mHeight;
+ bool mDrawSprites;
+ MapItem **mTiles;
+};
+
+class MapItem
+{
+ public:
+ friend class Map;
+ friend class MapLayer;
+
+ enum ItemType
+ {
+ EMPTY = 0,
+ HOME = 1,
+ ROAD = 2,
+ CROSS = 3,
+ ARROW_UP = 4,
+ ARROW_DOWN = 5,
+ ARROW_LEFT = 6,
+ ARROW_RIGHT = 7,
+ PORTAL = 8
+ };
+
+ MapItem();
+
+ MapItem(int type);
+
+ MapItem(int type, std::string comment);
+
+ MapItem(int type, std::string comment, int x, int y);
+
+ ~MapItem();
+
+ int getType() const
+ { return mType; }
+
+ void setType(int type);
+
+ void setPos(int x, int y);
+
+ int getX() const
+ { return mX; }
+
+ int getY() const
+ { return mY; }
+
+ std::string &getComment()
+ { return mComment; }
+
+ void setComment(std::string comment)
+ { mComment = comment; }
+
+ std::string &getName()
+ { return mName; }
+
+ void setName(std::string name)
+ { mName = name; }
+
+ void draw(Graphics *graphics, int x, int y, int dx, int dy);
+
+ private:
+ int mType;
+ Image *mImage;
+ std::string mComment;
+ std::string mName;
+ int mX;
+ int mY;
+};
+
+#endif