Cuberite
A lightweight, fast and extensible game server for Minecraft
ForEachSourceCallback.cpp
Go to the documentation of this file.
1 
2 #include "Globals.h"
3 
5 #include "BlockType.h"
6 #include "../../BlockInfo.h"
7 #include "../../Chunk.h"
9 #include "RedstoneHandler.h"
10 
11 
12 
13 
14 
15 ForEachSourceCallback::ForEachSourceCallback(const cChunk & Chunk, const Vector3i Position, const BLOCKTYPE CurrentBlock) :
16  Power(0),
17  m_Chunk(Chunk),
18  m_Position(Position),
19  m_CurrentBlock(CurrentBlock)
20 {
21 }
22 
23 
24 
25 
26 
28 {
29  if (!cChunkDef::IsValidHeight(Location))
30  {
31  return;
32  }
33 
34  const auto NeighbourChunk = m_Chunk.GetRelNeighborChunkAdjustCoords(Location);
35  if ((NeighbourChunk == nullptr) || !NeighbourChunk->IsValid())
36  {
37  return;
38  }
39 
40  const auto PotentialSourceBlock = NeighbourChunk->GetBlock(Location);
41  const auto NeighbourRelativeQueryPosition = cIncrementalRedstoneSimulatorChunkData::RebaseRelativePosition(m_Chunk, *NeighbourChunk, m_Position);
42 
43  if (!cBlockInfo::IsTransparent(PotentialSourceBlock))
44  {
45  Power = std::max(Power, QueryLinkedPower(*NeighbourChunk, NeighbourRelativeQueryPosition, m_CurrentBlock, Location));
46  }
47  else
48  {
49  Power = std::max(
50  Power,
52  *NeighbourChunk, Location, PotentialSourceBlock,
53  NeighbourRelativeQueryPosition, m_CurrentBlock, false
54  )
55  );
56  }
57 }
58 
59 
60 
61 
62 
64 {
65  const Vector3i OffsetYP(0, 1, 0);
66  const auto Above = m_Position + OffsetYP;
67 
68  if (Above.y == cChunkDef::Height)
69  {
70  return;
71  }
72 
73  // Object representing restarted power calculation where the
74  // block above this piston, dropspenser is requesting a power level.
75  ForEachSourceCallback QuasiQueryCallback(m_Chunk, Above, m_Chunk.GetBlock(Above));
76 
77  // Manually feed the callback object all positions that may deliver power to Above:
78  for (const auto & QuasiPowerOffset : cSimulator::GetLinkedOffsets(OffsetYP))
79  {
80  QuasiQueryCallback(m_Position + QuasiPowerOffset);
81  }
82 
83  // Get the results:
84  Power = std::max(Power, QuasiQueryCallback.Power);
85 }
86 
87 
88 
89 
90 
91 PowerLevel ForEachSourceCallback::QueryLinkedPower(const cChunk & Chunk, const Vector3i QueryPosition, const BLOCKTYPE QueryBlock, const Vector3i SolidBlockPosition)
92 {
93  PowerLevel Power = 0;
94 
95  // Loop through all linked powerable offsets in the direction requested:
96  for (const auto & Offset : cSimulator::GetLinkedOffsets(SolidBlockPosition - QueryPosition))
97  {
98  auto SourcePosition = QueryPosition + Offset;
99  if (!cChunkDef::IsValidHeight(SourcePosition))
100  {
101  continue;
102  }
103 
104  const auto NeighbourChunk = Chunk.GetRelNeighborChunkAdjustCoords(SourcePosition);
105  if ((NeighbourChunk == nullptr) || !NeighbourChunk->IsValid())
106  {
107  continue;
108  }
109 
110  // Conduit block's position, relative to NeighbourChunk.
111  const auto NeighbourRelativeSolidBlockPosition = cIncrementalRedstoneSimulatorChunkData::RebaseRelativePosition(Chunk, *NeighbourChunk, SolidBlockPosition);
112 
113  // Do a standard power query, but the requester's position is actually the solid block that will conduct power:
114  Power = std::max(
115  Power,
117  *NeighbourChunk, SourcePosition, NeighbourChunk->GetBlock(SourcePosition),
118  NeighbourRelativeSolidBlockPosition, QueryBlock, true
119  )
120  );
121  }
122 
123  return Power;
124 }
unsigned char BLOCKTYPE
The datatype used by blockdata.
Definition: ChunkDef.h:41
constexpr Vector3i OffsetYP
unsigned char PowerLevel
unsigned char Power(const BlockState Block)
PowerLevel GetPowerDeliveredToPosition(const cChunk &Chunk, const Vector3i Position, const BLOCKTYPE BlockType, const Vector3i QueryPosition, const BLOCKTYPE QueryBlockType, const bool IsLinked)
Asks a redstone component at the source position how much power it will deliver to the querying posit...
static bool IsTransparent(BLOCKTYPE Block)
Is a block transparent? (https://minecraft.wiki/w/Opacity)
Definition: BlockInfo.cpp:961
Definition: Chunk.h:36
BLOCKTYPE GetBlock(int a_RelX, int a_RelY, int a_RelZ) const
Definition: Chunk.h:146
cChunk * GetRelNeighborChunkAdjustCoords(Vector3i &a_RelPos) const
Returns the chunk into which the relatively-specified block belongs.
Definition: Chunk.cpp:1885
static bool IsValidHeight(Vector3i a_BlockPosition)
Validates a height-coordinate.
Definition: ChunkDef.h:185
static const int Height
Definition: ChunkDef.h:125
ForEachSourceCallback(const cChunk &Chunk, Vector3i Position, BLOCKTYPE CurrentBlock)
const BLOCKTYPE m_CurrentBlock
void operator()(Vector3i Location)
Callback invoked for each potential source position of the redstone component.
static PowerLevel QueryLinkedPower(const cChunk &Chunk, Vector3i QueryPosition, BLOCKTYPE QueryBlock, Vector3i SolidBlockPosition)
Asks redstone handlers adjacent to a solid block how much power they will deliver to the querying pos...
void CheckIndirectPower()
Callback invoked for blocks supporting quasiconnectivity.
static Vector3i RebaseRelativePosition(const cChunk &From, const cChunk &To, const Vector3i Position)
Adjust From-relative coordinates into To-relative coordinates.
static std::array< Vector3i, 5 > GetLinkedOffsets(Vector3i Offset)
For a given offset from a position, return the offsets that represent the adjacents of the newly offs...
Definition: Simulator.cpp:12