2012-10-13 09:53:28 +00:00
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2014-10-25 20:54:00 +00:00
|
|
|
class cWorld;
|
|
|
|
class cChunk;
|
2017-07-14 14:18:33 +00:00
|
|
|
class cCuboid;
|
2012-10-13 09:53:28 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-07-14 14:18:33 +00:00
|
|
|
/** Base class for all block-based physics simulators (such as fluid, fire, falling blocks etc.).
|
|
|
|
Each descendant provides an implementation of what needs to be done on each world tick.
|
|
|
|
The descendant may choose to do all processing in a single call for the entire world (Simulate())
|
|
|
|
or do per-chunk calculations (SimulateChunk()).
|
|
|
|
Whenever a block is changed, the WakeUp() or WakeUpArea() functions are called to notify all simulators.
|
|
|
|
The functions add all affected blocks and all their direct neighbors using the AddBlock() function. The simulator
|
|
|
|
may update its internal state based on this call. */
|
2012-10-13 09:53:28 +00:00
|
|
|
class cSimulator
|
|
|
|
{
|
|
|
|
public:
|
2020-07-28 23:12:45 +00:00
|
|
|
|
2014-10-25 20:54:00 +00:00
|
|
|
cSimulator(cWorld & a_World)
|
|
|
|
: m_World(a_World)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual ~cSimulator() {}
|
2012-10-13 09:53:28 +00:00
|
|
|
|
2020-07-28 23:12:45 +00:00
|
|
|
virtual void WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block);
|
2016-02-05 21:45:45 +00:00
|
|
|
|
2020-07-28 23:12:45 +00:00
|
|
|
protected:
|
|
|
|
|
|
|
|
friend class cChunk; // Calls AddBlock() in its WakeUpSimulators() function, to speed things up
|
|
|
|
|
|
|
|
virtual void Simulate(float a_Dt) = 0;
|
2015-01-11 21:12:26 +00:00
|
|
|
virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
|
2013-12-22 13:46:55 +00:00
|
|
|
{
|
|
|
|
UNUSED(a_Dt);
|
|
|
|
UNUSED(a_ChunkX);
|
|
|
|
UNUSED(a_ChunkZ);
|
|
|
|
UNUSED(a_Chunk);
|
2014-07-22 22:36:13 +00:00
|
|
|
}
|
2016-02-05 21:45:45 +00:00
|
|
|
|
2017-07-14 14:18:33 +00:00
|
|
|
/** Returns true if the specified block type is "interesting" for this simulator. */
|
2012-10-13 09:53:28 +00:00
|
|
|
virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) = 0;
|
|
|
|
|
2020-07-28 23:12:45 +00:00
|
|
|
/** 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;
|
2012-10-13 09:53:28 +00:00
|
|
|
|
2020-07-28 23:12:45 +00:00
|
|
|
/** 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);
|
2012-10-13 09:53:28 +00:00
|
|
|
|
2020-07-28 23:12:45 +00:00
|
|
|
/** 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);
|
2012-10-13 09:53:28 +00:00
|
|
|
|
2020-07-28 23:12:45 +00:00
|
|
|
/** Called to simulate an area by the manager, delegated to cSimulator to avoid virtual calls in tight loops. */
|
|
|
|
void WakeUp(const cCuboid & a_Area);
|
2012-10-13 09:53:28 +00:00
|
|
|
|
2020-07-28 23:12:45 +00:00
|
|
|
cWorld & m_World;
|
|
|
|
} ;
|