blob: 030b9ac12c1423bf17221193b2d7a5f146384c6f [file] [log] [blame] [raw]
package mekanism.common.tile;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import mekanism.api.Coord4D;
import mekanism.api.Range4D;
import mekanism.common.Mekanism;
import mekanism.common.base.IFluidContainerManager;
import mekanism.common.content.tank.SynchronizedTankData;
import mekanism.common.content.tank.SynchronizedTankData.ValveData;
import mekanism.common.content.tank.TankUpdateProtocol;
import mekanism.common.multiblock.IMultiblock;
import mekanism.common.multiblock.MultiblockManager;
import mekanism.common.network.PacketTileEntity.TileEntityMessage;
import mekanism.common.util.FluidContainerUtils;
import mekanism.common.util.FluidContainerUtils.ContainerEditMode;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.FluidContainerRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidContainerItem;
import io.netty.buffer.ByteBuf;
public class TileEntityDynamicTank extends TileEntityMultiblock<SynchronizedTankData> implements IFluidContainerManager
{
/** A client-sided and server-sided map of valves on this tank's structure, used on the client for rendering fluids. */
public Map<ValveData, Integer> valveViewing = new HashMap<ValveData, Integer>();
/** The capacity this tank has on the client-side. */
public int clientCapacity;
public float prevScale;
public TileEntityDynamicTank()
{
this("DynamicTank");
}
public TileEntityDynamicTank(String name)
{
super(name);
inventory = new ItemStack[2];
}
@Override
public void onUpdate()
{
super.onUpdate();
if(worldObj.isRemote)
{
if(structure != null && clientHasStructure && isRendering)
{
for(ValveData data : valveViewing.keySet())
{
if(valveViewing.get(data) > 0)
{
valveViewing.put(data, valveViewing.get(data)-1);
}
}
float targetScale = (float)(structure.fluidStored != null ? structure.fluidStored.amount : 0)/clientCapacity;
if(Math.abs(prevScale - targetScale) > 0.01)
{
prevScale = (9*prevScale + targetScale)/10;
}
}
if(!clientHasStructure || !isRendering)
{
for(ValveData data : valveViewing.keySet())
{
TileEntityDynamicTank tileEntity = (TileEntityDynamicTank)data.location.getTileEntity(worldObj);
if(tileEntity != null)
{
tileEntity.clientHasStructure = false;
}
}
valveViewing.clear();
}
}
if(!worldObj.isRemote)
{
if(structure != null)
{
manageInventory();
}
}
}
public void manageInventory()
{
int max = structure.volume * TankUpdateProtocol.FLUID_PER_TANK;
if(structure.inventory[0] != null)
{
if(structure.inventory[0].getItem() instanceof IFluidContainerItem)
{
if(structure.editMode == ContainerEditMode.FILL && structure.fluidStored != null)
{
int prev = structure.fluidStored.amount;
structure.fluidStored.amount -= FluidContainerUtils.insertFluid(structure.fluidStored, structure.inventory[0]);
if(prev == structure.fluidStored.amount || structure.fluidStored.amount == 0)
{
if(structure.inventory[1] == null)
{
structure.inventory[1] = structure.inventory[0].copy();
structure.inventory[0] = null;
markDirty();
}
}
if(structure.fluidStored.amount == 0)
{
structure.fluidStored = null;
}
}
else if(structure.editMode == ContainerEditMode.EMPTY)
{
if(structure.fluidStored != null)
{
FluidStack received = FluidContainerUtils.extractFluid(max-structure.fluidStored.amount, structure.inventory[0], structure.fluidStored.getFluid());
if(received != null)
{
structure.fluidStored.amount += received.amount;
}
}
else {
structure.fluidStored = FluidContainerUtils.extractFluid(max, structure.inventory[0], null);
}
int newStored = structure.fluidStored != null ? structure.fluidStored.amount : 0;
if(((IFluidContainerItem)structure.inventory[0].getItem()).getFluid(structure.inventory[0]) == null || newStored == max)
{
if(structure.inventory[1] == null)
{
structure.inventory[1] = structure.inventory[0].copy();
structure.inventory[0] = null;
markDirty();
}
}
}
}
else if(FluidContainerRegistry.isEmptyContainer(structure.inventory[0]) && (structure.editMode == ContainerEditMode.BOTH || structure.editMode == ContainerEditMode.FILL))
{
if(structure.fluidStored != null && structure.fluidStored.amount >= FluidContainerRegistry.BUCKET_VOLUME)
{
ItemStack filled = FluidContainerRegistry.fillFluidContainer(structure.fluidStored, structure.inventory[0]);
if(filled != null)
{
if(structure.inventory[1] == null || (structure.inventory[1].isItemEqual(filled) && structure.inventory[1].stackSize+1 <= filled.getMaxStackSize()))
{
structure.inventory[0].stackSize--;
if(structure.inventory[0].stackSize <= 0)
{
structure.inventory[0] = null;
}
if(structure.inventory[1] == null)
{
structure.inventory[1] = filled;
}
else {
structure.inventory[1].stackSize++;
}
markDirty();
structure.fluidStored.amount -= FluidContainerRegistry.getFluidForFilledItem(filled).amount;
if(structure.fluidStored.amount == 0)
{
structure.fluidStored = null;
}
Mekanism.packetHandler.sendToReceivers(new TileEntityMessage(Coord4D.get(this), getNetworkedData(new ArrayList())), new Range4D(Coord4D.get(this)));
}
}
}
}
else if(FluidContainerRegistry.isFilledContainer(structure.inventory[0]) && (structure.editMode == ContainerEditMode.BOTH || structure.editMode == ContainerEditMode.EMPTY))
{
FluidStack itemFluid = FluidContainerRegistry.getFluidForFilledItem(structure.inventory[0]);
if((structure.fluidStored == null && itemFluid.amount <= max) || structure.fluidStored.amount+itemFluid.amount <= max)
{
if(structure.fluidStored != null && !structure.fluidStored.isFluidEqual(itemFluid))
{
return;
}
ItemStack containerItem = structure.inventory[0].getItem().getContainerItem(structure.inventory[0]);
boolean filled = false;
if(containerItem != null)
{
if(structure.inventory[1] == null || (structure.inventory[1].isItemEqual(containerItem) && structure.inventory[1].stackSize+1 <= containerItem.getMaxStackSize()))
{
structure.inventory[0] = null;
if(structure.inventory[1] == null)
{
structure.inventory[1] = containerItem;
}
else {
structure.inventory[1].stackSize++;
}
filled = true;
}
}
else {
structure.inventory[0].stackSize--;
if(structure.inventory[0].stackSize == 0)
{
structure.inventory[0] = null;
}
filled = true;
}
if(filled)
{
if(structure.fluidStored == null)
{
structure.fluidStored = itemFluid.copy();
}
else {
structure.fluidStored.amount += itemFluid.amount;
}
markDirty();
}
Mekanism.packetHandler.sendToReceivers(new TileEntityMessage(Coord4D.get(this), getNetworkedData(new ArrayList())), new Range4D(Coord4D.get(this)));
}
}
}
}
@Override
protected SynchronizedTankData getNewStructure()
{
return new SynchronizedTankData();
}
@Override
protected TankUpdateProtocol getProtocol()
{
return new TankUpdateProtocol(this);
}
@Override
public MultiblockManager<SynchronizedTankData> getManager()
{
return Mekanism.tankManager;
}
@Override
public ArrayList getNetworkedData(ArrayList data)
{
super.getNetworkedData(data);
if(structure != null)
{
data.add(structure.volume*TankUpdateProtocol.FLUID_PER_TANK);
data.add(structure.editMode.ordinal());
}
if(structure != null && structure.fluidStored != null)
{
data.add(1);
data.add(structure.fluidStored.fluidID);
data.add(structure.fluidStored.amount);
}
else {
data.add(0);
}
if(structure != null && isRendering)
{
data.add(structure.valves.size());
for(ValveData valveData : structure.valves)
{
valveData.location.write(data);
data.add(valveData.side.ordinal());
data.add(valveData.serverFluid);
}
}
return data;
}
@Override
public void handlePacketData(ByteBuf dataStream)
{
super.handlePacketData(dataStream);
if(clientHasStructure)
{
clientCapacity = dataStream.readInt();
structure.editMode = ContainerEditMode.values()[dataStream.readInt()];
}
if(dataStream.readInt() == 1)
{
structure.fluidStored = new FluidStack(dataStream.readInt(), dataStream.readInt());
}
else {
structure.fluidStored = null;
}
if(clientHasStructure && isRendering)
{
int size = dataStream.readInt();
for(int i = 0; i < size; i++)
{
ValveData data = new ValveData();
data.location = Coord4D.read(dataStream);
data.side = ForgeDirection.getOrientation(dataStream.readInt());
int viewingTicks = 0;
if(dataStream.readBoolean())
{
viewingTicks = 30;
}
if(viewingTicks == 0)
{
if(valveViewing.containsKey(data) && valveViewing.get(data) > 0)
{
continue;
}
}
valveViewing.put(data, viewingTicks);
TileEntityDynamicTank tileEntity = (TileEntityDynamicTank)data.location.getTileEntity(worldObj);
if(tileEntity != null)
{
tileEntity.clientHasStructure = true;
}
}
}
}
public int getScaledFluidLevel(int i)
{
if(clientCapacity == 0 || structure.fluidStored == null)
{
return 0;
}
return structure.fluidStored.amount*i / clientCapacity;
}
@Override
public ContainerEditMode getContainerEditMode()
{
if(structure != null)
{
return structure.editMode;
}
return ContainerEditMode.BOTH;
}
@Override
public void setContainerEditMode(ContainerEditMode mode)
{
if(structure == null)
{
return;
}
structure.editMode = mode;
}
}