diff options
Diffstat (limited to 'src/Simulator')
-rw-r--r-- | src/Simulator/DelayedFluidSimulator.cpp | 2 | ||||
-rw-r--r-- | src/Simulator/FireSimulator.cpp | 26 | ||||
-rw-r--r-- | src/Simulator/FloodyFluidSimulator.cpp | 68 | ||||
-rw-r--r-- | src/Simulator/FloodyFluidSimulator.h | 6 | ||||
-rw-r--r-- | src/Simulator/IncrementalRedstoneSimulator.cpp | 2 | ||||
-rw-r--r-- | src/Simulator/VanillaFluidSimulator.cpp | 4 |
6 files changed, 95 insertions, 13 deletions
diff --git a/src/Simulator/DelayedFluidSimulator.cpp b/src/Simulator/DelayedFluidSimulator.cpp index 3d2170e44..bc5158d95 100644 --- a/src/Simulator/DelayedFluidSimulator.cpp +++ b/src/Simulator/DelayedFluidSimulator.cpp @@ -20,7 +20,7 @@ bool cDelayedFluidSimulatorChunkData::cSlot::Add(int a_RelX, int a_RelY, int a_RelZ) { ASSERT(a_RelZ >= 0); - ASSERT(a_RelZ < ARRAYCOUNT(m_Blocks)); + ASSERT(a_RelZ < static_cast<int>(ARRAYCOUNT(m_Blocks))); cCoordWithIntVector & Blocks = m_Blocks[a_RelZ]; int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ); diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp index 4967c83f9..26712e6e6 100644 --- a/src/Simulator/FireSimulator.cpp +++ b/src/Simulator/FireSimulator.cpp @@ -334,21 +334,33 @@ void cFireSimulator::RemoveFuelNeighbors(cChunk * a_Chunk, int a_RelX, int a_Rel for (size_t i = 0; i < ARRAYCOUNT(gNeighborCoords); i++) { BLOCKTYPE BlockType; - NIBBLETYPE BlockMeta; - if (!a_Chunk->UnboundedRelGetBlock(a_RelX + gNeighborCoords[i].x, a_RelY + gNeighborCoords[i].y, a_RelZ + gNeighborCoords[i].z, BlockType, BlockMeta)) + int X = a_RelX + gNeighborCoords[i].x; + int Z = a_RelZ + gNeighborCoords[i].z; + + cChunkPtr Neighbour = a_Chunk->GetRelNeighborChunkAdjustCoords(X, Z); + if (Neighbour == NULL) { - // Neighbor not accessible, ignore it continue; } + BlockType = Neighbour->GetBlock(X, a_RelY + gCrossCoords[i].y, Z); + if (!IsFuel(BlockType)) { continue; } + + if (BlockType == E_BLOCK_TNT) + { + int AbsX = X + Neighbour->GetPosX() * cChunkDef::Width; + int AbsZ = Z + Neighbour->GetPosZ() * cChunkDef::Width; + + m_World.SpawnPrimedTNT(AbsX, a_RelY + gNeighborCoords[i].y, AbsZ, 0); + Neighbour->SetBlock(X, a_RelY + gNeighborCoords[i].y, Z, E_BLOCK_AIR, 0); + return; + } + bool ShouldReplaceFuel = (m_World.GetTickRandomNumber(MAX_CHANCE_REPLACE_FUEL) < m_ReplaceFuelChance); - a_Chunk->UnboundedRelSetBlock( - a_RelX + gNeighborCoords[i].x, a_RelY + gNeighborCoords[i].y, a_RelZ + gNeighborCoords[i].z, - ShouldReplaceFuel ? E_BLOCK_FIRE : E_BLOCK_AIR, 0 - ); + Neighbour->SetBlock(X, a_RelY + gNeighborCoords[i].y, Z, ShouldReplaceFuel ? E_BLOCK_FIRE : E_BLOCK_AIR, 0); } // for i - Coords[] } 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/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index f377b0aa7..ca2ef4b1a 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -838,7 +838,7 @@ void cIncrementalRedstoneSimulator::HandleTNT(int a_BlockX, int a_BlockY, int a_ if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) { m_World.BroadcastSoundEffect("game.tnt.primed", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, 0.6f); - m_World.SpawnPrimedTNT(a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5, 4); // 4 seconds to boom + m_World.SpawnPrimedTNT(a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5); // 80 ticks to boom m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); } } 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; |