17 #define AXIS_ORDER_YZX 1 // Original (1.1-) 18 #define AXIS_ORDER_XZY 2 // New (1.2+) 19 #define AXIS_ORDER AXIS_ORDER_XZY 62 cChunkCoords(
int a_ChunkX,
int a_ChunkZ) : m_ChunkX(a_ChunkX), m_ChunkZ(a_ChunkZ) {}
82 return (m_ChunkZ < a_Other.
m_ChunkZ);
86 return (m_ChunkX < a_Other.
m_ChunkX);
94 return Printf(
"[%d, %d]", m_ChunkX, m_ChunkZ);
110 m_Begin(a_Container.cbegin()),
111 m_End(a_Container.cend())
134 static const int Width = 16;
135 static const int Height = 256;
136 static const int NumBlocks = Width * Height * Width;
163 inline static void AbsoluteToRelative(
int & a_X,
int & a_Y,
int & a_Z,
int & a_ChunkX,
int & a_ChunkZ)
166 BlockToChunk(a_X, a_Z, a_ChunkX, a_ChunkZ);
168 a_X = a_X - a_ChunkX * Width;
169 a_Z = a_Z - a_ChunkZ * Width;
181 return AbsoluteToRelative(a_BlockPosition, chunkPos);
191 return {a_BlockPosition.
x - a_ChunkPos.
m_ChunkX * Width, a_BlockPosition.
y, a_BlockPosition.
z - a_ChunkPos.
m_ChunkZ * Width};
201 a_RelBlockPosition.
x + a_ChunkCoords.
m_ChunkX * Width,
202 a_RelBlockPosition.
y,
203 a_RelBlockPosition.
z + a_ChunkCoords.
m_ChunkZ * Width
214 return ((a_Height >= 0) && (a_Height < Height));
220 return ((a_Width >= 0) && (a_Width < Width));
227 IsValidWidth(a_RelPos.
x) &&
228 IsValidHeight(a_RelPos.
y) &&
229 IsValidWidth(a_RelPos.
z)
234 inline static void BlockToChunk(
int a_X,
int a_Z,
int & a_ChunkX,
int & a_ChunkZ)
238 auto ChunkCoords = BlockToChunk({a_X, 0, a_Z});
239 a_ChunkX = ChunkCoords.m_ChunkX;
240 a_ChunkZ = ChunkCoords.m_ChunkZ;
247 if ((a_Pos.
x < 0) && (a_Pos.
x % Width != 0))
251 if ((a_Pos.
z < 0) && (a_Pos.
z % Width != 0))
262 (x < Width) && (x > -1) &&
263 (y < Height) && (y > -1) &&
264 (z < Width) && (z > -1)
267 return MakeIndexNoCheck(x, y, z);
269 FLOGERROR(
"cChunkDef::MakeIndex(): coords out of range: {0}; returning fake index 0",
Vector3i{x, y, z});
270 ASSERT(!
"cChunkDef::MakeIndex(): coords out of chunk range!");
277 #if AXIS_ORDER == AXIS_ORDER_XZY 280 #elif AXIS_ORDER == AXIS_ORDER_YZX 289 return MakeIndexNoCheck(a_RelPos.
x, a_RelPos.
y, a_RelPos.
z);
296 #if AXIS_ORDER == AXIS_ORDER_XZY 299 static_cast<int>(index / (cChunkDef::Width * cChunkDef::Width)),
300 static_cast<int>((index / cChunkDef::Width) % cChunkDef::Width)
302 #elif AXIS_ORDER == AXIS_ORDER_YZX 306 static_cast<int>((index / cChunkDef::Height) % cChunkDef::Width)
314 ASSERT((a_X >= 0) && (a_X < Width));
315 ASSERT((a_Y >= 0) && (a_Y < Height));
316 ASSERT((a_Z >= 0) && (a_Z < Width));
317 a_BlockTypes[MakeIndexNoCheck(a_X, a_Y, a_Z)] = a_Type;
323 ASSERT((a_Index >= 0) && (a_Index <= NumBlocks));
324 a_BlockTypes[a_Index] = a_Type;
330 ASSERT(IsValidRelPos(a_RelPos));
331 return a_BlockTypes[MakeIndexNoCheck(a_RelPos)];
337 ASSERT((a_X >= 0) && (a_X < Width));
338 ASSERT((a_Y >= 0) && (a_Y < Height));
339 ASSERT((a_Z >= 0) && (a_Z < Width));
340 return a_BlockTypes[MakeIndexNoCheck(a_X, a_Y, a_Z)];
346 ASSERT((a_Idx >= 0) && (a_Idx < NumBlocks));
347 return a_BlockTypes[a_Idx];
353 ASSERT((a_X >= 0) && (a_X < Width));
354 ASSERT((a_Z >= 0) && (a_Z < Width));
355 return a_HeightMap[a_X + Width * a_Z];
361 ASSERT((a_X >= 0) && (a_X < Width));
362 ASSERT((a_Z >= 0) && (a_Z < Width));
363 a_HeightMap[a_X + Width * a_Z] = a_Height;
369 ASSERT((a_X >= 0) && (a_X < Width));
370 ASSERT((a_Z >= 0) && (a_Z < Width));
371 return a_BiomeMap[a_X + Width * a_Z];
377 ASSERT((a_X >= 0) && (a_X < Width));
378 ASSERT((a_Z >= 0) && (a_Z < Width));
379 a_BiomeMap[a_X + Width * a_Z] = a_Biome;
383 static NIBBLETYPE GetNibble(
const COMPRESSED_NIBBLETYPE & a_Buffer,
int a_BlockIdx,
bool a_IsSkyLightNibble =
false)
385 if ((a_BlockIdx > -1) && (a_BlockIdx < NumBlocks))
387 if (static_cast<size_t>(a_BlockIdx / 2) >= a_Buffer.size())
389 return (a_IsSkyLightNibble ? 0xff : 0);
391 return (a_Buffer[static_cast<size_t>(a_BlockIdx / 2)] >> ((a_BlockIdx & 1) * 4)) & 0x0f;
393 ASSERT(!
"cChunkDef::GetNibble(): index out of chunk range!");
398 static NIBBLETYPE GetNibble(
const COMPRESSED_NIBBLETYPE & a_Buffer,
int x,
int y,
int z,
bool a_IsSkyLightNibble =
false)
400 if ((x < Width) && (x > -1) && (y < Height) && (y > -1) && (z < Width) && (z > -1))
402 size_t Index =
static_cast<size_t>(MakeIndexNoCheck(x, y, z));
403 if ((Index / 2) >= a_Buffer.size())
405 return (a_IsSkyLightNibble ? 0xff : 0);
407 return ExpandNibble(a_Buffer, Index);
409 ASSERT(!
"cChunkDef::GetNibble(): coords out of chunk range!");
416 if (IsValidRelPos(a_RelPos))
418 auto Index = MakeIndexNoCheck(a_RelPos);
419 return (a_Buffer[static_cast<size_t>(Index / 2)] >> ((Index & 1) * 4)) & 0x0f;
421 ASSERT(!
"Coords out of chunk range!");
428 if ((x < Width) && (x > -1) && (y < Height) && (y > -1) && (z < Width) && (z > -1))
430 int Index = MakeIndexNoCheck(x, y, z);
431 return (a_Buffer[static_cast<size_t>(Index / 2)] >> ((Index & 1) * 4)) & 0x0f;
433 ASSERT(!
"cChunkDef::GetNibble(): coords out of chunk range!");
440 if ((a_BlockIdx < 0) || (a_BlockIdx >= NumBlocks))
442 ASSERT(!
"cChunkDef::SetNibble(): index out of range!");
445 if (static_cast<size_t>(a_BlockIdx / 2) >= a_Buffer.size())
447 a_Buffer.resize(static_cast<size_t>((a_BlockIdx / 2) + 1));
449 a_Buffer[
static_cast<size_t>(a_BlockIdx / 2)] = PackNibble(a_Buffer, static_cast<size_t>(a_BlockIdx), a_Nibble);
456 (x >= Width) || (x < 0) ||
457 (y >= Height) || (y < 0) ||
458 (z >= Width) || (z < 0)
461 ASSERT(!
"cChunkDef::SetNibble(): index out of range!");
465 size_t Index =
static_cast<size_t>(MakeIndexNoCheck(x, y, z));
466 if ((Index / 2) >= a_Buffer.size())
468 a_Buffer.resize(((Index / 2) + 1));
470 a_Buffer[(Index / 2)] = PackNibble(a_Buffer, Index, a_Nibble);
480 (a_Buffer[a_Index / 2] & (0xf0 >> ((a_Index & 1) * 4))) |
481 ((a_Nibble & 0x0f) << ((a_Index & 1) * 4))
488 return (a_Buffer[a_Index / 2] >> ((a_Index & 1) * 4)) & 0x0f;
528 m_BlockType(a_BlockType),
529 m_BlockMeta(a_BlockMeta)
535 sSetBlock(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, a_BlockType, a_BlockMeta)
540 m_RelX(a_RelX), m_RelY(a_RelY), m_RelZ(a_RelZ),
541 m_ChunkX(a_ChunkX), m_ChunkZ(a_ChunkZ),
542 m_BlockType(a_BlockType),
543 m_BlockMeta(a_BlockMeta)
554 int GetY(
void)
const {
return m_RelY; }
580 return (static_cast<size_t>(a_Coords.
m_ChunkX) << 16) ^
static_cast<size_t>(a_Coords.
m_ChunkZ);
595 cChunkCoordsWithBool(
int a_ChunkX,
int a_ChunkZ,
bool a_ForceGenerate) : m_ChunkX(a_ChunkX), m_ChunkZ(a_ChunkZ), m_ForceGenerate(a_ForceGenerate){}
617 virtual void Call(
cChunkCoords a_Coords,
bool a_IsSuccess) = 0;
632 m_Callback(a_Callback)
655 x(a_X), y(a_Y), z(a_Z), Data()
660 x(a_X), y(a_Y), z(a_Z), Data(a_Data)
std::map< size_t, cBlockEntity * > cBlockEntities
cCoordWithData(int a_X, int a_Y, int a_Z)
Generic template that can store any kind of data together with a triplet of 3 coords.
unsigned char BLOCKTYPE
The datatype used by blockdata.
int GetY(void) const
Returns the absolute Y coord of the stored block.
static bool IsValidRelPos(Vector3i a_RelPos)
Validates a chunk relative coordinate.
static void SetBlock(BLOCKTYPE *a_BlockTypes, int a_X, int a_Y, int a_Z, BLOCKTYPE a_Type)
std::list< cChunkCoordsWithBool > cChunkCoordsWithBoolList
Provides storage for a set of chunk coords together with a callback.
cCoordWithData< BLOCKTYPE > cCoordWithBlock
static const int NumBlocks
static bool IsValidHeight(int a_Height)
Validates a height-coordinate.
static HEIGHTTYPE GetHeight(const HeightMap &a_HeightMap, int a_X, int a_Z)
static int MakeIndex(int x, int y, int z)
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
Constants used throughout the code, useful typedefs and utility functions.
static void SetNibble(COMPRESSED_NIBBLETYPE &a_Buffer, int a_BlockIdx, NIBBLETYPE a_Nibble)
EMCSBiome
Biome IDs The first batch corresponds to the clientside biomes, used by MineCraft.
int GetZ(void) const
Returns the absolute Z coord of the stored block.
static BLOCKTYPE GetBlock(const BLOCKTYPE *a_BlockTypes, Vector3i a_RelPos)
unsigned char HEIGHTTYPE
The type used by the heightmap.
Vector3i GetPos(void) const
Returns the absolute position of the stored block.
cChunkClientHandles(const std::vector< cClientHandle * > &a_Container)
static int MakeIndexNoCheck(int x, int y, int z)
static NIBBLETYPE ExpandNibble(const COMPRESSED_NIBBLETYPE &a_Buffer, size_t a_Index)
sSetBlock(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
static NIBBLETYPE GetNibble(const NIBBLETYPE *a_Buffer, Vector3i a_RelPos)
void FLOGERROR(const char *a_Format, fmt::ArgList a_ArgList)
static void BlockToChunk(int a_X, int a_Z, int &a_ChunkX, int &a_ChunkZ)
Converts absolute block coords to chunk coords:
cChunkCoords(int a_ChunkX, int a_ChunkZ)
std::vector< OwnedEntity > cEntityList
std::vector< cClientHandle * >::const_iterator const_iterator
static Vector3i AbsoluteToRelative(Vector3i a_BlockPosition, cChunkCoords a_ChunkPos)
Converts the absolute coords into coords relative to the specified chunk.
int GetX(void) const
Returns the absolute X coord of the stored block.
std::vector< NIBBLETYPE > COMPRESSED_NIBBLETYPE
The storage wrapper used for compressed nibbledata residing in RAMz.
sSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Interface class used for comparing clients of two chunks.
virtual ~cClientDiffCallback()
static NIBBLETYPE GetNibble(const NIBBLETYPE *a_Buffer, int x, int y, int z)
static void AbsoluteToRelative(int &a_X, int &a_Y, int &a_Z, int &a_ChunkX, int &a_ChunkZ)
Converts absolute block coords into relative (chunk + block) coords:
const_iterator cbegin() const
static void SetBiome(BiomeMap &a_BiomeMap, int a_X, int a_Z, EMCSBiome a_Biome)
AString & Printf(AString &str, const char *format, fmt::ArgList args)
Output the formatted text into the string.
static NIBBLETYPE PackNibble(const COMPRESSED_NIBBLETYPE &a_Buffer, size_t a_Index, NIBBLETYPE a_Nibble)
std::list< sSetBlock > sSetBlockList
std::vector< BLOCKTYPE > COMPRESSED_BLOCKTYPE
The storage wrapper used for compressed blockdata residing in RAMz.
std::list< cCoordWithInt > cCoordWithIntList
static void SetBlock(BLOCKTYPE *a_BlockTypes, int a_Index, BLOCKTYPE a_Type)
static Vector3i RelativeToAbsolute(Vector3i a_RelBlockPosition, cChunkCoords a_ChunkCoords)
Converts relative block coordinates into absolute coordinates with a known chunk location.
static NIBBLETYPE GetNibble(const COMPRESSED_NIBBLETYPE &a_Buffer, int a_BlockIdx, bool a_IsSkyLightNibble=false)
const_iterator begin() const
const_iterator cend() const
bool operator<(const cChunkCoords &a_Other) const
Simple comparison, to support ordering.
static void SetHeight(HeightMap &a_HeightMap, int a_X, int a_Z, HEIGHTTYPE a_Height)
A simple hash function for chunk coords, we assume that chunk coords won't use more than 16 bits...
std::vector< cCoordWithInt > cCoordWithIntVector
bool operator==(const cChunkCoords &a_Other) const
Interface class used as a callback for operations that involve chunk coords.
const_iterator end() const
static BLOCKTYPE GetBlock(const BLOCKTYPE *a_BlockTypes, int a_Idx)
bool operator!=(const cChunkCoords &a_Other) const
std::vector< cChunkCoords > cChunkCoordsVector
static BLOCKTYPE GetBlock(const BLOCKTYPE *a_BlockTypes, int a_X, int a_Y, int a_Z)
AString ToString() const
Returns a string that describes the chunk coords, suitable for logging.
std::unique_ptr< cEntity > OwnedEntity
sSetBlock(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
cChunkCoordsWithBool(int a_ChunkX, int a_ChunkZ, bool a_ForceGenerate)
cCoordWithData(int a_X, int a_Y, int a_Z, const X &a_Data)
static bool IsValidWidth(int a_Width)
Validates a width-coordinate.
std::list< cChunkCoords > cChunkCoordsList
static int MakeIndexNoCheck(Vector3i a_RelPos)
static NIBBLETYPE GetNibble(const COMPRESSED_NIBBLETYPE &a_Buffer, int x, int y, int z, bool a_IsSkyLightNibble=false)
static cChunkCoords BlockToChunk(Vector3i a_Pos)
The Y coordinate of a_Pos is ignored.
cChunkCoordCallback * m_Callback
static void SetNibble(COMPRESSED_NIBBLETYPE &a_Buffer, int x, int y, int z, NIBBLETYPE a_Nibble)
cChunkCoordsWithCallback(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback *a_Callback)
cCoordWithData< int > cCoordWithInt
std::vector< sSetBlock > sSetBlockVector
static Vector3i IndexToCoordinate(size_t index)
static Vector3i AbsoluteToRelative(Vector3i a_BlockPosition)
Converts the specified absolute position into a relative position within its chunk.
static EMCSBiome GetBiome(const BiomeMap &a_BiomeMap, int a_X, int a_Z)
virtual ~cChunkCoordCallback()
Non-owning view of a chunk's client handles.