1 //       _________ __                 __
2 //      /   _____//  |_____________ _/  |______     ____  __ __  ______
3 //      \_____  \\   __\_  __ \__  \\   __\__  \   / ___\|  |  \/  ___/
4 //      /        \|  |  |  | \// __ \|  |  / __ \_/ /_/  >  |  /\___ |
5 //     /_______  /|__|  |__|  (____  /__| (____  /\___  /|____//____  >
6 //             \/                  \/          \//_____/            \/
7 //  ______________________                           ______________________
8 //                        T H E   W A R   B E G I N S
9 //         Stratagus - A free fantasy real time strategy game engine
10 //
11 /**@name tileset.h - The tileset headerfile. */
12 //
13 //      (c) Copyright 1998-2005 by Lutz Sammer and Jimmy Salmon
14 //
15 //      This program is free software; you can redistribute it and/or modify
16 //      it under the terms of the GNU General Public License as published by
17 //      the Free Software Foundation; only version 2 of the License.
18 //
19 //      This program is distributed in the hope that it will be useful,
20 //      but WITHOUT ANY WARRANTY; without even the implied warranty of
21 //      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 //      GNU General Public License for more details.
23 //
24 //      You should have received a copy of the GNU General Public License
25 //      along with this program; if not, write to the Free Software
26 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 //      02111-1307, USA.
28 //
29 
30 #ifndef TILESET_H
31 #define TILESET_H
32 
33 //@{
34 
35 /*----------------------------------------------------------------------------
36 --  Declarations
37 ----------------------------------------------------------------------------*/
38 
39 #include "vec2i.h"
40 #include <vector>
41 //Wyrmgus start
42 #include <map>
43 #include <tuple>
44 
45 #include "color.h"
46 //Wyrmgus end
47 
48 struct lua_State;
49 //Wyrmgus start
50 class CGraphic;
51 class CPlayerColorGraphic;
52 class CUnitType;
53 //Wyrmgus end
54 
55 enum MapFieldFlag : unsigned long long {
56 	MapFieldSpeedMask = 1 << 0,		/// Move faster on this tile
57 
58 	MapFieldLandAllowed = 1 << 1,	/// Land units allowed
59 	MapFieldCoastAllowed = 1 << 2,	/// Coast (e.g. transporter) units allowed
60 	MapFieldWaterAllowed = 1 << 3,	/// Water units allowed
61 	MapFieldNoBuilding = 1 << 4,	/// No buildings allowed
62 
63 	MapFieldUnpassable = 1 << 5,	/// Field is movement blocked
64 	MapFieldAirUnpassable = 1 << 6,	/// Field is movement blocked for air units and missiles
65 	MapFieldWall = 1 << 7,			/// Field contains wall
66 	MapFieldRocks = 1 << 8,			/// Field contains rocks
67 	MapFieldForest = 1 << 9,		/// Field contains forest
68 
69 	MapFieldLandUnit = 1 << 10,		/// Land unit on field
70 	MapFieldSeaUnit = 1 << 11,		/// Water unit on field
71 	MapFieldAirUnit = 1 << 12,		/// Air unit on field
72 	MapFieldBuilding = 1 << 13,		/// Building on field
73 	MapFieldItem = 1 << 14,			/// Item on field
74 
75 	MapFieldRoad = 1 << 15,			/// Road (moves faster)
76 	MapFieldRailroad = 1 << 16,		/// Railroad (moves faster)
77 	MapFieldNoRail = 1 << 17,		/// Marker that there's no railroad, used for rail movemasks
78 	MapFieldBridge = 1 << 18,		/// Bridge or raft
79 
80 	MapFieldGrass = 1 << 19,		/// Used for playing grass step sounds
81 	MapFieldMud = 1 << 20,			/// Used for playing mud step sounds
82 	MapFieldStoneFloor = 1 << 21,	/// Used for playing stone step sounds
83 	MapFieldDirt = 1 << 22,			/// Used for playing dirt step sounds
84 	MapFieldDesert = 1 << 23,		/// Used for identifying desert tiles for desertstalk and dehydration
85 	MapFieldSnow = 1 << 24,			/// Used for playing snow step sounds
86 	MapFieldIce = 1 << 25,			/// Used for playing ice step sounds
87 
88 	MapFieldGravel = 1 << 26,		/// Used for playing gravel step sounds
89 	MapFieldStumps = 1 << 27,		/// Used for playing stumps step sounds and identifying removed forests
90 };
91 
92 /**
93 **  These are used for lookup tiles types
94 **  mainly used for the FOW implementation of the seen woods/rocks
95 **
96 **  @todo I think this can be removed, we can use the flags?
97 **  I'm not sure, if we have seen and real time to considere.
98 */
99 enum TileType {
100 	TileTypeUnknown,	/// Unknown tile type
101 	TileTypeWood,		/// Any wood tile
102 	TileTypeRock,		/// Any rock tile
103 	TileTypeCoast,		/// Any coast tile
104 	TileTypeWall,		/// Any wall tile
105 	TileTypeWater		/// Any water tile
106 };
107 
108 //Wyrmgus start
109 enum TransitionTypes {
110 	NorthTransitionType,
111 	SouthTransitionType,
112 	WestTransitionType,
113 	EastTransitionType,
114 	NorthwestOuterTransitionType,
115 	NortheastOuterTransitionType,
116 	SouthwestOuterTransitionType,
117 	SoutheastOuterTransitionType,
118 	NorthwestInnerTransitionType,
119 	NortheastInnerTransitionType,
120 	SouthwestInnerTransitionType,
121 	SoutheastInnerTransitionType,
122 	NorthwestSoutheastInnerTransitionType,
123 	NortheastSouthwestInnerTransitionType,
124 
125 	//single tile transition types (enabled for terrain types with the AllowSingle field)
126 	SingleTransitionType,
127 	NorthSingleTransitionType,
128 	SouthSingleTransitionType,
129 	WestSingleTransitionType,
130 	EastSingleTransitionType,
131 	NorthSouthTransitionType,
132 	WestEastTransitionType,
133 	NorthwestNortheastSouthwestSoutheastInnerTransitionType,
134 	NorthwestNortheastInnerTransitionType,
135 	SouthwestSoutheastInnerTransitionType,
136 	NorthwestSouthwestInnerTransitionType,
137 	NortheastSoutheastInnerTransitionType,
138 	NorthwestNortheastSouthwestInnerTransitionType,
139 	NorthwestNortheastSoutheastInnerTransitionType,
140 	NorthwestSouthwestSoutheastInnerTransitionType,
141 	NortheastSouthwestSoutheastInnerTransitionType,
142 	NorthSouthwestInnerSoutheastInnerTransitionType,
143 	NorthSouthwestInnerTransitionType,
144 	NorthSoutheastInnerTransitionType,
145 	SouthNorthwestInnerNortheastInnerTransitionType,
146 	SouthNorthwestInnerTransitionType,
147 	SouthNortheastInnerTransitionType,
148 	WestNortheastInnerSoutheastInnerTransitionType,
149 	WestNortheastInnerTransitionType,
150 	WestSoutheastInnerTransitionType,
151 	EastNorthwestInnerSouthwestInnerTransitionType,
152 	EastNorthwestInnerTransitionType,
153 	EastSouthwestInnerTransitionType,
154 	NorthwestOuterSoutheastInnerTransitionType,
155 	NortheastOuterSouthwestInnerTransitionType,
156 	SouthwestOuterNortheastInnerTransitionType,
157 	SoutheastOuterNorthwestInnerTransitionType,
158 
159 	MaxTransitionTypes
160 };
161 //Wyrmgus end
162 
163 /// Single tile definition
164 struct CTileInfo {
165 public:
CTileInfoCTileInfo166 	CTileInfo() : BaseTerrain(0), MixTerrain(0)
167 	{}
CTileInfoCTileInfo168 	CTileInfo(unsigned char base, unsigned char mix) : BaseTerrain(base), MixTerrain(mix)
169 	{}
170 
171 	bool operator ==(const CTileInfo &rhs) const
172 	{
173 		return BaseTerrain == rhs.BaseTerrain && MixTerrain == rhs.MixTerrain;
174 	}
175 	bool operator !=(const CTileInfo &rhs) const { return !(*this == rhs); }
176 
177 public:
178 	unsigned char BaseTerrain; /// Basic terrain of the tile
179 	unsigned char MixTerrain;  /// Terrain mixed with this
180 };
181 
182 /// Definition for a terrain type
183 struct SolidTerrainInfo {
184 	std::string TerrainName;  /// Name of the terrain
185 	// TODO: When drawing with the editor add some kind fo probabilities for every tile.
186 	//Wyrmgus start
187 	int DefaultTileIndex;		/// Index for the default tile for this type
188 	//Wyrmgus end
189 };
190 
191 class CTile
192 {
193 public:
CTile()194 	CTile() : tile(0), flag(0) {}
195 
196 public:
197 	unsigned short tile;  /// graphical pos
198 	//Wyrmgus start
199 //	unsigned short flag;  /// Flag
200 	unsigned long flag;  /// Flag
201 	//Wyrmgus end
202 	CTileInfo tileinfo;   /// Tile descriptions
203 };
204 
205 /// Tileset definition
206 class CTileset
207 {
208 public:
209 	void clear();
210 
getTileCount()211 	unsigned int getTileCount() const { return tiles.size(); }
212 
213 	unsigned int getDefaultTileIndex() const;
214 	//Wyrmgus start
215 	unsigned int getDefaultWoodTileIndex() const;
216 	//Wyrmgus end
217 
218 	bool isAWallTile(unsigned tile) const;
219 	bool isAWoodTile(unsigned tile) const;
220 	bool isARockTile(unsigned tile) const;
221 
getPixelTileSize()222 	const PixelSize &getPixelTileSize() const { return pixelTileSize; }
223 
224 	//Wyrmgus start
225 //	unsigned getRemovedRockTile() const { return removedRockTile; }
226 //	unsigned getRemovedTreeTile() const { return removedTreeTile; }
getRemovedRockTile()227 	unsigned getRemovedRockTile() const { return removedRockTiles.size() > 0 ? removedRockTiles[SyncRand(removedRockTiles.size())] : -1; }
getRemovedTreeTile()228 	unsigned getRemovedTreeTile() const { return removedTreeTiles.size() > 0 ? removedTreeTiles[SyncRand(removedTreeTiles.size())] : -1; }
229 	//Wyrmgus end
getBottomOneTreeTile()230 	unsigned getBottomOneTreeTile() const { return botOneTreeTile; }
getTopOneTreeTile()231 	unsigned getTopOneTreeTile() const { return topOneTreeTile; }
getMidOneTreeTile()232 	unsigned getMidOneTreeTile() const { return midOneTreeTile; }
233 
234 	unsigned getWallDirection(int tileIndex, bool human) const;
235 
236 	unsigned getHumanWallTileIndex(int dirFlag) const;
237 	unsigned getOrcWallTileIndex(int dirFlag) const;
238 	unsigned getHumanWallTileIndex_broken(int dirFlag) const;
239 	unsigned getOrcWallTileIndex_broken(int dirFlag) const;
240 	unsigned getHumanWallTileIndex_destroyed(int dirFlag) const;
241 	unsigned getOrcWallTileIndex_destroyed(int dirFlag) const;
242 
243 	unsigned int getSolidTerrainCount() const;
244 
245 	const std::string &getTerrainName(int solidTerrainIndex) const;
246 
247 	int findTileIndexByTile(unsigned int tile) const;
248 	unsigned int getTileNumber(int basic, bool random, bool filler) const;
249 	void fillSolidTiles(std::vector<unsigned int> *solidTiles) const;
250 
251 	//Wyrmgus start
252 //	unsigned getQuadFromTile(unsigned int tile) const;
253 	unsigned getQuadFromTile(unsigned int tileIndex) const;
254 	//Wyrmgus end
255 	//Wyrmgus start
256 	int getFromMixedLookupTable(int base_terrain, int tile) const;
257 //	int getTileBySurrounding(unsigned short type
258 	int getTileBySurrounding(unsigned short type,
259 							 int tile_index,
260 	//Wyrmgus end
261 							 int up, int right,
262 							 int bottom, int left) const;
263 	int tileFromQuad(unsigned fixed, unsigned quad) const;
264 	//Wyrmgus start
265 //	bool isEquivalentTile(unsigned int tile1, unsigned int tile2) const;
266 	bool isEquivalentTile(unsigned int tile1, unsigned int tile2, int tile_index) const;
267 	//Wyrmgus end
268 
269 	void parse(lua_State *l);
270 	void buildTable(lua_State *l);
271 
272 private:
273 	unsigned int getOrAddSolidTileIndexByName(const std::string &name);
274 	int findTileIndex(unsigned char baseTerrain, unsigned char mixTerrain = 0) const;
275 	int getTileIndex(unsigned char baseTerrain, unsigned char mixTerrain, unsigned int quad) const;
276 	void buildWallReplacementTable();
277 	void parseSlots(lua_State *l, int t);
278 	void parseSpecial(lua_State *l);
279 	void parseSolid(lua_State *l);
280 	void parseMixed(lua_State *l);
281 	int findTilePath(int base, int goal, int length, std::vector<char> &marks, int *tileIndex) const;
282 public:
283 	std::string Name;           /// Nice name to display
284 	//Wyrmgus start
285 	std::string Ident;			/// Ident of the tileset
286 	//Wyrmgus end
287 	std::string ImageFile;      /// File containing image data
288 
289 public:
290 	std::vector<CTile> tiles;
291 
292 	// TODO: currently hardcoded
293 	std::vector<unsigned char> TileTypeTable;  /// For fast lookup of tile type
294 	//Wyrmgus start
295 	std::vector<SolidTerrainInfo> solidTerrainTypes; /// Information about solid terrains.
296 	int TreeUnderlayTerrain;
297 	int RockUnderlayTerrain;
298 	std::vector<unsigned> removedTreeTiles;  /// Tiles placed where trees are gone
299 	std::vector<unsigned> removedRockTiles;  /// Tiles placed where trees are gone
300 	//Wyrmgus end
301 private:
302 	PixelSize pixelTileSize;    /// Size of a tile in pixel
303 	//Wyrmgus start
304 //	std::vector<SolidTerrainInfo> solidTerrainTypes; /// Information about solid terrains.
305 	//Wyrmgus end
306 #if 1
307 	//Wyrmgus start
308 //	std::vector<int> mixedLookupTable;  /// Lookup for what part of tile used
309 	std::map<std::pair<int,int>, int> mixedLookupTable;  /// Lookup for what part of tile used; mapped to a pair, which has its first element as the tile type and the second element as the graphic tile
310 	//Wyrmgus end
311 	unsigned topOneTreeTile;   /// Tile for one tree top
312 	unsigned midOneTreeTile;   /// Tile for one tree middle
313 	unsigned botOneTreeTile;   /// Tile for one tree bottom
314 	//Wyrmgus start
315 //	unsigned removedTreeTile;  /// Tile placed where trees are gone
316 	//Wyrmgus end
317 	int woodTable[20];     /// Table for tree removable
318 	unsigned topOneRockTile;   /// Tile for one rock top
319 	unsigned midOneRockTile;   /// Tile for one rock middle
320 	unsigned botOneRockTile;   /// Tile for one rock bottom
321 	//Wyrmgus start
322 //	unsigned removedRockTile;  /// Tile placed where rocks are gone
323 	//Wyrmgus end
324 	int rockTable[20];     /// Removed rock placement table
325 	unsigned humanWallTable[16];  /// Human wall placement table
326 	unsigned orcWallTable[16];    /// Orc wall placement table
327 #endif
328 };
329 
330 //Wyrmgus start
331 /*----------------------------------------------------------------------------
332 -- Variables
333 ----------------------------------------------------------------------------*/
334 
335 /*----------------------------------------------------------------------------
336 --  Functions
337 ----------------------------------------------------------------------------*/
338 
339 extern void ParseTilesetTileFlags(lua_State *l, int *back, int *j);
340 //Wyrmgus start
341 extern std::string GetTransitionTypeNameById(int transition_type);
342 extern int GetTransitionTypeIdByName(const std::string &transition_type);
343 //Wyrmgus end
344 
345 //@}
346 
347 #endif // !TILESET_H
348