diff options
Diffstat (limited to '')
-rw-r--r-- | src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h new file mode 100644 index 000000000..fbf6eb646 --- /dev/null +++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h @@ -0,0 +1,134 @@ + +#pragma once + +#include "RedstoneHandler.h" + + + + + +class cRedstoneWireHandler : public cRedstoneHandler +{ + typedef cRedstoneHandler super; +public: + + cRedstoneWireHandler(cWorld & a_World) : + super(a_World) + { + } + + inline static bool IsDirectlyConnectingMechanism(BLOCKTYPE a_Block) + { + switch (a_Block) + { + case E_BLOCK_REDSTONE_REPEATER_ON: + case E_BLOCK_REDSTONE_REPEATER_OFF: + case E_BLOCK_ACTIVE_COMPARATOR: + case E_BLOCK_INACTIVE_COMPARATOR: + case E_BLOCK_REDSTONE_TORCH_OFF: + case E_BLOCK_REDSTONE_TORCH_ON: + case E_BLOCK_REDSTONE_WIRE: return true; + default: return false; + } + } + + const cVector3iArray GetTerracingConnectionOffsets(const Vector3i & a_Position) + { + cVector3iArray RelativePositions; + bool IsYPTerracingBlocked = cBlockInfo::IsSolid(m_World.GetBlock(a_Position + OffsetYP())); + + for (const auto Adjacent : GetRelativeLaterals()) + { + if ( + !IsYPTerracingBlocked && + (m_World.GetBlock(a_Position + Adjacent + OffsetYP()) == E_BLOCK_REDSTONE_WIRE) + ) + { + RelativePositions.emplace_back(Adjacent + OffsetYP()); + } + + if ( + !cBlockInfo::IsSolid(m_World.GetBlock(a_Position + Adjacent)) && // IsYMTerracingBlocked (i.e. check block above lower terracing position, a.k.a. just the plain adjacent) + (m_World.GetBlock(a_Position + Adjacent + OffsetYM()) == E_BLOCK_REDSTONE_WIRE) + ) + { + RelativePositions.emplace_back(Adjacent + OffsetYM()); + } + } + + return RelativePositions; + } + + virtual unsigned char GetPowerDeliveredToPosition(const Vector3i & a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const Vector3i & a_QueryPosition, BLOCKTYPE a_QueryBlockType) override + { + if (a_QueryPosition == (a_Position + OffsetYP())) + { + // Wires do not power things above them + return 0; + } + + if (a_QueryBlockType != E_BLOCK_REDSTONE_WIRE) + { + // For mechanisms, wire of power one will still power them + a_Meta++; + } + + if ((a_QueryPosition != (a_Position + OffsetYM())) && !IsDirectlyConnectingMechanism(a_QueryBlockType)) + { + Vector3i PotentialOffset; + bool FoundOneBorderingMechanism = false; + + for (const auto & Offset : StaticAppend(GetRelativeLaterals(), GetTerracingConnectionOffsets(a_Position))) + { + if (IsDirectlyConnectingMechanism(m_World.GetBlock(Offset + a_Position))) + { + if (FoundOneBorderingMechanism) + { + return 0; + } + else + { + FoundOneBorderingMechanism = true; + PotentialOffset = { -Offset.x, 0, -Offset.z }; + } + } + } + + if (FoundOneBorderingMechanism && (a_QueryPosition != (a_Position + PotentialOffset))) + { + return 0; + } + } + + return (a_Meta != 0) ? --a_Meta : a_Meta; + } + + virtual unsigned char GetPowerLevel(const Vector3i & a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) override + { + UNUSED(a_Position); + UNUSED(a_BlockType); + return a_Meta; + } + + virtual cVector3iArray Update(const Vector3i & a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) override + { + UNUSED(a_BlockType); + LOGD("Evaluating dusty the wire (%d %d %d) %i", a_Position.x, a_Position.y, a_Position.z, a_PoweringData.PowerLevel); + + if (a_Meta != a_PoweringData.PowerLevel) + { + m_World.SetBlockMeta(a_Position, a_PoweringData.PowerLevel); + return GetAdjustedRelatives(a_Position, StaticAppend(StaticAppend(GetRelativeLaterals(), GetTerracingConnectionOffsets(a_Position)), cVector3iArray{ OffsetYM() })); + } + + return {}; + } + + virtual cVector3iArray GetValidSourcePositions(const Vector3i & a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) override + { + UNUSED(a_BlockType); + UNUSED(a_Meta); + + return GetAdjustedRelatives(a_Position, StaticAppend(GetRelativeAdjacents(), GetTerracingConnectionOffsets(a_Position))); + } +}; |