From aa3537112d5c69b676f2e0f594bba716487b401d Mon Sep 17 00:00:00 2001 From: Tycho Date: Mon, 16 Jun 2014 15:07:41 +0100 Subject: Moved repeater handling to seperate pass --- src/Simulator/IncrementalRedstoneSimulator.cpp | 157 ++++++++++--------------- src/Simulator/IncrementalRedstoneSimulator.h | 4 +- 2 files changed, 64 insertions(+), 97 deletions(-) (limited to 'src/Simulator') diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index f20f396f2..61258cd45 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -1,6 +1,8 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules +#include + #include "IncrementalRedstoneSimulator.h" #include "../BlockEntities/DropSpenserEntity.h" #include "../BlockEntities/NoteEntity.h" @@ -253,6 +255,8 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int ShouldUpdateSimulateOnceBlocks = true; } + HandleRedstoneRepeaterDelays(); + for (cRedstoneSimulatorChunkData::iterator dataitr = m_RedstoneSimulatorChunkData->begin(); dataitr != m_RedstoneSimulatorChunkData->end();) { if (dataitr->DataTwo) @@ -264,26 +268,6 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int switch (dataitr->Data) { case E_BLOCK_DAYLIGHT_SENSOR: HandleDaylightSensor(dataitr->x, dataitr->y, dataitr->z); break; - - case E_BLOCK_REDSTONE_REPEATER_OFF: - case E_BLOCK_REDSTONE_REPEATER_ON: - { - bool FoundItem = false; - for (RepeatersDelayList::iterator repeateritr = m_RepeatersDelayList->begin(); repeateritr != m_RepeatersDelayList->end(); ++repeateritr) - { - if (repeateritr->a_RelBlockPos == Vector3i(dataitr->x, dataitr->y, dataitr->z)) - { - HandleRedstoneRepeater(dataitr->x, dataitr->y, dataitr->z, dataitr->Data, repeateritr); - FoundItem = true; - break; - } - } - if (!FoundItem && ShouldUpdateSimulateOnceBlocks) - { - HandleRedstoneRepeater(dataitr->x, dataitr->y, dataitr->z, dataitr->Data, m_RepeatersDelayList->end()); - } - break; - } case E_BLOCK_WOODEN_PRESSURE_PLATE: case E_BLOCK_STONE_PRESSURE_PLATE: case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: @@ -339,6 +323,11 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int HandlePiston(dataitr->x, dataitr->y, dataitr->z); break; } + case E_BLOCK_REDSTONE_REPEATER_OFF: + case E_BLOCK_REDSTONE_REPEATER_ON: + { + HandleRedstoneRepeater(dataitr->x, dataitr->y, dataitr->z, dataitr->Data); + } case E_BLOCK_REDSTONE_TORCH_OFF: case E_BLOCK_REDSTONE_TORCH_ON: { @@ -493,7 +482,7 @@ void cIncrementalRedstoneSimulator::HandleRedstoneLever(int a_RelBlockX, int a_R { SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); - NIBBLETYPE Dir = cBlockLeverHandler::BlockMetaDataToBlockFace(Meta); + eBlockFace Dir = cBlockLeverHandler::BlockMetaDataToBlockFace(Meta); switch (Dir) // Now, flip the direction into the type used by SetBlockLinkedPowered() { case BLOCK_FACE_YP: @@ -562,7 +551,7 @@ void cIncrementalRedstoneSimulator::HandleRedstoneButton(int a_RelBlockX, int a_ { SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); - NIBBLETYPE Dir = cBlockButtonHandler::BlockMetaDataToBlockFace(Meta); + eBlockFace Dir = cBlockButtonHandler::BlockMetaDataToBlockFace(Meta); switch (Dir) // Now, flip the direction into the type used by SetBlockLinkedPowered() { case BLOCK_FACE_XP: @@ -749,7 +738,7 @@ void cIncrementalRedstoneSimulator::HandleRedstoneWire(int a_RelBlockX, int a_Re -void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState, RepeatersDelayList::iterator a_Itr) +void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState) { /* Repeater Orientation Mini Guide: =================================== @@ -776,102 +765,78 @@ void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_RelBlockX, int NIBBLETYPE a_Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ); bool IsOn = (a_MyState == E_BLOCK_REDSTONE_REPEATER_ON); - bool WereItrsChanged = false; if (!IsRepeaterLocked(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta)) // If we're locked, change nothing. Otherwise: { bool IsSelfPowered = IsRepeaterPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta); if (IsSelfPowered && !IsOn) // Queue a power change if powered, but not on and not locked. { - WereItrsChanged = QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, true); + QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, true); } else if (!IsSelfPowered && IsOn) // Queue a power change if unpowered, on, and not locked. { - WereItrsChanged = QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, false); - } - else if (a_Itr != m_RepeatersDelayList->end()) - { - return; - } - } - else if (a_Itr != m_RepeatersDelayList->end()) - { - return; - } - - if (WereItrsChanged) - { - for (a_Itr = m_RepeatersDelayList->begin(); a_Itr != m_RepeatersDelayList->end(); ++a_Itr) - { - if (a_Itr->a_RelBlockPos == Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ)) - { - // Leave a_Itr at where we found the entry - break; - } + QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, false); } } +} - // a_Itr may be passed with m_RepeatersDelayList::end, however, we can guarantee this iterator is always valid because... - // ...QueueRepeaterPowerChange is called to add an entry (and the above code updates iterator). However, if the repeater was locked or something similar... - // ...we will never get here because of the returns. - if (a_Itr->a_ElapsedTicks >= a_Itr->a_DelayTicks) // Has the elapsed ticks reached the target ticks? +void cIncrementalRedstoneSimulator::HandleRedstoneRepeaterDelays() +{ + for (RepeatersDelayList::iterator itr = m_RepeatersDelayList->begin(); itr != m_RepeatersDelayList->end(); itr++) { - if (a_Itr->ShouldPowerOn) + if (itr->a_ElapsedTicks >= itr->a_DelayTicks) // Has the elapsed ticks reached the target ticks? { - if (!IsOn) + int RelBlockX = itr->a_RelBlockPos.x; + int RelBlockY = itr->a_RelBlockPos.y; + int RelBlockZ = itr->a_RelBlockPos.z; + NIBBLETYPE Meta = m_Chunk->GetMeta(RelBlockX, RelBlockY, RelBlockZ); + if (itr->ShouldPowerOn) { - m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_REDSTONE_REPEATER_ON, a_Meta); // For performance - } + + m_Chunk->SetBlock(itr->a_RelBlockPos, E_BLOCK_REDSTONE_REPEATER_ON, Meta); // For performance - switch (a_Meta & 0x3) // We only want the direction (bottom) bits - { - case 0x0: + switch (Meta & 0x3) // We only want the direction (bottom) bits { - SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ); - SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_ZM); - break; - } - case 0x1: - { - SetBlockPowered(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ); - SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_XP); - break; - } - case 0x2: - { - SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ); - SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_ZP); - break; - } - case 0x3: - { - SetBlockPowered(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ); - SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_XM); - break; + case 0x0: + { + SetBlockPowered(RelBlockX, RelBlockY, RelBlockZ - 1, RelBlockX, RelBlockY, RelBlockZ); + SetDirectionLinkedPowered(RelBlockX, RelBlockY, RelBlockZ, BLOCK_FACE_ZM); + break; + } + case 0x1: + { + SetBlockPowered(RelBlockX + 1, RelBlockY, RelBlockZ, RelBlockX, RelBlockY, RelBlockZ); + SetDirectionLinkedPowered(RelBlockX, RelBlockY, RelBlockZ, BLOCK_FACE_XP); + break; + } + case 0x2: + { + SetBlockPowered(RelBlockX, RelBlockY, RelBlockZ + 1, RelBlockX, RelBlockY, RelBlockZ); + SetDirectionLinkedPowered(RelBlockX, RelBlockY, RelBlockZ, BLOCK_FACE_ZP); + break; + } + case 0x3: + { + SetBlockPowered(RelBlockX - 1, RelBlockY, RelBlockZ, RelBlockX, RelBlockY, RelBlockZ); + SetDirectionLinkedPowered(RelBlockX, RelBlockY, RelBlockZ, BLOCK_FACE_XM); + break; + } } } - - // Removal of the data entry will be handled in SimChunk - we still want to continue trying to power blocks, even if our delay time has reached - // Otherwise, the power state of blocks in front won't update after we have powered on - return; + else + { + m_Chunk->SetBlock(RelBlockX, RelBlockY, RelBlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, Meta); + } + m_RepeatersDelayList->erase(itr); } else { - if (IsOn) - { - m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, a_Meta); - } - m_RepeatersDelayList->erase(a_Itr); // We can remove off repeaters which don't need further updating - return; + // Apparently, incrementing ticks only works reliably here, and not in SimChunk; + // With a world with lots of redstone, the repeaters simply do not delay + // I am confounded to say why. Perhaps optimisation failure. + LOGD("Incremented a repeater @ {%i %i %i} | Elapsed ticks: %i | Target delay: %i", itr->a_RelBlockPos.x, itr->a_RelBlockPos.y, itr->a_RelBlockPos.z, itr->a_ElapsedTicks, itr->a_DelayTicks); + itr->a_ElapsedTicks++; } } - else - { - // Apparently, incrementing ticks only works reliably here, and not in SimChunk; - // With a world with lots of redstone, the repeaters simply do not delay - // I am confounded to say why. Perhaps optimisation failure. - LOGD("Incremented a repeater @ {%i %i %i} | Elapsed ticks: %i | Target delay: %i", a_Itr->a_RelBlockPos.x, a_Itr->a_RelBlockPos.y, a_Itr->a_RelBlockPos.z, a_Itr->a_ElapsedTicks, a_Itr->a_DelayTicks); - a_Itr->a_ElapsedTicks++; - } } diff --git a/src/Simulator/IncrementalRedstoneSimulator.h b/src/Simulator/IncrementalRedstoneSimulator.h index 1d6a49aca..9c1f9460c 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.h +++ b/src/Simulator/IncrementalRedstoneSimulator.h @@ -108,7 +108,9 @@ private: /** Handles redstone wire */ void HandleRedstoneWire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); /** Handles repeaters */ - void HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState, RepeatersDelayList::iterator a_Itr); + void HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState); + /** Handles delayed updates to Repeaters **/ + void HandleRedstoneRepeaterDelays(); /* ====================== */ /* ====== DEVICES ====== */ -- cgit v1.2.3 From 3a7c0c8ce9ff323690293dda6c8d2066db7ba985 Mon Sep 17 00:00:00 2001 From: Tycho Date: Mon, 16 Jun 2014 15:29:49 +0100 Subject: Fixed tigers weird enums --- src/Simulator/IncrementalRedstoneSimulator.cpp | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) (limited to 'src/Simulator') diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index 2e73195f1..79c23a7ba 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -501,20 +501,12 @@ void cIncrementalRedstoneSimulator::HandleRedstoneLever(int a_RelBlockX, int a_R eBlockFace Dir = cBlockLeverHandler::BlockMetaDataToBlockFace(Meta); switch (Dir) // Now, flip the direction into the type used by SetBlockLinkedPowered() { - case BLOCK_FACE_YP: - case BLOCK_FACE_XP: - case BLOCK_FACE_ZP: - { - Dir--; - break; - } - case BLOCK_FACE_XM: - case BLOCK_FACE_ZM: - case BLOCK_FACE_YM: - { - Dir++; - break; - } + case BLOCK_FACE_YP: Dir = BLOCK_FACE_YM; break; + case BLOCK_FACE_XP: Dir = BLOCK_FACE_XM; break; + case BLOCK_FACE_ZP: Dir = BLOCK_FACE_ZM; break; + case BLOCK_FACE_YM: Dir = BLOCK_FACE_YP; break; + case BLOCK_FACE_XM: Dir = BLOCK_FACE_XP; break; + case BLOCK_FACE_ZM :Dir = BLOCK_FACE_ZP; break; default: { ASSERT(!"Unhandled lever metadata!"); -- cgit v1.2.3 From 6fa99a211ec792ea4dbb4a303a26608de2cd5990 Mon Sep 17 00:00:00 2001 From: Tycho Date: Mon, 16 Jun 2014 17:55:58 +0100 Subject: Refactored reversing logic into seperate function --- src/Simulator/IncrementalRedstoneSimulator.cpp | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'src/Simulator') diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index 79c23a7ba..a49d0fb50 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -499,20 +499,9 @@ void cIncrementalRedstoneSimulator::HandleRedstoneLever(int a_RelBlockX, int a_R SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); eBlockFace Dir = cBlockLeverHandler::BlockMetaDataToBlockFace(Meta); - switch (Dir) // Now, flip the direction into the type used by SetBlockLinkedPowered() - { - case BLOCK_FACE_YP: Dir = BLOCK_FACE_YM; break; - case BLOCK_FACE_XP: Dir = BLOCK_FACE_XM; break; - case BLOCK_FACE_ZP: Dir = BLOCK_FACE_ZM; break; - case BLOCK_FACE_YM: Dir = BLOCK_FACE_YP; break; - case BLOCK_FACE_XM: Dir = BLOCK_FACE_XP; break; - case BLOCK_FACE_ZM :Dir = BLOCK_FACE_ZP; break; - default: - { - ASSERT(!"Unhandled lever metadata!"); - return; - } - } + + Dir = ReverseBlockFace(Dir); + SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Dir); } } -- cgit v1.2.3 From 74cd73058955683c277baf29f3cd7378c79292a9 Mon Sep 17 00:00:00 2001 From: Tycho Date: Mon, 16 Jun 2014 18:06:09 +0100 Subject: FIxed second weird enum --- src/Simulator/IncrementalRedstoneSimulator.cpp | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) (limited to 'src/Simulator') diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index a49d0fb50..1e7ff543d 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -549,26 +549,7 @@ void cIncrementalRedstoneSimulator::HandleRedstoneButton(int a_RelBlockX, int a_ SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); eBlockFace Dir = cBlockButtonHandler::BlockMetaDataToBlockFace(Meta); - switch (Dir) // Now, flip the direction into the type used by SetBlockLinkedPowered() - { - case BLOCK_FACE_XP: - case BLOCK_FACE_ZP: - { - Dir--; - break; - } - case BLOCK_FACE_XM: - case BLOCK_FACE_ZM: - { - Dir++; - break; - } - default: - { - ASSERT(!"Unhandled button metadata!"); - return; - } - } + Dir = ReverseBlockFace(Dir); SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Dir); } } -- cgit v1.2.3 From bcf798f260d55b6c8ce8e71ed619048c3e595877 Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 17 Jun 2014 19:47:32 +0200 Subject: Fix fence gate sound (Redstone simulator). --- src/Simulator/IncrementalRedstoneSimulator.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'src/Simulator') diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index 69c8b9f56..542bff8ad 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -553,8 +553,11 @@ void cIncrementalRedstoneSimulator::HandleFenceGate(int a_RelBlockX, int a_RelBl { if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true)) { - m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, MetaData | 0x4); - m_Chunk->BroadcastSoundParticleEffect(1003, BlockX, a_RelBlockY, BlockZ, 0); + if ((MetaData & 0x4) == 0) + { + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, MetaData | 0x4); + m_Chunk->BroadcastSoundParticleEffect(1003, BlockX, a_RelBlockY, BlockZ, 0); + } SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true); } } @@ -562,8 +565,11 @@ void cIncrementalRedstoneSimulator::HandleFenceGate(int a_RelBlockX, int a_RelBl { if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false)) { - m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, MetaData & 0xFFFFFFFB); - m_Chunk->BroadcastSoundParticleEffect(1003, BlockX, a_RelBlockY, BlockZ, 0); + if ((MetaData & 0x4) != 0) + { + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, MetaData & 0xFFFFFFFB); + m_Chunk->BroadcastSoundParticleEffect(1003, BlockX, a_RelBlockY, BlockZ, 0); + } SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false); } } -- cgit v1.2.3 From e8143de01bff31f9e153949d7ab5b0df82629541 Mon Sep 17 00:00:00 2001 From: archshift Date: Thu, 19 Jun 2014 01:49:56 -0700 Subject: Nullify deleted pointers. --- src/Simulator/FluidSimulator.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/Simulator') diff --git a/src/Simulator/FluidSimulator.cpp b/src/Simulator/FluidSimulator.cpp index 4a84084d2..f64955cb2 100644 --- a/src/Simulator/FluidSimulator.cpp +++ b/src/Simulator/FluidSimulator.cpp @@ -169,7 +169,8 @@ Direction cFluidSimulator::GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a X = Pos->x; Z = Pos->z; } - }else if(BlockID == E_BLOCK_AIR) + } + else if(BlockID == E_BLOCK_AIR) { LowestPoint = 9; //This always dominates X = Pos->x; @@ -177,6 +178,7 @@ Direction cFluidSimulator::GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a } delete Pos; + Pos = NULL; } if (LowestPoint == m_World.GetBlockMeta(a_X, a_Y, a_Z)) -- cgit v1.2.3 From 119ba562d50442ad78fc2dd573819759faadad44 Mon Sep 17 00:00:00 2001 From: worktycho Date: Sun, 22 Jun 2014 14:15:41 +0100 Subject: Fixed invalid iterator Fixes CID 60408 --- src/Simulator/IncrementalRedstoneSimulator.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/Simulator') diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index 183c527ca..ad4d1bee6 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -758,7 +758,7 @@ void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_RelBlockX, int void cIncrementalRedstoneSimulator::HandleRedstoneRepeaterDelays() { - for (RepeatersDelayList::iterator itr = m_RepeatersDelayList->begin(); itr != m_RepeatersDelayList->end(); itr++) + for (RepeatersDelayList::iterator itr = m_RepeatersDelayList->begin(); itr != m_RepeatersDelayList->end();) { if (itr->a_ElapsedTicks >= itr->a_DelayTicks) // Has the elapsed ticks reached the target ticks? @@ -804,7 +804,7 @@ void cIncrementalRedstoneSimulator::HandleRedstoneRepeaterDelays() { m_Chunk->SetBlock(RelBlockX, RelBlockY, RelBlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, Meta); } - m_RepeatersDelayList->erase(itr); + itr = m_RepeatersDelayList->erase(itr); } else { @@ -813,6 +813,7 @@ void cIncrementalRedstoneSimulator::HandleRedstoneRepeaterDelays() // I am confounded to say why. Perhaps optimisation failure. LOGD("Incremented a repeater @ {%i %i %i} | Elapsed ticks: %i | Target delay: %i", itr->a_RelBlockPos.x, itr->a_RelBlockPos.y, itr->a_RelBlockPos.z, itr->a_ElapsedTicks, itr->a_DelayTicks); itr->a_ElapsedTicks++; + itr++; } } } -- cgit v1.2.3 From 3c0452ebef2c37f030ce252229555fa95a89ed0d Mon Sep 17 00:00:00 2001 From: worktycho Date: Sun, 22 Jun 2014 14:17:07 +0100 Subject: Fixed missing break Fixes CID 68409 --- src/Simulator/IncrementalRedstoneSimulator.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/Simulator') diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index ad4d1bee6..9d0657dd6 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -343,6 +343,7 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int case E_BLOCK_REDSTONE_REPEATER_ON: { HandleRedstoneRepeater(dataitr->x, dataitr->y, dataitr->z, dataitr->Data); + break; } case E_BLOCK_REDSTONE_TORCH_OFF: case E_BLOCK_REDSTONE_TORCH_ON: -- cgit v1.2.3 From 3ec8b33b7660e1ab503ac9369b7d909957c9690a Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 22 Jun 2014 15:04:23 +0100 Subject: Fixed another daylight sensor bug Additionally fixed unpowering across chunks. --- src/Simulator/IncrementalRedstoneSimulator.cpp | 43 ++++++++++++++------------ 1 file changed, 23 insertions(+), 20 deletions(-) (limited to 'src/Simulator') diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index 183c527ca..a54867171 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -59,21 +59,20 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY, int RelZ = 0; BLOCKTYPE Block; NIBBLETYPE Meta; - cChunk * Chunk; + cChunk * OtherChunk = a_Chunk; if (a_OtherChunk != NULL) { RelX = a_BlockX - a_OtherChunk->GetPosX() * cChunkDef::Width; RelZ = a_BlockZ - a_OtherChunk->GetPosZ() * cChunkDef::Width; a_OtherChunk->GetBlockTypeMeta(RelX, a_BlockY, RelZ, Block, Meta); - Chunk = a_OtherChunk; + OtherChunk = a_OtherChunk; } else { RelX = a_BlockX - a_Chunk->GetPosX() * cChunkDef::Width; RelZ = a_BlockZ - a_Chunk->GetPosZ() * cChunkDef::Width; a_Chunk->GetBlockTypeMeta(RelX, a_BlockY, RelZ, Block, Meta); - Chunk = a_Chunk; } // Every time a block is changed (AddBlock called), we want to go through all lists and check to see if the coordiantes stored within are still valid @@ -92,7 +91,8 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY, { LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from powered blocks list as it no longer connected to a source", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); itr = PoweredBlocks->erase(itr); - Chunk->SetIsRedstoneDirty(true); + a_Chunk->SetIsRedstoneDirty(true); + OtherChunk->SetIsRedstoneDirty(true); continue; } else if ( @@ -107,21 +107,23 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY, { LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from powered blocks list due to present/past metadata mismatch", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); itr = PoweredBlocks->erase(itr); - Chunk->SetIsRedstoneDirty(true); + a_Chunk->SetIsRedstoneDirty(true); + OtherChunk->SetIsRedstoneDirty(true); continue; } else if (Block == E_BLOCK_DAYLIGHT_SENSOR) { - if (!m_World.IsChunkLighted(Chunk->GetPosX(), Chunk->GetPosZ())) + if (!m_World.IsChunkLighted(OtherChunk->GetPosX(), OtherChunk->GetPosZ())) { - m_World.QueueLightChunk(Chunk->GetPosX(), Chunk->GetPosZ()); + m_World.QueueLightChunk(OtherChunk->GetPosX(), OtherChunk->GetPosZ()); } else { - if (Chunk->GetTimeAlteredLight(Chunk->GetSkyLight(RelX, a_BlockY + 1, RelZ)) <= 7) + if (OtherChunk->GetTimeAlteredLight(OtherChunk->GetSkyLight(RelX, a_BlockY + 1, RelZ)) <= 7) { itr = PoweredBlocks->erase(itr); - Chunk->SetIsRedstoneDirty(true); + a_Chunk->SetIsRedstoneDirty(true); + OtherChunk->SetIsRedstoneDirty(true); continue; } } @@ -139,7 +141,8 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY, { LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list as it is no longer connected to a source", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); itr = LinkedPoweredBlocks->erase(itr); - Chunk->SetIsRedstoneDirty(true); + a_Chunk->SetIsRedstoneDirty(true); + OtherChunk->SetIsRedstoneDirty(true); continue; } else if ( @@ -153,7 +156,8 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY, { LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list due to present/past metadata mismatch", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); itr = LinkedPoweredBlocks->erase(itr); - Chunk->SetIsRedstoneDirty(true); + a_Chunk->SetIsRedstoneDirty(true); + OtherChunk->SetIsRedstoneDirty(true); continue; } } @@ -163,7 +167,8 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY, { LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list as it is no longer powered through a valid middle block", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); itr = LinkedPoweredBlocks->erase(itr); - Chunk->SetIsRedstoneDirty(true); + a_Chunk->SetIsRedstoneDirty(true); + OtherChunk->SetIsRedstoneDirty(true); continue; } } @@ -1072,19 +1077,17 @@ void cIncrementalRedstoneSimulator::HandleNoteBlock(int a_RelBlockX, int a_RelBl void cIncrementalRedstoneSimulator::HandleDaylightSensor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) { - int a_ChunkX, a_ChunkZ; - cChunkDef::BlockToChunk(a_RelBlockX, a_RelBlockZ, a_ChunkX, a_ChunkZ); + int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX, BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; + int ChunkX, ChunkZ; + cChunkDef::BlockToChunk(BlockX, BlockZ, ChunkX, ChunkZ); - if (!m_World.IsChunkLighted(a_ChunkX, a_ChunkZ)) + if (!m_World.IsChunkLighted(ChunkX, ChunkZ)) { - m_World.QueueLightChunk(a_ChunkX, a_ChunkZ); + m_World.QueueLightChunk(ChunkX, ChunkZ); } else { - int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; - int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; - NIBBLETYPE SkyLight = m_Chunk->GetTimeAlteredLight(m_World.GetBlockSkyLight(BlockX, a_RelBlockY + 1, BlockZ)); - if (SkyLight > 8) + if (m_Chunk->GetTimeAlteredLight(m_World.GetBlockSkyLight(BlockX, a_RelBlockY + 1, BlockZ)) > 8) { SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); } -- cgit v1.2.3 From bebfb230daf5c4e185791b6fc60f48e6f3dcfdf7 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 22 Jun 2014 17:29:02 +0200 Subject: Changed 0xFFFFFFFB to ~0x04 --- src/Simulator/IncrementalRedstoneSimulator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/Simulator') diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index d65d4eb45..6056fa554 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -566,7 +566,7 @@ void cIncrementalRedstoneSimulator::HandleFenceGate(int a_RelBlockX, int a_RelBl { if ((MetaData & 0x4) != 0) { - m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, MetaData & 0xFFFFFFFB); + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, MetaData & ~0x04); m_Chunk->BroadcastSoundParticleEffect(1003, BlockX, a_RelBlockY, BlockZ, 0); } SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false); -- cgit v1.2.3 From 69befa9851e8957d9efa996b08217287a87dee8c Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 27 Jun 2014 23:16:37 +0100 Subject: Fixed bad water/redstone simulator communication * Fixes #713 --- src/Simulator/FloodyFluidSimulator.cpp | 54 ++++++++++++++-------------------- 1 file changed, 22 insertions(+), 32 deletions(-) (limited to 'src/Simulator') diff --git a/src/Simulator/FloodyFluidSimulator.cpp b/src/Simulator/FloodyFluidSimulator.cpp index e95af3a1c..4ffda2365 100644 --- a/src/Simulator/FloodyFluidSimulator.cpp +++ b/src/Simulator/FloodyFluidSimulator.cpp @@ -217,14 +217,20 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i { ASSERT(a_NewMeta <= 8); // Invalid meta values ASSERT(a_NewMeta > 0); // Source blocks aren't spread - - BLOCKTYPE BlockType; - NIBBLETYPE BlockMeta; - if (!a_NearChunk->UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ, BlockType, BlockMeta)) + + a_NearChunk = a_NearChunk->GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); + if ((a_NearChunk == NULL) || (!a_NearChunk->IsValid())) { // Chunk not available return; } + + const int BlockX = a_NearChunk->GetPosX() * cChunkDef::Width + a_RelX; + const int BlockZ = a_NearChunk->GetPosZ() * cChunkDef::Width + a_RelZ; + + BLOCKTYPE BlockType; + NIBBLETYPE BlockMeta; + a_NearChunk->GetBlockTypeMeta(a_RelX, a_RelY, a_RelZ, BlockType, BlockMeta); if (IsAllowedBlock(BlockType)) { @@ -246,15 +252,9 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i a_RelX, a_RelY, a_RelZ, ItemTypeToString(NewBlock).c_str() ); - a_NearChunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, NewBlock, 0); + a_NearChunk->SetBlock(a_RelX, a_RelY, a_RelZ, NewBlock, 0); - int BaseX = a_NearChunk->GetPosX() * cChunkDef::Width; - int BaseZ = a_NearChunk->GetPosZ() * cChunkDef::Width; - - BaseX += a_RelX; - BaseZ += a_RelZ; - - a_NearChunk->BroadcastSoundEffect("random.fizz", BaseX * 8, a_RelY * 8, BaseZ * 8, 0.5f, 1.5f); + a_NearChunk->BroadcastSoundEffect("random.fizz", BlockX * 8, a_RelY * 8, BlockZ * 8, 0.5f, 1.5f); return; } } @@ -267,15 +267,9 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i FLOG(" Water flowing into lava, turning lava at rel {%d, %d, %d} into %s", a_RelX, a_RelY, a_RelZ, ItemTypeToString(NewBlock).c_str() ); - a_NearChunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, NewBlock, 0); - - int BaseX = a_NearChunk->GetPosX() * cChunkDef::Width; - int BaseZ = a_NearChunk->GetPosZ() * cChunkDef::Width; - - BaseX += a_RelX; - BaseZ += a_RelZ; + a_NearChunk->SetBlock(a_RelX, a_RelY, a_RelZ, NewBlock, 0); - a_NearChunk->BroadcastSoundEffect("random.fizz", BaseX * 8, a_RelY * 8, BaseZ * 8, 0.5f, 1.5f); + a_NearChunk->BroadcastSoundEffect("random.fizz", BlockX * 8, a_RelY * 8, BlockZ * 8, 0.5f, 1.5f); return; } } @@ -303,21 +297,17 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i m_World, PluginInterface, NULL, - a_NearChunk->GetPosX() * cChunkDef::Width + a_RelX, + BlockX, a_RelY, - a_NearChunk->GetPosZ() * cChunkDef::Width + a_RelZ + BlockZ ); } } // if (CanWashAway) - + // Spread: - FLOG(" Spreading to {%d, %d, %d} with meta %d", - a_NearChunk->GetPosX() * cChunkDef::Width + a_RelX, - a_RelY, - a_NearChunk->GetPosZ() * cChunkDef::Width + a_RelZ, - a_NewMeta - ); - a_NearChunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, m_FluidBlock, a_NewMeta); + FLOG(" Spreading to {%d, %d, %d} with meta %d", BlockX, a_RelY, BlockZ, a_NewMeta); + a_NearChunk->SetBlock(a_RelX, a_RelY, a_RelZ, m_FluidBlock, a_NewMeta); + m_World.GetSimulatorManager()->WakeUp(BlockX, a_RelY, BlockZ, a_NearChunk); HardenBlock(a_NearChunk, a_RelX, a_RelY, a_RelZ, m_FluidBlock, a_NewMeta); } @@ -409,13 +399,13 @@ bool cFloodyFluidSimulator::HardenBlock(cChunk * a_Chunk, int a_RelX, int a_RelY if (a_Meta == 0) { // Source lava block - a_Chunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_OBSIDIAN, 0); + a_Chunk->SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_OBSIDIAN, 0); return true; } // Ignore last lava level else if (a_Meta <= 4) { - a_Chunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_COBBLESTONE, 0); + a_Chunk->SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_COBBLESTONE, 0); return true; } } -- cgit v1.2.3 From 61cb08b54698e9b70f629858a6a9c5b389db8b3e Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 28 Jun 2014 20:44:34 +0100 Subject: Implemented tripwire(s) (hooks) * Fixes #944 --- src/Simulator/IncrementalRedstoneSimulator.cpp | 163 ++++++++++++++++++++++--- src/Simulator/IncrementalRedstoneSimulator.h | 8 ++ 2 files changed, 156 insertions(+), 15 deletions(-) (limited to 'src/Simulator') diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index 10446a879..866a5b65a 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -2,6 +2,7 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "IncrementalRedstoneSimulator.h" +#include "BoundingBox.h" #include "../BlockEntities/DropSpenserEntity.h" #include "../BlockEntities/NoteEntity.h" #include "../BlockEntities/CommandBlockEntity.h" @@ -12,10 +13,13 @@ #include "../Blocks/BlockButton.h" #include "../Blocks/BlockLever.h" #include "../Blocks/BlockPiston.h" +#include "../Blocks/BlockTripwireHook.h" + +#define WAKE_SIMULATOR_IF_DIRTY(a_Chunk, a_BlockX, a_BlockY, a_BlockZ) if (a_Chunk->IsRedstoneDirty()) WakeUp(a_BlockX, a_BlockY, a_BlockZ, a_Chunk); + - cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulator(cWorld & a_World) : super(a_World), @@ -99,10 +103,11 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY, // Changeable sources ((Block == E_BLOCK_REDSTONE_WIRE) && (Meta == 0)) || ((Block == E_BLOCK_LEVER) && !IsLeverOn(Meta)) || - ((Block == E_BLOCK_DETECTOR_RAIL) && (Meta & 0x08) == 0) || + ((Block == E_BLOCK_DETECTOR_RAIL) && ((Meta & 0x08) == 0)) || (((Block == E_BLOCK_STONE_BUTTON) || (Block == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(Meta))) || (((Block == E_BLOCK_STONE_PRESSURE_PLATE) || (Block == E_BLOCK_WOODEN_PRESSURE_PLATE)) && (Meta == 0)) || - (((Block == E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE) || (Block == E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE)) && (Meta == 0)) + (((Block == E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE) || (Block == E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE)) && (Meta == 0)) || + ((Block == E_BLOCK_TRIPWIRE_HOOK) && ((Meta & 0x08) == 0)) ) { LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from powered blocks list due to present/past metadata mismatch", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); @@ -289,6 +294,9 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int switch (dataitr->Data) { case E_BLOCK_DAYLIGHT_SENSOR: HandleDaylightSensor(dataitr->x, dataitr->y, dataitr->z); break; + case E_BLOCK_TRIPWIRE: HandleTripwire(dataitr->x, dataitr->y, dataitr->z); break; + case E_BLOCK_TRIPWIRE_HOOK: HandleTripwireHook(dataitr->x, dataitr->y, dataitr->z); break; + case E_BLOCK_WOODEN_PRESSURE_PLATE: case E_BLOCK_STONE_PRESSURE_PLATE: case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: @@ -1120,7 +1128,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R case E_BLOCK_STONE_PRESSURE_PLATE: { // MCS feature - stone pressure plates can only be triggered by players :D - cPlayer * a_Player = m_World.FindClosestPlayer(Vector3f(BlockX + 0.5f, (float)a_RelBlockY, BlockZ + 0.5f), 0.7f, false); + cPlayer * a_Player = m_World.FindClosestPlayer(Vector3f(BlockX + 0.5f, (float)a_RelBlockY, BlockZ + 0.5f), 0.5f, false); if (a_Player != NULL) { @@ -1131,7 +1139,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R else { m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, 0x0); - m_World.WakeUpSimulators(BlockX, a_RelBlockY, BlockZ); + WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ); } break; } @@ -1155,7 +1163,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R Vector3f BlockPos(m_X + 0.5f, (float)m_Y, m_Z + 0.5f); double Distance = (EntityPos - BlockPos).Length(); - if (Distance <= 0.7) + if (Distance <= 0.5) { m_NumberOfEntities++; } @@ -1177,7 +1185,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R }; cPressurePlateCallback PressurePlateCallback(BlockX, a_RelBlockY, BlockZ); - m_World.ForEachEntity(PressurePlateCallback); + m_World.ForEachEntityInChunk(m_Chunk->GetPosX(), m_Chunk->GetPosZ(), PressurePlateCallback); unsigned char Power; NIBBLETYPE Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ); @@ -1198,7 +1206,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R m_Chunk->BroadcastSoundEffect("random.click", (int)((BlockX + 0.5) * 8.0), (int)((a_RelBlockY + 0.1) * 8.0), (int)((BlockZ + 0.5) * 8.0), 0.3F, 0.6F); } m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_RAISED); - m_World.WakeUpSimulators(BlockX, a_RelBlockY, BlockZ); + WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ); } break; @@ -1223,7 +1231,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R Vector3f BlockPos(m_X + 0.5f, (float)m_Y, m_Z + 0.5f); double Distance = (EntityPos - BlockPos).Length(); - if (Distance <= 0.7) + if (Distance <= 0.5) { m_NumberOfEntities++; } @@ -1232,7 +1240,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R bool GetPowerLevel(unsigned char & a_PowerLevel) const { - a_PowerLevel = std::min((int)ceil(m_NumberOfEntities / (float)10), MAX_POWER_LEVEL); + a_PowerLevel = std::min((int)ceil(m_NumberOfEntities / 10.f), MAX_POWER_LEVEL); return (a_PowerLevel > 0); } @@ -1245,7 +1253,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R }; cPressurePlateCallback PressurePlateCallback(BlockX, a_RelBlockY, BlockZ); - m_World.ForEachEntity(PressurePlateCallback); + m_World.ForEachEntityInChunk(m_Chunk->GetPosX(), m_Chunk->GetPosZ(), PressurePlateCallback); unsigned char Power; NIBBLETYPE Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ); @@ -1266,7 +1274,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R m_Chunk->BroadcastSoundEffect("random.click", (int)((BlockX + 0.5) * 8.0), (int)((a_RelBlockY + 0.1) * 8.0), (int)((BlockZ + 0.5) * 8.0), 0.3F, 0.6F); } m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_RAISED); - m_World.WakeUpSimulators(BlockX, a_RelBlockY, BlockZ); + WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ); } break; @@ -1291,7 +1299,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R Vector3f BlockPos(m_X + 0.5f, (float)m_Y, m_Z + 0.5f); double Distance = (EntityPos - BlockPos).Length(); - if (Distance <= 0.7) + if (Distance <= 0.5) { m_FoundEntity = true; return true; // Break out, we only need to know for plates that at least one entity is on top @@ -1313,7 +1321,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R } ; cPressurePlateCallback PressurePlateCallback(BlockX, a_RelBlockY, BlockZ); - m_World.ForEachEntity(PressurePlateCallback); + m_World.ForEachEntityInChunk(m_Chunk->GetPosX(), m_Chunk->GetPosZ(), PressurePlateCallback); NIBBLETYPE Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ); if (PressurePlateCallback.FoundEntity()) @@ -1333,7 +1341,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R m_Chunk->BroadcastSoundEffect("random.click", (int)((BlockX + 0.5) * 8.0), (int)((a_RelBlockY + 0.1) * 8.0), (int)((BlockZ + 0.5) * 8.0), 0.3F, 0.6F); } m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_RAISED); - m_World.WakeUpSimulators(BlockX, a_RelBlockY, BlockZ); + WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ); } break; } @@ -1349,6 +1357,131 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R +void cIncrementalRedstoneSimulator::HandleTripwireHook(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) +{ + int BlockX = m_Chunk->GetPosX() * cChunkDef::Width + a_RelBlockX; + int BlockZ = m_Chunk->GetPosZ() * cChunkDef::Width + a_RelBlockZ; + int RelX = a_RelBlockX, RelZ = a_RelBlockZ; + bool FoundActivated = false; + eBlockFace FaceToGoTowards = cBlockTripwireHookHandler::MetadataToDirection(m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ)); + + for (int i = 0; i < 40; ++i) // Tripwires can be connected up to 40 blocks + { + BLOCKTYPE Type; + NIBBLETYPE Meta; + + AddFaceDirection(RelX, a_RelBlockY, RelZ, FaceToGoTowards); + m_Chunk->UnboundedRelGetBlock(RelX, a_RelBlockY, RelZ, Type, Meta); + + if (Type == E_BLOCK_TRIPWIRE) + { + if (Meta == 0x1) + { + FoundActivated = true; + } + } + else if (Type == E_BLOCK_TRIPWIRE_HOOK) + { + if (ReverseBlockFace(cBlockTripwireHookHandler::MetadataToDirection(Meta)) == FaceToGoTowards) + { + // Other hook not facing in opposite direction + break; + } + else + { + // Tripwire hook not connected at all, AND away all the power state bits + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x3); + WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ); + return; + } + } + else + { + // Tripwire hook not connected at all, AND away all the power state bits + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x3); + WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ); + return; + } + } + + if (FoundActivated) + { + // Connected and activated, set the 3rd and 4th highest bits + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) | 0xC); + SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); + } + else + { + // Connected but not activated, AND away the highest bit + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, (m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x7) | 0x4); + WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ); + } +} + + + + + +void cIncrementalRedstoneSimulator::HandleTripwire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) +{ + int BlockX = m_Chunk->GetPosX() * cChunkDef::Width + a_RelBlockX; + int BlockZ = m_Chunk->GetPosZ() * cChunkDef::Width + a_RelBlockZ; + + class cTripwireCallback : + public cEntityCallback + { + public: + cTripwireCallback(int a_BlockX, int a_BlockY, int a_BlockZ) : + m_FoundEntity(false), + m_X(a_BlockX), + m_Y(a_BlockY), + m_Z(a_BlockZ) + { + } + + virtual bool Item(cEntity * a_Entity) override + { + cBoundingBox bbWire(m_X, m_X + 1, m_Y, m_Y + 0.1, m_Z, m_Z + 1); + cBoundingBox bbEntity(a_Entity->GetPosition(), a_Entity->GetWidth() / 2, a_Entity->GetHeight()); + + if (bbEntity.DoesIntersect(bbWire)) + { + m_FoundEntity = true; + return true; // One entity is sufficient to trigger the wire + } + return false; + } + + bool FoundEntity(void) const + { + return m_FoundEntity; + } + + protected: + bool m_FoundEntity; + + int m_X; + int m_Y; + int m_Z; + }; + + cTripwireCallback TripwireCallback(BlockX, a_RelBlockY, BlockZ); + m_World.ForEachEntityInChunk(m_Chunk->GetPosX(), m_Chunk->GetPosZ(), TripwireCallback); + + if (TripwireCallback.FoundEntity()) + { + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, 0x1); + } + else + { + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, 0x0); + } +} + + + + + bool cIncrementalRedstoneSimulator::AreCoordsDirectlyPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) { int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; diff --git a/src/Simulator/IncrementalRedstoneSimulator.h b/src/Simulator/IncrementalRedstoneSimulator.h index 9c1f9460c..6cefdebf2 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.h +++ b/src/Simulator/IncrementalRedstoneSimulator.h @@ -102,6 +102,11 @@ private: void HandleDaylightSensor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); /** Handles pressure plates */ void HandlePressurePlate(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyType); + /** Handles tripwire hooks + Performs correct meta and power setting for self by going in the direction it faces and looking for a continous line of tripwire bounded by another oppositely facing hook + If this line is complete, it verifies that at least on wire reports an entity is on top (via its meta), and performs its task + */ + void HandleTripwireHook(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); /* ==================== */ /* ====== CARRIERS ====== */ @@ -134,6 +139,8 @@ private: void HandleFenceGate(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); /** Handles noteblocks */ void HandleNoteBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); + /** Handles tripwires */ + void HandleTripwire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); /* ===================== */ /* ====== Helper functions ====== */ @@ -271,6 +278,7 @@ private: case E_BLOCK_TNT: case E_BLOCK_TRAPDOOR: case E_BLOCK_TRIPWIRE_HOOK: + case E_BLOCK_TRIPWIRE: case E_BLOCK_WOODEN_BUTTON: case E_BLOCK_WOODEN_DOOR: case E_BLOCK_WOODEN_PRESSURE_PLATE: -- cgit v1.2.3 From ec2f576de69f2a6e73abb1aeadb173c0b2e12131 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 2 Jul 2014 22:25:18 +0100 Subject: Fixed c1deda5d8f01811efa5094e9375166acb69d50ed I keep on breaking stuff :P --- src/Simulator/IncrementalRedstoneSimulator.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/Simulator') diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index 866a5b65a..5af9a295d 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -1700,7 +1700,7 @@ bool cIncrementalRedstoneSimulator::IsWirePowered(int a_RelBlockX, int a_RelBloc { continue; } - a_PowerLevel = itr->a_PowerLevel; + a_PowerLevel = std::max(itr->a_PowerLevel , a_PowerLevel); // Get the highest power level (a_PowerLevel is initialised already and there CAN be multiple levels for one block) } for (LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks->begin(); itr != m_LinkedPoweredBlocks->end(); ++itr) // Check linked powered list @@ -1709,7 +1709,7 @@ bool cIncrementalRedstoneSimulator::IsWirePowered(int a_RelBlockX, int a_RelBloc { continue; } - a_PowerLevel = itr->a_PowerLevel; + a_PowerLevel = std::max(itr->a_PowerLevel, a_PowerLevel); } return (a_PowerLevel != 0); // Answer the inital question: is the wire powered? -- cgit v1.2.3