1
0

Merge pull request #764 from xdot/master

Fixed water/lava interaction
This commit is contained in:
Mattes D 2014-03-07 21:33:22 +01:00
commit ae84cdf242
3 changed files with 74 additions and 4 deletions

View File

@ -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;
}

View File

@ -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.

View File

@ -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;