From 1dec73be0b3967796fc0baf43e19cbb6abd09c1e Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 10 Dec 2013 00:21:24 +0000 Subject: Added repeater delays They DO sometimes get stuck though :P --- src/Simulator/RedstoneSimulator.cpp | 54 ++++++++++++++++++++++++++++++++++++- src/Simulator/RedstoneSimulator.h | 9 +++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/Simulator/RedstoneSimulator.cpp b/src/Simulator/RedstoneSimulator.cpp index c5fc1fb3f..2325ce6b6 100644 --- a/src/Simulator/RedstoneSimulator.cpp +++ b/src/Simulator/RedstoneSimulator.cpp @@ -543,6 +543,33 @@ void cRedstoneSimulator::HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int { if (!IsOn) { + // If repeater is not on already (and is POWERED), see if it is in repeater list, or has reached delay time + for (RepeatersDelayList::iterator itr = m_RepeatersDelayList.begin(); itr != m_RepeatersDelayList.end(); itr++) + { + if (itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) + { + if (itr->a_DelayTicks <= itr->a_ElapsedTicks) // Shouldn't need <=; just in case something happens + { + m_RepeatersDelayList.erase(itr); + goto powerrepeater; // Delay time reached, break straight out, and into the powering code + } + else + { + itr->a_ElapsedTicks++; // Increment elapsed ticks and quit + return; + } + } + } + + // Self not in list, add self to list + sRepeatersDelayList RC; + RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ); + RC.a_DelayTicks = ((a_Meta & 0xC) >> 0x2) + 1; // Gets the top two bits (delay time), shifts them into the lower two bits, and adds one (meta 0 = 1 tick; 1 = 2 etc.) + RC.a_ElapsedTicks = 0; + m_RepeatersDelayList.push_back(RC); + return; + +powerrepeater: m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON, a_Meta); // Only set if not on; SetBlock otherwise server doesn't set it in time for SimulateChunk's invalidation } switch (a_Meta & 0x3) // We only want the direction (bottom) bits @@ -577,7 +604,32 @@ void cRedstoneSimulator::HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int { if (IsOn) { - m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, a_Meta); + // If repeater is not off already (and is NOT POWERED), see if it is in repeater list, or has reached delay time + for (RepeatersDelayList::iterator itr = m_RepeatersDelayList.begin(); itr != m_RepeatersDelayList.end(); itr++) + { + if (itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) + { + if (itr->a_DelayTicks <= itr->a_ElapsedTicks) // Shouldn't need <=; just in case something happens + { + m_RepeatersDelayList.erase(itr); + m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, a_Meta); + return; + } + else + { + itr->a_ElapsedTicks++; // Increment elapsed ticks and quit + return; + } + } + } + + // Self not in list, add self to list + sRepeatersDelayList RC; + RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ); + RC.a_DelayTicks = ((a_Meta & 0xC) >> 0x2) + 1; + RC.a_ElapsedTicks = 0; + m_RepeatersDelayList.push_back(RC); + return; } } } diff --git a/src/Simulator/RedstoneSimulator.h b/src/Simulator/RedstoneSimulator.h index e094150e8..1d85c0634 100644 --- a/src/Simulator/RedstoneSimulator.h +++ b/src/Simulator/RedstoneSimulator.h @@ -56,14 +56,23 @@ private: Vector3i a_BlockPos; bool WasLastStatePowered; }; + + struct sRepeatersDelayList + { + Vector3i a_BlockPos; + short a_DelayTicks; + short a_ElapsedTicks; + }; typedef std::vector PoweredBlocksList; typedef std::vector LinkedBlocksList; typedef std::vector SimulatedPlayerToggleableList; + typedef std::vector RepeatersDelayList; PoweredBlocksList m_PoweredBlocks; LinkedBlocksList m_LinkedPoweredBlocks; SimulatedPlayerToggleableList m_SimulatedPlayerToggleableBlocks; + RepeatersDelayList m_RepeatersDelayList; virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override; -- cgit v1.2.3