From 455686e3ade61999d377965e02315603959ae2a4 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 30 Nov 2013 12:11:39 +0000 Subject: [PATCH] Pistons no longer accept power through front face This fixes #60. --- src/Simulator/RedstoneSimulator.cpp | 97 ++++++++++++++++++++++++++++- src/Simulator/RedstoneSimulator.h | 2 + 2 files changed, 96 insertions(+), 3 deletions(-) diff --git a/src/Simulator/RedstoneSimulator.cpp b/src/Simulator/RedstoneSimulator.cpp index 9be53ed88..c4da2db3a 100644 --- a/src/Simulator/RedstoneSimulator.cpp +++ b/src/Simulator/RedstoneSimulator.cpp @@ -566,7 +566,7 @@ void cRedstoneSimulator::HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int void cRedstoneSimulator::HandlePiston(int a_BlockX, int a_BlockY, int a_BlockZ) { cPiston Piston(&m_World); - if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) + if (IsPistonPowered(a_BlockX, a_BlockY, a_BlockZ, m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) & 0x7)) // We only want the bottom three bits (4th controls extended-ness) { Piston.ExtendPiston(a_BlockX, a_BlockY, a_BlockZ); } @@ -774,7 +774,8 @@ bool cRedstoneSimulator::AreCoordsPowered(int a_BlockX, int a_BlockY, int a_Bloc bool cRedstoneSimulator::IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta) { - // Check through powered blocks list + // Repeaters cannot be powered by any face except their back; verify that this is true for a source + for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr) { sPoweredBlocks & Change = *itr; @@ -807,7 +808,6 @@ bool cRedstoneSimulator::IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_Blo } } - // Check linked powered list, 'middle' blocks for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr) { sLinkedPoweredBlocks & Change = *itr; @@ -844,6 +844,97 @@ bool cRedstoneSimulator::IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_Blo +bool cRedstoneSimulator::IsPistonPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta) +{ + // Pistons cannot be powered through their front face; this function verifies that a source meets this requirement + + for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr) + { + sPoweredBlocks & Change = *itr; + + if (!Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; } + + switch (a_Meta) // Pistons' metas are the directions they face; the source cannot be there + { + case BLOCK_FACE_YM: + { + if (!Change.a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY - 1, a_BlockZ))) { return true; } + break; + } + case BLOCK_FACE_YP: + { + if (!Change.a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY + 1, a_BlockZ))) { return true; } + break; + } + case BLOCK_FACE_ZM: + { + if (!Change.a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ - 1))) { return true; } + break; + } + case BLOCK_FACE_ZP: + { + if (!Change.a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ + 1))) { return true; } + break; + } + case BLOCK_FACE_XM: + { + if (!Change.a_SourcePos.Equals(Vector3i(a_BlockX - 1, a_BlockY, a_BlockZ))) { return true; } + break; + } + case BLOCK_FACE_XP: + { + if (!Change.a_SourcePos.Equals(Vector3i(a_BlockX + 1, a_BlockY, a_BlockZ))) { return true; } + break; + } + } + } + + for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr) + { + sLinkedPoweredBlocks & Change = *itr; + + if (!Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; } + + switch (a_Meta) + { + case BLOCK_FACE_YM: + { + if (!Change.a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY - 1, a_BlockZ))) { return true; } + break; + } + case BLOCK_FACE_YP: + { + if (!Change.a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY + 1, a_BlockZ))) { return true; } + break; + } + case BLOCK_FACE_ZM: + { + if (!Change.a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ - 1))) { return true; } + break; + } + case BLOCK_FACE_ZP: + { + if (!Change.a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ + 1))) { return true; } + break; + } + case BLOCK_FACE_XM: + { + if (!Change.a_MiddlePos.Equals(Vector3i(a_BlockX - 1, a_BlockY, a_BlockZ))) { return true; } + break; + } + case BLOCK_FACE_XP: + { + if (!Change.a_MiddlePos.Equals(Vector3i(a_BlockX + 1, a_BlockY, a_BlockZ))) { return true; } + break; + } + } + } + return false; // Source was in front of the piston's front face +} + + + + void cRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Direction, BLOCKTYPE a_SourceType) { diff --git a/src/Simulator/RedstoneSimulator.h b/src/Simulator/RedstoneSimulator.h index 9e244d7da..59400b614 100644 --- a/src/Simulator/RedstoneSimulator.h +++ b/src/Simulator/RedstoneSimulator.h @@ -111,6 +111,8 @@ private: bool AreCoordsPowered(int a_BlockX, int a_BlockY, int a_BlockZ); /// Returns if a repeater is powered bool IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta); + /// Returns if a piston is powered + bool IsPistonPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta); /// Returns if lever metadata marks it as emitting power bool IsLeverOn(NIBBLETYPE a_BlockMeta);