/*
* This file is part of Project-Zed. Project-Zed is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Project-Zed is
* distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along
* with Project-Zed. If not, see <http://www.gnu.org/licenses/>
*
*/
package com.projectzed.mod.tileentity.container;
import com.hockeyhurd.hcorelib.api.util.BlockUtils;
import com.projectzed.api.fluid.FluidNetwork;
import com.projectzed.api.fluid.container.IFluidContainer;
import com.projectzed.api.tileentity.container.AbstractTileEntityEnergyContainer;
import com.projectzed.api.util.FluidUtils;
import com.projectzed.mod.ProjectZed;
import com.projectzed.mod.handler.PacketHandler;
import com.projectzed.mod.handler.message.MessageTileEntityRefinery;
import com.projectzed.mod.util.Reference;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.fluids.*;
import javax.annotation.Nullable;
/**
* TE class for refinery.
*
* @author hockeyhurd
* @version 8/4/2015.
*/
public class TileEntityRefinery extends AbstractTileEntityEnergyContainer implements IFluidContainer {
private final int MAX_FLUID_STORAGE = 8000;
private FluidTank inputTank, outputTank;
private FluidTank[] tanks;
public static final int ENERGY_BURN_RATE = Reference.Constants.getMcUFromRF((int) 1e5) / 1000;
private FluidNetwork network;
public enum TankID {
INPUT, OUTPUT
}
public TileEntityRefinery() {
super("refinery");
this.inputTank = new FluidTank(this.MAX_FLUID_STORAGE);
this.outputTank = new FluidTank(this.MAX_FLUID_STORAGE);
this.tanks = new FluidTank[] {
this.inputTank, this.outputTank
};
}
@Override
public int getSizeInventory() {
return 0;
}
@Override
public int getInventoryStackLimit() {
return 0;
}
@Override
protected void initContentsArray() {
}
@Override
protected void initSlotsArray() {
}
@Override
public boolean isItemValidForSlot(int slot, ItemStack stack) {
return false;
}
@Override
public int[] getSlotsForFace(EnumFacing side) {
return new int[0];
}
@Override
public boolean canInsertItem(int slot, ItemStack stack, EnumFacing side) {
return false;
}
@Override
public boolean canExtractItem(int slot, ItemStack stack, EnumFacing side) {
return false;
}
@Override
public int getMaxImportRate() {
return Reference.Constants.BASE_PIPE_TRANSFER_RATE * Reference.Constants.TIER3_ENERGY_PIPE_MULTIPLIER;
}
@Override
public int getMaxExportRate() {
return 0;
}
@Override
protected void importContents() {
}
@Override
protected void exportContents() {
}
// end energy code.
/**
* Function to check if TE contains basic necessities for producing fuel.
*
* @return true if valid parameters, else returns false.
*/
private boolean canProduceFuel() {
return storedPower - ENERGY_BURN_RATE >= 0 && inputTank.getFluidAmount() - 1 >= 0 && (outputTank.getFluid() == null
|| outputTank.getFluidAmount() + 1 <= outputTank.getCapacity());
}
/**
* Function to get output fuel from inputted fluidstack.
*
* @param fluidStack fluid stack to reference.
* @return output fluid if valid input, else returns NULL.
*/
public static Fluid getOutputFromInput(FluidStack fluidStack) {
return fluidStack != null && fluidStack.getFluid() == ProjectZed.fluidOil ? ProjectZed.fluidPetrol : null;
}
@Override
public void update() {
super.update();
// transferPower();
if (!worldObj.isRemote) {
Fluid outputFluid = getOutputFromInput(inputTank.getFluid());
if (canProduceFuel() && outputFluid != null) {
this.storedPower -= ENERGY_BURN_RATE;
inputTank.getFluid().amount--;
if (inputTank.getFluid().amount == 0) inputTank.setFluid(null);
if (outputTank.getFluid() == null) outputTank.setFluid(new FluidStack(outputFluid, 1));
else if (FluidUtils.areFluidsEqual(outputTank.getFluid(), (new FluidStack(outputFluid, 1)))) outputTank.getFluid().amount++;
this.powerMode = true;
}
else this.powerMode = false;
PacketHandler.INSTANCE.sendToAll(new MessageTileEntityRefinery(this));
// tanks[TankID.INPUT.ordinal()] = inputTank;
// tanks[TankID.OUTPUT.ordinal()] = outputTank;
}
}
@Nullable
@Override
public SPacketUpdateTileEntity getUpdatePacket() {
PacketHandler.INSTANCE.getPacketFrom(new MessageTileEntityRefinery(this));
final NBTTagCompound comp = getUpdateTag();
saveNBT(comp);
return new SPacketUpdateTileEntity(pos, 1, comp);
}
@Override
public void onDataPacket(NetworkManager manger, SPacketUpdateTileEntity packet) {
readNBT(packet.getNbtCompound());
BlockUtils.markBlockForUpdate(worldObj, pos);
}
@Override
public void readNBT(NBTTagCompound comp) {
super.readNBT(comp);
// if for some reason fluid tank array is null, init it first.
if (tanks == null) {
// tanks = new FluidTank[TankID.values().length];
tanks = new FluidTank[] {
inputTank, outputTank,
};
}
FluidUtils.readNBT(comp, tanks);
}
@Override
public void saveNBT(NBTTagCompound comp) {
super.saveNBT(comp);
FluidUtils.saveNBT(comp, tanks);
}
// Start fluid handling code:
/**
* @return number of tanks held in this tileentity.
*/
public int getNumTanks() {
return tanks.length;
}
public FluidTank getTank(TankID tankID) {
return tanks[tankID.ordinal()];
}
/**
* @deprecated as of 8/11/2015, use other getTank functions since this TE uses multiple tanks.
*
* @return ouput tank in TE.
*/
@Override
@Deprecated
public FluidTank getTank() {
return getTank(TankID.OUTPUT);
}
public FluidTank getTank(int id) {
return id >= 0 && id < tanks.length ? tanks[id] : null;
}
@Override
public String getLocalizedFluidName() {
return getLocalizedFluidName(TankID.OUTPUT);
}
public String getLocalizedFluidName(TankID tankID) {
return tanks[tankID.ordinal()].getFluid() != null && tanks[tankID.ordinal()].getFluid().getFluid() != null ?
tanks[tankID.ordinal()].getFluid().getFluid().getName() :
null;
}
@Override
public String getFluidID() {
return getFluidID(TankID.OUTPUT);
}
public String getFluidID(TankID tankID) {
return getTank(tankID).getFluid() != null ? getTank(tankID).getFluid().getFluid().getName() : null;
}
@Override
public int getMaxFluidImportRate() {
return 1000;
}
@Override
public int getMaxFluidExportRate() {
return 1000;
}
@Override
public boolean isPipe() {
return false;
}
@Override
public boolean canBeSourceNode() {
return false;
}
@Override
public boolean canBeMaster() {
return false;
}
@Override
public boolean isMaster() {
return false;
}
@Override
public void setMaster(boolean master) {
}
@Override
public boolean hasFluidNetwork() {
return network != null;
}
@Override
public FluidNetwork getNetwork() {
return network;
}
@Override
public void setFluidNetwork(FluidNetwork network) {
this.network = network;
}
@Override
public int fill(EnumFacing from, FluidStack resource, boolean doFill) {
if (!worldObj.isRemote) {
int fillAmount = inputTank.fill(resource, doFill);
if (doFill) {
worldObj.notifyBlockOfStateChange(pos, blockType);
this.markDirty();
if (this.getBlockType() != null) worldObj.notifyNeighborsOfStateChange(pos, blockType);
FluidEvent.fireEvent(new FluidEvent.FluidFillingEvent(resource, worldObj, pos, this.inputTank, fillAmount));
}
return fillAmount;
}
return 0;
}
@Override
public FluidStack drain(EnumFacing from, FluidStack resource, boolean doDrain) {
return drain(from, resource, -1, doDrain);
}
@Override
public FluidStack drain(EnumFacing from, int maxDrain, boolean doDrain) {
return drain(from, null, maxDrain, doDrain);
}
/**
* Drains fluid from this block to another.
*
* @param from direction drained from.
* @param drainFluid the fluid drained.
* @param drainAmount amount of fluid drained.
* @param doDrain whether draining should be simulated or not.
* @return type and amount of fluid drained.
*/
protected FluidStack drain(EnumFacing from, FluidStack drainFluid, int drainAmount, boolean doDrain) {
if (!worldObj.isRemote) {
FluidStack drainedFluid = (drainFluid != null && drainFluid.isFluidEqual(outputTank.getFluid())) ? outputTank.drain(
drainFluid.amount, doDrain) : drainAmount >= 0 ? outputTank.drain(drainAmount, doDrain) : null;
if (doDrain && drainedFluid != null && drainedFluid.amount > 0) {
this.markDirty();
worldObj.notifyBlockOfStateChange(pos, blockType);
worldObj.notifyNeighborsOfStateChange(pos, blockType);
FluidEvent.fireEvent(new FluidEvent.FluidDrainingEvent(drainedFluid, worldObj, pos, this.outputTank, drainedFluid.amount));
}
return drainedFluid;
}
return null;
}
@Override
public boolean canFill(EnumFacing from, Fluid fluid) {
if (fluid != null && !isFull(TankID.INPUT)) {
FluidStack tankFluid = this.inputTank.getFluid();
return tankFluid == null || tankFluid.isFluidEqual(new FluidStack(fluid, 0));
}
return false;
}
@Override
public boolean canDrain(EnumFacing from, Fluid fluid) {
if (fluid != null && this.outputTank.getFluidAmount() > 0) {
FluidStack tankFluid = this.outputTank.getFluid();
return tankFluid != null && tankFluid.isFluidEqual(new FluidStack(fluid, 0));
}
return false;
}
@Override
public FluidTankInfo[] getTankInfo(EnumFacing from) {
return new FluidTankInfo[] { inputTank.getInfo(), outputTank.getInfo() };
}
public boolean isFull(TankID tankID) {
return tanks[tankID.ordinal()].getFluidAmount() == tanks[tankID.ordinal()].getCapacity();
}
}