summaryrefslogtreecommitdiffstats
path: root/source/cChunk.h
blob: d90e817cfc2294822e1c19d42057c18df185bcb4 (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
#pragma once

#include <list>

namespace Json
{
	class Value;
};

class cCriticalSection;
class cFurnaceEntity;
class cPacket;
class cBlockEntity;
class cEntity;
class cClientHandle;
class cServer;
class cChunk
{
public:
	cChunk(int a_X, int a_Y, int a_Z);
	~cChunk();

	void Initialize();

	void Tick(float a_Dt);

	inline int GetPosX() { return m_PosX; }
	inline int GetPosY() { return m_PosY; }
	inline int GetPosZ() { return m_PosZ; }

	void Send( cClientHandle* a_Client );
	void AsyncUnload( cClientHandle* a_Client );

	void SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta );
	void FastSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta );
	char GetBlock( int a_X, int a_Y, int a_Z );
	char GetBlock( int a_BlockIdx );
	cBlockEntity* GetBlockEntity( int a_X, int a_Y, int a_Z );
	void RemoveBlockEntity( cBlockEntity* a_BlockEntity );
	void AddBlockEntity( cBlockEntity* a_BlockEntity );

	char GetHeight( int a_X, int a_Z );

	void SendBlockTo( int a_X, int a_Y, int a_Z, cClientHandle* a_Client );

	void AddClient( cClientHandle* a_Client );
	void RemoveClient( cClientHandle* a_Client );

	std::list< cEntity* > & GetEntities();// { return m_Entities; }
	void AddEntity( cEntity & a_Entity );
	bool RemoveEntity( cEntity & a_Entity, cChunk* a_CalledFrom = 0 );
	void LockEntities();
	void UnlockEntities();

	const std::list< cClientHandle* > & GetClients();// { return m_LoadedByClient; }

	inline void RecalculateLighting() { m_bCalculateLighting = true; } // Recalculate lighting next tick
	inline void RecalculateHeightmap() { m_bCalculateHeightmap = true; } // Recalculate heightmap next tick
	void SpreadLight(char* a_LightBuffer);

	bool SaveToDisk();
	bool LoadFromDisk();

	// Broadcasts to all clients that have loaded this chunk
	void Broadcast( const cPacket & a_Packet, cClientHandle* a_Exclude = 0 ) const;

	char* pGetBlockData() { return m_BlockData; }
	char* pGetType() { return m_BlockType; }
	char* pGetMeta() { return m_BlockMeta; }
	char* pGetLight() { return m_BlockLight; }
	char* pGetSkyLight() { return m_BlockSkyLight; }

	char GetLight(char* a_Buffer, int a_BlockIdx);
	char GetLight(char* a_Buffer, int x, int y, int z);
	void SetLight(char* a_Buffer, int a_BlockIdx, char a_Light);
	void SetLight(char* a_Buffer, int x, int y, int z, char light);

	void AddTickBlockEntity( cFurnaceEntity* a_Entity );
	//{
	//	m_TickBlockEntities.remove( a_Entity );
	//	m_TickBlockEntities.push_back( a_Entity );
	//}

	void RemoveTickBlockEntity( cFurnaceEntity* a_Entity );
	//{
	//	m_TickBlockEntities.remove( a_Entity );
	//}

	static const int c_NumBlocks = 16*128*16;
	static const int c_BlockDataSize = c_NumBlocks * 2 + (c_NumBlocks/2); // 2.5 * numblocks
private:
	struct sChunkState;
	sChunkState* m_pState;

	friend class cChunkMap; // So it has access to buffers and shit
	void LoadFromJson( const Json::Value & a_Value );
	void SaveToJson( Json::Value & a_Value );

	void GenerateTerrain();
	void CalculateLighting(); // Recalculate right now
	void CalculateHeightmap();
	void SpreadLightOfBlock(char* a_LightBuffer, int a_X, int a_Y, int a_Z, char a_Falloff);
	void SpreadLightOfBlockX(char* a_LightBuffer, int a_X, int a_Y, int a_Z);
	void SpreadLightOfBlockY(char* a_LightBuffer, int a_X, int a_Y, int a_Z);
	void SpreadLightOfBlockZ(char* a_LightBuffer, int a_X, int a_Y, int a_Z);

	void CreateBlockEntities();

	unsigned int MakeIndex(int x, int y, int z );

	bool m_bCalculateLighting;
	bool m_bCalculateHeightmap;

	int m_PosX, m_PosY, m_PosZ;

	char m_BlockData[c_BlockDataSize]; // Chunk data ready to be compressed and sent
	char *m_BlockType;		// Pointers to an element in m_BlockData
	char *m_BlockMeta;		// += NumBlocks
	char *m_BlockLight;		// += NumBlocks/2
	char *m_BlockSkyLight;	// += NumBlocks/2

	unsigned char m_HeightMap[16*16];

	unsigned int m_BlockTickNum;
	unsigned int m_BlockTickX, m_BlockTickY, m_BlockTickZ;

	cCriticalSection* m_EntitiesCriticalSection;
};