2013-05-23 05:01:19 +00:00
|
|
|
|
|
|
|
package net.minecraftforge.fluids;
|
|
|
|
|
|
|
|
import java.util.Random;
|
|
|
|
|
|
|
|
import net.minecraft.block.Block;
|
|
|
|
import net.minecraft.block.material.Material;
|
|
|
|
import net.minecraft.world.IBlockAccess;
|
|
|
|
import net.minecraft.world.World;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This is a cellular-automata based finite fluid block implementation.
|
|
|
|
*
|
|
|
|
* It is highly recommended that you use/extend this class for finite fluid blocks.
|
|
|
|
*
|
|
|
|
* @author OvermindDL1, KingLemming
|
|
|
|
*
|
|
|
|
*/
|
2013-07-17 04:40:49 +00:00
|
|
|
public class BlockFluidFinite extends BlockFluidBase
|
|
|
|
{
|
|
|
|
public BlockFluidFinite(int id, Fluid fluid, Material material)
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
super(id, fluid, material);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2013-07-17 04:40:49 +00:00
|
|
|
public int getQuantaValue(IBlockAccess world, int x, int y, int z)
|
|
|
|
{
|
|
|
|
if (world.isAirBlock(x, y, z))
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2013-07-17 04:40:49 +00:00
|
|
|
|
2013-09-05 17:16:01 +00:00
|
|
|
if (world.getBlockId(x, y, z) != blockID)
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2013-07-17 04:40:49 +00:00
|
|
|
|
2013-05-23 05:01:19 +00:00
|
|
|
int quantaRemaining = world.getBlockMetadata(x, y, z) + 1;
|
|
|
|
return quantaRemaining;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2013-07-17 04:40:49 +00:00
|
|
|
public boolean canCollideCheck(int meta, boolean fullHit)
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
return fullHit && meta == quantaPerBlock - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2013-07-17 04:40:49 +00:00
|
|
|
public int getMaxRenderHeightMeta()
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
return quantaPerBlock - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2013-07-17 04:40:49 +00:00
|
|
|
public void updateTick(World world, int x, int y, int z, Random rand)
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
boolean changed = false;
|
|
|
|
int quantaRemaining = world.getBlockMetadata(x, y, z) + 1;
|
|
|
|
|
|
|
|
// Flow vertically if possible
|
|
|
|
int prevRemaining = quantaRemaining;
|
|
|
|
quantaRemaining = tryToFlowVerticallyInto(world, x, y, z, quantaRemaining);
|
|
|
|
|
2013-07-17 04:40:49 +00:00
|
|
|
if (quantaRemaining < 1)
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
return;
|
2013-07-17 04:40:49 +00:00
|
|
|
}
|
|
|
|
else if (quantaRemaining != prevRemaining)
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
changed = true;
|
2013-07-17 04:40:49 +00:00
|
|
|
if (quantaRemaining == 1)
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
world.setBlockMetadataWithNotify(x, y, z, quantaRemaining - 1, 2);
|
|
|
|
return;
|
|
|
|
}
|
2013-07-17 04:40:49 +00:00
|
|
|
}
|
|
|
|
else if (quantaRemaining == 1)
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Flow out if possible
|
|
|
|
int lowerthan = quantaRemaining - 1;
|
2013-07-17 04:40:49 +00:00
|
|
|
if (displaceIfPossible(world, x, y, z - 1)) world.setBlock(x, y, z - 1, 0);
|
|
|
|
if (displaceIfPossible(world, x, y, z + 1)) world.setBlock(x, y, z + 1, 0);
|
|
|
|
if (displaceIfPossible(world, x - 1, y, z )) world.setBlock(x - 1, y, z, 0);
|
|
|
|
if (displaceIfPossible(world, x + 1, y, z )) world.setBlock(x + 1, y, z, 0);
|
|
|
|
int north = getQuantaValueBelow(world, x, y, z - 1, lowerthan);
|
|
|
|
int south = getQuantaValueBelow(world, x, y, z + 1, lowerthan);
|
|
|
|
int west = getQuantaValueBelow(world, x - 1, y, z, lowerthan);
|
|
|
|
int east = getQuantaValueBelow(world, x + 1, y, z, lowerthan);
|
2013-05-23 05:01:19 +00:00
|
|
|
int total = quantaRemaining;
|
|
|
|
int count = 1;
|
|
|
|
|
2013-07-17 04:40:49 +00:00
|
|
|
if (north >= 0)
|
|
|
|
{
|
|
|
|
count++;
|
2013-05-23 05:01:19 +00:00
|
|
|
total += north;
|
|
|
|
}
|
2013-07-17 04:40:49 +00:00
|
|
|
|
|
|
|
if (south >= 0)
|
|
|
|
{
|
|
|
|
count++;
|
2013-05-23 05:01:19 +00:00
|
|
|
total += south;
|
|
|
|
}
|
2013-07-17 04:40:49 +00:00
|
|
|
|
|
|
|
if (west >= 0)
|
|
|
|
{
|
|
|
|
count++;
|
2013-05-23 05:01:19 +00:00
|
|
|
total += west;
|
|
|
|
}
|
2013-07-17 04:40:49 +00:00
|
|
|
|
2013-09-05 17:16:01 +00:00
|
|
|
if (east >= 0)
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
++count;
|
|
|
|
total += east;
|
|
|
|
}
|
2013-07-17 04:40:49 +00:00
|
|
|
|
|
|
|
if (count == 1)
|
|
|
|
{
|
|
|
|
if (changed)
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
world.setBlockMetadataWithNotify(x, y, z, quantaRemaining - 1, 2);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2013-07-17 04:40:49 +00:00
|
|
|
|
2013-05-23 05:01:19 +00:00
|
|
|
int each = total / count;
|
|
|
|
int rem = total % count;
|
2013-07-17 04:40:49 +00:00
|
|
|
if (north >= 0)
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
int newnorth = each;
|
2013-07-17 04:40:49 +00:00
|
|
|
if (rem == count || rem > 1 && rand.nextInt(count - rem) != 0)
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
++newnorth;
|
|
|
|
--rem;
|
|
|
|
}
|
2013-07-17 04:40:49 +00:00
|
|
|
|
|
|
|
if (newnorth != north)
|
|
|
|
{
|
|
|
|
if (newnorth == 0)
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
world.setBlock(x, y, z - 1, 0);
|
2013-07-17 04:40:49 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
world.setBlock(x, y, z - 1, blockID, newnorth - 1, 2);
|
|
|
|
}
|
|
|
|
world.scheduleBlockUpdate(x, y, z - 1, blockID, tickRate);
|
|
|
|
}
|
|
|
|
--count;
|
|
|
|
}
|
|
|
|
|
2013-07-17 04:40:49 +00:00
|
|
|
if (south >= 0)
|
|
|
|
{
|
|
|
|
int newsouth = each;
|
|
|
|
if (rem == count || rem > 1 && rand.nextInt(count - rem) != 0)
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
++newsouth;
|
|
|
|
--rem;
|
|
|
|
}
|
2013-07-17 04:40:49 +00:00
|
|
|
|
|
|
|
if (newsouth != south)
|
|
|
|
{
|
|
|
|
if (newsouth == 0)
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
world.setBlock(x, y, z + 1, 0);
|
2013-07-17 04:40:49 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
world.setBlock(x, y, z + 1, blockID, newsouth - 1, 2);
|
|
|
|
}
|
|
|
|
world.scheduleBlockUpdate(x, y, z + 1, blockID, tickRate);
|
|
|
|
}
|
|
|
|
--count;
|
|
|
|
}
|
|
|
|
|
2013-07-17 04:40:49 +00:00
|
|
|
if (west >= 0)
|
|
|
|
{
|
|
|
|
int newwest = each;
|
|
|
|
if (rem == count || rem > 1 && rand.nextInt(count - rem) != 0)
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
++newwest;
|
|
|
|
--rem;
|
|
|
|
}
|
2013-09-05 17:16:01 +00:00
|
|
|
if (newwest != west)
|
|
|
|
{
|
|
|
|
if (newwest == 0)
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
world.setBlock(x - 1, y, z, 0);
|
2013-09-05 17:16:01 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
world.setBlock(x - 1, y, z, blockID, newwest - 1, 2);
|
|
|
|
}
|
|
|
|
world.scheduleBlockUpdate(x - 1, y, z, blockID, tickRate);
|
|
|
|
}
|
|
|
|
--count;
|
|
|
|
}
|
|
|
|
|
2013-07-17 04:40:49 +00:00
|
|
|
if (east >= 0)
|
|
|
|
{
|
|
|
|
int neweast = each;
|
|
|
|
if (rem == count || rem > 1 && rand.nextInt(count - rem) != 0)
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
++neweast;
|
|
|
|
--rem;
|
|
|
|
}
|
2013-07-17 04:40:49 +00:00
|
|
|
|
|
|
|
if (neweast != east)
|
|
|
|
{
|
|
|
|
if (neweast == 0)
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
world.setBlock(x + 1, y, z, 0);
|
2013-07-17 04:40:49 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
world.setBlock(x + 1, y, z, blockID, neweast - 1, 2);
|
|
|
|
}
|
|
|
|
world.scheduleBlockUpdate(x + 1, y, z, blockID, tickRate);
|
|
|
|
}
|
|
|
|
--count;
|
|
|
|
}
|
2013-07-17 04:40:49 +00:00
|
|
|
|
|
|
|
if (rem > 0)
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
++each;
|
|
|
|
}
|
|
|
|
world.setBlockMetadataWithNotify(x, y, z, each - 1, 2);
|
|
|
|
}
|
|
|
|
|
2013-07-17 04:40:49 +00:00
|
|
|
public int tryToFlowVerticallyInto(World world, int x, int y, int z, int amtToInput)
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
int otherY = y + densityDir;
|
2013-07-17 04:40:49 +00:00
|
|
|
if (otherY < 0 || otherY >= world.getHeight())
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
world.setBlockToAir(x, y, z);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-07-17 04:40:49 +00:00
|
|
|
int amt = getQuantaValueBelow(world, x, otherY, z, quantaPerBlock);
|
|
|
|
if (amt >= 0)
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
amt += amtToInput;
|
2013-07-17 04:40:49 +00:00
|
|
|
if (amt > quantaPerBlock)
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
world.setBlock(x, otherY, z, blockID, quantaPerBlock - 1, 3);
|
|
|
|
world.scheduleBlockUpdate(x, otherY, z, blockID, tickRate);
|
|
|
|
return amt - quantaPerBlock;
|
2013-07-17 04:40:49 +00:00
|
|
|
}
|
|
|
|
else if (amt > 0)
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
world.setBlock(x, otherY, z, blockID, amt - 1, 3);
|
|
|
|
world.scheduleBlockUpdate(x, otherY, z, blockID, tickRate);
|
|
|
|
world.setBlockToAir(x, y, z);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return amtToInput;
|
2013-07-17 04:40:49 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
int density_other = getDensity(world, x, otherY, z);
|
2013-07-17 04:40:49 +00:00
|
|
|
if (density_other == Integer.MAX_VALUE)
|
|
|
|
{
|
|
|
|
if (displaceIfPossible(world, x, otherY, z))
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
world.setBlock(x, otherY, z, blockID, amtToInput - 1, 3);
|
|
|
|
world.scheduleBlockUpdate(x, otherY, z, blockID, tickRate);
|
|
|
|
world.setBlockToAir(x, y, z);
|
|
|
|
return 0;
|
2013-07-17 04:40:49 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
return amtToInput;
|
|
|
|
}
|
|
|
|
}
|
2013-07-17 04:40:49 +00:00
|
|
|
|
|
|
|
if (densityDir < 0)
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
if (density_other < density) // then swap
|
|
|
|
{
|
|
|
|
int bId = world.getBlockId(x, otherY, z);
|
|
|
|
BlockFluidBase block = (BlockFluidBase) Block.blocksList[bId];
|
|
|
|
int otherData = world.getBlockMetadata(x, otherY, z);
|
|
|
|
world.setBlock(x, otherY, z, blockID, amtToInput - 1, 3);
|
|
|
|
world.setBlock(x, y, z, bId, otherData, 3);
|
|
|
|
world.scheduleBlockUpdate(x, otherY, z, blockID, tickRate);
|
|
|
|
world.scheduleBlockUpdate(x, y, z, bId, block.tickRate(world));
|
|
|
|
return 0;
|
|
|
|
}
|
2013-07-17 04:40:49 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (density_other > density)
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
int bId = world.getBlockId(x, otherY, z);
|
|
|
|
BlockFluidBase block = (BlockFluidBase) Block.blocksList[bId];
|
|
|
|
int otherData = world.getBlockMetadata(x, otherY, z);
|
|
|
|
world.setBlock(x, otherY, z, blockID, amtToInput - 1, 3);
|
|
|
|
world.setBlock(x, y, z, bId, otherData, 3);
|
|
|
|
world.scheduleBlockUpdate(x, otherY, z, blockID, tickRate);
|
|
|
|
world.scheduleBlockUpdate(x, y, z, bId, block.tickRate(world));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return amtToInput;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* IFluidBlock */
|
|
|
|
@Override
|
2013-07-17 04:40:49 +00:00
|
|
|
public FluidStack drain(World world, int x, int y, int z, boolean doDrain)
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2013-07-17 04:40:49 +00:00
|
|
|
public boolean canDrain(World world, int x, int y, int z)
|
|
|
|
{
|
2013-05-23 05:01:19 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|