1
0

Refactored block-to-pickup conversion. (#4417)

This commit is contained in:
Mattes D
2019-10-16 10:06:34 +02:00
committed by GitHub
parent 241d97bbf9
commit 221cc4ec5c
121 changed files with 2496 additions and 1744 deletions

View File

@@ -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
{