diff options
author | Tiger Wang <ziwei.tiger@outlook.com> | 2020-08-08 19:22:16 +0200 |
---|---|---|
committer | Tiger Wang <ziwei.tiger@outlook.com> | 2020-08-08 19:22:16 +0200 |
commit | 40eba5244ddd7045a9c3539c5f46c9921301ed90 (patch) | |
tree | 9edf40e2e5033ad19ce8a0739668500e30de653e /src/Simulator/IncrementalRedstoneSimulator/ForEachSourceCallback.cpp | |
parent | const-ify some Chunk functions (diff) | |
download | cuberite-40eba5244ddd7045a9c3539c5f46c9921301ed90.tar cuberite-40eba5244ddd7045a9c3539c5f46c9921301ed90.tar.gz cuberite-40eba5244ddd7045a9c3539c5f46c9921301ed90.tar.bz2 cuberite-40eba5244ddd7045a9c3539c5f46c9921301ed90.tar.lz cuberite-40eba5244ddd7045a9c3539c5f46c9921301ed90.tar.xz cuberite-40eba5244ddd7045a9c3539c5f46c9921301ed90.tar.zst cuberite-40eba5244ddd7045a9c3539c5f46c9921301ed90.zip |
Diffstat (limited to 'src/Simulator/IncrementalRedstoneSimulator/ForEachSourceCallback.cpp')
-rw-r--r-- | src/Simulator/IncrementalRedstoneSimulator/ForEachSourceCallback.cpp | 113 |
1 files changed, 113 insertions, 0 deletions
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; +} |