package pneumaticCraft.common.tileentity; import java.util.ArrayList; import java.util.List; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTank; import net.minecraftforge.fluids.FluidTankInfo; import net.minecraftforge.fluids.IFluidHandler; import pneumaticCraft.api.IHeatExchangerLogic; import pneumaticCraft.api.PneumaticRegistry; import pneumaticCraft.api.tileentity.IHeatExchanger; import pneumaticCraft.common.fluid.Fluids; import pneumaticCraft.common.network.DescSynced; import pneumaticCraft.common.network.GuiSynced; import pneumaticCraft.common.network.LazySynced; import pneumaticCraft.common.network.NetworkHandler; import pneumaticCraft.common.network.PacketSpawnParticle; import pneumaticCraft.lib.PneumaticValues; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; public class TileEntityRefinery extends TileEntityBase implements IFluidHandler, IHeatExchanger, IRedstoneControlled, IComparatorSupport{ @GuiSynced @DescSynced @LazySynced private final FluidTank oilTank = new FluidTank(PneumaticValues.NORMAL_TANK_CAPACITY); @GuiSynced @DescSynced @LazySynced private final FluidTank outputTank = new FluidTank(PneumaticValues.NORMAL_TANK_CAPACITY); @GuiSynced private final IHeatExchangerLogic heatExchanger = PneumaticRegistry.getInstance().getHeatExchangerLogic(); @DescSynced private int oilTankAmount, outputTankAmount;//amount divided by 100 to decrease network load. @GuiSynced private int redstoneMode; private int workTimer = 0; private int comparatorValue; /** * The amounts of LPG, Gasoline, Kerosine and Diesel produced per 10mL Oil, depending on how many refineries are stacked on top of eachother. * Type \ Refineries | 2 | 3 | 4 * ------------------------------ * LPG | 2 | 2 | 2 * Gasoline | - | - | 3 * Kerosine | - | 3 | 3 * Diesel | 4 | 2 | 2 */ public static final int[][] REFINING_TABLE = new int[][]{{4, 0, 0, 2}, {2, 3, 0, 2}, {2, 3, 3, 2}}; private final Fluid[] refiningFluids = getRefiningFluids(); public TileEntityRefinery(){ // setUpgradeSlots(0, 1, 2, 3); } public static Fluid[] getRefiningFluids(){ return new Fluid[]{Fluids.diesel, Fluids.kerosene, Fluids.gasoline, Fluids.lpg}; } @Override public void updateEntity(){ super.updateEntity(); if(!worldObj.isRemote) { oilTankAmount = oilTank.getFluidAmount() / 100; outputTankAmount = outputTank.getFluidAmount() / 100; if(isMaster()) { List<TileEntityRefinery> refineries = getRefineries(); if(redstoneAllows() && oilTank.getFluidAmount() >= 10) { if(refineries.size() > 1 && refineries.size() <= refiningFluids.length && refine(refineries, true)) { int progress = Math.max(0, ((int)heatExchanger.getTemperature() - 343) / 30); progress = Math.min(5, progress); heatExchanger.addHeat(-progress * 1); workTimer += progress; while(workTimer >= 20 && oilTank.getFluidAmount() >= 10) { workTimer -= 20; refine(refineries, false); oilTank.drain(10, true); for(int i = 0; i < 5; i++) NetworkHandler.sendToAllAround(new PacketSpawnParticle("largesmoke", xCoord + worldObj.rand.nextDouble(), yCoord + refineries.size(), zCoord + worldObj.rand.nextDouble(), 0, 0, 0), worldObj); } } else { workTimer = 0; } } updateComparatorValue(refineries); } } } private List<TileEntityRefinery> getRefineries(){ List<TileEntityRefinery> refineries = new ArrayList<TileEntityRefinery>(); refineries.add(this); TileEntityRefinery refinery = this; while(refinery.getTileCache()[ForgeDirection.UP.ordinal()].getTileEntity() instanceof TileEntityRefinery) { refinery = (TileEntityRefinery)refinery.getTileCache()[ForgeDirection.UP.ordinal()].getTileEntity(); refineries.add(refinery); } return refineries; } public boolean refine(List<TileEntityRefinery> refineries, boolean simulate){ int[] outputTable = REFINING_TABLE[refineries.size() - 2]; int i = 0; for(TileEntityRefinery refinery : refineries) { while(outputTable[i] == 0) i++; if(outputTable[i] != refinery.outputTank.fill(new FluidStack(refiningFluids[i], outputTable[i]), !simulate)) return false; i++; } return true; } public TileEntityRefinery getMasterRefinery(){ TileEntityRefinery master = this; while(master.getTileCache()[ForgeDirection.DOWN.ordinal()].getTileEntity() instanceof TileEntityRefinery) { master = (TileEntityRefinery)master.getTileCache()[ForgeDirection.DOWN.ordinal()].getTileEntity(); } return master; } private boolean isMaster(){ return getMasterRefinery() == this; } @Override public boolean redstoneAllows(){ if(worldObj.isRemote) onNeighborBlockUpdate(); boolean isPoweredByRedstone = poweredRedstone > 0; TileEntityRefinery refinery = this; while(poweredRedstone == 0 && refinery.getTileCache()[ForgeDirection.UP.ordinal()].getTileEntity() instanceof TileEntityRefinery) { refinery = (TileEntityRefinery)refinery.getTileCache()[ForgeDirection.UP.ordinal()].getTileEntity(); refinery.onNeighborBlockUpdate(); isPoweredByRedstone = refinery.poweredRedstone > 0; } switch(((IRedstoneControl)this).getRedstoneMode()){ case 0: return true; case 1: return isPoweredByRedstone; case 2: return !isPoweredByRedstone; } return false; } @Override public int fill(ForgeDirection from, FluidStack resource, boolean doFill){ if(canFill(from, resource != null ? resource.getFluid() : null)) { if(isMaster()) { return oilTank.fill(resource, doFill); } else { return getMasterRefinery().fill(from, resource, doFill); } } else { return 0; } } @Override public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain){ return outputTank.getFluid() != null && outputTank.getFluid().isFluidEqual(resource) ? outputTank.drain(resource.amount, doDrain) : null; } @Override public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain){ return outputTank.drain(maxDrain, doDrain); } @Override public boolean canFill(ForgeDirection from, Fluid fluid){ return Fluids.areFluidsEqual(fluid, Fluids.oil); } @Override public boolean canDrain(ForgeDirection from, Fluid fluid){ return true; } @Override public FluidTankInfo[] getTankInfo(ForgeDirection from){ return new FluidTankInfo[]{new FluidTankInfo(getMasterRefinery().oilTank), new FluidTankInfo(outputTank)}; } @SideOnly(Side.CLIENT) public FluidTank getOilTank(){ return oilTank; } @SideOnly(Side.CLIENT) public FluidTank getOutputTank(){ return outputTank; } @Override public void writeToNBT(NBTTagCompound tag){ super.writeToNBT(tag); NBTTagCompound tankTag = new NBTTagCompound(); oilTank.writeToNBT(tankTag); tag.setTag("oilTank", tankTag); tankTag = new NBTTagCompound(); outputTank.writeToNBT(tankTag); tag.setTag("outputTank", tankTag); tag.setByte("redstoneMode", (byte)redstoneMode); } @Override public void readFromNBT(NBTTagCompound tag){ super.readFromNBT(tag); oilTank.readFromNBT(tag.getCompoundTag("oilTank")); outputTank.readFromNBT(tag.getCompoundTag("outputTank")); redstoneMode = tag.getByte("redstoneMode"); } @Override public IHeatExchangerLogic getHeatExchangerLogic(ForgeDirection side){ return heatExchanger; } @Override public int getRedstoneMode(){ return redstoneMode; } @Override public void handleGUIButtonPress(int buttonID, EntityPlayer player){ if(buttonID == 0) { redstoneMode++; if(redstoneMode > 2) redstoneMode = 0; } } public void updateComparatorValue(List<TileEntityRefinery> refineries){ int value; if(oilTank.getFluidAmount() < 10 || refineries.size() < 2 || refineries.size() > refiningFluids.length) { value = 0; } else { value = refine(refineries, true) ? 15 : 0; } if(value != comparatorValue) { comparatorValue = value; updateNeighbours(); } } @Override public int getComparatorValue(ForgeDirection side){ return getMasterRefinery().comparatorValue; } }