File: map.h

package info (click to toggle)
scummvm 2.9.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 450,580 kB
  • sloc: cpp: 4,299,825; asm: 28,322; python: 12,901; sh: 11,302; java: 9,289; xml: 7,895; perl: 2,639; ansic: 2,465; yacc: 1,670; javascript: 1,020; makefile: 933; lex: 578; awk: 275; objc: 82; sed: 11; php: 1
file content (305 lines) | stat: -rw-r--r-- 8,654 bytes parent folder | download | duplicates (2)
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