summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Chunk.h1
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp63
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h5
3 files changed, 63 insertions, 6 deletions
diff --git a/src/Chunk.h b/src/Chunk.h
index 39dc07a9f..7ba12f5ef 100644
--- a/src/Chunk.h
+++ b/src/Chunk.h
@@ -151,6 +151,7 @@ public:
int GetPosX(void) const { return m_PosX; }
int GetPosZ(void) const { return m_PosZ; }
+ cChunkCoords GetPos() const { return {m_PosX, m_PosZ}; }
cWorld * GetWorld(void) const { return m_World; }
diff --git a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp
index ddd682288..6be03c947 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp
+++ b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp
@@ -157,8 +157,7 @@ void cIncrementalRedstoneSimulator::Simulate(float a_dt)
if (CurrentHandler == nullptr) // Block at CurrentPosition doesn't have a corresponding redstone handler
{
// Clean up cached PowerData for CurrentPosition
- static_cast<cIncrementalRedstoneSimulator *>(m_World.GetRedstoneSimulator())->GetChunkData()->ErasePowerData(CurrentLocation);
-
+ GetChunkData()->ErasePowerData(CurrentLocation);
continue;
}
@@ -193,3 +192,63 @@ void cIncrementalRedstoneSimulator::Simulate(float a_dt)
}
}
}
+
+
+
+
+
+void cIncrementalRedstoneSimulator::AddBlock(Vector3i a_Block, cChunk * a_Chunk)
+{
+ // Can't inspect block, so queue update anyway
+ if (a_Chunk == nullptr)
+ {
+ m_Data.WakeUp(a_Block);
+ return;
+ }
+
+ const auto RelPos = cChunkDef::AbsoluteToRelative(a_Block, a_Chunk->GetPos());
+ const auto CurBlock = a_Chunk->GetBlock(RelPos);
+
+ // Always update redstone devices
+ if (IsRedstone(CurBlock))
+ {
+ m_Data.WakeUp(a_Block);
+ return;
+ }
+
+ // Never update blocks without a handler
+ if (GetComponentHandler(CurBlock) == nullptr)
+ {
+ GetChunkData()->ErasePowerData(a_Block);
+ return;
+ }
+
+ // Only update others if there is a redstone device nearby
+ for (int x = -1; x < 2; ++x)
+ {
+ for (int y = -1; y < 2; ++y)
+ {
+ if (!cChunkDef::IsValidHeight(RelPos.y + y))
+ {
+ continue;
+ }
+
+ for (int z = -1; z < 2; ++z)
+ {
+ auto CheckPos = RelPos + Vector3i{x, y, z};
+ BLOCKTYPE Block;
+ NIBBLETYPE Meta;
+
+ // If we can't read the block, assume it is a mechanism
+ if (
+ !a_Chunk->UnboundedRelGetBlock(CheckPos, Block, Meta) ||
+ IsRedstone(Block)
+ )
+ {
+ m_Data.WakeUp(a_Block);
+ return;
+ }
+ }
+ }
+ }
+}
diff --git a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h
index e00db39b5..850bb30c4 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h
@@ -31,10 +31,7 @@ public:
return IsRedstone(a_BlockType);
}
- virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) override
- {
- m_Data.WakeUp(a_Block);
- }
+ virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) override;
/** Returns if a block is a mechanism (something that accepts power and does something)
Used by torches to determine if they will power a block