1 /*
2  * Copyright 2010-2014 OpenXcom Developers.
3  *
4  * This file is part of OpenXcom.
5  *
6  * OpenXcom is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * OpenXcom is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with OpenXcom.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 #ifndef OPENXCOM_TILE_H
20 #define OPENXCOM_TILE_H
21 
22 #include <string>
23 #include <vector>
24 #include "../Battlescape/Position.h"
25 #include "../Ruleset/MapData.h"
26 #include "BattleUnit.h"
27 
28 #include <SDL_types.h> // for Uint8
29 
30 namespace OpenXcom
31 {
32 
33 class Surface;
34 class MapData;
35 class BattleUnit;
36 class BattleItem;
37 class RuleInventory;
38 
39 /**
40  * Basic element of which a battle map is build.
41  * @sa http://www.ufopaedia.org/index.php?title=MAPS
42  */
43 class Tile
44 {
45 public:
46 	static struct SerializationKey
47 	{
48 		// how many bytes to store for each variable or each member of array of the same name
49 		Uint8 index; // for indexing the actual tile array
50 		Uint8 _mapDataSetID;
51 		Uint8 _mapDataID;
52 		Uint8 _smoke;
53 		Uint8 _fire;
54         Uint8 boolFields;
55 		Uint32 totalBytes; // per structure, including any data not mentioned here and accounting for all array members!
56 	} serializationKey;
57 
58 	static const int NOT_CALCULATED = -1;
59 
60 protected:
61 	static const int LIGHTLAYERS = 3;
62 	MapData *_objects[4];
63 	int _mapDataID[4];
64 	int _mapDataSetID[4];
65 	int _currentFrame[4];
66 	bool _discovered[3];
67 	int _light[LIGHTLAYERS], _lastLight[LIGHTLAYERS];
68 	int _smoke;
69 	int _fire;
70 	int _explosive;
71 	Position _pos;
72 	BattleUnit *_unit;
73 	std::vector<BattleItem *> _inventory;
74 	int _animationOffset;
75 	int _markerColor;
76 	int _visible;
77 	int _preview;
78 	int _TUMarker;
79 	int _overlaps;
80 	bool _danger;
81 public:
82 	/// Creates a tile.
83 	Tile(const Position& pos);
84 	/// Cleans up a tile.
85 	~Tile();
86 	/// Load the tile from yaml
87 	void load(const YAML::Node &node);
88 	/// Load the tile from binary buffer in memory
89 	void loadBinary(Uint8 *buffer, Tile::SerializationKey& serializationKey);
90 	/// Saves the tile to yaml
91 	YAML::Node save() const;
92 	/// Saves the tile to binary
93 	void saveBinary(Uint8** buffer) const;
94 
95 	/**
96 	 * Get the MapData pointer of a part of the tile.
97 	 * @param part the part 0-3.
98 	 * @return pointer to mapdata
99 	 */
getMapData(int part)100 	MapData *getMapData(int part) const
101 	{
102 		if (0 > part || 3 < part)
103 		{
104 			return NULL;
105 		}
106 		return _objects[part];
107 	}
108 
109 	/// Sets the pointer to the mapdata for a specific part of the tile
110 	void setMapData(MapData *dat, int mapDataID, int mapDataSetID, int part);
111 	/// Gets the IDs to the mapdata for a specific part of the tile
112 	void getMapData(int *mapDataID, int *mapDataSetID, int part) const;
113 	/// Gets whether this tile has no objects
114 	bool isVoid() const;
115 	/// Get the TU cost to walk over a certain part of the tile.
116 	int getTUCost(int part, MovementType movementType) const;
117 	/// Checks if this tile has a floor.
118 	bool hasNoFloor(Tile *tileBelow) const;
119 	/// Checks if this tile is a big wall.
120 	bool isBigWall() const;
121 	/// Get terrain level.
122 	int getTerrainLevel() const;
123 
124 	/**
125 	 * Gets the tile's position.
126 	 * @return position
127 	 */
getPosition()128 	const Position& getPosition() const
129 	{
130 		return _pos;
131 	}
132 
133 	/// Gets the floor object footstep sound.
134 	int getFootstepSound(Tile *tileBelow) const;
135 	/// Open a door, returns the ID, 0(normal), 1(ufo) or -1 if no door opened.
136 	int openDoor(int part, BattleUnit *Unit = 0, BattleActionType reserve = BA_NONE);
137 
138 	/**
139 	 * Check if the ufo door is open or opening. Used for visibility/light blocking checks.
140 	 * This function assumes that there never are 2 doors on 1 tile or a door and another wall on 1 tile.
141 	 * @param part
142 	 * @return bool
143 	 */
isUfoDoorOpen(int part)144 	bool isUfoDoorOpen(int part) const
145 	{
146 		return (_objects[part] && _objects[part]->isUFODoor() && _currentFrame[part] != 0);
147 	}
148 
149 	/// Close ufo door.
150 	int closeUfoDoor();
151 	/// Sets the black fog of war status of this tile.
152 	void setDiscovered(bool flag, int part);
153 	/// Gets the black fog of war status of this tile.
154 	bool isDiscovered(int part) const;
155 	/// Reset light to zero for this tile.
156 	void resetLight(int layer);
157 	/// Add light to this tile.
158 	void addLight(int light, int layer);
159 	/// Get the shade amount.
160 	int getShade() const;
161 	/// Destroy a tile part.
162 	bool destroy(int part);
163 	/// Damage a tile part.
164 	bool damage(int part, int power);
165 	/// Set a "virtual" explosive on this tile, to detonate later.
166 	void setExplosive(int power, bool force = false);
167 	/// Get explosive power of this tile.
168 	int getExplosive() const;
169 	/// Animated the tile parts.
170 	void animate();
171 	/// Get object sprites.
172 	Surface *getSprite(int part) const;
173 	/// Set a unit on this tile.
174 	void setUnit(BattleUnit *unit, Tile *tileBelow = 0);
175 	/**
176 	 * Get the (alive) unit on this tile.
177 	 * @return BattleUnit.
178 	 */
getUnit()179 	BattleUnit *getUnit() const
180 	{
181 		return _unit;
182 	}
183 	/// Set fire, does not increment overlaps.
184 	void setFire(int fire);
185 	/// Get fire.
186 	int getFire() const;
187 	/// Add smoke, increments overlap.
188 	void addSmoke(int smoke);
189 	/// Set smoke, does not increment overlaps.
190 	void setSmoke(int smoke);
191 	/// Get smoke.
192 	int getSmoke() const;
193 	/// Get flammability.
194 	int getFlammability() const;
195 	/// Get turns to burn
196 	int getFuel() const;
197 	/// attempt to set the tile on fire, sets overlaps to one if successful.
198 	void ignite(int power);
199 	/// Get fire and smoke animation offset.
200 	int getAnimationOffset() const;
201 	/// Add item
202 	void addItem(BattleItem *item, RuleInventory *ground);
203 	/// Remove item
204 	void removeItem(BattleItem *item);
205 	/// Get top-most item
206 	int getTopItemSprite();
207 	/// New turn preparations.
208 	void prepareNewTurn();
209 	/// Get inventory on this tile.
210 	std::vector<BattleItem *> *getInventory();
211 	/// Set the tile marker color.
212 	void setMarkerColor(int color);
213 	/// Get the tile marker color.
214 	int getMarkerColor();
215 	/// Set the tile visible flag.
216 	void setVisible(int visibility);
217 	/// Get the tile visible flag.
218 	int getVisible();
219 	/// set the direction (used for path previewing)
220 	void setPreview(int dir);
221 	/// retrieve the direction stored by the pathfinding.
222 	int getPreview() const;
223 	/// set the number to be displayed for pathfinding preview.
224 	void setTUMarker(int tu);
225 	/// get the number to be displayed for pathfinding preview.
226 	int getTUMarker() const;
227 	/// how many times has this tile been overlapped with smoke/fire (runtime only)
228 	int getOverlaps() const;
229 	/// increment the overlap value on this tile.
230 	void addOverlap();
231 	/// set the danger flag on this tile (so the AI will avoid it).
232 	void setDangerous();
233 	/// check the danger flag on this tile.
234 	bool getDangerous();
235 
236 };
237 
238 }
239 
240 #endif
241