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-c427514a06d6master
parent
393e34d571
commit
0b24efeb00
|
@ -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"
|
||||
>
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
} ;
|
||||
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "cWorld.h"
|
||||
#include "cRoot.h"
|
||||
#include "cPickup.h"
|
||||
#include "cChunk.h"
|
||||
#include <json/json.h>
|
||||
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
|
211
source/cChunk.h
211
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);
|
||||
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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "cIsThread.h"
|
||||
#include "cChunk.h"
|
||||
#include "ChunkDef.h"
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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())
|
||||
{
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include "cPlayer.h"
|
||||
#include "cClientHandle.h"
|
||||
#include "cWorld.h"
|
||||
#include "cChunk.h"
|
||||
#include "cRoot.h"
|
||||
|
||||
#include "packets/cPacket_UpdateSign.h"
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue