summaryrefslogtreecommitdiffstats
path: root/src/Simulator/SimulatorManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Simulator/SimulatorManager.cpp')
-rw-r--r--src/Simulator/SimulatorManager.cpp49
1 files changed, 45 insertions, 4 deletions
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
}