Split chunk data into separate arrays; decoupled most sources from cChunk.h dependency

git-svn-id: http://mc-server.googlecode.com/svn/trunk@411 0a769ca7-a7f5-676a-18bf-c427514a06d6
master
madmaxoft@gmail.com 2012-03-14 20:56:09 +00:00
parent 393e34d571
commit 0b24efeb00
34 changed files with 802 additions and 588 deletions

View File

@ -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"
@ -289,6 +292,10 @@
RelativePath="..\source\cHeartBeat.h"
>
</File>
<File
RelativePath="..\source\ChunkDef.h"
>
</File>
<File
RelativePath="..\source\ChunkSender.cpp"
>

320
source/ChunkDef.h Normal file
View File

@ -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;

View File

@ -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();

View File

@ -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);

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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;
} ;

View File

@ -9,7 +9,6 @@
#include "cWorld.h"
#include "cRoot.h"
#include "cPickup.h"
#include "cChunk.h"
#include <json/json.h>

View File

@ -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 );
}

View File

@ -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);
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_Blocks, only the block types
void GetBlocks(char * a_Blocks);
/// Copies m_BlockData into a_BlockTypes, only the block types
void GetBlockTypes(BLOCKTYPE * a_BlockTypes);
/// Copies m_BlockData into a_Blocks, the entire array
void GetBlockData(char * a_BlockData);
/// 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; }
/*
BLOCKTYPE * GetBlockTypes (void) { return m_BlockTypes; }
BLOCKTYPE * GetBlockMeta (void) { return m_BlockMeta; }
BLOCKTYPE * GetBlockLight (void) { return m_BlockLight; }
BLOCKTYPE * GetBlockSkyLight(void) { return m_BlockSkyLight; }
*/
void CopyBlockDataFrom(const char * a_NewBlockData); // Copies all blockdata, recalculates heightmap (used by chunk loaders)
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

View File

@ -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();
}

View File

@ -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);
}

View File

@ -17,7 +17,7 @@
#pragma once
#include "cIsThread.h"
#include "cChunk.h"
#include "ChunkDef.h"

View File

@ -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())
{

View File

@ -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);
bool GetChunkBlockTypes (int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_Blocks);
/// 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 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);
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 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:

View File

@ -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);

View File

@ -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"

View File

@ -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
);

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -6,7 +6,6 @@
#include "cPlayer.h"
#include "cClientHandle.h"
#include "cWorld.h"
#include "cChunk.h"
#include "cRoot.h"
#include "packets/cPacket_UpdateSign.h"

View File

@ -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);
}

View File

@ -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

View File

@ -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 );

View File

@ -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);

View File

@ -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;
}

View File

@ -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;