summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2012-03-14 21:56:09 +0100
committermadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2012-03-14 21:56:09 +0100
commit0b24efeb005e293a026f2ac8666020cea8316578 (patch)
tree4523c34112fbec3f056337191c00bddb6f7253d0
parentFixed the server not waiting for the world to save completely before stopping (diff)
downloadcuberite-0b24efeb005e293a026f2ac8666020cea8316578.tar
cuberite-0b24efeb005e293a026f2ac8666020cea8316578.tar.gz
cuberite-0b24efeb005e293a026f2ac8666020cea8316578.tar.bz2
cuberite-0b24efeb005e293a026f2ac8666020cea8316578.tar.lz
cuberite-0b24efeb005e293a026f2ac8666020cea8316578.tar.xz
cuberite-0b24efeb005e293a026f2ac8666020cea8316578.tar.zst
cuberite-0b24efeb005e293a026f2ac8666020cea8316578.zip
-rw-r--r--VC2008/MCServer.vcproj7
-rw-r--r--source/ChunkDef.h320
-rw-r--r--source/ChunkSender.cpp9
-rw-r--r--source/ChunkSender.h15
-rw-r--r--source/WGFlat.cpp16
-rw-r--r--source/WSSAnvil.cpp41
-rw-r--r--source/WSSCompact.cpp26
-rw-r--r--source/WorldStorage.cpp9
-rw-r--r--source/WorldStorage.h21
-rw-r--r--source/cChestEntity.cpp1
-rw-r--r--source/cChunk.cpp261
-rw-r--r--source/cChunk.h215
-rw-r--r--source/cChunk.inl.h78
-rw-r--r--source/cChunkGenerator.cpp14
-rw-r--r--source/cChunkGenerator.h2
-rw-r--r--source/cChunkMap.cpp65
-rw-r--r--source/cChunkMap.h94
-rw-r--r--source/cClientHandle.cpp8
-rw-r--r--source/cClientHandle.h2
-rw-r--r--source/cEntity.cpp3
-rw-r--r--source/cFurnaceEntity.cpp1
-rw-r--r--source/cMonster.cpp1
-rw-r--r--source/cPawn.cpp1
-rw-r--r--source/cPickup.cpp1
-rw-r--r--source/cPiston.cpp2
-rw-r--r--source/cPlayer.cpp1
-rw-r--r--source/cServer.cpp2
-rw-r--r--source/cSignEntity.cpp1
-rw-r--r--source/cWorld.cpp36
-rw-r--r--source/cWorld.h60
-rw-r--r--source/cWorldGenerator.cpp35
-rw-r--r--source/cWorldGenerator.h13
-rw-r--r--source/cWorldGenerator_Test.cpp7
-rw-r--r--source/packets/cPacket_MapChunk.cpp30
34 files changed, 806 insertions, 592 deletions
diff --git a/VC2008/MCServer.vcproj b/VC2008/MCServer.vcproj
index 589abdc27..6149af194 100644
--- a/VC2008/MCServer.vcproj
+++ b/VC2008/MCServer.vcproj
@@ -113,6 +113,9 @@
/>
<Tool
Name="VCCLCompilerTool"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="1"
+ WholeProgramOptimization="true"
AdditionalIncludeDirectories="../zlib-1.2.5;../jsoncpp-src-0.5.0/include;../lua-5.1.4/src;../tolua++-1.0.93/include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;"
RuntimeLibrary="2"
@@ -290,6 +293,10 @@
>
</File>
<File
+ RelativePath="..\source\ChunkDef.h"
+ >
+ </File>
+ <File
RelativePath="..\source\ChunkSender.cpp"
>
</File>
diff --git a/source/ChunkDef.h b/source/ChunkDef.h
new file mode 100644
index 000000000..38dfcd7b4
--- /dev/null
+++ b/source/ChunkDef.h
@@ -0,0 +1,320 @@
+
+// ChunkDef.h
+
+// Interfaces to helper types for chunk definitions. Most modules want to include this instead of cChunk.h
+
+
+
+
+
+#pragma once
+
+#include "Vector3i.h"
+
+
+
+
+
+/** This is really only a placeholder to be used in places where we need to "make up" a chunk's Y coord.
+It will help us when the new chunk format comes out and we need to patch everything up for compatibility.
+*/
+#define ZERO_CHUNK_Y 0
+
+// Used to smoothly convert to new axis ordering. One will be removed when deemed stable.
+#define AXIS_ORDER_YZX 1 // Original (1.1-)
+#define AXIS_ORDER_XZY 2 // New (1.2+)
+#define AXIS_ORDER AXIS_ORDER_XZY
+
+
+
+
+
+// fwd
+class cBlockEntity;
+class cEntity;
+class cClientHandle;
+class cBlockEntity;
+
+typedef std::list<cEntity *> cEntityList;
+typedef std::list<cBlockEntity *> cBlockEntityList;
+
+
+
+
+/// The datatype used by blockdata, metadata, blocklight and skylight
+typedef char BLOCKTYPE;
+
+
+
+
+
+/// Constants used throughout the code, useful typedefs and utility functions
+class cChunkDef
+{
+public:
+ static const int Width = 16;
+ static const int Height = 256;
+ static const int NumBlocks = Width * Height * Width;
+ static const int BlockDataSize = NumBlocks * 2 + (NumBlocks / 2); // 2.5 * numblocks
+
+ // Offsets to individual components in the joined blockdata array
+ static const int MetaOffset = NumBlocks;
+ static const int LightOffset = MetaOffset + NumBlocks / 2;
+ static const int SkyLightOffset = LightOffset + NumBlocks / 2;
+
+ static const unsigned int INDEX_OUT_OF_RANGE = 0xffffffff;
+
+ typedef unsigned char HeightMap[Width * Width];
+
+
+ /// Converts absolute block coords into relative (chunk + block) coords:
+ inline static void AbsoluteToRelative(/* in-out */ int & a_X, int & a_Y, int & a_Z, /* out */ int & a_ChunkX, int & a_ChunkZ )
+ {
+ BlockToChunk(a_X, a_Y, a_Z, a_ChunkX, a_ChunkZ);
+
+ a_X = a_X - a_ChunkX * Width;
+ a_Z = a_Z - a_ChunkZ * Width;
+ }
+
+
+ /// Converts absolute block coords to chunk coords:
+ inline static void BlockToChunk( int a_X, int a_Y, int a_Z, int & a_ChunkX, int & a_ChunkZ )
+ {
+ (void)a_Y;
+ a_ChunkX = a_X / Width;
+ if ((a_X < 0) && (a_X % Width != 0))
+ {
+ a_ChunkX--;
+ }
+ a_ChunkZ = a_Z / cChunkDef::Width;
+ if ((a_Z < 0) && (a_Z % Width != 0))
+ {
+ a_ChunkZ--;
+ }
+ }
+
+
+ inline static unsigned int MakeIndex(int x, int y, int z )
+ {
+ if( x < cChunkDef::Width && x > -1 && y < cChunkDef::Height && y > -1 && z < cChunkDef::Width && z > -1 )
+ {
+ return MakeIndexNoCheck(x, y, z);
+ }
+ return INDEX_OUT_OF_RANGE;
+ }
+
+
+ inline static unsigned int MakeIndexNoCheck(int x, int y, int z)
+ {
+ #if AXIS_ORDER == AXIS_ORDER_XZY
+ // For some reason, NOT using the Horner schema is faster. Weird.
+ return x + (z * cChunkDef::Width) + (y * cChunkDef::Width * cChunkDef::Width); // 1.2 is XZY
+ #elif AXIS_ORDER == AXIS_ORDER_YZX
+ return y + (z * cChunkDef::Width) + (x * cChunkDef::Height * cChunkDef::Width); // 1.1 is YZX
+ #endif
+ }
+
+
+ inline static Vector3i IndexToCoordinate( unsigned int index )
+ {
+ #if AXIS_ORDER == AXIS_ORDER_XZY
+ return Vector3i( // 1.2
+ index % cChunkDef::Width, // X
+ index / (cChunkDef::Width * cChunkDef::Width), // Y
+ (index / cChunkDef::Width) % cChunkDef::Width // Z
+ );
+ #elif AXIS_ORDER == AXIS_ORDER_YZX
+ return Vector3i( // 1.1
+ index / (cChunkDef::Height * cChunkDef::Width), // X
+ index % cChunkDef::Height, // Y
+ (index / cChunkDef::Height) % cChunkDef::Width // Z
+ );
+ #endif
+ }
+
+
+ static BLOCKTYPE GetNibble(BLOCKTYPE * a_Buffer, int a_BlockIdx)
+ {
+ if ((a_BlockIdx > -1) && (a_BlockIdx < cChunkDef::NumBlocks))
+ {
+ return (a_Buffer[a_BlockIdx / 2] >> ((a_BlockIdx & 1) * 4)) & 0x0f;
+ }
+ return 0;
+ }
+
+
+ static BLOCKTYPE GetNibble(BLOCKTYPE * a_Buffer, int x, int y, int z)
+ {
+ if ((x < Width) && (x > -1) && (y < Height) && (y > -1) && (z < Width) && (z > -1))
+ {
+ int Index = MakeIndexNoCheck(x, y, z);
+ return (a_Buffer[Index / 2] >> ((Index & 1) * 4)) & 0x0f;
+ }
+ return 0;
+ }
+
+
+ static void SetNibble(BLOCKTYPE * a_Buffer, int a_BlockIdx, BLOCKTYPE a_Nibble)
+ {
+ if ((a_BlockIdx > -1) && (a_BlockIdx < cChunkDef::NumBlocks))
+ {
+ a_Buffer[a_BlockIdx / 2] = (
+ (a_Buffer[a_BlockIdx / 2] & (0xf0 >> ((a_BlockIdx & 1) * 4))) | // The untouched nibble
+ ((a_Nibble & 0x0f) << ((a_BlockIdx & 1) * 4)) // The nibble being set
+ );
+ }
+ }
+
+
+ static void SetNibble(BLOCKTYPE * a_Buffer, int x, int y, int z, BLOCKTYPE a_Nibble)
+ {
+ if ((x < cChunkDef::Width) && (x > -1) && (y < cChunkDef::Height) && (y > -1) && (z < cChunkDef::Width) && (z > -1))
+ {
+ int Index = MakeIndexNoCheck(x, y, z);
+ a_Buffer[Index / 2] = (
+ (a_Buffer[Index / 2] & (0xf0 >> ((Index & 1) * 4))) | // The untouched nibble
+ ((a_Nibble & 0x0f) << ((Index & 1) * 4)) // The nibble being set
+ );
+ }
+ }
+
+
+ inline static BLOCKTYPE GetNibble(BLOCKTYPE * a_Buffer, const Vector3i & a_BlockPos )
+ {
+ return GetNibble( a_Buffer, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z );
+ }
+
+
+ inline static void SetNibble(BLOCKTYPE * a_Buffer, const Vector3i & a_BlockPos, char a_Value )
+ {
+ SetNibble( a_Buffer, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, a_Value );
+ }
+
+} ;
+
+
+
+
+
+/** Interface class used for getting data out of a chunk using the GetAllData() function.
+Implementation must use the pointers immediately and NOT store any of them for later use
+The virtual methods are called in the same order as they're declared here.
+*/
+class cChunkDataCallback abstract
+{
+public:
+ /// Called once to provide heightmap data
+ virtual void HeightMap(const cChunkDef::HeightMap * a_HeightMap) {};
+
+ /// Called once to export block types
+ virtual void BlockTypes (const BLOCKTYPE * a_Type) {};
+
+ /// Called once to export block meta
+ virtual void BlockMeta (const BLOCKTYPE * a_Meta) {};
+
+ /// Called once to export block light
+ virtual void BlockLight (const BLOCKTYPE * a_Meta) {};
+
+ /// Called once to export sky light
+ virtual void BlockSkyLight(const BLOCKTYPE * a_Meta) {};
+
+ /// Called for each entity in the chunk
+ virtual void Entity(cEntity * a_Entity) {};
+
+ /// Called for each blockentity in the chunk
+ virtual void BlockEntity(cBlockEntity * a_Entity) {};
+} ;
+
+
+
+
+
+/** A simple implementation of the cChunkDataCallback interface that collects all block data into a single buffer
+*/
+class cChunkDataCollector :
+ public cChunkDataCallback
+{
+protected:
+ BLOCKTYPE m_BlockData[cChunkDef::BlockDataSize];
+
+ virtual void BlockTypes(const BLOCKTYPE * a_BlockTypes) override
+ {
+ memcpy(m_BlockData, a_BlockTypes, cChunkDef::NumBlocks);
+ }
+
+
+ virtual void BlockMeta(const BLOCKTYPE * a_BlockMeta) override
+ {
+ memcpy(m_BlockData + cChunkDef::NumBlocks, a_BlockMeta, cChunkDef::NumBlocks / 2);
+ }
+
+
+ virtual void BlockLight(const BLOCKTYPE * a_BlockLight) override
+ {
+ memcpy(m_BlockData + 3 * cChunkDef::NumBlocks / 2, a_BlockLight, cChunkDef::NumBlocks / 2);
+ }
+
+
+ virtual void BlockSkyLight(const BLOCKTYPE * a_BlockSkyLight) override
+ {
+ memcpy(m_BlockData + 2 * cChunkDef::NumBlocks, a_BlockSkyLight, cChunkDef::NumBlocks / 2);
+ }
+} ;
+
+
+
+
+
+/** Interface class used for comparing clients of two chunks.
+Used primarily for entity moving while both chunks are locked.
+*/
+class cClientDiffCallback
+{
+public:
+ /// Called for clients that are in Chunk1 and not in Chunk2,
+ virtual void Removed(cClientHandle * a_Client) = 0;
+
+ /// Called for clients that are in Chunk2 and not in Chunk1.
+ virtual void Added(cClientHandle * a_Client) = 0;
+} ;
+
+
+
+
+
+struct sSetBlock
+{
+ int x, y, z;
+ int ChunkX, ChunkZ;
+ char BlockType, BlockMeta;
+
+ sSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta ); // absolute block position
+};
+
+typedef std::list< sSetBlock > sSetBlockList;
+
+
+
+
+
+class cChunkCoords
+{
+public:
+ int m_ChunkX;
+ int m_ChunkY;
+ int m_ChunkZ;
+
+ cChunkCoords(int a_ChunkX, int a_ChunkY, int a_ChunkZ) : m_ChunkX(a_ChunkX), m_ChunkY(a_ChunkY), m_ChunkZ(a_ChunkZ) {}
+
+ bool operator == (const cChunkCoords & a_Other) const
+ {
+ return ((m_ChunkX == a_Other.m_ChunkX) && (m_ChunkY == a_Other.m_ChunkY) && (m_ChunkZ == a_Other.m_ChunkZ));
+ }
+} ;
+
+typedef std::list<cChunkCoords> cChunkCoordsList;
+
+
+
+
+
diff --git a/source/ChunkSender.cpp b/source/ChunkSender.cpp
index 3374a0bff..da134eb8f 100644
--- a/source/ChunkSender.cpp
+++ b/source/ChunkSender.cpp
@@ -209,15 +209,6 @@ void cChunkSender::SendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHa
-void cChunkSender::BlockData(const char * a_Data)
-{
- memcpy(m_BlockData, a_Data, cChunk::c_BlockDataSize);
-}
-
-
-
-
-
void cChunkSender::BlockEntity(cBlockEntity * a_Entity)
{
cPacket * Packet = a_Entity->GetPacket();
diff --git a/source/ChunkSender.h b/source/ChunkSender.h
index 3c77c4210..b5b58b854 100644
--- a/source/ChunkSender.h
+++ b/source/ChunkSender.h
@@ -26,7 +26,7 @@ Note that it may be called by world's BroadcastToChunk() if the client is still
#pragma once
#include "cIsThread.h"
-#include "cChunk.h"
+#include "ChunkDef.h"
#include "packets/cPacket.h"
@@ -42,7 +42,7 @@ class cClientHandle;
class cChunkSender:
public cIsThread,
- public cChunkDataCallback
+ public cChunkDataCollector
{
typedef cIsThread super;
public:
@@ -101,18 +101,17 @@ protected:
cEvent m_evtRemoved; // Set when removed clients are safe to be deleted
// Data about the chunk that is being sent:
- char m_BlockData[cChunk::c_BlockDataSize];
- char m_BiomeData[cChunk::c_ChunkWidth * cChunk::c_ChunkWidth];
+ // NOTE that m_BlockData[] is inherited from the cChunkDataCollector
+ BLOCKTYPE m_BiomeData[cChunkDef::Width * cChunkDef::Width];
PacketList m_Packets; // Accumulator for the entity-packets to send
// cIsThread override:
virtual void Execute(void) override;
- // cChunkDataCallback overrides:
+ // cChunkDataCollector overrides:
// (Note that they are called while the ChunkMap's CS is locked - don't do heavy calculations here!)
- virtual void BlockData(const char * a_Data) override;
- virtual void Entity(cEntity * a_Entity) override;
- virtual void BlockEntity(cBlockEntity * a_Entity) override;
+ virtual void Entity (cEntity * a_Entity) override;
+ virtual void BlockEntity (cBlockEntity * a_Entity) override;
/// Sends the specified chunk to a_Client, or to all chunk clients if a_Client == NULL
void SendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client);
diff --git a/source/WGFlat.cpp b/source/WGFlat.cpp
index 725572334..5c901c916 100644
--- a/source/WGFlat.cpp
+++ b/source/WGFlat.cpp
@@ -35,7 +35,7 @@ cWGFlat::cWGFlat(cWorld * a_World) :
void cWGFlat::GenerateChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities)
{
- int SliceSize = cChunk::c_ChunkWidth * cChunk::c_ChunkWidth;
+ int SliceSize = cChunkDef::Width * cChunkDef::Width;
memset(a_BlockData, E_BLOCK_BEDROCK, SliceSize);
switch (m_Height)
{
@@ -73,18 +73,18 @@ void cWGFlat::GenerateChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, char * a_B
break;
}
}
- memset(a_BlockData + SliceSize * m_Height, E_BLOCK_AIR, cChunk::c_NumBlocks - SliceSize * m_Height);
+ memset(a_BlockData + SliceSize * m_Height, E_BLOCK_AIR, cChunkDef::NumBlocks - SliceSize * m_Height);
SliceSize /= 2; // Nibbles from now on
- char * Meta = a_BlockData + cChunk::c_NumBlocks;
- memset(Meta, 0, cChunk::c_NumBlocks / 2);
+ char * Meta = a_BlockData + cChunkDef::NumBlocks;
+ memset(Meta, 0, cChunkDef::NumBlocks / 2);
- char * SkyLight = Meta + cChunk::c_NumBlocks / 2;
+ char * SkyLight = Meta + cChunkDef::NumBlocks / 2;
memset(SkyLight, 0, m_Height * SliceSize);
- memset(SkyLight + m_Height * SliceSize, 0xff, cChunk::c_NumBlocks / 2 - m_Height * SliceSize);
+ memset(SkyLight + m_Height * SliceSize, 0xff, cChunkDef::NumBlocks / 2 - m_Height * SliceSize);
- char * BlockLight = SkyLight + cChunk::c_NumBlocks / 2;
- memset(BlockLight, 0, cChunk::c_NumBlocks / 2);
+ char * BlockLight = SkyLight + cChunkDef::NumBlocks / 2;
+ memset(BlockLight, 0, cChunkDef::NumBlocks / 2);
}
diff --git a/source/WSSAnvil.cpp b/source/WSSAnvil.cpp
index 73449e5bc..ddb9a6be6 100644
--- a/source/WSSAnvil.cpp
+++ b/source/WSSAnvil.cpp
@@ -170,13 +170,13 @@ bool cWSSAnvil::LoadChunkFromData(const cChunkCoords & a_Chunk, const AString &
bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, cNBTTag & a_NBT)
{
// The data arrays, in MCA-native y/z/x ordering (will be reordered for the final chunk data)
- char BlockData[cChunk::c_BlockDataSize];
- char * MetaData = BlockData + cChunk::c_NumBlocks;
- char * BlockLight = MetaData + cChunk::c_NumBlocks / 2;
- char * SkyLight = BlockLight + cChunk::c_NumBlocks / 2;
+ BLOCKTYPE BlockData[cChunkDef::BlockDataSize];
+ BLOCKTYPE * MetaData = BlockData + cChunkDef::MetaOffset;
+ BLOCKTYPE * BlockLight = BlockData + cChunkDef::LightOffset;
+ BLOCKTYPE * SkyLight = BlockData + cChunkDef::SkyLightOffset;
- memset(BlockData, E_BLOCK_AIR, sizeof(BlockData) - cChunk::c_NumBlocks / 2);
- memset(SkyLight, 0xff, cChunk::c_NumBlocks / 2); // By default, data not present in the NBT means air, which means full skylight
+ memset(BlockData, E_BLOCK_AIR, sizeof(BlockData) - cChunkDef::NumBlocks / 2);
+ memset(SkyLight, 0xff, cChunkDef::NumBlocks / 2); // By default, data not present in the NBT means air, which means full skylight
// Load the blockdata, blocklight and skylight:
cNBTList * Sections = (cNBTList *)a_NBT.FindChildByPath("Level\\Sections");
@@ -225,40 +225,49 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, cNBTTag & a_NBT)
#if (AXIS_ORDER == AXIS_ORDER_YZX)
// Reorder the chunk data - walk the MCA-formatted data sequentially and copy it into the right place in the ChunkData:
- char ChunkData[cChunk::c_BlockDataSize];
+ BLOCKTYPE ChunkData[cChunkDef::BlockDataSize];
memset(ChunkData, 0, sizeof(ChunkData));
int Index = 0; // Index into the MCA-formatted data, incremented sequentially
- for (int y = 0; y < cChunk::c_ChunkHeight; y++) for (int z = 0; z < cChunk::c_ChunkWidth; z++) for (int x = 0; x < cChunk::c_ChunkWidth; x++)
+ for (int y = 0; y < cChunkDef::Height; y++) for (int z = 0; z < cChunkDef::Width; z++) for (int x = 0; x < cChunkDef::Width; x++)
{
ChunkData[cChunk::MakeIndex(x, y, z)] = BlockData[Index];
Index++;
} // for y/z/x
- char * ChunkMeta = ChunkData + cChunk::c_NumBlocks;
+ BLOCKTYPE * ChunkMeta = ChunkData + cChunkDef::NumBlocks;
Index = 0;
- for (int y = 0; y < cChunk::c_ChunkHeight; y++) for (int z = 0; z < cChunk::c_ChunkWidth; z++) for (int x = 0; x < cChunk::c_ChunkWidth; x++)
+ for (int y = 0; y < cChunkDef::Height; y++) for (int z = 0; z < cChunkDef::Width; z++) for (int x = 0; x < cChunkDef::Width; x++)
{
cChunk::SetNibble(ChunkMeta, x, y, z, MetaData[Index / 2] >> ((Index % 2) * 4));
Index++;
} // for y/z/x
- char * ChunkBlockLight = ChunkMeta + cChunk::c_NumBlocks / 2;
+ BLOCKTYPE * ChunkBlockLight = ChunkMeta + cChunkDef::NumBlocks / 2;
Index = 0;
- for (int y = 0; y < cChunk::c_ChunkHeight; y++) for (int z = 0; z < cChunk::c_ChunkWidth; z++) for (int x = 0; x < cChunk::c_ChunkWidth; x++)
+ for (int y = 0; y < cChunkDef::Height; y++) for (int z = 0; z < cChunkDef::Width; z++) for (int x = 0; x < cChunkDef::Width; x++)
{
cChunk::SetNibble(ChunkBlockLight, x, y, z, BlockLight[Index / 2] >> ((Index % 2) * 4));
Index++;
} // for y/z/x
- char * ChunkSkyLight = ChunkBlockLight + cChunk::c_NumBlocks / 2;
+ BLOCKTYPE * ChunkSkyLight = ChunkBlockLight + cChunkDef::NumBlocks / 2;
Index = 0;
- for (int y = 0; y < cChunk::c_ChunkHeight; y++) for (int z = 0; z < cChunk::c_ChunkWidth; z++) for (int x = 0; x < cChunk::c_ChunkWidth; x++)
+ for (int y = 0; y < cChunkDef::Height; y++) for (int z = 0; z < cChunkDef::Width; z++) for (int x = 0; x < cChunkDef::Width; x++)
{
cChunk::SetNibble(ChunkSkyLight, x, y, z, SkyLight[Index / 2] >> ((Index % 2) * 4));
Index++;
} // for y/z/x
#else // AXIS_ORDER_YZX
- char * ChunkData = BlockData;
+ BLOCKTYPE * ChunkData = BlockData;
#endif // else AXIS_ORDER_YZX
- m_World->ChunkDataLoaded(a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ, ChunkData, Entities, BlockEntities);
+ m_World->ChunkDataLoaded(
+ a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ,
+ ChunkData,
+ ChunkData + cChunkDef::MetaOffset,
+ ChunkData + cChunkDef::LightOffset,
+ ChunkData + cChunkDef::SkyLightOffset,
+ NULL,
+ Entities,
+ BlockEntities
+ );
return true;
}
diff --git a/source/WSSCompact.cpp b/source/WSSCompact.cpp
index bafa3ced1..ae920e55f 100644
--- a/source/WSSCompact.cpp
+++ b/source/WSSCompact.cpp
@@ -458,7 +458,7 @@ void cWSSCompact::cPAKFile::UpdateChunk1To2()
// Old version is 128 blocks high with YZX axis order
- char ConvertedData[cChunk::c_BlockDataSize];
+ char ConvertedData[cChunkDef::BlockDataSize];
int Index = 0;
unsigned int InChunkOffset = 0;
for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z )
@@ -684,11 +684,11 @@ void cWSSCompact::cPAKFile::UpdateChunk2To3()
bool cWSSCompact::LoadChunkFromData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, const AString & a_Data, cWorld * a_World)
{
// Crude data integrity check:
- if (a_UncompressedSize < cChunk::c_BlockDataSize)
+ if (a_UncompressedSize < cChunkDef::BlockDataSize)
{
LOGWARNING("Chunk [%d, %d] has too short decompressed data (%d bytes out of %d needed), erasing",
a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ,
- a_UncompressedSize, cChunk::c_BlockDataSize
+ a_UncompressedSize, cChunkDef::BlockDataSize
);
EraseChunkData(a_Chunk);
return false;
@@ -718,11 +718,11 @@ bool cWSSCompact::LoadChunkFromData(const cChunkCoords & a_Chunk, int & a_Uncomp
cEntityList Entities;
cBlockEntityList BlockEntities;
- if (a_UncompressedSize > cChunk::c_BlockDataSize)
+ if (a_UncompressedSize > cChunkDef::BlockDataSize)
{
Json::Value root; // will contain the root value after parsing.
Json::Reader reader;
- if ( !reader.parse( UncompressedData.data() + cChunk::c_BlockDataSize, root, false ) )
+ if ( !reader.parse( UncompressedData.data() + cChunkDef::BlockDataSize, root, false ) )
{
LOGERROR("Failed to parse trailing JSON in chunk [%d, %d]!",
a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ
@@ -734,7 +734,16 @@ bool cWSSCompact::LoadChunkFromData(const cChunkCoords & a_Chunk, int & a_Uncomp
}
}
- a_World->ChunkDataLoaded(a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ, UncompressedData.data(), Entities, BlockEntities);
+ a_World->ChunkDataLoaded(
+ a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ,
+ UncompressedData.data(),
+ UncompressedData.data() + cChunkDef::MetaOffset,
+ UncompressedData.data() + cChunkDef::LightOffset,
+ UncompressedData.data() + cChunkDef::SkyLightOffset,
+ NULL,
+ Entities,
+ BlockEntities
+ );
return true;
}
@@ -771,8 +780,7 @@ bool cWSSCompact::cPAKFile::SaveChunkToData(const cChunkCoords & a_Chunk, cWorld
{
// Serialize the chunk:
cJsonChunkSerializer Serializer;
- a_World->GetChunkData(a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ, Serializer);
- if (Serializer.GetBlockData().empty())
+ if (!a_World->GetChunkData(a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ, Serializer))
{
// Chunk not valid
LOG("cWSSCompact: Trying to save chunk [%d, %d, %d] that has no data, ignoring request.", a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ);
@@ -780,7 +788,7 @@ bool cWSSCompact::cPAKFile::SaveChunkToData(const cChunkCoords & a_Chunk, cWorld
}
AString Data;
- std::swap(Serializer.GetBlockData(), Data);
+ Data.assign(Serializer.GetBlockData(), cChunkDef::BlockDataSize);
if (Serializer.HasJsonData())
{
AString JsonData;
diff --git a/source/WorldStorage.cpp b/source/WorldStorage.cpp
index 4a4b68134..e0e9e7c7b 100644
--- a/source/WorldStorage.cpp
+++ b/source/WorldStorage.cpp
@@ -52,15 +52,6 @@ cJsonChunkSerializer::cJsonChunkSerializer(void) :
-void cJsonChunkSerializer::BlockData(const char * a_Data)
-{
- m_BlockData.assign(a_Data, cChunk::c_BlockDataSize);
-}
-
-
-
-
-
void cJsonChunkSerializer::Entity(cEntity * a_Entity)
{
// TODO: a_Entity->SaveToJson(m_Root);
diff --git a/source/WorldStorage.h b/source/WorldStorage.h
index 0845a7ce7..da78b69f2 100644
--- a/source/WorldStorage.h
+++ b/source/WorldStorage.h
@@ -14,7 +14,7 @@
#ifndef WORLDSTORAGE_H_INCLUDED
#define WORLDSTORAGE_H_INCLUDED
-#include "cChunk.h"
+#include "ChunkDef.h"
#include "cIsThread.h"
#include <json/json.h>
@@ -23,8 +23,7 @@
// fwd:
-class cEntity;
-class cBlockEntity;
+class cWorld;
@@ -54,20 +53,19 @@ typedef std::list<cWSSchema *> cWSSchemaList;
/// Helper class for serializing a chunk into Json
class cJsonChunkSerializer :
- public cChunkDataCallback
+ public cChunkDataCollector
{
public:
cJsonChunkSerializer(void);
Json::Value & GetRoot (void) {return m_Root; }
- AString & GetBlockData(void) {return m_BlockData; }
+ BLOCKTYPE * GetBlockData(void) {return m_BlockData; }
bool HasJsonData (void) const {return m_HasJsonData; }
protected:
-
- // BlockData is serialized into string
- AString m_BlockData;
+
+ // NOTE: block data is serialized into inherited cChunkDataCollector's m_BlockData[] array
// Entities and BlockEntities are serialized to Json
Json::Value m_Root;
@@ -76,10 +74,9 @@ protected:
Json::Value m_AllSigns;
bool m_HasJsonData;
- // cChunkDataCallback overrides:
- virtual void BlockData (const char * a_Data) override;
- virtual void Entity (cEntity * a_Entity) override;
- virtual void BlockEntity(cBlockEntity * a_Entity) override;
+ // cChunkDataCollector overrides:
+ virtual void Entity (cEntity * a_Entity) override;
+ virtual void BlockEntity (cBlockEntity * a_Entity) override;
} ;
diff --git a/source/cChestEntity.cpp b/source/cChestEntity.cpp
index 47b5a9476..f1a99b8c3 100644
--- a/source/cChestEntity.cpp
+++ b/source/cChestEntity.cpp
@@ -9,7 +9,6 @@
#include "cWorld.h"
#include "cRoot.h"
#include "cPickup.h"
-#include "cChunk.h"
#include <json/json.h>
diff --git a/source/cChunk.cpp b/source/cChunk.cpp
index 1b181f575..dad101204 100644
--- a/source/cChunk.cpp
+++ b/source/cChunk.cpp
@@ -57,7 +57,7 @@ sSetBlock::sSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockM
, BlockType( a_BlockType )
, BlockMeta( a_BlockMeta )
{
- cChunkMap::AbsoluteToRelative(x, y, z, ChunkX, ChunkZ);
+ cChunkDef::AbsoluteToRelative(x, y, z, ChunkX, ChunkZ);
}
@@ -72,10 +72,6 @@ cChunk::cChunk(int a_X, int a_Y, int a_Z, cChunkMap * a_ChunkMap, cWorld * a_Wor
, m_PosX( a_X )
, m_PosY( a_Y )
, m_PosZ( a_Z )
- , m_BlockType( m_BlockData ) // Offset the pointers
- , m_BlockMeta( m_BlockType + c_NumBlocks )
- , m_BlockLight( m_BlockMeta + c_NumBlocks / 2 )
- , m_BlockSkyLight( m_BlockLight + c_NumBlocks / 2 )
, m_BlockTickNum( 0 )
, m_BlockTickX( 0 )
, m_BlockTickY( 0 )
@@ -220,7 +216,11 @@ void cChunk::MarkLoadFailed(void)
void cChunk::GetAllData(cChunkDataCallback & a_Callback)
{
- a_Callback.BlockData(m_BlockData);
+ a_Callback.HeightMap (&m_HeightMap);
+ a_Callback.BlockTypes (m_BlockTypes);
+ a_Callback.BlockMeta (m_BlockMeta);
+ a_Callback.BlockLight (m_BlockLight);
+ a_Callback.BlockSkyLight(m_BlockSkyLight);
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr)
{
@@ -237,9 +237,30 @@ void cChunk::GetAllData(cChunkDataCallback & a_Callback)
-void cChunk::SetAllData(const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities)
+void cChunk::SetAllData(
+ const BLOCKTYPE * a_BlockTypes,
+ const BLOCKTYPE * a_BlockMeta,
+ const BLOCKTYPE * a_BlockLight,
+ const BLOCKTYPE * a_BlockSkyLight,
+ const HeightMap * a_HeightMap,
+ cEntityList & a_Entities,
+ cBlockEntityList & a_BlockEntities
+)
{
- memcpy(m_BlockData, a_BlockData, sizeof(m_BlockData));
+ if (a_HeightMap != NULL)
+ {
+ memcpy(m_HeightMap, a_HeightMap, sizeof(m_HeightMap));
+ }
+
+ memcpy(m_BlockTypes, a_BlockTypes, sizeof(m_BlockTypes));
+ memcpy(m_BlockMeta, a_BlockMeta, sizeof(m_BlockMeta));
+ memcpy(m_BlockLight, a_BlockLight, sizeof(m_BlockLight));
+ memcpy(m_BlockSkyLight, a_BlockSkyLight, sizeof(m_BlockSkyLight));
+
+ if (a_HeightMap == NULL)
+ {
+ CalculateHeightmap();
+ }
// Clear the internal entities:
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr)
@@ -276,8 +297,6 @@ void cChunk::SetAllData(const char * a_BlockData, cEntityList & a_Entities, cBlo
// Create block entities that the loader didn't load; fill them with defaults
CreateBlockEntities();
- CalculateHeightmap();
-
m_HasLoadFailed = false;
}
@@ -285,20 +304,21 @@ void cChunk::SetAllData(const char * a_BlockData, cEntityList & a_Entities, cBlo
-/// Copies m_BlockData into a_Blocks, only the block types
-void cChunk::GetBlocks(char * a_Blocks)
+void cChunk::GetBlockTypes(BLOCKTYPE * a_BlockTypes)
{
- memcpy(a_Blocks, m_BlockData, cChunk::c_NumBlocks);
+ memcpy(a_BlockTypes, m_BlockTypes, NumBlocks);
}
-/// Copies m_BlockData into a_Blocks, only the block types
-void cChunk::GetBlockData(char * a_BlockData)
+void cChunk::GetBlockData(BLOCKTYPE * a_BlockData)
{
- memcpy(a_BlockData, m_BlockData, cChunk::c_BlockDataSize);
+ memcpy(a_BlockData, m_BlockTypes, NumBlocks);
+ memcpy(a_BlockData + MetaOffset, m_BlockMeta, NumBlocks / 2);
+ memcpy(a_BlockData + LightOffset, m_BlockLight, NumBlocks / 2);
+ memcpy(a_BlockData + SkyLightOffset, m_BlockSkyLight, NumBlocks / 2);
}
@@ -367,13 +387,13 @@ void cChunk::Tick(float a_Dt, MTRand & a_TickRandom)
Vector3i BlockPos = IndexToCoordinate( index );
#if (MINECRAFT_1_2_2 == 1)
- unsigned int Coords = BlockPos.y | BlockPos.z << 8 | BlockPos.x << 12;
- unsigned int Blocks = GetNibble( m_BlockMeta, index ) | (m_BlockType[index]<<4);
+ unsigned int Coords = BlockPos.y | (BlockPos.z << 8) | (BlockPos.x << 12);
+ unsigned int Blocks = GetNibble( m_BlockMeta, index ) | (m_BlockTypes[index] << 4);
MultiBlock.m_Data[i].Data = Coords << 16 | Blocks;
#else
MultiBlock.m_BlockCoordinates[i] = (BlockPos.z&0xf) | (BlockPos.x&0xf)<<4 | (BlockPos.y&0xff)<<8;
//LOG("X: %i Y: %i Z: %i Combo: 0x%04x", X, Y, Z, MultiBlock.m_BlockCoordinates[i] );
- MultiBlock.m_BlockTypes[i] = m_BlockType[index];
+ MultiBlock.m_BlockTypes[i] = m_BlockTypes[index];
MultiBlock.m_BlockMetas[i] = GetNibble( m_BlockMeta, index );
#endif
}
@@ -392,7 +412,7 @@ void cChunk::Tick(float a_Dt, MTRand & a_TickRandom)
BlockChange.m_PosX = WorldPos.x;
BlockChange.m_PosY = (unsigned char)WorldPos.y;
BlockChange.m_PosZ = WorldPos.z;
- BlockChange.m_BlockType = m_BlockType[index];
+ BlockChange.m_BlockType = m_BlockTypes[index];
BlockChange.m_BlockMeta = GetNibble( m_BlockMeta, index );
Broadcast( BlockChange );
}
@@ -510,14 +530,14 @@ void cChunk::Tick(float a_Dt, MTRand & a_TickRandom)
for(int i = 0; i < 50; i++)
{
- m_BlockTickX = (m_BlockTickX + RandomX) % c_ChunkWidth;
- m_BlockTickY = (m_BlockTickY + RandomY) % c_ChunkHeight;
- m_BlockTickZ = (m_BlockTickZ + RandomZ) % c_ChunkWidth;
+ m_BlockTickX = (m_BlockTickX + RandomX) % Width;
+ m_BlockTickY = (m_BlockTickY + RandomY) % Height;
+ m_BlockTickZ = (m_BlockTickZ + RandomZ) % Width;
- if( m_BlockTickY > m_HeightMap[ m_BlockTickX + m_BlockTickZ*c_ChunkWidth ] ) continue; // It's all air up here
+ if( m_BlockTickY > m_HeightMap[ m_BlockTickX + m_BlockTickZ * Width ] ) continue; // It's all air up here
unsigned int Index = MakeIndexNoCheck( m_BlockTickX, m_BlockTickY, m_BlockTickZ );
- char ID = m_BlockType[Index];
+ char ID = m_BlockTypes[Index];
switch( ID )
{
/*
@@ -543,7 +563,7 @@ void cChunk::Tick(float a_Dt, MTRand & a_TickRandom)
#if AXIS_ORDER == AXIS_ORDER_YZX
char AboveBlock = GetBlock( Index+1 );
#elif AXIS_ORDER == AXIS_ORDER_XZY
- char AboveBlock = GetBlock( Index + (c_ChunkWidth*c_ChunkWidth) );
+ char AboveBlock = GetBlock( Index + (Width*Width) );
#endif
if (!( (AboveBlock == 0) || (g_BlockOneHitDig[AboveBlock]) || (g_BlockTransparent[AboveBlock]) ) ) //changed to not allow grass if any one hit object is on top
{
@@ -554,7 +574,7 @@ void cChunk::Tick(float a_Dt, MTRand & a_TickRandom)
case E_BLOCK_SAPLING: //todo: check meta of sapling. change m_World->GrowTree to look change trunk and leaves based on meta of sapling
{
FastSetBlock( m_BlockTickX, m_BlockTickY, m_BlockTickZ, E_BLOCK_AIR, GetNibble( m_BlockMeta, Index ) );
- m_World->GrowTree( m_BlockTickX + m_PosX*c_ChunkWidth, m_BlockTickY, m_BlockTickZ + m_PosZ*c_ChunkWidth );
+ m_World->GrowTree( m_BlockTickX + m_PosX*Width, m_BlockTickY, m_BlockTickZ + m_PosZ*Width );
}
break;
case E_BLOCK_LEAVES: //todo, http://www.minecraftwiki.net/wiki/Data_values#Leaves
@@ -582,11 +602,11 @@ void cChunk::Tick(float a_Dt, MTRand & a_TickRandom)
int cChunk::GetHeight( int a_X, int a_Z )
{
- ASSERT((a_X >= 0) && (a_X < c_ChunkWidth) && (a_Z >= 0) && (a_Z < c_ChunkWidth));
+ ASSERT((a_X >= 0) && (a_X < Width) && (a_Z >= 0) && (a_Z < Width));
- if ((a_X >= 0) && (a_X < c_ChunkWidth) && (a_Z >= 0) && (a_Z < c_ChunkWidth))
+ if ((a_X >= 0) && (a_X < Width) && (a_Z >= 0) && (a_Z < Width))
{
- return m_HeightMap[a_X + a_Z * c_ChunkWidth];
+ return m_HeightMap[a_X + a_Z * Width];
}
return 0;
}
@@ -597,29 +617,29 @@ int cChunk::GetHeight( int a_X, int a_Z )
void cChunk::CreateBlockEntities(void)
{
- for (int x = 0; x < c_ChunkWidth; x++)
+ for (int x = 0; x < Width; x++)
{
- for (int z = 0; z < c_ChunkWidth; z++)
+ for (int z = 0; z < Width; z++)
{
- for (int y = 0; y < c_ChunkHeight; y++)
+ for (int y = 0; y < Height; y++)
{
- ENUM_BLOCK_ID BlockType = (ENUM_BLOCK_ID)m_BlockData[ MakeIndex( x, y, z ) ];
+ ENUM_BLOCK_ID BlockType = (ENUM_BLOCK_ID)m_BlockTypes[ MakeIndex( x, y, z ) ];
switch ( BlockType )
{
case E_BLOCK_CHEST:
{
- if (!HasBlockEntityAt(x + m_PosX * c_ChunkWidth, y + m_PosY * c_ChunkHeight, z + m_PosZ * c_ChunkWidth))
+ if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width))
{
- m_BlockEntities.push_back( new cChestEntity( x + m_PosX * c_ChunkWidth, y + m_PosY * c_ChunkHeight, z + m_PosZ * c_ChunkWidth, m_World) );
+ m_BlockEntities.push_back( new cChestEntity( x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World) );
}
break;
}
case E_BLOCK_FURNACE:
{
- if (!HasBlockEntityAt(x + m_PosX * c_ChunkWidth, y + m_PosY * c_ChunkHeight, z + m_PosZ * c_ChunkWidth))
+ if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width))
{
- m_BlockEntities.push_back( new cFurnaceEntity( x + m_PosX * c_ChunkWidth, y + m_PosY * c_ChunkHeight, z + m_PosZ * c_ChunkWidth, m_World) );
+ m_BlockEntities.push_back( new cFurnaceEntity( x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World) );
}
break;
}
@@ -627,9 +647,9 @@ void cChunk::CreateBlockEntities(void)
case E_BLOCK_SIGN_POST:
case E_BLOCK_WALLSIGN:
{
- if (!HasBlockEntityAt(x + m_PosX * c_ChunkWidth, y + m_PosY * c_ChunkHeight, z + m_PosZ * c_ChunkWidth))
+ if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width))
{
- m_BlockEntities.push_back( new cSignEntity( BlockType, x + m_PosX * c_ChunkWidth, y + m_PosY * c_ChunkHeight, z + m_PosZ * c_ChunkWidth, m_World) );
+ m_BlockEntities.push_back( new cSignEntity( BlockType, x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World) );
}
break;
}
@@ -645,16 +665,16 @@ void cChunk::CreateBlockEntities(void)
void cChunk::CalculateHeightmap()
{
- for (int x = 0; x < c_ChunkWidth; x++)
+ for (int x = 0; x < Width; x++)
{
- for (int z = 0; z < c_ChunkWidth; z++)
+ for (int z = 0; z < Width; z++)
{
- for (int y = c_ChunkHeight-1; y > -1; y--)
+ for (int y = Height - 1; y > -1; y--)
{
int index = MakeIndex( x, y, z );
- if (m_BlockData[index] != E_BLOCK_AIR)
+ if (m_BlockTypes[index] != E_BLOCK_AIR)
{
- m_HeightMap[x + z * c_ChunkWidth] = (unsigned char)y;
+ m_HeightMap[x + z * Width] = (unsigned char)y;
break;
}
} // for y
@@ -669,17 +689,17 @@ void cChunk::CalculateHeightmap()
void cChunk::CalculateLighting()
{
// Calculate sunlight
- memset(m_BlockSkyLight, 0xff, c_NumBlocks / 2 ); // Set all to fully lit, so everything above HeightMap is lit
- for (int x = 0; x < c_ChunkWidth; x++)
+ memset(m_BlockSkyLight, 0xff, NumBlocks / 2 ); // Set all to fully lit, so everything above HeightMap is lit
+ for (int x = 0; x < Width; x++)
{
- for (int z = 0; z < c_ChunkWidth; z++)
+ for (int z = 0; z < Width; z++)
{
char sunlight = 0xf;
- for (int y = m_HeightMap[x + z*c_ChunkWidth]; y > -1; y--)
+ for (int y = m_HeightMap[x + z*Width]; y > -1; y--)
{
int index = MakeIndexNoCheck(x, y, z);
- if( g_BlockTransparent[ (int)m_BlockData[index] ] == false )
+ if( g_BlockTransparent[ (int)m_BlockTypes[index] ] == false )
{
sunlight = 0x0;
}
@@ -689,11 +709,11 @@ void cChunk::CalculateLighting()
}
// Calculate blocklights
- for (int x = 0; x < c_ChunkWidth; x++)
+ for (int x = 0; x < Width; x++)
{
- for (int z = 0; z < c_ChunkWidth; z++)
+ for (int z = 0; z < Width; z++)
{
- int MaxHeight = m_HeightMap[x + z*c_ChunkWidth];
+ int MaxHeight = m_HeightMap[x + z * Width];
for (int y = 0; y < MaxHeight; y++)
{
char BlockID = GetBlock(x, y, z);
@@ -717,22 +737,22 @@ void cChunk::CalculateLighting()
void cChunk::SpreadLight(char* a_LightBuffer)
{
- // Spread the sunlight
- for(int x = 0; x < c_ChunkWidth; x++) for(int z = 0; z < c_ChunkWidth; z++) for(int y = 0; y < c_ChunkHeight; y++)
+ // Spread the light
+ for(int x = 0; x < Width; x++) for(int z = 0; z < Width; z++) for(int y = 0; y < Height; y++)
{
int index = MakeIndexNoCheck(x, y, z);
- if( g_BlockSpreadLightFalloff[ m_BlockData[index] ] > 0 )
+ if( g_BlockSpreadLightFalloff[ m_BlockTypes[index] ] > 0 )
{
- SpreadLightOfBlock(a_LightBuffer, x, y, z, g_BlockSpreadLightFalloff[ m_BlockData[index] ]);
+ SpreadLightOfBlock(a_LightBuffer, x, y, z, g_BlockSpreadLightFalloff[ m_BlockTypes[index] ]);
}
}
- for(int x = c_ChunkWidth-1; x > -1; x--) for(int z = c_ChunkWidth-1; z > -1; z--) for(int y = c_ChunkHeight-1; y > -1; y--)
+ for(int x = Width-1; x > -1; x--) for(int z = Width-1; z > -1; z--) for(int y = Height-1; y > -1; y--)
{
int index = MakeIndexNoCheck(x, y, z);
- if( g_BlockSpreadLightFalloff[ m_BlockData[index] ] > 0 )
+ if( g_BlockSpreadLightFalloff[ m_BlockTypes[index] ] > 0 )
{
- SpreadLightOfBlock(a_LightBuffer, x, y, z, g_BlockSpreadLightFalloff[ m_BlockData[index] ]);
+ SpreadLightOfBlock(a_LightBuffer, x, y, z, g_BlockSpreadLightFalloff[ m_BlockTypes[index] ]);
}
}
@@ -745,39 +765,39 @@ void cChunk::SpreadLight(char* a_LightBuffer)
char * LeftSky = NULL, *RightSky = NULL;
if (LeftChunk->IsValid())
{
- LeftSky = (a_LightBuffer == m_BlockSkyLight) ? LeftChunk->pGetSkyLight() : LeftChunk->pGetLight();
+ LeftSky = (a_LightBuffer == m_BlockSkyLight) ? LeftChunk->m_BlockSkyLight : LeftChunk->m_BlockLight;
}
if (RightChunk->IsValid())
{
- RightSky = (a_LightBuffer == m_BlockSkyLight) ? RightChunk->pGetSkyLight() : RightChunk->pGetLight();
+ RightSky = (a_LightBuffer == m_BlockSkyLight) ? RightChunk->m_BlockSkyLight : RightChunk->m_BlockLight;
}
- for (int z = 0; z < c_ChunkWidth; z++) for(int y = 0; y < c_ChunkHeight; y++)
+ for (int z = 0; z < Width; z++) for(int y = 0; y < Height; y++)
{
if (LeftSky != NULL)
{
int index = MakeIndexNoCheck( 0, y, z );
- if( g_BlockSpreadLightFalloff[ m_BlockData[index] ] > 0 )
+ if( g_BlockSpreadLightFalloff[ m_BlockTypes[index] ] > 0 )
{
char CurrentLight = GetNibble( a_LightBuffer, 0, y, z );
- char LeftLight = GetNibble( LeftSky, c_ChunkWidth-1, y, z );
- if( LeftLight < CurrentLight-g_BlockSpreadLightFalloff[ m_BlockData[index] ] )
+ char LeftLight = GetNibble( LeftSky, Width-1, y, z );
+ if( LeftLight < CurrentLight-g_BlockSpreadLightFalloff[ m_BlockTypes[index] ] )
{
- SetNibble( LeftSky, c_ChunkWidth - 1, y, z, MAX(0, CurrentLight-g_BlockSpreadLightFalloff[ m_BlockData[index] ]) );
+ SetNibble( LeftSky, Width - 1, y, z, MAX(0, CurrentLight-g_BlockSpreadLightFalloff[ m_BlockTypes[index] ]) );
bCalcLeft = true;
}
}
}
if (RightSky != NULL)
{
- int index = MakeIndexNoCheck( c_ChunkWidth-1, y, z );
- if( g_BlockSpreadLightFalloff[ m_BlockData[index] ] > 0 )
+ int index = MakeIndexNoCheck( Width - 1, y, z );
+ if( g_BlockSpreadLightFalloff[ m_BlockTypes[index] ] > 0 )
{
- char CurrentLight = GetNibble( a_LightBuffer, c_ChunkWidth-1, y, z );
+ char CurrentLight = GetNibble( a_LightBuffer, Width-1, y, z );
char RightLight = GetNibble( RightSky, 0, y, z );
- if( RightLight < CurrentLight-g_BlockSpreadLightFalloff[ m_BlockData[index] ] )
+ if( RightLight < CurrentLight-g_BlockSpreadLightFalloff[ m_BlockTypes[index] ] )
{
- SetNibble( RightSky, 0, y, z, MAX(0, CurrentLight-g_BlockSpreadLightFalloff[ m_BlockData[index] ]) );
+ SetNibble( RightSky, 0, y, z, MAX(0, CurrentLight-g_BlockSpreadLightFalloff[ m_BlockTypes[index] ]) );
bCalcRight = true;
}
}
@@ -790,38 +810,38 @@ void cChunk::SpreadLight(char* a_LightBuffer)
char * FrontSky = NULL, * BackSky = NULL;
if (FrontChunk->IsValid())
{
- FrontSky = (a_LightBuffer == m_BlockSkyLight) ? FrontChunk->pGetSkyLight() : FrontChunk->pGetLight();
+ FrontSky = (a_LightBuffer == m_BlockSkyLight) ? FrontChunk->m_BlockSkyLight : FrontChunk->m_BlockLight;
}
if (BackChunk->IsValid())
{
- BackSky = (a_LightBuffer == m_BlockSkyLight) ? BackChunk->pGetSkyLight() : BackChunk->pGetLight();
+ BackSky = (a_LightBuffer == m_BlockSkyLight) ? BackChunk->m_BlockSkyLight : BackChunk->m_BlockLight;
}
- for(int x = 0; x < c_ChunkWidth; x++) for(int y = 0; y < c_ChunkHeight; y++)
+ for(int x = 0; x < Width; x++) for(int y = 0; y < Height; y++)
{
if (FrontSky != NULL)
{
int index = MakeIndexNoCheck( x, y, 0 );
- if( g_BlockSpreadLightFalloff[ m_BlockData[index] ] > 0 )
+ if( g_BlockSpreadLightFalloff[ m_BlockTypes[index] ] > 0 )
{
- char CurrentLight = GetNibble( a_LightBuffer, x, y, 0 );
- char FrontLight = GetNibble( FrontSky, x, y, c_ChunkWidth-1 );
- if( FrontLight < CurrentLight-g_BlockSpreadLightFalloff[ m_BlockData[index] ] )
+ BLOCKTYPE CurrentLight = GetNibble( a_LightBuffer, x, y, 0 );
+ BLOCKTYPE FrontLight = GetNibble( FrontSky, x, y, Width-1 );
+ if( FrontLight < CurrentLight-g_BlockSpreadLightFalloff[ m_BlockTypes[index] ] )
{
- SetNibble( FrontSky, x, y, c_ChunkWidth-1, MAX(0, CurrentLight-g_BlockSpreadLightFalloff[ m_BlockData[index] ]) );
+ SetNibble( FrontSky, x, y, Width-1, MAX(0, CurrentLight-g_BlockSpreadLightFalloff[ m_BlockTypes[index] ]) );
bCalcFront = true;
}
}
}
if (BackSky != NULL)
{
- int index = MakeIndexNoCheck( x, y, c_ChunkWidth-1 );
- if( g_BlockSpreadLightFalloff[ m_BlockData[index] ] > 0 )
+ int index = MakeIndexNoCheck( x, y, Width-1 );
+ if( g_BlockSpreadLightFalloff[ m_BlockTypes[index] ] > 0 )
{
- char CurrentLight = GetNibble( a_LightBuffer, x, y, c_ChunkWidth-1 );
- char BackLight = GetNibble( BackSky, x, y, 0 );
- if ( BackLight < CurrentLight-g_BlockSpreadLightFalloff[ m_BlockData[index] ] )
+ BLOCKTYPE CurrentLight = GetNibble( a_LightBuffer, x, y, Width-1 );
+ BLOCKTYPE BackLight = GetNibble( BackSky, x, y, 0 );
+ if ( BackLight < CurrentLight-g_BlockSpreadLightFalloff[ m_BlockTypes[index] ] )
{
- SetNibble( BackSky, x, y, 0, MAX(0, CurrentLight-g_BlockSpreadLightFalloff[ m_BlockData[index] ]) );
+ SetNibble( BackSky, x, y, 0, MAX(0, CurrentLight-g_BlockSpreadLightFalloff[ m_BlockTypes[index] ]) );
bCalcBack = true;
}
}
@@ -839,9 +859,9 @@ void cChunk::SpreadLight(char* a_LightBuffer)
-void cChunk::SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta )
+void cChunk::SetBlock( int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta )
{
- if (a_X < 0 || a_X >= c_ChunkWidth || a_Y < 0 || a_Y >= c_ChunkHeight || a_Z < 0 || a_Z >= c_ChunkWidth)
+ if (a_X < 0 || a_X >= Width || a_Y < 0 || a_Y >= Height || a_Z < 0 || a_Z >= Width)
{
return; // Clip
}
@@ -849,9 +869,9 @@ void cChunk::SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_Block
ASSERT(IsValid()); // Is this chunk loaded / generated?
int index = MakeIndexNoCheck( a_X, a_Y, a_Z );
- char OldBlockMeta = GetNibble( m_BlockMeta, index );
- char OldBlockType = m_BlockType[index];
- m_BlockType[index] = a_BlockType;
+ BLOCKTYPE OldBlockMeta = GetNibble( m_BlockMeta, index );
+ BLOCKTYPE OldBlockType = m_BlockTypes[index];
+ m_BlockTypes[index] = a_BlockType;
SetNibble( m_BlockMeta, index, a_BlockMeta );
@@ -878,19 +898,19 @@ void cChunk::SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_Block
}
// Update heightmap, if needed:
- if (a_Y >= m_HeightMap[a_X + a_Z * c_ChunkWidth])
+ if (a_Y >= m_HeightMap[a_X + a_Z * Width])
{
if (a_BlockType != E_BLOCK_AIR)
{
- m_HeightMap[a_X + a_Z * c_ChunkWidth] = (unsigned char)a_Y;
+ m_HeightMap[a_X + a_Z * Width] = (unsigned char)a_Y;
}
else
{
for (int y = a_Y - 1; y > 0; --y)
{
- if (m_BlockData[MakeIndex(a_X, y, a_Z)] != E_BLOCK_AIR)
+ if (m_BlockTypes[MakeIndex(a_X, y, a_Z)] != E_BLOCK_AIR)
{
- m_HeightMap[a_X + a_Z * c_ChunkWidth] = (unsigned char)y;
+ m_HeightMap[a_X + a_Z * Width] = (unsigned char)y;
break;
}
} // for y - column in m_BlockData
@@ -938,23 +958,23 @@ void cChunk::SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_Block
-void cChunk::FastSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta)
+void cChunk::FastSetBlock( int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta)
{
- ASSERT(!((a_X < 0 || a_X >= c_ChunkWidth || a_Y < 0 || a_Y >= c_ChunkHeight || a_Z < 0 || a_Z >= c_ChunkWidth)));
+ ASSERT(!((a_X < 0 || a_X >= Width || a_Y < 0 || a_Y >= Height || a_Z < 0 || a_Z >= Width)));
ASSERT(IsValid());
const int index = MakeIndexNoCheck( a_X, a_Y, a_Z );
- const char OldBlock = m_BlockType[index];
- const char OldBlockMeta = GetNibble( m_BlockMeta, index );
- if (OldBlock == a_BlockType && OldBlockMeta == a_BlockMeta)
+ const BLOCKTYPE OldBlock = m_BlockTypes[index];
+ const BLOCKTYPE OldBlockMeta = GetNibble( m_BlockMeta, index );
+ if ((OldBlock == a_BlockType) && (OldBlockMeta == a_BlockMeta))
{
return;
}
MarkDirty();
- m_BlockType[index] = a_BlockType;
+ m_BlockTypes[index] = a_BlockType;
{
cCSLock Lock(m_CSBlockLists);
@@ -974,19 +994,19 @@ void cChunk::FastSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_B
}
// Update heightmap, if needed:
- if (a_Y >= m_HeightMap[a_X + a_Z * c_ChunkWidth])
+ if (a_Y >= m_HeightMap[a_X + a_Z * Width])
{
if (a_BlockType != E_BLOCK_AIR)
{
- m_HeightMap[a_X + a_Z * c_ChunkWidth] = (unsigned char)a_Y;
+ m_HeightMap[a_X + a_Z * Width] = (unsigned char)a_Y;
}
else
{
for (int y = a_Y - 1; y > 0; --y)
{
- if (m_BlockData[MakeIndexNoCheck(a_X, y, a_Z)] != E_BLOCK_AIR)
+ if (m_BlockTypes[MakeIndexNoCheck(a_X, y, a_Z)] != E_BLOCK_AIR)
{
- m_HeightMap[a_X + a_Z * c_ChunkWidth] = (unsigned char)y;
+ m_HeightMap[a_X + a_Z * Width] = (unsigned char)y;
break;
}
} // for y - column in m_BlockData
@@ -1027,7 +1047,7 @@ void cChunk::SendBlockTo( int a_X, int a_Y, int a_Z, cClientHandle* a_Client )
BlockChange.m_PosZ = WorldPos.z;
if( index != INDEX_OUT_OF_RANGE )
{
- BlockChange.m_BlockType = m_BlockType[ index ];
+ BlockChange.m_BlockType = m_BlockTypes[ index ];
BlockChange.m_BlockMeta = GetNibble( m_BlockMeta, index );
} // else it's both 0
a_Client->Send( BlockChange );
@@ -1251,21 +1271,21 @@ void cChunk::RemoveEntity(cEntity * a_Entity)
-char cChunk::GetBlock( int a_X, int a_Y, int a_Z )
+BLOCKTYPE cChunk::GetBlock( int a_X, int a_Y, int a_Z )
{
- if ((a_X < 0) || (a_X >= c_ChunkWidth) || (a_Y < 0) || (a_Y >= c_ChunkHeight) || (a_Z < 0) || (a_Z >= c_ChunkWidth)) return 0; // Clip
+ if ((a_X < 0) || (a_X >= Width) || (a_Y < 0) || (a_Y >= Height) || (a_Z < 0) || (a_Z >= Width)) return 0; // Clip
- return m_BlockType[ MakeIndexNoCheck( a_X, a_Y, a_Z ) ];
+ return m_BlockTypes[ MakeIndexNoCheck( a_X, a_Y, a_Z ) ];
}
-char cChunk::GetBlock( int a_BlockIdx )
+BLOCKTYPE cChunk::GetBlock( int a_BlockIdx )
{
- if( a_BlockIdx < 0 || a_BlockIdx >= c_NumBlocks ) return 0;
- return m_BlockType[ a_BlockIdx ];
+ if( a_BlockIdx < 0 || a_BlockIdx >= NumBlocks ) return 0;
+ return m_BlockTypes[ a_BlockIdx ];
}
@@ -1381,22 +1401,11 @@ void cChunk::Broadcast( const cPacket * a_Packet, cClientHandle* a_Exclude)
-void cChunk::CopyBlockDataFrom(const char * a_NewBlockData)
-{
- // Copies all blockdata, recalculates heightmap (used by chunk loaders)
- memcpy(m_BlockData, a_NewBlockData, sizeof(m_BlockData));
- CalculateHeightmap();
-}
-
-
-
-
-
void cChunk::PositionToWorldPosition(int a_ChunkX, int a_ChunkY, int a_ChunkZ, int & a_X, int & a_Y, int & a_Z)
{
a_Y = a_ChunkY;
- a_X = m_PosX * c_ChunkWidth + a_ChunkX;
- a_Z = m_PosZ * c_ChunkWidth + a_ChunkZ;
+ a_X = m_PosX * Width + a_ChunkX;
+ a_Z = m_PosZ * Width + a_ChunkZ;
}
@@ -1405,7 +1414,7 @@ void cChunk::PositionToWorldPosition(int a_ChunkX, int a_ChunkY, int a_ChunkZ, i
Vector3i cChunk::PositionToWorldPosition( int a_ChunkX, int a_ChunkY, int a_ChunkZ )
{
- return Vector3i( m_PosX * c_ChunkWidth + a_ChunkX, m_PosY * c_ChunkHeight + a_ChunkY, m_PosZ * c_ChunkWidth + a_ChunkZ );
+ return Vector3i( m_PosX * Width + a_ChunkX, m_PosY * Height + a_ChunkY, m_PosZ * Width + a_ChunkZ );
}
diff --git a/source/cChunk.h b/source/cChunk.h
index 1018936f2..cd43f2fe3 100644
--- a/source/cChunk.h
+++ b/source/cChunk.h
@@ -2,7 +2,7 @@
#pragma once
#include "cEntity.h"
-#include "Vector3i.h"
+#include "ChunkDef.h"
@@ -21,19 +21,6 @@
-/** This is really only a placeholder to be used in places where we need to "make up" a chunk's Y coord.
-It will help us when the new chunk format comes out and we need to patch everything up for compatibility.
-*/
-#define ZERO_CHUNK_Y 0
-
-// Used to smoothly convert to new axis ordering. One will be removed when deemed stable.
-#define AXIS_ORDER_YZX 1 // Original (1.1-)
-#define AXIS_ORDER_XZY 2 // New (1.2+)
-#define AXIS_ORDER AXIS_ORDER_XZY
-
-
-
-
namespace Json
{
class Value;
@@ -46,7 +33,6 @@ namespace Json
class cWorld;
class cFurnaceEntity;
class cPacket;
-class cBlockEntity;
class cClientHandle;
class cServer;
class MTRand;
@@ -54,59 +40,6 @@ class cPlayer;
class cChunkMap;
typedef std::list<cClientHandle *> cClientHandleList;
-typedef std::list<cBlockEntity *> cBlockEntityList;
-
-
-
-
-
-/** Interface class used for getting data out of a chunk using the GetAllData() function.
-Implementation must use the pointers immediately and NOT store any of them for later use
-*/
-class cChunkDataCallback
-{
-public:
- /// Called once to export blockdata
- virtual void BlockData(const char * a_Data) = 0;
-
- /// Called for each entity in the chunk
- virtual void Entity(cEntity * a_Entity) = 0;
-
- /// Called for each blockentity in the chunk
- virtual void BlockEntity(cBlockEntity * a_Entity) = 0;
-} ;
-
-
-
-
-
-/** Interface class used for comparing clients of two chunks.
-Used primarily for entity moving while both chunks are locked.
-*/
-class cClientDiffCallback
-{
-public:
- /// Called for clients that are in Chunk1 and not in Chunk2,
- virtual void Removed(cClientHandle * a_Client) = 0;
-
- /// Called for clients that are in Chunk2 and not in Chunk1.
- virtual void Added(cClientHandle * a_Client) = 0;
-} ;
-
-
-
-
-
-struct sSetBlock
-{
- int x, y, z;
- int ChunkX, ChunkZ;
- char BlockType, BlockMeta;
-
- sSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta ); // absolute block position
-};
-
-typedef std::list< sSetBlock > sSetBlockList;
@@ -114,14 +47,10 @@ typedef std::list< sSetBlock > sSetBlockList;
// This class is not to be used directly
// Instead, call actions on cChunkMap (such as cChunkMap::SetBlock() etc.)
-class cChunk
+class cChunk :
+ public cChunkDef // The inheritance is "misused" here only to inherit the functions and constants defined in cChunkDef
{
public:
- static const int c_ChunkWidth = 16;
- static const int c_ChunkHeight = 256;
- static const int c_NumBlocks = c_ChunkWidth * c_ChunkHeight * c_ChunkWidth;
- static const int c_BlockDataSize = c_NumBlocks * 2 + (c_NumBlocks/2); // 2.5 * numblocks
-
cChunk(int a_X, int a_Y, int a_Z, cChunkMap * a_ChunkMap, cWorld * a_World);
~cChunk();
@@ -147,13 +76,21 @@ public:
void GetAllData(cChunkDataCallback & a_Callback);
/// Sets all chunk data
- void SetAllData(const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities);
-
- /// Copies m_BlockData into a_Blocks, only the block types
- void GetBlocks(char * a_Blocks);
-
- /// Copies m_BlockData into a_Blocks, the entire array
- void GetBlockData(char * a_BlockData);
+ void SetAllData(
+ const BLOCKTYPE * a_BlockTypes,
+ const BLOCKTYPE * a_BlockMeta,
+ const BLOCKTYPE * a_BlockLight,
+ const BLOCKTYPE * a_BlockSkyLight,
+ const cChunkDef::HeightMap * a_HeightMap,
+ cEntityList & a_Entities,
+ cBlockEntityList & a_BlockEntities
+ );
+
+ /// Copies m_BlockData into a_BlockTypes, only the block types
+ void GetBlockTypes(BLOCKTYPE * a_BlockTypes);
+
+ /// Copies entire block data into a_BlockData, the entire 4 arrays (Type, Meta, Light, SkyLight)
+ void GetBlockData(BLOCKTYPE * a_BlockData);
/// Returns true if there is a block entity at the coords specified
bool HasBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ);
@@ -170,11 +107,11 @@ public:
// OBSOLETE void SendTo( cClientHandle * a_Client );
- void SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta );
- void SetBlock( const Vector3i & a_BlockPos, char a_BlockType, char a_BlockMeta ) { SetBlock( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, a_BlockType, a_BlockMeta ); }
- void FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, char a_BlockType, char a_BlockMeta ); // Doesn't force block updates on neighbors, use for simple changes such as grass growing etc.
- char GetBlock( int a_X, int a_Y, int a_Z );
- char GetBlock( int a_BlockIdx );
+ void SetBlock( int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta );
+ void SetBlock( const Vector3i & a_BlockPos, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta ) { SetBlock( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, a_BlockType, a_BlockMeta ); }
+ void FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta ); // Doesn't force block updates on neighbors, use for simple changes such as grass growing etc.
+ BLOCKTYPE GetBlock( int a_X, int a_Y, int a_Z );
+ BLOCKTYPE GetBlock( int a_BlockIdx );
void CollectPickupsByPlayer(cPlayer * a_Player);
void UpdateSign(int a_PosX, int a_PosY, int a_PosZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4); // Also sends update packets to all clients in the chunk
@@ -196,7 +133,7 @@ public:
void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z); // [x, y, z] in world block coords
inline void RecalculateLighting() { m_bCalculateLighting = true; } // Recalculate lighting next tick
- void SpreadLight(char* a_LightBuffer);
+
void CalculateLighting(); // Recalculate right now
void CalculateHeightmap();
@@ -207,67 +144,28 @@ public:
// Loaded(blockdata, lightdata, blockentities, entities),
// Generated(blockdata, lightdata, blockentities, entities),
// GetBlockData(blockdatadest) etc.
- 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; }
-
- void CopyBlockDataFrom(const char * a_NewBlockData); // Copies all blockdata, recalculates heightmap (used by chunk loaders)
+ /*
+ BLOCKTYPE * GetBlockTypes (void) { return m_BlockTypes; }
+ BLOCKTYPE * GetBlockMeta (void) { return m_BlockMeta; }
+ BLOCKTYPE * GetBlockLight (void) { return m_BlockLight; }
+ BLOCKTYPE * GetBlockSkyLight(void) { return m_BlockSkyLight; }
+ */
- static char GetNibble(char * a_Buffer, int a_BlockIdx);
- static char GetNibble(char * a_Buffer, int x, int y, int z);
- static char GetNibble(char * a_Buffer, const Vector3i & a_BlockPos ) { return GetNibble( a_Buffer, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z ); }
- static void SetNibble(char * a_Buffer, int a_BlockIdx, char a_Value);
- static void SetNibble(char * a_Buffer, int x, int y, int z, char a_Value);
- static void SetNibble(char * a_Buffer, const Vector3i & a_BlockPos, char a_Value ) { SetNibble( a_Buffer, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, a_Value ); }
-
void PositionToWorldPosition(int a_ChunkX, int a_ChunkY, int a_ChunkZ, int & a_X, int & a_Y, int & a_Z);
Vector3i PositionToWorldPosition( const Vector3i & a_InChunkPos ) { return PositionToWorldPosition( a_InChunkPos.x, a_InChunkPos.y, a_InChunkPos.z ); }
Vector3i PositionToWorldPosition( int a_ChunkX, int a_ChunkY, int a_ChunkZ );
- static const unsigned int INDEX_OUT_OF_RANGE = 0xffffffff;
- inline static unsigned int MakeIndex(int x, int y, int z )
- {
- if( x < c_ChunkWidth && x > -1 && y < c_ChunkHeight && y > -1 && z < c_ChunkWidth && z > -1 )
- {
- return MakeIndexNoCheck(x, y, z);
- }
- return INDEX_OUT_OF_RANGE;
- }
-
- inline static unsigned int MakeIndexNoCheck(int x, int y, int z)
- {
- #if AXIS_ORDER == AXIS_ORDER_XZY
- // For some reason, NOT using the Horner schema is faster. Weird.
- return x + (z * c_ChunkWidth) + (y * c_ChunkWidth * c_ChunkWidth); // 1.2 is XZY
- #elif AXIS_ORDER == AXIS_ORDER_YZX
- return y + (z * c_ChunkHeight) + (x * c_ChunkHeight * c_ChunkWidth); // 1.1 is YZX
- #endif
- }
-
- inline static Vector3i IndexToCoordinate( unsigned int index )
- {
- #if AXIS_ORDER == AXIS_ORDER_XZY
- return Vector3i( // 1.2
- index % c_ChunkWidth, // X
- index / (c_ChunkWidth * c_ChunkWidth), // Y
- (index / c_ChunkWidth) % c_ChunkWidth // Z
- );
- #elif AXIS_ORDER == AXIS_ORDER_YZX
- return Vector3i( // 1.1
- index / (c_ChunkHeight * c_ChunkWidth), // X
- index % c_ChunkHeight, // Y
- (index / c_ChunkHeight) % c_ChunkWidth // Z
- );
- #endif
- }
-
inline void MarkDirty(void)
{
m_IsDirty = true;
m_IsSaving = false;
}
+
+ inline void SpreadBlockSkyLight(void) {SpreadLight(m_BlockSkyLight); }
+ inline void SpreadBlockLight (void) {SpreadLight(m_BlockLight); }
+
+ inline BLOCKTYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) {return cChunkDef::GetNibble(m_BlockMeta, a_RelX, a_RelY, a_RelZ); }
+ inline void SetMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_Meta) { cChunkDef::SetNibble(m_BlockMeta, a_RelX, a_RelY, a_RelZ, a_Meta); }
private:
@@ -278,9 +176,9 @@ private:
bool m_IsSaving; // True if the chunk is being saved
bool m_HasLoadFailed; // True if chunk failed to load and hasn't been generated yet since then
- cCriticalSection m_CSBlockLists;
- std::deque< unsigned int > m_ToTickBlocks;
- std::vector< unsigned int > m_PendingSendBlocks;
+ cCriticalSection m_CSBlockLists;
+ std::deque< unsigned int > m_ToTickBlocks;
+ std::vector< unsigned int > m_PendingSendBlocks;
// A critical section is not needed, because all chunk access is protected by its parent ChunkMap's csLayers
cClientHandleList m_LoadedByClient;
@@ -297,13 +195,13 @@ private:
cWorld * m_World;
cChunkMap * m_ChunkMap;
- 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
+ // TODO: Make these pointers and don't allocate what isn't needed
+ BLOCKTYPE m_BlockTypes [cChunkDef::NumBlocks];
+ BLOCKTYPE m_BlockMeta [cChunkDef::NumBlocks / 2];
+ BLOCKTYPE m_BlockLight [cChunkDef::NumBlocks / 2];
+ BLOCKTYPE m_BlockSkyLight[cChunkDef::NumBlocks / 2];
- unsigned char m_HeightMap[c_ChunkWidth * c_ChunkWidth];
+ cChunkDef::HeightMap m_HeightMap;
unsigned int m_BlockTickNum;
unsigned int m_BlockTickX, m_BlockTickY, m_BlockTickZ;
@@ -319,6 +217,8 @@ private:
// Makes a copy of the list
cClientHandleList GetAllClients(void) const {return m_LoadedByClient; }
+
+ void SpreadLight(BLOCKTYPE * a_LightBuffer);
};
typedef cChunk * cChunkPtr;
@@ -329,27 +229,6 @@ typedef std::list<cChunkPtr> cChunkPtrList;
-class cChunkCoords
-{
-public:
- int m_ChunkX;
- int m_ChunkY;
- int m_ChunkZ;
-
- cChunkCoords(int a_ChunkX, int a_ChunkY, int a_ChunkZ) : m_ChunkX(a_ChunkX), m_ChunkY(a_ChunkY), m_ChunkZ(a_ChunkZ) {}
-
- bool operator == (const cChunkCoords & a_Other)
- {
- return ((m_ChunkX == a_Other.m_ChunkX) && (m_ChunkY == a_Other.m_ChunkY) && (m_ChunkZ == a_Other.m_ChunkZ));
- }
-} ;
-
-typedef std::list<cChunkCoords> cChunkCoordsList;
-
-
-
-
-
#if C_CHUNK_USE_INLINE
#include "cChunk.inl.h"
#endif
diff --git a/source/cChunk.inl.h b/source/cChunk.inl.h
index b4c7353d9..1300f8209 100644
--- a/source/cChunk.inl.h
+++ b/source/cChunk.inl.h
@@ -11,77 +11,15 @@
__C_CHUNK_INLINE__
-char cChunk::GetNibble(char * a_Buffer, int a_BlockIdx)
+void cChunk::SpreadLightOfBlock(BLOCKTYPE * a_LightBuffer, int a_X, int a_Y, int a_Z, BLOCKTYPE a_Falloff)
{
- if ((a_BlockIdx > -1) && (a_BlockIdx < c_NumBlocks))
- {
- return (a_Buffer[a_BlockIdx / 2] >> ((a_BlockIdx & 1) * 4)) & 0x0f;
- }
- return 0;
-}
-
-
-
-
-
-__C_CHUNK_INLINE__
-char cChunk::GetNibble(char * a_Buffer, int x, int y, int z)
-{
- if ((x < c_ChunkWidth) && (x > -1) && (y < c_ChunkHeight) && (y > -1) && (z < c_ChunkWidth) && (z > -1))
- {
- int Index = MakeIndexNoCheck(x, y, z);
- return (a_Buffer[Index / 2] >> ((Index & 1) * 4)) & 0x0f;
- }
- return 0;
-}
-
-
-
-
-
-__C_CHUNK_INLINE__
-void cChunk::SetNibble(char * a_Buffer, int a_BlockIdx, char a_Nibble)
-{
- if ((a_BlockIdx > -1) && (a_BlockIdx < c_NumBlocks))
- {
- a_Buffer[a_BlockIdx / 2] = (
- (a_Buffer[a_BlockIdx / 2] & (0xf0 >> ((a_BlockIdx & 1) * 4))) | // The untouched nibble
- ((a_Nibble & 0x0f) << ((a_BlockIdx & 1) * 4)) // The nibble being set
- );
- }
-}
-
-
-
-
-
-__C_CHUNK_INLINE__
-void cChunk::SetNibble(char * a_Buffer, int x, int y, int z, char a_Nibble)
-{
- if ((x < c_ChunkWidth) && (x > -1) && (y < c_ChunkHeight) && (y > -1) && (z < c_ChunkWidth) && (z > -1))
- {
- int Index = MakeIndexNoCheck(x, y, z);
- a_Buffer[Index / 2] = (
- (a_Buffer[Index / 2] & (0xf0 >> ((Index & 1) * 4))) | // The untouched nibble
- ((a_Nibble & 0x0f) << ((Index & 1) * 4)) // The nibble being set
- );
- }
-}
-
-
-
-
-
-__C_CHUNK_INLINE__
-void cChunk::SpreadLightOfBlock(char * a_LightBuffer, int a_X, int a_Y, int a_Z, char a_Falloff)
-{
- unsigned char CurrentLight = GetNibble( a_LightBuffer, a_X, a_Y, a_Z );
- SetNibble( a_LightBuffer, a_X-1, a_Y, a_Z, MAX(GetNibble( a_LightBuffer, a_X-1, a_Y, a_Z ), MAX(0,CurrentLight-a_Falloff) ) );
- SetNibble( a_LightBuffer, a_X+1, a_Y, a_Z, MAX(GetNibble( a_LightBuffer, a_X+1, a_Y, a_Z ), MAX(0,CurrentLight-a_Falloff) ) );
- SetNibble( a_LightBuffer, a_X, a_Y-1, a_Z, MAX(GetNibble( a_LightBuffer, a_X, a_Y-1, a_Z ), MAX(0,CurrentLight-a_Falloff) ) );
- SetNibble( a_LightBuffer, a_X, a_Y+1, a_Z, MAX(GetNibble( a_LightBuffer, a_X, a_Y+1, a_Z ), MAX(0,CurrentLight-a_Falloff) ) );
- SetNibble( a_LightBuffer, a_X, a_Y, a_Z-1, MAX(GetNibble( a_LightBuffer, a_X, a_Y, a_Z-1 ), MAX(0,CurrentLight-a_Falloff) ) );
- SetNibble( a_LightBuffer, a_X, a_Y, a_Z+1, MAX(GetNibble( a_LightBuffer, a_X, a_Y, a_Z+1 ), MAX(0,CurrentLight-a_Falloff) ) );
+ unsigned char CurrentLight = cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y, a_Z );
+ cChunkDef::SetNibble( a_LightBuffer, a_X-1, a_Y, a_Z, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X-1, a_Y, a_Z ), MAX(0,CurrentLight-a_Falloff) ) );
+ cChunkDef::SetNibble( a_LightBuffer, a_X+1, a_Y, a_Z, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X+1, a_Y, a_Z ), MAX(0,CurrentLight-a_Falloff) ) );
+ cChunkDef::SetNibble( a_LightBuffer, a_X, a_Y-1, a_Z, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y-1, a_Z ), MAX(0,CurrentLight-a_Falloff) ) );
+ cChunkDef::SetNibble( a_LightBuffer, a_X, a_Y+1, a_Z, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y+1, a_Z ), MAX(0,CurrentLight-a_Falloff) ) );
+ cChunkDef::SetNibble( a_LightBuffer, a_X, a_Y, a_Z-1, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y, a_Z-1 ), MAX(0,CurrentLight-a_Falloff) ) );
+ cChunkDef::SetNibble( a_LightBuffer, a_X, a_Y, a_Z+1, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y, a_Z+1 ), MAX(0,CurrentLight-a_Falloff) ) );
MarkDirty();
}
diff --git a/source/cChunkGenerator.cpp b/source/cChunkGenerator.cpp
index 7dde581c2..95b43e5b4 100644
--- a/source/cChunkGenerator.cpp
+++ b/source/cChunkGenerator.cpp
@@ -180,11 +180,21 @@ void cChunkGenerator::Execute(void)
void cChunkGenerator::DoGenerate(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
{
- char BlockData[cChunk::c_BlockDataSize];
+ char BlockData[cChunkDef::BlockDataSize];
cEntityList Entities;
cBlockEntityList BlockEntities;
m_pWorldGenerator->GenerateChunk(a_ChunkX, a_ChunkY, a_ChunkZ, BlockData, Entities, BlockEntities);
- m_World->ChunkDataGenerated(a_ChunkX, a_ChunkY, a_ChunkZ, BlockData, Entities, BlockEntities);
+
+ m_World->ChunkDataGenerated(
+ a_ChunkX, a_ChunkY, a_ChunkZ,
+ BlockData,
+ BlockData + cChunkDef::MetaOffset,
+ BlockData + cChunkDef::LightOffset,
+ BlockData + cChunkDef::SkyLightOffset,
+ NULL,
+ Entities, BlockEntities
+ );
+
m_pWorldGenerator->PostGenerateChunk(a_ChunkX, a_ChunkY, a_ChunkZ);
}
diff --git a/source/cChunkGenerator.h b/source/cChunkGenerator.h
index de1b081d5..1a2403c80 100644
--- a/source/cChunkGenerator.h
+++ b/source/cChunkGenerator.h
@@ -17,7 +17,7 @@
#pragma once
#include "cIsThread.h"
-#include "cChunk.h"
+#include "ChunkDef.h"
diff --git a/source/cChunkMap.cpp b/source/cChunkMap.cpp
index a6b158360..02ea0917e 100644
--- a/source/cChunkMap.cpp
+++ b/source/cChunkMap.cpp
@@ -9,6 +9,7 @@
#include "BlockID.h"
#include "cItem.h"
#include "cPickup.h"
+#include "cChunk.h"
#ifndef _WIN32
#include <cstdlib> // abs
@@ -198,7 +199,7 @@ void cChunkMap::BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, const cPacket
cCSLock Lock(m_CSLayers);
int ChunkX, ChunkZ;
- BlockToChunk(a_X, a_Y, a_Z, ChunkX, ChunkZ);
+ cChunkDef::BlockToChunk(a_X, a_Y, a_Z, ChunkX, ChunkZ);
cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ);
if (Chunk == NULL)
{
@@ -217,7 +218,7 @@ void cChunkMap::UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z)
// a_Player rclked block entity at the coords specified, handle it
cCSLock Lock(m_CSLayers);
int ChunkX, ChunkZ;
- BlockToChunk(a_X, a_Y, a_Z, ChunkX, ChunkZ);
+ cChunkDef::BlockToChunk(a_X, a_Y, a_Z, ChunkX, ChunkZ);
cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ);
if ((Chunk == NULL) || !Chunk->IsValid())
{
@@ -275,7 +276,16 @@ void cChunkMap::MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-void cChunkMap::ChunkDataLoaded(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities)
+void cChunkMap::ChunkDataLoaded(
+ int a_ChunkX, int a_ChunkY, int a_ChunkZ,
+ const BLOCKTYPE * a_BlockTypes,
+ const BLOCKTYPE * a_BlockMeta,
+ const BLOCKTYPE * a_BlockLight,
+ const BLOCKTYPE * a_BlockSkyLight,
+ const cChunkDef::HeightMap * a_HeightMap,
+ cEntityList & a_Entities,
+ cBlockEntityList & a_BlockEntities
+)
{
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkY, a_ChunkZ);
@@ -283,7 +293,7 @@ void cChunkMap::ChunkDataLoaded(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const
{
return;
}
- Chunk->SetAllData(a_BlockData, a_Entities, a_BlockEntities);
+ Chunk->SetAllData(a_BlockTypes, a_BlockMeta, a_BlockLight, a_BlockSkyLight, a_HeightMap, a_Entities, a_BlockEntities);
Chunk->MarkLoaded();
}
@@ -291,7 +301,16 @@ void cChunkMap::ChunkDataLoaded(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const
-void cChunkMap::ChunkDataGenerated(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities)
+void cChunkMap::ChunkDataGenerated(
+ int a_ChunkX, int a_ChunkY, int a_ChunkZ,
+ const BLOCKTYPE * a_BlockTypes,
+ const BLOCKTYPE * a_BlockMeta,
+ const BLOCKTYPE * a_BlockLight,
+ const BLOCKTYPE * a_BlockSkyLight,
+ const cChunkDef::HeightMap * a_HeightMap,
+ cEntityList & a_Entities,
+ cBlockEntityList & a_BlockEntities
+)
{
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkY, a_ChunkZ);
@@ -299,7 +318,7 @@ void cChunkMap::ChunkDataGenerated(int a_ChunkX, int a_ChunkY, int a_ChunkZ, con
{
return;
}
- Chunk->SetAllData(a_BlockData, a_Entities, a_BlockEntities);
+ Chunk->SetAllData(a_BlockTypes, a_BlockMeta, a_BlockLight, a_BlockSkyLight, a_HeightMap, a_Entities, a_BlockEntities);
// TODO: This has to go - lighting takes way too long to execute in a locked ChunkMap!
Chunk->CalculateLighting();
@@ -328,7 +347,7 @@ bool cChunkMap::GetChunkData(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDat
-bool cChunkMap::GetChunkBlocks(int a_ChunkX, int a_ChunkY, int a_ChunkZ, char * a_Blocks)
+bool cChunkMap::GetChunkBlockTypes(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockTypes)
{
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
@@ -336,7 +355,7 @@ bool cChunkMap::GetChunkBlocks(int a_ChunkX, int a_ChunkY, int a_ChunkZ, char *
{
return false;
}
- Chunk->GetBlocks(a_Blocks);
+ Chunk->GetBlockTypes(a_BlockTypes);
return true;
}
@@ -344,7 +363,7 @@ bool cChunkMap::GetChunkBlocks(int a_ChunkX, int a_ChunkY, int a_ChunkZ, char *
-bool cChunkMap::GetChunkBlockData(int a_ChunkX, int a_ChunkY, int a_ChunkZ, char * a_BlockData)
+bool cChunkMap::GetChunkBlockData(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockData)
{
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
@@ -388,9 +407,8 @@ void cChunkMap::SpreadChunkLighting(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
if ((Chunk != NULL) && Chunk->IsValid())
{
- // TODO: Rewrite this to call Chunk's lighting without any parameters
- Chunk->SpreadLight( Chunk->pGetSkyLight() );
- Chunk->SpreadLight( Chunk->pGetLight() );
+ Chunk->SpreadBlockSkyLight();
+ Chunk->SpreadBlockLight();
}
}
@@ -402,7 +420,7 @@ int cChunkMap::GetHeight(int a_BlockX, int a_BlockZ)
{
cCSLock Lock(m_CSLayers);
int ChunkX, ChunkZ, BlockY = 0;
- AbsoluteToRelative(a_BlockX, BlockY, a_BlockZ, ChunkX, ChunkZ);
+ cChunkDef::AbsoluteToRelative(a_BlockX, BlockY, a_BlockZ, ChunkX, ChunkZ);
cChunkPtr Chunk = GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ);
if (Chunk == NULL)
{
@@ -482,7 +500,7 @@ void cChunkMap::CollectPickupsByPlayer(cPlayer * a_Player)
int BlockY = (int)(a_Player->GetPosY());
int BlockZ = (int)(a_Player->GetPosZ());
int ChunkX, ChunkZ, ChunkY = ZERO_CHUNK_Y;
- AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ);
+ cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ);
int OtherChunkX = ChunkX + ((BlockX > 8) ? 1 : -1);
int OtherChunkZ = ChunkZ + ((BlockZ > 8) ? 1 : -1);
@@ -506,7 +524,7 @@ void cChunkMap::CollectPickupsByPlayer(cPlayer * a_Player)
char cChunkMap::GetBlock(int a_X, int a_Y, int a_Z)
{
int ChunkX, ChunkZ;
- AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkZ );
+ cChunkDef::AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkZ );
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ);
@@ -524,14 +542,13 @@ char cChunkMap::GetBlock(int a_X, int a_Y, int a_Z)
char cChunkMap::GetBlockMeta(int a_X, int a_Y, int a_Z)
{
int ChunkX, ChunkZ;
- AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkZ );
+ cChunkDef::AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkZ );
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ );
if ((Chunk != NULL) && Chunk->IsValid() )
{
- // Although it is called GetLight(), it actually gets meta when passed the Meta field
- return cChunk::GetNibble( Chunk->pGetMeta(), a_X, a_Y, a_Z );
+ return Chunk->GetMeta(a_X, a_Y, a_Z);
}
return 0;
}
@@ -543,13 +560,13 @@ char cChunkMap::GetBlockMeta(int a_X, int a_Y, int a_Z)
void cChunkMap::SetBlockMeta(int a_X, int a_Y, int a_Z, char a_BlockMeta)
{
int ChunkX, ChunkZ;
- AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkZ );
+ cChunkDef::AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkZ );
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ );
if ((Chunk != NULL) && Chunk->IsValid() )
{
- cChunk::SetNibble( Chunk->pGetMeta(), a_X, a_Y, a_Z, a_BlockMeta );
+ Chunk->SetMeta(a_X, a_Y, a_Z, a_BlockMeta);
Chunk->MarkDirty();
Chunk->SendBlockTo( a_X, a_Y, a_Z, NULL );
}
@@ -562,7 +579,7 @@ void cChunkMap::SetBlockMeta(int a_X, int a_Y, int a_Z, char a_BlockMeta)
void cChunkMap::SetBlock(int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta)
{
int ChunkX, ChunkZ, X = a_X, Y = a_Y, Z = a_Z;
- AbsoluteToRelative( X, Y, Z, ChunkX, ChunkZ );
+ cChunkDef::AbsoluteToRelative( X, Y, Z, ChunkX, ChunkZ );
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ );
@@ -580,7 +597,7 @@ bool cChunkMap::DigBlock(int a_X, int a_Y, int a_Z, cItem & a_PickupItem)
{
int PosX = a_X, PosY = a_Y, PosZ = a_Z, ChunkX, ChunkZ;
- AbsoluteToRelative( PosX, PosY, PosZ, ChunkX, ChunkZ );
+ cChunkDef::AbsoluteToRelative( PosX, PosY, PosZ, ChunkX, ChunkZ );
{
cCSLock Lock(m_CSLayers);
@@ -610,7 +627,7 @@ bool cChunkMap::DigBlock(int a_X, int a_Y, int a_Z, cItem & a_PickupItem)
void cChunkMap::SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player)
{
int ChunkX, ChunkZ;
- AbsoluteToRelative(a_X, a_Y, a_Z, ChunkX, ChunkZ);
+ cChunkDef::AbsoluteToRelative(a_X, a_Y, a_Z, ChunkX, ChunkZ);
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ);
@@ -831,7 +848,7 @@ void cChunkMap::UpdateSign(int a_X, int a_Y, int a_Z, const AString & a_Line1, c
{
cCSLock Lock(m_CSLayers);
int ChunkX, ChunkZ;
- BlockToChunk(a_X, a_Y, a_Z, ChunkX, ChunkZ);
+ cChunkDef::BlockToChunk(a_X, a_Y, a_Z, ChunkX, ChunkZ);
cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ);
if ((Chunk == NULL) || !Chunk->IsValid())
{
diff --git a/source/cChunkMap.h b/source/cChunkMap.h
index 297056d81..10fe1e70a 100644
--- a/source/cChunkMap.h
+++ b/source/cChunkMap.h
@@ -5,17 +5,23 @@
#pragma once
-#include "cChunk.h"
+#include "ChunkDef.h"
class cWorld;
-class cEntity;
class cItem;
class MTRand;
class cChunkStay;
+class cChunk;
+class cPacket;
+class cPlayer;
+
+typedef std::list<cClientHandle *> cClientHandleList;
+typedef cChunk * cChunkPtr;
+
@@ -42,28 +48,49 @@ public:
void MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
void MarkChunkSaving (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
void MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
- void ChunkDataLoaded (int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities);
- void ChunkDataGenerated (int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities);
+
+ void ChunkDataLoaded(
+ int a_ChunkX, int a_ChunkY, int a_ChunkZ,
+ const BLOCKTYPE * a_BlockTypes,
+ const BLOCKTYPE * a_BlockMeta,
+ const BLOCKTYPE * a_BlockLight,
+ const BLOCKTYPE * a_BlockSkyLight,
+ const cChunkDef::HeightMap * a_HeightMap,
+ cEntityList & a_Entities,
+ cBlockEntityList & a_BlockEntities
+ );
+
+ void ChunkDataGenerated (
+ int a_ChunkX, int a_ChunkY, int a_ChunkZ,
+ const BLOCKTYPE * a_BlockTypes,
+ const BLOCKTYPE * a_BlockMeta,
+ const BLOCKTYPE * a_BlockLight,
+ const BLOCKTYPE * a_BlockSkyLight,
+ const cChunkDef::HeightMap * a_HeightMap,
+ cEntityList & a_Entities,
+ cBlockEntityList & a_BlockEntities
+ );
+
bool GetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback & a_Callback);
/// Gets the chunk's blocks, only the block types
- bool GetChunkBlocks (int a_ChunkX, int a_ChunkY, int a_ChunkZ, char * a_Blocks);
-
- /// Gets the chunk's blockdata, the entire array
- bool GetChunkBlockData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, char * a_BlockData);
-
- bool IsChunkValid (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
- bool HasChunkAnyClients (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
- void SpreadChunkLighting(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
- int GetHeight (int a_BlockX, int a_BlockZ);
- void FastSetBlocks (sSetBlockList & a_BlockList);
- void CollectPickupsByPlayer(cPlayer * a_Player);
- char GetBlock (int a_X, int a_Y, int a_Z);
- char GetBlockMeta (int a_X, int a_Y, int a_Z);
- void SetBlockMeta (int a_X, int a_Y, int a_Z, char a_BlockMeta);
- void SetBlock (int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta);
- bool DigBlock (int a_X, int a_Y, int a_Z, cItem & a_PickupItem);
- void SendBlockTo (int a_X, int a_Y, int a_Z, cPlayer * a_Player);
+ bool GetChunkBlockTypes (int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_Blocks);
+
+ /// Gets the chunk's block data, the entire 4 arrays (Types, Meta, Light, SkyLight)
+ bool GetChunkBlockData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockData);
+
+ bool IsChunkValid (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
+ bool HasChunkAnyClients (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
+ void SpreadChunkLighting(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
+ int GetHeight (int a_BlockX, int a_BlockZ);
+ void FastSetBlocks (sSetBlockList & a_BlockList);
+ void CollectPickupsByPlayer(cPlayer * a_Player);
+ BLOCKTYPE GetBlock (int a_X, int a_Y, int a_Z);
+ BLOCKTYPE GetBlockMeta (int a_X, int a_Y, int a_Z);
+ void SetBlockMeta (int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockMeta);
+ void SetBlock (int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta);
+ bool DigBlock (int a_X, int a_Y, int a_Z, cItem & a_PickupItem);
+ void SendBlockTo (int a_X, int a_Y, int a_Z, cPlayer * a_Player);
/// Compares clients of two chunks, calls the callback accordingly
void CompareChunkClients(int a_ChunkX1, int a_ChunkY1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkY2, int a_ChunkZ2, cClientDiffCallback & a_Callback);
@@ -109,31 +136,6 @@ public:
int GetNumChunks(void);
- /// Converts absolute block coords into relative (chunk + block) coords:
- inline static void AbsoluteToRelative(/* in-out */ int & a_X, int & a_Y, int & a_Z, /* out */ int & a_ChunkX, int & a_ChunkZ )
- {
- BlockToChunk(a_X, a_Y, a_Z, a_ChunkX, a_ChunkZ);
-
- a_X = a_X - a_ChunkX * cChunk::c_ChunkWidth;
- a_Z = a_Z - a_ChunkZ * cChunk::c_ChunkWidth;
- }
-
- /// Converts absolute block coords to chunk coords:
- inline static void BlockToChunk( int a_X, int a_Y, int a_Z, int & a_ChunkX, int & a_ChunkZ )
- {
- (void)a_Y;
- a_ChunkX = a_X / cChunk::c_ChunkWidth;
- if ((a_X < 0) && (a_X % cChunk::c_ChunkWidth != 0))
- {
- a_ChunkX--;
- }
- a_ChunkZ = a_Z / cChunk::c_ChunkWidth;
- if ((a_Z < 0) && (a_Z % cChunk::c_ChunkWidth != 0))
- {
- a_ChunkZ--;
- }
- }
-
void ChunkValidated(void); // Called by chunks that have become valid
private:
diff --git a/source/cClientHandle.cpp b/source/cClientHandle.cpp
index 07be3d4a7..d7b1aa55c 100644
--- a/source/cClientHandle.cpp
+++ b/source/cClientHandle.cpp
@@ -349,8 +349,8 @@ void cClientHandle::StreamChunks(void)
ASSERT(m_Player != NULL);
- int ChunkPosX = FAST_FLOOR_DIV(m_Player->GetPosX(), cChunk::c_ChunkWidth);
- int ChunkPosZ = FAST_FLOOR_DIV(m_Player->GetPosZ(), cChunk::c_ChunkWidth);
+ int ChunkPosX = FAST_FLOOR_DIV(m_Player->GetPosX(), cChunkDef::Width);
+ int ChunkPosZ = FAST_FLOOR_DIV(m_Player->GetPosZ(), cChunkDef::Width);
if ((ChunkPosX == m_LastStreamedChunkX) && (ChunkPosZ == m_LastStreamedChunkZ))
{
// Already streamed for this position
@@ -1721,8 +1721,8 @@ void cClientHandle::Send(const cPacket & a_Packet, ENUM_PRIORITY a_Priority /* =
int ChunkX = ((cPacket_MapChunk &)a_Packet).m_PosX;
int ChunkZ = ((cPacket_MapChunk &)a_Packet).m_PosZ;
#else
- int ChunkX = ((cPacket_MapChunk &)a_Packet).m_PosX / cChunk::c_ChunkWidth;
- int ChunkZ = ((cPacket_MapChunk &)a_Packet).m_PosZ / cChunk::c_ChunkWidth;
+ int ChunkX = ((cPacket_MapChunk &)a_Packet).m_PosX / cChunkDef::Width;
+ int ChunkZ = ((cPacket_MapChunk &)a_Packet).m_PosZ / cChunkDef::Width;
#endif
bool Found = false;
cCSLock Lock(m_CSChunkLists);
diff --git a/source/cClientHandle.h b/source/cClientHandle.h
index 0b868420e..c41d08de7 100644
--- a/source/cClientHandle.h
+++ b/source/cClientHandle.h
@@ -14,7 +14,7 @@
#include "packets/cPacket.h"
#include "Vector3d.h"
#include "cSocketThreads.h"
-#include "cChunk.h"
+#include "ChunkDef.h"
#include "packets/cPacket_KeepAlive.h"
#include "packets/cPacket_PlayerPosition.h"
diff --git a/source/cEntity.cpp b/source/cEntity.cpp
index f9e9d4e82..40bef9cb9 100644
--- a/source/cEntity.cpp
+++ b/source/cEntity.cpp
@@ -3,7 +3,6 @@
#include "cEntity.h"
#include "cWorld.h"
-#include "cChunk.h"
#include "cServer.h"
#include "cRoot.h"
#include "Vector3d.h"
@@ -54,7 +53,7 @@ cEntity::~cEntity()
LOG("Deleting entity %d at pos {%.2f, %.2f} ~ [%d, %d]; ptr %p",
m_UniqueID,
m_Pos.x, m_Pos.z,
- (int)(m_Pos.x / cChunk::c_ChunkWidth), (int)(m_Pos.z / cChunk::c_ChunkWidth),
+ (int)(m_Pos.x / cChunkDef::Width), (int)(m_Pos.z / cChunkDef::Width),
this
);
diff --git a/source/cFurnaceEntity.cpp b/source/cFurnaceEntity.cpp
index 4485d2c01..3c4a7403d 100644
--- a/source/cFurnaceEntity.cpp
+++ b/source/cFurnaceEntity.cpp
@@ -7,7 +7,6 @@
#include "cFurnaceWindow.h"
#include "cPlayer.h"
#include "cWorld.h"
-#include "cChunk.h"
#include "cClientHandle.h"
#include "cFurnaceRecipe.h"
#include "cServer.h"
diff --git a/source/cMonster.cpp b/source/cMonster.cpp
index 80c7e8d24..15fb16fc3 100644
--- a/source/cMonster.cpp
+++ b/source/cMonster.cpp
@@ -6,7 +6,6 @@
#include "cServer.h"
#include "cClientHandle.h"
#include "cWorld.h"
-#include "cChunk.h"
#include "cPlayer.h"
#include "BlockID.h"
#include "Defines.h"
diff --git a/source/cPawn.cpp b/source/cPawn.cpp
index 4ec75eaa9..986d8904c 100644
--- a/source/cPawn.cpp
+++ b/source/cPawn.cpp
@@ -6,7 +6,6 @@
#include "cServer.h"
#include "cWorld.h"
#include "cPlayer.h"
-#include "cChunk.h"
#include "cPluginManager.h"
#include "Vector3d.h"
#include "BlockID.h"
diff --git a/source/cPickup.cpp b/source/cPickup.cpp
index e8c0b80db..5b35f215f 100644
--- a/source/cPickup.cpp
+++ b/source/cPickup.cpp
@@ -16,7 +16,6 @@
#include "cItem.h"
#include "cRoot.h"
#include "cTracer.h"
-#include "cChunk.h"
#include "packets/cPacket_TeleportEntity.h"
#include "packets/cPacket_PickupSpawn.h"
diff --git a/source/cPiston.cpp b/source/cPiston.cpp
index df9af6fb7..f97a80b8c 100644
--- a/source/cPiston.cpp
+++ b/source/cPiston.cpp
@@ -3,7 +3,7 @@
#include "cPiston.h"
#include "cRedstone.h"
-#include "cChunk.h"
+#include "ChunkDef.h"
#include "cPickup.h"
#include "cBlockToPickup.h"
#include "cItem.h"
diff --git a/source/cPlayer.cpp b/source/cPlayer.cpp
index 01c99f1dc..d375bb539 100644
--- a/source/cPlayer.cpp
+++ b/source/cPlayer.cpp
@@ -9,7 +9,6 @@
#include "cWorld.h"
#include "cPickup.h"
#include "cPluginManager.h"
-#include "cChunk.h"
#include "cWindow.h"
#include "cBlockEntity.h"
#include "cGroupManager.h"
diff --git a/source/cServer.cpp b/source/cServer.cpp
index 88bf9d240..39b74464d 100644
--- a/source/cServer.cpp
+++ b/source/cServer.cpp
@@ -11,7 +11,7 @@
#include "cSocket.h"
#include "cRoot.h"
#include "cWorld.h"
-#include "cChunk.h"
+#include "ChunkDef.h"
#include "cPluginManager.h"
#include "cGroupManager.h"
#include "cChatColor.h"
diff --git a/source/cSignEntity.cpp b/source/cSignEntity.cpp
index 3f0befc3f..ca21d847b 100644
--- a/source/cSignEntity.cpp
+++ b/source/cSignEntity.cpp
@@ -6,7 +6,6 @@
#include "cPlayer.h"
#include "cClientHandle.h"
#include "cWorld.h"
-#include "cChunk.h"
#include "cRoot.h"
#include "packets/cPacket_UpdateSign.h"
diff --git a/source/cWorld.cpp b/source/cWorld.cpp
index 91fbe7f64..9abcac4f7 100644
--- a/source/cWorld.cpp
+++ b/source/cWorld.cpp
@@ -4,7 +4,7 @@
#include "BlockID.h"
#include "cWorld.h"
#include "cRedstone.h"
-#include "cChunk.h"
+#include "ChunkDef.h"
#include "cClientHandle.h"
#include "cPickup.h"
#include "cBlockToPickup.h"
@@ -190,7 +190,7 @@ cWorld::cWorld( const AString & a_WorldName )
MTRand r1;
m_SpawnX = (double)((r1.randInt()%1000)-500);
- m_SpawnY = cChunk::c_ChunkHeight;
+ m_SpawnY = cChunkDef::Height;
m_SpawnZ = (double)((r1.randInt()%1000)-500);
m_WorldSeed = r1.randInt();
m_GameMode = eGameMode_Creative;
@@ -994,9 +994,18 @@ void cWorld::MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-void cWorld::ChunkDataLoaded(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities)
+void cWorld::ChunkDataLoaded(
+ int a_ChunkX, int a_ChunkY, int a_ChunkZ,
+ const BLOCKTYPE * a_BlockTypes,
+ const BLOCKTYPE * a_BlockMeta,
+ const BLOCKTYPE * a_BlockLight,
+ const BLOCKTYPE * a_BlockSkyLight,
+ const cChunkDef::HeightMap * a_HeightMap,
+ cEntityList & a_Entities,
+ cBlockEntityList & a_BlockEntities
+)
{
- m_ChunkMap->ChunkDataLoaded(a_ChunkX, a_ChunkY, a_ChunkZ, a_BlockData, a_Entities, a_BlockEntities);
+ m_ChunkMap->ChunkDataLoaded(a_ChunkX, a_ChunkY, a_ChunkZ, a_BlockTypes, a_BlockMeta, a_BlockLight, a_BlockSkyLight, a_HeightMap, a_Entities, a_BlockEntities);
m_ChunkSender.ChunkReady(a_ChunkX, a_ChunkY, a_ChunkZ);
}
@@ -1004,9 +1013,18 @@ void cWorld::ChunkDataLoaded(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const cha
-void cWorld::ChunkDataGenerated(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities)
+void cWorld::ChunkDataGenerated(
+ int a_ChunkX, int a_ChunkY, int a_ChunkZ,
+ const BLOCKTYPE * a_BlockTypes,
+ const BLOCKTYPE * a_BlockMeta,
+ const BLOCKTYPE * a_BlockLight,
+ const BLOCKTYPE * a_BlockSkyLight,
+ const cChunkDef::HeightMap * a_HeightMap,
+ cEntityList & a_Entities,
+ cBlockEntityList & a_BlockEntities
+)
{
- m_ChunkMap->ChunkDataGenerated(a_ChunkX, a_ChunkY, a_ChunkZ, a_BlockData, a_Entities, a_BlockEntities);
+ m_ChunkMap->ChunkDataGenerated(a_ChunkX, a_ChunkY, a_ChunkZ, a_BlockTypes, a_BlockMeta, a_BlockLight, a_BlockSkyLight, a_HeightMap, a_Entities, a_BlockEntities);
m_ChunkSender.ChunkReady(a_ChunkX, a_ChunkY, a_ChunkZ);
}
@@ -1023,16 +1041,16 @@ bool cWorld::GetChunkData(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCa
-bool cWorld::GetChunkBlocks(int a_ChunkX, int a_ChunkY, int a_ChunkZ, char * a_Blocks)
+bool cWorld::GetChunkBlockTypes(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockTypes)
{
- return m_ChunkMap->GetChunkBlocks(a_ChunkX, a_ChunkY, a_ChunkZ, a_Blocks);
+ return m_ChunkMap->GetChunkBlockTypes(a_ChunkX, a_ChunkY, a_ChunkZ, a_BlockTypes);
}
-bool cWorld::GetChunkBlockData(int a_ChunkX, int a_ChunkY, int a_ChunkZ, char * a_BlockData)
+bool cWorld::GetChunkBlockData(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockData)
{
return m_ChunkMap->GetChunkBlockData(a_ChunkX, a_ChunkY, a_ChunkZ, a_BlockData);
}
diff --git a/source/cWorld.h b/source/cWorld.h
index bdf2ae2c5..c2f3d3fcf 100644
--- a/source/cWorld.h
+++ b/source/cWorld.h
@@ -15,6 +15,7 @@
#include "WorldStorage.h"
#include "cChunkGenerator.h"
#include "Vector3i.h"
+#include "Vector3f.h"
#include "ChunkSender.h"
#include "Defines.h"
@@ -67,18 +68,39 @@ public:
void BroadcastToChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const cPacket & a_Packet, cClientHandle * a_Exclude = NULL);
void BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, cPacket * a_Packet, cClientHandle * a_Exclude = NULL);
- void MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
- void MarkChunkSaving (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
- void MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
- void ChunkDataLoaded (int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities);
- void ChunkDataGenerated(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities);
+ void MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
+ void MarkChunkSaving(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
+ void MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
+
+ void ChunkDataLoaded(
+ int a_ChunkX, int a_ChunkY, int a_ChunkZ,
+ const BLOCKTYPE * a_BlockTypes,
+ const BLOCKTYPE * a_BlockMeta,
+ const BLOCKTYPE * a_BlockLight,
+ const BLOCKTYPE * a_BlockSkyLight,
+ const cChunkDef::HeightMap * a_HeightMap,
+ cEntityList & a_Entities,
+ cBlockEntityList & a_BlockEntities
+ );
+
+ void ChunkDataGenerated (
+ int a_ChunkX, int a_ChunkY, int a_ChunkZ,
+ const BLOCKTYPE * a_BlockTypes,
+ const BLOCKTYPE * a_BlockMeta,
+ const BLOCKTYPE * a_BlockLight,
+ const BLOCKTYPE * a_BlockSkyLight,
+ const cChunkDef::HeightMap * a_HeightMap,
+ cEntityList & a_Entities,
+ cBlockEntityList & a_BlockEntities
+ );
+
bool GetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback & a_Callback);
/// Gets the chunk's blocks, only the block types
- bool GetChunkBlocks (int a_ChunkX, int a_ChunkY, int a_ChunkZ, char * a_Blocks);
+ bool GetChunkBlockTypes(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockTypes);
- /// Gets the chunk's blockdata, the entire array
- bool GetChunkBlockData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, char * a_BlockData);
+ /// Gets the chunk's blockdata, the entire 4 arrays (Types, Meta, Light, SkyLight)
+ bool GetChunkBlockData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockData);
bool IsChunkValid (int a_ChunkX, int a_ChunkY, int a_ChunkZ) const;
bool HasChunkAnyClients(int a_ChunkX, int a_ChunkY, int a_ChunkZ) const;
@@ -193,15 +215,15 @@ public:
{
// TODO: Use floor() instead of weird if statements
// Also fix Y
- a_ChunkX = a_X/cChunk::c_ChunkWidth;
- if(a_X < 0 && a_X % cChunk::c_ChunkWidth != 0) a_ChunkX--;
+ a_ChunkX = a_X/cChunkDef::Width;
+ if(a_X < 0 && a_X % cChunkDef::Width != 0) a_ChunkX--;
a_ChunkY = 0;
- a_ChunkZ = a_Z/cChunk::c_ChunkWidth;
- if(a_Z < 0 && a_Z % cChunk::c_ChunkWidth != 0) a_ChunkZ--;
+ a_ChunkZ = a_Z/cChunkDef::Width;
+ if(a_Z < 0 && a_Z % cChunkDef::Width != 0) a_ChunkZ--;
- a_X = a_X - a_ChunkX*cChunk::c_ChunkWidth;
- a_Y = a_Y - a_ChunkY*cChunk::c_ChunkHeight;
- a_Z = a_Z - a_ChunkZ*cChunk::c_ChunkWidth;
+ a_X = a_X - a_ChunkX*cChunkDef::Width;
+ a_Y = a_Y - a_ChunkY*cChunkDef::Height;
+ a_Z = a_Z - a_ChunkZ*cChunkDef::Width;
}
inline static void BlockToChunk( int a_X, int a_Y, int a_Z, int & a_ChunkX, int & a_ChunkY, int & a_ChunkZ )
@@ -209,11 +231,11 @@ public:
// TODO: Use floor() instead of weird if statements
// Also fix Y
(void)a_Y; // not unused anymore
- a_ChunkX = a_X/cChunk::c_ChunkWidth;
- if(a_X < 0 && a_X % cChunk::c_ChunkWidth != 0) a_ChunkX--;
+ a_ChunkX = a_X/cChunkDef::Width;
+ if(a_X < 0 && a_X % cChunkDef::Width != 0) a_ChunkX--;
a_ChunkY = 0;
- a_ChunkZ = a_Z/cChunk::c_ChunkWidth;
- if(a_Z < 0 && a_Z % cChunk::c_ChunkWidth != 0) a_ChunkZ--;
+ a_ChunkZ = a_Z/cChunkDef::Width;
+ if(a_Z < 0 && a_Z % cChunkDef::Width != 0) a_ChunkZ--;
}
void SaveAllChunks(); //tolua_export
diff --git a/source/cWorldGenerator.cpp b/source/cWorldGenerator.cpp
index 410dc4d97..80b01e963 100644
--- a/source/cWorldGenerator.cpp
+++ b/source/cWorldGenerator.cpp
@@ -4,7 +4,6 @@
#include "cWorldGenerator.h"
#include "cNoise.h"
#include "cWorld.h"
-#include "cChunk.h"
#include "cGenSettings.h"
#include "BlockID.h"
@@ -182,9 +181,9 @@ static float GetMarbleNoise( float x, float y, float z, cNoise & a_Noise )
unsigned int cWorldGenerator::MakeIndex(int x, int y, int z )
{
- ASSERT((x < cChunk::c_ChunkWidth) && (x > -1) && (y < cChunk::c_ChunkHeight) && (y > -1) && (z < cChunk::c_ChunkWidth) && (z > -1));
+ ASSERT((x < cChunkDef::Width) && (x > -1) && (y < cChunkDef::Height) && (y > -1) && (z < cChunkDef::Width) && (z > -1));
- return cChunk::MakeIndexNoCheck( x, y, z );
+ return cChunkDef::MakeIndexNoCheck( x, y, z );
}
@@ -196,19 +195,19 @@ void cWorldGenerator::GenerateTerrain(int a_ChunkX, int a_ChunkY, int a_ChunkZ,
const int WATER_LEVEL = 60;
const int SAND_LEVEL = 3;
- memset(a_BlockData, E_BLOCK_AIR, cChunk::c_BlockDataSize);
+ memset(a_BlockData, E_BLOCK_AIR, cChunkDef::BlockDataSize);
cNoise Noise(m_World->GetWorldSeed());
- for (int z = 0; z < cChunk::c_ChunkWidth; z++)
+ for (int z = 0; z < cChunkDef::Width; z++)
{
- const float zz = (float)(a_ChunkZ * cChunk::c_ChunkWidth + z);
- for (int x = 0; x < cChunk::c_ChunkWidth; x++)
+ const float zz = (float)(a_ChunkZ * cChunkDef::Width + z);
+ for (int x = 0; x < cChunkDef::Width; x++)
{
// Place bedrock on bottom layer
a_BlockData[MakeIndex(x, 0, z)] = E_BLOCK_BEDROCK;
- const float xx = (float)(a_ChunkX * cChunk::c_ChunkWidth + x);
+ const float xx = (float)(a_ChunkX * cChunkDef::Width + x);
int Height = (int)(GetNoise( xx * 0.05f, zz * 0.05f, Noise ) * 16);
const int Lower = 64;
@@ -335,9 +334,9 @@ void cWorldGenerator::GenerateOre(char a_OreType, int a_MaxHeight, int a_NumNest
// Only stone gets replaced with ore, all other blocks stay (so the nest can actually be smaller than specified).
for (int i = 0; i < a_NumNests; i++)
{
- int BaseX = r1.randInt(cChunk::c_ChunkWidth);
+ int BaseX = r1.randInt(cChunkDef::Width);
int BaseY = r1.randInt(a_MaxHeight);
- int BaseZ = r1.randInt(cChunk::c_ChunkWidth);
+ int BaseZ = r1.randInt(cChunkDef::Width);
sSetBlockList OreBlocks;
size_t NestSize = (size_t)(a_NestSize + r1.randInt(a_NestSize / 4)); // The actual nest size may be up to 1/4 larger
while (OreBlocks.size() < NestSize)
@@ -378,7 +377,7 @@ void cWorldGenerator::GenerateOre(char a_OreType, int a_MaxHeight, int a_NumNest
// Replace stone with the queued ore blocks:
for (sSetBlockList::iterator itr = OreBlocks.begin(); itr != OreBlocks.end(); ++itr)
{
- if ((itr->x < 0) || (itr->y < 0) || (itr->z < 0) || (itr->x >= cChunk::c_ChunkWidth) || (itr->y >= cChunk::c_ChunkHeight-1) || (itr->z >= cChunk::c_ChunkWidth))
+ if ((itr->x < 0) || (itr->y < 0) || (itr->z < 0) || (itr->x >= cChunkDef::Width) || (itr->y >= cChunkDef::Height-1) || (itr->z >= cChunkDef::Width))
{
continue;
}
@@ -398,24 +397,24 @@ void cWorldGenerator::GenerateOre(char a_OreType, int a_MaxHeight, int a_NumNest
void cWorldGenerator::GenerateFoliage(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
{
- char BlockType[cChunk::c_NumBlocks];
+ char BlockType[cChunkDef::NumBlocks];
- if (!m_World->GetChunkBlocks(a_ChunkX, a_ChunkY, a_ChunkZ, BlockType))
+ if (!m_World->GetChunkBlockTypes(a_ChunkX, a_ChunkY, a_ChunkZ, BlockType))
{
LOGWARNING("Cannot generate foliage on chunk [%d, %d]", a_ChunkX, a_ChunkZ);
return;
}
cNoise Noise(m_World->GetWorldSeed());
- for (int z = 0; z < cChunk::c_ChunkWidth; z++)
+ for (int z = 0; z < cChunkDef::Width; z++)
{
- int zz = z + a_ChunkZ * cChunk::c_ChunkWidth;
- for (int x = 0; x < cChunk::c_ChunkWidth; x++)
+ int zz = z + a_ChunkZ * cChunkDef::Width;
+ for (int x = 0; x < cChunkDef::Width; x++)
{
- int xx = x + a_ChunkX * cChunk::c_ChunkWidth;
+ int xx = x + a_ChunkX * cChunkDef::Width;
int TopY = m_World->GetHeight(xx, zz);
- int index = cChunk::MakeIndexNoCheck(x, MAX(TopY - 1, 0), z);
+ int index = cChunkDef::MakeIndexNoCheck(x, MAX(TopY - 1, 0), z);
if (BlockType[index] == BLOCK_GRASS)
{
float val1 = Noise.CubicNoise2D( xx * 0.1f, zz * 0.1f );
diff --git a/source/cWorldGenerator.h b/source/cWorldGenerator.h
index 3083b37dd..832680e28 100644
--- a/source/cWorldGenerator.h
+++ b/source/cWorldGenerator.h
@@ -5,13 +5,20 @@
-#include "cChunk.h"
+#include "ChunkDef.h"
#include "MersenneTwister.h"
+// fwd:
+class cWorld;
+
+
+
+
+
class cWorldGenerator
{
public:
@@ -29,11 +36,11 @@ protected:
// Thread-unsafe:
MTRand r1;
- void GenerateOre(char a_OreType, int a_MaxHeight, int a_NumNests, int a_NestSize, char * a_BlockData);
+ void GenerateOre(char a_OreType, int a_MaxHeight, int a_NumNests, int a_NestSize, BLOCKTYPE * a_BlockData);
static unsigned int MakeIndex(int x, int y, int z );
- virtual void GenerateTerrain(int a_ChunkX, int a_ChunkY, int a_ChunkZ, char * a_BlockData);
+ virtual void GenerateTerrain(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockData);
virtual void GenerateFoliage(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
diff --git a/source/cWorldGenerator_Test.cpp b/source/cWorldGenerator_Test.cpp
index 37ac9025c..86a7b8388 100644
--- a/source/cWorldGenerator_Test.cpp
+++ b/source/cWorldGenerator_Test.cpp
@@ -2,7 +2,6 @@
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "cWorldGenerator_Test.h"
-#include "cChunk.h"
#include "BlockID.h"
@@ -11,10 +10,10 @@
void cWorldGenerator_Test::GenerateTerrain(int a_ChunkX, int a_ChunkY, int a_ChunkZ, char * a_BlockData)
{
- memset(a_BlockData, E_BLOCK_DIRT, cChunk::c_NumBlocks);
- for(int x = 0; x < cChunk::c_ChunkWidth; x++)
+ memset(a_BlockData, E_BLOCK_DIRT, cChunkDef::NumBlocks);
+ for(int x = 0; x < cChunkDef::Width; x++)
{
- for(int z = 0; z < cChunk::c_ChunkWidth; z++)
+ for(int z = 0; z < cChunkDef::Width; z++)
{
a_BlockData[MakeIndex(x, 0, z)] = E_BLOCK_BEDROCK;
}
diff --git a/source/packets/cPacket_MapChunk.cpp b/source/packets/cPacket_MapChunk.cpp
index 18b924f15..3c94ef012 100644
--- a/source/packets/cPacket_MapChunk.cpp
+++ b/source/packets/cPacket_MapChunk.cpp
@@ -2,7 +2,7 @@
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "cPacket_MapChunk.h"
-#include "../cChunk.h"
+#include "../ChunkDef.h"
#include "zlib.h"
@@ -36,15 +36,15 @@ cPacket_MapChunk::cPacket_MapChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, con
m_UnusedInt = 0;
- const int BlockDataSize = (cChunk::c_ChunkHeight / 16) * (4096 + 2048 + 2048 + 2048);
- const int BiomeDataSize = cChunk::c_ChunkWidth * cChunk::c_ChunkWidth;
+ const int BlockDataSize = (cChunkDef::Height / 16) * (4096 + 2048 + 2048 + 2048);
+ const int BiomeDataSize = cChunkDef::Width * cChunkDef::Width;
char AllData [ BlockDataSize + BiomeDataSize ];
#if AXIS_ORDER == AXIS_ORDER_YZX
memset( AllData, 0, BlockDataSize );
unsigned int iterator = 0;
- for ( int i = 0; i < (cChunk::c_ChunkHeight / 16); ++i )
+ for ( int i = 0; i < (cChunkDef::Height / 16); ++i )
{
m_BitMap1 |= (1 << i); // This tells what chunks are sent. Use this to NOT send air only chunks (right now everything is sent)
for ( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z ) for( int x = 0; x < 16; ++x )
@@ -56,8 +56,8 @@ cPacket_MapChunk::cPacket_MapChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, con
}
// Send block metadata:
- char * Meta = a_BlockData + cChunk::c_NumBlocks;
- for ( int i = 0; i < (cChunk::c_ChunkHeight / 16); ++i )
+ char * Meta = a_BlockData + cChunkDef::NumBlocks;
+ for ( int i = 0; i < (cChunkDef::Height / 16); ++i )
{
for ( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z )
{
@@ -70,8 +70,8 @@ cPacket_MapChunk::cPacket_MapChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, con
}
// Send block light:
- char * Light = Meta + cChunk::c_NumBlocks / 2;
- for ( int i = 0; i < (cChunk::c_ChunkHeight / 16); ++i )
+ char * Light = Meta + cChunkDef::NumBlocks / 2;
+ for ( int i = 0; i < (cChunkDef::Height / 16); ++i )
{
for ( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z )
{
@@ -84,8 +84,8 @@ cPacket_MapChunk::cPacket_MapChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, con
}
// Send sky light:
- char * SkyLight = Light + cChunk::c_NumBlocks / 2;
- for( int i = 0; i < (cChunk::c_ChunkHeight/16); ++i )
+ char * SkyLight = Light + cChunkDef::NumBlocks / 2;
+ for( int i = 0; i < (cChunkDef::Height/16); ++i )
{
for( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z )
{
@@ -115,18 +115,18 @@ cPacket_MapChunk::cPacket_MapChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, con
m_CompressedSize = CompressedSize;
#else
- m_PosX = a_ChunkX * cChunk::c_ChunkWidth; // It has to be block coordinates
- m_PosY = (short)(a_ChunkY * cChunk::c_ChunkHeight);
- m_PosZ = a_ChunkZ * cChunk::c_ChunkWidth;
+ m_PosX = a_ChunkX * cChunkDef::Width; // It has to be block coordinates
+ m_PosY = (short)(a_ChunkY * cChunkDef::Height);
+ m_PosZ = a_ChunkZ * cChunkDef::Width;
m_SizeX = 15;
m_SizeY = 127;
m_SizeZ = 15;
- uLongf CompressedSize = compressBound( cChunk::c_BlockDataSize );
+ uLongf CompressedSize = compressBound( cChunkDef::BlockDataSize );
char * CompressedBlockData = new char[CompressedSize];
- compress2( (Bytef*)CompressedBlockData, &CompressedSize, (const Bytef*)a_BlockData, cChunk::c_BlockDataSize, Z_DEFAULT_COMPRESSION);
+ compress2( (Bytef*)CompressedBlockData, &CompressedSize, (const Bytef*)a_BlockData, cChunkDef::BlockDataSize, Z_DEFAULT_COMPRESSION);
m_CompressedData = CompressedBlockData;
m_CompressedSize = CompressedSize;