summaryrefslogtreecommitdiffstats
path: root/src/Simulator
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/Simulator/DelayedFluidSimulator.cpp15
-rw-r--r--src/Simulator/DelayedFluidSimulator.h1
-rw-r--r--src/Simulator/FireSimulator.cpp15
-rw-r--r--src/Simulator/FireSimulator.h5
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp4
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h1
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/RedstoneDataHelper.h30
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h48
-rw-r--r--src/Simulator/NoopFluidSimulator.h16
-rw-r--r--src/Simulator/NoopRedstoneSimulator.h10
-rw-r--r--src/Simulator/SandSimulator.h10
-rw-r--r--src/Simulator/Simulator.cpp50
-rw-r--r--src/Simulator/Simulator.h13
-rw-r--r--src/Simulator/SimulatorManager.cpp49
-rw-r--r--src/Simulator/VaporizeFluidSimulator.cpp27
-rw-r--r--src/Simulator/VaporizeFluidSimulator.h6
16 files changed, 151 insertions, 149 deletions
diff --git a/src/Simulator/DelayedFluidSimulator.cpp b/src/Simulator/DelayedFluidSimulator.cpp
index b7f7c890c..7e62acd04 100644
--- a/src/Simulator/DelayedFluidSimulator.cpp
+++ b/src/Simulator/DelayedFluidSimulator.cpp
@@ -138,18 +138,3 @@ void cDelayedFluidSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLO
++m_TotalBlocks;
}
-
-
-
-
-
-void cDelayedFluidSimulator::WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block)
-{
- if (!cChunkDef::IsValidHeight(a_Position))
- {
- // Not inside the world (may happen when rclk with a full bucket - the client sends Y = -1)
- return;
- }
-
- AddBlock(a_Chunk, a_Position, a_Block);
-}
diff --git a/src/Simulator/DelayedFluidSimulator.h b/src/Simulator/DelayedFluidSimulator.h
index 826489849..312bc1ff9 100644
--- a/src/Simulator/DelayedFluidSimulator.h
+++ b/src/Simulator/DelayedFluidSimulator.h
@@ -59,7 +59,6 @@ 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 void WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override;
virtual cFluidSimulatorData * CreateChunkData(void) override { return new cDelayedFluidSimulatorChunkData(m_TickDelay); }
int m_TickDelay; // Count of the m_Slots array in each ChunkData
diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp
index d1eb8618c..a025f6afd 100644
--- a/src/Simulator/FireSimulator.cpp
+++ b/src/Simulator/FireSimulator.cpp
@@ -363,14 +363,21 @@ void cFireSimulator::RemoveFuelNeighbors(cChunk * a_Chunk, Vector3i a_RelPos)
{
for (auto & coord : gNeighborCoords)
{
- BLOCKTYPE BlockType;
auto relPos = a_RelPos + coord;
- auto neighbor = a_Chunk->GetRelNeighborChunkAdjustCoords(relPos);
- if (neighbor == nullptr)
+
+ if (!cChunkDef::IsValidHeight(relPos))
+ {
+ continue;
+ }
+
+ const auto neighbor = a_Chunk->GetRelNeighborChunkAdjustCoords(relPos);
+
+ if ((neighbor == nullptr) || !neighbor->IsValid())
{
continue;
}
- BlockType = neighbor->GetBlock(relPos);
+
+ BLOCKTYPE BlockType = neighbor->GetBlock(relPos);
if (!IsFuel(BlockType))
{
diff --git a/src/Simulator/FireSimulator.h b/src/Simulator/FireSimulator.h
index 1e9b0b6d7..37ae3e63f 100644
--- a/src/Simulator/FireSimulator.h
+++ b/src/Simulator/FireSimulator.h
@@ -27,7 +27,6 @@ public:
private:
- virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used
virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override;
static bool IsAllowedBlock(BLOCKTYPE a_BlockType);
@@ -68,7 +67,3 @@ private:
/** 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/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp
index c23af9f75..8063e72a4 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp
+++ b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp
@@ -217,12 +217,14 @@ void cIncrementalRedstoneSimulator::WakeUp(cChunk & a_Chunk, Vector3i a_Position
for (const auto & Offset : cSimulator::GetLinkedOffsets(a_Offset))
{
auto Relative = a_Position - a_Offset + Offset;
+
if (!cChunkDef::IsValidHeight(Relative))
{
continue;
}
- auto Chunk = a_Chunk.GetRelNeighborChunkAdjustCoords(Relative);
+ const auto Chunk = a_Chunk.GetRelNeighborChunkAdjustCoords(Relative);
+
if ((Chunk == nullptr) || !Chunk->IsValid())
{
continue;
diff --git a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h
index 7f08c50af..365f0176e 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h
@@ -26,7 +26,6 @@ private:
void ProcessWorkItem(cChunk & Chunk, cChunk & TickingSource, const Vector3i Position);
- virtual void Simulate(float Dt) override {}
virtual void SimulateChunk(std::chrono::milliseconds Dt, int ChunkX, int ChunkZ, cChunk * Chunk) override;
virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override;
virtual cRedstoneSimulatorChunkData * CreateChunkData() override;
diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneDataHelper.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneDataHelper.h
index dc97a34d4..3942f803c 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneDataHelper.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneDataHelper.h
@@ -7,23 +7,37 @@ inline auto & DataForChunk(const cChunk & a_Chunk)
return *static_cast<cIncrementalRedstoneSimulatorChunkData *>(a_Chunk.GetRedstoneSimulatorData());
}
-template <typename... ArrayTypes>
-inline void UpdateAdjustedRelative(const cChunk & From, const cChunk & To, const Vector3i Position, const Vector3i Offset)
+inline void UpdateAdjustedRelative(const cChunk & a_Chunk, const cChunk & a_TickingChunk, const Vector3i a_Position, const Vector3i a_Offset)
{
- DataForChunk(To).WakeUp(cIncrementalRedstoneSimulatorChunkData::RebaseRelativePosition(From, To, Position + Offset));
+ const auto PositionToWake = a_Position + a_Offset;
- for (const auto & LinkedOffset : cSimulator::GetLinkedOffsets(Offset))
+ if (!cChunkDef::IsValidHeight(PositionToWake))
{
- DataForChunk(To).WakeUp(cIncrementalRedstoneSimulatorChunkData::RebaseRelativePosition(From, To, Position + LinkedOffset));
+ // If an offset position is not a valid height, its linked offset positions won't be either.
+ return;
+ }
+
+ auto & ChunkData = DataForChunk(a_TickingChunk);
+
+ // Schedule the block in the requested direction to update:
+ 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));
+ }
}
}
template <typename ArrayType>
-inline void UpdateAdjustedRelatives(const cChunk & From, const cChunk & To, const Vector3i Position, const ArrayType & Relative)
+inline void UpdateAdjustedRelatives(const cChunk & a_Chunk, const cChunk & a_TickingChunk, const Vector3i a_Position, const ArrayType & a_Relative)
{
- for (const auto & Offset : Relative)
+ for (const auto & Offset : a_Relative)
{
- UpdateAdjustedRelative(From, To, Position, Offset);
+ UpdateAdjustedRelative(a_Chunk, a_TickingChunk, a_Position, Offset);
}
}
diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h
index 5f2026842..b40491820 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h
@@ -100,19 +100,32 @@ namespace RedstoneWireHandler
}
}
+ static bool IsYPTerracingBlocked(const cChunk & a_Chunk, const Vector3i a_Position)
+ {
+ const auto Position = a_Position + OffsetYP;
+
+ 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);
+ }
+
/** 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 & Chunk, const Vector3i Position)
+ static void SetWireState(const cChunk & a_Chunk, const Vector3i a_Position)
{
auto Block = Block::RedstoneWire::RedstoneWire();
- const auto YPTerraceBlock = Chunk.GetBlock(Position + OffsetYP);
- const bool IsYPTerracingBlocked = cBlockInfo::IsSolid(YPTerraceBlock) && !cBlockInfo::IsTransparent(YPTerraceBlock);
+ const bool IsYPTerracingBlocked = RedstoneWireHandler::IsYPTerracingBlocked(a_Chunk, a_Position);
// Loop through laterals, discovering terracing connections:
for (const auto & Offset : RelativeLaterals)
{
- auto Adjacent = Position + Offset;
- auto NeighbourChunk = Chunk.GetRelNeighborChunkAdjustCoords(Adjacent);
+ auto Adjacent = a_Position + Offset;
+ auto NeighbourChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(Adjacent);
if ((NeighbourChunk == nullptr) || !NeighbourChunk->IsValid())
{
@@ -131,7 +144,7 @@ namespace RedstoneWireHandler
// 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 != &Chunk) && (LateralBlock == E_BLOCK_REDSTONE_WIRE))
+ if ((NeighbourChunk != &a_Chunk) && (LateralBlock == E_BLOCK_REDSTONE_WIRE))
{
auto & NeighbourBlock = DataForChunk(*NeighbourChunk).WireStates.find(Adjacent)->second;
SetDirectionState(-Offset, NeighbourBlock, TemporaryDirection::Side);
@@ -148,7 +161,7 @@ namespace RedstoneWireHandler
{
SetDirectionState(Offset, Block, cBlockInfo::IsTransparent(LateralBlock) ? TemporaryDirection::Side : TemporaryDirection::Up);
- if (NeighbourChunk != &Chunk)
+ if (NeighbourChunk != &a_Chunk)
{
auto & NeighbourBlock = DataForChunk(*NeighbourChunk).WireStates.find(Adjacent + OffsetYP)->second;
SetDirectionState(-Offset, NeighbourBlock, TemporaryDirection::Side);
@@ -166,7 +179,7 @@ namespace RedstoneWireHandler
{
SetDirectionState(Offset, Block, TemporaryDirection::Side);
- if (NeighbourChunk != &Chunk)
+ if (NeighbourChunk != &a_Chunk)
{
auto & NeighbourBlock = DataForChunk(*NeighbourChunk).WireStates.find(Adjacent + OffsetYM)->second;
SetDirectionState(-Offset, NeighbourBlock, TemporaryDirection::Up);
@@ -174,8 +187,8 @@ namespace RedstoneWireHandler
}
}
- auto & States = DataForChunk(Chunk).WireStates;
- const auto FindResult = States.find(Position);
+ auto & States = DataForChunk(a_Chunk).WireStates;
+ const auto FindResult = States.find(a_Position);
if (FindResult != States.end())
{
if (Block != FindResult->second)
@@ -184,13 +197,13 @@ namespace RedstoneWireHandler
// 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:
- Chunk.GetWorld()->WakeUpSimulators(cChunkDef::RelativeToAbsolute(Position, Chunk.GetPos()));
+ a_Chunk.GetWorld()->WakeUpSimulators(cChunkDef::RelativeToAbsolute(a_Position, a_Chunk.GetPos()));
}
return;
}
- DataForChunk(Chunk).WireStates.emplace(Position, Block);
+ 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)
@@ -269,15 +282,8 @@ namespace RedstoneWireHandler
a_Chunk.SetMeta(a_Position, Power);
// Notify all positions, sans YP, to update:
- for (const auto & Offset : RelativeAdjacents)
- {
- if (Offset == OffsetYP)
- {
- continue;
- }
-
- UpdateAdjustedRelative(a_Chunk, CurrentlyTicking, a_Position, Offset);
- }
+ 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)
diff --git a/src/Simulator/NoopFluidSimulator.h b/src/Simulator/NoopFluidSimulator.h
index 1b963f569..93d5cb50a 100644
--- a/src/Simulator/NoopFluidSimulator.h
+++ b/src/Simulator/NoopFluidSimulator.h
@@ -15,7 +15,7 @@
-class cNoopFluidSimulator:
+class cNoopFluidSimulator final :
public cFluidSimulator
{
using Super = cFluidSimulator;
@@ -26,15 +26,19 @@ public:
private:
- virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);}
+ virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override
+ {
+ UNUSED(a_Dt);
+ UNUSED(a_ChunkX);
+ UNUSED(a_ChunkZ);
+ UNUSED(a_Chunk);
+ }
+
virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override
{
UNUSED(a_Block);
UNUSED(a_Chunk);
}
+
virtual cFluidSimulatorData * CreateChunkData(void) override { return nullptr; }
} ;
-
-
-
-
diff --git a/src/Simulator/NoopRedstoneSimulator.h b/src/Simulator/NoopRedstoneSimulator.h
index 746ee1886..a361b5b12 100644
--- a/src/Simulator/NoopRedstoneSimulator.h
+++ b/src/Simulator/NoopRedstoneSimulator.h
@@ -19,7 +19,14 @@ public:
{
}
- virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used
+ virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override
+ {
+ UNUSED(a_Dt);
+ UNUSED(a_ChunkX);
+ UNUSED(a_ChunkZ);
+ UNUSED(a_Chunk);
+ }
+
virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override
{
UNUSED(a_Block);
@@ -30,5 +37,4 @@ public:
{
return nullptr;
}
-
} ;
diff --git a/src/Simulator/SandSimulator.h b/src/Simulator/SandSimulator.h
index e05b0de80..d27fd5873 100644
--- a/src/Simulator/SandSimulator.h
+++ b/src/Simulator/SandSimulator.h
@@ -55,7 +55,6 @@ public:
private:
- virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used
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
@@ -67,12 +66,3 @@ private:
/** Performs the instant fall of the block - removes it from top, Finishes it at the bottom */
void DoInstantFall(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ);
};
-
-
-
-
-
-
-
-
-
diff --git a/src/Simulator/Simulator.cpp b/src/Simulator/Simulator.cpp
index 36b03520c..7bf553912 100644
--- a/src/Simulator/Simulator.cpp
+++ b/src/Simulator/Simulator.cpp
@@ -3,7 +3,6 @@
#include "Simulator.h"
#include "../Chunk.h"
-#include "../Cuboid.h"
#include "../World.h"
@@ -94,62 +93,29 @@ std::array<Vector3i, 5> cSimulator::GetLinkedOffsets(const Vector3i Offset)
-void cSimulator::WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block)
+void cSimulator::Simulate(float a_Dt)
{
- ASSERT(a_Chunk.IsValid());
-
- AddBlock(a_Chunk, a_Position, a_Block);
+ UNUSED(a_Dt);
}
-void cSimulator::WakeUp(cChunk & a_Chunk, Vector3i a_Position, Vector3i a_Offset, BLOCKTYPE a_Block)
+void cSimulator::WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block)
{
ASSERT(a_Chunk.IsValid());
- WakeUp(a_Chunk, a_Position, a_Block);
+ AddBlock(a_Chunk, a_Position, a_Block);
}
-void cSimulator::WakeUp(const cCuboid & a_Area)
+void cSimulator::WakeUp(cChunk & a_Chunk, Vector3i a_Position, Vector3i a_Offset, BLOCKTYPE a_Block)
{
- cCuboid area(a_Area);
- area.Sort();
- area.Expand(1, 1, 1, 1, 1, 1); // Expand the area to contain the neighbors, too.
- area.ClampY(0, cChunkDef::Height - 1);
-
- // Add all blocks, in a per-chunk manner:
- cChunkCoords ChunkStart = cChunkDef::BlockToChunk(area.p1);
- cChunkCoords ChunkEnd = cChunkDef::BlockToChunk(area.p2);
- for (int cz = ChunkStart.m_ChunkZ; cz <= ChunkEnd.m_ChunkZ; ++cz)
- {
- for (int cx = ChunkStart.m_ChunkX; cx <= ChunkEnd.m_ChunkX; ++cx)
- {
- m_World.DoWithChunk(cx, cz, [this, &area](cChunk & a_CBChunk) -> bool
- {
- 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 (int z = startZ; z <= endZ; ++z)
- {
- for (int x = startX; x <= endX; ++x)
- {
- const auto Position = cChunkDef::AbsoluteToRelative({ x, y, z });
- AddBlock(a_CBChunk, Position, a_CBChunk.GetBlock(Position));
- } // for x
- } // for z
- } // for y
- return true;
- } // lambda
- ); // DoWithChunk
- } // for cx
- } // for cz
+ ASSERT(a_Chunk.IsValid());
+
+ WakeUp(a_Chunk, a_Position, a_Block);
}
diff --git a/src/Simulator/Simulator.h b/src/Simulator/Simulator.h
index e386c0bcf..5bb8376b0 100644
--- a/src/Simulator/Simulator.h
+++ b/src/Simulator/Simulator.h
@@ -50,14 +50,8 @@ 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
- virtual void Simulate(float a_Dt) = 0;
- virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
- {
- UNUSED(a_Dt);
- UNUSED(a_ChunkX);
- UNUSED(a_ChunkZ);
- UNUSED(a_Chunk);
- }
+ virtual void Simulate(float a_Dt);
+ virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) = 0;
/** Called to simulate a new block. Unlike WakeUp this function will perform minimal checking.
It queues the block to be simulated as fast as possible, suitable for area wakeups. */
@@ -74,8 +68,5 @@ protected:
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);
- /** Called to simulate an area by the manager, delegated to cSimulator to avoid virtual calls in tight loops. */
- void WakeUp(const cCuboid & a_Area);
-
cWorld & m_World;
} ;
diff --git a/src/Simulator/SimulatorManager.cpp b/src/Simulator/SimulatorManager.cpp
index 321035de5..7e5b9d036 100644
--- a/src/Simulator/SimulatorManager.cpp
+++ b/src/Simulator/SimulatorManager.cpp
@@ -3,6 +3,7 @@
#include "SimulatorManager.h"
#include "../Chunk.h"
+#include "../Cuboid.h"
#include "../World.h"
@@ -30,6 +31,7 @@ cSimulatorManager::~cSimulatorManager()
void cSimulatorManager::Simulate(float a_Dt)
{
m_Ticks++;
+
for (cSimulators::iterator itr = m_Simulators.begin(); itr != m_Simulators.end(); ++itr)
{
if ((m_Ticks % itr->second) == 0)
@@ -46,6 +48,7 @@ void cSimulatorManager::Simulate(float a_Dt)
void cSimulatorManager::SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
{
// m_Ticks has already been increased in Simulate()
+
for (cSimulators::iterator itr = m_Simulators.begin(); itr != m_Simulators.end(); ++itr)
{
if ((m_Ticks % itr->second) == 0)
@@ -71,12 +74,14 @@ void cSimulatorManager::WakeUp(cChunk & a_Chunk, Vector3i a_Position)
for (const auto & Offset : cSimulator::AdjacentOffsets)
{
auto Relative = a_Position + Offset;
+
if (!cChunkDef::IsValidHeight(Relative))
{
continue;
}
- auto Chunk = a_Chunk.GetRelNeighborChunkAdjustCoords(Relative);
+ const auto Chunk = a_Chunk.GetRelNeighborChunkAdjustCoords(Relative);
+
if ((Chunk == nullptr) || !Chunk->IsValid())
{
continue;
@@ -99,10 +104,46 @@ void cSimulatorManager::WakeUp(cChunk & a_Chunk, Vector3i a_Position)
void cSimulatorManager::WakeUp(const cCuboid & a_Area)
{
- for (const auto & Item : m_Simulators)
+ cCuboid area(a_Area);
+ area.Sort();
+ area.Expand(1, 1, 1, 1, 1, 1); // Expand the area to contain the neighbors, too.
+ area.ClampY(0, cChunkDef::Height - 1);
+
+ cChunkCoords ChunkStart = cChunkDef::BlockToChunk(area.p1);
+ cChunkCoords ChunkEnd = cChunkDef::BlockToChunk(area.p2);
+
+ // Add all blocks, in a per-chunk manner:
+ for (int cz = ChunkStart.m_ChunkZ; cz <= ChunkEnd.m_ChunkZ; ++cz)
{
- Item.first->WakeUp(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)
+ {
+ const auto Simulator = Item.first;
+
+ for (int y = area.p1.y; y <= area.p2.y; ++y)
+ {
+ for (int z = startZ; z <= endZ; ++z)
+ {
+ 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;
+ });
+ } // for cx
+ } // for cz
}
diff --git a/src/Simulator/VaporizeFluidSimulator.cpp b/src/Simulator/VaporizeFluidSimulator.cpp
index 6256c8e78..a0939ebca 100644
--- a/src/Simulator/VaporizeFluidSimulator.cpp
+++ b/src/Simulator/VaporizeFluidSimulator.cpp
@@ -14,6 +14,20 @@
+void cVaporizeFluidSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
+{
+ // Nothing needed
+
+ UNUSED(a_Dt);
+ UNUSED(a_ChunkX);
+ UNUSED(a_ChunkZ);
+ UNUSED(a_Chunk);
+}
+
+
+
+
+
void cVaporizeFluidSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block)
{
if ((a_Block == m_FluidBlock) || (a_Block == m_StationaryFluidBlock))
@@ -27,16 +41,3 @@ void cVaporizeFluidSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BL
);
}
}
-
-
-
-
-
-void cVaporizeFluidSimulator::Simulate(float a_Dt)
-{
- // Nothing needed
-}
-
-
-
-
diff --git a/src/Simulator/VaporizeFluidSimulator.h b/src/Simulator/VaporizeFluidSimulator.h
index 963cc7bc3..60752bc72 100644
--- a/src/Simulator/VaporizeFluidSimulator.h
+++ b/src/Simulator/VaporizeFluidSimulator.h
@@ -27,11 +27,7 @@ public:
private:
- 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 nullptr; }
} ;
-
-
-
-