buildcraftAdditions.tileEntities.TileCoolingTower.java Source code

Java tutorial

Introduction

Here is the source code for buildcraftAdditions.tileEntities.TileCoolingTower.java

Source

package buildcraftAdditions.tileEntities;

import java.util.EnumSet;
import java.util.Set;

import com.google.common.collect.ImmutableSet;

import io.netty.buffer.ByteBuf;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;

import net.minecraftforge.common.util.Constants;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidHandler;

import buildcraft.api.fuels.ICoolant;
import buildcraft.api.transport.IPipeConnection;
import buildcraft.api.transport.IPipeTile;
import buildcraft.energy.fuels.CoolantManager;

import buildcraftAdditions.BuildcraftAdditions;
import buildcraftAdditions.api.networking.ISynchronizedTile;
import buildcraftAdditions.api.recipe.BCARecipeManager;
import buildcraftAdditions.api.recipe.refinery.ICoolingTowerRecipe;
import buildcraftAdditions.config.ConfigurationHandler;
import buildcraftAdditions.multiBlocks.IMultiBlockTile;
import buildcraftAdditions.reference.Variables;
import buildcraftAdditions.reference.enums.EnumMachineUpgrades;
import buildcraftAdditions.tileEntities.Bases.TileBase;
import buildcraftAdditions.tileEntities.interfaces.IUpgradableMachine;
import buildcraftAdditions.tileEntities.varHelpers.MultiBlockData;
import buildcraftAdditions.tileEntities.varHelpers.Upgrades;
import buildcraftAdditions.utils.Location;
import buildcraftAdditions.utils.Utils;
import buildcraftAdditions.utils.fluids.CoolantTank;
import buildcraftAdditions.utils.fluids.CoolingRecipeTank;
import buildcraftAdditions.utils.fluids.ITankHolder;
import buildcraftAdditions.utils.fluids.Tank;

/**
 * Copyright (c) 2014-2015, AEnterprise
 * http://buildcraftadditions.wordpress.com/
 * Buildcraft Additions is distributed under the terms of GNU GPL v3.0
 * Please check the contents of the license located in
 * http://buildcraftadditions.wordpress.com/wiki/licensing-stuff/
 */
