summaryrefslogtreecommitdiffstats
path: root/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h')
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h48
1 files changed, 27 insertions, 21 deletions
diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h
index 5f2026842..b40491820 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h
@@ -100,19 +100,32 @@ namespace RedstoneWireHandler
}
}
+ static bool IsYPTerracingBlocked(const cChunk & a_Chunk, const Vector3i a_Position)
+ {
+ const auto Position = a_Position + OffsetYP;
+
+ if (!cChunkDef::IsValidHeight(Position))
+ {
+ // Certainly cannot terrace at the top of the world:
+ return true;
+ }
+
+ const auto YPTerraceBlock = a_Chunk.GetBlock(Position);
+ return cBlockInfo::IsSolid(YPTerraceBlock) && !cBlockInfo::IsTransparent(YPTerraceBlock);
+ }
+
/** Temporary. Discovers a wire's connection state, including terracing, storing the block inside redstone chunk data.
TODO: once the server supports block states this should go in the block handler, with data saved in the world. */
- static void SetWireState(const cChunk & Chunk, const Vector3i Position)
+ static void SetWireState(const cChunk & a_Chunk, const Vector3i a_Position)
{
auto Block = Block::RedstoneWire::RedstoneWire();
- const auto YPTerraceBlock = Chunk.GetBlock(Position + OffsetYP);
- const bool IsYPTerracingBlocked = cBlockInfo::IsSolid(YPTerraceBlock) && !cBlockInfo::IsTransparent(YPTerraceBlock);
+ const bool IsYPTerracingBlocked = RedstoneWireHandler::IsYPTerracingBlocked(a_Chunk, a_Position);
// Loop through laterals, discovering terracing connections:
for (const auto & Offset : RelativeLaterals)
{
- auto Adjacent = Position + Offset;
- auto NeighbourChunk = Chunk.GetRelNeighborChunkAdjustCoords(Adjacent);
+ auto Adjacent = a_Position + Offset;
+ auto NeighbourChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(Adjacent);
if ((NeighbourChunk == nullptr) || !NeighbourChunk->IsValid())
{
@@ -131,7 +144,7 @@ namespace RedstoneWireHandler
// Temporary: this case will eventually be handled when wires are placed, with the state saved as blocks
// When a neighbour wire was loaded into its chunk, its neighbour chunks may not have loaded yet
// This function is called during chunk load (through AddBlock). Attempt to tell it its new state:
- if ((NeighbourChunk != &Chunk) && (LateralBlock == E_BLOCK_REDSTONE_WIRE))
+ if ((NeighbourChunk != &a_Chunk) && (LateralBlock == E_BLOCK_REDSTONE_WIRE))
{
auto & NeighbourBlock = DataForChunk(*NeighbourChunk).WireStates.find(Adjacent)->second;
SetDirectionState(-Offset, NeighbourBlock, TemporaryDirection::Side);
@@ -148,7 +161,7 @@ namespace RedstoneWireHandler
{
SetDirectionState(Offset, Block, cBlockInfo::IsTransparent(LateralBlock) ? TemporaryDirection::Side : TemporaryDirection::Up);
- if (NeighbourChunk != &Chunk)
+ if (NeighbourChunk != &a_Chunk)
{
auto & NeighbourBlock = DataForChunk(*NeighbourChunk).WireStates.find(Adjacent + OffsetYP)->second;
SetDirectionState(-Offset, NeighbourBlock, TemporaryDirection::Side);
@@ -166,7 +179,7 @@ namespace RedstoneWireHandler
{
SetDirectionState(Offset, Block, TemporaryDirection::Side);
- if (NeighbourChunk != &Chunk)
+ if (NeighbourChunk != &a_Chunk)
{
auto & NeighbourBlock = DataForChunk(*NeighbourChunk).WireStates.find(Adjacent + OffsetYM)->second;
SetDirectionState(-Offset, NeighbourBlock, TemporaryDirection::Up);
@@ -174,8 +187,8 @@ namespace RedstoneWireHandler
}
}
- auto & States = DataForChunk(Chunk).WireStates;
- const auto FindResult = States.find(Position);
+ auto & States = DataForChunk(a_Chunk).WireStates;
+ const auto FindResult = States.find(a_Position);
if (FindResult != States.end())
{
if (Block != FindResult->second)
@@ -184,13 +197,13 @@ namespace RedstoneWireHandler
// TODO: when state is stored as the block, the block handler updating via SetBlock will do this automatically
// When a wire changes connection state, it needs to update its neighbours:
- Chunk.GetWorld()->WakeUpSimulators(cChunkDef::RelativeToAbsolute(Position, Chunk.GetPos()));
+ a_Chunk.GetWorld()->WakeUpSimulators(cChunkDef::RelativeToAbsolute(a_Position, a_Chunk.GetPos()));
}
return;
}
- DataForChunk(Chunk).WireStates.emplace(Position, Block);
+ DataForChunk(a_Chunk).WireStates.emplace(a_Position, Block);
}
static PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
@@ -269,15 +282,8 @@ namespace RedstoneWireHandler
a_Chunk.SetMeta(a_Position, Power);
// Notify all positions, sans YP, to update:
- for (const auto & Offset : RelativeAdjacents)
- {
- if (Offset == OffsetYP)
- {
- continue;
- }
-
- UpdateAdjustedRelative(a_Chunk, CurrentlyTicking, a_Position, Offset);
- }
+ UpdateAdjustedRelative(a_Chunk, CurrentlyTicking, a_Position, OffsetYM);
+ UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position, RelativeLaterals);
}
static void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback)