321 lines
8 KiB
Java
321 lines
8 KiB
Java
/**
|
|
* Copyright (c) 2011-2017, SpaceToad and the BuildCraft Team
|
|
* http://www.mod-buildcraft.com
|
|
* <p/>
|
|
* BuildCraft is distributed under the terms of the Minecraft Mod Public
|
|
* License 1.0, or MMPL. Please check the contents of the license located in
|
|
* http://www.mod-buildcraft.com/MMPL-1.0.txt
|
|
*/
|
|
package buildcraft.factory;
|
|
|
|
import io.netty.buffer.ByteBuf;
|
|
|
|
import net.minecraft.nbt.NBTTagCompound;
|
|
import net.minecraft.tileentity.TileEntity;
|
|
import net.minecraft.world.EnumSkyBlock;
|
|
|
|
import net.minecraftforge.common.util.ForgeDirection;
|
|
import net.minecraftforge.fluids.Fluid;
|
|
import net.minecraftforge.fluids.FluidContainerRegistry;
|
|
import net.minecraftforge.fluids.FluidEvent;
|
|
import net.minecraftforge.fluids.FluidStack;
|
|
import net.minecraftforge.fluids.FluidTank;
|
|
import net.minecraftforge.fluids.FluidTankInfo;
|
|
import net.minecraftforge.fluids.IFluidHandler;
|
|
|
|
import buildcraft.BuildCraftCore;
|
|
import buildcraft.api.core.SafeTimeTracker;
|
|
import buildcraft.core.lib.block.TileBuildCraft;
|
|
import buildcraft.core.lib.fluids.Tank;
|
|
import buildcraft.core.lib.fluids.TankManager;
|
|
import buildcraft.core.lib.utils.BlockUtils;
|
|
|
|
public class TileTank extends TileBuildCraft implements IFluidHandler {
|
|
public final Tank tank = new Tank("tank", FluidContainerRegistry.BUCKET_VOLUME * 16, this);
|
|
public final TankManager<Tank> tankManager = new TankManager<Tank>(tank);
|
|
public boolean hasUpdate = false;
|
|
public boolean hasNetworkUpdate = false;
|
|
public SafeTimeTracker tracker = new SafeTimeTracker(2 * BuildCraftCore.updateFactor);
|
|
private int prevLightValue = 0;
|
|
private int cachedComparatorOverride = 0;
|
|
|
|
@Override
|
|
public void initialize() {
|
|
super.initialize();
|
|
updateComparators();
|
|
}
|
|
|
|
protected void updateComparators() {
|
|
int co = calculateComparatorInputOverride();
|
|
TileTank uTank = getBottomTank();
|
|
while (uTank != null) {
|
|
uTank.cachedComparatorOverride = co;
|
|
uTank.hasUpdate = true;
|
|
uTank = getTankAbove(uTank);
|
|
}
|
|
}
|
|
|
|
protected void onBlockBreak() {
|
|
if (!tank.isEmpty()) {
|
|
FluidEvent.fireEvent(new FluidEvent.FluidSpilledEvent(
|
|
tank.getFluid(),
|
|
worldObj, xCoord, yCoord, zCoord
|
|
));
|
|
}
|
|
}
|
|
|
|
/* UPDATING */
|
|
@Override
|
|
public void updateEntity() {
|
|
super.updateEntity();
|
|
|
|
if (worldObj.isRemote) {
|
|
int lightValue = getFluidLightLevel();
|
|
if (prevLightValue != lightValue) {
|
|
prevLightValue = lightValue;
|
|
worldObj.updateLightByType(EnumSkyBlock.Block, xCoord, yCoord, zCoord);
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Have liquid flow down into tanks below if any.
|
|
if (tank.getFluid() != null) {
|
|
moveFluidBelow();
|
|
}
|
|
|
|
if (hasUpdate) {
|
|
BlockUtils.onComparatorUpdate(worldObj, xCoord, yCoord, zCoord, getBlockType());
|
|
hasUpdate = false;
|
|
}
|
|
|
|
if (hasNetworkUpdate && tracker.markTimeIfDelay(worldObj)) {
|
|
sendNetworkUpdate();
|
|
hasNetworkUpdate = false;
|
|
}
|
|
}
|
|
|
|
/* NETWORK */
|
|
@Override
|
|
public void writeData(ByteBuf data) {
|
|
tankManager.writeData(data);
|
|
}
|
|
|
|
@Override
|
|
public void readData(ByteBuf stream) {
|
|
tankManager.readData(stream);
|
|
}
|
|
|
|
/* SAVING & LOADING */
|
|
@Override
|
|
public void readFromNBT(NBTTagCompound data) {
|
|
super.readFromNBT(data);
|
|
tankManager.readFromNBT(data);
|
|
}
|
|
|
|
@Override
|
|
public void writeToNBT(NBTTagCompound data) {
|
|
super.writeToNBT(data);
|
|
tankManager.writeToNBT(data);
|
|
}
|
|
|
|
/* HELPER FUNCTIONS */
|
|
|
|
/**
|
|
* @return Last tank block below this one or this one if it is the last.
|
|
*/
|
|
public TileTank getBottomTank() {
|
|
|
|
TileTank lastTank = this;
|
|
|
|
while (true) {
|
|
TileTank below = getTankBelow(lastTank);
|
|
if (below != null) {
|
|
lastTank = below;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return lastTank;
|
|
}
|
|
|
|
public TileTank getTopTank() {
|
|
TileTank lastTank = this;
|
|
|
|
while (true) {
|
|
TileTank above = getTankAbove(lastTank);
|
|
if (above != null) {
|
|
lastTank = above;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return lastTank;
|
|
}
|
|
|
|
public static TileTank getTankBelow(TileTank tile) {
|
|
TileEntity below = tile.getTile(ForgeDirection.DOWN);
|
|
if (below instanceof TileTank) {
|
|
return (TileTank) below;
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public static TileTank getTankAbove(TileTank tile) {
|
|
TileEntity above = tile.getTile(ForgeDirection.UP);
|
|
if (above instanceof TileTank) {
|
|
return (TileTank) above;
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public void moveFluidBelow() {
|
|
TileTank below = getTankBelow(this);
|
|
if (below == null) {
|
|
return;
|
|
}
|
|
|
|
int oldComparator = getComparatorInputOverride();
|
|
int used = below.tank.fill(tank.getFluid(), true);
|
|
|
|
if (used > 0) {
|
|
hasNetworkUpdate = true; // not redundant because tank.drain operates on an IFluidTank, not a tile
|
|
below.hasNetworkUpdate = true; // redundant because below.fill sets hasUpdate
|
|
|
|
if (oldComparator != calculateComparatorInputOverride()) {
|
|
updateComparators();
|
|
}
|
|
|
|
tank.drain(used, true);
|
|
}
|
|
}
|
|
|
|
/* ITANKCONTAINER */
|
|
@Override
|
|
public int fill(ForgeDirection from, FluidStack resource, boolean doFill) {
|
|
if (resource == null) {
|
|
return 0;
|
|
}
|
|
|
|
FluidStack resourceCopy = resource.copy();
|
|
int totalUsed = 0;
|
|
TileTank tankToFill = getBottomTank();
|
|
|
|
FluidStack liquid = tankToFill.tank.getFluid();
|
|
if (liquid != null && liquid.amount > 0 && !liquid.isFluidEqual(resourceCopy)) {
|
|
return 0;
|
|
}
|
|
|
|
int oldComparator = getComparatorInputOverride();
|
|
|
|
while (tankToFill != null && resourceCopy.amount > 0) {
|
|
int used = tankToFill.tank.fill(resourceCopy, doFill);
|
|
resourceCopy.amount -= used;
|
|
if (used > 0) {
|
|
tankToFill.hasNetworkUpdate = true;
|
|
}
|
|
|
|
totalUsed += used;
|
|
tankToFill = getTankAbove(tankToFill);
|
|
}
|
|
|
|
if (oldComparator != calculateComparatorInputOverride()) {
|
|
updateComparators();
|
|
}
|
|
|
|
return totalUsed;
|
|
}
|
|
|
|
@Override
|
|
public FluidStack drain(ForgeDirection from, int maxEmpty, boolean doDrain) {
|
|
TileTank bottom = getBottomTank();
|
|
bottom.hasNetworkUpdate = true;
|
|
int oldComparator = getComparatorInputOverride();
|
|
FluidStack output = bottom.tank.drain(maxEmpty, doDrain);
|
|
|
|
if (oldComparator != calculateComparatorInputOverride()) {
|
|
updateComparators();
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
@Override
|
|
public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) {
|
|
if (resource == null) {
|
|
return null;
|
|
}
|
|
TileTank bottom = getBottomTank();
|
|
if (!resource.isFluidEqual(bottom.tank.getFluid())) {
|
|
return null;
|
|
}
|
|
return drain(from, resource.amount, doDrain);
|
|
}
|
|
|
|
@Override
|
|
public FluidTankInfo[] getTankInfo(ForgeDirection direction) {
|
|
FluidTank compositeTank = new FluidTank(tank.getCapacity());
|
|
|
|
TileTank tile = getBottomTank();
|
|
|
|
if (tile != null && tile.tank.getFluid() != null) {
|
|
compositeTank.setFluid(tile.tank.getFluid().copy());
|
|
} else {
|
|
return new FluidTankInfo[]{compositeTank.getInfo()};
|
|
}
|
|
|
|
int capacity = tile.tank.getCapacity();
|
|
tile = getTankAbove(tile);
|
|
|
|
while (tile != null) {
|
|
FluidStack liquid = tile.tank.getFluid();
|
|
if (liquid == null || liquid.amount == 0) {
|
|
// NOOP
|
|
} else if (!compositeTank.getFluid().isFluidEqual(liquid)) {
|
|
break;
|
|
} else {
|
|
compositeTank.getFluid().amount += liquid.amount;
|
|
}
|
|
|
|
capacity += tile.tank.getCapacity();
|
|
tile = getTankAbove(tile);
|
|
}
|
|
|
|
compositeTank.setCapacity(capacity);
|
|
return new FluidTankInfo[]{compositeTank.getInfo()};
|
|
}
|
|
|
|
@Override
|
|
public boolean canFill(ForgeDirection from, Fluid fluid) {
|
|
Fluid tankFluid = getBottomTank().tank.getFluidType();
|
|
return tankFluid == null || tankFluid == fluid;
|
|
}
|
|
|
|
@Override
|
|
public boolean canDrain(ForgeDirection from, Fluid fluid) {
|
|
Fluid tankFluid = getBottomTank().tank.getFluidType();
|
|
return tankFluid != null && tankFluid == fluid;
|
|
}
|
|
|
|
public int getFluidLightLevel() {
|
|
FluidStack tankFluid = tank.getFluid();
|
|
return tankFluid == null || tankFluid.amount == 0 ? 0 : tankFluid.getFluid().getLuminosity(tankFluid);
|
|
}
|
|
|
|
public int calculateComparatorInputOverride() {
|
|
FluidTankInfo[] info = getTankInfo(ForgeDirection.UNKNOWN);
|
|
if (info.length > 0 && info[0] != null && info[0].fluid != null) {
|
|
return info[0].fluid.amount * 15 / info[0].capacity;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
public int getComparatorInputOverride() {
|
|
return cachedComparatorOverride;
|
|
}
|
|
}
|