1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef ULTIMA4_MAP_TILE_H
24 #define ULTIMA4_MAP_TILE_H
25 
26 #include "ultima/ultima4/map/direction.h"
27 #include "ultima/ultima4/core/types.h"
28 #include "ultima/ultima4/map/tileset.h"
29 #include "ultima/shared/std/containers.h"
30 
31 namespace Ultima {
32 namespace Ultima4 {
33 
34 class ConfigElement;
35 class Image;
36 class Tileset;
37 class TileAnim;
38 
39 /* attr masks */
40 #define MASK_SHIP                   0x0001
41 #define MASK_HORSE                  0x0002
42 #define MASK_BALLOON                0x0004
43 #define MASK_DISPEL                 0x0008
44 #define MASK_TALKOVER               0x0010
45 #define MASK_DOOR                   0x0020
46 #define MASK_LOCKEDDOOR             0x0040
47 #define MASK_CHEST                  0x0080
48 #define MASK_ATTACKOVER             0x0100
49 #define MASK_CANLANDBALLOON         0x0200
50 #define MASK_REPLACEMENT            0x0400
51 #define MASK_WATER_REPLACEMENT      0x0800
52 #define MASK_FOREGROUND             0x1000
53 #define MASK_LIVING_THING           0x2000
54 
55 
56 /* movement masks */
57 #define MASK_SWIMABLE           0x0001
58 #define MASK_SAILABLE           0x0002
59 #define MASK_UNFLYABLE          0x0004
60 #define MASK_CREATURE_UNWALKABLE 0x0008
61 
62 /**
63  * A Tile object represents a specific tile type.  Every tile is a
64  * member of a Tileset.
65  */
66 class Tile : private Uncopyable {
67 public:
68 	Tile(Tileset *tileset);
69 	~Tile();
70 
71 	/**
72 	 * Loads tile information.
73 	 */
74 	void loadProperties(const ConfigElement &conf);
75 
getId()76 	TileId getId() const {
77 		return _id;
78 	}
getName()79 	const Common::String &getName() const {
80 		return _name;
81 	}
getWidth()82 	int getWidth() const {
83 		return _w;
84 	}
getHeight()85 	int getHeight() const {
86 		return _h;
87 	}
getFrames()88 	int getFrames() const {
89 		return _frames;
90 	}
getScale()91 	int getScale() const {
92 		return _scale;
93 	}
getAnim()94 	TileAnim *getAnim() const {
95 		return _anim;
96 	}
97 	Image *getImage();
getLooksLike()98 	const Common::String &getLooksLike() const {
99 		return _looksLike;
100 	}
101 
isTiledInDungeon()102 	bool isTiledInDungeon() const {
103 		return _tiledInDungeon;
104 	}
isLandForeground()105 	bool isLandForeground() const {
106 		return _foreground;
107 	}
isWaterForeground()108 	bool isWaterForeground() const {
109 		return _waterForeground;
110 	}
111 
canWalkOn(Direction d)112 	int canWalkOn(Direction d) const {
113 		return DIR_IN_MASK(d, rule->_walkOnDirs);
114 	}
canWalkOff(Direction d)115 	int canWalkOff(Direction d) const {
116 		return DIR_IN_MASK(d, rule->_walkOffDirs);
117 	}
118 
119 	/**
120 	 * All tiles that you can walk, swim, or sail on, can be attacked over. All others must declare
121 	 * themselves
122 	 */
canAttackOver()123 	int  canAttackOver() const {
124 		return isWalkable() || isSwimable() || isSailable() || (rule->_mask & MASK_ATTACKOVER);
125 	}
canLandBalloon()126 	int  canLandBalloon() const {
127 		return rule->_mask & MASK_CANLANDBALLOON;
128 	}
isLivingObject()129 	int  isLivingObject() const {
130 		return rule->_mask & MASK_LIVING_THING;
131 	}
isReplacement()132 	int  isReplacement() const {
133 		return rule->_mask & MASK_REPLACEMENT;
134 	}
isWaterReplacement()135 	int  isWaterReplacement() const {
136 		return rule->_mask & MASK_WATER_REPLACEMENT;
137 	}
138 
isWalkable()139 	int  isWalkable() const {
140 		return rule->_walkOnDirs > 0;
141 	}
isCreatureWalkable()142 	bool isCreatureWalkable() const {
143 		return canWalkOn(DIR_ADVANCE) && !(rule->_movementMask & MASK_CREATURE_UNWALKABLE);
144 	}
145 	bool isDungeonWalkable() const;
146 	bool isDungeonFloor() const;
isSwimable()147 	int  isSwimable() const {
148 		return rule->_movementMask & MASK_SWIMABLE;
149 	}
isSailable()150 	int  isSailable() const {
151 		return rule->_movementMask & MASK_SAILABLE;
152 	}
isWater()153 	bool isWater() const {
154 		return (isSwimable() || isSailable());
155 	}
isFlyable()156 	int  isFlyable() const {
157 		return !(rule->_movementMask & MASK_UNFLYABLE);
158 	}
isDoor()159 	int  isDoor() const {
160 		return rule->_mask & MASK_DOOR;
161 	}
isLockedDoor()162 	int  isLockedDoor() const {
163 		return rule->_mask & MASK_LOCKEDDOOR;
164 	}
isChest()165 	int  isChest() const {
166 		return rule->_mask & MASK_CHEST;
167 	}
isShip()168 	int  isShip() const {
169 		return rule->_mask & MASK_SHIP;
170 	}
isPirateShip()171 	bool isPirateShip() const {
172 		return _name == "pirate_ship";
173 	}
isHorse()174 	int  isHorse() const {
175 		return rule->_mask & MASK_HORSE;
176 	}
isBalloon()177 	int  isBalloon() const {
178 		return rule->_mask & MASK_BALLOON;
179 	}
canDispel()180 	int  canDispel() const {
181 		return rule->_mask & MASK_DISPEL;
182 	}
canTalkOver()183 	int  canTalkOver() const {
184 		return rule->_mask & MASK_TALKOVER;
185 	}
getSpeed()186 	TileSpeed getSpeed() const {
187 		return rule->_speed;
188 	}
getEffect()189 	TileEffect getEffect() const {
190 		return rule->_effect;
191 	}
192 
193 	bool isOpaque() const;
194 
195 	/**
196 	 * Is tile a foreground tile (i.e. has transparent parts).
197 	 * Deprecated? Never used in XML. Other mechanisms exist, though this could help?
198 	 */
199 	bool isForeground() const;
200 	Direction directionForFrame(int frame) const;
201 	int frameForDirection(Direction d) const;
202 
resetNextId()203 	static void resetNextId() {
204 		_nextId = 0;
205 	}
canTalkOverTile(const Tile * tile)206 	static bool canTalkOverTile(const Tile *tile) {
207 		return tile->canTalkOver() != 0;
208 	}
canAttackOverTile(const Tile * tile)209 	static bool canAttackOverTile(const Tile *tile) {
210 		return tile->canAttackOver() != 0;
211 	}
212 	void deleteImage();
213 
214 private:
215 	/**
216 	 * Loads the tile image
217 	 */
218 	void loadImage();
219 
220 private:
221 	TileId _id;          /**< an id that is unique across all tilesets */
222 	Common::String _name;        /**< The name of this tile */
223 	Tileset *_tileSet;   /**< The tileset this tile belongs to */
224 	int _w, _h;           /**< width and height of the tile */
225 	int _frames;         /**< The number of frames this tile has */
226 	int _scale;          /**< The scale of the tile */
227 	TileAnim *_anim;     /**< The tile animation for this tile */
228 	bool _opaque;        /**< Is this tile opaque? */
229 
230 	bool _foreground;    /**< As a maptile, is a foreground that will search neighbour maptiles for a land-based background replacement. ex: chests */
231 	bool _waterForeground;/**< As a maptile, is a foreground that will search neighbour maptiles for a water-based background replacement. ex: chests */
232 
233 	TileRule *rule;     /**< The rules that govern the behavior of this tile */
234 	Common::String _imageName;   /**< The name of the image that belongs to this tile */
235 	Common::String _looksLike;  /**< The name of the tile that this tile looks exactly like (if any) */
236 
237 	Image *_image;       /**< The original image for this tile (with all of its frames) */
238 	bool _tiledInDungeon;
239 	Std::vector<Direction> _directions;
240 
241 	Common::String _animationRule;
242 
243 
244 	static TileId _nextId;
245 };
246 
247 } // End of namespace Ultima4
248 } // End of namespace Ultima
249 
250 #endif
251