summaryrefslogtreecommitdiffstats
path: root/src/ChunkMap.cpp
diff options
context:
space:
mode:
authorMattes D <github@xoft.cz>2019-10-16 10:06:34 +0200
committerGitHub <noreply@github.com>2019-10-16 10:06:34 +0200
commit221cc4ec5cb6301743e947eaabed3fecedba796f (patch)
tree4e44c8bb7523e5d1d04468fc906ae24674c10abc /src/ChunkMap.cpp
parentFixed crash in hopper while pulling items from blockentity above itself (#4412) (diff)
downloadcuberite-221cc4ec5cb6301743e947eaabed3fecedba796f.tar
cuberite-221cc4ec5cb6301743e947eaabed3fecedba796f.tar.gz
cuberite-221cc4ec5cb6301743e947eaabed3fecedba796f.tar.bz2
cuberite-221cc4ec5cb6301743e947eaabed3fecedba796f.tar.lz
cuberite-221cc4ec5cb6301743e947eaabed3fecedba796f.tar.xz
cuberite-221cc4ec5cb6301743e947eaabed3fecedba796f.tar.zst
cuberite-221cc4ec5cb6301743e947eaabed3fecedba796f.zip
Diffstat (limited to '')
-rw-r--r--src/ChunkMap.cpp201
1 files changed, 58 insertions, 143 deletions
diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp
index a859deca5..ec6b74192 100644
--- a/src/ChunkMap.cpp
+++ b/src/ChunkMap.cpp
@@ -145,108 +145,6 @@ cChunkPtr cChunkMap::GetChunkNoLoad(int a_ChunkX, int a_ChunkZ)
-bool cChunkMap::LockedGetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta)
-{
- // We already have m_CSChunks locked since this can be called only from within the tick thread
- ASSERT(m_CSChunks.IsLockedByCurrentThread());
-
- int ChunkX, ChunkZ;
- cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ);
- cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ);
- if (Chunk == nullptr)
- {
- return false;
- }
-
- a_BlockType = Chunk->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
- a_BlockMeta = Chunk->GetMeta(a_BlockX, a_BlockY, a_BlockZ);
- return true;
-}
-
-
-
-
-
-bool cChunkMap::LockedGetBlockType(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType)
-{
- // We already have m_CSChunks locked since this can be called only from within the tick thread
- ASSERT(m_CSChunks.IsLockedByCurrentThread());
-
- int ChunkX, ChunkZ;
- cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ);
- cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ);
- if (Chunk == nullptr)
- {
- return false;
- }
-
- a_BlockType = Chunk->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
- return true;
-}
-
-
-
-
-
-bool cChunkMap::LockedGetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE & a_BlockMeta)
-{
- // We already have m_CSChunks locked since this can be called only from within the tick thread
- ASSERT(m_CSChunks.IsLockedByCurrentThread());
-
- int ChunkX, ChunkZ;
- cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ);
- cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ);
- if (Chunk == nullptr)
- {
- return false;
- }
-
- a_BlockMeta = Chunk->GetMeta(a_BlockX, a_BlockY, a_BlockZ);
- return true;
-}
-
-
-
-
-
-bool cChunkMap::LockedSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
-{
- // We already have m_CSChunks locked since this can be called only from within the tick thread
- int ChunkX, ChunkZ;
- cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ);
- cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ);
- if (Chunk == nullptr)
- {
- return false;
- }
-
- Chunk->SetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta);
- return true;
-}
-
-
-
-
-
-bool cChunkMap::LockedFastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
-{
- // We already have m_CSChunks locked since this can be called only from within the tick thread
- int ChunkX, ChunkZ;
- cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ);
- cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ);
- if (Chunk == nullptr)
- {
- return false;
- }
-
- Chunk->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta);
- return true;
-}
-
-
-
-
-
cChunk * cChunkMap::FindChunk(int a_ChunkX, int a_ChunkZ)
{
ASSERT(m_CSChunks.IsLockedByCurrentThread());
@@ -581,7 +479,7 @@ void cChunkMap::SetBlocks(const sSetBlockVector & a_Blocks)
// If the chunk is valid, set the block:
if (chunk != nullptr)
{
- chunk->SetBlock(block.m_RelX, block.m_RelY, block.m_RelZ, block.m_BlockType, block.m_BlockMeta);
+ chunk->SetBlock({block.m_RelX, block.m_RelY, block.m_RelZ}, block.m_BlockType, block.m_BlockMeta);
}
} // for block - a_Blocks[]
}
@@ -711,38 +609,40 @@ void cChunkMap::SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYP
-void cChunkMap::SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, bool a_SendToClients)
+void cChunkMap::SetBlock(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
- cChunkInterface ChunkInterface(this);
- BlockHandler(GetBlock(a_BlockX, a_BlockY, a_BlockZ))->OnDestroyed(ChunkInterface, *m_World, a_BlockX, a_BlockY, a_BlockZ);
-
- int ChunkX, ChunkZ, X = a_BlockX, Y = a_BlockY, Z = a_BlockZ;
- cChunkDef::AbsoluteToRelative( X, Y, Z, ChunkX, ChunkZ);
+ auto chunkCoord = cChunkDef::BlockToChunk(a_BlockPos);
+ auto relPos = cChunkDef::AbsoluteToRelative(a_BlockPos, chunkCoord);
cCSLock Lock(m_CSChunks);
- cChunkPtr Chunk = GetChunk( ChunkX, ChunkZ);
- if ((Chunk != nullptr) && Chunk->IsValid())
+ auto chunk = GetChunk(chunkCoord.m_ChunkX, chunkCoord.m_ChunkZ);
+ if ((chunk != nullptr) && chunk->IsValid())
{
- Chunk->SetBlock(X, Y, Z, a_BlockType, a_BlockMeta, a_SendToClients);
- m_World->GetSimulatorManager()->WakeUp({a_BlockX, a_BlockY, a_BlockZ}, Chunk);
+ BLOCKTYPE blockType;
+ NIBBLETYPE blockMeta;
+ GetBlockTypeMeta(a_BlockPos, blockType, blockMeta);
+ cChunkInterface ChunkInterface(this);
+ BlockHandler(blockType)->OnBroken(ChunkInterface, *m_World, a_BlockPos, blockType, blockMeta);
+ chunk->SetBlock(relPos, a_BlockType, a_BlockMeta);
+ m_World->GetSimulatorManager()->WakeUp(a_BlockPos, chunk);
+ BlockHandler(a_BlockType)->OnPlaced(ChunkInterface, *m_World, a_BlockPos, a_BlockType, a_BlockMeta);
}
- BlockHandler(a_BlockType)->OnPlaced(ChunkInterface, *m_World, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta);
}
-bool cChunkMap::GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta)
+bool cChunkMap::GetBlockTypeMeta(Vector3i a_BlockPos, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta)
{
- int ChunkX, ChunkZ, X = a_BlockX, Y = a_BlockY, Z = a_BlockZ;
- cChunkDef::AbsoluteToRelative( X, Y, Z, ChunkX, ChunkZ);
+ auto chunkCoord = cChunkDef::BlockToChunk(a_BlockPos);
+ auto relPos = cChunkDef::AbsoluteToRelative(a_BlockPos, chunkCoord);
cCSLock Lock(m_CSChunks);
- cChunkPtr Chunk = GetChunk( ChunkX, ChunkZ);
- if ((Chunk != nullptr) && Chunk->IsValid())
+ auto chunk = GetChunk(chunkCoord.m_ChunkX, chunkCoord.m_ChunkZ);
+ if ((chunk != nullptr) && chunk->IsValid())
{
- Chunk->GetBlockTypeMeta(X, Y, Z, a_BlockType, a_BlockMeta);
+ chunk->GetBlockTypeMeta(relPos, a_BlockType, a_BlockMeta);
return true;
}
return false;
@@ -776,14 +676,15 @@ void cChunkMap::ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_Filt
cCSLock Lock(m_CSChunks);
for (sSetBlockVector::const_iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr)
{
- cChunkPtr Chunk = GetChunk(itr->m_ChunkX, itr->m_ChunkZ);
- if ((Chunk == nullptr) || !Chunk->IsValid())
+ auto chunk = GetChunk(itr->m_ChunkX, itr->m_ChunkZ);
+ if ((chunk == nullptr) || !chunk->IsValid())
{
continue;
}
- if (Chunk->GetBlock(itr->m_RelX, itr->m_RelY, itr->m_RelZ) == a_FilterBlockType)
+ Vector3i relPos(itr->m_RelX, itr->m_RelY, itr->m_RelZ);
+ if (chunk->GetBlock(relPos) == a_FilterBlockType)
{
- Chunk->SetBlock(itr->m_RelX, itr->m_RelY, itr->m_RelZ, itr->m_BlockType, itr->m_BlockMeta);
+ chunk->SetBlock(relPos, itr->m_BlockType, itr->m_BlockMeta);
}
}
}
@@ -797,16 +698,17 @@ void cChunkMap::ReplaceTreeBlocks(const sSetBlockVector & a_Blocks)
cCSLock Lock(m_CSChunks);
for (sSetBlockVector::const_iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr)
{
- cChunkPtr Chunk = GetChunk(itr->m_ChunkX, itr->m_ChunkZ);
- if ((Chunk == nullptr) || !Chunk->IsValid())
+ auto chunk = GetChunk(itr->m_ChunkX, itr->m_ChunkZ);
+ if ((chunk == nullptr) || !chunk->IsValid())
{
continue;
}
- switch (Chunk->GetBlock(itr->m_RelX, itr->m_RelY, itr->m_RelZ))
+ Vector3i relPos(itr->m_RelX, itr->m_RelY, itr->m_RelZ);
+ switch (chunk->GetBlock(relPos))
{
CASE_TREE_OVERWRITTEN_BLOCKS:
{
- Chunk->SetBlock(itr->m_RelX, itr->m_RelY, itr->m_RelZ, itr->m_BlockType, itr->m_BlockMeta);
+ chunk->SetBlock(relPos, itr->m_BlockType, itr->m_BlockMeta);
break;
}
case E_BLOCK_LEAVES:
@@ -814,7 +716,7 @@ void cChunkMap::ReplaceTreeBlocks(const sSetBlockVector & a_Blocks)
{
if ((itr->m_BlockType == E_BLOCK_LOG) || (itr->m_BlockType == E_BLOCK_NEW_LOG))
{
- Chunk->SetBlock(itr->m_RelX, itr->m_RelY, itr->m_RelZ, itr->m_BlockType, itr->m_BlockMeta);
+ chunk->SetBlock(relPos, itr->m_BlockType, itr->m_BlockMeta);
}
break;
}
@@ -930,24 +832,22 @@ bool cChunkMap::GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure)
-bool cChunkMap::DigBlock(int a_BlockX, int a_BlockY, int a_BlockZ)
+bool cChunkMap::DigBlock(Vector3i a_BlockPos)
{
- int PosX = a_BlockX, PosY = a_BlockY, PosZ = a_BlockZ, ChunkX, ChunkZ;
-
- cChunkDef::AbsoluteToRelative(PosX, PosY, PosZ, ChunkX, ChunkZ);
+ auto chunkCoords = cChunkDef::BlockToChunk(a_BlockPos);
+ auto relPos = cChunkDef::AbsoluteToRelative(a_BlockPos, chunkCoords);
{
cCSLock Lock(m_CSChunks);
- cChunkPtr DestChunk = GetChunk( ChunkX, ChunkZ);
- if ((DestChunk == nullptr) || !DestChunk->IsValid())
+ auto destChunk = GetChunk(chunkCoords.m_ChunkX, chunkCoords.m_ChunkZ);
+ if ((destChunk == nullptr) || !destChunk->IsValid())
{
return false;
}
- DestChunk->SetBlock(PosX, PosY, PosZ, E_BLOCK_AIR, 0);
- m_World->GetSimulatorManager()->WakeUp({a_BlockX, a_BlockY, a_BlockZ}, DestChunk);
+ destChunk->SetBlock(relPos, E_BLOCK_AIR, 0);
+ m_World->GetSimulatorManager()->WakeUp(a_BlockPos, destChunk);
}
-
return true;
}
@@ -955,6 +855,24 @@ bool cChunkMap::DigBlock(int a_BlockX, int a_BlockY, int a_BlockZ)
+cItems cChunkMap::PickupsFromBlock(Vector3i a_BlockPos, const cEntity * a_Digger, const cItem * a_Tool)
+{
+ auto chunkCoords = cChunkDef::BlockToChunk(a_BlockPos);
+ auto relPos = cChunkDef::AbsoluteToRelative(a_BlockPos, chunkCoords);
+
+ cCSLock Lock(m_CSChunks);
+ auto destChunk = GetChunk(chunkCoords.m_ChunkX, chunkCoords.m_ChunkZ);
+ if ((destChunk == nullptr) || !destChunk->IsValid())
+ {
+ return {};
+ }
+ return destChunk->PickupsFromBlock(relPos, a_Digger, a_Tool);
+}
+
+
+
+
+
void cChunkMap::SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer & a_Player)
{
int ChunkX, ChunkZ;
@@ -1305,11 +1223,8 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_
auto & Random = GetRandomProvider();
if (Random.RandBool(0.25)) // 25% chance of pickups
{
- cItems Drops;
- cBlockHandler * Handler = BlockHandler(Block);
-
- Handler->ConvertToPickups(Drops, area.GetBlockMeta(bx + x, by + y, bz + z)); // Stone becomes cobblestone, coal ore becomes coal, etc.
- m_World->SpawnItemPickups(Drops, bx + x, by + y, bz + z);
+ auto pickups = area.PickupsFromBlock({bx + x, by + y, bz + z});
+ m_World->SpawnItemPickups(pickups, bx + x, by + y, bz + z);
}
else if ((m_World->GetTNTShrapnelLevel() > slNone) && Random.RandBool(0.20)) // 20% chance of flinging stuff around
{