Add WakeUp/AddBlock distinction
* WakeUp is for singular changes (block breaking for example). The simulator should check blocks around the position and discover other affected blocks as it sees fit * AddBlock is for when you know a whole area is to be updated; chunk loading, or area wakeups for example + Prepares for correct handling of destroyed blocks after removal of SolidBlockHandler in the redstone simulator
This commit is contained in:
parent
6d7b83a69d
commit
99856df686
@ -1330,7 +1330,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_
|
||||
);
|
||||
|
||||
// Wake up all simulators for the area, so that water and lava flows and sand falls into the blasted holes (FS #391):
|
||||
m_World->GetSimulatorManager()->WakeUpArea(cCuboid(
|
||||
m_World->GetSimulatorManager()->WakeUp(cCuboid(
|
||||
{bx - ExplosionSizeInt - 1, MinY, bz - ExplosionSizeInt - 1},
|
||||
{bx + ExplosionSizeInt + 1, MaxY, bz + ExplosionSizeInt + 1}
|
||||
));
|
||||
|
@ -111,7 +111,6 @@ void cMultiVersionProtocol::HandleIncomingDataInRecognitionStage(cClientHandle &
|
||||
// The protocol recogniser succesfully identified, switch mode:
|
||||
HandleIncomingData = [this](cClientHandle &, const std::string_view a_In)
|
||||
{
|
||||
// TODO: make it take our a_ReceivedData
|
||||
m_Protocol->DataReceived(m_Buffer, a_In.data(), a_In.size());
|
||||
};
|
||||
}
|
||||
|
@ -78,19 +78,8 @@ cDelayedFluidSimulator::cDelayedFluidSimulator(cWorld & a_World, BLOCKTYPE a_Flu
|
||||
|
||||
|
||||
|
||||
void cDelayedFluidSimulator::AddBlock(Vector3i a_Block, cChunk * a_Chunk)
|
||||
void cDelayedFluidSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block)
|
||||
{
|
||||
if ((a_Block.y < 0) || (a_Block.y >= cChunkDef::Height))
|
||||
{
|
||||
// Not inside the world (may happen when rclk with a full bucket - the client sends Y = -1)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((a_Chunk == nullptr) || !a_Chunk->IsValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int RelX = a_Block.x - a_Chunk->GetPosX() * cChunkDef::Width;
|
||||
int RelZ = a_Block.z - a_Chunk->GetPosZ() * cChunkDef::Width;
|
||||
BLOCKTYPE BlockType = a_Chunk->GetBlock(RelX, a_Block.y, RelZ);
|
||||
@ -156,3 +145,14 @@ void cDelayedFluidSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a
|
||||
|
||||
|
||||
|
||||
|
||||
void cDelayedFluidSimulator::WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block)
|
||||
{
|
||||
if (!cChunkDef::IsValidHeight(a_Position.y))
|
||||
{
|
||||
// Not inside the world (may happen when rclk with a full bucket - the client sends Y = -1)
|
||||
return;
|
||||
}
|
||||
|
||||
Super::WakeUp(a_Chunk, a_Position, a_Block);
|
||||
}
|
||||
|
@ -55,7 +55,8 @@ public:
|
||||
cDelayedFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid, int a_TickDelay);
|
||||
|
||||
// cSimulator overrides:
|
||||
virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) override;
|
||||
virtual void WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override;
|
||||
virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override;
|
||||
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 cFluidSimulatorData * CreateChunkData(void) override { return new cDelayedFluidSimulatorChunkData(m_TickDelay); }
|
||||
|
@ -239,7 +239,7 @@ bool cFireSimulator::DoesBurnForever(BLOCKTYPE a_BlockType)
|
||||
|
||||
|
||||
|
||||
void cFireSimulator::AddBlock(Vector3i a_Block, cChunk * a_Chunk)
|
||||
void cFireSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block)
|
||||
{
|
||||
if ((a_Chunk == nullptr) || !a_Chunk->IsValid())
|
||||
{
|
||||
|
@ -43,8 +43,7 @@ protected:
|
||||
/** Chance [0..100000] of a fuel burning out being replaced by a new fire block instead of an air block */
|
||||
int m_ReplaceFuelChance;
|
||||
|
||||
|
||||
virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) override;
|
||||
virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override;
|
||||
|
||||
/** Returns the time [msec] after which the specified fire block is stepped again; based on surrounding fuels */
|
||||
int GetBurnStepTime(cChunk * a_Chunk, Vector3i a_RelPos);
|
||||
|
@ -128,6 +128,53 @@ std::unique_ptr<cRedstoneHandler> cIncrementalRedstoneSimulator::CreateComponent
|
||||
|
||||
|
||||
|
||||
void cIncrementalRedstoneSimulator::WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block)
|
||||
{
|
||||
Super::WakeUp(a_Chunk, a_Position, a_Block);
|
||||
|
||||
auto & ChunkData = *static_cast<cIncrementalRedstoneSimulatorChunkData *>(a_Chunk.GetRedstoneSimulatorData());
|
||||
|
||||
// Never update blocks without a handler:
|
||||
if (GetComponentHandler(a_Block) == nullptr)
|
||||
{
|
||||
ChunkData.ErasePowerData(a_Position);
|
||||
return;
|
||||
}
|
||||
|
||||
// Only update others if there is a redstone device nearby
|
||||
for (int x = -1; x < 2; ++x)
|
||||
{
|
||||
for (int y = -1; y < 2; ++y)
|
||||
{
|
||||
if (!cChunkDef::IsValidHeight(a_Position.y + y))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int z = -1; z < 2; ++z)
|
||||
{
|
||||
auto CheckPos = a_Position + Vector3i{ x, y, z };
|
||||
BLOCKTYPE Block;
|
||||
NIBBLETYPE Meta;
|
||||
|
||||
// If we can't read the block, assume it is a mechanism
|
||||
if (
|
||||
!a_Chunk.UnboundedRelGetBlock(CheckPos, Block, Meta) ||
|
||||
IsRedstone(Block)
|
||||
)
|
||||
{
|
||||
ChunkData.WakeUp(a_Position);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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());
|
||||
@ -224,7 +271,7 @@ void cIncrementalRedstoneSimulator::ProcessWorkItem(cChunk & Chunk, cChunk & Tic
|
||||
|
||||
|
||||
|
||||
void cIncrementalRedstoneSimulator::AddBlock(Vector3i a_Block, cChunk * a_Chunk)
|
||||
void cIncrementalRedstoneSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block)
|
||||
{
|
||||
// Can't inspect block, ignore:
|
||||
if ((a_Chunk == nullptr) || !a_Chunk->IsValid())
|
||||
@ -236,50 +283,16 @@ void cIncrementalRedstoneSimulator::AddBlock(Vector3i a_Block, cChunk * a_Chunk)
|
||||
const auto Relative = cChunkDef::AbsoluteToRelative(a_Block, a_Chunk->GetPos());
|
||||
const auto CurrentBlock = a_Chunk->GetBlock(Relative);
|
||||
|
||||
// Always update redstone devices
|
||||
if (IsRedstone(CurrentBlock))
|
||||
if (!IsRedstone(CurrentBlock))
|
||||
{
|
||||
if (IsAlwaysTicked(CurrentBlock))
|
||||
{
|
||||
ChunkData.AlwaysTickedPositions.emplace(Relative);
|
||||
}
|
||||
ChunkData.WakeUp(Relative);
|
||||
return;
|
||||
}
|
||||
|
||||
// Never update blocks without a handler
|
||||
if (GetComponentHandler(CurrentBlock) == nullptr)
|
||||
if (IsAlwaysTicked(CurrentBlock))
|
||||
{
|
||||
ChunkData.ErasePowerData(Relative);
|
||||
return;
|
||||
ChunkData.AlwaysTickedPositions.emplace(Relative);
|
||||
}
|
||||
|
||||
// Only update others if there is a redstone device nearby
|
||||
for (int x = -1; x < 2; ++x)
|
||||
{
|
||||
for (int y = -1; y < 2; ++y)
|
||||
{
|
||||
if (!cChunkDef::IsValidHeight(Relative.y + y))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int z = -1; z < 2; ++z)
|
||||
{
|
||||
auto CheckPos = Relative + Vector3i{x, y, z};
|
||||
BLOCKTYPE Block;
|
||||
NIBBLETYPE Meta;
|
||||
|
||||
// If we can't read the block, assume it is a mechanism
|
||||
if (
|
||||
!a_Chunk->UnboundedRelGetBlock(CheckPos, Block, Meta) ||
|
||||
IsRedstone(Block)
|
||||
)
|
||||
{
|
||||
ChunkData.WakeUp(Relative);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Always update redstone devices:
|
||||
ChunkData.WakeUp(Relative);
|
||||
}
|
||||
|
@ -21,6 +21,10 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
virtual void WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override;
|
||||
|
||||
virtual void Simulate(float Dt) override {};
|
||||
virtual void SimulateChunk(std::chrono::milliseconds Dt, int ChunkX, int ChunkZ, cChunk * Chunk) override;
|
||||
|
||||
@ -36,7 +40,7 @@ public:
|
||||
return IsRedstone(a_BlockType);
|
||||
}
|
||||
|
||||
virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) override;
|
||||
virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override;
|
||||
|
||||
/** Returns if a block is a mechanism (something that accepts power and does something)
|
||||
Used by torches to determine if they will power a block */
|
||||
|
@ -28,7 +28,7 @@ public:
|
||||
}
|
||||
|
||||
// cSimulator overrides:
|
||||
virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) override
|
||||
virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override
|
||||
{
|
||||
UNUSED(a_Block);
|
||||
UNUSED(a_Chunk);
|
||||
|
@ -28,7 +28,7 @@ public:
|
||||
UNUSED(a_Chunk);
|
||||
}
|
||||
virtual bool IsAllowedBlock( BLOCKTYPE a_BlockType) override { return false; }
|
||||
virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) override
|
||||
virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override
|
||||
{
|
||||
UNUSED(a_Block);
|
||||
UNUSED(a_Chunk);
|
||||
|
@ -31,11 +31,6 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
virtual void Simulate(float a_Dt) = 0;
|
||||
virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) = 0;
|
||||
virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) = 0;
|
||||
virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) = 0;
|
||||
|
||||
virtual cRedstoneSimulatorChunkData * CreateChunkData() = 0;
|
||||
|
||||
};
|
||||
|
@ -97,7 +97,7 @@ bool cSandSimulator::IsAllowedBlock(BLOCKTYPE a_BlockType)
|
||||
|
||||
|
||||
|
||||
void cSandSimulator::AddBlock(Vector3i a_Block, cChunk * a_Chunk)
|
||||
void cSandSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block)
|
||||
{
|
||||
if ((a_Chunk == nullptr) || !a_Chunk->IsValid())
|
||||
{
|
||||
|
@ -27,6 +27,7 @@ class cSandSimulator :
|
||||
public cSimulator
|
||||
{
|
||||
public:
|
||||
|
||||
cSandSimulator(cWorld & a_World, cIniFile & a_IniFile);
|
||||
|
||||
// cSimulator overrides:
|
||||
@ -56,11 +57,12 @@ public:
|
||||
);
|
||||
|
||||
protected:
|
||||
|
||||
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
|
||||
|
||||
virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) override;
|
||||
virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override;
|
||||
|
||||
/** 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);
|
||||
|
@ -1,33 +1,38 @@
|
||||
|
||||
#include "Globals.h"
|
||||
|
||||
#include "../World.h"
|
||||
#include "../Defines.h"
|
||||
#include "Simulator.h"
|
||||
#include "../Chunk.h"
|
||||
#include "../Cuboid.h"
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic ignored "-Wweak-template-vtables"
|
||||
#endif // __clang__
|
||||
|
||||
|
||||
|
||||
#include "Simulator.h"
|
||||
#include "../World.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSimulator::WakeUp(Vector3i a_Block, cChunk * a_Chunk)
|
||||
void cSimulator::WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block)
|
||||
{
|
||||
AddBlock(a_Block, a_Chunk);
|
||||
ASSERT(a_Chunk.IsValid());
|
||||
|
||||
AddBlock(a_Chunk, a_Position, a_Block);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSimulator::WakeUpArea(const cCuboid & a_Area)
|
||||
void cSimulator::WakeUp(cChunk & a_Chunk, Vector3i a_Position, Vector3i a_Offset, BLOCKTYPE a_Block)
|
||||
{
|
||||
ASSERT(a_Chunk.IsValid());
|
||||
|
||||
WakeUp(a_Chunk, a_Position, a_Block);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSimulator::WakeUp(const cCuboid & a_Area)
|
||||
{
|
||||
cCuboid area(a_Area);
|
||||
area.Sort();
|
||||
@ -60,7 +65,8 @@ void cSimulator::WakeUpArea(const cCuboid & a_Area)
|
||||
{
|
||||
for (int x = startX; x <= endX; ++x)
|
||||
{
|
||||
AddBlock({x, y, z}, &a_CBChunk);
|
||||
const auto Position = cChunkDef::AbsoluteToRelative({ x, y, z });
|
||||
AddBlock(a_CBChunk, Position, a_CBChunk.GetBlock(Position));
|
||||
} // for x
|
||||
} // for z
|
||||
} // for y
|
||||
@ -70,7 +76,3 @@ void cSimulator::WakeUpArea(const cCuboid & a_Area)
|
||||
} // for cx
|
||||
} // for cz
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -19,6 +19,7 @@ may update its internal state based on this call. */
|
||||
class cSimulator
|
||||
{
|
||||
public:
|
||||
|
||||
cSimulator(cWorld & a_World)
|
||||
: m_World(a_World)
|
||||
{
|
||||
@ -26,10 +27,13 @@ public:
|
||||
|
||||
virtual ~cSimulator() {}
|
||||
|
||||
/** Called in each tick, a_Dt is the time passed since the last tick, in msec */
|
||||
virtual void Simulate(float a_Dt) = 0;
|
||||
virtual void WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block);
|
||||
|
||||
/** 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 */
|
||||
protected:
|
||||
|
||||
friend class cChunk; // Calls AddBlock() in its WakeUpSimulators() function, to speed things up
|
||||
|
||||
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);
|
||||
@ -38,28 +42,26 @@ public:
|
||||
UNUSED(a_Chunk);
|
||||
}
|
||||
|
||||
/** Called when a block changes */
|
||||
void WakeUp(Vector3i a_Block, cChunk * a_Chunk);
|
||||
|
||||
/** 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. So far none of the simulators care about that. */
|
||||
void WakeUpArea(const cCuboid & a_Area);
|
||||
|
||||
/** Returns true if the specified block type is "interesting" for this simulator. */
|
||||
virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) = 0;
|
||||
|
||||
protected:
|
||||
friend class cChunk; // Calls AddBlock() in its WakeUpSimulators() function, to speed things up
|
||||
/** 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, only making sure that the block type IsAllowedBlock. */
|
||||
virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) = 0;
|
||||
|
||||
/** Called to simulate a new block */
|
||||
virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) = 0;
|
||||
/** Called to simulate a single new block, typically as a result of a single block break or change.
|
||||
The simulator implementation may decide to perform additional checks or maintain consistency of internal state
|
||||
before the block is added to the simulate queue. */
|
||||
virtual void WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block);
|
||||
|
||||
/** 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. */
|
||||
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;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||
|
||||
#include "SimulatorManager.h"
|
||||
#include "../Chunk.h"
|
||||
#include "../World.h"
|
||||
|
||||
|
||||
@ -58,11 +59,13 @@ void cSimulatorManager::SimulateChunk(std::chrono::milliseconds a_Dt, int a_Chun
|
||||
|
||||
|
||||
|
||||
void cSimulatorManager::WakeUp(Vector3i a_Block, cChunk * a_Chunk)
|
||||
void cSimulatorManager::WakeUp(cChunk & a_Chunk, Vector3i a_Position)
|
||||
{
|
||||
ASSERT(a_Chunk.IsValid());
|
||||
|
||||
for (cSimulators::iterator itr = m_Simulators.begin(); itr != m_Simulators.end(); ++itr)
|
||||
{
|
||||
itr->first->WakeUp(a_Block, a_Chunk);
|
||||
itr->first->WakeUp(a_Chunk, a_Position, a_Chunk.GetBlock(a_Position));
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,11 +73,11 @@ void cSimulatorManager::WakeUp(Vector3i a_Block, cChunk * a_Chunk)
|
||||
|
||||
|
||||
|
||||
void cSimulatorManager::WakeUpArea(const cCuboid & a_Area)
|
||||
void cSimulatorManager::WakeUp(const cCuboid & a_Area)
|
||||
{
|
||||
for (cSimulators::iterator itr = m_Simulators.begin(); itr != m_Simulators.end(); ++itr)
|
||||
for (const auto Item : m_Simulators)
|
||||
{
|
||||
itr->first->WakeUpArea(a_Area);
|
||||
Item.first->WakeUp(a_Area);
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,7 +89,3 @@ void cSimulatorManager::RegisterSimulator(cSimulator * a_Simulator, int a_Rate)
|
||||
{
|
||||
m_Simulators.push_back(std::make_pair(a_Simulator, a_Rate));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -28,26 +28,30 @@ class cWorld;
|
||||
class cSimulatorManager
|
||||
{
|
||||
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. */
|
||||
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. */
|
||||
void WakeUp(Vector3i a_Block, cChunk * a_Chunk);
|
||||
/* Called when a single block changes, wakes all simulators up for the block.
|
||||
The simulator implementation may also decide to wake the block's face-neighbors or blocks farther away. */
|
||||
void WakeUp(cChunk & a_Chunk, Vector3i a_Position);
|
||||
|
||||
/** 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. So far none of the simulators care about that. */
|
||||
void WakeUpArea(const cCuboid & a_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;
|
||||
|
||||
cWorld & m_World;
|
||||
|
@ -22,7 +22,7 @@ cVaporizeFluidSimulator::cVaporizeFluidSimulator(cWorld & a_World, BLOCKTYPE a_F
|
||||
|
||||
|
||||
|
||||
void cVaporizeFluidSimulator::AddBlock(Vector3i a_Block, cChunk * a_Chunk)
|
||||
void cVaporizeFluidSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block)
|
||||
{
|
||||
if (a_Chunk == nullptr)
|
||||
{
|
||||
|
@ -26,7 +26,7 @@ public:
|
||||
cVaporizeFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid);
|
||||
|
||||
// cSimulator overrides:
|
||||
virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) override;
|
||||
virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override;
|
||||
virtual void Simulate(float a_Dt) override;
|
||||
} ;
|
||||
|
||||
|
@ -1327,7 +1327,7 @@ void cWorld::WakeUpSimulatorsInArea(int a_MinBlockX, int a_MaxBlockX, int a_MinB
|
||||
|
||||
void cWorld::WakeUpSimulatorsInArea(const cCuboid & a_Area)
|
||||
{
|
||||
m_SimulatorManager->WakeUpArea(a_Area);
|
||||
m_SimulatorManager->WakeUp(a_Area);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user