public class TileCoolingTower extends TileBase implements IMultiBlockTile, IFluidHandler, ITankHolder,
        ISynchronizedTile, IPipeConnection, IUpgradableMachine {
    public final Tank input = new CoolingRecipeTank("input", 2000, this);
    public final Tank output = new Tank(2000, this, "output");
    public final Tank coolant = new CoolantTank("coolant", 10000, this);
    private final MultiBlockData data = new MultiBlockData().setPatern(Variables.Paterns.COOLING_TOWER);
    private final Upgrades upgrades = new Upgrades(0);
    public int tank;
    public boolean valve;
    public float heat;
    private TileCoolingTower master;
    private ICoolingTowerRecipe recipe;

    @Override
    public void updateEntity() {
        super.updateEntity();
        if (data.moved) {
            data.afterMoveCheck(worldObj);
            worldObj.scheduleBlockUpdate(xCoord, yCoord, zCoord, worldObj.getBlock(xCoord, yCoord, zCoord), 80);
        }
        if (master == null && !isMaster())
            findMaster();
        if (master == null && !isMaster())
            return;
        if (valve && upgrades.hasUpgrade(EnumMachineUpgrades.AUTO_OUTPUT)) {
            for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS) {
                Location location = new Location(this).move(direction);
                TileEntity entity = location.getTileEntity();
                if (entity != null && entity instanceof IFluidHandler && !(entity instanceof TileCoolingTower)
                        && master.output.getFluidType() != null) {
                    IFluidHandler tank = (IFluidHandler) entity;
                    int drain = tank.fill(direction.getOpposite(), new FluidStack(master.output.getFluidType(),
                            ConfigurationHandler.coolingTowerAutoExportMaxTransfer), false);
                    FluidStack stack = master.drain(drain, true, 1);
                    tank.fill(direction.getOpposite(), stack, true);
                }
            }
        }
        if (valve && upgrades.hasUpgrade(EnumMachineUpgrades.AUTO_IMPORT)) {
            if (master == null)
                findMaster();
            if (master == null)
                return;
            for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS) {
                Location location = new Location(this).move(direction);
                TileEntity tile = location.getTileEntity();
                if (tile != null && tile instanceof IFluidHandler) {
                    IFluidHandler tank = (IFluidHandler) tile;
                    FluidStack drain = tank.drain(direction.getOpposite(),
                            ConfigurationHandler.coolingTowerAutoImportMaxTransfer, false);
                    int fill = fill(direction.getOpposite(), drain, true);
                    if (fill > 0) {
                        tank.drain(direction.getOpposite(), fill, true);
                    }
                }
            }
        }
        if (!isMaster())
            return;
        if (input.getFluid() != null && input.getFluid().amount <= 0)
            input.setFluid(null);
        if (output.getFluid() != null && output.getFluid().amount <= 0)
            output.setFluid(null);
        while (!coolant.isEmpty() && heat > 0) {
            ICoolant cooling = CoolantManager.INSTANCE.getCoolant(coolant.getFluid().getFluid());
            if (cooling == null)
                break;
            coolant.drain(1, true);
            float factor = 1;
            if (upgrades.hasUpgrade(EnumMachineUpgrades.EFFICIENCY_1))
                factor += ConfigurationHandler.coolingTowerEfficiency1CoolingModifier;
            if (upgrades.hasUpgrade(EnumMachineUpgrades.EFFICIENCY_2))
                factor += ConfigurationHandler.coolingTowerEfficiency2CoolingModifier;
            if (upgrades.hasUpgrade(EnumMachineUpgrades.EFFICIENCY_3))
                factor += ConfigurationHandler.coolingTowerEfficiency3CoolingModifier;
            heat -= cooling.getDegreesCoolingPerMB(heat) * factor;
        }
        int count = 1;
        if (upgrades.hasUpgrade(EnumMachineUpgrades.SPEED_1))
            count += ConfigurationHandler.coolingTowerSpeed1SpeedModifier;
        if (upgrades.hasUpgrade(EnumMachineUpgrades.SPEED_2))
            count += ConfigurationHandler.coolingTowerSpeed2SpeedModifier;
        if (upgrades.hasUpgrade(EnumMachineUpgrades.SPEED_3))
            count += ConfigurationHandler.coolingTowerSpeed3SpeedModifier;
        for (int i = 0; i < count; i++) {
            if (heat > 80 || recipe == null || output.isFull() || input.isEmpty()
                    || !input.getFluid().isFluidEqual(recipe.getInput())
                    || input.getFluidAmount() < recipe.getInput().amount
                    || (!output.isEmpty() && !output.getFluid().isFluidEqual(recipe.getOutput()))
                    || output.getFreeSpace() < recipe.getOutput().amount)
                return;
            input.drain(recipe.getInput().amount, true);
            output.fill(recipe.getOutput(), true);
            heat += recipe.getHeat();
        }
    }

    private void updateRecipe() {
        if (input.getFluid() == null || input.getFluidAmount() == 0)
            recipe = null;
        else
            recipe = BCARecipeManager.cooling.getRecipe(input.getFluid());
    }

    @Override
    public void makeMaster(int rotationIndex) {
        data.isMaster = true;
        data.rotationIndex = rotationIndex;
        upgrades.blacklistUpgrade(EnumMachineUpgrades.AUTO_OUTPUT).blacklistUpgrade(EnumMachineUpgrades.AUTO_IMPORT)
                .setMaxUpgrades(4);
    }

    @Override
    public void invalidateMultiblock() {
        if (isMaster())
            data.patern.destroyMultiblock(worldObj, xCoord, yCoord, zCoord, data.rotationIndex);
        else
            data.patern.destroyMultiblock(worldObj, data.masterX, data.masterY, data.masterZ, data.rotationIndex);
        recipe = null;
    }

    @Override
    public boolean onBlockActivated(EntityPlayer player) {
        if (isMaster()) {
            player.openGui(BuildcraftAdditions.instance, Variables.Gui.COOLING_TOWER.ordinal(), worldObj, xCoord,
                    yCoord, zCoord);
            return true;
        }
        if (masterCheck())
            return master.onBlockActivated(player);
        return isPartOfMultiblock();
    }

    @Override
    public void formMultiblock(int masterX, int masterY, int masterZ, int rotationIndex) {
        data.formMultiBlock(masterX, masterY, masterZ, rotationIndex);
        if (valve)
            upgrades.whitelistUpgrade(EnumMachineUpgrades.AUTO_OUTPUT)
                    .whitelistUpgrade(EnumMachineUpgrades.AUTO_IMPORT).setMaxUpgrades(1);
        sync();
    }

    @Override
    public void readFromNBT(NBTTagCompound tag) {
        super.readFromNBT(tag);
        valve = tag.getBoolean("valve");
        heat = tag.getFloat("heat");
        tank = tag.getInteger("tank");
        data.readFromNBT(tag);
        if (tag.hasKey("input", Constants.NBT.TAG_COMPOUND))
            input.readFromNBT(tag.getCompoundTag("input"));
        if (tag.hasKey("output", Constants.NBT.TAG_COMPOUND))
            output.readFromNBT(tag.getCompoundTag("output"));
        if (tag.hasKey("coolant", Constants.NBT.TAG_COMPOUND))
            coolant.readFromNBT(tag.getCompoundTag("coolant"));
        updateRecipe();
        upgrades.readFromNBT(tag);
        if (valve)
            upgrades.whitelistUpgrade(EnumMachineUpgrades.AUTO_OUTPUT)
                    .whitelistUpgrade(EnumMachineUpgrades.AUTO_IMPORT);
        if (isMaster())
            upgrades.blacklistUpgrade(EnumMachineUpgrades.AUTO_OUTPUT)
                    .blacklistUpgrade(EnumMachineUpgrades.AUTO_IMPORT);
    }

    @Override
    public void writeToNBT(NBTTagCompound tag) {
        super.writeToNBT(tag);
        tag.setFloat("heat", heat);
        tag.setBoolean("valve", valve);
        tag.setInteger("tank", tank);
        data.writeToNBT(tag);
        tag.setTag("input", input.writeToNBT(new NBTTagCompound()));
        tag.setTag("output", output.writeToNBT(new NBTTagCompound()));
        tag.setTag("coolant", coolant.writeToNBT(new NBTTagCompound()));
        upgrades.writeToNBT(tag);
    }

    @Override
    public void invalidateBlock() {
        worldObj.setBlockMetadataWithNotify(xCoord, yCoord, zCoord, 0, 2);
        worldObj.scheduleBlockUpdate(xCoord, yCoord, zCoord, worldObj.getBlock(xCoord, yCoord, zCoord), 80);
        data.invalidate();
        input.setFluid(null);
        output.setFluid(null);
        coolant.setFluid(null);
        heat = 0;
        recipe = null;
        sync();
    }

    private void findMaster() {
        TileEntity entity = worldObj.getTileEntity(data.masterX, data.masterY, data.masterZ);
        if (entity instanceof TileCoolingTower && ((TileCoolingTower) entity).isMaster())
            master = (TileCoolingTower) entity;
        else
            data.invalidataMultiblock(worldObj);
    }

    @Override
    public void moved(ForgeDirection direction) {
        data.onMove(direction);
    }

    @Override
    public int getMasterX() {
        return data.masterX;
    }

    @Override
    public void setMasterX(int masterX) {
        data.masterX = masterX;
    }

    @Override
    public int getMasterY() {
        return data.masterY;
    }

    @Override
    public void setMasterY(int masterY) {
        data.masterY = masterY;
    }

    @Override
    public int getMasterZ() {
        return data.masterZ;
    }

    @Override
    public void setMasterZ(int masterZ) {
        data.masterZ = masterZ;
    }

    @Override
    public int getRotationIndex() {
        return data.rotationIndex;
    }

    @Override
    public void setRotationIndex(int rotationIndex) {
        data.rotationIndex = rotationIndex;
    }

    @Override
    public boolean isMaster() {
        return data.isMaster;
    }

    @Override
    public boolean isPartOfMultiblock() {
        return data.partOfMultiBlock;
    }

    @Override
    public void setIsMaster(boolean isMaster) {
        data.isMaster = isMaster;
    }

    @Override
    public void setPartOfMultiBlock(boolean partOfMultiBlock) {
        data.partOfMultiBlock = partOfMultiBlock;
    }

    @Override
    public int fill(ForgeDirection from, FluidStack resource, boolean doFill) {
        if (isPartOfMultiblock() && valve) {
            if (masterCheck())
                return master.fill(resource, doFill, tank);
        }
        return 0;
    }

    private int fill(FluidStack resouce, boolean doFill, int tankID) {
        Tank tank = getTanks()[tankID];
        int filled = tank.fill(resouce, doFill);
        updateRecipe();
        sync();
        return filled;
    }

    @Override
    public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) {
        if (isMaster())
            return drain(resource, doDrain, tank);
        if (isPartOfMultiblock() && valve) {
            if (masterCheck())
                return master.drain(resource, doDrain, tank);
        }
        return null;
    }

    @Override
    public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) {
        if (isMaster())
            return drain(maxDrain, doDrain, tank);
        if (isPartOfMultiblock() && valve) {
            if (masterCheck())
                return master.drain(maxDrain, doDrain, tank);
        }
        return null;
    }

    private FluidStack drain(int maxDrain, boolean doDrain, int tankID) {
        Tank tank = getTanks()[tankID];
        FluidStack drained = tank.drain(maxDrain, doDrain);
        updateRecipe();
        return drained;
    }

    private FluidStack drain(FluidStack fluid, boolean doDrain, int tankID) {
        Tank tank = getTanks()[tankID];
        FluidStack drained = tank.drain(fluid, doDrain);
        updateRecipe();
        return drained;
    }

    @Override
    public boolean canFill(ForgeDirection from, Fluid fluid) {
        return valve;
    }

    @Override
    public boolean canDrain(ForgeDirection from, Fluid fluid) {
        return valve;
    }

    @Override
    public FluidTankInfo[] getTankInfo(ForgeDirection from) {
        if (valve) {
            if (masterCheck())
                return master.getRealInfo();
            return new FluidTankInfo[] { new FluidTankInfo(input), new FluidTankInfo(output) };
        }
        return new FluidTankInfo[0];
    }

    private FluidTankInfo[] getRealInfo() {
        return new FluidTankInfo[] { new FluidTankInfo(input), new FluidTankInfo(output) };
    }

    @Override
    public Tank[] getTanks() {
        return new Tank[] { input, output, coolant };
    }

    private boolean masterCheck() {
        if (master == null)
            findMaster();
        return master != null;
    }

    @Override
    public void writeToByteBuff(ByteBuf buf) {
        buf.writeBoolean(valve);
        buf.writeFloat(heat);
        input.writeToByteBuff(buf);
        output.writeToByteBuff(buf);
        coolant.writeToByteBuff(buf);
        data.writeToByteBuff(buf);
        upgrades.writeToByteBuff(buf);
    }

    @Override
    public void readFromByteBuff(ByteBuf buf) {
        valve = buf.readBoolean();
        heat = buf.readFloat();
        input.readFromByteBuff(buf);
        output.readFromByteBuff(buf);
        coolant.readFromByteBuff(buf);
        data.readFromByteBuff(buf);
        upgrades.readFromByteBuff(buf);
    }

    @Override
    public int getX() {
        return xCoord;
    }

    @Override
    public int getY() {
        return yCoord;
    }

    @Override
    public int getZ() {
        return zCoord;
    }

    @Override
    public ConnectOverride overridePipeConnection(IPipeTile.PipeType type, ForgeDirection with) {
        return valve && type == IPipeTile.PipeType.FLUID ? ConnectOverride.CONNECT : ConnectOverride.DISCONNECT;
    }

    @Override
    public boolean canAcceptUpgrade(EnumMachineUpgrades upgrade) {
        if (valve || isMaster()) {
            return upgrades.canInstallUpgrade(upgrade);
        } else {
            if (master == null)
                findMaster();
            return master != null && master.canAcceptUpgrade(upgrade);
        }
    }

    @Override
    public void installUpgrade(EnumMachineUpgrades upgrade) {
        if (valve || isMaster()) {
            upgrades.installUpgrade(upgrade);
        } else {
            if (master == null)
                findMaster();
            if (master == null)
                return;
            master.installUpgrade(upgrade);
        }
    }

    @Override
    public Set<EnumMachineUpgrades> getInstalledUpgrades() {
        if (isMaster()) {
            return upgrades.getUpgrades();
        } else {
            if (master == null)
                findMaster();
            if (master == null)
                return EnumSet.noneOf(EnumMachineUpgrades.class);
            Set<EnumMachineUpgrades> set = EnumSet.noneOf(EnumMachineUpgrades.class);
            set.addAll(master.getInstalledUpgrades());
            if (valve)
                set.addAll(upgrades.getUpgrades());
            return ImmutableSet.copyOf(set);
        }
    }

    @Override
    public void removeUpgrade() {
        if (valve || isMaster()) {
            EnumMachineUpgrades upgrade = upgrades.removeUpgrade();
            if (upgrade == null)
                return;
            ItemStack stack = upgrade.getItemStack();
            Utils.dropItemstack(worldObj, xCoord, yCoord, zCoord, stack);
        } else {
            if (master == null)
                findMaster();
            if (master == null)
                return;
            EnumMachineUpgrades upgrade = master.upgrades.removeUpgrade();
            if (upgrade == null)
                return;
            ItemStack stack = upgrade.getItemStack();
            Utils.dropItemstack(worldObj, xCoord, yCoord, zCoord, stack);
        }
    }
}