summaryrefslogtreecommitdiffstats
path: root/src/Blocks/BlockFluid.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/Blocks/BlockFluid.h')
-rw-r--r--src/Blocks/BlockFluid.h137
1 files changed, 137 insertions, 0 deletions
diff --git a/src/Blocks/BlockFluid.h b/src/Blocks/BlockFluid.h
new file mode 100644
index 000000000..bce5064bc
--- /dev/null
+++ b/src/Blocks/BlockFluid.h
@@ -0,0 +1,137 @@
+
+#pragma once
+
+#include "BlockHandler.h"
+
+
+
+
+
+class cBlockFluidHandler :
+ public cBlockHandler
+{
+ typedef cBlockHandler super;
+
+public:
+ cBlockFluidHandler(BLOCKTYPE a_BlockType)
+ : cBlockHandler(a_BlockType)
+ {
+
+ }
+
+
+ virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
+ {
+ // No pickups
+ }
+
+
+ virtual bool DoesIgnoreBuildCollision(void) override
+ {
+ return true;
+ }
+
+
+ virtual void Check(int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk) override
+ {
+ switch (m_BlockType)
+ {
+ case E_BLOCK_STATIONARY_LAVA:
+ {
+ a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_LAVA, a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ));
+ break;
+ }
+ case E_BLOCK_STATIONARY_WATER:
+ {
+ a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_WATER, a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ));
+ break;
+ }
+ }
+ super::Check(a_RelX, a_RelY, a_RelZ, a_Chunk);
+ }
+} ;
+
+
+
+
+
+class cBlockLavaHandler :
+ public cBlockFluidHandler
+{
+ typedef cBlockFluidHandler super;
+public:
+
+ cBlockLavaHandler(BLOCKTYPE a_BlockType) :
+ super(a_BlockType)
+ {
+ }
+
+
+ /// Called to tick the block
+ virtual void OnUpdate(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
+ {
+ if (a_Chunk.GetWorld()->ShouldLavaSpawnFire())
+ {
+ // Try to start up to 5 fires:
+ for (int i = 0; i < 5; i++)
+ {
+ TryStartFireNear(a_RelX, a_RelY, a_RelZ, a_Chunk);
+ }
+ }
+ }
+
+
+ /// Tries to start a fire near the lava at given coords. Returns true if fire started.
+ static bool TryStartFireNear(int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk)
+ {
+ // Pick a block next to this lava block:
+ int rnd = a_Chunk.GetWorld()->GetTickRandomNumber(cChunkDef::NumBlocks * 8) / 7;
+ int x = (rnd % 3) - 1; // -1 .. 1
+ int y = ((rnd / 4) % 4) - 1; // -1 .. 2
+ int z = ((rnd / 16) % 3) - 1; // -1 .. 1
+
+ // Check if it's fuel:
+ BLOCKTYPE BlockType;
+ if (
+ !a_Chunk.UnboundedRelGetBlockType(a_RelX + x, a_RelY + y, a_RelZ + z, BlockType) ||
+ !cFireSimulator::IsFuel(BlockType)
+ )
+ {
+ return false;
+ }
+
+ // Try to set it on fire:
+ static struct
+ {
+ int x, y, z;
+ } CrossCoords[] =
+ {
+ {-1, 0, 0},
+ { 1, 0, 0},
+ { 0, -1, 0},
+ { 0, 1, 0},
+ { 0, 0, -1},
+ { 0, 0, 1},
+ } ;
+ int RelX = a_RelX + x;
+ int RelY = a_RelY + y;
+ int RelZ = a_RelZ + z;
+ for (size_t i = 0; i < ARRAYCOUNT(CrossCoords); i++)
+ {
+ if (
+ a_Chunk.UnboundedRelGetBlockType(RelX + CrossCoords[i].x, RelY + CrossCoords[i].y, RelZ + CrossCoords[i].z, BlockType) &&
+ (BlockType == E_BLOCK_AIR)
+ )
+ {
+ // This is an air block next to a fuel next to lava, light it up:
+ a_Chunk.UnboundedRelSetBlock(RelX + CrossCoords[i].x, RelY + CrossCoords[i].y, RelZ + CrossCoords[i].z, E_BLOCK_FIRE, 0);
+ return true;
+ }
+ } // for i - CrossCoords[]
+ return false;
+ }
+} ;
+
+
+
+