mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-13 00:37:52 +00:00
MinecraftForge/FML@03fb1879d7 Fix obf error when right clicking a Empty Map. MinecraftForge/FML@6bb9b8b953 Clean up FMLEventChannel. Closes #367. MinecraftForge/FML@b7b3450dcd Update MCP mapping snapshot to latest crowdsourced names. MinecraftForge/FML@8c9e8b5270 Fix isRemote, this is integral to so many parts of the code, everyone knows it by this name, People should not change it.
324 lines
9.3 KiB
Java
324 lines
9.3 KiB
Java
|
|
package net.minecraftforge.fluids;
|
|
|
|
import java.util.Random;
|
|
|
|
import net.minecraft.block.material.Material;
|
|
import net.minecraft.init.Blocks;
|
|
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
|
|
*
|
|
*/
|
|
public class BlockFluidFinite extends BlockFluidBase
|
|
{
|
|
public BlockFluidFinite(Fluid fluid, Material material)
|
|
{
|
|
super(fluid, material);
|
|
}
|
|
|
|
@Override
|
|
public int getQuantaValue(IBlockAccess world, int x, int y, int z)
|
|
{
|
|
if (world.getBlock(x, y, z).isAir(world, x, y, z))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (world.getBlock(x, y, z) != this)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
int quantaRemaining = world.getBlockMetadata(x, y, z) + 1;
|
|
return quantaRemaining;
|
|
}
|
|
|
|
@Override
|
|
public boolean canCollideCheck(int meta, boolean fullHit)
|
|
{
|
|
return fullHit && meta == quantaPerBlock - 1;
|
|
}
|
|
|
|
@Override
|
|
public int getMaxRenderHeightMeta()
|
|
{
|
|
return quantaPerBlock - 1;
|
|
}
|
|
|
|
@Override
|
|
public void updateTick(World world, int x, int y, int z, Random rand)
|
|
{
|
|
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);
|
|
|
|
if (quantaRemaining < 1)
|
|
{
|
|
return;
|
|
}
|
|
else if (quantaRemaining != prevRemaining)
|
|
{
|
|
changed = true;
|
|
if (quantaRemaining == 1)
|
|
{
|
|
world.setBlockMetadataWithNotify(x, y, z, quantaRemaining - 1, 2);
|
|
return;
|
|
}
|
|
}
|
|
else if (quantaRemaining == 1)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Flow out if possible
|
|
int lowerthan = quantaRemaining - 1;
|
|
if (displaceIfPossible(world, x, y, z - 1)) world.setBlock(x, y, z - 1, Blocks.air);
|
|
if (displaceIfPossible(world, x, y, z + 1)) world.setBlock(x, y, z + 1, Blocks.air);
|
|
if (displaceIfPossible(world, x - 1, y, z )) world.setBlock(x - 1, y, z, Blocks.air);
|
|
if (displaceIfPossible(world, x + 1, y, z )) world.setBlock(x + 1, y, z, Blocks.air);
|
|
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);
|
|
int total = quantaRemaining;
|
|
int count = 1;
|
|
|
|
if (north >= 0)
|
|
{
|
|
count++;
|
|
total += north;
|
|
}
|
|
|
|
if (south >= 0)
|
|
{
|
|
count++;
|
|
total += south;
|
|
}
|
|
|
|
if (west >= 0)
|
|
{
|
|
count++;
|
|
total += west;
|
|
}
|
|
|
|
if (east >= 0)
|
|
{
|
|
++count;
|
|
total += east;
|
|
}
|
|
|
|
if (count == 1)
|
|
{
|
|
if (changed)
|
|
{
|
|
world.setBlockMetadataWithNotify(x, y, z, quantaRemaining - 1, 2);
|
|
}
|
|
return;
|
|
}
|
|
|
|
int each = total / count;
|
|
int rem = total % count;
|
|
if (north >= 0)
|
|
{
|
|
int newnorth = each;
|
|
if (rem == count || rem > 1 && rand.nextInt(count - rem) != 0)
|
|
{
|
|
++newnorth;
|
|
--rem;
|
|
}
|
|
|
|
if (newnorth != north)
|
|
{
|
|
if (newnorth == 0)
|
|
{
|
|
world.setBlock(x, y, z - 1, Blocks.air);
|
|
}
|
|
else
|
|
{
|
|
world.setBlock(x, y, z - 1, this, newnorth - 1, 2);
|
|
}
|
|
world.scheduleBlockUpdate(x, y, z - 1, this, tickRate);
|
|
}
|
|
--count;
|
|
}
|
|
|
|
if (south >= 0)
|
|
{
|
|
int newsouth = each;
|
|
if (rem == count || rem > 1 && rand.nextInt(count - rem) != 0)
|
|
{
|
|
++newsouth;
|
|
--rem;
|
|
}
|
|
|
|
if (newsouth != south)
|
|
{
|
|
if (newsouth == 0)
|
|
{
|
|
world.setBlock(x, y, z + 1, Blocks.air);
|
|
}
|
|
else
|
|
{
|
|
world.setBlock(x, y, z + 1, this, newsouth - 1, 2);
|
|
}
|
|
world.scheduleBlockUpdate(x, y, z + 1, this, tickRate);
|
|
}
|
|
--count;
|
|
}
|
|
|
|
if (west >= 0)
|
|
{
|
|
int newwest = each;
|
|
if (rem == count || rem > 1 && rand.nextInt(count - rem) != 0)
|
|
{
|
|
++newwest;
|
|
--rem;
|
|
}
|
|
if (newwest != west)
|
|
{
|
|
if (newwest == 0)
|
|
{
|
|
world.setBlock(x - 1, y, z, Blocks.air);
|
|
}
|
|
else
|
|
{
|
|
world.setBlock(x - 1, y, z, this, newwest - 1, 2);
|
|
}
|
|
world.scheduleBlockUpdate(x - 1, y, z, this, tickRate);
|
|
}
|
|
--count;
|
|
}
|
|
|
|
if (east >= 0)
|
|
{
|
|
int neweast = each;
|
|
if (rem == count || rem > 1 && rand.nextInt(count - rem) != 0)
|
|
{
|
|
++neweast;
|
|
--rem;
|
|
}
|
|
|
|
if (neweast != east)
|
|
{
|
|
if (neweast == 0)
|
|
{
|
|
world.setBlock(x + 1, y, z, Blocks.air);
|
|
}
|
|
else
|
|
{
|
|
world.setBlock(x + 1, y, z, this, neweast - 1, 2);
|
|
}
|
|
world.scheduleBlockUpdate(x + 1, y, z, this, tickRate);
|
|
}
|
|
--count;
|
|
}
|
|
|
|
if (rem > 0)
|
|
{
|
|
++each;
|
|
}
|
|
world.setBlockMetadataWithNotify(x, y, z, each - 1, 2);
|
|
}
|
|
|
|
public int tryToFlowVerticallyInto(World world, int x, int y, int z, int amtToInput)
|
|
{
|
|
int otherY = y + densityDir;
|
|
if (otherY < 0 || otherY >= world.getHeight())
|
|
{
|
|
world.setBlock(x, y, z, Blocks.air);
|
|
return 0;
|
|
}
|
|
|
|
int amt = getQuantaValueBelow(world, x, otherY, z, quantaPerBlock);
|
|
if (amt >= 0)
|
|
{
|
|
amt += amtToInput;
|
|
if (amt > quantaPerBlock)
|
|
{
|
|
world.setBlock(x, otherY, z, this, quantaPerBlock - 1, 3);
|
|
world.scheduleBlockUpdate(x, otherY, z, this, tickRate);
|
|
return amt - quantaPerBlock;
|
|
}
|
|
else if (amt > 0)
|
|
{
|
|
world.setBlock(x, otherY, z, this, amt - 1, 3);
|
|
world.scheduleBlockUpdate(x, otherY, z, this, tickRate);
|
|
world.setBlock(x, y, z, Blocks.air);
|
|
return 0;
|
|
}
|
|
return amtToInput;
|
|
}
|
|
else
|
|
{
|
|
int density_other = getDensity(world, x, otherY, z);
|
|
if (density_other == Integer.MAX_VALUE)
|
|
{
|
|
if (displaceIfPossible(world, x, otherY, z))
|
|
{
|
|
world.setBlock(x, otherY, z, this, amtToInput - 1, 3);
|
|
world.scheduleBlockUpdate(x, otherY, z, this, tickRate);
|
|
world.setBlock(x, y, z, Blocks.air);
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
return amtToInput;
|
|
}
|
|
}
|
|
|
|
if (densityDir < 0)
|
|
{
|
|
if (density_other < density) // then swap
|
|
{
|
|
BlockFluidBase block = (BlockFluidBase)world.getBlock(x, otherY, z);
|
|
int otherData = world.getBlockMetadata(x, otherY, z);
|
|
world.setBlock(x, otherY, z, this, amtToInput - 1, 3);
|
|
world.setBlock(x, y, z, block, otherData, 3);
|
|
world.scheduleBlockUpdate(x, otherY, z, this, tickRate);
|
|
world.scheduleBlockUpdate(x, y, z, block, block.tickRate(world));
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (density_other > density)
|
|
{
|
|
BlockFluidBase block = (BlockFluidBase)world.getBlock(x, otherY, z);
|
|
int otherData = world.getBlockMetadata(x, otherY, z);
|
|
world.setBlock(x, otherY, z, this, amtToInput - 1, 3);
|
|
world.setBlock(x, y, z, block, otherData, 3);
|
|
world.scheduleBlockUpdate(x, otherY, z, this, tickRate);
|
|
world.scheduleBlockUpdate(x, y, z, block, block.tickRate(world));
|
|
return 0;
|
|
}
|
|
}
|
|
return amtToInput;
|
|
}
|
|
}
|
|
|
|
/* IFluidBlock */
|
|
@Override
|
|
public FluidStack drain(World world, int x, int y, int z, boolean doDrain)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public boolean canDrain(World world, int x, int y, int z)
|
|
{
|
|
return false;
|
|
}
|
|
@Override public Fluid getFluid() { return null; }
|
|
@Override public float getFilledPercentage(World world, int x, int y, int z) { return 0; }
|
|
}
|