summaryrefslogtreecommitdiffstats
path: root/src/Simulator
diff options
context:
space:
mode:
Diffstat (limited to 'src/Simulator')
-rw-r--r--src/Simulator/DelayedFluidSimulator.cpp13
-rw-r--r--src/Simulator/DelayedFluidSimulator.h39
-rw-r--r--src/Simulator/FireSimulator.cpp78
-rw-r--r--src/Simulator/FireSimulator.h16
-rw-r--r--src/Simulator/FloodyFluidSimulator.cpp115
-rw-r--r--src/Simulator/FloodyFluidSimulator.h35
-rw-r--r--src/Simulator/FluidSimulator.cpp27
-rw-r--r--src/Simulator/FluidSimulator.h27
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/CommandBlockHandler.h83
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/DaylightSensorHandler.h104
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/DoorHandler.h160
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/DropSpenserHandler.h126
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/ForEachSourceCallback.cpp45
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/ForEachSourceCallback.h17
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/HopperHandler.h99
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp12
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h11
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/NoteBlockHandler.h83
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/ObserverHandler.h178
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/PistonHandler.h111
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/PoweredRailHandler.h144
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/PressurePlateHandler.h319
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/RedstoneBlockHandler.h68
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/RedstoneComparatorHandler.h221
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/RedstoneDataHelper.h68
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/RedstoneHandler.cpp184
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/RedstoneHandler.h53
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/RedstoneLampHandler.h78
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/RedstoneRepeaterHandler.h255
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/RedstoneSimulatorChunkData.h19
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/RedstoneToggleHandler.h158
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/RedstoneTorchHandler.h149
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h433
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/SmallGateHandler.h80
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/TNTHandler.h76
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/TrappedChestHandler.h89
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/TripwireHookHandler.h178
-rw-r--r--src/Simulator/NoopFluidSimulator.h11
-rw-r--r--src/Simulator/NoopRedstoneSimulator.h15
-rw-r--r--src/Simulator/RedstoneSimulator.h13
-rw-r--r--src/Simulator/SandSimulator.cpp24
-rw-r--r--src/Simulator/SandSimulator.h19
-rw-r--r--src/Simulator/Simulator.cpp66
-rw-r--r--src/Simulator/Simulator.h39
-rw-r--r--src/Simulator/SimulatorManager.cpp49
-rw-r--r--src/Simulator/SimulatorManager.h20
-rw-r--r--src/Simulator/VanillaFluidSimulator.cpp26
-rw-r--r--src/Simulator/VanillaFluidSimulator.h24
-rw-r--r--src/Simulator/VaporizeFluidSimulator.cpp15
-rw-r--r--src/Simulator/VaporizeFluidSimulator.h11
50 files changed, 2382 insertions, 1901 deletions
diff --git a/src/Simulator/DelayedFluidSimulator.cpp b/src/Simulator/DelayedFluidSimulator.cpp
index 7e62acd04..0f01064e7 100644
--- a/src/Simulator/DelayedFluidSimulator.cpp
+++ b/src/Simulator/DelayedFluidSimulator.cpp
@@ -65,7 +65,12 @@ cDelayedFluidSimulatorChunkData::~cDelayedFluidSimulatorChunkData()
////////////////////////////////////////////////////////////////////////////////
// cDelayedFluidSimulator:
-cDelayedFluidSimulator::cDelayedFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid, int a_TickDelay) :
+cDelayedFluidSimulator::cDelayedFluidSimulator(
+ cWorld & a_World,
+ BLOCKTYPE a_Fluid,
+ BLOCKTYPE a_StationaryFluid,
+ int a_TickDelay
+) :
Super(a_World, a_Fluid, a_StationaryFluid),
m_TickDelay(a_TickDelay),
m_AddSlotNum(a_TickDelay - 1),
@@ -94,7 +99,8 @@ void cDelayedFluidSimulator::Simulate(float a_Dt)
void cDelayedFluidSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
{
- auto ChunkDataRaw = (m_FluidBlock == E_BLOCK_WATER) ? a_Chunk->GetWaterSimulatorData() : a_Chunk->GetLavaSimulatorData();
+ auto ChunkDataRaw =
+ (m_FluidBlock == E_BLOCK_WATER) ? a_Chunk->GetWaterSimulatorData() : a_Chunk->GetLavaSimulatorData();
cDelayedFluidSimulatorChunkData * ChunkData = static_cast<cDelayedFluidSimulatorChunkData *>(ChunkDataRaw);
cDelayedFluidSimulatorChunkData::cSlot & Slot = ChunkData->m_Slots[m_SimSlotNum];
@@ -126,7 +132,8 @@ void cDelayedFluidSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLO
return;
}
- auto ChunkDataRaw = (m_FluidBlock == E_BLOCK_WATER) ? a_Chunk.GetWaterSimulatorData() : a_Chunk.GetLavaSimulatorData();
+ auto ChunkDataRaw =
+ (m_FluidBlock == E_BLOCK_WATER) ? a_Chunk.GetWaterSimulatorData() : a_Chunk.GetLavaSimulatorData();
cDelayedFluidSimulatorChunkData * ChunkData = static_cast<cDelayedFluidSimulatorChunkData *>(ChunkDataRaw);
cDelayedFluidSimulatorChunkData::cSlot & Slot = ChunkData->m_Slots[m_AddSlotNum];
diff --git a/src/Simulator/DelayedFluidSimulator.h b/src/Simulator/DelayedFluidSimulator.h
index 312bc1ff9..01d25ae01 100644
--- a/src/Simulator/DelayedFluidSimulator.h
+++ b/src/Simulator/DelayedFluidSimulator.h
@@ -15,53 +15,53 @@
-class cDelayedFluidSimulatorChunkData :
- public cFluidSimulatorData
+class cDelayedFluidSimulatorChunkData : public cFluidSimulatorData
{
-public:
+ public:
class cSlot
{
- public:
+ public:
/** Returns true if the specified block is stored */
bool HasBlock(int a_RelX, int a_RelY, int a_RelZ);
- /** Adds the specified block unless already present; returns true if added, false if the block was already present */
+ /** Adds the specified block unless already present; returns true if added, false if the block was already
+ * present */
bool Add(int a_RelX, int a_RelY, int a_RelZ);
/** Array of block containers, each item stores blocks for one Z coord
size_t param is the block index (for faster duplicate comparison in Add())
*/
std::vector<cCoordWithData<size_t>> m_Blocks[16];
- } ;
+ };
cDelayedFluidSimulatorChunkData(int a_TickDelay);
virtual ~cDelayedFluidSimulatorChunkData() override;
/** Slots, one for each delay tick, each containing the blocks to simulate */
cSlot * m_Slots;
-} ;
+};
-class cDelayedFluidSimulator:
- public cFluidSimulator
+class cDelayedFluidSimulator : public cFluidSimulator
{
using Super = cFluidSimulator;
-public:
-
+ public:
cDelayedFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid, int a_TickDelay);
-protected:
-
+ protected:
virtual void Simulate(float a_Dt) override;
virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override;
virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override;
- virtual cFluidSimulatorData * CreateChunkData(void) override { return new cDelayedFluidSimulatorChunkData(m_TickDelay); }
+ virtual cFluidSimulatorData * CreateChunkData(void) override
+ {
+ return new cDelayedFluidSimulatorChunkData(m_TickDelay);
+ }
- int m_TickDelay; // Count of the m_Slots array in each ChunkData
+ int m_TickDelay; // Count of the m_Slots array in each ChunkData
int m_AddSlotNum; // Index into m_Slots[] where to add new blocks in each ChunkData
int m_SimSlotNum; // Index into m_Slots[] where to simulate blocks in each ChunkData
@@ -71,10 +71,7 @@ protected:
| 0 | 1 | ... | m_AddSlotNum | m_SimSlotNum | ... | m_TickDelay - 1 |
| adding blocks here ^ | ^ simulating here */
- /** Called from SimulateChunk() to simulate each block in one slot of blocks. Descendants override this method to provide custom simulation. */
+ /** Called from SimulateChunk() to simulate each block in one slot of blocks. Descendants override this method to
+ * provide custom simulation. */
virtual void SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ) = 0;
-} ;
-
-
-
-
+};
diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp
index a025f6afd..ab720e593 100644
--- a/src/Simulator/FireSimulator.cpp
+++ b/src/Simulator/FireSimulator.cpp
@@ -15,9 +15,9 @@
// Easy switch for turning on debugging logging:
#if 0
- #define FIRE_FLOG FLOGD
+#define FIRE_FLOG FLOGD
#else
- #define FIRE_FLOG(...)
+#define FIRE_FLOG(...)
#endif
@@ -36,26 +36,24 @@
-static constexpr Vector3i gCrossCoords[] =
-{
- { 1, 0, 0},
- {-1, 0, 0},
- { 0, 0, 1},
- { 0, 0, -1},
-} ;
+static constexpr Vector3i gCrossCoords[] = {
+ {1, 0, 0},
+ {-1, 0, 0},
+ {0, 0, 1},
+ {0, 0, -1},
+};
-static constexpr Vector3i gNeighborCoords[] =
-{
- { 1, 0, 0},
- {-1, 0, 0},
- { 0, 1, 0},
- { 0, -1, 0},
- { 0, 0, 1},
- { 0, 0, -1},
+static constexpr Vector3i gNeighborCoords[] = {
+ {1, 0, 0},
+ {-1, 0, 0},
+ {0, 1, 0},
+ {0, -1, 0},
+ {0, 0, 1},
+ {0, 0, -1},
};
@@ -69,10 +67,10 @@ cFireSimulator::cFireSimulator(cWorld & a_World, cIniFile & a_IniFile) :
cSimulator(a_World)
{
// Read params from the ini file:
- m_BurnStepTimeFuel = static_cast<unsigned>(a_IniFile.GetValueSetI("FireSimulator", "BurnStepTimeFuel", 500));
- m_BurnStepTimeNonfuel = static_cast<unsigned>(a_IniFile.GetValueSetI("FireSimulator", "BurnStepTimeNonfuel", 100));
- m_Flammability = a_IniFile.GetValueSetI("FireSimulator", "Flammability", 50);
- m_ReplaceFuelChance = a_IniFile.GetValueSetI("FireSimulator", "ReplaceFuelChance", 50000);
+ m_BurnStepTimeFuel = static_cast<unsigned>(a_IniFile.GetValueSetI("FireSimulator", "BurnStepTimeFuel", 500));
+ m_BurnStepTimeNonfuel = static_cast<unsigned>(a_IniFile.GetValueSetI("FireSimulator", "BurnStepTimeNonfuel", 100));
+ m_Flammability = a_IniFile.GetValueSetI("FireSimulator", "Flammability", 50);
+ m_ReplaceFuelChance = a_IniFile.GetValueSetI("FireSimulator", "ReplaceFuelChance", 50000);
}
@@ -91,7 +89,8 @@ void cFireSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX,
if (!IsAllowedBlock(blockType))
{
- // The block is no longer eligible (not a fire block anymore; a player probably placed a block over the fire)
+ // The block is no longer eligible (not a fire block anymore; a player probably placed a block over the
+ // fire)
FIRE_FLOG("FS: Removing block {0}", absPos);
itr = Data.erase(itr);
continue;
@@ -100,19 +99,24 @@ void cFireSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX,
auto BurnsForever = ((relPos.y > 0) && DoesBurnForever(a_Chunk->GetBlock(relPos.addedY(-1))));
auto BlockMeta = a_Chunk->GetMeta(relPos);
- auto Raining = std::any_of(std::begin(gCrossCoords), std::end(gCrossCoords), [a_Chunk, relPos](Vector3i cc)
- {
- auto Adjusted = relPos + cc;
- const auto Chunk = a_Chunk->GetRelNeighborChunkAdjustCoords(Adjusted);
- if ((Chunk != nullptr) && Chunk->IsValid())
+ auto Raining = std::any_of(
+ std::begin(gCrossCoords),
+ std::end(gCrossCoords),
+ [a_Chunk, relPos](Vector3i cc)
{
- return Chunk->IsWeatherWetAt(Adjusted);
+ auto Adjusted = relPos + cc;
+ const auto Chunk = a_Chunk->GetRelNeighborChunkAdjustCoords(Adjusted);
+ if ((Chunk != nullptr) && Chunk->IsValid())
+ {
+ return Chunk->IsWeatherWetAt(Adjusted);
+ }
+ return false;
}
- return false;
- });
+ );
// Randomly burn out the fire if it is raining:
- if (!BurnsForever && Raining && GetRandomProvider().RandBool(CHANCE_BASE_RAIN_EXTINGUISH + (BlockMeta * CHANCE_AGE_M_RAIN_EXTINGUISH)))
+ if (!BurnsForever && Raining &&
+ GetRandomProvider().RandBool(CHANCE_BASE_RAIN_EXTINGUISH + (BlockMeta * CHANCE_AGE_M_RAIN_EXTINGUISH)))
{
a_Chunk->SetBlock(relPos, E_BLOCK_AIR, 0);
itr = Data.erase(itr);
@@ -245,7 +249,7 @@ void cFireSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a
cFireSimulatorChunkData & ChunkData = a_Chunk.GetFireSimulatorData();
for (cCoordWithIntList::iterator itr = ChunkData.begin(), end = ChunkData.end(); itr != end; ++itr)
{
- const Vector3i ItrPos{itr->x, itr->y, itr->z};
+ const Vector3i ItrPos {itr->x, itr->y, itr->z};
if (ItrPos == a_Position)
{
// Block already present, check if burn step should decrease
@@ -287,9 +291,9 @@ int cFireSimulator::GetBurnStepTime(cChunk * a_Chunk, Vector3i a_RelPos)
IsBlockBelowSolid = cBlockInfo::IsSolid(BlockBelow);
}
- for (const auto & cross: gCrossCoords)
+ for (const auto & cross : gCrossCoords)
{
- BLOCKTYPE BlockType;
+ BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
if (a_Chunk->UnboundedRelGetBlock(a_RelPos + cross, BlockType, BlockMeta))
{
@@ -338,7 +342,7 @@ void cFireSimulator::TrySpreadFire(cChunk * a_Chunk, Vector3i a_RelPos)
}
// Start the fire in the neighbor a_RelPos + {x, y, z}
- auto dstRelPos = a_RelPos + Vector3i{x, y, z};
+ auto dstRelPos = a_RelPos + Vector3i {x, y, z};
if (CanStartFireInBlock(a_Chunk, dstRelPos))
{
auto dstAbsPos = a_Chunk->RelativeToAbsolute(dstRelPos);
@@ -410,7 +414,7 @@ void cFireSimulator::RemoveFuelNeighbors(cChunk * a_Chunk, Vector3i a_RelPos)
bool cFireSimulator::CanStartFireInBlock(cChunk * a_NearChunk, Vector3i a_RelPos)
{
- BLOCKTYPE BlockType;
+ BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
if (!a_NearChunk->UnboundedRelGetBlock(a_RelPos, BlockType, BlockMeta))
{
@@ -424,7 +428,7 @@ bool cFireSimulator::CanStartFireInBlock(cChunk * a_NearChunk, Vector3i a_RelPos
return false;
}
- for (const auto & neighbor: gNeighborCoords)
+ for (const auto & neighbor : gNeighborCoords)
{
if (!a_NearChunk->UnboundedRelGetBlock(a_RelPos + neighbor, BlockType, BlockMeta))
{
diff --git a/src/Simulator/FireSimulator.h b/src/Simulator/FireSimulator.h
index 37ae3e63f..9f9f78271 100644
--- a/src/Simulator/FireSimulator.h
+++ b/src/Simulator/FireSimulator.h
@@ -15,18 +15,15 @@ The data value associated with each coord is used as the number of msec that the
it progresses to the next step (blockmeta++). This value is updated if a neighbor is changed.
The simulator reads its parameters from the ini file given to the constructor.
*/
-class cFireSimulator :
- public cSimulator
+class cFireSimulator : public cSimulator
{
-public:
-
+ public:
cFireSimulator(cWorld & a_World, cIniFile & a_IniFile);
- static bool IsFuel (BLOCKTYPE a_BlockType);
+ static bool IsFuel(BLOCKTYPE a_BlockType);
static bool DoesBurnForever(BLOCKTYPE a_BlockType);
-private:
-
+ private:
virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override;
static bool IsAllowedBlock(BLOCKTYPE a_BlockType);
@@ -59,11 +56,12 @@ private:
Note that a_NearChunk may be a chunk neighbor to the block specified!
The coords are relative to a_NearChunk but not necessarily in it. */
bool CanStartFireInBlock(cChunk * a_NearChunk, Vector3i a_RelPos);
-} ;
+};
-/** Stores individual fire blocks in the chunk; the int data is used as the time [msec] the fire takes to step to another stage (blockmeta++) */
+/** Stores individual fire blocks in the chunk; the int data is used as the time [msec] the fire takes to step to
+ * another stage (blockmeta++) */
typedef cCoordWithIntList cFireSimulatorChunkData;
diff --git a/src/Simulator/FloodyFluidSimulator.cpp b/src/Simulator/FloodyFluidSimulator.cpp
index 428c0dbc1..ff0d43524 100644
--- a/src/Simulator/FloodyFluidSimulator.cpp
+++ b/src/Simulator/FloodyFluidSimulator.cpp
@@ -21,9 +21,9 @@
// Enable or disable detailed logging
#if 0
- #define FLUID_FLOG FLOGD
+#define FLUID_FLOG FLOGD
#else
- #define FLUID_FLOG(...)
+#define FLUID_FLOG(...)
#endif
@@ -50,13 +50,15 @@ cFloodyFluidSimulator::cFloodyFluidSimulator(
void cFloodyFluidSimulator::SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ)
{
- FLUID_FLOG("Simulating block {0}: block {1}, meta {2}",
+ FLUID_FLOG(
+ "Simulating block {0}: block {1}, meta {2}",
a_Chunk->PositionToWorldPosition(a_RelX, a_RelY, a_RelZ),
a_Chunk->GetBlock(a_RelX, a_RelY, a_RelZ),
a_Chunk->GetMeta(a_RelX, a_RelY, a_RelZ)
);
- BLOCKTYPE MyBlock; NIBBLETYPE MyMeta;
+ BLOCKTYPE MyBlock;
+ NIBBLETYPE MyMeta;
a_Chunk->GetBlockTypeMeta(a_RelX, a_RelY, a_RelZ, MyBlock, MyMeta);
if (!IsAnyFluidBlock(MyBlock))
@@ -111,12 +113,10 @@ void cFloodyFluidSimulator::SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_Re
}
// If source creation is on, check for it here:
- if (
- (m_NumNeighborsForSource > 0) && // Source creation is on
- (MyMeta == m_Falloff) && // Only exactly one block away from a source (fast bail-out)
- (
- !IsPassableForFluid(Below) || // Only exactly 1 block deep
- (Below == m_StationaryFluidBlock) // Or a source block underneath
+ if ((m_NumNeighborsForSource > 0) && // Source creation is on
+ (MyMeta == m_Falloff) && // Only exactly one block away from a source (fast bail-out)
+ (!IsPassableForFluid(Below) || // Only exactly 1 block deep
+ (Below == m_StationaryFluidBlock) // Or a source block underneath
) &&
CheckNeighborsForSource(a_Chunk, a_RelX, a_RelY, a_RelZ) // Did we create a source?
)
@@ -137,10 +137,10 @@ void cFloodyFluidSimulator::SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_Re
void cFloodyFluidSimulator::SpreadXZ(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta)
{
- SpreadToNeighbor(a_Chunk, a_RelX - 1, a_RelY, a_RelZ, a_NewMeta);
- SpreadToNeighbor(a_Chunk, a_RelX + 1, a_RelY, a_RelZ, a_NewMeta);
- SpreadToNeighbor(a_Chunk, a_RelX, a_RelY, a_RelZ - 1, a_NewMeta);
- SpreadToNeighbor(a_Chunk, a_RelX, a_RelY, a_RelZ + 1, a_NewMeta);
+ SpreadToNeighbor(a_Chunk, a_RelX - 1, a_RelY, a_RelZ, a_NewMeta);
+ SpreadToNeighbor(a_Chunk, a_RelX + 1, a_RelY, a_RelZ, a_NewMeta);
+ SpreadToNeighbor(a_Chunk, a_RelX, a_RelY, a_RelZ - 1, a_NewMeta);
+ SpreadToNeighbor(a_Chunk, a_RelX, a_RelY, a_RelZ + 1, a_NewMeta);
}
@@ -165,25 +165,27 @@ bool cFloodyFluidSimulator::CheckTributaries(cChunk * a_Chunk, int a_RelX, int a
{
BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
- static const Vector3i Coords[] =
- {
- Vector3i( 1, 0, 0),
- Vector3i(-1, 0, 0),
- Vector3i( 0, 0, 1),
- Vector3i( 0, 0, -1),
- } ;
+ static const Vector3i Coords[] = {
+ Vector3i(1, 0, 0),
+ Vector3i(-1, 0, 0),
+ Vector3i(0, 0, 1),
+ Vector3i(0, 0, -1),
+ };
for (size_t i = 0; i < ARRAYCOUNT(Coords); i++)
{
- if (!a_Chunk->UnboundedRelGetBlock(a_RelX + Coords[i].x, a_RelY, a_RelZ + Coords[i].z, BlockType, BlockMeta))
+ if (!a_Chunk
+ ->UnboundedRelGetBlock(a_RelX + Coords[i].x, a_RelY, a_RelZ + Coords[i].z, BlockType, BlockMeta))
{
continue;
}
if (IsAllowedBlock(BlockType) && IsHigherMeta(BlockMeta, a_MyMeta))
{
// This block is fed, no more processing needed
- FLUID_FLOG(" Fed from {0}, type {1}, meta {2}",
- a_Chunk->PositionToWorldPosition(a_RelX+ Coords[i].x, a_RelY, a_RelZ + Coords[i].z),
- BlockType, BlockMeta
+ FLUID_FLOG(
+ " Fed from {0}, type {1}, meta {2}",
+ a_Chunk->PositionToWorldPosition(a_RelX + Coords[i].x, a_RelY, a_RelZ + Coords[i].z),
+ BlockType,
+ BlockMeta
);
return false;
}
@@ -217,7 +219,13 @@ bool cFloodyFluidSimulator::CheckTributaries(cChunk * a_Chunk, int a_RelX, int a
-void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta)
+void cFloodyFluidSimulator::SpreadToNeighbor(
+ cChunk * a_NearChunk,
+ int a_RelX,
+ int a_RelY,
+ int a_RelZ,
+ NIBBLETYPE a_NewMeta
+)
{
ASSERT(a_NewMeta <= 8); // Invalid meta values
ASSERT(a_NewMeta > 0); // Source blocks aren't spread
@@ -251,17 +259,14 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i
{
// Lava flowing into water, change to stone / cobblestone based on direction:
BLOCKTYPE NewBlock = (a_NewMeta == 8) ? E_BLOCK_STONE : E_BLOCK_COBBLESTONE;
- FLUID_FLOG(" Lava flowing into water, turning water at rel {0} into {1}",
- relPos, ItemTypeToString(NewBlock)
+ FLUID_FLOG(
+ " Lava flowing into water, turning water at rel {0} into {1}",
+ relPos,
+ ItemTypeToString(NewBlock)
);
a_NearChunk->SetBlock(relPos, NewBlock, 0);
- m_World.BroadcastSoundEffect(
- "block.lava.extinguish",
- absPos,
- 0.5f,
- 1.5f
- );
+ m_World.BroadcastSoundEffect("block.lava.extinguish", absPos, 0.5f, 1.5f);
return;
}
}
@@ -271,17 +276,14 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i
{
// Water flowing into lava, change to cobblestone / obsidian based on dest block:
BLOCKTYPE NewBlock = (BlockMeta == 0) ? E_BLOCK_OBSIDIAN : E_BLOCK_COBBLESTONE;
- FLUID_FLOG(" Water flowing into lava, turning lava at rel {0} into {1}",
- relPos, ItemTypeToString(NewBlock)
+ FLUID_FLOG(
+ " Water flowing into lava, turning lava at rel {0} into {1}",
+ relPos,
+ ItemTypeToString(NewBlock)
);
a_NearChunk->SetBlock(relPos, NewBlock, 0);
- m_World.BroadcastSoundEffect(
- "block.lava.extinguish",
- absPos,
- 0.5f,
- 1.5f
- );
+ m_World.BroadcastSoundEffect("block.lava.extinguish", absPos, 0.5f, 1.5f);
return;
}
}
@@ -318,13 +320,12 @@ bool cFloodyFluidSimulator::CheckNeighborsForSource(cChunk * a_Chunk, int a_RelX
{
FLUID_FLOG(" Checking neighbors for source creation");
- static const Vector3i NeighborCoords[] =
- {
- Vector3i(-1, 0, 0),
- Vector3i( 1, 0, 0),
- Vector3i( 0, 0, -1),
- Vector3i( 0, 0, 1),
- } ;
+ static const Vector3i NeighborCoords[] = {
+ Vector3i(-1, 0, 0),
+ Vector3i(1, 0, 0),
+ Vector3i(0, 0, -1),
+ Vector3i(0, 0, 1),
+ };
int NumNeeded = m_NumNeighborsForSource;
for (size_t i = 0; i < ARRAYCOUNT(NeighborCoords); i++)
@@ -375,14 +376,13 @@ bool cFloodyFluidSimulator::HardenBlock(cChunk * a_Chunk, Vector3i a_RelPos, BLO
BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
- static const Vector3i neighborOffsets[] =
- {
- Vector3i( 1, 0, 0),
- Vector3i(-1, 0, 0),
- Vector3i( 0, 0, 1),
- Vector3i( 0, 0, -1),
+ static const Vector3i neighborOffsets[] = {
+ Vector3i(1, 0, 0),
+ Vector3i(-1, 0, 0),
+ Vector3i(0, 0, 1),
+ Vector3i(0, 0, -1),
};
- for (const auto & ofs: neighborOffsets)
+ for (const auto & ofs : neighborOffsets)
{
if (!a_Chunk->UnboundedRelGetBlock(a_RelPos + ofs, BlockType, BlockMeta))
{
@@ -412,6 +412,3 @@ bool cFloodyFluidSimulator::HardenBlock(cChunk * a_Chunk, Vector3i a_RelPos, BLO
return false;
}
-
-
-
diff --git a/src/Simulator/FloodyFluidSimulator.h b/src/Simulator/FloodyFluidSimulator.h
index 6923bb637..e402a23e4 100644
--- a/src/Simulator/FloodyFluidSimulator.h
+++ b/src/Simulator/FloodyFluidSimulator.h
@@ -16,19 +16,23 @@
-class cFloodyFluidSimulator:
- public cDelayedFluidSimulator
+class cFloodyFluidSimulator : public cDelayedFluidSimulator
{
using Super = cDelayedFluidSimulator;
-public:
-
- cFloodyFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid, NIBBLETYPE a_Falloff, int a_TickDelay, int a_NumNeighborsForSource);
-
-protected:
-
+ public:
+ cFloodyFluidSimulator(
+ cWorld & a_World,
+ BLOCKTYPE a_Fluid,
+ BLOCKTYPE a_StationaryFluid,
+ NIBBLETYPE a_Falloff,
+ int a_TickDelay,
+ int a_NumNeighborsForSource
+ );
+
+ protected:
NIBBLETYPE m_Falloff;
- int m_NumNeighborsForSource;
+ int m_NumNeighborsForSource;
// cDelayedFluidSimulator overrides:
virtual void SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override;
@@ -39,19 +43,16 @@ protected:
/** Spreads into the specified block, if the blocktype there allows. a_Area is for checking. */
void SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta);
- /** Checks if there are enough neighbors to create a source at the coords specified; turns into source and returns true if so. */
+ /** Checks if there are enough neighbors to create a source at the coords specified; turns into source and returns
+ * true if so. */
bool CheckNeighborsForSource(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ);
- /** Checks if the specified block should harden (Water / Lava interaction) and if so, converts it to a suitable block.
- Returns whether the block was changed or not. */
+ /** Checks if the specified block should harden (Water / Lava interaction) and if so, converts it to a suitable
+ block. Returns whether the block was changed or not. */
bool HardenBlock(cChunk * a_Chunk, Vector3i a_RelPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta);
/** Spread fluid to XZ neighbors.
The coords are of the block currently being processed; a_NewMeta is the new meta for the new fluid block.
Descendants may overridde to provide more sophisticated algorithms. */
virtual void SpreadXZ(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta);
-} ;
-
-
-
-
+};
diff --git a/src/Simulator/FluidSimulator.cpp b/src/Simulator/FluidSimulator.cpp
index 3771b0804..47dbe744b 100644
--- a/src/Simulator/FluidSimulator.cpp
+++ b/src/Simulator/FluidSimulator.cpp
@@ -8,9 +8,7 @@
cFluidSimulator::cFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid) :
- Super(a_World),
- m_FluidBlock(a_Fluid),
- m_StationaryFluidBlock(a_StationaryFluid)
+ Super(a_World), m_FluidBlock(a_Fluid), m_StationaryFluidBlock(a_StationaryFluid)
{
}
@@ -87,9 +85,7 @@ bool cFluidSimulator::IsSolidBlock(BLOCKTYPE a_BlockType)
bool cFluidSimulator::IsPassableForFluid(BLOCKTYPE a_BlockType)
{
return (
- (a_BlockType == E_BLOCK_AIR) ||
- (a_BlockType == E_BLOCK_FIRE) ||
- IsAllowedBlock(a_BlockType) ||
+ (a_BlockType == E_BLOCK_AIR) || (a_BlockType == E_BLOCK_FIRE) || IsAllowedBlock(a_BlockType) ||
CanWashAway(a_BlockType)
);
}
@@ -143,25 +139,17 @@ Vector3f cFluidSimulator::GetFlowingDirection(Vector3i a_Pos)
}
const auto HeightFromMeta = [](NIBBLETYPE a_BlockMeta) -> NIBBLETYPE
- {
- // Falling water blocks are always full height (0)
- return ((a_BlockMeta & 0x08) != 0) ? 0 : a_BlockMeta;
- };
+ {
+ // Falling water blocks are always full height (0)
+ return ((a_BlockMeta & 0x08) != 0) ? 0 : a_BlockMeta;
+ };
auto BlockMeta = m_World.GetBlockMeta(a_Pos);
NIBBLETYPE CentralPoint = HeightFromMeta(BlockMeta);
NIBBLETYPE LevelPoint[4];
// blocks around the checking pos
- std::array<Vector3i, 4> Offsets
- {
- {
- { 1, 0, 0 },
- { 0, 0, 1 },
- { 1, 0, 0 },
- { 0, 0, 1 }
- }
- };
+ std::array<Vector3i, 4> Offsets {{{1, 0, 0}, {0, 0, 1}, {1, 0, 0}, {0, 0, 1}}};
for (size_t i = 0; i < Offsets.size(); i++)
{
@@ -189,4 +177,3 @@ Vector3f cFluidSimulator::GetFlowingDirection(Vector3i a_Pos)
return Direction;
}
-
diff --git a/src/Simulator/FluidSimulator.h b/src/Simulator/FluidSimulator.h
index 3aa6deb8a..6d6e87ea1 100644
--- a/src/Simulator/FluidSimulator.h
+++ b/src/Simulator/FluidSimulator.h
@@ -26,7 +26,7 @@ enum Direction
Needed so that cChunk can properly delete instances of fluid simulator data, no matter what simulator it's using. */
class cFluidSimulatorData
{
-public:
+ public:
virtual ~cFluidSimulatorData() {}
};
@@ -34,13 +34,11 @@ public:
-class cFluidSimulator:
- public cSimulator
+class cFluidSimulator : public cSimulator
{
using Super = cSimulator;
-public:
-
+ public:
cFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid);
/** Returns a unit vector in the direction the fluid is flowing or a zero-vector if not flowing. */
@@ -49,27 +47,24 @@ public:
/** Creates a ChunkData object for the simulator to use. The simulator returns the correct object type. */
virtual cFluidSimulatorData * CreateChunkData(void) = 0;
- bool IsFluidBlock (BLOCKTYPE a_BlockType) const { return (a_BlockType == m_FluidBlock); }
+ bool IsFluidBlock(BLOCKTYPE a_BlockType) const { return (a_BlockType == m_FluidBlock); }
bool IsStationaryFluidBlock(BLOCKTYPE a_BlockType) const { return (a_BlockType == m_StationaryFluidBlock); }
- bool IsAnyFluidBlock (BLOCKTYPE a_BlockType) const { return ((a_BlockType == m_FluidBlock) || (a_BlockType == m_StationaryFluidBlock)); }
+ bool IsAnyFluidBlock(BLOCKTYPE a_BlockType) const
+ {
+ return ((a_BlockType == m_FluidBlock) || (a_BlockType == m_StationaryFluidBlock));
+ }
static bool CanWashAway(BLOCKTYPE a_BlockType);
- bool IsSolidBlock (BLOCKTYPE a_BlockType);
+ bool IsSolidBlock(BLOCKTYPE a_BlockType);
bool IsPassableForFluid(BLOCKTYPE a_BlockType);
/** Returns true if a_Meta1 is a higher fluid than a_Meta2. Takes source blocks into account. */
bool IsHigherMeta(NIBBLETYPE a_Meta1, NIBBLETYPE a_Meta2);
-protected:
-
+ protected:
bool IsAllowedBlock(BLOCKTYPE a_BlockType);
- BLOCKTYPE m_FluidBlock; // The fluid block type that needs simulating
+ BLOCKTYPE m_FluidBlock; // The fluid block type that needs simulating
BLOCKTYPE m_StationaryFluidBlock; // The fluid block type that indicates no simulation is needed
};
-
-
-
-
-
diff --git a/src/Simulator/IncrementalRedstoneSimulator/CommandBlockHandler.h b/src/Simulator/IncrementalRedstoneSimulator/CommandBlockHandler.h
index 50ea6dcb6..4966d6859 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/CommandBlockHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/CommandBlockHandler.h
@@ -9,42 +9,65 @@
namespace CommandBlockHandler
{
- static PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
- {
- UNUSED(a_Chunk);
- UNUSED(a_Position);
- UNUSED(a_BlockType);
- UNUSED(a_QueryPosition);
- UNUSED(a_QueryBlockType);
- UNUSED(IsLinked);
- return 0;
- }
+static PowerLevel GetPowerDeliveredToPosition(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ Vector3i a_QueryPosition,
+ BLOCKTYPE a_QueryBlockType,
+ bool IsLinked
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_Position);
+ UNUSED(a_BlockType);
+ UNUSED(a_QueryPosition);
+ UNUSED(a_QueryBlockType);
+ UNUSED(IsLinked);
+ return 0;
+}
- static void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
- {
- // LOGD("Evaluating commander the cmdblck (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
+static void Update(
+ cChunk & a_Chunk,
+ cChunk &,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ const PowerLevel Power
+)
+{
+ // LOGD("Evaluating commander the cmdblck (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- const auto Previous = DataForChunk(a_Chunk).ExchangeUpdateOncePowerData(a_Position, Power);
- if ((Previous != 0) || (Power == 0))
- {
- // If we're already powered or received an update of no power, don't activate
- return;
- }
+ const auto Previous = DataForChunk(a_Chunk).ExchangeUpdateOncePowerData(a_Position, Power);
+ if ((Previous != 0) || (Power == 0))
+ {
+ // If we're already powered or received an update of no power, don't activate
+ return;
+ }
- a_Chunk.DoWithBlockEntityAt(a_Position, [](cBlockEntity & a_BlockEntity)
+ a_Chunk.DoWithBlockEntityAt(
+ a_Position,
+ [](cBlockEntity & a_BlockEntity)
{
ASSERT(a_BlockEntity.GetBlockType() == E_BLOCK_COMMAND_BLOCK);
static_cast<cCommandBlockEntity &>(a_BlockEntity).Activate();
return false;
- });
- }
+ }
+ );
+}
- static void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback)
- {
- UNUSED(a_Chunk);
- UNUSED(a_BlockType);
- UNUSED(a_Meta);
- InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
- }
-};
+static void ForValidSourcePositions(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ ForEachSourceCallback & Callback
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_BlockType);
+ UNUSED(a_Meta);
+ InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
+}
+}; // namespace CommandBlockHandler
diff --git a/src/Simulator/IncrementalRedstoneSimulator/DaylightSensorHandler.h b/src/Simulator/IncrementalRedstoneSimulator/DaylightSensorHandler.h
index 75e6651da..a520960dc 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/DaylightSensorHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/DaylightSensorHandler.h
@@ -9,55 +9,75 @@
namespace DaylightSensorHandler
{
- static PowerLevel GetPowerLevel(const cChunk & a_Chunk, const Vector3i a_Position)
+static PowerLevel GetPowerLevel(const cChunk & a_Chunk, const Vector3i a_Position)
+{
+ if (a_Chunk.GetBlock(a_Position) == E_BLOCK_INVERTED_DAYLIGHT_SENSOR)
{
- if (a_Chunk.GetBlock(a_Position) == E_BLOCK_INVERTED_DAYLIGHT_SENSOR)
- {
- // Inverted sensor directly returns darkened skylight, no fancy tricks:
- return 15 - a_Chunk.GetSkyLightAltered(a_Position);
- }
-
- // The [0, 1) proportion of the current day that has elapsed.
- const auto ProportionOfDay = a_Chunk.GetWorld()->GetTimeOfDay().count() * (static_cast<float>(M_PI) / 12000.f);
-
- // The curved value of darkened skylight, with outputs somewhat similar to Vanilla.
- const auto RawOutput = a_Chunk.GetSkyLightAltered(a_Position) * (0.6f * std::sin(ProportionOfDay) + 0.5f);
-
- // Saturate the amplified sine curve at 0 and 15:
- return static_cast<PowerLevel>(std::clamp(RawOutput, 0.f, 15.f));
+ // Inverted sensor directly returns darkened skylight, no fancy tricks:
+ return 15 - a_Chunk.GetSkyLightAltered(a_Position);
}
- static PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
- {
- UNUSED(a_Chunk);
- UNUSED(a_BlockType);
- UNUSED(a_QueryPosition);
+ // The [0, 1) proportion of the current day that has elapsed.
+ const auto ProportionOfDay = a_Chunk.GetWorld()->GetTimeOfDay().count() * (static_cast<float>(M_PI) / 12000.f);
- // Daylight sensors only output to immediately surrounding blocks:
- return IsLinked ? 0 : a_Chunk.GetMeta(a_Position);
- }
+ // The curved value of darkened skylight, with outputs somewhat similar to Vanilla.
+ const auto RawOutput = a_Chunk.GetSkyLightAltered(a_Position) * (0.6f * std::sin(ProportionOfDay) + 0.5f);
- static void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
- {
- // LOGD("Evaluating Darryl the daylight sensor (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
+ // Saturate the amplified sine curve at 0 and 15:
+ return static_cast<PowerLevel>(std::clamp(RawOutput, 0.f, 15.f));
+}
- // What the sensor should output according to the time-power function.
- const auto PowerLevel = GetPowerLevel(a_Chunk, a_Position);
+static PowerLevel GetPowerDeliveredToPosition(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ Vector3i a_QueryPosition,
+ BLOCKTYPE a_QueryBlockType,
+ bool IsLinked
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_BlockType);
+ UNUSED(a_QueryPosition);
+
+ // Daylight sensors only output to immediately surrounding blocks:
+ return IsLinked ? 0 : a_Chunk.GetMeta(a_Position);
+}
+
+static void Update(
+ cChunk & a_Chunk,
+ cChunk & CurrentlyTicking,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ const PowerLevel Power
+)
+{
+ // LOGD("Evaluating Darryl the daylight sensor (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- // Only update the output if the power level has changed:
- if (PowerLevel != a_Meta)
- {
- a_Chunk.SetMeta(a_Position, PowerLevel);
- UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position, RelativeAdjacents);
- }
- }
+ // What the sensor should output according to the time-power function.
+ const auto PowerLevel = GetPowerLevel(a_Chunk, a_Position);
- static void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback)
+ // Only update the output if the power level has changed:
+ if (PowerLevel != a_Meta)
{
- UNUSED(a_Chunk);
- UNUSED(a_Position);
- UNUSED(a_BlockType);
- UNUSED(a_Meta);
- UNUSED(Callback);
+ a_Chunk.SetMeta(a_Position, PowerLevel);
+ UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position, RelativeAdjacents);
}
-};
+}
+
+static void ForValidSourcePositions(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ ForEachSourceCallback & Callback
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_Position);
+ UNUSED(a_BlockType);
+ UNUSED(a_Meta);
+ UNUSED(Callback);
+}
+}; // namespace DaylightSensorHandler
diff --git a/src/Simulator/IncrementalRedstoneSimulator/DoorHandler.h b/src/Simulator/IncrementalRedstoneSimulator/DoorHandler.h
index cb772bb5b..9e3a2b6d4 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/DoorHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/DoorHandler.h
@@ -9,90 +9,110 @@
namespace DoorHandler
{
- // "Doormammu, I've come to bargain"
+// "Doormammu, I've come to bargain"
+
+static PowerLevel GetPowerDeliveredToPosition(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ Vector3i a_QueryPosition,
+ BLOCKTYPE a_QueryBlockType,
+ bool IsLinked
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_Position);
+ UNUSED(a_BlockType);
+ UNUSED(a_QueryPosition);
+ UNUSED(a_QueryBlockType);
+ UNUSED(IsLinked);
+ return 0;
+}
+
+static void ForValidSourcePositions(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ ForEachSourceCallback & Callback
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_BlockType);
+ UNUSED(a_Meta);
+ InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
+}
+
+static void Update(
+ cChunk & a_Chunk,
+ cChunk &,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ PowerLevel Power
+)
+{
+ // LOGD("Evaluating dori the door (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- static PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
- {
- UNUSED(a_Chunk);
- UNUSED(a_Position);
- UNUSED(a_BlockType);
- UNUSED(a_QueryPosition);
- UNUSED(a_QueryBlockType);
- UNUSED(IsLinked);
- return 0;
- }
+ NIBBLETYPE TopMeta;
+ const bool IsTop = (a_Meta & 0x8) == 0x8;
+ const auto TopPosition = IsTop ? a_Position : a_Position.addedY(1);
- static void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback)
+ // Figure out the metadata of the top half, which stores the previous redstone power state:
+ if (IsTop)
{
- UNUSED(a_Chunk);
- UNUSED(a_BlockType);
- UNUSED(a_Meta);
- InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
+ TopMeta = a_Meta;
}
-
- static void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PowerLevel Power)
+ else
{
- // LOGD("Evaluating dori the door (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
-
- NIBBLETYPE TopMeta;
- const bool IsTop = (a_Meta & 0x8) == 0x8;
- const auto TopPosition = IsTop ? a_Position : a_Position.addedY(1);
-
- // Figure out the metadata of the top half, which stores the previous redstone power state:
- if (IsTop)
+ if (TopPosition.y == cChunkDef::Height)
{
- TopMeta = a_Meta;
+ return;
}
- else
+
+ BLOCKTYPE AboveType;
+ a_Chunk.GetBlockTypeMeta(TopPosition, AboveType, TopMeta);
+ if (!cBlockDoorHandler::IsDoorBlockType(AboveType))
{
- if (TopPosition.y == cChunkDef::Height)
- {
- return;
- }
-
- BLOCKTYPE AboveType;
- a_Chunk.GetBlockTypeMeta(TopPosition, AboveType, TopMeta);
- if (!cBlockDoorHandler::IsDoorBlockType(AboveType))
- {
- return;
- }
+ return;
}
+ }
- const auto OppositeHalfPosition = a_Position + (IsTop ? OffsetYM : OffsetYP);
- ForEachSourceCallback Callback(a_Chunk, OppositeHalfPosition, a_BlockType);
- ForValidSourcePositions(a_Chunk, OppositeHalfPosition, a_BlockType, a_Meta, Callback);
+ const auto OppositeHalfPosition = a_Position + (IsTop ? OffsetYM : OffsetYP);
+ ForEachSourceCallback Callback(a_Chunk, OppositeHalfPosition, a_BlockType);
+ ForValidSourcePositions(a_Chunk, OppositeHalfPosition, a_BlockType, a_Meta, Callback);
- // Factor in what the other half is getting:
- Power = std::max(Power, Callback.Power);
+ // Factor in what the other half is getting:
+ Power = std::max(Power, Callback.Power);
- const bool ShouldBeOpen = Power != 0;
- const bool PreviouslyPowered = (TopMeta & 0x2) == 0x2;
+ const bool ShouldBeOpen = Power != 0;
+ const bool PreviouslyPowered = (TopMeta & 0x2) == 0x2;
- // Allow players to override redstone control
- // don't update if redstone power hasn't changed since we last saw it:
- if (ShouldBeOpen == PreviouslyPowered)
- {
- return;
- }
+ // Allow players to override redstone control
+ // don't update if redstone power hasn't changed since we last saw it:
+ if (ShouldBeOpen == PreviouslyPowered)
+ {
+ return;
+ }
- // Update the previous redstone power:
- if (ShouldBeOpen)
- {
- a_Chunk.SetMeta(TopPosition, TopMeta | 0x2);
- }
- else
- {
- a_Chunk.SetMeta(TopPosition, TopMeta & ~0x2);
- }
+ // Update the previous redstone power:
+ if (ShouldBeOpen)
+ {
+ a_Chunk.SetMeta(TopPosition, TopMeta | 0x2);
+ }
+ else
+ {
+ a_Chunk.SetMeta(TopPosition, TopMeta & ~0x2);
+ }
- cChunkInterface ChunkInterface(a_Chunk.GetWorld()->GetChunkMap());
- const auto AbsolutePosition = cChunkDef::RelativeToAbsolute(a_Position, a_Chunk.GetPos());
+ cChunkInterface ChunkInterface(a_Chunk.GetWorld()->GetChunkMap());
+ const auto AbsolutePosition = cChunkDef::RelativeToAbsolute(a_Position, a_Chunk.GetPos());
- // Toggle the door, if it needs to be changed:
- if (ShouldBeOpen != cBlockDoorHandler::IsOpen(ChunkInterface, AbsolutePosition))
- {
- cBlockDoorHandler::SetOpen(ChunkInterface, AbsolutePosition, ShouldBeOpen);
- a_Chunk.GetWorld()->BroadcastSoundParticleEffect(EffectID::SFX_RANDOM_WOODEN_DOOR_OPEN, AbsolutePosition, 0);
- }
+ // Toggle the door, if it needs to be changed:
+ if (ShouldBeOpen != cBlockDoorHandler::IsOpen(ChunkInterface, AbsolutePosition))
+ {
+ cBlockDoorHandler::SetOpen(ChunkInterface, AbsolutePosition, ShouldBeOpen);
+ a_Chunk.GetWorld()->BroadcastSoundParticleEffect(EffectID::SFX_RANDOM_WOODEN_DOOR_OPEN, AbsolutePosition, 0);
}
-};
+}
+}; // namespace DoorHandler
diff --git a/src/Simulator/IncrementalRedstoneSimulator/DropSpenserHandler.h b/src/Simulator/IncrementalRedstoneSimulator/DropSpenserHandler.h
index 5f92c3868..ba2589fac 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/DropSpenserHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/DropSpenserHandler.h
@@ -9,69 +9,95 @@
namespace DropSpenserHandler
{
- static bool IsActivated(NIBBLETYPE a_Meta)
- {
- return (a_Meta & E_META_DROPSPENSER_ACTIVATED) != 0;
- }
+static bool IsActivated(NIBBLETYPE a_Meta)
+{
+ return (a_Meta & E_META_DROPSPENSER_ACTIVATED) != 0;
+}
- static NIBBLETYPE SetActivationState(NIBBLETYPE a_Meta, bool IsOn)
+static NIBBLETYPE SetActivationState(NIBBLETYPE a_Meta, bool IsOn)
+{
+ if (IsOn)
{
- if (IsOn)
- {
- return a_Meta | E_META_DROPSPENSER_ACTIVATED; // set the bit
- }
- else
- {
- return a_Meta & ~E_META_DROPSPENSER_ACTIVATED; // clear the bit
- }
+ return a_Meta | E_META_DROPSPENSER_ACTIVATED; // set the bit
}
-
- static PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
+ else
{
- UNUSED(a_Chunk);
- UNUSED(a_Position);
- UNUSED(a_BlockType);
- UNUSED(a_QueryPosition);
- UNUSED(a_QueryBlockType);
- UNUSED(IsLinked);
- return 0;
+ return a_Meta & ~E_META_DROPSPENSER_ACTIVATED; // clear the bit
}
+}
+
+static PowerLevel GetPowerDeliveredToPosition(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ Vector3i a_QueryPosition,
+ BLOCKTYPE a_QueryBlockType,
+ bool IsLinked
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_Position);
+ UNUSED(a_BlockType);
+ UNUSED(a_QueryPosition);
+ UNUSED(a_QueryBlockType);
+ UNUSED(IsLinked);
+ return 0;
+}
+
+static void Update(
+ cChunk & a_Chunk,
+ cChunk &,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ const PowerLevel Power
+)
+{
+ // LOGD("Evaluating spencer the dropspenser (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- static void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
- {
- // LOGD("Evaluating spencer the dropspenser (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
-
- const bool IsPoweredNow = (Power > 0);
- const bool WasPoweredPreviously = IsActivated(a_Meta);
+ const bool IsPoweredNow = (Power > 0);
+ const bool WasPoweredPreviously = IsActivated(a_Meta);
- if (IsPoweredNow && !WasPoweredPreviously)
- {
- a_Chunk.DoWithBlockEntityAt(a_Position, [](cBlockEntity & a_BlockEntity)
+ if (IsPoweredNow && !WasPoweredPreviously)
+ {
+ a_Chunk.DoWithBlockEntityAt(
+ a_Position,
+ [](cBlockEntity & a_BlockEntity)
{
- ASSERT((a_BlockEntity.GetBlockType() == E_BLOCK_DISPENSER) || (a_BlockEntity.GetBlockType() == E_BLOCK_DROPPER));
+ ASSERT(
+ (a_BlockEntity.GetBlockType() == E_BLOCK_DISPENSER) ||
+ (a_BlockEntity.GetBlockType() == E_BLOCK_DROPPER)
+ );
static_cast<cDropSpenserEntity &>(a_BlockEntity).Activate();
return false;
- });
- }
-
- // Update the internal dropspenser state if necessary
- if (IsPoweredNow != WasPoweredPreviously)
- {
- a_Chunk.SetMeta(a_Position, SetActivationState(a_Meta, IsPoweredNow));
- }
+ }
+ );
}
- static void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback)
+ // Update the internal dropspenser state if necessary
+ if (IsPoweredNow != WasPoweredPreviously)
{
- UNUSED(a_Chunk);
- UNUSED(a_BlockType);
- UNUSED(a_Meta);
+ a_Chunk.SetMeta(a_Position, SetActivationState(a_Meta, IsPoweredNow));
+ }
+}
+
+static void ForValidSourcePositions(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ ForEachSourceCallback & Callback
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_BlockType);
+ UNUSED(a_Meta);
- // Consider indirect power:
- Callback.CheckIndirectPower();
+ // Consider indirect power:
+ Callback.CheckIndirectPower();
- // Consider normal adjacents:
- InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
- }
-};
+ // Consider normal adjacents:
+ InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
+}
+}; // namespace DropSpenserHandler
diff --git a/src/Simulator/IncrementalRedstoneSimulator/ForEachSourceCallback.cpp b/src/Simulator/IncrementalRedstoneSimulator/ForEachSourceCallback.cpp
index 9c7560a6c..3b0df14e7 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/ForEachSourceCallback.cpp
+++ b/src/Simulator/IncrementalRedstoneSimulator/ForEachSourceCallback.cpp
@@ -12,11 +12,12 @@
-ForEachSourceCallback::ForEachSourceCallback(const cChunk & Chunk, const Vector3i Position, const BLOCKTYPE CurrentBlock) :
- Power(0),
- m_Chunk(Chunk),
- m_Position(Position),
- m_CurrentBlock(CurrentBlock)
+ForEachSourceCallback::ForEachSourceCallback(
+ const cChunk & Chunk,
+ const Vector3i Position,
+ const BLOCKTYPE CurrentBlock
+) :
+ Power(0), m_Chunk(Chunk), m_Position(Position), m_CurrentBlock(CurrentBlock)
{
}
@@ -38,19 +39,27 @@ void ForEachSourceCallback::operator()(Vector3i Location)
}
const auto PotentialSourceBlock = NeighbourChunk->GetBlock(Location);
- const auto NeighbourRelativeQueryPosition = cIncrementalRedstoneSimulatorChunkData::RebaseRelativePosition(m_Chunk, *NeighbourChunk, m_Position);
+ const auto NeighbourRelativeQueryPosition =
+ cIncrementalRedstoneSimulatorChunkData::RebaseRelativePosition(m_Chunk, *NeighbourChunk, m_Position);
if (!cBlockInfo::IsTransparent(PotentialSourceBlock))
{
- Power = std::max(Power, QueryLinkedPower(*NeighbourChunk, NeighbourRelativeQueryPosition, m_CurrentBlock, Location));
+ Power = std::max(
+ Power,
+ QueryLinkedPower(*NeighbourChunk, NeighbourRelativeQueryPosition, m_CurrentBlock, Location)
+ );
}
else
{
Power = std::max(
Power,
RedstoneHandler::GetPowerDeliveredToPosition(
- *NeighbourChunk, Location, PotentialSourceBlock,
- NeighbourRelativeQueryPosition, m_CurrentBlock, false
+ *NeighbourChunk,
+ Location,
+ PotentialSourceBlock,
+ NeighbourRelativeQueryPosition,
+ m_CurrentBlock,
+ false
)
);
}
@@ -88,7 +97,12 @@ void ForEachSourceCallback::CheckIndirectPower()
-PowerLevel ForEachSourceCallback::QueryLinkedPower(const cChunk & Chunk, const Vector3i QueryPosition, const BLOCKTYPE QueryBlock, const Vector3i SolidBlockPosition)
+PowerLevel ForEachSourceCallback::QueryLinkedPower(
+ const cChunk & Chunk,
+ const Vector3i QueryPosition,
+ const BLOCKTYPE QueryBlock,
+ const Vector3i SolidBlockPosition
+)
{
PowerLevel Power = 0;
@@ -108,14 +122,19 @@ PowerLevel ForEachSourceCallback::QueryLinkedPower(const cChunk & Chunk, const V
}
// Conduit block's position, relative to NeighbourChunk.
- const auto NeighbourRelativeSolidBlockPosition = cIncrementalRedstoneSimulatorChunkData::RebaseRelativePosition(Chunk, *NeighbourChunk, SolidBlockPosition);
+ const auto NeighbourRelativeSolidBlockPosition =
+ cIncrementalRedstoneSimulatorChunkData::RebaseRelativePosition(Chunk, *NeighbourChunk, SolidBlockPosition);
// Do a standard power query, but the requester's position is actually the solid block that will conduct power:
Power = std::max(
Power,
RedstoneHandler::GetPowerDeliveredToPosition(
- *NeighbourChunk, SourcePosition, NeighbourChunk->GetBlock(SourcePosition),
- NeighbourRelativeSolidBlockPosition, QueryBlock, true
+ *NeighbourChunk,
+ SourcePosition,
+ NeighbourChunk->GetBlock(SourcePosition),
+ NeighbourRelativeSolidBlockPosition,
+ QueryBlock,
+ true
)
);
}
diff --git a/src/Simulator/IncrementalRedstoneSimulator/ForEachSourceCallback.h b/src/Simulator/IncrementalRedstoneSimulator/ForEachSourceCallback.h
index 16c10fd5e..9dcc982c8 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/ForEachSourceCallback.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/ForEachSourceCallback.h
@@ -9,8 +9,7 @@
class ForEachSourceCallback
{
-public:
-
+ public:
ForEachSourceCallback(const cChunk & Chunk, Vector3i Position, BLOCKTYPE CurrentBlock);
/** Callback invoked for each potential source position of the redstone component. */
@@ -22,11 +21,15 @@ public:
// The maximum power level of all source locations.
PowerLevel Power;
-private:
-
- /** Asks redstone handlers adjacent to a solid block how much power they will deliver to the querying position, via the solid block.
- Both QueryPosition and SolidBlockPosition are relative to Chunk. */
- static PowerLevel QueryLinkedPower(const cChunk & Chunk, Vector3i QueryPosition, BLOCKTYPE QueryBlock, Vector3i SolidBlockPosition);
+ private:
+ /** Asks redstone handlers adjacent to a solid block how much power they will deliver to the querying position, via
+ the solid block. Both QueryPosition and SolidBlockPosition are relative to Chunk. */
+ static PowerLevel QueryLinkedPower(
+ const cChunk & Chunk,
+ Vector3i QueryPosition,
+ BLOCKTYPE QueryBlock,
+ Vector3i SolidBlockPosition
+ );
const cChunk & m_Chunk;
const Vector3i m_Position;
diff --git a/src/Simulator/IncrementalRedstoneSimulator/HopperHandler.h b/src/Simulator/IncrementalRedstoneSimulator/HopperHandler.h
index 95ef6ae62..006bda455 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/HopperHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/HopperHandler.h
@@ -9,52 +9,75 @@
namespace HopperHandler
{
- static PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
- {
- UNUSED(a_Chunk);
- UNUSED(a_Position);
- UNUSED(a_BlockType);
- UNUSED(a_QueryPosition);
- UNUSED(a_QueryBlockType);
- UNUSED(IsLinked);
- return 0;
- }
+static PowerLevel GetPowerDeliveredToPosition(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ Vector3i a_QueryPosition,
+ BLOCKTYPE a_QueryBlockType,
+ bool IsLinked
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_Position);
+ UNUSED(a_BlockType);
+ UNUSED(a_QueryPosition);
+ UNUSED(a_QueryBlockType);
+ UNUSED(IsLinked);
+ return 0;
+}
- static void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
- {
- // LOGD("Evaluating holey the hopper (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
+static void Update(
+ cChunk & a_Chunk,
+ cChunk &,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ const PowerLevel Power
+)
+{
+ // LOGD("Evaluating holey the hopper (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- const bool ShouldBeLocked = Power != 0;
- const bool PreviouslyLocked = (a_Meta & 0x8) == 0x8;
+ const bool ShouldBeLocked = Power != 0;
+ const bool PreviouslyLocked = (a_Meta & 0x8) == 0x8;
- if (ShouldBeLocked == PreviouslyLocked)
- {
- return;
- }
+ if (ShouldBeLocked == PreviouslyLocked)
+ {
+ return;
+ }
- if (ShouldBeLocked)
- {
- a_Chunk.SetMeta(a_Position, a_Meta | 0x8);
- }
- else
- {
- a_Chunk.SetMeta(a_Position, a_Meta & ~0x8);
- }
+ if (ShouldBeLocked)
+ {
+ a_Chunk.SetMeta(a_Position, a_Meta | 0x8);
+ }
+ else
+ {
+ a_Chunk.SetMeta(a_Position, a_Meta & ~0x8);
+ }
- a_Chunk.DoWithBlockEntityAt(a_Position, [ShouldBeLocked](cBlockEntity & a_BlockEntity)
+ a_Chunk.DoWithBlockEntityAt(
+ a_Position,
+ [ShouldBeLocked](cBlockEntity & a_BlockEntity)
{
ASSERT(a_BlockEntity.GetBlockType() == E_BLOCK_HOPPER);
static_cast<cHopperEntity &>(a_BlockEntity).SetLocked(ShouldBeLocked);
return false;
- });
- }
+ }
+ );
+}
- static void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback)
- {
- UNUSED(a_Chunk);
- UNUSED(a_BlockType);
- UNUSED(a_Meta);
- InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
- }
-};
+static void ForValidSourcePositions(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ ForEachSourceCallback & Callback
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_BlockType);
+ UNUSED(a_Meta);
+ InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
+}
+}; // namespace HopperHandler
diff --git a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp
index 8063e72a4..cf652b509 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp
+++ b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp
@@ -22,7 +22,7 @@ bool cIncrementalRedstoneSimulator::IsAlwaysTicked(BLOCKTYPE a_Block)
case E_BLOCK_STONE_PRESSURE_PLATE:
case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE:
case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: return true;
- default: return false;
+ default: return false;
}
}
@@ -112,7 +112,12 @@ void cIncrementalRedstoneSimulator::ProcessWorkItem(cChunk & Chunk, cChunk & Tic
-void cIncrementalRedstoneSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
+void cIncrementalRedstoneSimulator::SimulateChunk(
+ std::chrono::milliseconds a_Dt,
+ int a_ChunkX,
+ int a_ChunkZ,
+ cChunk * a_Chunk
+)
{
auto & ChunkData = *static_cast<cIncrementalRedstoneSimulatorChunkData *>(a_Chunk->GetRedstoneSimulatorData());
for (auto & DelayInfo : ChunkData.m_MechanismDelays)
@@ -194,7 +199,8 @@ void cIncrementalRedstoneSimulator::WakeUp(cChunk & a_Chunk, Vector3i a_Position
{
// Having WakeUp called on us directly means someone called SetBlock (or WakeUp)
// Since the simulator never does this, something external changed. Clear cached data:
- static_cast<cIncrementalRedstoneSimulatorChunkData *>(a_Chunk.GetRedstoneSimulatorData())->ErasePowerData(a_Position);
+ static_cast<cIncrementalRedstoneSimulatorChunkData *>(a_Chunk.GetRedstoneSimulatorData())
+ ->ErasePowerData(a_Position);
// Queue the block, in case the set block was redstone:
AddBlock(a_Chunk, a_Position, a_Block);
diff --git a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h
index 365f0176e..4f2028ff1 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h
@@ -7,17 +7,14 @@
-class cIncrementalRedstoneSimulator final :
- public cRedstoneSimulator
+class cIncrementalRedstoneSimulator final : public cRedstoneSimulator
{
using Super = cRedstoneSimulator;
-public:
-
+ public:
using Super::Super;
-private:
-
+ private:
/** Returns if a redstone device is always ticked due to influence by its environment */
static bool IsAlwaysTicked(BLOCKTYPE a_Block);
@@ -31,4 +28,4 @@ private:
virtual cRedstoneSimulatorChunkData * CreateChunkData() override;
virtual void WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override;
virtual void WakeUp(cChunk & a_Chunk, Vector3i a_Position, Vector3i a_Offset, BLOCKTYPE a_Block) override;
-} ;
+};
diff --git a/src/Simulator/IncrementalRedstoneSimulator/NoteBlockHandler.h b/src/Simulator/IncrementalRedstoneSimulator/NoteBlockHandler.h
index fd96d8721..21008cd89 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/NoteBlockHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/NoteBlockHandler.h
@@ -9,42 +9,65 @@
namespace NoteBlockHandler
{
- static PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
- {
- UNUSED(a_Chunk);
- UNUSED(a_Position);
- UNUSED(a_BlockType);
- UNUSED(a_QueryPosition);
- UNUSED(a_QueryBlockType);
- UNUSED(IsLinked);
- return 0;
- }
+static PowerLevel GetPowerDeliveredToPosition(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ Vector3i a_QueryPosition,
+ BLOCKTYPE a_QueryBlockType,
+ bool IsLinked
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_Position);
+ UNUSED(a_BlockType);
+ UNUSED(a_QueryPosition);
+ UNUSED(a_QueryBlockType);
+ UNUSED(IsLinked);
+ return 0;
+}
- static void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
- {
- // LOGD("Evaluating sparky the magical note block (%d %d %d) %i", a_Position.x, a_Position.y, a_Position.z, Power);
+static void Update(
+ cChunk & a_Chunk,
+ cChunk &,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ const PowerLevel Power
+)
+{
+ // LOGD("Evaluating sparky the magical note block (%d %d %d) %i", a_Position.x, a_Position.y, a_Position.z, Power);
- const auto Previous = DataForChunk(a_Chunk).ExchangeUpdateOncePowerData(a_Position, Power);
- if ((Previous != 0) || (Power == 0))
- {
- // If we're already powered or received an update of no power, don't make a sound
- return;
- }
+ const auto Previous = DataForChunk(a_Chunk).ExchangeUpdateOncePowerData(a_Position, Power);
+ if ((Previous != 0) || (Power == 0))
+ {
+ // If we're already powered or received an update of no power, don't make a sound
+ return;
+ }
- a_Chunk.DoWithBlockEntityAt(a_Position, [](cBlockEntity & a_BlockEntity)
+ a_Chunk.DoWithBlockEntityAt(
+ a_Position,
+ [](cBlockEntity & a_BlockEntity)
{
ASSERT(a_BlockEntity.GetBlockType() == E_BLOCK_NOTE_BLOCK);
static_cast<cNoteEntity &>(a_BlockEntity).MakeSound();
return false;
- });
- }
+ }
+ );
+}
- static void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback)
- {
- UNUSED(a_Chunk);
- UNUSED(a_BlockType);
- UNUSED(a_Meta);
- InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
- }
-};
+static void ForValidSourcePositions(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ ForEachSourceCallback & Callback
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_BlockType);
+ UNUSED(a_Meta);
+ InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
+}
+}; // namespace NoteBlockHandler
diff --git a/src/Simulator/IncrementalRedstoneSimulator/ObserverHandler.h b/src/Simulator/IncrementalRedstoneSimulator/ObserverHandler.h
index 802b9307c..4cac17b72 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/ObserverHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/ObserverHandler.h
@@ -9,100 +9,130 @@
namespace ObserverHandler
{
- static bool IsOn(NIBBLETYPE a_Meta)
+static bool IsOn(NIBBLETYPE a_Meta)
+{
+ return (a_Meta & 0x8) == 0x8;
+}
+
+static bool ShouldPowerOn(
+ cChunk & Chunk,
+ const Vector3i a_Position,
+ NIBBLETYPE a_Meta,
+ cIncrementalRedstoneSimulatorChunkData & a_Data
+)
+{
+ BLOCKTYPE BlockType;
+ NIBBLETYPE BlockMeta;
+ if (!Chunk.UnboundedRelGetBlock(
+ a_Position + cBlockObserverHandler::GetObservingFaceOffset(a_Meta),
+ BlockType,
+ BlockMeta
+ ))
{
- return (a_Meta & 0x8) == 0x8;
+ return false;
}
- static bool ShouldPowerOn(cChunk & Chunk, const Vector3i a_Position, NIBBLETYPE a_Meta, cIncrementalRedstoneSimulatorChunkData & a_Data)
- {
- BLOCKTYPE BlockType;
- NIBBLETYPE BlockMeta;
- if (!Chunk.UnboundedRelGetBlock(a_Position + cBlockObserverHandler::GetObservingFaceOffset(a_Meta), BlockType, BlockMeta))
- {
- return false;
- }
+ auto & ObserverCache = a_Data.ObserverCache;
+ const auto FindResult = ObserverCache.find(a_Position);
+ const auto Observed = std::make_pair(BlockType, BlockMeta);
- auto & ObserverCache = a_Data.ObserverCache;
- const auto FindResult = ObserverCache.find(a_Position);
- const auto Observed = std::make_pair(BlockType, BlockMeta);
+ if (FindResult == ObserverCache.end())
+ {
+ // Cache the last seen block for this position:
+ ObserverCache.emplace(a_Position, Observed);
- if (FindResult == ObserverCache.end())
- {
- // Cache the last seen block for this position:
- ObserverCache.emplace(a_Position, Observed);
+ // Definitely should signal update:
+ return true;
+ }
- // Definitely should signal update:
- return true;
- }
+ // The block this observer previously saw.
+ const auto Previous = FindResult->second;
- // The block this observer previously saw.
- const auto Previous = FindResult->second;
+ // Update the last seen block:
+ FindResult->second = Observed;
- // Update the last seen block:
- FindResult->second = Observed;
+ // Determine if to signal an update based on the block previously observed changed
+ return Previous != Observed;
+}
- // Determine if to signal an update based on the block previously observed changed
- return Previous != Observed;
- }
+static PowerLevel GetPowerDeliveredToPosition(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ Vector3i a_QueryPosition,
+ BLOCKTYPE a_QueryBlockType,
+ bool IsLinked
+)
+{
+ const auto Meta = a_Chunk.GetMeta(a_Position);
+ return (IsOn(Meta) && (a_QueryPosition == (a_Position + cBlockObserverHandler::GetSignalOutputOffset(Meta)))) ? 15
+ : 0;
+}
+
+static void Update(
+ cChunk & a_Chunk,
+ cChunk & CurrentlyTicking,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ const PowerLevel Power
+)
+{
+ // LOGD("Evaluating Lenny the observer (%i %i %i)", a_Position.x, a_Position.y, a_Position.z);
- static PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
- {
- const auto Meta = a_Chunk.GetMeta(a_Position);
- return (IsOn(Meta) && (a_QueryPosition == (a_Position + cBlockObserverHandler::GetSignalOutputOffset(Meta)))) ? 15 : 0;
- }
+ auto & Data = DataForChunk(a_Chunk);
+ auto DelayInfo = Data.GetMechanismDelayInfo(a_Position);
- static void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
+ if (DelayInfo == nullptr)
{
- // LOGD("Evaluating Lenny the observer (%i %i %i)", a_Position.x, a_Position.y, a_Position.z);
-
- auto & Data = DataForChunk(a_Chunk);
- auto DelayInfo = Data.GetMechanismDelayInfo(a_Position);
-
- if (DelayInfo == nullptr)
+ if (!ShouldPowerOn(a_Chunk, a_Position, a_Meta, Data))
{
- if (!ShouldPowerOn(a_Chunk, a_Position, a_Meta, Data))
- {
- return;
- }
-
- // From rest, we've determined there was a block update
- // Schedule power-on 1 tick in the future
- Data.m_MechanismDelays[a_Position] = std::make_pair(1, true);
-
return;
}
- int DelayTicks;
- bool ShouldPowerOn;
- std::tie(DelayTicks, ShouldPowerOn) = *DelayInfo;
+ // From rest, we've determined there was a block update
+ // Schedule power-on 1 tick in the future
+ Data.m_MechanismDelays[a_Position] = std::make_pair(1, true);
- if (DelayTicks != 0)
- {
- return;
- }
+ return;
+ }
- if (ShouldPowerOn)
- {
- // Remain on for 1 tick before resetting
- *DelayInfo = std::make_pair(1, false);
- a_Chunk.SetMeta(a_Position, a_Meta | 0x8);
- }
- else
- {
- // We've reset. Erase delay data in preparation for detecting further updates
- Data.m_MechanismDelays.erase(a_Position);
- a_Chunk.SetMeta(a_Position, a_Meta & ~0x8);
- }
+ int DelayTicks;
+ bool ShouldPowerOn;
+ std::tie(DelayTicks, ShouldPowerOn) = *DelayInfo;
- UpdateAdjustedRelative(a_Chunk, CurrentlyTicking, a_Position, cBlockObserverHandler::GetSignalOutputOffset(a_Meta));
+ if (DelayTicks != 0)
+ {
+ return;
}
- static void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback)
+ if (ShouldPowerOn)
+ {
+ // Remain on for 1 tick before resetting
+ *DelayInfo = std::make_pair(1, false);
+ a_Chunk.SetMeta(a_Position, a_Meta | 0x8);
+ }
+ else
{
- UNUSED(a_Chunk);
- UNUSED(a_Position);
- UNUSED(a_BlockType);
- UNUSED(a_BlockType);
+ // We've reset. Erase delay data in preparation for detecting further updates
+ Data.m_MechanismDelays.erase(a_Position);
+ a_Chunk.SetMeta(a_Position, a_Meta & ~0x8);
}
-};
+
+ UpdateAdjustedRelative(a_Chunk, CurrentlyTicking, a_Position, cBlockObserverHandler::GetSignalOutputOffset(a_Meta));
+}
+
+static void ForValidSourcePositions(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ ForEachSourceCallback & Callback
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_Position);
+ UNUSED(a_BlockType);
+ UNUSED(a_BlockType);
+}
+}; // namespace ObserverHandler
diff --git a/src/Simulator/IncrementalRedstoneSimulator/PistonHandler.h b/src/Simulator/IncrementalRedstoneSimulator/PistonHandler.h
index 9713bc0a6..16334808d 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/PistonHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/PistonHandler.h
@@ -9,59 +9,80 @@
namespace PistonHandler
{
- static PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
- {
- UNUSED(a_Chunk);
- UNUSED(a_Position);
- UNUSED(a_BlockType);
- UNUSED(a_QueryPosition);
- UNUSED(a_QueryBlockType);
- UNUSED(IsLinked);
- return 0;
- }
+static PowerLevel GetPowerDeliveredToPosition(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ Vector3i a_QueryPosition,
+ BLOCKTYPE a_QueryBlockType,
+ bool IsLinked
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_Position);
+ UNUSED(a_BlockType);
+ UNUSED(a_QueryPosition);
+ UNUSED(a_QueryBlockType);
+ UNUSED(IsLinked);
+ return 0;
+}
+
+static void Update(
+ cChunk & a_Chunk,
+ cChunk &,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ const PowerLevel Power
+)
+{
+ // LOGD("Evaluating pisty the piston (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- static void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
+ const bool ShouldBeExtended = Power != 0;
+ if (ShouldBeExtended == cBlockPistonHandler::IsExtended(a_Meta))
{
- // LOGD("Evaluating pisty the piston (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
-
- const bool ShouldBeExtended = Power != 0;
- if (ShouldBeExtended == cBlockPistonHandler::IsExtended(a_Meta))
- {
- return;
- }
+ return;
+ }
- a_Position = cChunkDef::RelativeToAbsolute(a_Position, a_Chunk.GetPos());
+ a_Position = cChunkDef::RelativeToAbsolute(a_Position, a_Chunk.GetPos());
- if (ShouldBeExtended)
- {
- cBlockPistonHandler::ExtendPiston(a_Position, *a_Chunk.GetWorld());
- }
- else
- {
- cBlockPistonHandler::RetractPiston(a_Position, *a_Chunk.GetWorld());
- }
-
- // It is necessary to delay after a signal to prevent an infinite loop (#3168)
- // However, this delay is already present: as a side effect of the implementation of piston animation in Blocks\BlockPiston.cpp
+ if (ShouldBeExtended)
+ {
+ cBlockPistonHandler::ExtendPiston(a_Position, *a_Chunk.GetWorld());
}
-
- static void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback)
+ else
{
- UNUSED(a_Chunk);
- UNUSED(a_BlockType);
+ cBlockPistonHandler::RetractPiston(a_Position, *a_Chunk.GetWorld());
+ }
- const auto Face = cBlockPistonHandler::MetaDataToDirection(a_Meta);
- const auto FrontOffset = AddFaceDirection(Vector3i(), Face);
+ // It is necessary to delay after a signal to prevent an infinite loop (#3168)
+ // However, this delay is already present: as a side effect of the implementation of piston animation in
+ // Blocks\BlockPiston.cpp
+}
+
+static void ForValidSourcePositions(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ ForEachSourceCallback & Callback
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_BlockType);
+
+ const auto Face = cBlockPistonHandler::MetaDataToDirection(a_Meta);
+ const auto FrontOffset = AddFaceDirection(Vector3i(), Face);
- for (const auto & Offset : RelativeAdjacents)
+ for (const auto & Offset : RelativeAdjacents)
+ {
+ if (Offset != FrontOffset)
{
- if (Offset != FrontOffset)
- {
- Callback(a_Position + Offset);
- }
+ Callback(a_Position + Offset);
}
-
- // Consider indirect power:
- Callback.CheckIndirectPower();
}
-};
+
+ // Consider indirect power:
+ Callback.CheckIndirectPower();
+}
+}; // namespace PistonHandler
diff --git a/src/Simulator/IncrementalRedstoneSimulator/PoweredRailHandler.h b/src/Simulator/IncrementalRedstoneSimulator/PoweredRailHandler.h
index 28eeb4b04..8220f14a7 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/PoweredRailHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/PoweredRailHandler.h
@@ -7,85 +7,105 @@
namespace PoweredRailHandler
{
- /** Get the offset along which the rail faces.
- Not in cBlockRailHandler since specific to powered rails. */
- static Vector3i GetPoweredRailAdjacentXZCoordinateOffset(NIBBLETYPE a_Meta)
+/** Get the offset along which the rail faces.
+Not in cBlockRailHandler since specific to powered rails. */
+static Vector3i GetPoweredRailAdjacentXZCoordinateOffset(NIBBLETYPE a_Meta)
+{
+ switch (a_Meta & 0x7)
{
- switch (a_Meta & 0x7)
+ case E_META_RAIL_ZM_ZP: return {0, 0, 1};
+ case E_META_RAIL_XM_XP: return {1, 0, 0};
+ case E_META_RAIL_ASCEND_XP: return {1, 1, 0};
+ case E_META_RAIL_ASCEND_XM: return {1, 1, 0};
+ case E_META_RAIL_ASCEND_ZM: return {0, 1, 1};
+ case E_META_RAIL_ASCEND_ZP: return {0, 1, 1};
+ default:
{
- case E_META_RAIL_ZM_ZP: return { 0, 0, 1 };
- case E_META_RAIL_XM_XP: return { 1, 0, 0 };
- case E_META_RAIL_ASCEND_XP: return { 1, 1, 0 };
- case E_META_RAIL_ASCEND_XM: return { 1, 1, 0 };
- case E_META_RAIL_ASCEND_ZM: return { 0, 1, 1 };
- case E_META_RAIL_ASCEND_ZP: return { 0, 1, 1 };
- default:
- {
- ASSERT(!"Impossible rail meta! wat wat wat");
- return { 0, 0, 0 };
- }
+ ASSERT(!"Impossible rail meta! wat wat wat");
+ return {0, 0, 0};
}
}
+}
- static PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
- {
- UNUSED(a_QueryBlockType);
+static PowerLevel GetPowerDeliveredToPosition(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ Vector3i a_QueryPosition,
+ BLOCKTYPE a_QueryBlockType,
+ bool IsLinked
+)
+{
+ UNUSED(a_QueryBlockType);
- const auto Meta = a_Chunk.GetMeta(a_Position);
- const auto Offset = GetPoweredRailAdjacentXZCoordinateOffset(Meta);
- if (((Offset + a_Position) == a_QueryPosition) || ((-Offset + a_Position) == a_QueryPosition))
- {
- const auto Power = DataForChunk(a_Chunk).GetCachedPowerData(a_Position);
- return (Power <= 7) ? 0 : (Power - 1);
- }
- return 0;
+ const auto Meta = a_Chunk.GetMeta(a_Position);
+ const auto Offset = GetPoweredRailAdjacentXZCoordinateOffset(Meta);
+ if (((Offset + a_Position) == a_QueryPosition) || ((-Offset + a_Position) == a_QueryPosition))
+ {
+ const auto Power = DataForChunk(a_Chunk).GetCachedPowerData(a_Position);
+ return (Power <= 7) ? 0 : (Power - 1);
}
+ return 0;
+}
- static void Update(cChunk & a_Chunk, cChunk & CurrentlyTickingChunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
- {
- // LOGD("Evaluating tracky the rail (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
+static void Update(
+ cChunk & a_Chunk,
+ cChunk & CurrentlyTickingChunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ const PowerLevel Power
+)
+{
+ // LOGD("Evaluating tracky the rail (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- switch (a_BlockType)
+ switch (a_BlockType)
+ {
+ case E_BLOCK_DETECTOR_RAIL:
{
- case E_BLOCK_DETECTOR_RAIL:
+ /*
+ if ((m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x08) == 0x08)
{
- /*
- if ((m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x08) == 0x08)
- {
- SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_MyType);
- }
- */
- return;
+ SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_MyType);
}
- case E_BLOCK_ACTIVATOR_RAIL:
- case E_BLOCK_POWERED_RAIL:
+ */
+ return;
+ }
+ case E_BLOCK_ACTIVATOR_RAIL:
+ case E_BLOCK_POWERED_RAIL:
+ {
+ const auto Offset = GetPoweredRailAdjacentXZCoordinateOffset(a_Meta);
+ if (Power != DataForChunk(a_Chunk).ExchangeUpdateOncePowerData(a_Position, Power))
{
- const auto Offset = GetPoweredRailAdjacentXZCoordinateOffset(a_Meta);
- if (Power != DataForChunk(a_Chunk).ExchangeUpdateOncePowerData(a_Position, Power))
- {
- a_Chunk.SetMeta(a_Position, (Power == 0) ? (a_Meta & 0x07) : (a_Meta | 0x08));
-
- UpdateAdjustedRelative(a_Chunk, CurrentlyTickingChunk, a_Position, Offset);
- UpdateAdjustedRelative(a_Chunk, CurrentlyTickingChunk, a_Position, -Offset);
- }
+ a_Chunk.SetMeta(a_Position, (Power == 0) ? (a_Meta & 0x07) : (a_Meta | 0x08));
- return;
- }
- default:
- {
- ASSERT(!"Unhandled type of rail in passed to rail handler!");
+ UpdateAdjustedRelative(a_Chunk, CurrentlyTickingChunk, a_Position, Offset);
+ UpdateAdjustedRelative(a_Chunk, CurrentlyTickingChunk, a_Position, -Offset);
}
+
+ return;
+ }
+ default:
+ {
+ ASSERT(!"Unhandled type of rail in passed to rail handler!");
}
}
+}
- static void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback)
- {
- UNUSED(a_Chunk);
- UNUSED(a_Meta);
+static void ForValidSourcePositions(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ ForEachSourceCallback & Callback
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_Meta);
- if ((a_BlockType == E_BLOCK_POWERED_RAIL) || (a_BlockType == E_BLOCK_ACTIVATOR_RAIL))
- {
- InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
- }
+ if ((a_BlockType == E_BLOCK_POWERED_RAIL) || (a_BlockType == E_BLOCK_ACTIVATOR_RAIL))
+ {
+ InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
}
-};
+}
+}; // namespace PoweredRailHandler
diff --git a/src/Simulator/IncrementalRedstoneSimulator/PressurePlateHandler.h b/src/Simulator/IncrementalRedstoneSimulator/PressurePlateHandler.h
index 003b5b253..dda3e2d57 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/PressurePlateHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/PressurePlateHandler.h
@@ -10,12 +10,14 @@
namespace PressurePlateHandler
{
- static unsigned char GetPowerLevel(const cChunk & Chunk, const Vector3i Position, const BLOCKTYPE BlockType)
- {
- size_t NumberOfEntities = 0;
- bool FoundPlayer = false;
+static unsigned char GetPowerLevel(const cChunk & Chunk, const Vector3i Position, const BLOCKTYPE BlockType)
+{
+ size_t NumberOfEntities = 0;
+ bool FoundPlayer = false;
- Chunk.ForEachEntityInBox(cBoundingBox(Vector3d(0.5, 0, 0.5) + Position, 0.5, 0.5), [&](cEntity & Entity)
+ Chunk.ForEachEntityInBox(
+ cBoundingBox(Vector3d(0.5, 0, 0.5) + Position, 0.5, 0.5),
+ [&](cEntity & Entity)
{
if (Entity.GetHealth() <= 0)
{
@@ -42,187 +44,210 @@ namespace PressurePlateHandler
NumberOfEntities++;
return false;
- });
+ }
+ );
- switch (BlockType)
+ switch (BlockType)
+ {
+ case E_BLOCK_STONE_PRESSURE_PLATE:
{
- case E_BLOCK_STONE_PRESSURE_PLATE:
- {
- return FoundPlayer ? 15 : 0;
- }
- case E_BLOCK_WOODEN_PRESSURE_PLATE:
- {
- return (NumberOfEntities != 0) ? 15 : 0;
- }
- case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE:
- {
- return std::min(static_cast<unsigned char>(CeilC(NumberOfEntities / 10.f)), static_cast<unsigned char>(15));
- }
- case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE:
- {
- return std::min(static_cast<unsigned char>(NumberOfEntities), static_cast<unsigned char>(15));
- }
- default:
- {
- ASSERT(!"Unhandled/unimplemented block in pressure plate handler!");
- return 0;
- }
+ return FoundPlayer ? 15 : 0;
+ }
+ case E_BLOCK_WOODEN_PRESSURE_PLATE:
+ {
+ return (NumberOfEntities != 0) ? 15 : 0;
+ }
+ case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE:
+ {
+ return std::min(static_cast<unsigned char>(CeilC(NumberOfEntities / 10.f)), static_cast<unsigned char>(15));
+ }
+ case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE:
+ {
+ return std::min(static_cast<unsigned char>(NumberOfEntities), static_cast<unsigned char>(15));
+ }
+ default:
+ {
+ ASSERT(!"Unhandled/unimplemented block in pressure plate handler!");
+ return 0;
}
}
+}
- static const char * GetClickOnSound(BLOCKTYPE a_BlockType)
+static const char * GetClickOnSound(BLOCKTYPE a_BlockType)
+{
+ // manage on-sound
+ switch (a_BlockType)
{
- // manage on-sound
- switch (a_BlockType)
+ case E_BLOCK_STONE_PRESSURE_PLATE: return "block.stone_pressureplate.click_on";
+ case E_BLOCK_WOODEN_PRESSURE_PLATE: return "block.wood_pressureplate.click_on";
+ case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE:
+ case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: return "block.metal_pressureplate.click_on";
+ default:
{
- case E_BLOCK_STONE_PRESSURE_PLATE: return "block.stone_pressureplate.click_on";
- case E_BLOCK_WOODEN_PRESSURE_PLATE: return "block.wood_pressureplate.click_on";
- case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE:
- case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: return "block.metal_pressureplate.click_on";
- default:
- {
- ASSERT(!"No on sound for this one!");
- return "";
- }
+ ASSERT(!"No on sound for this one!");
+ return "";
}
}
+}
- static const char * GetClickOffSound(BLOCKTYPE a_BlockType)
+static const char * GetClickOffSound(BLOCKTYPE a_BlockType)
+{
+ // manage off-sound
+ switch (a_BlockType)
{
- // manage off-sound
- switch (a_BlockType)
+ case E_BLOCK_STONE_PRESSURE_PLATE: return "block.stone_pressureplate.click_off";
+ case E_BLOCK_WOODEN_PRESSURE_PLATE: return "block.wood_pressureplate.click_off";
+ case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE:
+ case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: return "block.metal_pressureplate.click_off";
+ default:
{
- case E_BLOCK_STONE_PRESSURE_PLATE: return "block.stone_pressureplate.click_off";
- case E_BLOCK_WOODEN_PRESSURE_PLATE: return "block.wood_pressureplate.click_off";
- case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE:
- case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: return "block.metal_pressureplate.click_off";
- default:
- {
- ASSERT(!"No off sound for this one!");
- return "";
- }
+ ASSERT(!"No off sound for this one!");
+ return "";
}
}
+}
+
+static PowerLevel GetPowerDeliveredToPosition(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ Vector3i a_QueryPosition,
+ BLOCKTYPE a_QueryBlockType,
+ bool IsLinked
+)
+{
+ UNUSED(a_BlockType);
+ UNUSED(a_QueryPosition);
+ UNUSED(a_QueryBlockType);
+
+ // Plates only link power blocks below
+ // Retrieve and return the cached power calculated by Update for performance:
+ return (IsLinked && (a_QueryPosition != (a_Position + OffsetYM)))
+ ? 0
+ : DataForChunk(a_Chunk).GetCachedPowerData(a_Position);
+}
+
+static void Update(
+ cChunk & a_Chunk,
+ cChunk & CurrentlyTicking,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ const PowerLevel Power
+)
+{
+ // LOGD("Evaluating clicky the pressure plate (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- static PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
- {
- UNUSED(a_BlockType);
- UNUSED(a_QueryPosition);
- UNUSED(a_QueryBlockType);
+ auto & ChunkData = DataForChunk(a_Chunk);
- // Plates only link power blocks below
- // Retrieve and return the cached power calculated by Update for performance:
- return (IsLinked && (a_QueryPosition != (a_Position + OffsetYM))) ? 0 : DataForChunk(a_Chunk).GetCachedPowerData(a_Position);
- }
+ const auto PreviousPower = ChunkData.GetCachedPowerData(a_Position);
+ const auto Absolute = cChunkDef::RelativeToAbsolute(a_Position, a_Chunk.GetPos());
+ const auto PowerLevel = GetPowerLevel(a_Chunk, Absolute, a_BlockType); // Get the current power of the platey
+ const auto DelayInfo = ChunkData.GetMechanismDelayInfo(a_Position);
- static void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
+ // Resting state?
+ if (DelayInfo == nullptr)
{
- // LOGD("Evaluating clicky the pressure plate (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
+ if (PowerLevel == 0)
+ {
+ // Nothing happened, back to rest
+ return;
+ }
- auto & ChunkData = DataForChunk(a_Chunk);
+ // From rest, a player stepped on us
+ // Schedule a minimum 0.5 second delay before even thinking about releasing
+ ChunkData.m_MechanismDelays[a_Position] = std::make_pair(5, true);
- const auto PreviousPower = ChunkData.GetCachedPowerData(a_Position);
- const auto Absolute = cChunkDef::RelativeToAbsolute(a_Position, a_Chunk.GetPos());
- const auto PowerLevel = GetPowerLevel(a_Chunk, Absolute, a_BlockType); // Get the current power of the platey
- const auto DelayInfo = ChunkData.GetMechanismDelayInfo(a_Position);
+ a_Chunk.GetWorld()->BroadcastSoundEffect(GetClickOnSound(a_BlockType), Absolute, 0.5f, 0.6f);
- // Resting state?
- if (DelayInfo == nullptr)
- {
- if (PowerLevel == 0)
- {
- // Nothing happened, back to rest
- return;
- }
+ // Update power
+ ChunkData.SetCachedPowerData(a_Position, PowerLevel);
- // From rest, a player stepped on us
- // Schedule a minimum 0.5 second delay before even thinking about releasing
- ChunkData.m_MechanismDelays[a_Position] = std::make_pair(5, true);
+ // Immediately depress plate
+ a_Chunk.SetMeta(a_Position, E_META_PRESSURE_PLATE_DEPRESSED);
- a_Chunk.GetWorld()->BroadcastSoundEffect(GetClickOnSound(a_BlockType), Absolute, 0.5f, 0.6f);
+ UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position, RelativeAdjacents);
+ return;
+ }
- // Update power
- ChunkData.SetCachedPowerData(a_Position, PowerLevel);
+ // Not a resting state
- // Immediately depress plate
- a_Chunk.SetMeta(a_Position, E_META_PRESSURE_PLATE_DEPRESSED);
+ int DelayTicks;
+ bool HasExitedMinimumOnDelayPhase;
+ std::tie(DelayTicks, HasExitedMinimumOnDelayPhase) = *DelayInfo;
- UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position, RelativeAdjacents);
+ // Are we waiting for the initial delay or subsequent release delay?
+ if (DelayTicks > 0)
+ {
+ // Nothing changes, if there is nothing on it anymore, because the state is locked.
+ if (PowerLevel == 0)
+ {
return;
}
- // Not a resting state
-
- int DelayTicks;
- bool HasExitedMinimumOnDelayPhase;
- std::tie(DelayTicks, HasExitedMinimumOnDelayPhase) = *DelayInfo;
-
- // Are we waiting for the initial delay or subsequent release delay?
- if (DelayTicks > 0)
+ // Yes. Are we waiting to release, and found that the player stepped on it again?
+ if (!HasExitedMinimumOnDelayPhase)
{
- // Nothing changes, if there is nothing on it anymore, because the state is locked.
- if (PowerLevel == 0)
- {
- return;
- }
+ // Reset delay
+ *DelayInfo = std::make_pair(0, true);
+ }
- // Yes. Are we waiting to release, and found that the player stepped on it again?
- if (!HasExitedMinimumOnDelayPhase)
- {
- // Reset delay
- *DelayInfo = std::make_pair(0, true);
- }
+ // Did the power level change and is still above zero?
+ if (PowerLevel != PreviousPower)
+ {
+ // Yes. Update power
+ ChunkData.SetCachedPowerData(a_Position, PowerLevel);
+ UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position, RelativeAdjacents);
+ }
- // Did the power level change and is still above zero?
- if (PowerLevel != PreviousPower)
- {
- // Yes. Update power
- ChunkData.SetCachedPowerData(a_Position, PowerLevel);
- UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position, RelativeAdjacents);
- }
+ return;
+ }
+ // Not waiting for anything. Has the initial delay elapsed?
+ if (HasExitedMinimumOnDelayPhase)
+ {
+ // Yep, initial delay elapsed. Has the player gotten off?
+ if (PowerLevel == 0)
+ {
+ // Yes. Go into subsequent release delay, for a further 0.5 seconds
+ *DelayInfo = std::make_pair(5, false);
return;
}
- // Not waiting for anything. Has the initial delay elapsed?
- if (HasExitedMinimumOnDelayPhase)
+ // Did the power level change and is still above zero?
+ if (PowerLevel != PreviousPower)
{
- // Yep, initial delay elapsed. Has the player gotten off?
- if (PowerLevel == 0)
- {
- // Yes. Go into subsequent release delay, for a further 0.5 seconds
- *DelayInfo = std::make_pair(5, false);
- return;
- }
-
- // Did the power level change and is still above zero?
- if (PowerLevel != PreviousPower)
- {
- // Yes. Update power
- ChunkData.SetCachedPowerData(a_Position, PowerLevel);
- UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position, RelativeAdjacents);
- }
-
- // Yes, but player's still on the plate, do nothing
- return;
+ // Yes. Update power
+ ChunkData.SetCachedPowerData(a_Position, PowerLevel);
+ UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position, RelativeAdjacents);
}
- // Just got out of the subsequent release phase, reset everything and raise the plate
- ChunkData.m_MechanismDelays.erase(a_Position);
+ // Yes, but player's still on the plate, do nothing
+ return;
+ }
- a_Chunk.GetWorld()->BroadcastSoundEffect(GetClickOffSound(a_BlockType), Absolute, 0.5f, 0.5f);
- ChunkData.SetCachedPowerData(a_Position, PowerLevel);
+ // Just got out of the subsequent release phase, reset everything and raise the plate
+ ChunkData.m_MechanismDelays.erase(a_Position);
- a_Chunk.SetMeta(a_Position, E_META_PRESSURE_PLATE_RAISED);
- UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position, RelativeAdjacents);
- }
+ a_Chunk.GetWorld()->BroadcastSoundEffect(GetClickOffSound(a_BlockType), Absolute, 0.5f, 0.5f);
+ ChunkData.SetCachedPowerData(a_Position, PowerLevel);
- static void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback)
- {
- UNUSED(a_Chunk);
- UNUSED(a_Position);
- UNUSED(a_BlockType);
- UNUSED(a_Meta);
- UNUSED(Callback);
- }
-};
+ a_Chunk.SetMeta(a_Position, E_META_PRESSURE_PLATE_RAISED);
+ UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position, RelativeAdjacents);
+}
+
+static void ForValidSourcePositions(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ ForEachSourceCallback & Callback
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_Position);
+ UNUSED(a_BlockType);
+ UNUSED(a_Meta);
+ UNUSED(Callback);
+}
+}; // namespace PressurePlateHandler
diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneBlockHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneBlockHandler.h
index 25e44f3d7..d80c53303 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneBlockHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneBlockHandler.h
@@ -7,27 +7,47 @@
namespace RedstoneBlockHandler
{
- static PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
- {
- UNUSED(a_Chunk);
- UNUSED(a_Position);
- UNUSED(a_BlockType);
- UNUSED(a_QueryPosition);
- UNUSED(IsLinked);
- return IsLinked ? 0 : 15;
- }
-
- static void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
- {
- // LOGD("Evaluating crimson the redstone block (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- }
-
- static void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback)
- {
- UNUSED(a_Chunk);
- UNUSED(a_Position);
- UNUSED(a_BlockType);
- UNUSED(a_Meta);
- UNUSED(Callback);
- }
-};
+static PowerLevel GetPowerDeliveredToPosition(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ Vector3i a_QueryPosition,
+ BLOCKTYPE a_QueryBlockType,
+ bool IsLinked
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_Position);
+ UNUSED(a_BlockType);
+ UNUSED(a_QueryPosition);
+ UNUSED(IsLinked);
+ return IsLinked ? 0 : 15;
+}
+
+static void Update(
+ cChunk & a_Chunk,
+ cChunk & CurrentlyTicking,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ const PowerLevel Power
+)
+{
+ // LOGD("Evaluating crimson the redstone block (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
+}
+
+static void ForValidSourcePositions(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ ForEachSourceCallback & Callback
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_Position);
+ UNUSED(a_BlockType);
+ UNUSED(a_Meta);
+ UNUSED(Callback);
+}
+}; // namespace RedstoneBlockHandler
diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneComparatorHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneComparatorHandler.h
index df8f697a2..b90c4b693 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneComparatorHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneComparatorHandler.h
@@ -9,44 +9,60 @@
namespace RedstoneComparatorHandler
{
- static unsigned char GetFrontPowerLevel(NIBBLETYPE a_Meta, unsigned char a_HighestSidePowerLevel, unsigned char a_HighestRearPowerLevel)
+static unsigned char GetFrontPowerLevel(
+ NIBBLETYPE a_Meta,
+ unsigned char a_HighestSidePowerLevel,
+ unsigned char a_HighestRearPowerLevel
+)
+{
+ if (cBlockComparatorHandler::IsInSubtractionMode(a_Meta))
{
- if (cBlockComparatorHandler::IsInSubtractionMode(a_Meta))
- {
- // Subtraction mode
- return static_cast<unsigned char>(std::max(static_cast<char>(a_HighestRearPowerLevel) - a_HighestSidePowerLevel, 0));
- }
- else
- {
- // Comparison mode
- return (a_HighestRearPowerLevel < a_HighestSidePowerLevel) ? 0 : a_HighestRearPowerLevel;
- }
+ // Subtraction mode
+ return static_cast<unsigned char>(
+ std::max(static_cast<char>(a_HighestRearPowerLevel) - a_HighestSidePowerLevel, 0)
+ );
}
-
- static PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
+ else
{
- UNUSED(a_QueryPosition);
- UNUSED(a_QueryBlockType);
-
- const auto Meta = a_Chunk.GetMeta(a_Position);
- return (
- (cBlockComparatorHandler::GetFrontCoordinate(a_Position, Meta & 0x3) == a_QueryPosition) ?
- DataForChunk(a_Chunk).GetCachedPowerData(a_Position) : 0
- );
+ // Comparison mode
+ return (a_HighestRearPowerLevel < a_HighestSidePowerLevel) ? 0 : a_HighestRearPowerLevel;
}
+}
+
+static PowerLevel GetPowerDeliveredToPosition(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ Vector3i a_QueryPosition,
+ BLOCKTYPE a_QueryBlockType,
+ bool IsLinked
+)
+{
+ UNUSED(a_QueryPosition);
+ UNUSED(a_QueryBlockType);
+
+ const auto Meta = a_Chunk.GetMeta(a_Position);
+ return (
+ (cBlockComparatorHandler::GetFrontCoordinate(a_Position, Meta & 0x3) == a_QueryPosition)
+ ? DataForChunk(a_Chunk).GetCachedPowerData(a_Position)
+ : 0
+ );
+}
+
+static unsigned char GetPowerLevel(cChunk & a_Chunk, Vector3i Position, BLOCKTYPE BlockType, NIBBLETYPE Meta)
+{
+ UInt8 SignalStrength = 0;
+ auto RearCoordinate = cBlockComparatorHandler::GetRearCoordinate(Position, Meta & 0x3);
- static unsigned char GetPowerLevel(cChunk & a_Chunk, Vector3i Position, BLOCKTYPE BlockType, NIBBLETYPE Meta)
+ auto RearChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(RearCoordinate);
+ if ((RearChunk == nullptr) || !RearChunk->IsValid())
{
- UInt8 SignalStrength = 0;
- auto RearCoordinate = cBlockComparatorHandler::GetRearCoordinate(Position, Meta & 0x3);
-
- auto RearChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(RearCoordinate);
- if ((RearChunk == nullptr) || !RearChunk->IsValid())
- {
- return SignalStrength;
- }
+ return SignalStrength;
+ }
- RearChunk->DoWithBlockEntityAt(RearCoordinate, [&](cBlockEntity & a_BlockEntity)
+ RearChunk->DoWithBlockEntityAt(
+ RearCoordinate,
+ [&](cBlockEntity & a_BlockEntity)
{
// Skip BlockEntities that don't have slots
auto BlockEntityWithItems = dynamic_cast<cBlockEntityWithItems *>(&a_BlockEntity);
@@ -62,75 +78,102 @@ namespace RedstoneComparatorHandler
for (int Slot = 0; Slot != Contents.GetNumSlots(); ++Slot)
{
- Fullness += static_cast<float>(Contents.GetSlot(Slot).m_ItemCount) / Contents.GetSlot(Slot).GetMaxStackSize();
+ Fullness +=
+ static_cast<float>(Contents.GetSlot(Slot).m_ItemCount) / Contents.GetSlot(Slot).GetMaxStackSize();
}
- SignalStrength = (Fullness < 0.001 /* container empty? */) ? 0 : static_cast<UInt8>(1 + (Fullness / Contents.GetNumSlots()) * 14);
+ SignalStrength = (Fullness < 0.001 /* container empty? */)
+ ? 0
+ : static_cast<UInt8>(1 + (Fullness / Contents.GetNumSlots()) * 14);
return false;
- });
-
- const auto RearType = RearChunk->GetBlock(RearCoordinate);
- return std::max(
- SignalStrength,
- RedstoneHandler::GetPowerDeliveredToPosition(
- *RearChunk, RearCoordinate, RearType,
- cIncrementalRedstoneSimulatorChunkData::RebaseRelativePosition(a_Chunk, *RearChunk, Position), BlockType, false
- )
- );
- }
-
- static void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
- {
- // Note that Power here contains the maximum * side * power level, as specified by GetValidSourcePositions
- // LOGD("Evaluating ALU the comparator (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
-
- auto & Data = DataForChunk(a_Chunk);
- auto DelayInfo = Data.GetMechanismDelayInfo(a_Position);
-
- // Delay is used here to prevent an infinite loop (#3168)
- if (DelayInfo == nullptr)
- {
- const auto RearPower = GetPowerLevel(a_Chunk, a_Position, a_BlockType, a_Meta);
- const auto FrontPower = GetFrontPowerLevel(a_Meta, Power, RearPower);
- const auto PreviousFrontPower = Data.GetCachedPowerData(a_Position);
- const bool ShouldUpdate = (FrontPower != PreviousFrontPower); // "Business logic" (:P) - determined by side and rear power levels
-
- if (ShouldUpdate)
- {
- Data.m_MechanismDelays[a_Position] = std::make_pair(1, bool());
- }
-
- return;
}
+ );
+
+ const auto RearType = RearChunk->GetBlock(RearCoordinate);
+ return std::max(
+ SignalStrength,
+ RedstoneHandler::GetPowerDeliveredToPosition(
+ *RearChunk,
+ RearCoordinate,
+ RearType,
+ cIncrementalRedstoneSimulatorChunkData::RebaseRelativePosition(a_Chunk, *RearChunk, Position),
+ BlockType,
+ false
+ )
+ );
+}
+
+static void Update(
+ cChunk & a_Chunk,
+ cChunk & CurrentlyTicking,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ const PowerLevel Power
+)
+{
+ // Note that Power here contains the maximum * side * power level, as specified by GetValidSourcePositions
+ // LOGD("Evaluating ALU the comparator (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- int DelayTicks;
- std::tie(DelayTicks, std::ignore) = *DelayInfo;
-
- if (DelayTicks != 0)
- {
- return;
- }
+ auto & Data = DataForChunk(a_Chunk);
+ auto DelayInfo = Data.GetMechanismDelayInfo(a_Position);
+ // Delay is used here to prevent an infinite loop (#3168)
+ if (DelayInfo == nullptr)
+ {
const auto RearPower = GetPowerLevel(a_Chunk, a_Position, a_BlockType, a_Meta);
const auto FrontPower = GetFrontPowerLevel(a_Meta, Power, RearPower);
- const NIBBLETYPE NewMeta = (FrontPower > 0) ? (a_Meta | 0x08u) : (a_Meta & 0x07u);
-
- // Don't care about the previous power level so return value ignored
- Data.ExchangeUpdateOncePowerData(a_Position, FrontPower);
+ const auto PreviousFrontPower = Data.GetCachedPowerData(a_Position);
+ const bool ShouldUpdate =
+ (FrontPower != PreviousFrontPower); // "Business logic" (:P) - determined by side and rear power levels
- a_Chunk.SetMeta(a_Position, NewMeta);
- Data.m_MechanismDelays.erase(a_Position);
+ if (ShouldUpdate)
+ {
+ Data.m_MechanismDelays[a_Position] = std::make_pair(1, bool());
+ }
- // Assume that an update (to front power) is needed:
- UpdateAdjustedRelative(a_Chunk, CurrentlyTicking, a_Position, cBlockComparatorHandler::GetFrontCoordinate(a_Position, a_Meta & 0x3) - a_Position);
+ return;
}
- static void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback)
- {
- UNUSED(a_Chunk);
- UNUSED(a_BlockType);
+ int DelayTicks;
+ std::tie(DelayTicks, std::ignore) = *DelayInfo;
- Callback(cBlockComparatorHandler::GetSideCoordinate(a_Position, a_Meta & 0x3, false));
- Callback(cBlockComparatorHandler::GetSideCoordinate(a_Position, a_Meta & 0x3, true));
+ if (DelayTicks != 0)
+ {
+ return;
}
-};
+
+ const auto RearPower = GetPowerLevel(a_Chunk, a_Position, a_BlockType, a_Meta);
+ const auto FrontPower = GetFrontPowerLevel(a_Meta, Power, RearPower);
+ const NIBBLETYPE NewMeta = (FrontPower > 0) ? (a_Meta | 0x08u) : (a_Meta & 0x07u);
+
+ // Don't care about the previous power level so return value ignored
+ Data.ExchangeUpdateOncePowerData(a_Position, FrontPower);
+
+ a_Chunk.SetMeta(a_Position, NewMeta);
+ Data.m_MechanismDelays.erase(a_Position);
+
+ // Assume that an update (to front power) is needed:
+ UpdateAdjustedRelative(
+ a_Chunk,
+ CurrentlyTicking,
+ a_Position,
+ cBlockComparatorHandler::GetFrontCoordinate(a_Position, a_Meta & 0x3) - a_Position
+ );
+}
+
+static void ForValidSourcePositions(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ ForEachSourceCallback & Callback
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_BlockType);
+
+ Callback(cBlockComparatorHandler::GetSideCoordinate(a_Position, a_Meta & 0x3, false));
+ Callback(cBlockComparatorHandler::GetSideCoordinate(a_Position, a_Meta & 0x3, true));
+}
+}; // namespace RedstoneComparatorHandler
diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneDataHelper.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneDataHelper.h
index 3942f803c..e10c6027f 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneDataHelper.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneDataHelper.h
@@ -7,7 +7,12 @@ inline auto & DataForChunk(const cChunk & a_Chunk)
return *static_cast<cIncrementalRedstoneSimulatorChunkData *>(a_Chunk.GetRedstoneSimulatorData());
}
-inline void UpdateAdjustedRelative(const cChunk & a_Chunk, const cChunk & a_TickingChunk, const Vector3i a_Position, const Vector3i a_Offset)
+inline void UpdateAdjustedRelative(
+ const cChunk & a_Chunk,
+ const cChunk & a_TickingChunk,
+ const Vector3i a_Position,
+ const Vector3i a_Offset
+)
{
const auto PositionToWake = a_Position + a_Offset;
@@ -20,20 +25,31 @@ inline void UpdateAdjustedRelative(const cChunk & a_Chunk, const cChunk & a_Tick
auto & ChunkData = DataForChunk(a_TickingChunk);
// Schedule the block in the requested direction to update:
- ChunkData.WakeUp(cIncrementalRedstoneSimulatorChunkData::RebaseRelativePosition(a_Chunk, a_TickingChunk, PositionToWake));
+ ChunkData.WakeUp(
+ cIncrementalRedstoneSimulatorChunkData::RebaseRelativePosition(a_Chunk, a_TickingChunk, PositionToWake)
+ );
// To follow Vanilla behaviour, update all linked positions:
for (const auto & LinkedOffset : cSimulator::GetLinkedOffsets(a_Offset))
{
if (const auto LinkedPositionToWake = a_Position + LinkedOffset; cChunkDef::IsValidHeight(LinkedPositionToWake))
{
- ChunkData.WakeUp(cIncrementalRedstoneSimulatorChunkData::RebaseRelativePosition(a_Chunk, a_TickingChunk, LinkedPositionToWake));
+ ChunkData.WakeUp(cIncrementalRedstoneSimulatorChunkData::RebaseRelativePosition(
+ a_Chunk,
+ a_TickingChunk,
+ LinkedPositionToWake
+ ));
}
}
}
template <typename ArrayType>
-inline void UpdateAdjustedRelatives(const cChunk & a_Chunk, const cChunk & a_TickingChunk, const Vector3i a_Position, const ArrayType & a_Relative)
+inline void UpdateAdjustedRelatives(
+ const cChunk & a_Chunk,
+ const cChunk & a_TickingChunk,
+ const Vector3i a_Position,
+ const ArrayType & a_Relative
+)
{
for (const auto & Offset : a_Relative)
{
@@ -42,7 +58,11 @@ inline void UpdateAdjustedRelatives(const cChunk & a_Chunk, const cChunk & a_Tic
}
template <typename ArrayType>
-inline void InvokeForAdjustedRelatives(ForEachSourceCallback & Callback, const Vector3i Position, const ArrayType & Relative)
+inline void InvokeForAdjustedRelatives(
+ ForEachSourceCallback & Callback,
+ const Vector3i Position,
+ const ArrayType & Relative
+)
{
for (const auto & Offset : Relative)
{
@@ -50,28 +70,22 @@ inline void InvokeForAdjustedRelatives(ForEachSourceCallback & Callback, const V
}
}
-inline constexpr Vector3i OffsetYP{ 0, 1, 0 };
+inline constexpr Vector3i OffsetYP {0, 1, 0};
-inline constexpr Vector3i OffsetYM{ 0, -1, 0 };
+inline constexpr Vector3i OffsetYM {0, -1, 0};
-inline constexpr std::array<Vector3i, 6> RelativeAdjacents
-{
- {
- { 1, 0, 0 },
- { -1, 0, 0 },
- { 0, 1, 0 },
- { 0, -1, 0 },
- { 0, 0, 1 },
- { 0, 0, -1 },
- }
-};
+inline constexpr std::array<Vector3i, 6> RelativeAdjacents {{
+ {1, 0, 0},
+ {-1, 0, 0},
+ {0, 1, 0},
+ {0, -1, 0},
+ {0, 0, 1},
+ {0, 0, -1},
+}};
-inline constexpr std::array<Vector3i, 4> RelativeLaterals
-{
- {
- { 1, 0, 0 },
- { -1, 0, 0 },
- { 0, 0, 1 },
- { 0, 0, -1 },
- }
-};
+inline constexpr std::array<Vector3i, 4> RelativeLaterals {{
+ {1, 0, 0},
+ {-1, 0, 0},
+ {0, 0, 1},
+ {0, 0, -1},
+}};
diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneHandler.cpp b/src/Simulator/IncrementalRedstoneSimulator/RedstoneHandler.cpp
index ab6b35c0b..cfe9a03ea 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneHandler.cpp
+++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneHandler.cpp
@@ -32,61 +32,62 @@
-#define INVOKE_FOR_HANDLERS(Callback) \
- do \
- { \
- switch (BlockType) \
- { \
- case E_BLOCK_ACTIVATOR_RAIL: \
- case E_BLOCK_DETECTOR_RAIL: \
- case E_BLOCK_POWERED_RAIL: return PoweredRailHandler::Callback; \
- case E_BLOCK_ACTIVE_COMPARATOR: \
- case E_BLOCK_INACTIVE_COMPARATOR: return RedstoneComparatorHandler::Callback; \
- case E_BLOCK_DISPENSER: \
- case E_BLOCK_DROPPER: return DropSpenserHandler::Callback; \
- case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: \
- case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: \
- case E_BLOCK_STONE_PRESSURE_PLATE: \
- case E_BLOCK_WOODEN_PRESSURE_PLATE: return PressurePlateHandler::Callback; \
- case E_BLOCK_ACACIA_FENCE_GATE: \
- case E_BLOCK_BIRCH_FENCE_GATE: \
- case E_BLOCK_DARK_OAK_FENCE_GATE: \
- case E_BLOCK_FENCE_GATE: \
- case E_BLOCK_IRON_TRAPDOOR: \
- case E_BLOCK_JUNGLE_FENCE_GATE: \
- case E_BLOCK_SPRUCE_FENCE_GATE: \
- case E_BLOCK_TRAPDOOR: return SmallGateHandler::Callback; \
- case E_BLOCK_REDSTONE_LAMP_OFF: \
- case E_BLOCK_REDSTONE_LAMP_ON: return RedstoneLampHandler::Callback; \
- case E_BLOCK_REDSTONE_REPEATER_OFF: \
- case E_BLOCK_REDSTONE_REPEATER_ON: return RedstoneRepeaterHandler::Callback; \
- case E_BLOCK_REDSTONE_TORCH_OFF: \
- case E_BLOCK_REDSTONE_TORCH_ON: return RedstoneTorchHandler::Callback; \
- case E_BLOCK_OBSERVER: return ObserverHandler::Callback; \
- case E_BLOCK_PISTON: \
- case E_BLOCK_STICKY_PISTON: return PistonHandler::Callback; \
- case E_BLOCK_DAYLIGHT_SENSOR: \
- case E_BLOCK_INVERTED_DAYLIGHT_SENSOR: return DaylightSensorHandler::Callback; \
- case E_BLOCK_LEVER: \
- case E_BLOCK_STONE_BUTTON: \
- case E_BLOCK_WOODEN_BUTTON: return RedstoneToggleHandler::Callback; \
- case E_BLOCK_BLOCK_OF_REDSTONE: return RedstoneBlockHandler::Callback; \
- case E_BLOCK_COMMAND_BLOCK: return CommandBlockHandler::Callback; \
- case E_BLOCK_HOPPER: return HopperHandler::Callback; \
- case E_BLOCK_NOTE_BLOCK: return NoteBlockHandler::Callback; \
- case E_BLOCK_REDSTONE_WIRE: return RedstoneWireHandler::Callback; \
- case E_BLOCK_TNT: return TNTHandler::Callback; \
- case E_BLOCK_TRAPPED_CHEST: return TrappedChestHandler::Callback; \
- case E_BLOCK_TRIPWIRE_HOOK: return TripwireHookHandler::Callback; \
- default: \
- { \
- if (cBlockDoorHandler::IsDoorBlockType(BlockType)) \
- { \
- return DoorHandler::Callback; \
- } \
- } \
- } \
- } while (false)
+#define INVOKE_FOR_HANDLERS(Callback) \
+ do \
+ { \
+ switch (BlockType) \
+ { \
+ case E_BLOCK_ACTIVATOR_RAIL: \
+ case E_BLOCK_DETECTOR_RAIL: \
+ case E_BLOCK_POWERED_RAIL: return PoweredRailHandler::Callback; \
+ case E_BLOCK_ACTIVE_COMPARATOR: \
+ case E_BLOCK_INACTIVE_COMPARATOR: return RedstoneComparatorHandler::Callback; \
+ case E_BLOCK_DISPENSER: \
+ case E_BLOCK_DROPPER: return DropSpenserHandler::Callback; \
+ case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: \
+ case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: \
+ case E_BLOCK_STONE_PRESSURE_PLATE: \
+ case E_BLOCK_WOODEN_PRESSURE_PLATE: return PressurePlateHandler::Callback; \
+ case E_BLOCK_ACACIA_FENCE_GATE: \
+ case E_BLOCK_BIRCH_FENCE_GATE: \
+ case E_BLOCK_DARK_OAK_FENCE_GATE: \
+ case E_BLOCK_FENCE_GATE: \
+ case E_BLOCK_IRON_TRAPDOOR: \
+ case E_BLOCK_JUNGLE_FENCE_GATE: \
+ case E_BLOCK_SPRUCE_FENCE_GATE: \
+ case E_BLOCK_TRAPDOOR: return SmallGateHandler::Callback; \
+ case E_BLOCK_REDSTONE_LAMP_OFF: \
+ case E_BLOCK_REDSTONE_LAMP_ON: return RedstoneLampHandler::Callback; \
+ case E_BLOCK_REDSTONE_REPEATER_OFF: \
+ case E_BLOCK_REDSTONE_REPEATER_ON: return RedstoneRepeaterHandler::Callback; \
+ case E_BLOCK_REDSTONE_TORCH_OFF: \
+ case E_BLOCK_REDSTONE_TORCH_ON: return RedstoneTorchHandler::Callback; \
+ case E_BLOCK_OBSERVER: return ObserverHandler::Callback; \
+ case E_BLOCK_PISTON: \
+ case E_BLOCK_STICKY_PISTON: return PistonHandler::Callback; \
+ case E_BLOCK_DAYLIGHT_SENSOR: \
+ case E_BLOCK_INVERTED_DAYLIGHT_SENSOR: return DaylightSensorHandler::Callback; \
+ case E_BLOCK_LEVER: \
+ case E_BLOCK_STONE_BUTTON: \
+ case E_BLOCK_WOODEN_BUTTON: return RedstoneToggleHandler::Callback; \
+ case E_BLOCK_BLOCK_OF_REDSTONE: return RedstoneBlockHandler::Callback; \
+ case E_BLOCK_COMMAND_BLOCK: return CommandBlockHandler::Callback; \
+ case E_BLOCK_HOPPER: return HopperHandler::Callback; \
+ case E_BLOCK_NOTE_BLOCK: return NoteBlockHandler::Callback; \
+ case E_BLOCK_REDSTONE_WIRE: return RedstoneWireHandler::Callback; \
+ case E_BLOCK_TNT: return TNTHandler::Callback; \
+ case E_BLOCK_TRAPPED_CHEST: return TrappedChestHandler::Callback; \
+ case E_BLOCK_TRIPWIRE_HOOK: return TripwireHookHandler::Callback; \
+ default: \
+ { \
+ if (cBlockDoorHandler::IsDoorBlockType(BlockType)) \
+ { \
+ return DoorHandler::Callback; \
+ } \
+ } \
+ } \
+ } \
+ while (false)
@@ -94,30 +95,51 @@
namespace RedstoneHandler
{
- PowerLevel GetPowerDeliveredToPosition(const cChunk & Chunk, const Vector3i Position, const BLOCKTYPE BlockType, const Vector3i QueryPosition, const BLOCKTYPE QueryBlockType, const bool IsLinked)
- {
- INVOKE_FOR_HANDLERS(GetPowerDeliveredToPosition(Chunk, Position, BlockType, QueryPosition, QueryBlockType, IsLinked));
-
- // Fell through the switch statement
- // Block at Position doesn't have a corresponding redstone handler
- // ErasePowerData will have been called in AddBlock
-
- // Default:
- return 0;
- }
-
- void Update(cChunk & Chunk, cChunk & CurrentlyTicking, const Vector3i Position, const BLOCKTYPE BlockType, const NIBBLETYPE Meta, const PowerLevel PowerLevel)
- {
- INVOKE_FOR_HANDLERS(Update(Chunk, CurrentlyTicking, Position, BlockType, Meta, PowerLevel));
- }
-
- void ForValidSourcePositions(const cChunk & Chunk, const Vector3i Position, const BLOCKTYPE BlockType, const NIBBLETYPE Meta, ForEachSourceCallback & Callback)
- {
- INVOKE_FOR_HANDLERS(ForValidSourcePositions(Chunk, Position, BlockType, Meta, Callback));
- }
-
- void SetWireState(const cChunk & Chunk, const Vector3i Position)
- {
- RedstoneWireHandler::SetWireState(Chunk, Position);
- }
+PowerLevel GetPowerDeliveredToPosition(
+ const cChunk & Chunk,
+ const Vector3i Position,
+ const BLOCKTYPE BlockType,
+ const Vector3i QueryPosition,
+ const BLOCKTYPE QueryBlockType,
+ const bool IsLinked
+)
+{
+ INVOKE_FOR_HANDLERS(GetPowerDeliveredToPosition(Chunk, Position, BlockType, QueryPosition, QueryBlockType, IsLinked)
+ );
+
+ // Fell through the switch statement
+ // Block at Position doesn't have a corresponding redstone handler
+ // ErasePowerData will have been called in AddBlock
+
+ // Default:
+ return 0;
+}
+
+void Update(
+ cChunk & Chunk,
+ cChunk & CurrentlyTicking,
+ const Vector3i Position,
+ const BLOCKTYPE BlockType,
+ const NIBBLETYPE Meta,
+ const PowerLevel PowerLevel
+)
+{
+ INVOKE_FOR_HANDLERS(Update(Chunk, CurrentlyTicking, Position, BlockType, Meta, PowerLevel));
+}
+
+void ForValidSourcePositions(
+ const cChunk & Chunk,
+ const Vector3i Position,
+ const BLOCKTYPE BlockType,
+ const NIBBLETYPE Meta,
+ ForEachSourceCallback & Callback
+)
+{
+ INVOKE_FOR_HANDLERS(ForValidSourcePositions(Chunk, Position, BlockType, Meta, Callback));
+}
+
+void SetWireState(const cChunk & Chunk, const Vector3i Position)
+{
+ RedstoneWireHandler::SetWireState(Chunk, Position);
}
+} // namespace RedstoneHandler
diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneHandler.h
index fdac7901f..42334e58b 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneHandler.h
@@ -16,19 +16,40 @@ class ForEachSourceCallback;
namespace RedstoneHandler
{
- /** Asks a redstone component at the source position how much power it will deliver to the querying position.
- If IsLinked is true, QueryPosition should point to the intermediate conduit block.
- The Position and QueryPosition are both relative to Chunk. */
- PowerLevel GetPowerDeliveredToPosition(const cChunk & Chunk, Vector3i Position, BLOCKTYPE BlockType, Vector3i QueryPosition, BLOCKTYPE QueryBlockType, bool IsLinked);
-
- /** Tells a redstone component at this position to update itself.
- PowerLevel represents the maximum power level all of its source positions gave to it.
- Position is relative to Chunk, but if the component needs to queue neighbour updates, they are queued to CurrentlyTicking. */
- void Update(cChunk & Chunk, cChunk & CurrentlyTicking, Vector3i Position, BLOCKTYPE BlockType, NIBBLETYPE Meta, PowerLevel PowerLevel);
-
- /** Invokes Callback for each position this component can accept power from. */
- void ForValidSourcePositions(const cChunk & Chunk, Vector3i Position, BLOCKTYPE BlockType, NIBBLETYPE Meta, ForEachSourceCallback & Callback);
-
- /** Temporary: compute and set the block state of a redstone wire. */
- void SetWireState(const cChunk & Chunk, Vector3i Position);
-}
+/** Asks a redstone component at the source position how much power it will deliver to the querying position.
+If IsLinked is true, QueryPosition should point to the intermediate conduit block.
+The Position and QueryPosition are both relative to Chunk. */
+PowerLevel GetPowerDeliveredToPosition(
+ const cChunk & Chunk,
+ Vector3i Position,
+ BLOCKTYPE BlockType,
+ Vector3i QueryPosition,
+ BLOCKTYPE QueryBlockType,
+ bool IsLinked
+);
+
+/** Tells a redstone component at this position to update itself.
+PowerLevel represents the maximum power level all of its source positions gave to it.
+Position is relative to Chunk, but if the component needs to queue neighbour updates, they are queued to
+CurrentlyTicking. */
+void Update(
+ cChunk & Chunk,
+ cChunk & CurrentlyTicking,
+ Vector3i Position,
+ BLOCKTYPE BlockType,
+ NIBBLETYPE Meta,
+ PowerLevel PowerLevel
+);
+
+/** Invokes Callback for each position this component can accept power from. */
+void ForValidSourcePositions(
+ const cChunk & Chunk,
+ Vector3i Position,
+ BLOCKTYPE BlockType,
+ NIBBLETYPE Meta,
+ ForEachSourceCallback & Callback
+);
+
+/** Temporary: compute and set the block state of a redstone wire. */
+void SetWireState(const cChunk & Chunk, Vector3i Position);
+} // namespace RedstoneHandler
diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneLampHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneLampHandler.h
index 3b37783f6..e65e10fb7 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneLampHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneLampHandler.h
@@ -7,41 +7,61 @@
namespace RedstoneLampHandler
{
- static bool IsOn(BLOCKTYPE a_BlockType)
- {
- return (a_BlockType == E_BLOCK_REDSTONE_LAMP_ON);
- }
+static bool IsOn(BLOCKTYPE a_BlockType)
+{
+ return (a_BlockType == E_BLOCK_REDSTONE_LAMP_ON);
+}
- static PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
- {
- return 0;
- }
+static PowerLevel GetPowerDeliveredToPosition(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ Vector3i a_QueryPosition,
+ BLOCKTYPE a_QueryBlockType,
+ bool IsLinked
+)
+{
+ return 0;
+}
- static void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
- {
- // LOGD("Evaluating lamp (%i %i %i)", a_Position.x, a_Position.y, a_Position.z);
+static void Update(
+ cChunk & a_Chunk,
+ cChunk &,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ const PowerLevel Power
+)
+{
+ // LOGD("Evaluating lamp (%i %i %i)", a_Position.x, a_Position.y, a_Position.z);
- if (Power > 0)
+ if (Power > 0)
+ {
+ if (!IsOn(a_BlockType))
{
- if (!IsOn(a_BlockType))
- {
- a_Chunk.FastSetBlock(a_Position, E_BLOCK_REDSTONE_LAMP_ON, 0);
- }
+ a_Chunk.FastSetBlock(a_Position, E_BLOCK_REDSTONE_LAMP_ON, 0);
}
- else
+ }
+ else
+ {
+ if (IsOn(a_BlockType))
{
- if (IsOn(a_BlockType))
- {
- a_Chunk.FastSetBlock(a_Position, E_BLOCK_REDSTONE_LAMP_OFF, 0);
- }
+ a_Chunk.FastSetBlock(a_Position, E_BLOCK_REDSTONE_LAMP_OFF, 0);
}
}
+}
- static void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback)
- {
- UNUSED(a_Chunk);
- UNUSED(a_Meta);
- UNUSED(a_BlockType);
- InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
- }
-};
+static void ForValidSourcePositions(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ ForEachSourceCallback & Callback
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_Meta);
+ UNUSED(a_BlockType);
+ InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
+}
+}; // namespace RedstoneLampHandler
diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneRepeaterHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneRepeaterHandler.h
index 8f5e8c1b7..ea10e004e 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneRepeaterHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneRepeaterHandler.h
@@ -9,147 +9,170 @@
namespace RedstoneRepeaterHandler
{
- static bool IsOn(BLOCKTYPE a_Block)
- {
- return (a_Block == E_BLOCK_REDSTONE_REPEATER_ON);
- }
-
- /** Returns a pair with first element indicating if the block at the given position is an activated repeater.
- If it is activated, the second element is the repeater metadata. */
- static std::pair<bool, NIBBLETYPE> IsOnRepeater(cChunk & Chunk, const Vector3i a_Position)
- {
- BLOCKTYPE Type;
- NIBBLETYPE Meta;
-
- if (!Chunk.UnboundedRelGetBlock(a_Position, Type, Meta))
- {
- return std::make_pair(false, static_cast<NIBBLETYPE>(0));
- }
+static bool IsOn(BLOCKTYPE a_Block)
+{
+ return (a_Block == E_BLOCK_REDSTONE_REPEATER_ON);
+}
- return std::make_pair(IsOn(Type), Meta);
- }
+/** Returns a pair with first element indicating if the block at the given position is an activated repeater.
+If it is activated, the second element is the repeater metadata. */
+static std::pair<bool, NIBBLETYPE> IsOnRepeater(cChunk & Chunk, const Vector3i a_Position)
+{
+ BLOCKTYPE Type;
+ NIBBLETYPE Meta;
- /** Determine, from the metadata of a repeater on our left side, if they lock us.
- To test a repeater on our right, simply invert the order of arguments provided.
- "Left" is relative to the direction the repeater output faces, naturally. */
- static bool DoesLhsLockMe(NIBBLETYPE a_MetaLhs, NIBBLETYPE a_MyMeta)
+ if (!Chunk.UnboundedRelGetBlock(a_Position, Type, Meta))
{
- // Get the direction bits
- a_MetaLhs &= E_META_REDSTONE_REPEATER_FACING_MASK;
- a_MyMeta &= E_META_REDSTONE_REPEATER_FACING_MASK;
-
- /*
- Check for a valid locking configuration, where they are perpendicular and one snuggles into the other.
-
- Order of comparisons:
- XP >^ ZM
- ZP |_ XP
- XM <| ZP
- ZP ^< xM
-
- Key:
- ^ Facing up
- _ Facing right
- | Facing down
- < Facing left
- */
- return
- ((a_MetaLhs == E_META_REDSTONE_REPEATER_FACING_XP) && (a_MyMeta == E_META_REDSTONE_REPEATER_FACING_ZM)) ||
- ((a_MetaLhs == E_META_REDSTONE_REPEATER_FACING_ZP) && (a_MyMeta == E_META_REDSTONE_REPEATER_FACING_XP)) ||
- ((a_MetaLhs == E_META_REDSTONE_REPEATER_FACING_XM) && (a_MyMeta == E_META_REDSTONE_REPEATER_FACING_ZP)) ||
- ((a_MetaLhs == E_META_REDSTONE_REPEATER_FACING_ZM) && (a_MyMeta == E_META_REDSTONE_REPEATER_FACING_XM))
- ;
+ return std::make_pair(false, static_cast<NIBBLETYPE>(0));
}
- /** Determine if a repeater is locked.
- A locked repeater is one with another powered repeater facing them, to their immediate left or right sides.
- "Left" is relative to the direction the repeater output faces, naturally. */
- static bool IsLocked(cChunk & Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta)
- {
- // The left hand side offset. Will be negated to get the rhs offset
- const auto LhsOffset = cBlockRedstoneRepeaterHandler::GetLeftCoordinateOffset(a_Meta);
+ return std::make_pair(IsOn(Type), Meta);
+}
- // Test the block to the left of us
- const auto Lhs = IsOnRepeater(Chunk, LhsOffset + a_Position);
- if (Lhs.first && DoesLhsLockMe(Lhs.second, a_Meta))
- {
- return true;
- }
+/** Determine, from the metadata of a repeater on our left side, if they lock us.
+To test a repeater on our right, simply invert the order of arguments provided.
+"Left" is relative to the direction the repeater output faces, naturally. */
+static bool DoesLhsLockMe(NIBBLETYPE a_MetaLhs, NIBBLETYPE a_MyMeta)
+{
+ // Get the direction bits
+ a_MetaLhs &= E_META_REDSTONE_REPEATER_FACING_MASK;
+ a_MyMeta &= E_META_REDSTONE_REPEATER_FACING_MASK;
+
+ /*
+ Check for a valid locking configuration, where they are perpendicular and one snuggles into the other.
+
+ Order of comparisons:
+ XP >^ ZM
+ ZP |_ XP
+ XM <| ZP
+ ZP ^< xM
+
+ Key:
+ ^ Facing up
+ _ Facing right
+ | Facing down
+ < Facing left
+ */
+ return ((a_MetaLhs == E_META_REDSTONE_REPEATER_FACING_XP) && (a_MyMeta == E_META_REDSTONE_REPEATER_FACING_ZM)) ||
+ ((a_MetaLhs == E_META_REDSTONE_REPEATER_FACING_ZP) && (a_MyMeta == E_META_REDSTONE_REPEATER_FACING_XP)) ||
+ ((a_MetaLhs == E_META_REDSTONE_REPEATER_FACING_XM) && (a_MyMeta == E_META_REDSTONE_REPEATER_FACING_ZP)) ||
+ ((a_MetaLhs == E_META_REDSTONE_REPEATER_FACING_ZM) && (a_MyMeta == E_META_REDSTONE_REPEATER_FACING_XM));
+}
+
+/** Determine if a repeater is locked.
+A locked repeater is one with another powered repeater facing them, to their immediate left or right sides.
+"Left" is relative to the direction the repeater output faces, naturally. */
+static bool IsLocked(cChunk & Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta)
+{
+ // The left hand side offset. Will be negated to get the rhs offset
+ const auto LhsOffset = cBlockRedstoneRepeaterHandler::GetLeftCoordinateOffset(a_Meta);
- // Test the right side, flipping the argument order to DoesLhsLockMe
- const auto Rhs = IsOnRepeater(Chunk, -LhsOffset + a_Position);
- return Rhs.first && DoesLhsLockMe(a_Meta, Rhs.second);
+ // Test the block to the left of us
+ const auto Lhs = IsOnRepeater(Chunk, LhsOffset + a_Position);
+ if (Lhs.first && DoesLhsLockMe(Lhs.second, a_Meta))
+ {
+ return true;
}
- static PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
+ // Test the right side, flipping the argument order to DoesLhsLockMe
+ const auto Rhs = IsOnRepeater(Chunk, -LhsOffset + a_Position);
+ return Rhs.first && DoesLhsLockMe(a_Meta, Rhs.second);
+}
+
+static PowerLevel GetPowerDeliveredToPosition(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ Vector3i a_QueryPosition,
+ BLOCKTYPE a_QueryBlockType,
+ bool IsLinked
+)
+{
+ if (!IsOn(a_BlockType))
{
- if (!IsOn(a_BlockType))
- {
- return 0;
- }
-
- const auto FrontOffset = cBlockRedstoneRepeaterHandler::GetFrontCoordinateOffset(a_Chunk.GetMeta(a_Position));
- const auto FrontPosition = a_Position + FrontOffset;
- if (a_QueryPosition == FrontPosition)
- {
- return 15;
- }
-
return 0;
}
- static void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
+ const auto FrontOffset = cBlockRedstoneRepeaterHandler::GetFrontCoordinateOffset(a_Chunk.GetMeta(a_Position));
+ const auto FrontPosition = a_Position + FrontOffset;
+ if (a_QueryPosition == FrontPosition)
{
- // LOGD("Evaluating loopy the repeater (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
-
- auto & Data = DataForChunk(a_Chunk);
- const auto DelayInfo = Data.GetMechanismDelayInfo(a_Position);
+ return 15;
+ }
- // If the repeater is locked by another, ignore and forget all power changes:
- if (IsLocked(a_Chunk, a_Position, a_Meta))
- {
- if (DelayInfo != nullptr)
- {
- Data.m_MechanismDelays.erase(a_Position);
- }
+ return 0;
+}
+
+static void Update(
+ cChunk & a_Chunk,
+ cChunk & CurrentlyTicking,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ const PowerLevel Power
+)
+{
+ // LOGD("Evaluating loopy the repeater (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- return;
- }
+ auto & Data = DataForChunk(a_Chunk);
+ const auto DelayInfo = Data.GetMechanismDelayInfo(a_Position);
- if (DelayInfo == nullptr)
+ // If the repeater is locked by another, ignore and forget all power changes:
+ if (IsLocked(a_Chunk, a_Position, a_Meta))
+ {
+ if (DelayInfo != nullptr)
{
- bool ShouldBeOn = (Power != 0);
- if (ShouldBeOn != IsOn(a_BlockType))
- {
- Data.m_MechanismDelays[a_Position] = std::make_pair((((a_Meta & 0xC) >> 0x2) + 1), ShouldBeOn);
- }
-
- return;
+ Data.m_MechanismDelays.erase(a_Position);
}
- int DelayTicks;
- bool ShouldPowerOn;
- std::tie(DelayTicks, ShouldPowerOn) = *DelayInfo;
+ return;
+ }
- if (DelayTicks != 0)
+ if (DelayInfo == nullptr)
+ {
+ bool ShouldBeOn = (Power != 0);
+ if (ShouldBeOn != IsOn(a_BlockType))
{
- return;
+ Data.m_MechanismDelays[a_Position] = std::make_pair((((a_Meta & 0xC) >> 0x2) + 1), ShouldBeOn);
}
- const auto NewType = ShouldPowerOn ? E_BLOCK_REDSTONE_REPEATER_ON : E_BLOCK_REDSTONE_REPEATER_OFF;
- a_Chunk.FastSetBlock(a_Position, NewType, a_Meta);
- Data.m_MechanismDelays.erase(a_Position);
-
- // While sleeping, we ignore any power changes and apply our saved ShouldBeOn when sleep expires
- // Now, we need to recalculate to be aware of any new changes that may e.g. cause a new output change
- // FastSetBlock doesn't wake simulators, so manually update ourselves:
- Update(a_Chunk, CurrentlyTicking, a_Position, NewType, a_Meta, Power);
-
- UpdateAdjustedRelative(a_Chunk, CurrentlyTicking, a_Position, cBlockRedstoneRepeaterHandler::GetFrontCoordinateOffset(a_Meta));
+ return;
}
- static void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback)
+ int DelayTicks;
+ bool ShouldPowerOn;
+ std::tie(DelayTicks, ShouldPowerOn) = *DelayInfo;
+
+ if (DelayTicks != 0)
{
- Callback(cBlockRedstoneRepeaterHandler::GetRearCoordinateOffset(a_Meta) + a_Position);
+ return;
}
-};
+
+ const auto NewType = ShouldPowerOn ? E_BLOCK_REDSTONE_REPEATER_ON : E_BLOCK_REDSTONE_REPEATER_OFF;
+ a_Chunk.FastSetBlock(a_Position, NewType, a_Meta);
+ Data.m_MechanismDelays.erase(a_Position);
+
+ // While sleeping, we ignore any power changes and apply our saved ShouldBeOn when sleep expires
+ // Now, we need to recalculate to be aware of any new changes that may e.g. cause a new output change
+ // FastSetBlock doesn't wake simulators, so manually update ourselves:
+ Update(a_Chunk, CurrentlyTicking, a_Position, NewType, a_Meta, Power);
+
+ UpdateAdjustedRelative(
+ a_Chunk,
+ CurrentlyTicking,
+ a_Position,
+ cBlockRedstoneRepeaterHandler::GetFrontCoordinateOffset(a_Meta)
+ );
+}
+
+static void ForValidSourcePositions(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ ForEachSourceCallback & Callback
+)
+{
+ Callback(cBlockRedstoneRepeaterHandler::GetRearCoordinateOffset(a_Meta) + a_Position);
+}
+}; // namespace RedstoneRepeaterHandler
diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneSimulatorChunkData.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneSimulatorChunkData.h
index f9545d997..9a31d1872 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneSimulatorChunkData.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneSimulatorChunkData.h
@@ -19,17 +19,10 @@ using PowerLevel = unsigned char;
class cIncrementalRedstoneSimulatorChunkData final : public cRedstoneSimulatorChunkData
{
-public:
+ public:
+ void WakeUp(const Vector3i & a_Position) { m_ActiveBlocks.push(a_Position); }
- void WakeUp(const Vector3i & a_Position)
- {
- m_ActiveBlocks.push(a_Position);
- }
-
- auto & GetActiveBlocks()
- {
- return m_ActiveBlocks;
- }
+ auto & GetActiveBlocks() { return m_ActiveBlocks; }
PowerLevel GetCachedPowerData(const Vector3i Position) const
{
@@ -74,8 +67,7 @@ public:
/** Adjust From-relative coordinates into To-relative coordinates. */
inline static Vector3i RebaseRelativePosition(const cChunk & From, const cChunk & To, const Vector3i Position)
{
- return
- {
+ return {
Position.x + (From.GetPosX() - To.GetPosX()) * cChunkDef::Width,
Position.y,
Position.z + (From.GetPosZ() - To.GetPosZ()) * cChunkDef::Width
@@ -93,8 +85,7 @@ public:
/** Structure storing position of mechanism + it's delay ticks (countdown) & if to power on. */
std::unordered_map<Vector3i, std::pair<int, bool>, VectorHasher<int>> m_MechanismDelays;
-private:
-
+ private:
std::stack<Vector3i, std::vector<Vector3i>> m_ActiveBlocks;
// TODO: map<Vector3i, int> -> Position of torch + it's heat level
diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneToggleHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneToggleHandler.h
index 45682406d..cd8a4d45c 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneToggleHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneToggleHandler.h
@@ -10,96 +10,116 @@
namespace RedstoneToggleHandler
{
- static Vector3i GetOffsetAttachedTo(Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta)
+static Vector3i GetOffsetAttachedTo(Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta)
+{
+ switch (a_BlockType)
{
- switch (a_BlockType)
+ case E_BLOCK_LEVER:
{
- case E_BLOCK_LEVER:
+ switch (a_Meta & 0x7)
{
- switch (a_Meta & 0x7)
+ case 0x0:
+ case 0x7: return {0, 1, 0};
+ case 0x1: return {-1, 0, 0};
+ case 0x2: return {1, 0, 0};
+ case 0x3: return {0, 0, -1};
+ case 0x4: return {0, 0, 1};
+ case 0x5:
+ case 0x6: return {0, -1, 0};
+ default:
{
- case 0x0:
- case 0x7: return { 0, 1, 0 };
- case 0x1: return { -1, 0, 0 };
- case 0x2: return { 1, 0, 0 };
- case 0x3: return { 0, 0, -1 };
- case 0x4: return { 0, 0, 1 };
- case 0x5:
- case 0x6: return { 0, -1, 0 };
- default:
- {
- ASSERT(!"Unhandled lever metadata!");
- return { 0, 0, 0 };
- }
+ ASSERT(!"Unhandled lever metadata!");
+ return {0, 0, 0};
}
}
- case E_BLOCK_STONE_BUTTON:
- case E_BLOCK_WOODEN_BUTTON:
+ }
+ case E_BLOCK_STONE_BUTTON:
+ case E_BLOCK_WOODEN_BUTTON:
+ {
+ switch (a_Meta & 0x7)
{
- switch (a_Meta & 0x7)
+ case 0x0: return {0, 1, 0};
+ case 0x1: return {-1, 0, 0};
+ case 0x2: return {1, 0, 0};
+ case 0x3: return {0, 0, -1};
+ case 0x4: return {0, 0, 1};
+ case 0x5: return {0, -1, 0};
+ default:
{
- case 0x0: return { 0, 1, 0 };
- case 0x1: return { -1, 0, 0 };
- case 0x2: return { 1, 0, 0 };
- case 0x3: return { 0, 0, -1 };
- case 0x4: return { 0, 0, 1 };
- case 0x5: return { 0, -1, 0 };
- default:
- {
- ASSERT(!"Unhandled button metadata!");
- return { 0, 0, 0 };
- }
+ ASSERT(!"Unhandled button metadata!");
+ return {0, 0, 0};
}
}
- default:
- {
- ASSERT(!"Unexpected block passed to button/lever handler");
- return { 0, 0, 0 };
- }
}
- }
-
- static unsigned char GetPowerLevel(BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta)
- {
- switch (a_BlockType)
+ default:
{
- case E_BLOCK_LEVER: return cBlockLeverHandler::IsLeverOn(a_Meta) ? 15 : 0;
- case E_BLOCK_STONE_BUTTON:
- case E_BLOCK_WOODEN_BUTTON: return cBlockButtonHandler::IsButtonOn(a_Meta) ? 15 : 0;
- default:
- {
- ASSERT(!"Unexpected block passed to button/lever handler");
- return 0;
- }
+ ASSERT(!"Unexpected block passed to button/lever handler");
+ return {0, 0, 0};
}
}
+}
- static PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
+static unsigned char GetPowerLevel(BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta)
+{
+ switch (a_BlockType)
{
- UNUSED(a_QueryBlockType);
-
- const auto Meta = a_Chunk.GetMeta(a_Position);
- const auto QueryOffset = a_QueryPosition - a_Position;
-
- if (IsLinked && (QueryOffset != GetOffsetAttachedTo(a_Position, a_BlockType, Meta)))
+ case E_BLOCK_LEVER: return cBlockLeverHandler::IsLeverOn(a_Meta) ? 15 : 0;
+ case E_BLOCK_STONE_BUTTON:
+ case E_BLOCK_WOODEN_BUTTON: return cBlockButtonHandler::IsButtonOn(a_Meta) ? 15 : 0;
+ default:
{
+ ASSERT(!"Unexpected block passed to button/lever handler");
return 0;
}
-
- return GetPowerLevel(a_BlockType, Meta);
}
+}
- static void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
- {
- // LOGD("Evaluating templatio<> the lever/button (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- }
+static PowerLevel GetPowerDeliveredToPosition(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ Vector3i a_QueryPosition,
+ BLOCKTYPE a_QueryBlockType,
+ bool IsLinked
+)
+{
+ UNUSED(a_QueryBlockType);
+
+ const auto Meta = a_Chunk.GetMeta(a_Position);
+ const auto QueryOffset = a_QueryPosition - a_Position;
- static void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback)
+ if (IsLinked && (QueryOffset != GetOffsetAttachedTo(a_Position, a_BlockType, Meta)))
{
- UNUSED(a_Chunk);
- UNUSED(a_Position);
- UNUSED(a_BlockType);
- UNUSED(a_Meta);
- UNUSED(Callback);
+ return 0;
}
-};
+
+ return GetPowerLevel(a_BlockType, Meta);
+}
+
+static void Update(
+ cChunk & a_Chunk,
+ cChunk & CurrentlyTicking,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ const PowerLevel Power
+)
+{
+ // LOGD("Evaluating templatio<> the lever/button (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
+}
+
+static void ForValidSourcePositions(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ ForEachSourceCallback & Callback
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_Position);
+ UNUSED(a_BlockType);
+ UNUSED(a_Meta);
+ UNUSED(Callback);
+}
+}; // namespace RedstoneToggleHandler
diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneTorchHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneTorchHandler.h
index 8acaecc8d..ef9279602 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneTorchHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneTorchHandler.h
@@ -7,89 +7,106 @@
namespace RedstoneTorchHandler
{
- static bool IsOn(BLOCKTYPE a_Block)
- {
- return (a_Block == E_BLOCK_REDSTONE_TORCH_ON);
- }
+static bool IsOn(BLOCKTYPE a_Block)
+{
+ return (a_Block == E_BLOCK_REDSTONE_TORCH_ON);
+}
- static Vector3i GetOffsetAttachedTo(const NIBBLETYPE a_Meta)
+static Vector3i GetOffsetAttachedTo(const NIBBLETYPE a_Meta)
+{
+ switch (a_Meta)
{
- switch (a_Meta)
+ case E_META_TORCH_FLOOR: return {0, -1, 0};
+ case E_META_TORCH_EAST: return {-1, 0, 0};
+ case E_META_TORCH_WEST: return {1, 0, 0};
+ case E_META_TORCH_NORTH: return {0, 0, 1};
+ case E_META_TORCH_SOUTH: return {0, 0, -1};
+ default:
{
- case E_META_TORCH_FLOOR: return { 0, -1, 0 };
- case E_META_TORCH_EAST: return { -1, 0, 0 };
- case E_META_TORCH_WEST: return { 1, 0, 0 };
- case E_META_TORCH_NORTH: return { 0, 0, 1 };
- case E_META_TORCH_SOUTH: return { 0, 0, -1 };
- default:
- {
- ASSERT(!"Unhandled torch metadata");
- return { 0, 0, 0 };
- }
+ ASSERT(!"Unhandled torch metadata");
+ return {0, 0, 0};
}
}
+}
+
+static PowerLevel GetPowerDeliveredToPosition(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ Vector3i a_QueryPosition,
+ BLOCKTYPE a_QueryBlockType,
+ bool IsLinked
+)
+{
+ const auto QueryOffset = a_QueryPosition - a_Position;
- static PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
+ if (!IsOn(a_BlockType) || (QueryOffset == GetOffsetAttachedTo(a_Chunk.GetMeta(a_Position))) ||
+ (IsLinked && (QueryOffset != OffsetYP)))
{
- const auto QueryOffset = a_QueryPosition - a_Position;
-
- if (
- !IsOn(a_BlockType) ||
- (QueryOffset == GetOffsetAttachedTo(a_Chunk.GetMeta(a_Position))) ||
- (IsLinked && (QueryOffset != OffsetYP))
- )
- {
- return 0;
- }
-
- return 15;
+ return 0;
}
- static void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
- {
- // LOGD("Evaluating torchy the redstone torch (%i %i %i)", a_Position.x, a_Position.y, a_Position.z);
+ return 15;
+}
+
+static void Update(
+ cChunk & a_Chunk,
+ cChunk & CurrentlyTicking,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ const PowerLevel Power
+)
+{
+ // LOGD("Evaluating torchy the redstone torch (%i %i %i)", a_Position.x, a_Position.y, a_Position.z);
- auto & Data = DataForChunk(a_Chunk);
- auto DelayInfo = Data.GetMechanismDelayInfo(a_Position);
+ auto & Data = DataForChunk(a_Chunk);
+ auto DelayInfo = Data.GetMechanismDelayInfo(a_Position);
- if (DelayInfo == nullptr)
+ if (DelayInfo == nullptr)
+ {
+ const bool ShouldBeOn = (Power == 0);
+ if (ShouldBeOn != IsOn(a_BlockType))
{
- const bool ShouldBeOn = (Power == 0);
- if (ShouldBeOn != IsOn(a_BlockType))
- {
- Data.m_MechanismDelays[a_Position] = std::make_pair(1, ShouldBeOn);
- }
-
- return;
+ Data.m_MechanismDelays[a_Position] = std::make_pair(1, ShouldBeOn);
}
- int DelayTicks;
- bool ShouldPowerOn;
- std::tie(DelayTicks, ShouldPowerOn) = *DelayInfo;
-
- if (DelayTicks != 0)
- {
- return;
- }
+ return;
+ }
- a_Chunk.FastSetBlock(a_Position, ShouldPowerOn ? E_BLOCK_REDSTONE_TORCH_ON : E_BLOCK_REDSTONE_TORCH_OFF, a_Meta);
- Data.m_MechanismDelays.erase(a_Position);
+ int DelayTicks;
+ bool ShouldPowerOn;
+ std::tie(DelayTicks, ShouldPowerOn) = *DelayInfo;
- for (const auto & Adjacent : RelativeAdjacents)
- {
- // Update all adjacents (including linked power positions)
- // apart from our attachment, which can't possibly need an update:
- if (Adjacent != GetOffsetAttachedTo(a_Meta))
- {
- UpdateAdjustedRelative(a_Chunk, CurrentlyTicking, a_Position, Adjacent);
- }
- }
+ if (DelayTicks != 0)
+ {
+ return;
}
- static void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback)
+ a_Chunk.FastSetBlock(a_Position, ShouldPowerOn ? E_BLOCK_REDSTONE_TORCH_ON : E_BLOCK_REDSTONE_TORCH_OFF, a_Meta);
+ Data.m_MechanismDelays.erase(a_Position);
+
+ for (const auto & Adjacent : RelativeAdjacents)
{
- UNUSED(a_Chunk);
- UNUSED(a_BlockType);
- Callback(a_Position + GetOffsetAttachedTo(a_Meta));
+ // Update all adjacents (including linked power positions)
+ // apart from our attachment, which can't possibly need an update:
+ if (Adjacent != GetOffsetAttachedTo(a_Meta))
+ {
+ UpdateAdjustedRelative(a_Chunk, CurrentlyTicking, a_Position, Adjacent);
+ }
}
-};
+}
+
+static void ForValidSourcePositions(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ ForEachSourceCallback & Callback
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_BlockType);
+ Callback(a_Position + GetOffsetAttachedTo(a_Meta));
+}
+}; // namespace RedstoneTorchHandler
diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h
index b40491820..6706e4078 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h
@@ -10,48 +10,51 @@
namespace RedstoneWireHandler
{
- /** A unified representation of wire direction. */
- enum class TemporaryDirection
- {
- Up,
- Side
- };
-
- /** Invokes Callback with the wire's left, front, and right direction state corresponding to Offset.
- Returns a new block constructed from the directions that the callback may have modified. */
- template <class OffsetCallback>
- static BlockState DoWithDirectionState(const Vector3i Offset, BlockState Block, OffsetCallback Callback)
- {
- auto North = Block::RedstoneWire::North(Block);
- auto South = Block::RedstoneWire::South(Block);
- auto West = Block::RedstoneWire::West(Block);
- auto East = Block::RedstoneWire::East(Block);
-
- if (Offset.x == -1)
- {
- Callback(South, West, North);
- }
- else if (Offset.x == 1)
- {
- Callback(North, East, South);
- }
+/** A unified representation of wire direction. */
+enum class TemporaryDirection
+{
+ Up,
+ Side
+};
- if (Offset.z == -1)
- {
- Callback(West, North, East);
- }
- else if (Offset.z == 1)
- {
- Callback(East, South, West);
- }
+/** Invokes Callback with the wire's left, front, and right direction state corresponding to Offset.
+Returns a new block constructed from the directions that the callback may have modified. */
+template <class OffsetCallback>
+static BlockState DoWithDirectionState(const Vector3i Offset, BlockState Block, OffsetCallback Callback)
+{
+ auto North = Block::RedstoneWire::North(Block);
+ auto South = Block::RedstoneWire::South(Block);
+ auto West = Block::RedstoneWire::West(Block);
+ auto East = Block::RedstoneWire::East(Block);
- return Block::RedstoneWire::RedstoneWire(East, North, 0, South, West);
+ if (Offset.x == -1)
+ {
+ Callback(South, West, North);
+ }
+ else if (Offset.x == 1)
+ {
+ Callback(North, East, South);
}
- /** Adjusts a given wire block so that the direction represented by Offset has state Direction. */
- static void SetDirectionState(const Vector3i Offset, BlockState & Block, TemporaryDirection Direction)
+ if (Offset.z == -1)
+ {
+ Callback(West, North, East);
+ }
+ else if (Offset.z == 1)
{
- Block = DoWithDirectionState(Offset, Block, [Direction](auto, auto & Front, auto)
+ Callback(East, South, West);
+ }
+
+ return Block::RedstoneWire::RedstoneWire(East, North, 0, South, West);
+}
+
+/** Adjusts a given wire block so that the direction represented by Offset has state Direction. */
+static void SetDirectionState(const Vector3i Offset, BlockState & Block, TemporaryDirection Direction)
+{
+ Block = DoWithDirectionState(
+ Offset,
+ Block,
+ [Direction](auto, auto & Front, auto)
{
using FrontState = std::remove_reference_t<decltype(Front)>;
switch (Direction)
@@ -67,169 +70,184 @@ namespace RedstoneWireHandler
return;
}
}
- });
- }
+ }
+ );
+}
- static bool IsDirectlyConnectingMechanism(BLOCKTYPE a_Block, NIBBLETYPE a_BlockMeta, const Vector3i a_Offset)
+static bool IsDirectlyConnectingMechanism(BLOCKTYPE a_Block, NIBBLETYPE a_BlockMeta, const Vector3i a_Offset)
+{
+ switch (a_Block)
{
- switch (a_Block)
+ case E_BLOCK_REDSTONE_REPEATER_ON:
+ case E_BLOCK_REDSTONE_REPEATER_OFF:
{
- case E_BLOCK_REDSTONE_REPEATER_ON:
- case E_BLOCK_REDSTONE_REPEATER_OFF:
+ a_BlockMeta &= E_META_REDSTONE_REPEATER_FACING_MASK;
+ if ((a_BlockMeta == E_META_REDSTONE_REPEATER_FACING_XP) ||
+ (a_BlockMeta == E_META_REDSTONE_REPEATER_FACING_XM))
{
- a_BlockMeta &= E_META_REDSTONE_REPEATER_FACING_MASK;
- if ((a_BlockMeta == E_META_REDSTONE_REPEATER_FACING_XP) || (a_BlockMeta == E_META_REDSTONE_REPEATER_FACING_XM))
- {
- // Wire connects to repeater if repeater is aligned along X
- // and wire is in front or behind it (#4639)
- return a_Offset.x != 0;
- }
-
- return a_Offset.z != 0;
+ // Wire connects to repeater if repeater is aligned along X
+ // and wire is in front or behind it (#4639)
+ return a_Offset.x != 0;
}
- case E_BLOCK_ACTIVE_COMPARATOR:
- case E_BLOCK_BLOCK_OF_REDSTONE:
- case E_BLOCK_INACTIVE_COMPARATOR:
- case E_BLOCK_LEVER:
- case E_BLOCK_REDSTONE_TORCH_OFF:
- case E_BLOCK_REDSTONE_TORCH_ON:
- case E_BLOCK_REDSTONE_WIRE:
- case E_BLOCK_STONE_BUTTON:
- case E_BLOCK_WOODEN_BUTTON: return true;
- default: return false;
+
+ return a_Offset.z != 0;
}
+ case E_BLOCK_ACTIVE_COMPARATOR:
+ case E_BLOCK_BLOCK_OF_REDSTONE:
+ case E_BLOCK_INACTIVE_COMPARATOR:
+ case E_BLOCK_LEVER:
+ case E_BLOCK_REDSTONE_TORCH_OFF:
+ case E_BLOCK_REDSTONE_TORCH_ON:
+ case E_BLOCK_REDSTONE_WIRE:
+ case E_BLOCK_STONE_BUTTON:
+ case E_BLOCK_WOODEN_BUTTON: return true;
+ default: return false;
}
+}
- static bool IsYPTerracingBlocked(const cChunk & a_Chunk, const Vector3i a_Position)
+static bool IsYPTerracingBlocked(const cChunk & a_Chunk, const Vector3i a_Position)
+{
+ const auto Position = a_Position + OffsetYP;
+
+ if (!cChunkDef::IsValidHeight(Position))
{
- const auto Position = a_Position + OffsetYP;
+ // Certainly cannot terrace at the top of the world:
+ return true;
+ }
- 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);
+}
- 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 & a_Chunk, const Vector3i a_Position)
+{
+ auto Block = Block::RedstoneWire::RedstoneWire();
+ const bool IsYPTerracingBlocked = RedstoneWireHandler::IsYPTerracingBlocked(a_Chunk, a_Position);
- /** 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 & a_Chunk, const Vector3i a_Position)
+ // Loop through laterals, discovering terracing connections:
+ for (const auto & Offset : RelativeLaterals)
{
- auto Block = Block::RedstoneWire::RedstoneWire();
- const bool IsYPTerracingBlocked = RedstoneWireHandler::IsYPTerracingBlocked(a_Chunk, a_Position);
+ auto Adjacent = a_Position + Offset;
+ auto NeighbourChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(Adjacent);
- // Loop through laterals, discovering terracing connections:
- for (const auto & Offset : RelativeLaterals)
+ if ((NeighbourChunk == nullptr) || !NeighbourChunk->IsValid())
{
- auto Adjacent = a_Position + Offset;
- auto NeighbourChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(Adjacent);
+ continue;
+ }
- if ((NeighbourChunk == nullptr) || !NeighbourChunk->IsValid())
- {
- continue;
- }
+ BLOCKTYPE LateralBlock;
+ NIBBLETYPE LateralMeta;
+ NeighbourChunk->GetBlockTypeMeta(Adjacent, LateralBlock, LateralMeta);
- BLOCKTYPE LateralBlock;
- NIBBLETYPE LateralMeta;
- NeighbourChunk->GetBlockTypeMeta(Adjacent, LateralBlock, LateralMeta);
+ if (IsDirectlyConnectingMechanism(LateralBlock, LateralMeta, Offset))
+ {
+ // Any direct connections on a lateral means the wire has side connection in that direction:
+ SetDirectionState(Offset, Block, TemporaryDirection::Side);
- if (IsDirectlyConnectingMechanism(LateralBlock, LateralMeta, Offset))
+ // 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 != &a_Chunk) && (LateralBlock == E_BLOCK_REDSTONE_WIRE))
{
- // Any direct connections on a lateral means the wire has side connection in that direction:
- SetDirectionState(Offset, Block, TemporaryDirection::Side);
+ auto & NeighbourBlock = DataForChunk(*NeighbourChunk).WireStates.find(Adjacent)->second;
+ SetDirectionState(-Offset, NeighbourBlock, TemporaryDirection::Side);
+ }
- // 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 != &a_Chunk) && (LateralBlock == E_BLOCK_REDSTONE_WIRE))
- {
- auto & NeighbourBlock = DataForChunk(*NeighbourChunk).WireStates.find(Adjacent)->second;
- SetDirectionState(-Offset, NeighbourBlock, TemporaryDirection::Side);
- }
+ continue;
+ }
- continue;
- }
+ if (!IsYPTerracingBlocked && // A block above us blocks all YP terracing, so the check is static in the loop
+ (Adjacent.y < (cChunkDef::Height - 1)) &&
+ (NeighbourChunk->GetBlock(Adjacent + OffsetYP) == E_BLOCK_REDSTONE_WIRE
+ ) // Only terrace YP with another wire
+ )
+ {
+ SetDirectionState(
+ Offset,
+ Block,
+ cBlockInfo::IsTransparent(LateralBlock) ? TemporaryDirection::Side : TemporaryDirection::Up
+ );
- if (
- !IsYPTerracingBlocked && // A block above us blocks all YP terracing, so the check is static in the loop
- (Adjacent.y < (cChunkDef::Height - 1)) &&
- (NeighbourChunk->GetBlock(Adjacent + OffsetYP) == E_BLOCK_REDSTONE_WIRE) // Only terrace YP with another wire
- )
+ if (NeighbourChunk != &a_Chunk)
{
- SetDirectionState(Offset, Block, cBlockInfo::IsTransparent(LateralBlock) ? TemporaryDirection::Side : TemporaryDirection::Up);
+ auto & NeighbourBlock = DataForChunk(*NeighbourChunk).WireStates.find(Adjacent + OffsetYP)->second;
+ SetDirectionState(-Offset, NeighbourBlock, TemporaryDirection::Side);
+ }
- if (NeighbourChunk != &a_Chunk)
- {
- auto & NeighbourBlock = DataForChunk(*NeighbourChunk).WireStates.find(Adjacent + OffsetYP)->second;
- SetDirectionState(-Offset, NeighbourBlock, TemporaryDirection::Side);
- }
+ continue;
+ }
- continue;
- }
+ if (
+ // IsYMTerracingBlocked (i.e. check block above lower terracing position, a.k.a. just the plain adjacent)
+ (!cBlockInfo::IsSolid(LateralBlock) || cBlockInfo::IsTransparent(LateralBlock)) && (Adjacent.y > 0) &&
+ (NeighbourChunk->GetBlock(Adjacent + OffsetYM) == E_BLOCK_REDSTONE_WIRE
+ ) // Only terrace YM with another wire
+ )
+ {
+ SetDirectionState(Offset, Block, TemporaryDirection::Side);
- if (
- // IsYMTerracingBlocked (i.e. check block above lower terracing position, a.k.a. just the plain adjacent)
- (!cBlockInfo::IsSolid(LateralBlock) || cBlockInfo::IsTransparent(LateralBlock)) &&
- (Adjacent.y > 0) &&
- (NeighbourChunk->GetBlock(Adjacent + OffsetYM) == E_BLOCK_REDSTONE_WIRE) // Only terrace YM with another wire
- )
+ if (NeighbourChunk != &a_Chunk)
{
- SetDirectionState(Offset, Block, TemporaryDirection::Side);
-
- if (NeighbourChunk != &a_Chunk)
- {
- auto & NeighbourBlock = DataForChunk(*NeighbourChunk).WireStates.find(Adjacent + OffsetYM)->second;
- SetDirectionState(-Offset, NeighbourBlock, TemporaryDirection::Up);
- }
+ auto & NeighbourBlock = DataForChunk(*NeighbourChunk).WireStates.find(Adjacent + OffsetYM)->second;
+ SetDirectionState(-Offset, NeighbourBlock, TemporaryDirection::Up);
}
}
+ }
- auto & States = DataForChunk(a_Chunk).WireStates;
- const auto FindResult = States.find(a_Position);
- if (FindResult != States.end())
+ auto & States = DataForChunk(a_Chunk).WireStates;
+ const auto FindResult = States.find(a_Position);
+ if (FindResult != States.end())
+ {
+ if (Block != FindResult->second)
{
- if (Block != FindResult->second)
- {
- FindResult->second = Block;
+ FindResult->second = Block;
- // 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:
- a_Chunk.GetWorld()->WakeUpSimulators(cChunkDef::RelativeToAbsolute(a_Position, a_Chunk.GetPos()));
- }
-
- return;
+ // 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:
+ a_Chunk.GetWorld()->WakeUpSimulators(cChunkDef::RelativeToAbsolute(a_Position, a_Chunk.GetPos()));
}
- DataForChunk(a_Chunk).WireStates.emplace(a_Position, Block);
+ return;
}
- static PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
- {
- // Starts off as the wire's meta value, modified appropriately and returned
- auto Power = a_Chunk.GetMeta(a_Position);
- const auto QueryOffset = a_QueryPosition - a_Position;
+ 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
+)
+{
+ // Starts off as the wire's meta value, modified appropriately and returned
+ auto Power = a_Chunk.GetMeta(a_Position);
+ const auto QueryOffset = a_QueryPosition - a_Position;
- if (
- (QueryOffset == OffsetYP) || // Wires do not power things above them
- (IsLinked && (a_QueryBlockType == E_BLOCK_REDSTONE_WIRE)) // Nor do they link power other wires
- )
- {
- return 0;
- }
+ if ((QueryOffset == OffsetYP) || // Wires do not power things above them
+ (IsLinked && (a_QueryBlockType == E_BLOCK_REDSTONE_WIRE)) // Nor do they link power other wires
+ )
+ {
+ return 0;
+ }
- if (QueryOffset == OffsetYM)
- {
- // Wires always deliver power to the block underneath
- return Power;
- }
+ if (QueryOffset == OffsetYM)
+ {
+ // Wires always deliver power to the block underneath
+ return Power;
+ }
- const auto & Data = DataForChunk(a_Chunk);
- const auto Block = Data.WireStates.find(a_Position)->second;
+ const auto & Data = DataForChunk(a_Chunk);
+ const auto Block = Data.WireStates.find(a_Position)->second;
- DoWithDirectionState(QueryOffset, Block, [a_QueryBlockType, &Power](const auto Left, const auto Front, const auto Right)
+ DoWithDirectionState(
+ QueryOffset,
+ Block,
+ [a_QueryBlockType, &Power](const auto Left, const auto Front, const auto Right)
{
using LeftState = std::remove_reference_t<decltype(Left)>;
using FrontState = std::remove_reference_t<decltype(Front)>;
@@ -252,8 +270,8 @@ namespace RedstoneWireHandler
Okay, we do not directly connect to the wire.
1. If there are no DC mechanisms at all, the wire powers all laterals. Great, left and right are both None.
2. If there is one DC mechanism, the wire "goes straight" along the axis of the wire and mechanism.
- The only possible way for us to be powered is for us to be on the opposite end, with the wire pointing towards us.
- Check that left and right are both None.
+ The only possible way for us to be powered is for us to be on the opposite end, with the wire pointing
+ towards us. Check that left and right are both None.
3. If there is more than one DC, no non-DCs are powered. Left, right, cannot both be None.
*/
if ((Left == LeftState::None) && (Right == RightState::None))
@@ -265,45 +283,62 @@ namespace RedstoneWireHandler
// Case 3
Power = 0;
- });
-
- return Power;
- }
+ }
+ );
+
+ return Power;
+}
+
+static void Update(
+ cChunk & a_Chunk,
+ cChunk & CurrentlyTicking,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ const PowerLevel Power
+)
+{
+ // LOGD("Evaluating dusty the wire (%d %d %d) %i", a_Position.x, a_Position.y, a_Position.z, Power);
- static void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
+ if (a_Meta == Power)
{
- // LOGD("Evaluating dusty the wire (%d %d %d) %i", a_Position.x, a_Position.y, a_Position.z, Power);
-
- if (a_Meta == Power)
- {
- return;
- }
+ return;
+ }
- a_Chunk.SetMeta(a_Position, Power);
+ a_Chunk.SetMeta(a_Position, Power);
- // Notify all positions, sans YP, to update:
- UpdateAdjustedRelative(a_Chunk, CurrentlyTicking, a_Position, OffsetYM);
- UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position, RelativeLaterals);
- }
+ // Notify all positions, sans YP, to update:
+ 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)
- {
- UNUSED(a_BlockType);
- UNUSED(a_Meta);
+static void ForValidSourcePositions(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ ForEachSourceCallback & Callback
+)
+{
+ UNUSED(a_BlockType);
+ UNUSED(a_Meta);
- Callback(a_Position + OffsetYP);
- Callback(a_Position + OffsetYM);
+ Callback(a_Position + OffsetYP);
+ Callback(a_Position + OffsetYM);
- const auto & Data = DataForChunk(a_Chunk);
- const auto Block = Data.WireStates.find(a_Position)->second;
+ const auto & Data = DataForChunk(a_Chunk);
+ const auto Block = Data.WireStates.find(a_Position)->second;
- // Figure out, based on our pre-computed block, where we connect to:
- for (const auto & Offset : RelativeLaterals)
- {
- const auto Relative = a_Position + Offset;
- Callback(Relative);
+ // Figure out, based on our pre-computed block, where we connect to:
+ for (const auto & Offset : RelativeLaterals)
+ {
+ const auto Relative = a_Position + Offset;
+ Callback(Relative);
- DoWithDirectionState(Offset, Block, [&a_Chunk, &Callback, Relative](auto, const auto Front, auto)
+ DoWithDirectionState(
+ Offset,
+ Block,
+ [&a_Chunk, &Callback, Relative](auto, const auto Front, auto)
{
using FrontState = std::remove_reference_t<decltype(Front)>;
@@ -317,17 +352,15 @@ namespace RedstoneWireHandler
// Have to do a manual check to only accept power from YM diagonal if there's a wire there
const auto YMDiagonalPosition = Relative + OffsetYM;
- if (
- BLOCKTYPE QueryBlock;
- cChunkDef::IsValidHeight(YMDiagonalPosition) &&
+ if (BLOCKTYPE QueryBlock; cChunkDef::IsValidHeight(YMDiagonalPosition) &&
a_Chunk.UnboundedRelGetBlockType(YMDiagonalPosition, QueryBlock) &&
- (QueryBlock == E_BLOCK_REDSTONE_WIRE)
- )
+ (QueryBlock == E_BLOCK_REDSTONE_WIRE))
{
Callback(YMDiagonalPosition);
}
}
- });
- }
+ }
+ );
}
-};
+}
+}; // namespace RedstoneWireHandler
diff --git a/src/Simulator/IncrementalRedstoneSimulator/SmallGateHandler.h b/src/Simulator/IncrementalRedstoneSimulator/SmallGateHandler.h
index aed9d98ee..55eb7917c 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/SmallGateHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/SmallGateHandler.h
@@ -7,37 +7,57 @@
namespace SmallGateHandler
{
- static PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
- {
- UNUSED(a_Chunk);
- UNUSED(a_Position);
- UNUSED(a_BlockType);
- UNUSED(a_QueryPosition);
- UNUSED(a_QueryBlockType);
- UNUSED(IsLinked);
- return 0;
- }
-
- static void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
- {
- // LOGD("Evaluating gateydory the fence gate/trapdoor (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
-
- // Use redstone data rather than block state so players can override redstone control
- const auto Previous = DataForChunk(a_Chunk).ExchangeUpdateOncePowerData(a_Position, Power);
- const bool IsOpen = (Previous != 0);
- const bool ShouldBeOpen = Power != 0;
+static PowerLevel GetPowerDeliveredToPosition(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ Vector3i a_QueryPosition,
+ BLOCKTYPE a_QueryBlockType,
+ bool IsLinked
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_Position);
+ UNUSED(a_BlockType);
+ UNUSED(a_QueryPosition);
+ UNUSED(a_QueryBlockType);
+ UNUSED(IsLinked);
+ return 0;
+}
+
+static void Update(
+ cChunk & a_Chunk,
+ cChunk &,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ const PowerLevel Power
+)
+{
+ // LOGD("Evaluating gateydory the fence gate/trapdoor (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- if (ShouldBeOpen != IsOpen)
- {
- a_Chunk.SetMeta(a_Position, ShouldBeOpen ? (a_Meta | 0x4) : (a_Meta & ~0x04));
- }
- }
+ // Use redstone data rather than block state so players can override redstone control
+ const auto Previous = DataForChunk(a_Chunk).ExchangeUpdateOncePowerData(a_Position, Power);
+ const bool IsOpen = (Previous != 0);
+ const bool ShouldBeOpen = Power != 0;
- static void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback)
+ if (ShouldBeOpen != IsOpen)
{
- UNUSED(a_Chunk);
- UNUSED(a_BlockType);
- UNUSED(a_Meta);
- InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
+ a_Chunk.SetMeta(a_Position, ShouldBeOpen ? (a_Meta | 0x4) : (a_Meta & ~0x04));
}
-};
+}
+
+static void ForValidSourcePositions(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ ForEachSourceCallback & Callback
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_BlockType);
+ UNUSED(a_Meta);
+ InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
+}
+}; // namespace SmallGateHandler
diff --git a/src/Simulator/IncrementalRedstoneSimulator/TNTHandler.h b/src/Simulator/IncrementalRedstoneSimulator/TNTHandler.h
index cae538418..7b9a32972 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/TNTHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/TNTHandler.h
@@ -7,32 +7,54 @@
namespace TNTHandler
{
- static PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
- {
- UNUSED(a_Chunk);
- UNUSED(a_Position);
- UNUSED(a_BlockType);
- UNUSED(a_QueryPosition);
- UNUSED(a_QueryBlockType);
- UNUSED(IsLinked);
- return 0;
- }
-
- static void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
- {
- // LOGD("Evaluating explodinator the trinitrotoluene (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- if (Power != 0)
- {
- a_Chunk.SetBlock(a_Position, E_BLOCK_AIR, 0);
- a_Chunk.GetWorld()->SpawnPrimedTNT(Vector3d(0.5, 0.5, 0.5) + cChunkDef::RelativeToAbsolute(a_Position, a_Chunk.GetPos())); // 80 ticks to boom
- }
- }
-
- static void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback)
+static PowerLevel GetPowerDeliveredToPosition(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ Vector3i a_QueryPosition,
+ BLOCKTYPE a_QueryBlockType,
+ bool IsLinked
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_Position);
+ UNUSED(a_BlockType);
+ UNUSED(a_QueryPosition);
+ UNUSED(a_QueryBlockType);
+ UNUSED(IsLinked);
+ return 0;
+}
+
+static void Update(
+ cChunk & a_Chunk,
+ cChunk &,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ const PowerLevel Power
+)
+{
+ // LOGD("Evaluating explodinator the trinitrotoluene (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
+ if (Power != 0)
{
- UNUSED(a_Chunk);
- UNUSED(a_BlockType);
- UNUSED(a_Meta);
- InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
+ a_Chunk.SetBlock(a_Position, E_BLOCK_AIR, 0);
+ a_Chunk.GetWorld()->SpawnPrimedTNT(
+ Vector3d(0.5, 0.5, 0.5) + cChunkDef::RelativeToAbsolute(a_Position, a_Chunk.GetPos())
+ ); // 80 ticks to boom
}
-};
+}
+
+static void ForValidSourcePositions(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ ForEachSourceCallback & Callback
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_BlockType);
+ UNUSED(a_Meta);
+ InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
+}
+}; // namespace TNTHandler
diff --git a/src/Simulator/IncrementalRedstoneSimulator/TrappedChestHandler.h b/src/Simulator/IncrementalRedstoneSimulator/TrappedChestHandler.h
index d68e48997..9b604f8ef 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/TrappedChestHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/TrappedChestHandler.h
@@ -9,49 +9,72 @@
namespace TrappedChestHandler
{
- static PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
- {
- UNUSED(a_BlockType);
- UNUSED(a_QueryPosition);
- UNUSED(a_QueryBlockType);
- UNUSED(IsLinked);
+static PowerLevel GetPowerDeliveredToPosition(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ Vector3i a_QueryPosition,
+ BLOCKTYPE a_QueryBlockType,
+ bool IsLinked
+)
+{
+ UNUSED(a_BlockType);
+ UNUSED(a_QueryPosition);
+ UNUSED(a_QueryBlockType);
+ UNUSED(IsLinked);
- return DataForChunk(a_Chunk).GetCachedPowerData(a_Position);
- }
+ return DataForChunk(a_Chunk).GetCachedPowerData(a_Position);
+}
- static unsigned char GetPowerLevel(cChunk & a_Chunk, Vector3i a_Position)
- {
- int NumberOfPlayers = 0;
- a_Chunk.DoWithBlockEntityAt(a_Position, [&NumberOfPlayers](cBlockEntity & a_BlockEntity)
+static unsigned char GetPowerLevel(cChunk & a_Chunk, Vector3i a_Position)
+{
+ int NumberOfPlayers = 0;
+ a_Chunk.DoWithBlockEntityAt(
+ a_Position,
+ [&NumberOfPlayers](cBlockEntity & a_BlockEntity)
{
ASSERT(a_BlockEntity.GetBlockType() == E_BLOCK_TRAPPED_CHEST);
NumberOfPlayers = static_cast<cChestEntity &>(a_BlockEntity).GetNumberOfPlayers();
return false;
- });
+ }
+ );
- return static_cast<unsigned char>(std::min(NumberOfPlayers, 15));
- }
+ return static_cast<unsigned char>(std::min(NumberOfPlayers, 15));
+}
- static void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
- {
- // LOGD("Evaluating tricky the trapped chest (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
+static void Update(
+ cChunk & a_Chunk,
+ cChunk & CurrentlyTicking,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ const PowerLevel Power
+)
+{
+ // LOGD("Evaluating tricky the trapped chest (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- const auto PowerLevel = GetPowerLevel(a_Chunk, a_Position);
- const auto PreviousPower = DataForChunk(a_Chunk).ExchangeUpdateOncePowerData(a_Position, PowerLevel);
+ const auto PowerLevel = GetPowerLevel(a_Chunk, a_Position);
+ const auto PreviousPower = DataForChunk(a_Chunk).ExchangeUpdateOncePowerData(a_Position, PowerLevel);
- if (PowerLevel != PreviousPower)
- {
- UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position, RelativeAdjacents);
- }
- }
-
- static void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback)
+ if (PowerLevel != PreviousPower)
{
- UNUSED(a_Chunk);
- UNUSED(a_Position);
- UNUSED(a_BlockType);
- UNUSED(a_Meta);
- UNUSED(Callback);
+ UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position, RelativeAdjacents);
}
-};
+}
+
+static void ForValidSourcePositions(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ ForEachSourceCallback & Callback
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_Position);
+ UNUSED(a_BlockType);
+ UNUSED(a_Meta);
+ UNUSED(Callback);
+}
+}; // namespace TrappedChestHandler
diff --git a/src/Simulator/IncrementalRedstoneSimulator/TripwireHookHandler.h b/src/Simulator/IncrementalRedstoneSimulator/TripwireHookHandler.h
index 578831db5..9fcadb0b3 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/TripwireHookHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/TripwireHookHandler.h
@@ -9,104 +9,126 @@
namespace TripwireHookHandler
{
- static unsigned char GetPowerLevel(const cChunk & a_Chunk, Vector3i a_Position, NIBBLETYPE a_Meta)
+static unsigned char GetPowerLevel(const cChunk & a_Chunk, Vector3i a_Position, NIBBLETYPE a_Meta)
+{
+ bool FoundActivated = false;
+ const auto FaceToGoTowards = cBlockTripwireHookHandler::MetadataToDirection(a_Meta);
+
+ for (int i = 0; i < 40; ++i) // Tripwires can be connected up to 40 blocks
{
- bool FoundActivated = false;
- const auto FaceToGoTowards = cBlockTripwireHookHandler::MetadataToDirection(a_Meta);
+ BLOCKTYPE Type;
+ NIBBLETYPE Meta;
- for (int i = 0; i < 40; ++i) // Tripwires can be connected up to 40 blocks
+ a_Position = AddFaceDirection(a_Position, FaceToGoTowards);
+ if (!a_Chunk.UnboundedRelGetBlock(a_Position, Type, Meta))
{
- BLOCKTYPE Type;
- NIBBLETYPE Meta;
+ return 0;
+ }
- a_Position = AddFaceDirection(a_Position, FaceToGoTowards);
- if (!a_Chunk.UnboundedRelGetBlock(a_Position, Type, Meta))
+ if (Type == E_BLOCK_TRIPWIRE)
+ {
+ if (FoundActivated)
{
- return 0;
+ continue;
}
- if (Type == E_BLOCK_TRIPWIRE)
+ if (!a_Chunk.ForEachEntityInBox(
+ cBoundingBox(
+ Vector3d(0.5, 0, 0.5) + cChunkDef::RelativeToAbsolute(a_Position, a_Chunk.GetPos()),
+ 0.5,
+ 0.5
+ ),
+ [](cEntity &) { return true; }
+ ))
{
- if (FoundActivated)
- {
- continue;
- }
-
- if (
- !a_Chunk.ForEachEntityInBox(
- cBoundingBox(Vector3d(0.5, 0, 0.5) + cChunkDef::RelativeToAbsolute(a_Position, a_Chunk.GetPos()), 0.5, 0.5),
- [](cEntity &) { return true; }
- )
- )
- {
- FoundActivated = true;
- }
-
- continue;
+ FoundActivated = true;
}
- else if (Type == E_BLOCK_TRIPWIRE_HOOK)
+
+ continue;
+ }
+ else if (Type == E_BLOCK_TRIPWIRE_HOOK)
+ {
+ if (ReverseBlockFace(cBlockTripwireHookHandler::MetadataToDirection(Meta)) == FaceToGoTowards)
{
- if (ReverseBlockFace(cBlockTripwireHookHandler::MetadataToDirection(Meta)) == FaceToGoTowards)
- {
- // Other hook facing in opposite direction - circuit completed!
- return FoundActivated ? 15 : 1;
- }
+ // Other hook facing in opposite direction - circuit completed!
+ return FoundActivated ? 15 : 1;
}
-
- // Tripwire hook not connected at all
- return 0;
}
+ // Tripwire hook not connected at all
return 0;
}
- static PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
- {
- UNUSED(a_BlockType);
- UNUSED(a_QueryBlockType);
- UNUSED(a_QueryPosition);
+ return 0;
+}
+
+static PowerLevel GetPowerDeliveredToPosition(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ Vector3i a_QueryPosition,
+ BLOCKTYPE a_QueryBlockType,
+ bool IsLinked
+)
+{
+ UNUSED(a_BlockType);
+ UNUSED(a_QueryBlockType);
+ UNUSED(a_QueryPosition);
+
+ return (GetPowerLevel(a_Chunk, a_Position, a_Chunk.GetMeta(a_Position)) == 15) ? 15 : 0;
+}
+
+static void Update(
+ cChunk & a_Chunk,
+ cChunk & CurrentlyTicking,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ const PowerLevel Power
+)
+{
+ // LOGD("Evaluating hooky the tripwire hook (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
- return (GetPowerLevel(a_Chunk, a_Position, a_Chunk.GetMeta(a_Position)) == 15) ? 15 : 0;
+ const auto PowerLevel = GetPowerLevel(a_Chunk, a_Position, a_Meta);
+ NIBBLETYPE Meta;
+ if (PowerLevel == 0)
+ {
+ Meta = (a_Meta & 0x3);
}
-
- static void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
+ else if (PowerLevel == 1)
{
- // LOGD("Evaluating hooky the tripwire hook (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
-
- const auto PowerLevel = GetPowerLevel(a_Chunk, a_Position, a_Meta);
- NIBBLETYPE Meta;
- if (PowerLevel == 0)
- {
- Meta = (a_Meta & 0x3);
- }
- else if (PowerLevel == 1)
- {
- // Connected but not activated, AND away the highest bit
- Meta = (a_Meta & 0x7) | 0x4;
- }
- else if (PowerLevel == 15)
- {
- // Connected and activated, set the 3rd and 4th highest bits
- Meta = (a_Meta | 0xC);
- }
- else
- {
- UNREACHABLE("Unexpected tripwire hook power level!");
- }
-
- if (Meta != a_Meta)
- {
- a_Chunk.SetMeta(a_Position, Meta);
- UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position, RelativeAdjacents);
- }
+ // Connected but not activated, AND away the highest bit
+ Meta = (a_Meta & 0x7) | 0x4;
+ }
+ else if (PowerLevel == 15)
+ {
+ // Connected and activated, set the 3rd and 4th highest bits
+ Meta = (a_Meta | 0xC);
+ }
+ else
+ {
+ UNREACHABLE("Unexpected tripwire hook power level!");
}
- static void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback)
+ if (Meta != a_Meta)
{
- UNUSED(a_Chunk);
- UNUSED(a_BlockType);
- UNUSED(a_Meta);
- UNUSED(a_Position);
- UNUSED(Callback);
+ a_Chunk.SetMeta(a_Position, Meta);
+ UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position, RelativeAdjacents);
}
-};
+}
+
+static void ForValidSourcePositions(
+ const cChunk & a_Chunk,
+ Vector3i a_Position,
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_Meta,
+ ForEachSourceCallback & Callback
+)
+{
+ UNUSED(a_Chunk);
+ UNUSED(a_BlockType);
+ UNUSED(a_Meta);
+ UNUSED(a_Position);
+ UNUSED(Callback);
+}
+}; // namespace TripwireHookHandler
diff --git a/src/Simulator/NoopFluidSimulator.h b/src/Simulator/NoopFluidSimulator.h
index 93d5cb50a..d42f014df 100644
--- a/src/Simulator/NoopFluidSimulator.h
+++ b/src/Simulator/NoopFluidSimulator.h
@@ -15,17 +15,14 @@
-class cNoopFluidSimulator final :
- public cFluidSimulator
+class cNoopFluidSimulator final : public cFluidSimulator
{
using Super = cFluidSimulator;
-public:
-
+ public:
using Super::Super;
-private:
-
+ private:
virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override
{
UNUSED(a_Dt);
@@ -41,4 +38,4 @@ private:
}
virtual cFluidSimulatorData * CreateChunkData(void) override { return nullptr; }
-} ;
+};
diff --git a/src/Simulator/NoopRedstoneSimulator.h b/src/Simulator/NoopRedstoneSimulator.h
index a361b5b12..e40959840 100644
--- a/src/Simulator/NoopRedstoneSimulator.h
+++ b/src/Simulator/NoopRedstoneSimulator.h
@@ -7,14 +7,12 @@
-class cRedstoneNoopSimulator final :
- public cRedstoneSimulator
+class cRedstoneNoopSimulator final : public cRedstoneSimulator
{
using Super = cRedstoneSimulator;
-public:
-
- cRedstoneNoopSimulator(cWorld & a_World):
+ public:
+ cRedstoneNoopSimulator(cWorld & a_World) :
Super(a_World)
{
}
@@ -33,8 +31,5 @@ public:
UNUSED(a_Chunk);
}
- virtual cRedstoneSimulatorChunkData * CreateChunkData() override
- {
- return nullptr;
- }
-} ;
+ virtual cRedstoneSimulatorChunkData * CreateChunkData() override { return nullptr; }
+};
diff --git a/src/Simulator/RedstoneSimulator.h b/src/Simulator/RedstoneSimulator.h
index 86b5b84b3..3443f37be 100644
--- a/src/Simulator/RedstoneSimulator.h
+++ b/src/Simulator/RedstoneSimulator.h
@@ -9,24 +9,19 @@
class cRedstoneSimulatorChunkData
{
-public:
-
- virtual ~cRedstoneSimulatorChunkData()
- {
- }
+ public:
+ virtual ~cRedstoneSimulatorChunkData() {}
};
-class cRedstoneSimulator:
- public cSimulator
+class cRedstoneSimulator : public cSimulator
{
using Super = cSimulator;
-public:
-
+ public:
using Super::Super;
virtual cRedstoneSimulatorChunkData * CreateChunkData() = 0;
diff --git a/src/Simulator/SandSimulator.cpp b/src/Simulator/SandSimulator.cpp
index 13bc6bb36..218699b75 100644
--- a/src/Simulator/SandSimulator.cpp
+++ b/src/Simulator/SandSimulator.cpp
@@ -15,8 +15,7 @@
cSandSimulator::cSandSimulator(cWorld & a_World, cIniFile & a_IniFile) :
- cSimulator(a_World),
- m_TotalBlocks(0)
+ cSimulator(a_World), m_TotalBlocks(0)
{
m_IsInstantFall = a_IniFile.GetValueSetB("Physics", "SandInstantFall", false);
}
@@ -43,7 +42,8 @@ void cSandSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX,
continue;
}
- BLOCKTYPE BlockBelow = (itr->y > 0) ? a_Chunk->GetBlock(itr->x, itr->y - 1, itr->z) : static_cast<BLOCKTYPE>(E_BLOCK_AIR);
+ BLOCKTYPE BlockBelow =
+ (itr->y > 0) ? a_Chunk->GetBlock(itr->x, itr->y - 1, itr->z) : static_cast<BLOCKTYPE>(E_BLOCK_AIR);
if (CanStartFallingThrough(BlockBelow))
{
if (m_IsInstantFall)
@@ -230,17 +230,21 @@ bool cSandSimulator::DoesBreakFallingThrough(BLOCKTYPE a_BlockType, NIBBLETYPE a
void cSandSimulator::FinishFalling(
- cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ,
- BLOCKTYPE a_FallingBlockType, NIBBLETYPE a_FallingBlockMeta
+ cWorld * a_World,
+ int a_BlockX,
+ int a_BlockY,
+ int a_BlockZ,
+ BLOCKTYPE a_FallingBlockType,
+ NIBBLETYPE a_FallingBlockMeta
)
{
ASSERT(a_BlockY < cChunkDef::Height);
- BLOCKTYPE CurrentBlockType = a_World->GetBlock({ a_BlockX, a_BlockY, a_BlockZ });
+ BLOCKTYPE CurrentBlockType = a_World->GetBlock({a_BlockX, a_BlockY, a_BlockZ});
if ((a_FallingBlockType == E_BLOCK_ANVIL) || IsReplacedOnRematerialization(CurrentBlockType))
{
// Rematerialize the material here:
- a_World->SetBlock({ a_BlockX, a_BlockY, a_BlockZ }, a_FallingBlockType, a_FallingBlockMeta);
+ a_World->SetBlock({a_BlockX, a_BlockY, a_BlockZ}, a_FallingBlockType, a_FallingBlockMeta);
if (a_FallingBlockType == E_BLOCK_ANVIL)
{
a_World->BroadcastSoundParticleEffect(EffectID::SFX_RANDOM_ANVIL_LAND, {a_BlockX, a_BlockY, a_BlockZ}, 0);
@@ -289,7 +293,7 @@ bool cSandSimulator::IsAllowedBlock(BLOCKTYPE a_BlockType)
void cSandSimulator::DoInstantFall(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ)
{
// Remove the original block:
- BLOCKTYPE FallingBlockType;
+ BLOCKTYPE FallingBlockType;
NIBBLETYPE FallingBlockMeta;
a_Chunk->GetBlockTypeMeta(a_RelX, a_RelY, a_RelZ, FallingBlockType, FallingBlockMeta);
a_Chunk->SetBlock({a_RelX, a_RelY, a_RelZ}, E_BLOCK_AIR, 0);
@@ -329,7 +333,3 @@ void cSandSimulator::DoInstantFall(cChunk * a_Chunk, int a_RelX, int a_RelY, int
// The block just "fell off the world" without leaving a trace
}
-
-
-
-
diff --git a/src/Simulator/SandSimulator.h b/src/Simulator/SandSimulator.h
index d27fd5873..62c650b1d 100644
--- a/src/Simulator/SandSimulator.h
+++ b/src/Simulator/SandSimulator.h
@@ -23,11 +23,9 @@ typedef cCoordWithIntList cSandSimulatorChunkData;
/** Despite the class name, this simulator takes care of all blocks that fall when suspended in the air. */
-class cSandSimulator :
- public cSimulator
+class cSandSimulator : public cSimulator
{
-public:
-
+ public:
cSandSimulator(cWorld & a_World, cIniFile & a_IniFile);
/** Returns true if a falling-able block can start falling through the specified block type */
@@ -47,19 +45,22 @@ public:
It either rematerializes the block (a_FallingBlockType) at the specified coords, or creates a pickup,
based on the block currently present in the world at the dest specified coords. */
static void FinishFalling(
- cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ,
- BLOCKTYPE a_FallingBlockType, NIBBLETYPE a_FallingBlockMeta
+ cWorld * a_World,
+ int a_BlockX,
+ int a_BlockY,
+ int a_BlockZ,
+ BLOCKTYPE a_FallingBlockType,
+ NIBBLETYPE a_FallingBlockMeta
);
static bool IsAllowedBlock(BLOCKTYPE a_BlockType);
-private:
-
+ private:
virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override;
bool m_IsInstantFall; // If set to true, blocks don't fall using cFallingBlock entity, but instantly instead
- int m_TotalBlocks; // Total number of blocks currently in the queue for simulating
+ int m_TotalBlocks; // Total number of blocks currently in the queue for simulating
virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override;
diff --git a/src/Simulator/Simulator.cpp b/src/Simulator/Simulator.cpp
index 7bf553912..40a709b76 100644
--- a/src/Simulator/Simulator.cpp
+++ b/src/Simulator/Simulator.cpp
@@ -13,80 +13,26 @@ std::array<Vector3i, 5> cSimulator::GetLinkedOffsets(const Vector3i Offset)
{
if (Offset.x == -1)
{
- return
- {
- {
- { -2, 0, 0 },
- { -1, -1, 0 },
- { -1, 1, 0 },
- { -1, 0, -1 },
- { -1, 0, 1 }
- }
- };
+ return {{{-2, 0, 0}, {-1, -1, 0}, {-1, 1, 0}, {-1, 0, -1}, {-1, 0, 1}}};
}
else if (Offset.x == 1)
{
- return
- {
- {
- { 2, 0, 0 },
- { 1, -1, 0 },
- { 1, 1, 0 },
- { 1, 0, -1 },
- { 1, 0, 1 }
- }
- };
+ return {{{2, 0, 0}, {1, -1, 0}, {1, 1, 0}, {1, 0, -1}, {1, 0, 1}}};
}
else if (Offset.y == -1)
{
- return
- {
- {
- { 0, -2, 0 },
- { -1, -1, 0 },
- { 1, -1, 0 },
- { 0, -1, -1 },
- { 0, -1, 1 }
- }
- };
+ return {{{0, -2, 0}, {-1, -1, 0}, {1, -1, 0}, {0, -1, -1}, {0, -1, 1}}};
}
else if (Offset.y == 1)
{
- return
- {
- {
- { 0, 2, 0 },
- { -1, 1, 0 },
- { 1, 1, 0 },
- { 0, 1, -1 },
- { 0, 1, 1 }
- }
- };
+ return {{{0, 2, 0}, {-1, 1, 0}, {1, 1, 0}, {0, 1, -1}, {0, 1, 1}}};
}
else if (Offset.z == -1)
{
- return
- {
- {
- { 0, 0, -2 },
- { -1, 0, -1 },
- { 1, 0, -1 },
- { 0, -1, -1 },
- { 0, 1, -1 }
- }
- };
+ return {{{0, 0, -2}, {-1, 0, -1}, {1, 0, -1}, {0, -1, -1}, {0, 1, -1}}};
}
- return
- {
- {
- { 0, 0, 2 },
- { -1, 0, 1 },
- { 1, 0, 1 },
- { 0, -1, 1 },
- { 0, 1, 1 }
- }
- };
+ return {{{0, 0, 2}, {-1, 0, 1}, {1, 0, 1}, {0, -1, 1}, {0, 1, 1}}};
}
diff --git a/src/Simulator/Simulator.h b/src/Simulator/Simulator.h
index 5bb8376b0..4a5017332 100644
--- a/src/Simulator/Simulator.h
+++ b/src/Simulator/Simulator.h
@@ -20,33 +20,29 @@ The functions are invoked to add all affected blocks and their direct neighbors
The simulator may update its internal state based on this call. */
class cSimulator
{
-public:
-
- cSimulator(cWorld & a_World)
- : m_World(a_World)
+ public:
+ cSimulator(cWorld & a_World) :
+ m_World(a_World)
{
}
virtual ~cSimulator() {}
/** Contains offsets for direct adjacents of any position. */
- static constexpr std::array<Vector3i, 6> AdjacentOffsets
- {
- {
- { 1, 0, 0 },
- { -1, 0, 0 },
- { 0, 1, 0 },
- { 0, -1, 0 },
- { 0, 0, 1 },
- { 0, 0, -1 },
- }
- };
-
- /** For a given offset from a position, return the offsets that represent the adjacents of the newly offset position, excluding the old position. */
+ static constexpr std::array<Vector3i, 6> AdjacentOffsets {{
+ {1, 0, 0},
+ {-1, 0, 0},
+ {0, 1, 0},
+ {0, -1, 0},
+ {0, 0, 1},
+ {0, 0, -1},
+ }};
+
+ /** For a given offset from a position, return the offsets that represent the adjacents of the newly offset
+ * position, excluding the old position. */
static std::array<Vector3i, 5> GetLinkedOffsets(Vector3i Offset);
-protected:
-
+ protected:
friend class cChunk; // Calls AddBlock() in its WakeUpSimulators() function, to speed things up
friend class cSimulatorManager; // Class reponsible for dispatching calls to the various slave Simulators
@@ -65,8 +61,9 @@ protected:
/** Called to simulate a single block, synthesised by the simulator manager.
The position represents the adjacents of the block that was actually changed, with the offset used given.
Simulators may use this information to update additional blocks that were affected by the change, or queue
- farther, extra-adjacents blocks to be updated. The simulator manager calls this overload after the 3-argument WakeUp. */
+ farther, extra-adjacents blocks to be updated. The simulator manager calls this overload after the 3-argument
+ WakeUp. */
virtual void WakeUp(cChunk & a_Chunk, Vector3i a_Position, Vector3i a_Offset, BLOCKTYPE a_Block);
cWorld & m_World;
-} ;
+};
diff --git a/src/Simulator/SimulatorManager.cpp b/src/Simulator/SimulatorManager.cpp
index 7e5b9d036..06254a1f2 100644
--- a/src/Simulator/SimulatorManager.cpp
+++ b/src/Simulator/SimulatorManager.cpp
@@ -11,8 +11,7 @@
cSimulatorManager::cSimulatorManager(cWorld & a_World) :
- m_World(a_World),
- m_Ticks(0)
+ m_World(a_World), m_Ticks(0)
{
}
@@ -20,9 +19,7 @@ cSimulatorManager::cSimulatorManager(cWorld & a_World) :
-cSimulatorManager::~cSimulatorManager()
-{
-}
+cSimulatorManager::~cSimulatorManager() {}
@@ -117,31 +114,35 @@ void cSimulatorManager::WakeUp(const cCuboid & a_Area)
{
for (int cx = ChunkStart.m_ChunkX; cx <= ChunkEnd.m_ChunkX; ++cx)
{
- m_World.DoWithChunk(cx, cz, [this, &area](cChunk & a_CBChunk)
- {
- int startX = std::max(area.p1.x, a_CBChunk.GetPosX() * cChunkDef::Width);
- int startZ = std::max(area.p1.z, a_CBChunk.GetPosZ() * cChunkDef::Width);
- int endX = std::min(area.p2.x, a_CBChunk.GetPosX() * cChunkDef::Width + cChunkDef::Width - 1);
- int endZ = std::min(area.p2.z, a_CBChunk.GetPosZ() * cChunkDef::Width + cChunkDef::Width - 1);
-
- for (const auto & Item : m_Simulators)
+ m_World.DoWithChunk(
+ cx,
+ cz,
+ [this, &area](cChunk & a_CBChunk)
{
- const auto Simulator = Item.first;
+ int startX = std::max(area.p1.x, a_CBChunk.GetPosX() * cChunkDef::Width);
+ int startZ = std::max(area.p1.z, a_CBChunk.GetPosZ() * cChunkDef::Width);
+ int endX = std::min(area.p2.x, a_CBChunk.GetPosX() * cChunkDef::Width + cChunkDef::Width - 1);
+ int endZ = std::min(area.p2.z, a_CBChunk.GetPosZ() * cChunkDef::Width + cChunkDef::Width - 1);
- for (int y = area.p1.y; y <= area.p2.y; ++y)
+ for (const auto & Item : m_Simulators)
{
- for (int z = startZ; z <= endZ; ++z)
+ const auto Simulator = Item.first;
+
+ for (int y = area.p1.y; y <= area.p2.y; ++y)
{
- for (int x = startX; x <= endX; ++x)
+ for (int z = startZ; z <= endZ; ++z)
{
- const auto Position = cChunkDef::AbsoluteToRelative({ x, y, z });
- Simulator->WakeUp(a_CBChunk, Position, a_CBChunk.GetBlock(Position));
- } // for x
- } // for z
- } // for y
+ for (int x = startX; x <= endX; ++x)
+ {
+ const auto Position = cChunkDef::AbsoluteToRelative({x, y, z});
+ Simulator->WakeUp(a_CBChunk, Position, a_CBChunk.GetBlock(Position));
+ } // for x
+ } // for z
+ } // for y
+ }
+ return true;
}
- return true;
- });
+ );
} // for cx
} // for cz
}
diff --git a/src/Simulator/SimulatorManager.h b/src/Simulator/SimulatorManager.h
index 4594bd7d6..25d980942 100644
--- a/src/Simulator/SimulatorManager.h
+++ b/src/Simulator/SimulatorManager.h
@@ -27,15 +27,15 @@ class cWorld;
class cSimulatorManager
{
-public:
-
+ public:
cSimulatorManager(cWorld & a_World);
~cSimulatorManager();
/** Called in each tick, a_Dt is the time passed since the last tick, in msec. */
void Simulate(float a_Dt);
- /** Called in each tick for each chunk, a_Dt is the time passed since the last tick, in msec; direct access to chunk data available. */
+ /** Called in each tick for each chunk, a_Dt is the time passed since the last tick, in msec; direct access to chunk
+ * data available. */
void SimulateChunk(std::chrono::milliseconds a_DT, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk);
/* Called when a single block changes, wakes all simulators up for the block and its face-neighbors.
@@ -45,20 +45,16 @@ public:
/** Does the same processing as WakeUp, but for all blocks within the specified area.
Has better performance than calling WakeUp for each block individually, due to neighbor-checking.
All chunks intersected by the area should be valid (outputs a warning if not).
- Note that, unlike WakeUp(), this call adds blocks not only face-neighboring, but also edge-neighboring and corner-neighboring the specified area. */
+ Note that, unlike WakeUp(), this call adds blocks not only face-neighboring, but also edge-neighboring and
+ corner-neighboring the specified area. */
void WakeUp(const cCuboid & a_Area);
void RegisterSimulator(cSimulator * a_Simulator, int a_Rate); // Takes ownership of the simulator object!
-protected:
-
- typedef std::vector <std::pair<cSimulator *, int> > cSimulators;
+ protected:
+ typedef std::vector<std::pair<cSimulator *, int>> cSimulators;
cWorld & m_World;
cSimulators m_Simulators;
- long long m_Ticks;
+ long long m_Ticks;
};
-
-
-
-
diff --git a/src/Simulator/VanillaFluidSimulator.cpp b/src/Simulator/VanillaFluidSimulator.cpp
index b1c690785..9e0245533 100644
--- a/src/Simulator/VanillaFluidSimulator.cpp
+++ b/src/Simulator/VanillaFluidSimulator.cpp
@@ -28,7 +28,7 @@ cVanillaFluidSimulator::cVanillaFluidSimulator(
NIBBLETYPE a_Falloff,
int a_TickDelay,
int a_NumNeighborsForSource
-):
+) :
Super(a_World, a_Fluid, a_StationaryFluid, a_Falloff, a_TickDelay, a_NumNeighborsForSource)
{
}
@@ -41,10 +41,10 @@ void cVanillaFluidSimulator::SpreadXZ(cChunk * a_Chunk, int a_RelX, int a_RelY,
{
// Calculate the distance to the nearest "hole" in each direction:
int Cost[4];
- Cost[0] = CalculateFlowCost(a_Chunk, a_RelX + 1, a_RelY, a_RelZ, X_PLUS);
- Cost[1] = CalculateFlowCost(a_Chunk, a_RelX - 1, a_RelY, a_RelZ, X_MINUS);
- Cost[2] = CalculateFlowCost(a_Chunk, a_RelX, a_RelY, a_RelZ + 1, Z_PLUS);
- Cost[3] = CalculateFlowCost(a_Chunk, a_RelX, a_RelY, a_RelZ - 1, Z_MINUS);
+ Cost[0] = CalculateFlowCost(a_Chunk, a_RelX + 1, a_RelY, a_RelZ, X_PLUS);
+ Cost[1] = CalculateFlowCost(a_Chunk, a_RelX - 1, a_RelY, a_RelZ, X_MINUS);
+ Cost[2] = CalculateFlowCost(a_Chunk, a_RelX, a_RelY, a_RelZ + 1, Z_PLUS);
+ Cost[3] = CalculateFlowCost(a_Chunk, a_RelX, a_RelY, a_RelZ - 1, Z_MINUS);
// Find the minimum distance:
int MinCost = InfiniteCost;
@@ -79,7 +79,14 @@ void cVanillaFluidSimulator::SpreadXZ(cChunk * a_Chunk, int a_RelX, int a_RelY,
-int cVanillaFluidSimulator::CalculateFlowCost(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, Direction a_Dir, unsigned a_Iteration)
+int cVanillaFluidSimulator::CalculateFlowCost(
+ cChunk * a_Chunk,
+ int a_RelX,
+ int a_RelY,
+ int a_RelZ,
+ Direction a_Dir,
+ unsigned a_Iteration
+)
{
int Cost = InfiniteCost;
@@ -91,8 +98,7 @@ int cVanillaFluidSimulator::CalculateFlowCost(cChunk * a_Chunk, int a_RelX, int
{
return Cost;
}
- if (
- !IsPassableForFluid(BlockType) || // The block cannot be passed by the liquid ...
+ if (!IsPassableForFluid(BlockType) || // The block cannot be passed by the liquid ...
(IsAllowedBlock(BlockType) && (BlockMeta == 0)) // ... or if it is liquid, it is a source block
)
{
@@ -152,7 +158,3 @@ int cVanillaFluidSimulator::CalculateFlowCost(cChunk * a_Chunk, int a_RelX, int
return Cost;
}
-
-
-
-
diff --git a/src/Simulator/VanillaFluidSimulator.h b/src/Simulator/VanillaFluidSimulator.h
index 96ce8dc70..c5365c57f 100644
--- a/src/Simulator/VanillaFluidSimulator.h
+++ b/src/Simulator/VanillaFluidSimulator.h
@@ -13,13 +13,11 @@
-class cVanillaFluidSimulator:
- public cFloodyFluidSimulator
+class cVanillaFluidSimulator : public cFloodyFluidSimulator
{
using Super = cFloodyFluidSimulator;
-public:
-
+ public:
cVanillaFluidSimulator(
cWorld & a_World,
BLOCKTYPE a_Fluid,
@@ -29,15 +27,17 @@ public:
int a_NumNeighborsForSource
);
-protected:
+ protected:
// cFloodyFluidSimulator overrides:
virtual void SpreadXZ(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta) override;
/** Recursively calculates the minimum number of blocks needed to descend a level. */
- int CalculateFlowCost(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, Direction a_Dir, unsigned a_Iteration = 0);
-
-} ;
-
-
-
-
+ int CalculateFlowCost(
+ cChunk * a_Chunk,
+ int a_RelX,
+ int a_RelY,
+ int a_RelZ,
+ Direction a_Dir,
+ unsigned a_Iteration = 0
+ );
+};
diff --git a/src/Simulator/VaporizeFluidSimulator.cpp b/src/Simulator/VaporizeFluidSimulator.cpp
index a0939ebca..b4d5707ee 100644
--- a/src/Simulator/VaporizeFluidSimulator.cpp
+++ b/src/Simulator/VaporizeFluidSimulator.cpp
@@ -14,7 +14,12 @@
-void cVaporizeFluidSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
+void cVaporizeFluidSimulator::SimulateChunk(
+ std::chrono::milliseconds a_Dt,
+ int a_ChunkX,
+ int a_ChunkZ,
+ cChunk * a_Chunk
+)
{
// Nothing needed
@@ -33,11 +38,7 @@ void cVaporizeFluidSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BL
if ((a_Block == m_FluidBlock) || (a_Block == m_StationaryFluidBlock))
{
a_Chunk.FastSetBlock(a_Position, E_BLOCK_AIR, 0);
- World::GetBroadcastInterface(m_World).BroadcastSoundEffect(
- "block.fire.extinguish",
- Vector3d(a_Position),
- 1.0f,
- 0.6f
- );
+ World::GetBroadcastInterface(m_World)
+ .BroadcastSoundEffect("block.fire.extinguish", Vector3d(a_Position), 1.0f, 0.6f);
}
}
diff --git a/src/Simulator/VaporizeFluidSimulator.h b/src/Simulator/VaporizeFluidSimulator.h
index 60752bc72..e62d70d42 100644
--- a/src/Simulator/VaporizeFluidSimulator.h
+++ b/src/Simulator/VaporizeFluidSimulator.h
@@ -16,18 +16,15 @@
-class cVaporizeFluidSimulator:
- public cFluidSimulator
+class cVaporizeFluidSimulator : public cFluidSimulator
{
using Super = cFluidSimulator;
-public:
-
+ public:
using Super::Super;
-private:
-
+ private:
virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override;
virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override;
virtual cFluidSimulatorData * CreateChunkData(void) override { return nullptr; }
-} ;
+};