diff options
author | madmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6> | 2013-01-04 06:21:07 +0100 |
---|---|---|
committer | madmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6> | 2013-01-04 06:21:07 +0100 |
commit | 412c21a22cd67971bc27ee3fd022e1565eb48e69 (patch) | |
tree | c4f5d99c7016f26f3c6de39c21c269c0c2dadd58 | |
parent | cBlockArea now has a GetBlockTypeMeta() and GetRelBlockTypeMeta() methods (diff) | |
download | cuberite-412c21a22cd67971bc27ee3fd022e1565eb48e69.tar cuberite-412c21a22cd67971bc27ee3fd022e1565eb48e69.tar.gz cuberite-412c21a22cd67971bc27ee3fd022e1565eb48e69.tar.bz2 cuberite-412c21a22cd67971bc27ee3fd022e1565eb48e69.tar.lz cuberite-412c21a22cd67971bc27ee3fd022e1565eb48e69.tar.xz cuberite-412c21a22cd67971bc27ee3fd022e1565eb48e69.tar.zst cuberite-412c21a22cd67971bc27ee3fd022e1565eb48e69.zip |
-rw-r--r-- | source/Simulator/FloodyFluidSimulator.cpp | 70 | ||||
-rw-r--r-- | source/Simulator/FloodyFluidSimulator.h | 8 | ||||
-rw-r--r-- | source/World.cpp | 9 |
3 files changed, 78 insertions, 9 deletions
diff --git a/source/Simulator/FloodyFluidSimulator.cpp b/source/Simulator/FloodyFluidSimulator.cpp index fe53c9014..e89bb6bf6 100644 --- a/source/Simulator/FloodyFluidSimulator.cpp +++ b/source/Simulator/FloodyFluidSimulator.cpp @@ -26,9 +26,17 @@ -cFloodyFluidSimulator::cFloodyFluidSimulator(cWorld * a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid, NIBBLETYPE a_Falloff, int a_TickDelay) :
+cFloodyFluidSimulator::cFloodyFluidSimulator(
+ 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_TickDelay),
- m_Falloff(a_Falloff)
+ m_Falloff(a_Falloff),
+ m_NumNeighborsForSource(a_NumNeighborsForSource)
{
}
@@ -62,8 +70,10 @@ void cFloodyFluidSimulator::SimulateBlock(int a_BlockX, int a_BlockY, int a_Bloc if (MyMeta != 0)
{
+ // Source blocks aren't checked for tributaries, others are.
if (CheckTributaries(a_BlockX, a_BlockY, a_BlockZ, Area, MyMeta))
{
+ // Has no tributary, has been decreased, no more processing needed (neighbors have been scheduled by the decrease)
return;
}
}
@@ -81,6 +91,19 @@ void cFloodyFluidSimulator::SimulateBlock(int a_BlockX, int a_BlockY, int a_Bloc }
else if (NewMeta < 8) // Can reach there
{
+ // If source creation is on, check for it here:
+ if (
+ (m_NumNeighborsForSource > 0) && // Source creation is on
+ (MyMeta == m_Falloff) && // Only exactly one block away from a source (fast bail-out)
+ !IsPassableForFluid(Below) && // Only exactly 1 block deep
+ CheckNeighborsForSource(a_BlockX, a_BlockY, a_BlockZ, Area) // Did we create a source?
+ )
+ {
+ // We created a source, no more spreading is to be done now
+ // Also has been re-scheduled for ticking in the next wave
+ return;
+ }
+
// Spread to the neighbors:
SpreadToNeighbor(a_BlockX - 1, a_BlockY, a_BlockZ, Area, NewMeta);
SpreadToNeighbor(a_BlockX + 1, a_BlockY, a_BlockZ, Area, NewMeta);
@@ -229,3 +252,46 @@ void cFloodyFluidSimulator::SpreadToNeighbor(int a_BlockX, int a_BlockY, int a_B +
+bool cFloodyFluidSimulator::CheckNeighborsForSource(int a_BlockX, int a_BlockY, int a_BlockZ, const cBlockArea & a_Area)
+{
+ FLOG(" Checking neighbors for source creation");
+
+ static const Vector3i NeighborCoords[] =
+ {
+ Vector3i(-1, 0, 0),
+ Vector3i( 1, 0, 0),
+ Vector3i( 0, 0,-1),
+ Vector3i( 0, 0, 1),
+ } ;
+
+ int NumNeeded = m_NumNeighborsForSource;
+ for (int i = 0; i < ARRAYCOUNT(NeighborCoords); i++)
+ {
+ int x = a_BlockX + NeighborCoords[i].x;
+ int y = a_BlockY + NeighborCoords[i].y;
+ int z = a_BlockZ + NeighborCoords[i].z;
+ BLOCKTYPE BlockType;
+ NIBBLETYPE BlockMeta;
+ a_Area.GetBlockTypeMeta(x, y, z, BlockType, BlockMeta);
+ FLOG(" Neighbor at {%d, %d, %d}: %s", x, y, z, ItemToFullString(cItem(BlockType, 1, BlockMeta)).c_str());
+ if ((BlockMeta == 0) && IsAnyFluidBlock(BlockType))
+ {
+ NumNeeded--;
+ FLOG(" Found a neighbor source at {%d, %d, %d}, NumNeeded := %d", x, y, z, NumNeeded);
+ if (NumNeeded == 0)
+ {
+ // Found enough, turn into a source and bail out
+ FLOG(" Found enough neighbor sources, turning into a source");
+ m_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_FluidBlock, 0);
+ return true;
+ }
+ }
+ }
+ FLOG(" Not enough neighbors for turning into a source, NumNeeded = %d", NumNeeded);
+ return false;
+}
+
+
+
+
diff --git a/source/Simulator/FloodyFluidSimulator.h b/source/Simulator/FloodyFluidSimulator.h index d3fa85fce..dc9ff2557 100644 --- a/source/Simulator/FloodyFluidSimulator.h +++ b/source/Simulator/FloodyFluidSimulator.h @@ -29,10 +29,11 @@ class cFloodyFluidSimulator : typedef cDelayedFluidSimulator super;
public:
- cFloodyFluidSimulator(cWorld * a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid, NIBBLETYPE a_Falloff, int a_TickDelay);
+ cFloodyFluidSimulator(cWorld * a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid, NIBBLETYPE a_Falloff, int a_TickDelay, int a_NumNeighborsForSource);
protected:
NIBBLETYPE m_Falloff;
+ int m_NumNeighborsForSource;
// cDelayedFluidSimulator overrides:
virtual void SimulateBlock(int a_BlockX, int a_BlockY, int a_BlockZ) override;
@@ -40,8 +41,11 @@ protected: /// Checks tributaries, if not fed, decreases the block's level and returns true
bool CheckTributaries(int a_BlockX, int a_BlockY, int a_BlockZ, const cBlockArea & a_Area, NIBBLETYPE a_MyMeta);
- /// Spreads into the specified block, if the block there allows. a_Area is for checking.
+ /// Spreads into the specified block, if the blocktype there allows. a_Area is for checking.
void SpreadToNeighbor(int a_BlockX, int a_BlockY, int a_BlockZ, const cBlockArea & a_Area, NIBBLETYPE a_NewMeta);
+
+ /// Checks if there are enough neighbors to create a source at the coords specified; turns into source and returns true if so
+ bool CheckNeighborsForSource(int a_BlockX, int a_BlockY, int a_BlockZ, const cBlockArea & a_Area);
} ;
diff --git a/source/World.cpp b/source/World.cpp index d2c60690b..6eaf7a279 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -2249,11 +2249,10 @@ cFluidSimulator * cWorld::InitializeFluidSimulator(cIniFile & a_IniFile, const c int Rate = 1; if (NoCaseCompare(SimulatorName, "floody") == 0) { - int DefaultFalloff = IsWater ? 1 : 2; - int DefaultTickDelay = IsWater ? 5 : 30; - int Falloff = a_IniFile.GetValueSetI(SimulatorSectionName, "Falloff", DefaultFalloff); - int TickDelay = a_IniFile.GetValueSetI(SimulatorSectionName, "TickDelay", DefaultTickDelay); - res = new cFloodyFluidSimulator(this, a_SimulateBlock, a_StationaryBlock, Falloff, TickDelay); + int Falloff = a_IniFile.GetValueSetI(SimulatorSectionName, "Falloff", IsWater ? 1 : 2); + int TickDelay = a_IniFile.GetValueSetI(SimulatorSectionName, "TickDelay", IsWater ? 5 : 30); + int NumNeighborsForSource = a_IniFile.GetValueSetI(SimulatorSectionName, "NumNeighborsForSource", IsWater ? 2 : -1); + res = new cFloodyFluidSimulator(this, a_SimulateBlock, a_StationaryBlock, Falloff, TickDelay, NumNeighborsForSource); } else { |