summaryrefslogtreecommitdiffstats
path: root/src/Blocks
diff options
context:
space:
mode:
authorTiger Wang <ziwei.tiger@outlook.com>2020-07-29 20:30:38 +0200
committerTiger Wang <ziwei.tiger@outlook.com>2020-08-04 19:15:18 +0200
commit6bdd130aab51b630918ed664c4389cf33bcb2e06 (patch)
treeeed35c8716f9ea18afe8fd909c09e8595928a671 /src/Blocks
parentDo not GetBlock individually in simulators (diff)
downloadcuberite-6bdd130aab51b630918ed664c4389cf33bcb2e06.tar
cuberite-6bdd130aab51b630918ed664c4389cf33bcb2e06.tar.gz
cuberite-6bdd130aab51b630918ed664c4389cf33bcb2e06.tar.bz2
cuberite-6bdd130aab51b630918ed664c4389cf33bcb2e06.tar.lz
cuberite-6bdd130aab51b630918ed664c4389cf33bcb2e06.tar.xz
cuberite-6bdd130aab51b630918ed664c4389cf33bcb2e06.tar.zst
cuberite-6bdd130aab51b630918ed664c4389cf33bcb2e06.zip
Diffstat (limited to 'src/Blocks')
-rw-r--r--src/Blocks/BlockConcretePowder.h67
-rw-r--r--src/Blocks/BlockHandler.cpp64
-rw-r--r--src/Blocks/BlockHandler.h27
-rw-r--r--src/Blocks/BlockPlant.h2
-rw-r--r--src/Blocks/ChunkInterface.cpp21
-rw-r--r--src/Blocks/ChunkInterface.h4
6 files changed, 64 insertions, 121 deletions
diff --git a/src/Blocks/BlockConcretePowder.h b/src/Blocks/BlockConcretePowder.h
index d3133a571..7cd99149e 100644
--- a/src/Blocks/BlockConcretePowder.h
+++ b/src/Blocks/BlockConcretePowder.h
@@ -19,66 +19,41 @@ public:
{
}
-
-
-
-
- virtual void Check(
- cChunkInterface & a_ChunkInterface, cBlockPluginInterface & a_PluginInterface,
- Vector3i a_RelPos,
- cChunk & a_Chunk
+ virtual void OnPlaced(
+ cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
+ Vector3i a_BlockPos,
+ BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
) override
{
- if (GetSoaked(a_RelPos, a_Chunk))
- {
- return;
- }
- Super::Check(a_ChunkInterface, a_PluginInterface, a_RelPos, a_Chunk);
+ OnNeighborChanged(a_ChunkInterface, a_BlockPos, BLOCK_FACE_NONE);
}
+ virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, Vector3i a_BlockPos, eBlockFace a_WhichNeighbor) override
+ {
+ a_ChunkInterface.DoWithChunkAt(a_BlockPos, [&](cChunk & a_Chunk) { CheckSoaked(a_Chunk.AbsoluteToRelative(a_BlockPos), a_Chunk); return true; });
+ }
-
-
-
- /** Check blocks above and around to see if they are water. If one is, converts this into concrete block.
- Returns true if the block was changed. */
- bool GetSoaked(Vector3i a_Rel, cChunk & a_Chunk)
+ /** Check blocks above and around to see if they are water. If one is, converts this into concrete block. */
+ void CheckSoaked(Vector3i a_Rel, cChunk & a_Chunk)
{
- static const std::array<Vector3i, 5> WaterCheck
+ const auto & WaterCheck = cSimulator::AdjacentOffsets;
+ const bool ShouldSoak = std::any_of(WaterCheck.cbegin(), WaterCheck.cend(), [a_Rel, & a_Chunk](Vector3i a_Offset)
{
- {
- { 1, 0, 0},
- {-1, 0, 0},
- { 0, 0, 1},
- { 0, 0, -1},
- { 0, 1, 0},
- }
- };
-
- bool ShouldSoak = std::any_of(WaterCheck.cbegin(), WaterCheck.cend(), [a_Rel, & a_Chunk](Vector3i a_Offset)
- {
- BLOCKTYPE NeighborType;
- return (
- a_Chunk.UnboundedRelGetBlockType(a_Rel.x + a_Offset.x, a_Rel.y + a_Offset.y, a_Rel.z + a_Offset.z, NeighborType)
- && IsBlockWater(NeighborType)
- );
- }
- );
+ BLOCKTYPE NeighborType;
+ return (
+ a_Chunk.UnboundedRelGetBlockType(a_Rel.x + a_Offset.x, a_Rel.y + a_Offset.y, a_Rel.z + a_Offset.z, NeighborType)
+ && IsBlockWater(NeighborType)
+ );
+ });
if (ShouldSoak)
{
NIBBLETYPE BlockMeta;
BlockMeta = a_Chunk.GetMeta(a_Rel.x, a_Rel.y, a_Rel.z);
a_Chunk.SetBlock(a_Rel, E_BLOCK_CONCRETE, BlockMeta);
- return true;
}
- return false;
}
-
-
-
-
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
switch (a_Meta)
@@ -107,7 +82,3 @@ public:
}
}
};
-
-
-
-
diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp
index b7e746418..c3535987c 100644
--- a/src/Blocks/BlockHandler.cpp
+++ b/src/Blocks/BlockHandler.cpp
@@ -436,39 +436,21 @@ void cBlockHandler::OnUpdate(
-void cBlockHandler::OnPlacedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, const sSetBlock & a_BlockChange)
+void cBlockHandler::OnNeighborChanged(cChunkInterface & a_ChunkInterface, Vector3i a_BlockPos, eBlockFace a_WhichNeighbor)
{
- OnPlaced(a_ChunkInterface, a_WorldInterface, a_BlockChange.GetAbsolutePos(), a_BlockChange.m_BlockType, a_BlockChange.m_BlockMeta);
-}
-
-
-
-
-
-void cBlockHandler::OnPlaced(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
-{
- // Notify the neighbors
- NeighborChanged(a_ChunkInterface, a_BlockPos.addedX(-1), BLOCK_FACE_XP);
- NeighborChanged(a_ChunkInterface, a_BlockPos.addedX( 1), BLOCK_FACE_XM);
- NeighborChanged(a_ChunkInterface, a_BlockPos.addedY(-1), BLOCK_FACE_YP);
- NeighborChanged(a_ChunkInterface, a_BlockPos.addedY( 1), BLOCK_FACE_YM);
- NeighborChanged(a_ChunkInterface, a_BlockPos.addedZ(-1), BLOCK_FACE_ZP);
- NeighborChanged(a_ChunkInterface, a_BlockPos.addedZ( 1), BLOCK_FACE_ZM);
-}
-
-
-
-
+ if (a_ChunkInterface.DoWithChunkAt(a_BlockPos, [&](cChunk & a_Chunk) { return CanBeAt(a_ChunkInterface, a_Chunk.AbsoluteToRelative(a_BlockPos), a_Chunk); }))
+ {
+ return;
+ }
-void cBlockHandler::OnBroken(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, Vector3i a_BlockPos, BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta)
-{
- // Notify the neighbors
- NeighborChanged(a_ChunkInterface, a_BlockPos.addedX(-1), BLOCK_FACE_XP);
- NeighborChanged(a_ChunkInterface, a_BlockPos.addedX( 1), BLOCK_FACE_XM);
- NeighborChanged(a_ChunkInterface, a_BlockPos.addedY(-1), BLOCK_FACE_YP);
- NeighborChanged(a_ChunkInterface, a_BlockPos.addedY( 1), BLOCK_FACE_YM);
- NeighborChanged(a_ChunkInterface, a_BlockPos.addedZ(-1), BLOCK_FACE_ZP);
- NeighborChanged(a_ChunkInterface, a_BlockPos.addedZ( 1), BLOCK_FACE_ZM);
+ if (DoesDropOnUnsuitable())
+ {
+ a_ChunkInterface.DropBlockAsPickups(a_BlockPos);
+ }
+ else
+ {
+ a_ChunkInterface.SetBlock(a_BlockPos, E_BLOCK_AIR, 0);
+ }
}
@@ -585,19 +567,13 @@ void cBlockHandler::Check(
cChunk & a_Chunk
)
{
- if (CanBeAt(a_ChunkInterface, a_RelPos, a_Chunk))
- {
- return;
- }
-
- if (DoesDropOnUnsuitable())
- {
- a_ChunkInterface.DropBlockAsPickups(a_Chunk.RelativeToAbsolute(a_RelPos));
- }
- else
- {
- a_Chunk.SetBlock(a_RelPos, E_BLOCK_AIR, 0);
- }
+ const auto Position = cChunkDef::RelativeToAbsolute(a_RelPos, a_Chunk.GetPos());
+ NeighborChanged(a_ChunkInterface, Position.addedX(-1), BLOCK_FACE_XP);
+ NeighborChanged(a_ChunkInterface, Position.addedX(1), BLOCK_FACE_XM);
+ NeighborChanged(a_ChunkInterface, Position.addedY(-1), BLOCK_FACE_YP);
+ NeighborChanged(a_ChunkInterface, Position.addedY(1), BLOCK_FACE_YM);
+ NeighborChanged(a_ChunkInterface, Position.addedZ(-1), BLOCK_FACE_ZP);
+ NeighborChanged(a_ChunkInterface, Position.addedZ(1), BLOCK_FACE_ZM);
}
diff --git a/src/Blocks/BlockHandler.h b/src/Blocks/BlockHandler.h
index a582b8dc2..90866fbb7 100644
--- a/src/Blocks/BlockHandler.h
+++ b/src/Blocks/BlockHandler.h
@@ -65,21 +65,12 @@ public:
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
Vector3i a_BlockPos,
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
- );
+ ) {};
/** Called by cPlayer::PlaceBlocks() for each block after it has been set to the world. Called after OnPlaced(). */
virtual void OnPlacedByPlayer(
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, const sSetBlock & a_BlockChange
- );
-
- /** Called just before the player breaks the block.
- The block is still valid in the world.
- By default does nothing special; descendants may provide further behavior. */
- virtual void OnPlayerBreakingBlock(
- cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
- cPlayer & a_Player,
- Vector3i a_BlockPos
- ) {}
+ ) {};
/** Called just after the player breaks the block.
The block is already dug up in the world, the original block type and meta is passed in a_OldBlockType and a_OldBlockMeta.
@@ -91,14 +82,6 @@ public:
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
) {}
- /** Called before a block gets broken (replaced with air), either by player or by natural means.
- If by player, it is called after the OnPlayerBreakingBlock() callback.
- By default does nothing. */
- virtual void OnBreaking(
- cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
- Vector3i a_BlockPos
- ) {}
-
/** Called after a block gets broken (replaced with air), either by player or by natural means.
If by player, it is called before the OnPlayerBrokeBlock() callback.
The block is already dug up in the world, the original block type and meta is passed in a_OldBlockType and a_OldBlockMeta.
@@ -107,13 +90,13 @@ public:
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
Vector3i a_BlockPos,
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
- );
+ ) {};
/** Called when a direct neighbor of this block has been changed.
The position is the block's own position, NOT the changed neighbor's position.
a_WhichNeighbor indicates which neighbor has changed. For example, BLOCK_FACE_YP meant the neighbor above has changed.
BLOCK_FACE_NONE means that it is a neighbor not directly adjacent (diagonal, etc.) */
- virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, Vector3i a_BlockPos, eBlockFace a_WhichNeighbor) {}
+ virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, Vector3i a_BlockPos, eBlockFace a_WhichNeighbor);
/** Notifies the specified neighbor that the current block has changed.
a_NeighborPos are the coords of the neighbor to be notified
@@ -208,7 +191,7 @@ public:
/** Called when one of the neighbors gets set; equivalent to MC block update.
By default drops (DropBlockAsPickup() / SetBlock()) if the position is no longer suitable (CanBeAt(), DoesDropOnUnsuitable()),
otherwise wakes up all simulators on the block. */
- virtual void Check(
+ void Check(
cChunkInterface & ChunkInterface, cBlockPluginInterface & a_PluginInterface,
Vector3i a_RelPos,
cChunk & a_Chunk
diff --git a/src/Blocks/BlockPlant.h b/src/Blocks/BlockPlant.h
index b0760528c..a0d6ffe52 100644
--- a/src/Blocks/BlockPlant.h
+++ b/src/Blocks/BlockPlant.h
@@ -44,7 +44,7 @@ public:
}
case paDeath:
{
- a_ChunkInterface.DigBlock(a_WorldInterface, a_Chunk.RelativeToAbsolute(a_RelPos));
+ a_ChunkInterface.SetBlock(a_Chunk.RelativeToAbsolute(a_RelPos), E_BLOCK_AIR, 0);
break;
}
case paStay: break; // do nothing
diff --git a/src/Blocks/ChunkInterface.cpp b/src/Blocks/ChunkInterface.cpp
index fd64ee9fc..15198dd37 100644
--- a/src/Blocks/ChunkInterface.cpp
+++ b/src/Blocks/ChunkInterface.cpp
@@ -12,6 +12,15 @@
+bool cChunkInterface::DoWithChunkAt(Vector3i a_BlockPos, cChunkCallback a_Callback)
+{
+ return m_ChunkMap->DoWithChunkAt(a_BlockPos, a_Callback);
+}
+
+
+
+
+
BLOCKTYPE cChunkInterface::GetBlock(Vector3i a_Pos)
{
return m_ChunkMap->GetBlock(a_Pos);
@@ -95,16 +104,16 @@ bool cChunkInterface::WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a
bool cChunkInterface::DigBlock(cWorldInterface & a_WorldInterface, Vector3i a_BlockPos)
{
- BLOCKTYPE blockType;
- NIBBLETYPE blockMeta;
- GetBlockTypeMeta(a_BlockPos, blockType, blockMeta);
- auto handler = cBlockInfo::GetHandler(blockType);
- handler->OnBreaking(*this, a_WorldInterface, a_BlockPos);
+ BLOCKTYPE BlockType;
+ NIBBLETYPE BlockMeta;
+ GetBlockTypeMeta(a_BlockPos, BlockType, BlockMeta);
+
if (!m_ChunkMap->DigBlock(a_BlockPos))
{
return false;
}
- handler->OnBroken(*this, a_WorldInterface, a_BlockPos, blockType, blockMeta);
+
+ cBlockInfo::GetHandler(BlockType)->OnBroken(*this, a_WorldInterface, a_BlockPos, BlockType, BlockMeta);
return true;
}
diff --git a/src/Blocks/ChunkInterface.h b/src/Blocks/ChunkInterface.h
index 345fca4d2..6ee54b17f 100644
--- a/src/Blocks/ChunkInterface.h
+++ b/src/Blocks/ChunkInterface.h
@@ -2,12 +2,14 @@
#pragma once
#include "../ForEachChunkProvider.h"
+#include "../FunctionRef.h"
// fwd:
class cItem;
+class cChunk;
class cChunkMap;
class cWorldInterface;
class cPlayer;
@@ -23,6 +25,8 @@ public:
cChunkInterface(cChunkMap * a_ChunkMap) : m_ChunkMap(a_ChunkMap) {}
+ bool DoWithChunkAt(Vector3i a_BlockPos, cFunctionRef<bool(cChunk &)> a_Callback);
+
BLOCKTYPE GetBlock(Vector3i a_Pos);
NIBBLETYPE GetBlockMeta(Vector3i a_Pos);