summaryrefslogtreecommitdiffstats
path: root/src/Chunk.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/Chunk.cpp159
1 files changed, 70 insertions, 89 deletions
diff --git a/src/Chunk.cpp b/src/Chunk.cpp
index f43b5b4bb..03415b348 100644
--- a/src/Chunk.cpp
+++ b/src/Chunk.cpp
@@ -322,26 +322,15 @@ void cChunk::SetAllData(cSetChunkData & a_SetChunkData)
memcpy(m_BiomeMap, a_SetChunkData.GetBiomes(), sizeof(m_BiomeMap));
memcpy(m_HeightMap, a_SetChunkData.GetHeightMap(), sizeof(m_HeightMap));
- m_ChunkData.SetBlockTypes(a_SetChunkData.GetBlockTypes());
- m_ChunkData.SetMetas(a_SetChunkData.GetBlockMetas());
- if (a_SetChunkData.IsLightValid())
- {
- m_ChunkData.SetBlockLight(a_SetChunkData.GetBlockLight());
- m_ChunkData.SetSkyLight(a_SetChunkData.GetSkyLight());
- m_IsLightValid = true;
- }
- else
- {
- m_IsLightValid = false;
- }
+ m_ChunkData.Assign(std::move(a_SetChunkData.GetChunkData()));
+ m_IsLightValid = a_SetChunkData.IsLightValid();
// Clear the block entities present - either the loader / saver has better, or we'll create empty ones:
for (auto & KeyPair : m_BlockEntities)
{
delete KeyPair.second;
}
- m_BlockEntities.clear();
- std::swap(a_SetChunkData.GetBlockEntities(), m_BlockEntities);
+ m_BlockEntities = std::move(a_SetChunkData.GetBlockEntities());
// Check that all block entities have a valid blocktype at their respective coords (DEBUG-mode only):
#ifdef _DEBUG
@@ -504,9 +493,9 @@ void cChunk::WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlock
-bool cChunk::HasBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ)
+bool cChunk::HasBlockEntityAt(Vector3i a_BlockPos)
{
- return (GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ) != nullptr);
+ return (GetBlockEntity(a_BlockPos) != nullptr);
}
@@ -1433,48 +1422,32 @@ int cChunk::GetHeight(int a_X, int a_Z)
void cChunk::CreateBlockEntities(void)
{
- for (int x = 0; x < Width; x++)
+ for (size_t SectionIdx = 0; SectionIdx != cChunkData::NumSections; ++SectionIdx)
{
- for (int z = 0; z < Width; z++)
+ const auto * Section = m_ChunkData.GetSection(SectionIdx);
+ if (Section == nullptr)
{
- for (int y = 0; y < Height; y++)
+ continue;
+ }
+
+ for (size_t BlockIdx = 0; BlockIdx != cChunkData::SectionBlockCount; ++BlockIdx)
+ {
+ auto BlockType = Section->m_BlockTypes[BlockIdx];
+ if (cBlockEntity::IsBlockEntityBlockType(BlockType))
{
- BLOCKTYPE BlockType = GetBlock(x, y, z);
- switch (BlockType)
+ auto RelPos = IndexToCoordinate(BlockIdx);
+ RelPos.y += SectionIdx * cChunkData::SectionHeight;
+ auto WorldPos = RelativeToAbsolute(RelPos, m_PosX, m_PosZ);
+
+ if (!HasBlockEntityAt(WorldPos))
{
- case E_BLOCK_BEACON:
- case E_BLOCK_BED:
- case E_BLOCK_TRAPPED_CHEST:
- case E_BLOCK_CHEST:
- case E_BLOCK_COMMAND_BLOCK:
- case E_BLOCK_DISPENSER:
- case E_BLOCK_DROPPER:
- case E_BLOCK_ENDER_CHEST:
- case E_BLOCK_LIT_FURNACE:
- case E_BLOCK_FURNACE:
- case E_BLOCK_HOPPER:
- case E_BLOCK_SIGN_POST:
- case E_BLOCK_WALLSIGN:
- case E_BLOCK_HEAD:
- case E_BLOCK_NOTE_BLOCK:
- case E_BLOCK_JUKEBOX:
- case E_BLOCK_FLOWER_POT:
- case E_BLOCK_MOB_SPAWNER:
- case E_BLOCK_BREWING_STAND:
- {
- if (!HasBlockEntityAt(x + m_PosX * Width, y, z + m_PosZ * Width))
- {
- AddBlockEntityClean(cBlockEntity::CreateByBlockType(
- BlockType, GetMeta(x, y, z),
- x + m_PosX * Width, y, z + m_PosZ * Width, m_World
- ));
- }
- break;
- }
- } // switch (BlockType)
- } // for y
- } // for z
- } // for x
+ AddBlockEntityClean(cBlockEntity::CreateByBlockType(
+ BlockType, GetMeta(RelPos), WorldPos.x, WorldPos.y, WorldPos.z, m_World
+ ));
+ }
+ }
+ }
+ }
}
@@ -1483,48 +1456,56 @@ void cChunk::CreateBlockEntities(void)
void cChunk::WakeUpSimulators(void)
{
- cSimulator * WaterSimulator = m_World->GetWaterSimulator();
- cSimulator * LavaSimulator = m_World->GetLavaSimulator();
- cSimulator * RedstoneSimulator = m_World->GetRedstoneSimulator();
- int BaseX = m_PosX * cChunkDef::Width;
- int BaseZ = m_PosZ * cChunkDef::Width;
- for (int x = 0; x < Width; x++)
+ auto * WaterSimulator = m_World->GetWaterSimulator();
+ auto * LavaSimulator = m_World->GetLavaSimulator();
+ auto * RedstoneSimulator = m_World->GetRedstoneSimulator();
+
+ for (size_t SectionIdx = 0; SectionIdx != cChunkData::NumSections; ++SectionIdx)
{
- int BlockX = x + BaseX;
- for (int z = 0; z < Width; z++)
+ const auto * Section = m_ChunkData.GetSection(SectionIdx);
+ if (Section == nullptr)
+ {
+ continue;
+ }
+
+ for (size_t BlockIdx = 0; BlockIdx != cChunkData::SectionBlockCount; ++BlockIdx)
{
- int BlockZ = z + BaseZ;
- for (int y = GetHeight(x, z); y >= 0; y--)
+ auto BlockType = Section->m_BlockTypes[BlockIdx];
+
+ // Defer calculation until it's actually needed
+ auto WorldPos = [&]
{
- BLOCKTYPE Block = GetBlock(x, y, z);
+ auto RelPos = IndexToCoordinate(BlockIdx);
+ RelPos.y += SectionIdx * cChunkData::SectionHeight;
+ return RelativeToAbsolute(RelPos, m_PosX, m_PosZ);
+ };
- // The redstone sim takes multiple blocks, use the inbuilt checker
- if (RedstoneSimulator->IsAllowedBlock(Block))
+ // The redstone sim takes multiple blocks, use the inbuilt checker
+ if (RedstoneSimulator->IsAllowedBlock(BlockType))
+ {
+ RedstoneSimulator->AddBlock(WorldPos(), this);
+ continue;
+ }
+
+ switch (BlockType)
+ {
+ case E_BLOCK_WATER:
{
- RedstoneSimulator->AddBlock({BlockX, y, BlockZ}, this);
- continue;
+ WaterSimulator->AddBlock(WorldPos(), this);
+ break;
}
-
- switch (Block)
+ case E_BLOCK_LAVA:
{
- case E_BLOCK_WATER:
- {
- WaterSimulator->AddBlock({BlockX, y, BlockZ}, this);
- break;
- }
- case E_BLOCK_LAVA:
- {
- LavaSimulator->AddBlock({BlockX, y, BlockZ}, this);
- break;
- }
- default:
- {
- break;
- }
- } // switch (BlockType)
- } // for y
- } // for z
- } // for x
+ LavaSimulator->AddBlock(WorldPos(), this);
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ } // switch (BlockType)
+ }
+ }
}