summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTiger Wang <ziwei.tiger@outlook.com>2018-07-24 01:35:20 +0200
committerTiger Wang <ziwei.tiger@outlook.com>2018-07-25 16:29:53 +0200
commitb8ab03bc6b41dbe8262f87def3ff3513924315d4 (patch)
tree689ae898e310323b7574f23fff27ff4e00ec371e
parentReimplemented fall particles (diff)
downloadcuberite-b8ab03bc6b41dbe8262f87def3ff3513924315d4.tar
cuberite-b8ab03bc6b41dbe8262f87def3ff3513924315d4.tar.gz
cuberite-b8ab03bc6b41dbe8262f87def3ff3513924315d4.tar.bz2
cuberite-b8ab03bc6b41dbe8262f87def3ff3513924315d4.tar.lz
cuberite-b8ab03bc6b41dbe8262f87def3ff3513924315d4.tar.xz
cuberite-b8ab03bc6b41dbe8262f87def3ff3513924315d4.tar.zst
cuberite-b8ab03bc6b41dbe8262f87def3ff3513924315d4.zip
-rw-r--r--src/Blocks/BlockPiston.cpp158
-rw-r--r--src/Blocks/BlockPiston.h6
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/PistonHandler.h38
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/RedstoneSimulatorChunkData.h1
4 files changed, 117 insertions, 86 deletions
diff --git a/src/Blocks/BlockPiston.cpp b/src/Blocks/BlockPiston.cpp
index 16dd53daf..3fa421141 100644
--- a/src/Blocks/BlockPiston.cpp
+++ b/src/Blocks/BlockPiston.cpp
@@ -214,36 +214,58 @@ bool cBlockPistonHandler::CanPushBlock(
void cBlockPistonHandler::ExtendPiston(Vector3i a_BlockPos, cWorld & a_World)
{
- BLOCKTYPE pistonBlock;
- NIBBLETYPE pistonMeta;
- a_World.GetBlockTypeMeta(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, pistonBlock, pistonMeta);
-
- if (IsExtended(pistonMeta))
{
- // Already extended, bail out
- return;
+ // Broadcast block action first. Will do nothing if piston cannot in fact push
+
+ BLOCKTYPE pistonBlock;
+ NIBBLETYPE pistonMeta;
+ a_World.GetBlockTypeMeta(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, pistonBlock, pistonMeta);
+ a_World.BroadcastBlockAction(a_BlockPos, PistonExtendAction, pistonMeta, pistonBlock);
}
- Vector3i pushDir = MetadataToOffset(pistonMeta);
+ // Client expects the server to "play" the animation before setting the final blocks
+ // However, we don't confuse animation with the underlying state of the world, so emulate by delaying 1 tick
+ // (Probably why vanilla has so many dupe glitches with sand and pistons lolol)
- Vector3iSet blocksPushed;
- if (!CanPushBlock(a_BlockPos + pushDir, a_World, true, blocksPushed, pushDir))
- {
- // Can't push anything, bail out
- return;
- }
+ a_World.ScheduleTask(1, [a_BlockPos](cWorld & World)
+ {
+ BLOCKTYPE pistonBlock;
+ NIBBLETYPE pistonMeta;
+ World.GetBlockTypeMeta(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, pistonBlock, pistonMeta);
- a_World.BroadcastBlockAction(a_BlockPos, 0, pistonMeta, pistonBlock);
- a_World.BroadcastSoundEffect("block.piston.extend", a_BlockPos, 0.5f, 0.7f);
+ if ((pistonBlock != E_BLOCK_PISTON) && !IsSticky(pistonBlock))
+ {
+ // Ensure we operate on a piston to avoid spurious behaviour
+ // Note that the scheduled task may result in the block type of a_BlockPos changing
+ return;
+ }
- PushBlocks(blocksPushed, a_World, pushDir);
+ if (IsExtended(pistonMeta))
+ {
+ // Already extended, bail out
+ return;
+ }
- // Set the extension and the piston base correctly
- Vector3i extensionPos = a_BlockPos + pushDir;
- a_World.SetBlock(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, pistonBlock, pistonMeta | 0x8);
- a_World.SetBlock(
- extensionPos.x, extensionPos.y, extensionPos.z,
- E_BLOCK_PISTON_EXTENSION, pistonMeta | (IsSticky(pistonBlock) ? 8 : 0)
+ Vector3i pushDir = MetadataToOffset(pistonMeta);
+ Vector3iSet blocksPushed;
+ if (!CanPushBlock(a_BlockPos + pushDir, World, true, blocksPushed, pushDir))
+ {
+ // Can't push anything, bail out
+ return;
+ }
+ PushBlocks(blocksPushed, World, pushDir);
+
+ // Set the extension and the piston base correctly
+ Vector3i extensionPos = a_BlockPos + pushDir;
+ World.SetBlock(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, pistonBlock, pistonMeta | 0x8);
+ World.SetBlock(
+ extensionPos.x, extensionPos.y, extensionPos.z,
+ E_BLOCK_PISTON_EXTENSION, pistonMeta | (IsSticky(pistonBlock) ? 8 : 0)
+ );
+
+ // Play sound effect only if extended successfully
+ World.BroadcastSoundEffect("block.piston.extend", a_BlockPos, 0.5f, 0.7f);
+ }
);
}
@@ -253,52 +275,70 @@ void cBlockPistonHandler::ExtendPiston(Vector3i a_BlockPos, cWorld & a_World)
void cBlockPistonHandler::RetractPiston(Vector3i a_BlockPos, cWorld & a_World)
{
- BLOCKTYPE pistonBlock;
- NIBBLETYPE pistonMeta;
- a_World.GetBlockTypeMeta(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, pistonBlock, pistonMeta);
-
- if (!IsExtended(pistonMeta))
{
- // Already retracted, bail out
- return;
+ BLOCKTYPE pistonBlock;
+ NIBBLETYPE pistonMeta;
+ a_World.GetBlockTypeMeta(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, pistonBlock, pistonMeta);
+ a_World.BroadcastBlockAction(a_BlockPos, PistonRetractAction, pistonMeta, pistonBlock);
}
- Vector3i pushDir = MetadataToOffset(pistonMeta);
+ a_World.ScheduleTask(1, [a_BlockPos](cWorld & World)
+ {
+ BLOCKTYPE pistonBlock;
+ NIBBLETYPE pistonMeta;
+ World.GetBlockTypeMeta(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, pistonBlock, pistonMeta);
- // Check the extension:
- Vector3i extensionPos = a_BlockPos + pushDir;
- if (a_World.GetBlock(extensionPos) != E_BLOCK_PISTON_EXTENSION)
- {
- LOGD("%s: Piston without an extension - still extending, or just in an invalid state?", __FUNCTION__);
- return;
- }
+ if ((pistonBlock != E_BLOCK_PISTON) && !IsSticky(pistonBlock))
+ {
+ // Ensure we operate on a piston to avoid spurious behaviour
+ // Note that the scheduled task may result in the block type of a_BlockPos changing
+ return;
+ }
- // Remove Extension
- a_World.SetBlock(extensionPos.x, extensionPos.y, extensionPos.z, E_BLOCK_AIR, 0);
+ if (!IsExtended(pistonMeta))
+ {
+ // Already retracted, bail out
+ return;
+ }
- a_World.SetBlock(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, pistonBlock, pistonMeta & ~(8));
- a_World.BroadcastBlockAction(a_BlockPos, 1, pistonMeta & ~(8), pistonBlock);
- a_World.BroadcastSoundEffect("block.piston.contract", a_BlockPos, 0.5f, 0.7f);
+ Vector3i pushDir = MetadataToOffset(pistonMeta);
- if (!IsSticky(pistonBlock))
- {
- // No need for block pulling, bail out
- return;
- }
+ // Check the extension:
+ Vector3i extensionPos = a_BlockPos + pushDir;
+ if (World.GetBlock(extensionPos) != E_BLOCK_PISTON_EXTENSION)
+ {
+ LOGD("%s: Piston without an extension - still extending, or just in an invalid state?", __FUNCTION__);
+ return;
+ }
- // Get the block to pull
- a_BlockPos += pushDir * 2;
- // Try to "push" the pulling block in the opposite direction
- pushDir *= -1;
+ // Remove extension, update base state
+ World.SetBlock(extensionPos.x, extensionPos.y, extensionPos.z, E_BLOCK_AIR, 0);
+ World.SetBlock(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, pistonBlock, pistonMeta & ~(8));
- Vector3iSet pushedBlocks;
- if (!CanPushBlock(a_BlockPos, a_World, false, pushedBlocks, pushDir))
- {
- // Not pushable, bail out
- return;
- }
+ // (Retraction is always successful, but play in the task for consistency)
+ World.BroadcastSoundEffect("block.piston.contract", a_BlockPos, 0.5f, 0.7f);
- PushBlocks(pushedBlocks, a_World, pushDir);
+ if (!IsSticky(pistonBlock))
+ {
+ // No need for block pulling, bail out
+ return;
+ }
+
+ // Get the block to pull
+ Vector3i AdjustedPosition = a_BlockPos + pushDir * 2;
+ // Try to "push" the pulling block in the opposite direction
+ pushDir *= -1;
+
+ Vector3iSet pushedBlocks;
+ if (!CanPushBlock(AdjustedPosition, World, false, pushedBlocks, pushDir))
+ {
+ // Not pushable, bail out
+ return;
+ }
+
+ PushBlocks(pushedBlocks, World, pushDir);
+ }
+ );
}
diff --git a/src/Blocks/BlockPiston.h b/src/Blocks/BlockPiston.h
index 21ebbcd39..e604cd38e 100644
--- a/src/Blocks/BlockPiston.h
+++ b/src/Blocks/BlockPiston.h
@@ -100,6 +100,12 @@ private:
typedef std::unordered_set<Vector3i, VectorHasher<int>> Vector3iSet;
+ /** Piston extension block action */
+ static const Byte PistonExtendAction = 0U;
+
+ /** Piston retraction block action */
+ static const Byte PistonRetractAction = 1U;
+
/** Returns true if the piston (specified by blocktype) is a sticky piston */
static inline bool IsSticky(BLOCKTYPE a_BlockType) { return (a_BlockType == E_BLOCK_STICKY_PISTON); }
diff --git a/src/Simulator/IncrementalRedstoneSimulator/PistonHandler.h b/src/Simulator/IncrementalRedstoneSimulator/PistonHandler.h
index 01742b13c..de001a9e5 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/PistonHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/PistonHandler.h
@@ -36,39 +36,25 @@ public:
virtual cVector3iArray Update(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
{
// LOGD("Evaluating pisty the piston (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- auto Data = static_cast<cIncrementalRedstoneSimulator *>(a_World.GetRedstoneSimulator())->GetChunkData();
- auto DelayInfo = Data->GetMechanismDelayInfo(a_Position);
- // Delay is used here to prevent an infinite loop (#3168)
- if (DelayInfo == nullptr)
+ bool ShouldBeExtended = (a_PoweringData.PowerLevel != 0);
+ if (ShouldBeExtended == cBlockPistonHandler::IsExtended(a_Meta))
{
- bool ShouldBeExtended = (a_PoweringData.PowerLevel != 0);
- if (ShouldBeExtended != cBlockPistonHandler::IsExtended(a_Meta))
- {
- Data->m_MechanismDelays[a_Position] = std::make_pair(1, ShouldBeExtended);
- }
+ return {};
+ }
+
+ if (ShouldBeExtended)
+ {
+ cBlockPistonHandler::ExtendPiston(a_Position, a_World);
}
else
{
- int DelayTicks;
- bool ShouldBeExtended;
- std::tie(DelayTicks, ShouldBeExtended) = *DelayInfo;
-
- if (DelayTicks == 0)
- {
- if (ShouldBeExtended)
- {
- cBlockPistonHandler::ExtendPiston(a_Position, a_World);
- }
- else
- {
- cBlockPistonHandler::RetractPiston(a_Position, a_World);
- }
-
- Data->m_MechanismDelays.erase(a_Position);
- }
+ cBlockPistonHandler::RetractPiston(a_Position, a_World);
}
+ // It is necessary to delay after a signal to prevent an infinite loop (#3168)
+ // However, that is present as a side effect of the implementation of piston animation in Blocks\BlockPiston.cpp
+
return {};
}
diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneSimulatorChunkData.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneSimulatorChunkData.h
index 83374e311..f0fd8d512 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneSimulatorChunkData.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneSimulatorChunkData.h
@@ -60,7 +60,6 @@ public:
/** Structure storing position of mechanism + it's delay ticks (countdown) & if to power on */
std::unordered_map<Vector3i, std::pair<int, bool>, VectorHasher<int>> m_MechanismDelays;
- std::unordered_map<Vector3i, bool, VectorHasher<int>> m_UpdateOncePositions;
private: