summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Simulator/RedstoneSimulator.cpp54
-rw-r--r--src/Simulator/RedstoneSimulator.h9
2 files changed, 62 insertions, 1 deletions
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 <sPoweredBlocks> PoweredBlocksList;
typedef std::vector <sLinkedPoweredBlocks> LinkedBlocksList;
typedef std::vector <sSimulatedPlayerToggleableList> SimulatedPlayerToggleableList;
+ typedef std::vector <sRepeatersDelayList> 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;