summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Simulator/FloodyFluidSimulator.cpp68
-rw-r--r--src/Simulator/FloodyFluidSimulator.h6
-rw-r--r--src/Simulator/VanillaFluidSimulator.cpp4
3 files changed, 74 insertions, 4 deletions
diff --git a/src/Simulator/FloodyFluidSimulator.cpp b/src/Simulator/FloodyFluidSimulator.cpp
index b1ac734d7..03e94e791 100644
--- a/src/Simulator/FloodyFluidSimulator.cpp
+++ b/src/Simulator/FloodyFluidSimulator.cpp
@@ -54,14 +54,23 @@ void cFloodyFluidSimulator::SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_Re
a_Chunk->GetMeta(a_RelX, a_RelY, a_RelZ)
);
- NIBBLETYPE MyMeta = a_Chunk->GetMeta(a_RelX, a_RelY, a_RelZ);
- if (!IsAnyFluidBlock(a_Chunk->GetBlock(a_RelX, a_RelY, a_RelZ)))
+ BLOCKTYPE MyBlock; NIBBLETYPE MyMeta;
+ a_Chunk->GetBlockTypeMeta(a_RelX, a_RelY, a_RelZ, MyBlock, MyMeta);
+
+ if (!IsAnyFluidBlock(MyBlock))
{
// Can happen - if a block is scheduled for simulating and gets replaced in the meantime.
FLOG(" BadBlockType exit");
return;
}
+ // When in contact with water, lava should harden
+ if (HardenBlock(a_Chunk, a_RelX, a_RelY, a_RelZ, MyBlock, MyMeta))
+ {
+ // Block was changed, bail out
+ return;
+ }
+
if (MyMeta != 0)
{
// Source blocks aren't checked for tributaries, others are.
@@ -309,6 +318,8 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i
a_NewMeta
);
a_NearChunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, m_FluidBlock, a_NewMeta);
+
+ HardenBlock(a_NearChunk, a_RelX, a_RelY, a_RelZ, m_FluidBlock, a_NewMeta);
}
@@ -361,3 +372,56 @@ bool cFloodyFluidSimulator::CheckNeighborsForSource(cChunk * a_Chunk, int a_RelX
+
+bool cFloodyFluidSimulator::HardenBlock(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta)
+{
+ // Only lava blocks can harden
+ if (!IsBlockLava(a_BlockType))
+ {
+ return false;
+ }
+
+ bool ShouldHarden = false;
+
+ BLOCKTYPE BlockType;
+ NIBBLETYPE BlockMeta;
+ static const Vector3i Coords[] =
+ {
+ Vector3i( 1, 0, 0),
+ Vector3i(-1, 0, 0),
+ Vector3i( 0, 0, 1),
+ Vector3i( 0, 0, -1),
+ };
+ for (size_t i = 0; i < ARRAYCOUNT(Coords); i++)
+ {
+ if (!a_Chunk->UnboundedRelGetBlock(a_RelX + Coords[i].x, a_RelY, a_RelZ + Coords[i].z, BlockType, BlockMeta))
+ {
+ continue;
+ }
+ if (IsBlockWater(BlockType))
+ {
+ ShouldHarden = true;
+ }
+ } // for i - Coords[]
+
+ if (ShouldHarden)
+ {
+ if (a_Meta == 0)
+ {
+ // Source lava block
+ a_Chunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_OBSIDIAN, 0);
+ return true;
+ }
+ // Ignore last lava level
+ else if (a_Meta <= 4)
+ {
+ a_Chunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_COBBLESTONE, 0);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+
diff --git a/src/Simulator/FloodyFluidSimulator.h b/src/Simulator/FloodyFluidSimulator.h
index 5fd91b2b1..632de3bb2 100644
--- a/src/Simulator/FloodyFluidSimulator.h
+++ b/src/Simulator/FloodyFluidSimulator.h
@@ -47,6 +47,12 @@ protected:
/** Checks if there are enough neighbors to create a source at the coords specified; turns into source and returns true if so. */
bool CheckNeighborsForSource(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ);
+ /** Checks if the specified block should harden (Water/Lava interaction) and if so, converts it to a suitable block.
+ *
+ * Returns whether the block was changed or not.
+ */
+ bool HardenBlock(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta);
+
/** Spread water to neighbors.
*
* May be overridden to provide more sophisticated algorithms.
diff --git a/src/Simulator/VanillaFluidSimulator.cpp b/src/Simulator/VanillaFluidSimulator.cpp
index 5308d162b..78aff9d68 100644
--- a/src/Simulator/VanillaFluidSimulator.cpp
+++ b/src/Simulator/VanillaFluidSimulator.cpp
@@ -86,7 +86,7 @@ int cVanillaFluidSimulator::CalculateFlowCost(cChunk * a_Chunk, int a_RelX, int
{
return Cost;
}
- if (!IsPassableForFluid(BlockType))
+ if (!IsPassableForFluid(BlockType) && !IsBlockLiquid(BlockType))
{
return Cost;
}
@@ -96,7 +96,7 @@ int cVanillaFluidSimulator::CalculateFlowCost(cChunk * a_Chunk, int a_RelX, int
{
return Cost;
}
- if (IsPassableForFluid(BlockType))
+ if (IsPassableForFluid(BlockType) || IsBlockLiquid(BlockType))
{
// Path found, exit
return a_Iteration;