summaryrefslogtreecommitdiffstats
path: root/src/Map.h
blob: a6df7e5f2ef7920b170fbef7c064362010bc6d4e (plain) (blame)
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

// Map.h

// Implementation of in-game coloured maps





#pragma once





#include "BlockID.h"





class cClientHandle;
class cWorld;
class cPlayer;
class cMap;





/** Encapsulates a map decorator.
 *
 * A map decorator represents an object drawn on the map that can move freely.
 * (e.g. player trackers and item frame pointers)
 *
 * Excluding manually placed decorators,
 * decorators are automatically managed (allocated and freed) by their parent cMap instance.
 */
class cMapDecorator
{
public:

	enum eType
	{
		E_TYPE_PLAYER         = 0x00,
		E_TYPE_ITEM_FRAME     = 0x01,

		/** Player outside of the boundaries of the map. */
		E_TYPE_PLAYER_OUTSIDE = 0x06
	};


public:

	/** Constructs a map decorator fixed at the specified pixel coordinates. (DEBUG) */
	cMapDecorator(cMap * a_Map, eType a_Type, int a_X, int a_Z, int a_Rot);

	/** Constructs a map decorator that tracks a player. */
	cMapDecorator(cMap * a_Map, cPlayer * a_Player);

	/** Updates the decorator. */
	void Update(void);

	unsigned int GetPixelX(void) const { return m_PixelX; }
	unsigned int GetPixelZ(void) const { return m_PixelZ; }

	int GetRot(void) const { return m_Rot; }

	eType GetType(void) const { return m_Type; }

	cPlayer * GetPlayer(void) { return m_Player; }


protected:

	cMap * m_Map;

	eType m_Type;

	unsigned int m_PixelX;
	unsigned int m_PixelZ;

	unsigned int m_Rot;

	cPlayer * m_Player;

};

typedef std::list<cMapDecorator> cMapDecoratorList;





// tolua_begin

/** Encapsulates an in-game world map. */
class cMap
{
public:

	enum eBaseColor
	{
		E_BASE_COLOR_TRANSPARENT = 0,  /* Air     */
		E_BASE_COLOR_LIGHT_GREEN = 4,  /* Grass   */
		E_BASE_COLOR_LIGHT_BROWN = 8,  /* Sand    */
		E_BASE_COLOR_GRAY_1      = 12, /* Cloth   */
		E_BASE_COLOR_RED         = 16, /* TNT     */
		E_BASE_COLOR_PALE_BLUE   = 20, /* Ice     */
		E_BASE_COLOR_GRAY_2      = 24, /* Iron    */
		E_BASE_COLOR_DARK_GREEN  = 28, /* Foliage */
		E_BASE_COLOR_WHITE       = 32, /* Snow    */
		E_BASE_COLOR_LIGHT_GRAY  = 36, /* Clay    */
		E_BASE_COLOR_BROWN       = 40, /* Dirt    */
		E_BASE_COLOR_DARK_GRAY   = 44, /* Stone   */
		E_BASE_COLOR_BLUE        = 48, /* Water   */
		E_BASE_COLOR_DARK_BROWN  = 52  /* Wood    */
	};

	typedef Byte ColorID;

	// tolua_end

	typedef std::vector<ColorID> cColorList;


public:

	/** Construct an empty map. */
	cMap(unsigned int a_ID, cWorld * a_World);

	/** Construct an empty map at the specified coordinates. */
	cMap(unsigned int a_ID, int a_CenterX, int a_CenterZ, cWorld * a_World, unsigned int a_Scale = 3);

	/** Send this map to the specified client. WARNING: Slow */
	void SendTo(cClientHandle & a_Client);

	/** Update a circular region with the specified radius and center (in pixels). */
	void UpdateRadius(int a_PixelX, int a_PixelZ, unsigned int a_Radius);

	/** Update a circular region around the specified player. */
	void UpdateRadius(cPlayer & a_Player, unsigned int a_Radius);

	/** Send next update packet to the specified player and remove invalid decorators/clients. */
	void UpdateClient(cPlayer * a_Player);

	// tolua_begin

	/** Erase pixel data */
	void EraseData(void);

	void Resize(unsigned int a_Width, unsigned int a_Height);

	void SetPosition(int a_CenterX, int a_CenterZ);

	void SetScale(unsigned int a_Scale);

	bool SetPixel(unsigned int a_X, unsigned int a_Z, ColorID a_Data);

	ColorID GetPixel(unsigned int a_X, unsigned int a_Z);

	unsigned int GetWidth (void) const { return m_Width;  }
	unsigned int GetHeight(void) const { return m_Height; }

	unsigned int GetScale(void) const { return m_Scale; }

	int GetCenterX(void) const { return m_CenterX; }
	int GetCenterZ(void) const { return m_CenterZ; }

	unsigned int GetID(void) const { return m_ID; }

	cWorld * GetWorld(void) { return m_World; }

	AString GetName(void) { return m_Name; }

	eDimension GetDimension(void) const;

	unsigned int GetNumPixels(void) const;

	unsigned int GetPixelWidth(void) const;

	// tolua_end

	unsigned int GetNumDecorators(void) const;

	const cColorList & GetData(void) const { return m_Data; }

	static const char * GetClassStatic(void)  // Needed for ManualBindings's DoWith templates
	{
		return "cMap";
	}


protected:

	/** Encapsulates the state of a map client.
	 *
	 * In order to enhance performace, maps are streamed column-by-column to each client.
	 * This structure stores the state of the stream.
	 */
	struct cMapClient
	{
		cClientHandle * m_Handle;

		/** Whether the map scale was modified and needs to be resent. */
		bool m_SendInfo;

		/** Ticks since last decorator update. */
		unsigned int m_NextDecoratorUpdate;

		/** Number of pixel data updates. */
		Int64 m_DataUpdate;

		Int64 m_LastUpdate;
	};

	typedef std::list<cMapClient> cMapClientList;


private:

	/** Update the associated decorators. */
	void UpdateDecorators(void);

	/** Update the specified pixel. */
	bool UpdatePixel(unsigned int a_X, unsigned int a_Z);

	/** Add a new map client. */
	void AddPlayer(cPlayer * a_Player, cClientHandle * a_Handle, Int64 a_WorldAge);

	/** Remove inactive or invalid clients. */
	void RemoveInactiveClients(Int64 a_WorldAge);

	/** Send next update packet to the specified client. */
	void StreamNext(cMapClient & a_Client);

	unsigned int m_ID;

	unsigned int m_Width;
	unsigned int m_Height;

	/** The zoom level, 2^scale square blocks per pixel */
	unsigned int m_Scale;

	int m_CenterX;
	int m_CenterZ;

	/** Column-major array of colours */
	cColorList m_Data;

	cWorld * m_World;

	cMapDecoratorList m_Decorators;

	cMapClientList m_Clients;

	AString m_Name;

	friend class cMapSerializer;

}; // tolua_export