From 58224863c0e3c61f28e2f345e53ee632043de9c4 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 2 May 2014 22:07:30 +0200 Subject: Fixed vanilla fluid simulator. Fixes #919. --- src/Simulator/FloodyFluidSimulator.cpp | 4 ++-- src/Simulator/FloodyFluidSimulator.h | 13 +++++-------- src/Simulator/VanillaFluidSimulator.cpp | 15 ++++++++++++--- src/Simulator/VanillaFluidSimulator.h | 2 +- 4 files changed, 20 insertions(+), 14 deletions(-) (limited to 'src/Simulator') diff --git a/src/Simulator/FloodyFluidSimulator.cpp b/src/Simulator/FloodyFluidSimulator.cpp index 03e94e791..e95af3a1c 100644 --- a/src/Simulator/FloodyFluidSimulator.cpp +++ b/src/Simulator/FloodyFluidSimulator.cpp @@ -119,7 +119,7 @@ void cFloodyFluidSimulator::SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_Re if (SpreadFurther && (NewMeta < 8)) { // Spread to the neighbors: - Spread(a_Chunk, a_RelX, a_RelY, a_RelZ, NewMeta); + SpreadXZ(a_Chunk, a_RelX, a_RelY, a_RelZ, NewMeta); } // Mark as processed: @@ -130,7 +130,7 @@ void cFloodyFluidSimulator::SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_Re -void cFloodyFluidSimulator::Spread(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta) +void cFloodyFluidSimulator::SpreadXZ(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta) { SpreadToNeighbor(a_Chunk, a_RelX - 1, a_RelY, a_RelZ, a_NewMeta); SpreadToNeighbor(a_Chunk, a_RelX + 1, a_RelY, a_RelZ, a_NewMeta); diff --git a/src/Simulator/FloodyFluidSimulator.h b/src/Simulator/FloodyFluidSimulator.h index 632de3bb2..8e1be5e6b 100644 --- a/src/Simulator/FloodyFluidSimulator.h +++ b/src/Simulator/FloodyFluidSimulator.h @@ -48,16 +48,13 @@ protected: 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. - */ + 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. - */ - virtual void Spread(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta); + /** Spread fluid to XZ neighbors. + The coords are of the block currently being processed; a_NewMeta is the new meta for the new fluid block. + Descendants may overridde to provide more sophisticated algorithms. */ + virtual void SpreadXZ(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta); } ; diff --git a/src/Simulator/VanillaFluidSimulator.cpp b/src/Simulator/VanillaFluidSimulator.cpp index 78aff9d68..28d75214c 100644 --- a/src/Simulator/VanillaFluidSimulator.cpp +++ b/src/Simulator/VanillaFluidSimulator.cpp @@ -35,14 +35,16 @@ cVanillaFluidSimulator::cVanillaFluidSimulator( -void cVanillaFluidSimulator::Spread(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta) +void cVanillaFluidSimulator::SpreadXZ(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta) { + // Calculate the distance to the nearest "hole" in each direction: 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); + // Find the minimum distance: int MinCost = InfiniteCost; for (unsigned int i = 0; i < ARRAYCOUNT(Cost); ++i) { @@ -52,6 +54,7 @@ void cVanillaFluidSimulator::Spread(cChunk * a_Chunk, int a_RelX, int a_RelY, in } } + // Spread in all directions where the distance matches the minimum: if (Cost[0] == MinCost) { SpreadToNeighbor(a_Chunk, a_RelX + 1, a_RelY, a_RelZ, a_NewMeta); @@ -86,7 +89,10 @@ int cVanillaFluidSimulator::CalculateFlowCost(cChunk * a_Chunk, int a_RelX, int { return Cost; } - if (!IsPassableForFluid(BlockType) && !IsBlockLiquid(BlockType)) + if ( + !IsPassableForFluid(BlockType) || // The block cannot be passed by the liquid ... + (IsAllowedBlock(BlockType) && (BlockMeta == 0)) // ... or if it is liquid, it is a source block + ) { return Cost; } @@ -96,7 +102,10 @@ int cVanillaFluidSimulator::CalculateFlowCost(cChunk * a_Chunk, int a_RelX, int { return Cost; } - if (IsPassableForFluid(BlockType) || IsBlockLiquid(BlockType)) + if ( + IsPassableForFluid(BlockType) || // The block can be passed by the liquid ... + (IsBlockLiquid(BlockType) && (BlockMeta != 0)) // ... or it is a liquid and not a source block + ) { // Path found, exit return a_Iteration; diff --git a/src/Simulator/VanillaFluidSimulator.h b/src/Simulator/VanillaFluidSimulator.h index a9ea98b5a..89a56ca14 100644 --- a/src/Simulator/VanillaFluidSimulator.h +++ b/src/Simulator/VanillaFluidSimulator.h @@ -30,7 +30,7 @@ public: protected: // cFloodyFluidSimulator overrides: - virtual void Spread(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta) override; + virtual void SpreadXZ(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta) override; /** Recursively calculates the minimum number of blocks needed to descend a level. */ int CalculateFlowCost(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, Direction a_Dir, unsigned a_Iteration = 0); -- cgit v1.2.3 From 4377a5c31ec39974a4b9597528f95edae166ce29 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 3 May 2014 19:23:59 +0200 Subject: Fixed vanilla fluid simulator. Fixes #919. --- src/Simulator/VanillaFluidSimulator.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/Simulator') diff --git a/src/Simulator/VanillaFluidSimulator.cpp b/src/Simulator/VanillaFluidSimulator.cpp index 28d75214c..18d9b07e1 100644 --- a/src/Simulator/VanillaFluidSimulator.cpp +++ b/src/Simulator/VanillaFluidSimulator.cpp @@ -102,10 +102,7 @@ int cVanillaFluidSimulator::CalculateFlowCost(cChunk * a_Chunk, int a_RelX, int { return Cost; } - if ( - IsPassableForFluid(BlockType) || // The block can be passed by the liquid ... - (IsBlockLiquid(BlockType) && (BlockMeta != 0)) // ... or it is a liquid and not a source block - ) + if (IsPassableForFluid(BlockType) || IsBlockLiquid(BlockType)) { // Path found, exit return a_Iteration; -- cgit v1.2.3 From bcd8f727b49ee0308346b7421d35d09817362b19 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 4 May 2014 00:39:03 +0100 Subject: Fixed pressure plate oversights * Fixed stone pressure plates not checking for the correct distance for players * Fixed pressure plates in general not link powering the blocks beneath them --- src/Simulator/IncrementalRedstoneSimulator.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/Simulator') diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index d37d2eecf..7d3f1a53e 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -116,7 +116,9 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY, // Things that can send power through a block but which depends on meta ((Block == E_BLOCK_REDSTONE_WIRE) && (Meta == 0)) || ((Block == E_BLOCK_LEVER) && !IsLeverOn(Meta)) || - (((Block == E_BLOCK_STONE_BUTTON) || (Block == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(Meta))) + (((Block == E_BLOCK_STONE_BUTTON) || (Block == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(Meta))) || + (((Block == E_BLOCK_STONE_PRESSURE_PLATE) || (Block == E_BLOCK_WOODEN_PRESSURE_PLATE)) && (Meta == 0)) || + (((Block == E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE) || (Block == E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE)) && (Meta == 0)) ) { LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list due to present/past metadata mismatch", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); @@ -1001,12 +1003,13 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_BlockX, int a_Bloc case E_BLOCK_STONE_PRESSURE_PLATE: { // MCS feature - stone pressure plates can only be triggered by players :D - cPlayer * a_Player = m_World.FindClosestPlayer(Vector3f(a_BlockX + 0.5f, (float)a_BlockY, a_BlockZ + 0.5f), 0.5f, false); + cPlayer * a_Player = m_World.FindClosestPlayer(Vector3f(a_BlockX + 0.5f, (float)a_BlockY, a_BlockZ + 0.5f), 0.7f, false); if (a_Player != NULL) { m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, 0x1); SetAllDirsAsPowered(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_STONE_PRESSURE_PLATE); + SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YM, a_MyType); } else { @@ -1069,6 +1072,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_BlockX, int a_Bloc } m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, E_META_PRESSURE_PLATE_DEPRESSED); SetAllDirsAsPowered(a_BlockX, a_BlockY, a_BlockZ, a_MyType, Power); + SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YM, a_MyType); } else { @@ -1135,6 +1139,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_BlockX, int a_Bloc } m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, E_META_PRESSURE_PLATE_DEPRESSED); SetAllDirsAsPowered(a_BlockX, a_BlockY, a_BlockZ, a_MyType, Power); + SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YM, a_MyType); } else { @@ -1201,6 +1206,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_BlockX, int a_Bloc } m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, E_META_PRESSURE_PLATE_DEPRESSED); SetAllDirsAsPowered(a_BlockX, a_BlockY, a_BlockZ, a_MyType); + SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YM, a_MyType); } else { -- cgit v1.2.3