From 40eba5244ddd7045a9c3539c5f46c9921301ed90 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 8 Aug 2020 18:22:16 +0100 Subject: Remove the redstone solid block handler - Remove cSolidBlockHandler * Functionality now integrated into simulator dispatcher * Fix door double open/close issues, arisen due to the top/bottom halves getting different power + Small migration to block states for redstone wire --- .../ForEachSourceCallback.cpp | 113 +++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 src/Simulator/IncrementalRedstoneSimulator/ForEachSourceCallback.cpp (limited to 'src/Simulator/IncrementalRedstoneSimulator/ForEachSourceCallback.cpp') diff --git a/src/Simulator/IncrementalRedstoneSimulator/ForEachSourceCallback.cpp b/src/Simulator/IncrementalRedstoneSimulator/ForEachSourceCallback.cpp new file mode 100644 index 000000000..3bf0fc371 --- /dev/null +++ b/src/Simulator/IncrementalRedstoneSimulator/ForEachSourceCallback.cpp @@ -0,0 +1,113 @@ + +#include "Globals.h" + +#include "ForEachSourceCallback.h" +#include "IncrementalRedstoneSimulator.h" +#include "../../BlockInfo.h" +#include "../../Chunk.h" + + + + + +ForEachSourceCallback::ForEachSourceCallback(const cChunk & Chunk, const Vector3i Position, const BLOCKTYPE CurrentBlock) : + m_Chunk(Chunk), + m_Position(Position), + m_CurrentBlock(CurrentBlock) +{ +} + + + + + +bool ForEachSourceCallback::ShouldQueryLinkedPosition(const Vector3i Location, const BLOCKTYPE Block) +{ + switch (Block) + { + case E_BLOCK_BLOCK_OF_REDSTONE: + case E_BLOCK_TRAPPED_CHEST: return false; + default: return cBlockInfo::IsSolid(Block); + } +} + + + + + +void ForEachSourceCallback::operator()(Vector3i Location) +{ + if (!cChunk::IsValidHeight(Location.y)) + { + return; + } + + const auto NeighbourChunk = m_Chunk.GetRelNeighborChunkAdjustCoords(Location); + if ((NeighbourChunk == nullptr) || !NeighbourChunk->IsValid()) + { + return; + } + + const auto PotentialSourceBlock = NeighbourChunk->GetBlock(Location); + const auto NeighbourRelativeQueryPosition = cIncrementalRedstoneSimulatorChunkData::RebaseRelativePosition(m_Chunk, *NeighbourChunk, m_Position); + + if (ShouldQueryLinkedPosition(Location, PotentialSourceBlock)) + { + Power = std::max(Power, QueryLinkedPower(*NeighbourChunk, NeighbourRelativeQueryPosition, m_CurrentBlock, Location)); + } + else + { + Power = std::max(Power, QueryPower(*NeighbourChunk, Location, PotentialSourceBlock, NeighbourRelativeQueryPosition, m_CurrentBlock, false)); + } +} + + + + + +PoweringData ForEachSourceCallback::QueryPower(const cChunk & Chunk, const Vector3i SourcePosition, const BLOCKTYPE SourceBlock, const Vector3i QueryPosition, const BLOCKTYPE QueryBlock, const bool IsLinked) +{ + const auto PotentialSourceHandler = cIncrementalRedstoneSimulator::GetComponentHandler(SourceBlock); + if (PotentialSourceHandler == nullptr) + { + return {}; + } + + return + { + SourceBlock, + PotentialSourceHandler->GetPowerDeliveredToPosition( + Chunk, SourcePosition, SourceBlock, + QueryPosition, QueryBlock, IsLinked + ) + }; +} + + + + + +PoweringData ForEachSourceCallback::QueryLinkedPower(const cChunk & Chunk, const Vector3i QueryPosition, const BLOCKTYPE QueryBlock, const Vector3i SolidBlockPosition) +{ + PoweringData Power; + + for (const auto Offset : cSimulator::GetLinkedOffsets(SolidBlockPosition - QueryPosition)) + { + auto SourcePosition = QueryPosition + Offset; + if (!cChunk::IsValidHeight(SourcePosition.y)) + { + continue; + } + + const auto NeighbourChunk = Chunk.GetRelNeighborChunkAdjustCoords(SourcePosition); + if ((NeighbourChunk == nullptr) || !NeighbourChunk->IsValid()) + { + continue; + } + + const auto NeighbourRelativeSolidBlockPosition = cIncrementalRedstoneSimulatorChunkData::RebaseRelativePosition(Chunk, *NeighbourChunk, SolidBlockPosition); + Power = std::max(Power, QueryPower(*NeighbourChunk, SourcePosition, NeighbourChunk->GetBlock(SourcePosition), NeighbourRelativeSolidBlockPosition, QueryBlock, true)); + } + + return Power; +} -- cgit v1.2.3