1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305
|
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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 3 of the License, or
* (at your option) 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 ULTIMA4_MAP_MAP_H
#define ULTIMA4_MAP_MAP_H
#include "ultima/ultima4/core/coords.h"
#include "ultima/ultima4/map/direction.h"
#include "ultima/ultima4/sound/music.h"
#include "ultima/ultima4/game/object.h"
#include "ultima/ultima4/filesys/savegame.h"
#include "ultima/ultima4/core/types.h"
namespace Ultima {
namespace Ultima4 {
#define MAP_IS_OOB(mapptr, c) (((c).x) < 0 || ((c).x) >= (static_cast<int>((mapptr)->_width)) || ((c).y) < 0 || ((c).y) >= (static_cast<int>((mapptr)->_height)) || ((c).z) < 0 || ((c).z) >= (static_cast<int>((mapptr)->_levels)))
class AnnotationMgr;
class Map;
class Object;
class Person;
class Creature;
class TileMap;
class Tileset;
struct Portal;
struct _Dungeon;
typedef Std::vector<Portal *> PortalList;
typedef Common::List<int> CompressedChunkList;
typedef Std::vector<MapTile> MapData;
/* flags */
#define SHOW_AVATAR (1 << 0)
#define NO_LINE_OF_SIGHT (1 << 1)
#define FIRST_PERSON (1 << 2)
/* mapTileAt flags */
#define WITHOUT_OBJECTS 0
#define WITH_GROUND_OBJECTS 1
#define WITH_OBJECTS 2
/**
* MapCoords class
*/
class MapCoords : public Coords {
public:
MapCoords(int initx = 0, int inity = 0, int initz = 0) : Coords(initx, inity, initz) {}
MapCoords(const Coords &a) : Coords(a.x, a.y, a.z) {}
MapCoords &operator=(const Coords &a) {
x = a.x;
y = a.y;
z = a.z;
return *this;
}
bool operator==(const MapCoords &a) const;
bool operator!=(const MapCoords &a) const;
bool operator<(const MapCoords &a) const;
MapCoords &wrap(const class Map *map);
MapCoords &putInBounds(const class Map *map);
MapCoords &move(Direction d, const class Map *map = nullptr);
MapCoords &move(int dx, int dy, const class Map *map = nullptr);
/**
* Returns a mask of directions that indicate where one point is relative
* to another. For instance, if the object at (x, y) is
* northeast of (c.x, c.y), then this function returns
* (MASK_DIR(DIR_NORTH) | MASK_DIR(DIR_EAST))
* This function also takes into account map boundaries and adjusts
* itself accordingly. If the two coordinates are not on the same z-plane,
* then this function return DIR_NONE.
*/
int getRelativeDirection(const MapCoords &c, const class Map *map = nullptr) const;
/**
* Finds the appropriate direction to travel to get from one point to
* another. This algorithm will avoid getting trapped behind simple
* obstacles, but still fails with anything mildly complicated.
* This function also takes into account map boundaries and adjusts
* itself accordingly, provided the 'map' parameter is passed
*/
Direction pathTo(const MapCoords &c, int valid_dirs = MASK_DIR_ALL, bool towards = true, const class Map *map = nullptr) const;
/**
* Finds the appropriate direction to travel to move away from one point
*/
Direction pathAway(const MapCoords &c, int valid_dirs = MASK_DIR_ALL) const;
/**
* Finds the movement distance (not using diagonals) from point a to point b
* on a map, taking into account map boundaries and such. If the two coords
* are not on the same z-plane, then this function returns -1;
*/
int movementDistance(const MapCoords &c, const class Map *map = nullptr) const;
/**
* Finds the distance (using diagonals) from point a to point b on a map
* If the two coordinates are not on the same z-plane, then this function
* returns -1. This function also takes into account map boundaries.
*/
int distance(const MapCoords &c, const class Map *map = nullptr) const;
/**
* Returns true if the co-ordinates point to nowhere
*/
static MapCoords nowhere() {
return MapCoords(-1, -1, -1);
}
};
/**
* Map class
*/
class Map {
public:
enum Type {
WORLD,
CITY,
SHRINE,
COMBAT,
DUNGEON,
XML
};
enum BorderBehavior {
BORDER_WRAP,
BORDER_EXIT2PARENT,
BORDER_FIXED
};
class Source {
public:
Source() : _type(WORLD) {}
Source(const Common::String &f, Type t) : _fname(f), _type(t) {}
Common::String _fname;
Type _type;
};
Map();
virtual ~Map();
// Member functions
virtual Common::String getName();
/**
* Returns the object at the given (x,y,z) coords, if one exists.
* Otherwise, returns nullptr.
*/
Object *objectAt(const Coords &coords);
/**
* Returns the portal for the correspoding action(s) given.
* If there is no portal that corresponds to the actions flagged
* by 'actionFlags' at the given (x,y,z) coords, it returns nullptr.
*/
const Portal *portalAt(const Coords &coords, int actionFlags);
/**
* Returns the raw tile for the given (x,y,z) coords for the given map
*/
MapTile *getTileFromData(const Coords &coords);
/**
* Returns the current ground tile at the given point on a map. Visual-only
* annotations like moongates and attack icons are ignored. Any walkable tiles
* are taken into account (treasure chests, ships, balloon, etc.)
*/
MapTile *tileAt(const Coords &coords, int withObjects);
const Tile *tileTypeAt(const Coords &coords, int withObjects);
/**
* Returns true if the given map is the world map
*/
bool isWorldMap();
/**
* Returns true if the map is enclosed (to see if gem layouts should cut themselves off)
*/
bool isEnclosed(const Coords &party);
/**
* Adds a creature object to the given map
*/
Creature *addCreature(const class Creature *m, Coords coords);
Object *addObject(MapTile tile, MapTile prevTile, Coords coords);
/**
* Adds an object to the given map
*/
Object *addObject(Object *obj, Coords coords);
/**
* Removes an object from the map
*
* This function should only be used when not iterating through an
* ObjectDeque, as the iterator will be invalidated and the
* results will be unpredictable. Instead, use the function below.
*/
void removeObject(const class Object *rem, bool deleteObject = true);
ObjectDeque::iterator removeObject(ObjectDeque::iterator rem, bool deleteObject = true);
/**
* Removes all objects from the given map
*/
void clearObjects();
/**
* Moves all of the objects on the given map.
* Returns an attacking object if there is a creature attacking.
* Also performs special creature actions and creature effects.
*/
Creature *moveObjects(MapCoords avatar);
/**
* Resets object animations to a value that is acceptable for
* savegame compatibility with u4dos.
*/
void resetObjectAnimations();
/**
* Returns the number of creatures on the given map
*/
int getNumberOfCreatures();
/**
* Returns a mask of valid moves for the given transport on the given map
*/
int getValidMoves(MapCoords from, MapTile transport);
bool move(Object *obj, Direction d);
/**
* Alerts the guards that the avatar is doing something bad
*/
void alertGuards();
MapCoords getLabel(const Common::String &name) const;
// u4dos compatibility
bool fillMonsterTable();
MapTile translateFromRawTileIndex(int c) const;
uint translateToRawTileIndex(MapTile &tile) const;
public:
MapId _id;
Common::Path _fname;
Type _type;
uint _width, _height, _levels;
uint _chunkWidth, _chunkHeight;
uint _offset;
Source _baseSource;
Common::List<Source> _extraSources;
CompressedChunkList _compressedChunks;
BorderBehavior _borderBehavior;
PortalList _portals;
AnnotationMgr *_annotations;
int _flags;
Music::Type _music;
MapData _data;
ObjectDeque _objects;
Common::HashMap<Common::String, MapCoords> _labels;
Tileset *_tileSet;
TileMap *_tileMap;
MapTile _blank;
// u4dos compatibility
SaveGameMonsterRecord _monsterTable[MONSTERTABLE_SIZE];
private:
// disallow map copying: all maps should be created and accessed
// through the MapMgr
Map(const Map &map);
Map &operator=(const Map &map);
void findWalkability(Coords coords, int *path_data);
};
} // End of namespace Ultima4
} // End of namespace Ultima
#endif
|