10 #include "../BlockInfo.h"
13 #include "../BlockArea.h"
14 #include "../Blocks/BlockHandler.h"
15 #include "../BlockInServerPluginInterface.h"
16 #include "../Blocks/ChunkInterface.h"
24 #define FLUID_FLOG FLOGD
26 #define FLUID_FLOG(...)
39 int a_NumNeighborsForSource
41 Super(a_World, a_Fluid, a_StationaryFluid, a_TickDelay),
43 m_NumNeighborsForSource(a_NumNeighborsForSource)
53 FLUID_FLOG(
"Simulating block {0}: block {1}, meta {2}",
55 a_Chunk->
GetBlock(a_RelX, a_RelY, a_RelZ),
56 a_Chunk->
GetMeta(a_RelX, a_RelY, a_RelZ)
70 if (
HardenBlock(a_Chunk, {a_RelX, a_RelY, a_RelZ}, MyBlock, MyMeta))
94 bool SpreadFurther =
true;
104 SpreadFurther =
false;
108 if (SpreadFurther && (NewMeta < 8))
110 SpreadXZ(a_Chunk, a_RelX, a_RelY, a_RelZ, NewMeta);
175 for (
size_t i = 0; i <
ARRAYCOUNT(Coords); i++)
184 FLUID_FLOG(
" Fed from {0}, type {1}, meta {2}",
209 FLUID_FLOG(
" Not fed, meta {0}, erasing altogether", a_MyMeta);
225 Vector3i relPos(a_RelX, a_RelY, a_RelZ);
227 if ((a_NearChunk ==
nullptr) || (!a_NearChunk->
IsValid()))
240 if ((BlockMeta == a_NewMeta) ||
IsHigherMeta(BlockMeta, a_NewMeta))
254 FLUID_FLOG(
" Lava flowing into water, turning water at rel {0} into {1}",
257 a_NearChunk->
SetBlock(relPos, NewBlock, 0);
260 "block.lava.extinguish",
274 FLUID_FLOG(
" Water flowing into lava, turning lava at rel {0} into {1}",
277 a_NearChunk->
SetBlock(relPos, NewBlock, 0);
280 "block.lava.extinguish",
290 ASSERT(!
"Unknown fluid!");
306 FLUID_FLOG(
" Spreading to {0} with meta {1}", absPos, a_NewMeta);
319 FLUID_FLOG(
" Checking neighbors for source creation");
321 static const Vector3i NeighborCoords[] =
330 for (
size_t i = 0; i <
ARRAYCOUNT(NeighborCoords); i++)
332 int x = a_RelX + NeighborCoords[i].
x;
333 int y = a_RelY + NeighborCoords[i].
y;
334 int z = a_RelZ + NeighborCoords[i].
z;
374 bool ShouldHarden =
false;
378 static const Vector3i neighborOffsets[] =
385 for (
const auto & ofs: neighborOffsets)
406 else if (a_Meta <= 4)
bool IsBlockWater(BLOCKTYPE a_BlockType)
bool IsBlockLava(BLOCKTYPE a_BlockType)
AString ItemTypeToString(short a_ItemType)
Translates itemtype into a string.
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
unsigned char BLOCKTYPE
The datatype used by blockdata.
#define ARRAYCOUNT(X)
Evaluates to the number of elements in an array (compile-time!)
NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) const
void FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta)
BLOCKTYPE GetBlock(int a_RelX, int a_RelY, int a_RelZ) const
Vector3i RelativeToAbsolute(Vector3i a_RelBlockPosition) const
Converts the coord relative to this chunk into an absolute coord.
cChunk * GetRelNeighborChunkAdjustCoords(Vector3i &a_RelPos) const
Returns the chunk into which the relatively-specified block belongs.
void SetBlock(Vector3i a_RelBlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
bool UnboundedRelGetBlock(Vector3i a_RelCoords, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_BlockMeta) const
Same as GetBlock(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in ...
bool IsValid(void) const
Returns true iff the chunk block data is valid (loaded / generated)
Vector3i PositionToWorldPosition(Vector3i a_RelPos)
void GetBlockTypeMeta(Vector3i a_RelPos, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_BlockMeta) const
static bool IsValidRelPos(Vector3i a_RelPos)
Validates a chunk relative coordinate.
bool CheckTributaries(cChunk *a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_MyMeta)
Checks tributaries, if not fed, decreases the block's level and returns true.
bool HardenBlock(cChunk *a_Chunk, Vector3i a_RelPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta)
Checks if the specified block should harden (Water / Lava interaction) and if so, converts it to a su...
bool CheckNeighborsForSource(cChunk *a_Chunk, int a_RelX, int a_RelY, int a_RelZ)
Checks if there are enough neighbors to create a source at the coords specified; turns into source an...
virtual void SpreadXZ(cChunk *a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta)
Spread fluid to XZ neighbors.
virtual void SimulateBlock(cChunk *a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
Called from SimulateChunk() to simulate each block in one slot of blocks.
int m_NumNeighborsForSource
cFloodyFluidSimulator(cWorld &a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid, NIBBLETYPE a_Falloff, int a_TickDelay, int a_NumNeighborsForSource)
void SpreadToNeighbor(cChunk *a_NearChunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta)
Spreads into the specified block, if the blocktype there allows.
bool IsHigherMeta(NIBBLETYPE a_Meta1, NIBBLETYPE a_Meta2)
Returns true if a_Meta1 is a higher fluid than a_Meta2.
BLOCKTYPE m_StationaryFluidBlock
static bool CanWashAway(BLOCKTYPE a_BlockType)
bool IsAllowedBlock(BLOCKTYPE a_BlockType)
bool IsAnyFluidBlock(BLOCKTYPE a_BlockType) const
bool IsPassableForFluid(BLOCKTYPE a_BlockType)
void WakeUp(cChunk &a_Chunk, Vector3i a_Position)
bool DropBlockAsPickups(Vector3i a_BlockPos, const cEntity *a_Digger=nullptr, const cItem *a_Tool=nullptr)
Digs the specified block, and spawns the appropriate pickups for it.
virtual void BroadcastSoundEffect(const AString &a_SoundName, Vector3d a_Position, float a_Volume, float a_Pitch, const cClientHandle *a_Exclude=nullptr) override
cSimulatorManager * GetSimulatorManager(void)