summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/Blocks/BlockFluid.h26
-rw-r--r--src/Blocks/BlockIce.h19
-rw-r--r--src/Blocks/BlockPiston.cpp44
-rw-r--r--src/Blocks/BlockPiston.h7
-rw-r--r--src/Blocks/BlockSponge.h79
-rw-r--r--src/Blocks/BlockVine.h19
-rw-r--r--src/Chunk.cpp4
-rw-r--r--src/Simulator/DelayedFluidSimulator.cpp2
-rw-r--r--src/Simulator/Simulator.h2
-rw-r--r--src/World.cpp7
10 files changed, 70 insertions, 139 deletions
diff --git a/src/Blocks/BlockFluid.h b/src/Blocks/BlockFluid.h
index e856dba38..35b702f4b 100644
--- a/src/Blocks/BlockFluid.h
+++ b/src/Blocks/BlockFluid.h
@@ -43,32 +43,6 @@ public:
- virtual void Check(
- cChunkInterface & a_ChunkInterface, cBlockPluginInterface & a_PluginInterface,
- Vector3i a_RelPos,
- cChunk & a_Chunk
- ) override
- {
- switch (m_BlockType)
- {
- case E_BLOCK_STATIONARY_LAVA:
- {
- a_Chunk.FastSetBlock(a_RelPos, E_BLOCK_LAVA, a_Chunk.GetMeta(a_RelPos));
- break;
- }
- case E_BLOCK_STATIONARY_WATER:
- {
- a_Chunk.FastSetBlock(a_RelPos, E_BLOCK_WATER, a_Chunk.GetMeta(a_RelPos));
- break;
- }
- }
- Super::Check(a_ChunkInterface, a_PluginInterface, a_RelPos, a_Chunk);
- }
-
-
-
-
-
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
UNUSED(a_Meta);
diff --git a/src/Blocks/BlockIce.h b/src/Blocks/BlockIce.h
index 5e2fd9dbb..a4372d0ea 100644
--- a/src/Blocks/BlockIce.h
+++ b/src/Blocks/BlockIce.h
@@ -19,10 +19,6 @@ public:
{
}
-
-
-
-
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{
// Only drop self when using silk-touch:
@@ -36,10 +32,6 @@ public:
}
}
-
-
-
-
virtual void OnBroken(
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
Vector3i a_BlockPos,
@@ -51,19 +43,14 @@ public:
{
return;
}
- auto blockTypeBelow = a_ChunkInterface.GetBlock(a_BlockPos.addedY(-1));
- if (cBlockInfo::FullyOccupiesVoxel(blockTypeBelow) || IsBlockLiquid(blockTypeBelow))
+
+ const auto Below = a_ChunkInterface.GetBlock(a_BlockPos.addedY(-1));
+ if (cBlockInfo::FullyOccupiesVoxel(Below) || IsBlockLiquid(Below))
{
- // Setting air with FastSetBlock prevents SetBlock recursively calling OnBroken.
- a_ChunkInterface.FastSetBlock(a_BlockPos, E_BLOCK_AIR, 0);
a_ChunkInterface.SetBlock(a_BlockPos, E_BLOCK_WATER, 0);
}
}
-
-
-
-
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
UNUSED(a_Meta);
diff --git a/src/Blocks/BlockPiston.cpp b/src/Blocks/BlockPiston.cpp
index e68e05809..b68a59461 100644
--- a/src/Blocks/BlockPiston.cpp
+++ b/src/Blocks/BlockPiston.cpp
@@ -32,14 +32,19 @@ void cBlockPistonHandler::OnBroken(
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
)
{
- // If the piston is extended, destroy the extension as well
- if (IsExtended(a_OldBlockMeta))
+ if (!IsExtended(a_OldBlockMeta))
{
- auto extPos = a_BlockPos + MetadataToOffset(a_OldBlockMeta);
- if (a_ChunkInterface.GetBlock(extPos) == E_BLOCK_PISTON_EXTENSION)
- {
- a_ChunkInterface.DropBlockAsPickups(extPos);
- }
+ return;
+ }
+
+ const auto Extension = a_BlockPos + MetadataToOffset(a_OldBlockMeta);
+ if (
+ cChunkDef::IsValidHeight(Extension.y) &&
+ (a_ChunkInterface.GetBlock(Extension) == E_BLOCK_PISTON_EXTENSION)
+ )
+ {
+ // If the piston is extended, destroy the extension as well:
+ a_ChunkInterface.SetBlock(Extension, E_BLOCK_AIR, 0);
}
}
@@ -75,7 +80,7 @@ void cBlockPistonHandler::PushBlocks(
cWorld & a_World, const Vector3i & a_PushDir
)
{
- // Sort blocks to move the blocks first, which are farest away from the piston
+ // Sort blocks to move the blocks first, which are farthest away from the piston
// This prevents the overwriting of existing blocks
std::vector<Vector3i> sortedBlocks(a_BlocksToPush.begin(), a_BlocksToPush.end());
std::sort(sortedBlocks.begin(), sortedBlocks.end(), [a_PushDir](const Vector3i & a, const Vector3i & b)
@@ -281,8 +286,7 @@ void cBlockPistonHandler::RetractPiston(Vector3i a_BlockPos, cWorld & a_World)
return;
}
- // Remove extension, update base state. Calling FastSetBlock inhibits OnBroken being called by SetBlock.
- World.FastSetBlock(extensionPos, E_BLOCK_AIR, 0);
+ // Remove extension, update base state:
World.SetBlock(extensionPos, E_BLOCK_AIR, 0);
World.SetBlock(a_BlockPos, pistonBlock, pistonMeta & ~(8));
@@ -334,11 +338,17 @@ void cBlockPistonHeadHandler::OnBroken(
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
)
{
- // Drop the base of the piston:
- auto basePos = a_BlockPos - cBlockPistonHandler::MetadataToOffset(a_OldBlockMeta);
- if (cChunkDef::IsValidHeight(basePos.y))
+ const auto Base = a_BlockPos - cBlockPistonHandler::MetadataToOffset(a_OldBlockMeta);
+ if (!cChunkDef::IsValidHeight(Base.y))
{
- a_ChunkInterface.DropBlockAsPickups(basePos);
+ return;
+ }
+
+ const auto Block = a_ChunkInterface.GetBlock(Base);
+ if ((Block == E_BLOCK_PISTON) || (Block == E_BLOCK_STICKY_PISTON))
+ {
+ // Remove the base of the piston:
+ a_ChunkInterface.SetBlock(Base, E_BLOCK_AIR, 0);
}
}
@@ -346,3 +356,9 @@ void cBlockPistonHeadHandler::OnBroken(
+cItems cBlockPistonHeadHandler::ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool)
+{
+ // Give a normal\sticky piston base, not piston extension
+ // With 1.7, the item forms of these technical blocks have been removed, so giving someone this will crash their client...
+ return { cItem(((a_BlockMeta & 0x8) == 0x8) ? E_BLOCK_STICKY_PISTON : E_BLOCK_PISTON) };
+}
diff --git a/src/Blocks/BlockPiston.h b/src/Blocks/BlockPiston.h
index 7ff478a68..8799ba3ca 100644
--- a/src/Blocks/BlockPiston.h
+++ b/src/Blocks/BlockPiston.h
@@ -155,10 +155,5 @@ public:
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
) override;
- virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
- {
- // No pickups
- // Also with 1.7, the item forms of these technical blocks have been removed, so giving someone this will crash their client...
- return {};
- }
+ virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override;
} ;
diff --git a/src/Blocks/BlockSponge.h b/src/Blocks/BlockSponge.h
index 88981567a..2ef078ea1 100644
--- a/src/Blocks/BlockSponge.h
+++ b/src/Blocks/BlockSponge.h
@@ -19,44 +19,25 @@ 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 around the sponge to see if they are water.
If a dry sponge is touching water, soak up up to 65 blocks of water,
- with a taxicab distance of 7, and turn the sponge into a wet sponge.
- Returns TRUE if the block was changed. */
- bool GetSoaked(Vector3i a_Rel, cChunk & a_Chunk)
+ with a taxicab distance of 7, and turn the sponge into a wet sponge. */
+ void CheckSoaked(Vector3i a_Rel, cChunk & a_Chunk)
{
- static const std::array<Vector3i, 6> WaterCheck
- {
- {
- { 1, 0, 0},
- {-1, 0, 0},
- { 0, 0, 1},
- { 0, 0, -1},
- { 0, 1, 0},
- { 0, -1, 0},
- }
- };
struct sSeed
{
sSeed(Vector3i pos, int d)
@@ -68,27 +49,25 @@ public:
int m_Depth;
};
-
// Check if this is a dry sponge next to a water block.
NIBBLETYPE TargetMeta = a_Chunk.GetMeta(a_Rel.x, a_Rel.y, a_Rel.z);
if (TargetMeta != E_META_SPONGE_DRY)
{
- return false;
+ return;
}
- bool ShouldSoak = std::any_of(WaterCheck.cbegin(), WaterCheck.cend(), [a_Rel, & a_Chunk](Vector3i a_Offset)
- {
- return IsWet(a_Rel + a_Offset, a_Chunk);
- }
- );
+ const auto & WaterCheck = cSimulator::AdjacentOffsets;
+ const bool ShouldSoak = std::any_of(WaterCheck.cbegin(), WaterCheck.cend(), [a_Rel, &a_Chunk](Vector3i a_Offset)
+ {
+ return IsWet(a_Rel + a_Offset, a_Chunk);
+ });
// Early return if the sponge isn't touching any water.
- if (! ShouldSoak)
+ if (!ShouldSoak)
{
- return false;
+ return;
}
-
// Use a queue to hold blocks that we want to check, so our search is breadth-first.
std::queue<sSeed> Seeds;
int count = 0;
@@ -100,7 +79,6 @@ public:
Seeds.emplace(a_Rel + WaterCheck[i], maxDepth - 1);
}
-
// Keep checking blocks that are touching water blocks, or until 65 have been soaked up.
while (!Seeds.empty() && count < 65)
{
@@ -122,24 +100,16 @@ public:
}
Seeds.pop();
}
+
a_Chunk.SetBlock(a_Rel, E_BLOCK_SPONGE, E_META_SPONGE_WET);
- return true;
}
-
-
-
-
static void DryUp(Vector3i a_Rel, cChunk & a_Chunk)
{
// TODO: support evaporating waterlogged blocks.
a_Chunk.UnboundedRelSetBlock(a_Rel.x, a_Rel.y, a_Rel.z, E_BLOCK_AIR, 0);
}
-
-
-
-
static bool IsWet(Vector3i a_Rel, cChunk & a_Chunk)
{
// TODO: support detecting waterlogged blocks.
@@ -147,18 +117,9 @@ public:
return(a_Chunk.UnboundedRelGetBlockType(a_Rel.x, a_Rel.y, a_Rel.z, Type) && IsBlockWater(Type));
}
-
-
-
-
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
UNUSED(a_Meta);
return 18;
}
-
-
-
-
-
};
diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h
index 68e6e2ddc..25b6efe47 100644
--- a/src/Blocks/BlockVine.h
+++ b/src/Blocks/BlockVine.h
@@ -162,12 +162,12 @@ public:
- virtual void Check(
- cChunkInterface & a_ChunkInterface, cBlockPluginInterface & a_PluginInterface,
- Vector3i a_RelPos,
- cChunk & a_Chunk
- ) override
+ virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, Vector3i a_BlockPos, eBlockFace a_WhichNeighbor) override
{
+ a_ChunkInterface.DoWithChunkAt(a_BlockPos, [&](cChunk & a_Chunk)
+ {
+
+ const auto a_RelPos = a_Chunk.AbsoluteToRelative(a_BlockPos);
NIBBLETYPE CurMeta = a_Chunk.GetMeta(a_RelPos);
NIBBLETYPE MaxMeta = GetMaxMeta(a_Chunk, a_RelPos);
@@ -190,14 +190,13 @@ public:
a_ChunkInterface.DropBlockAsPickups(a_Chunk.RelativeToAbsolute(a_RelPos));
}
a_Chunk.SetBlock(a_RelPos, E_BLOCK_AIR, 0);
- return;
+ return false;
}
a_Chunk.SetBlock(a_RelPos, m_BlockType, Common);
}
- else
- {
- a_Chunk.GetWorld()->GetSimulatorManager()->WakeUp(a_Chunk, a_RelPos);
- }
+
+ return false;
+ });
}
diff --git a/src/Chunk.cpp b/src/Chunk.cpp
index 21261e828..25af8d6fb 100644
--- a/src/Chunk.cpp
+++ b/src/Chunk.cpp
@@ -651,8 +651,6 @@ void cChunk::Tick(std::chrono::milliseconds a_Dt)
return;
}
- BroadcastPendingBlockChanges();
-
CheckBlocks();
// Tick simulators:
@@ -716,6 +714,8 @@ void cChunk::Tick(std::chrono::milliseconds a_Dt)
} // for itr - m_Entitites[]
ApplyWeatherToTop();
+
+ BroadcastPendingBlockChanges();
}
diff --git a/src/Simulator/DelayedFluidSimulator.cpp b/src/Simulator/DelayedFluidSimulator.cpp
index ec1918617..9bec01359 100644
--- a/src/Simulator/DelayedFluidSimulator.cpp
+++ b/src/Simulator/DelayedFluidSimulator.cpp
@@ -121,7 +121,7 @@ void cDelayedFluidSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a
void cDelayedFluidSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block)
{
- if (a_Block != m_FluidBlock)
+ if ((a_Block != m_FluidBlock) && (a_Block != m_StationaryFluidBlock))
{
return;
}
diff --git a/src/Simulator/Simulator.h b/src/Simulator/Simulator.h
index f82b579cb..e18465bee 100644
--- a/src/Simulator/Simulator.h
+++ b/src/Simulator/Simulator.h
@@ -28,7 +28,7 @@ public:
virtual ~cSimulator() {}
// Contains our direct adjacents
- inline static std::array<Vector3i, 6> AdjacentOffsets
+ static constexpr std::array<Vector3i, 6> AdjacentOffsets
{
{
{ 1, 0, 0 },
diff --git a/src/World.cpp b/src/World.cpp
index f70343889..d19d9f6c6 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -1036,12 +1036,11 @@ void cWorld::Tick(std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_La
// Add players waiting in the queue to be added:
AddQueuedPlayers();
- m_ChunkMap->Tick(a_Dt);
- TickMobs(a_Dt);
- m_MapManager.TickMaps();
-
TickClients(static_cast<float>(a_Dt.count()));
TickQueuedBlocks();
+ m_ChunkMap->Tick(a_Dt); // Tick chunk after clients to apply at least one round of queued ticks (e.g. cBlockHandler::Check) this tick
+ TickMobs(a_Dt);
+ m_MapManager.TickMaps();
TickQueuedTasks();
GetSimulatorManager()->Simulate(static_cast<float>(a_Dt.count()));