From 1ea17c0a75b84d5f4070c57ad2a7d6cbb4e8b79b Mon Sep 17 00:00:00 2001 From: andrew Date: Wed, 5 Mar 2014 15:54:38 +0200 Subject: Implemented vanilla-like fluid simulator --- src/Simulator/VanillaFluidSimulator.cpp | 150 ++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 src/Simulator/VanillaFluidSimulator.cpp (limited to 'src/Simulator/VanillaFluidSimulator.cpp') diff --git a/src/Simulator/VanillaFluidSimulator.cpp b/src/Simulator/VanillaFluidSimulator.cpp new file mode 100644 index 000000000..5308d162b --- /dev/null +++ b/src/Simulator/VanillaFluidSimulator.cpp @@ -0,0 +1,150 @@ + +// VanillaFluidSimulator.cpp + +#include "Globals.h" + +#include "VanillaFluidSimulator.h" +#include "../World.h" +#include "../Chunk.h" +#include "../BlockArea.h" +#include "../Blocks/BlockHandler.h" +#include "../BlockInServerPluginInterface.h" + + + + + +static const int InfiniteCost = 100; + + + + + +cVanillaFluidSimulator::cVanillaFluidSimulator( + cWorld & a_World, + BLOCKTYPE a_Fluid, + BLOCKTYPE a_StationaryFluid, + NIBBLETYPE a_Falloff, + int a_TickDelay, + int a_NumNeighborsForSource +) : super(a_World, a_Fluid, a_StationaryFluid, a_Falloff, a_TickDelay, a_NumNeighborsForSource) +{ +} + + + + + +void cVanillaFluidSimulator::Spread(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta) +{ + int Cost[4]; + Cost[0] = CalculateFlowCost(a_Chunk, a_RelX + 1, a_RelY, a_RelZ, X_PLUS); + Cost[1] = CalculateFlowCost(a_Chunk, a_RelX - 1, a_RelY, a_RelZ, X_MINUS); + Cost[2] = CalculateFlowCost(a_Chunk, a_RelX, a_RelY, a_RelZ + 1, Z_PLUS); + Cost[3] = CalculateFlowCost(a_Chunk, a_RelX, a_RelY, a_RelZ - 1, Z_MINUS); + + int MinCost = InfiniteCost; + for (unsigned int i = 0; i < ARRAYCOUNT(Cost); ++i) + { + if (Cost[i] < MinCost) + { + MinCost = Cost[i]; + } + } + + if (Cost[0] == MinCost) + { + SpreadToNeighbor(a_Chunk, a_RelX + 1, a_RelY, a_RelZ, a_NewMeta); + } + if (Cost[1] == MinCost) + { + SpreadToNeighbor(a_Chunk, a_RelX - 1, a_RelY, a_RelZ, a_NewMeta); + } + if (Cost[2] == MinCost) + { + SpreadToNeighbor(a_Chunk, a_RelX, a_RelY, a_RelZ + 1, a_NewMeta); + } + if (Cost[3] == MinCost) + { + SpreadToNeighbor(a_Chunk, a_RelX, a_RelY, a_RelZ - 1, a_NewMeta); + } +} + + + + + +int cVanillaFluidSimulator::CalculateFlowCost(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, Direction a_Dir, unsigned a_Iteration) +{ + int Cost = InfiniteCost; + + BLOCKTYPE BlockType; + NIBBLETYPE BlockMeta; + + // Check if block is passable + if (!a_Chunk->UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ, BlockType, BlockMeta)) + { + return Cost; + } + if (!IsPassableForFluid(BlockType)) + { + return Cost; + } + + // Check if block below is passable + if (!a_Chunk->UnboundedRelGetBlock(a_RelX, a_RelY - 1, a_RelZ, BlockType, BlockMeta)) + { + return Cost; + } + if (IsPassableForFluid(BlockType)) + { + // Path found, exit + return a_Iteration; + } + + // 5 blocks away, bail out + if (a_Iteration > 3) + { + return Cost; + } + + // Recurse + if (a_Dir != X_MINUS) + { + int NextCost = CalculateFlowCost(a_Chunk, a_RelX + 1, a_RelY, a_RelZ, X_PLUS, a_Iteration + 1); + if (NextCost < Cost) + { + Cost = NextCost; + } + } + if (a_Dir != X_PLUS) + { + int NextCost = CalculateFlowCost(a_Chunk, a_RelX - 1, a_RelY, a_RelZ, X_MINUS, a_Iteration + 1); + if (NextCost < Cost) + { + Cost = NextCost; + } + } + if (a_Dir != Z_MINUS) + { + int NextCost = CalculateFlowCost(a_Chunk, a_RelX, a_RelY, a_RelZ + 1, Z_PLUS, a_Iteration + 1); + if (NextCost < Cost) + { + Cost = NextCost; + } + } + if (a_Dir != Z_PLUS) + { + int NextCost = CalculateFlowCost(a_Chunk, a_RelX, a_RelY, a_RelZ - 1, Z_MINUS, a_Iteration + 1); + if (NextCost < Cost) + { + Cost = NextCost; + } + } + + return Cost; +} + + + + -- cgit v1.2.3 From 880852394275c4cc3c458582fc245f6f22f9d200 Mon Sep 17 00:00:00 2001 From: andrew Date: Fri, 7 Mar 2014 15:42:03 +0200 Subject: Fixed water/lava interaction --- src/Simulator/VanillaFluidSimulator.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/Simulator/VanillaFluidSimulator.cpp') 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; -- cgit v1.2.3