summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/BlockArea.cpp8
-rw-r--r--src/Chunk.cpp31
-rw-r--r--src/Chunk.h65
-rw-r--r--src/ChunkData.cpp140
-rw-r--r--src/ChunkData.h12
-rw-r--r--src/ChunkDef.h10
6 files changed, 145 insertions, 121 deletions
diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp
index 5e66e4aec..bd9ba3a9f 100644
--- a/src/BlockArea.cpp
+++ b/src/BlockArea.cpp
@@ -2895,7 +2895,7 @@ void cBlockArea::cChunkReader::ChunkData(const cChunkData & a_BlockBuffer)
{
int InChunkX = BaseX + x;
int AreaX = OffX + x;
- m_Area.m_BlockTypes[m_Area.MakeIndex(AreaX, AreaY, AreaZ)] = a_BlockBuffer.GetBlock(InChunkX, InChunkY, InChunkZ);
+ m_Area.m_BlockTypes[m_Area.MakeIndex(AreaX, AreaY, AreaZ)] = a_BlockBuffer.GetBlock({ InChunkX, InChunkY, InChunkZ });
} // for x
} // for z
} // for y
@@ -2916,7 +2916,7 @@ void cBlockArea::cChunkReader::ChunkData(const cChunkData & a_BlockBuffer)
{
int InChunkX = BaseX + x;
int AreaX = OffX + x;
- m_Area.m_BlockMetas[m_Area.MakeIndex(AreaX, AreaY, AreaZ)] = a_BlockBuffer.GetMeta(InChunkX, InChunkY, InChunkZ);
+ m_Area.m_BlockMetas[m_Area.MakeIndex(AreaX, AreaY, AreaZ)] = a_BlockBuffer.GetMeta({ InChunkX, InChunkY, InChunkZ });
} // for x
} // for z
} // for y
@@ -2937,7 +2937,7 @@ void cBlockArea::cChunkReader::ChunkData(const cChunkData & a_BlockBuffer)
{
int InChunkX = BaseX + x;
int AreaX = OffX + x;
- m_Area.m_BlockLight[m_Area.MakeIndex(AreaX, AreaY, AreaZ)] = a_BlockBuffer.GetBlockLight(InChunkX, InChunkY, InChunkZ);
+ m_Area.m_BlockLight[m_Area.MakeIndex(AreaX, AreaY, AreaZ)] = a_BlockBuffer.GetBlockLight({ InChunkX, InChunkY, InChunkZ });
} // for x
} // for z
} // for y
@@ -2958,7 +2958,7 @@ void cBlockArea::cChunkReader::ChunkData(const cChunkData & a_BlockBuffer)
{
int InChunkX = BaseX + x;
int AreaX = OffX + x;
- m_Area.m_BlockSkyLight[m_Area.MakeIndex(AreaX, AreaY, AreaZ)] = a_BlockBuffer.GetSkyLight(InChunkX, InChunkY, InChunkZ);
+ m_Area.m_BlockSkyLight[m_Area.MakeIndex(AreaX, AreaY, AreaZ)] = a_BlockBuffer.GetSkyLight({ InChunkX, InChunkY, InChunkZ });
} // for x
} // for z
} // for y
diff --git a/src/Chunk.cpp b/src/Chunk.cpp
index 8d88ed3a4..ff3ff7243 100644
--- a/src/Chunk.cpp
+++ b/src/Chunk.cpp
@@ -1659,7 +1659,7 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT
ASSERT(IsValid());
const BLOCKTYPE OldBlockType = GetBlock(a_RelX, a_RelY, a_RelZ);
- const BLOCKTYPE OldBlockMeta = m_ChunkData.GetMeta(a_RelX, a_RelY, a_RelZ);
+ const BLOCKTYPE OldBlockMeta = m_ChunkData.GetMeta({ a_RelX, a_RelY, a_RelZ });
if ((OldBlockType == a_BlockType) && (OldBlockMeta == a_BlockMeta))
{
return;
@@ -1677,7 +1677,7 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT
MarkDirty();
}
- m_ChunkData.SetBlock(a_RelX, a_RelY, a_RelZ, a_BlockType);
+ m_ChunkData.SetBlock({ a_RelX, a_RelY, a_RelZ }, a_BlockType);
// Queue block to be sent only if ...
if (
@@ -1696,7 +1696,7 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT
m_PendingSendBlocks.push_back(sSetBlock(m_PosX, m_PosZ, a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta));
}
- m_ChunkData.SetMeta(a_RelX, a_RelY, a_RelZ, a_BlockMeta);
+ m_ChunkData.SetMeta({ a_RelX, a_RelY, a_RelZ }, a_BlockMeta);
// ONLY recalculate lighting if it's necessary!
if (
@@ -2471,31 +2471,22 @@ bool cChunk::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_
-BLOCKTYPE cChunk::GetBlock(int a_RelX, int a_RelY, int a_RelZ) const
+void cChunk::GetBlockTypeMeta(Vector3i a_RelPos, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const
{
- return m_ChunkData.GetBlock(a_RelX, a_RelY, a_RelZ);
+ a_BlockType = GetBlock(a_RelPos);
+ a_BlockMeta = GetMeta(a_RelPos);
}
-void cChunk::GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const
+void cChunk::GetBlockInfo(Vector3i a_RelPos, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight)
{
- a_BlockType = GetBlock(a_RelX, a_RelY, a_RelZ);
- a_BlockMeta = m_ChunkData.GetMeta(a_RelX, a_RelY, a_RelZ);
-}
-
-
-
-
-
-void cChunk::GetBlockInfo(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight)
-{
- a_BlockType = GetBlock(a_RelX, a_RelY, a_RelZ);
- a_Meta = m_ChunkData.GetMeta(a_RelX, a_RelY, a_RelZ);
- a_SkyLight = m_ChunkData.GetSkyLight(a_RelX, a_RelY, a_RelZ);
- a_BlockLight = m_ChunkData.GetBlockLight(a_RelX, a_RelY, a_RelZ);
+ a_BlockType = GetBlock(a_RelPos);
+ a_Meta = m_ChunkData.GetMeta(a_RelPos);
+ a_SkyLight = m_ChunkData.GetSkyLight(a_RelPos);
+ a_BlockLight = m_ChunkData.GetBlockLight(a_RelPos);
}
diff --git a/src/Chunk.h b/src/Chunk.h
index d6856f911..18b3e9482 100644
--- a/src/Chunk.h
+++ b/src/Chunk.h
@@ -154,7 +154,7 @@ public:
void SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, bool a_SendToClients = true);
// SetBlock() does a lot of work (heightmap, tickblocks, blockentities) so a BlockIdx version doesn't make sense
- void SetBlock( const Vector3i & a_RelBlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { SetBlock( a_RelBlockPos.x, a_RelBlockPos.y, a_RelBlockPos.z, a_BlockType, a_BlockMeta); }
+ void SetBlock(Vector3i a_RelBlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { SetBlock( a_RelBlockPos.x, a_RelBlockPos.y, a_RelBlockPos.z, a_BlockType, a_BlockMeta); }
/** Queues block for ticking (m_ToTickQueue) */
void QueueTickBlock(int a_RelX, int a_RelY, int a_RelZ);
@@ -163,10 +163,25 @@ public:
void QueueTickBlockNeighbors(int a_RelX, int a_RelY, int a_RelZ);
void FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta, bool a_SendToClients = true); // Doesn't force block updates on neighbors, use for simple changes such as grass growing etc.
- BLOCKTYPE GetBlock(int a_RelX, int a_RelY, int a_RelZ) const;
- BLOCKTYPE GetBlock(const Vector3i & a_RelCoords) const { return GetBlock(a_RelCoords.x, a_RelCoords.y, a_RelCoords.z); }
- void GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const;
- void GetBlockInfo (int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight);
+ void FastSetBlock(Vector3i a_RelPos, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta, bool a_SendToClients = true)
+ {
+ FastSetBlock(a_RelPos.x, a_RelPos.y, a_RelPos.z, a_BlockType, a_BlockMeta, a_SendToClients);
+ }
+
+ BLOCKTYPE GetBlock(int a_RelX, int a_RelY, int a_RelZ) const { return m_ChunkData.GetBlock({ a_RelX, a_RelY, a_RelZ }); }
+ BLOCKTYPE GetBlock(Vector3i a_RelCoords) const { return m_ChunkData.GetBlock(a_RelCoords); }
+
+ void GetBlockTypeMeta(Vector3i a_RelPos, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const;
+ void GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const
+ {
+ GetBlockTypeMeta({ a_RelX, a_RelY, a_RelZ }, a_BlockType, a_BlockMeta);
+ }
+
+ void GetBlockInfo(Vector3i a_RelPos, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight);
+ void GetBlockInfo(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight)
+ {
+ GetBlockInfo({ a_RelX, a_RelY, a_RelZ }, a_BlockType, a_Meta, a_SkyLight, a_BlockLight);
+ }
/** Convert absolute coordinates into relative coordinates.
Returns false on failure to obtain a valid chunk. Returns true otherwise.
@@ -392,39 +407,49 @@ public:
inline NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) const
{
- return m_ChunkData.GetMeta(a_RelX, a_RelY, a_RelZ);
+ return m_ChunkData.GetMeta({ a_RelX, a_RelY, a_RelZ });
+ }
+
+ NIBBLETYPE GetMeta(Vector3i a_RelPos) const { return m_ChunkData.GetMeta(a_RelPos); }
+
+ void SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Meta, bool a_ShouldMarkDirty = true, bool a_ShouldInformClients = true)
+ {
+ SetMeta({ a_RelX, a_RelY, a_RelZ }, a_Meta, a_ShouldMarkDirty, a_ShouldInformClients);
}
/** Set a meta value, with the option of not informing the client and / or not marking dirty.
Used for setting metas that are of little value for saving to disk and / or for sending to the client,
such as leaf decay flags. */
- inline void SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Meta, bool a_ShouldMarkDirty = true, bool a_ShouldInformClients = true)
+ inline void SetMeta(Vector3i a_RelPos, NIBBLETYPE a_Meta, bool a_ShouldMarkDirty = true, bool a_ShouldInformClients = true)
{
- bool hasChanged = m_ChunkData.SetMeta(a_RelX, a_RelY, a_RelZ, a_Meta);
- if (hasChanged)
+ bool hasChanged = m_ChunkData.SetMeta(a_RelPos, a_Meta);
+ if (hasChanged)
+ {
+ if (a_ShouldMarkDirty)
+ {
+ MarkDirty();
+ }
+ if (a_ShouldInformClients)
{
- if (a_ShouldMarkDirty)
- {
- MarkDirty();
- }
- if (a_ShouldInformClients)
- {
- m_PendingSendBlocks.push_back(sSetBlock(m_PosX, m_PosZ, a_RelX, a_RelY, a_RelZ, GetBlock(a_RelX, a_RelY, a_RelZ), a_Meta));
- }
+ m_PendingSendBlocks.push_back(sSetBlock(m_PosX, m_PosZ, a_RelPos.x, a_RelPos.y, a_RelPos.z, GetBlock(a_RelPos), a_Meta));
}
+ }
}
/** Light alterations based on time */
NIBBLETYPE GetTimeAlteredLight(NIBBLETYPE a_Skylight) const;
/** Get the level of artificial light illuminating the block (0 - 15) */
- inline NIBBLETYPE GetBlockLight(int a_RelX, int a_RelY, int a_RelZ) const {return m_ChunkData.GetBlockLight(a_RelX, a_RelY, a_RelZ); }
+ inline NIBBLETYPE GetBlockLight(Vector3i a_RelPos) const { return m_ChunkData.GetBlockLight(a_RelPos); }
+ inline NIBBLETYPE GetBlockLight(int a_RelX, int a_RelY, int a_RelZ) const { return m_ChunkData.GetBlockLight({ a_RelX, a_RelY, a_RelZ }); }
/** Get the level of sky light illuminating the block (0 - 15) independent of daytime. */
- inline NIBBLETYPE GetSkyLight (int a_RelX, int a_RelY, int a_RelZ) const {return m_ChunkData.GetSkyLight(a_RelX, a_RelY, a_RelZ); }
+ inline NIBBLETYPE GetSkyLight(Vector3i a_RelPos) const { return m_ChunkData.GetSkyLight(a_RelPos); }
+ inline NIBBLETYPE GetSkyLight(int a_RelX, int a_RelY, int a_RelZ) const { return m_ChunkData.GetSkyLight({ a_RelX, a_RelY, a_RelZ }); }
/** Get the level of sky light illuminating the block (0 - 15), taking daytime into a account. */
- inline NIBBLETYPE GetSkyLightAltered (int a_RelX, int a_RelY, int a_RelZ) const {return GetTimeAlteredLight(m_ChunkData.GetSkyLight(a_RelX, a_RelY, a_RelZ)); }
+ inline NIBBLETYPE GetSkyLightAltered(Vector3i a_RelPos) const { return GetTimeAlteredLight(m_ChunkData.GetSkyLight(a_RelPos)); }
+ inline NIBBLETYPE GetSkyLightAltered(int a_RelX, int a_RelY, int a_RelZ) const { return GetSkyLightAltered({ a_RelX, a_RelY, a_RelZ }); }
/** Same as GetBlock(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case); returns true on success */
bool UnboundedRelGetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const;
diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp
index 310945f17..70e06b032 100644
--- a/src/ChunkData.cpp
+++ b/src/ChunkData.cpp
@@ -10,18 +10,41 @@
-/** Returns true if all a_Array's elements between [0] and [a_NumElements - 1] are equal to a_Value. */
-template <typename T> inline bool IsAllValue(const T * a_Array, size_t a_NumElements, T a_Value)
+namespace
{
- for (size_t i = 0; i < a_NumElements; i++)
+ /** Returns true if all a_Array's elements between [0] and [a_NumElements - 1] are equal to a_Value. */
+ template <typename T>
+ bool IsAllValue(const T * a_Array, size_t a_NumElements, T a_Value)
{
- if (a_Array[i] != a_Value)
+ for (size_t i = 0; i < a_NumElements; i++)
{
- return false;
+ if (a_Array[i] != a_Value)
+ {
+ return false;
+ }
}
+ return true;
}
- return true;
-}
+
+
+
+
+
+ struct sSectionIndices
+ {
+ int Section = 0; // Index into m_Sections
+ int Index = 0; // Index into a single sChunkSection
+ };
+
+ sSectionIndices IndicesFromRelPos(Vector3i a_RelPos)
+ {
+ ASSERT(cChunkDef::IsValidRelPos(a_RelPos));
+ sSectionIndices Ret;
+ Ret.Section = a_RelPos.y / cChunkData::SectionHeight;
+ Ret.Index = cChunkDef::MakeIndexNoCheck(a_RelPos.x, a_RelPos.y % cChunkData::SectionHeight, a_RelPos.z);
+ return Ret;
+ }
+} // namespace (anonymous)
@@ -110,21 +133,16 @@ void cChunkData::Assign(cChunkData && a_Other)
-BLOCKTYPE cChunkData::GetBlock(int a_X, int a_Y, int a_Z) const
+BLOCKTYPE cChunkData::GetBlock(Vector3i a_RelPos) const
{
- if (
- (a_X < 0) || (a_X >= cChunkDef::Width) ||
- (a_Y < 0) || (a_Y >= cChunkDef::Height) ||
- (a_Z < 0) || (a_Z >= cChunkDef::Width)
- )
+ if (!cChunkDef::IsValidRelPos(a_RelPos))
{
return E_BLOCK_AIR; // Coordinates are outside outside the world, so this must be an air block
}
- int Section = a_Y / SectionHeight;
- if (m_Sections[Section] != nullptr)
+ auto Idxs = IndicesFromRelPos(a_RelPos);
+ if (m_Sections[Idxs.Section] != nullptr)
{
- int Index = cChunkDef::MakeIndexNoCheck(a_X, static_cast<int>(static_cast<UInt32>(a_Y) - (static_cast<UInt32>(Section) * SectionHeight)), a_Z);
- return m_Sections[Section]->m_BlockTypes[Index];
+ return m_Sections[Idxs.Section]->m_BlockTypes[Idxs.Index];
}
else
{
@@ -136,53 +154,44 @@ BLOCKTYPE cChunkData::GetBlock(int a_X, int a_Y, int a_Z) const
-void cChunkData::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_Block)
+void cChunkData::SetBlock(Vector3i a_RelPos, BLOCKTYPE a_Block)
{
- if (
- (a_RelX >= cChunkDef::Width) || (a_RelX < 0) ||
- (a_RelY >= cChunkDef::Height) || (a_RelY < 0) ||
- (a_RelZ >= cChunkDef::Width) || (a_RelZ < 0)
- )
+ if (!cChunkDef::IsValidRelPos(a_RelPos))
{
ASSERT(!"cChunkData::SetMeta(): index out of range!");
return;
}
- int Section = static_cast<int>(static_cast<UInt32>(a_RelY) / SectionHeight);
- if (m_Sections[Section] == nullptr)
+ auto Idxs = IndicesFromRelPos(a_RelPos);
+ if (m_Sections[Idxs.Section] == nullptr)
{
if (a_Block == 0x00)
{
return;
}
- m_Sections[Section] = Allocate();
- if (m_Sections[Section] == nullptr)
+ m_Sections[Idxs.Section] = Allocate();
+ if (m_Sections[Idxs.Section] == nullptr)
{
ASSERT(!"Failed to allocate a new section in Chunkbuffer");
return;
}
- ZeroSection(m_Sections[Section]);
+ ZeroSection(m_Sections[Idxs.Section]);
}
- int Index = cChunkDef::MakeIndexNoCheck(a_RelX, static_cast<int>(static_cast<UInt32>(a_RelY) - (static_cast<UInt32>(Section) * SectionHeight)), a_RelZ);
- m_Sections[Section]->m_BlockTypes[Index] = a_Block;
+ m_Sections[Idxs.Section]->m_BlockTypes[Idxs.Index] = a_Block;
}
-NIBBLETYPE cChunkData::GetMeta(int a_RelX, int a_RelY, int a_RelZ) const
+NIBBLETYPE cChunkData::GetMeta(Vector3i a_RelPos) const
{
- if (
- (a_RelX < cChunkDef::Width) && (a_RelX > -1) &&
- (a_RelY < cChunkDef::Height) && (a_RelY > -1) &&
- (a_RelZ < cChunkDef::Width) && (a_RelZ > -1))
+ if (cChunkDef::IsValidRelPos(a_RelPos))
{
- int Section = static_cast<int>(static_cast<UInt32>(a_RelY) / SectionHeight);
- if (m_Sections[Section] != nullptr)
+ auto Idxs = IndicesFromRelPos(a_RelPos);
+ if (m_Sections[Idxs.Section] != nullptr)
{
- int Index = cChunkDef::MakeIndexNoCheck(a_RelX, static_cast<int>(static_cast<UInt32>(a_RelY) - (static_cast<UInt32>(Section) * SectionHeight)), a_RelZ);
- return (m_Sections[Section]->m_BlockMetas[Index / 2] >> ((Index & 1) * 4)) & 0x0f;
+ return (m_Sections[Idxs.Section]->m_BlockMetas[Idxs.Index / 2] >> ((Idxs.Index & 1) * 4)) & 0x0f;
}
else
{
@@ -197,38 +206,33 @@ NIBBLETYPE cChunkData::GetMeta(int a_RelX, int a_RelY, int a_RelZ) const
-bool cChunkData::SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Nibble)
+bool cChunkData::SetMeta(Vector3i a_RelPos, NIBBLETYPE a_Nibble)
{
- if (
- (a_RelX >= cChunkDef::Width) || (a_RelX < 0) ||
- (a_RelY >= cChunkDef::Height) || (a_RelY < 0) ||
- (a_RelZ >= cChunkDef::Width) || (a_RelZ < 0)
- )
+ if (!cChunkDef::IsValidRelPos(a_RelPos))
{
ASSERT(!"cChunkData::SetMeta(): index out of range!");
return false;
}
- int Section = static_cast<int>(static_cast<UInt32>(a_RelY) / SectionHeight);
- if (m_Sections[Section] == nullptr)
+ auto Idxs = IndicesFromRelPos(a_RelPos);
+ if (m_Sections[Idxs.Section] == nullptr)
{
if ((a_Nibble & 0xf) == 0x00)
{
return false;
}
- m_Sections[Section] = Allocate();
- if (m_Sections[Section] == nullptr)
+ m_Sections[Idxs.Section] = Allocate();
+ if (m_Sections[Idxs.Section] == nullptr)
{
ASSERT(!"Failed to allocate a new section in Chunkbuffer");
return false;
}
- ZeroSection(m_Sections[Section]);
+ ZeroSection(m_Sections[Idxs.Section]);
}
- int Index = cChunkDef::MakeIndexNoCheck(a_RelX, static_cast<int>(static_cast<UInt32>(a_RelY) - (static_cast<UInt32>(Section) * SectionHeight)), a_RelZ);
- NIBBLETYPE oldval = m_Sections[Section]->m_BlockMetas[Index / 2] >> ((Index & 1) * 4) & 0xf;
- m_Sections[Section]->m_BlockMetas[Index / 2] = static_cast<NIBBLETYPE>(
- (m_Sections[Section]->m_BlockMetas[Index / 2] & (0xf0 >> ((Index & 1) * 4))) | // The untouched nibble
- ((a_Nibble & 0x0f) << ((Index & 1) * 4)) // The nibble being set
+ NIBBLETYPE oldval = m_Sections[Idxs.Section]->m_BlockMetas[Idxs.Index / 2] >> ((Idxs.Index & 1) * 4) & 0xf;
+ m_Sections[Idxs.Section]->m_BlockMetas[Idxs.Index / 2] = static_cast<NIBBLETYPE>(
+ (m_Sections[Idxs.Section]->m_BlockMetas[Idxs.Index / 2] & (0xf0 >> ((Idxs.Index & 1) * 4))) | // The untouched nibble
+ ((a_Nibble & 0x0f) << ((Idxs.Index & 1) * 4)) // The nibble being set
);
return oldval != a_Nibble;
}
@@ -237,19 +241,14 @@ bool cChunkData::SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Nibble
-NIBBLETYPE cChunkData::GetBlockLight(int a_RelX, int a_RelY, int a_RelZ) const
+NIBBLETYPE cChunkData::GetBlockLight(Vector3i a_RelPos) const
{
- if (
- (a_RelX < cChunkDef::Width) && (a_RelX > -1) &&
- (a_RelY < cChunkDef::Height) && (a_RelY > -1) &&
- (a_RelZ < cChunkDef::Width) && (a_RelZ > -1)
- )
+ if (cChunkDef::IsValidRelPos(a_RelPos))
{
- int Section = static_cast<int>(static_cast<UInt32>(a_RelY) / SectionHeight);
- if (m_Sections[Section] != nullptr)
+ auto Idxs = IndicesFromRelPos(a_RelPos);
+ if (m_Sections[Idxs.Section] != nullptr)
{
- int Index = cChunkDef::MakeIndexNoCheck(a_RelX, static_cast<int>(static_cast<UInt32>(a_RelY) - (static_cast<UInt32>(Section) * SectionHeight)), a_RelZ);
- return (m_Sections[Section]->m_BlockLight[Index / 2] >> ((Index & 1) * 4)) & 0x0f;
+ return (m_Sections[Idxs.Section]->m_BlockLight[Idxs.Index / 2] >> ((Idxs.Index & 1) * 4)) & 0x0f;
}
else
{
@@ -264,15 +263,14 @@ NIBBLETYPE cChunkData::GetBlockLight(int a_RelX, int a_RelY, int a_RelZ) const
-NIBBLETYPE cChunkData::GetSkyLight(int a_RelX, int a_RelY, int a_RelZ) const
+NIBBLETYPE cChunkData::GetSkyLight(Vector3i a_RelPos) const
{
- if ((a_RelX < cChunkDef::Width) && (a_RelX > -1) && (a_RelY < cChunkDef::Height) && (a_RelY > -1) && (a_RelZ < cChunkDef::Width) && (a_RelZ > -1))
+ if (cChunkDef::IsValidRelPos(a_RelPos))
{
- int Section = static_cast<int>(static_cast<UInt32>(a_RelY) / SectionHeight);
- if (m_Sections[Section] != nullptr)
+ auto Idxs = IndicesFromRelPos(a_RelPos);
+ if (m_Sections[Idxs.Section] != nullptr)
{
- int Index = cChunkDef::MakeIndexNoCheck(a_RelX, static_cast<int>(static_cast<UInt32>(a_RelY) - (static_cast<UInt32>(Section) * SectionHeight)), a_RelZ);
- return (m_Sections[Section]->m_BlockSkyLight[Index / 2] >> ((Index & 1) * 4)) & 0x0f;
+ return (m_Sections[Idxs.Section]->m_BlockSkyLight[Idxs.Index / 2] >> ((Idxs.Index & 1) * 4)) & 0x0f;
}
else
{
diff --git a/src/ChunkData.h b/src/ChunkData.h
index 6bc2b5366..95a38b194 100644
--- a/src/ChunkData.h
+++ b/src/ChunkData.h
@@ -48,15 +48,15 @@ public:
/** Move assign from another cChunkData */
void Assign(cChunkData && a_Other);
- BLOCKTYPE GetBlock(int a_X, int a_Y, int a_Z) const;
- void SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_Block);
+ BLOCKTYPE GetBlock(Vector3i a_RelPos) const;
+ void SetBlock(Vector3i a_RelPos, BLOCKTYPE a_Block);
- NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) const;
- bool SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Nibble);
+ NIBBLETYPE GetMeta(Vector3i a_RelPos) const;
+ bool SetMeta(Vector3i a_RelPos, NIBBLETYPE a_Nibble);
- NIBBLETYPE GetBlockLight(int a_RelX, int a_RelY, int a_RelZ) const;
+ NIBBLETYPE GetBlockLight(Vector3i a_RelPos) const;
- NIBBLETYPE GetSkyLight(int a_RelX, int a_RelY, int a_RelZ) const;
+ NIBBLETYPE GetSkyLight(Vector3i a_RelPos) const;
/** Return a pointer to the chunk section or nullptr if all air */
const sChunkSection * GetSection(size_t a_SectionNum) const;
diff --git a/src/ChunkDef.h b/src/ChunkDef.h
index 188ad33d8..bdba4061f 100644
--- a/src/ChunkDef.h
+++ b/src/ChunkDef.h
@@ -144,6 +144,16 @@ public:
return ((a_Width >= 0) && (a_Width < Width));
}
+ /** Validates a chunk relative coordinate. Returns false if the coordiante is out of bounds for a chunk. */
+ inline static bool IsValidRelPos(Vector3i a_RelPos)
+ {
+ return (
+ IsValidWidth(a_RelPos.x) &&
+ IsValidHeight(a_RelPos.y) &&
+ IsValidWidth(a_RelPos.z)
+ );
+ }
+
/** Converts absolute block coords to chunk coords: */
inline static void BlockToChunk(int a_X, int a_Z, int & a_ChunkX, int & a_ChunkZ)
{