/* 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.machine;
import com.projectzed.api.tileentity.machine.AbstractTileEntityMachine;
import com.projectzed.api.util.Sound;
import com.projectzed.mod.ProjectZed;
import com.projectzed.mod.handler.PacketHandler;
import com.projectzed.mod.handler.message.MessageTileEntityCentrifuge;
import com.projectzed.mod.registry.CentrifugeRecipeRegistry;
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.*;
/**
* Class containing code for industrialCentrifuge.
*
* @author hockeyhurd
* @version Dec 21, 2014
*/
public class TileEntityIndustrialCentrifuge extends AbstractTileEntityMachine implements IFluidHandler {
private final int MAX_WATER_STORAGE = 10000;
private FluidTank internalTank;
private byte craftingAmount = 1;
public TileEntityIndustrialCentrifuge() {
super("industrialCentrifuge");
this.internalTank = new FluidTank(this.MAX_WATER_STORAGE);
}
/**
* Gets the crafting amount when processing.
*
* @return crafting amount.
*/
public byte getCraftingAmount() {
return craftingAmount;
}
/**
* Sets the crafting amount for processing.
*
* @param craftingAmount craftingAmount to set.
*/
public void setCraftingAmount(byte craftingAmount) {
this.craftingAmount = craftingAmount;
}
@Override
public int getSizeInventory() {
return slots.length;
}
@Override
public int getInventoryStackLimit() {
return 64;
}
@Override
protected void initContentsArray() {
this.slots = new ItemStack[3 + getSizeUpgradeSlots()];
}
@Override
protected void initSlotsArray() {
this.slotTop = new int[] {
0
};
this.slotRight = new int[] {
1
};
this.slotInput = new int[] {
0, 1
};
this.slotBottom = new int[] {
2
};
}
@Override
public boolean isItemValidForSlot(int slot, ItemStack stack) {
return slot != 2 && super.isItemValidForSlot(slot, stack);
}
@Override
public int[] getSlotsForFace(EnumFacing side) {
return openSides[side.ordinal()] == 1 ? this.slotRight : openSides[side.ordinal()] == -1 ? this.slotInput : new int[0];
}
@Override
public boolean canExtractItem(int slot, ItemStack stack, EnumFacing side) {
return slot > 1 && slot < slots.length - getSizeUpgradeSlots() && openSides[side.ordinal()] == 1;
}
@Override
protected boolean canSmelt() {
if (this.slots[0] == null || this.slots[2] == null || this.stored - this.energyBurnRate <= 0 || !hasWaterInTank()) return false;
else {
// Check if the item in the slot 1 can be smelted (has a set furnace recipe).
// ItemStack stack = CentrifugeRecipeRegistry.centrifugeList(this.slots[0], this.slots[2]);
ItemStack itemStack = CentrifugeRecipeRegistry.centrifugeList(this.slots[0], this.slots[2]);
int amountLeft = /*this.slots[2].getMaxDamage() - */this.slots[2].getItemDamage();
int allowedAmount = Math.min(this.craftingAmount, amountLeft);
allowedAmount = Math.min(allowedAmount, Math.max(this.slots[0].stackSize, this.slots[0].stackSize));
if (allowedAmount > 0 && this.slots[0].stackSize < allowedAmount && this.slots[2].stackSize < allowedAmount) return false;
if (craftingAmount > 1 && itemStack != null && itemStack.stackSize > 0) {
itemStack = CentrifugeRecipeRegistry.stackOffset(itemStack, allowedAmount);
if (itemStack == null) {
itemStack = CentrifugeRecipeRegistry.centrifugeList(this.slots[0], this.slots[2]);
itemStack = CentrifugeRecipeRegistry.stackOffset(itemStack, Math.min(this.craftingAmount, Math.max(this.slots[0].stackSize, this.slots[0].stackSize)));
}
}
if (itemStack == null) return false;
if (this.slots[1] == null) return true;
if (!this.slots[1].isItemEqual(itemStack)) return false;
// Add the result of the furnace recipe to the current stack size (already smelted so far).
int result = this.slots[1].stackSize + itemStack.stackSize;
// Make sure we aren't going over the set stack limit's size.
return (result <= getInventoryStackLimit() && result <= itemStack.getMaxStackSize());
}
}
/**
* Function to get whether there is water in tank.
*
* @return true if has water, else returns false.
*/
public boolean hasWaterInTank() {
return this.internalTank.getFluidAmount() > 0;
}
/**
* Gets the fluid tank associated with this tileentity.
*
* @return fluid tank object.
*/
public FluidTank getTank() {
return this.internalTank;
}
@Override
public void smeltItem() {
if (this.canSmelt()) {
ItemStack itemStack = CentrifugeRecipeRegistry.centrifugeList(this.slots[0], this.slots[2]);
int amountLeft = /*this.slots[2].getMaxDamage() - */this.slots[2].getItemDamage();
int allowedAmount = Math.min(this.craftingAmount, amountLeft);
allowedAmount = Math.min(allowedAmount, Math.max(this.slots[0].stackSize, this.slots[0].stackSize));
int altAmount = Math.min(this.craftingAmount, Math.max(this.slots[0].stackSize, this.slots[0].stackSize));
boolean usedAlt = false;
if (allowedAmount > 0 && this.slots[0].stackSize < allowedAmount && this.slots[2].stackSize < allowedAmount) return;
if (craftingAmount > 1 && itemStack != null && itemStack.stackSize > 0) {
itemStack = CentrifugeRecipeRegistry.stackOffset(itemStack, allowedAmount);
if (itemStack == null) {
itemStack = CentrifugeRecipeRegistry.centrifugeList(this.slots[0], this.slots[2]);
itemStack = CentrifugeRecipeRegistry.stackOffset(itemStack, altAmount);
usedAlt = true;
}
}
if (this.slots[1] == null) this.slots[1] = itemStack.copy();
else if (this.slots[1].isItemEqual(itemStack)) slots[1].stackSize += itemStack.stackSize;
if (this.slots[0].stackSize > this.slots[2].stackSize) {
this.slots[0].stackSize -= !usedAlt ? allowedAmount : altAmount;
this.slots[2].stackSize--;
ProjectZed.logHelper.info("this one!", allowedAmount);
}
else if (this.slots[0].stackSize < this.slots[2].stackSize) {
this.slots[0].stackSize--;
this.slots[2].stackSize -= !usedAlt ? allowedAmount : altAmount;
}
else {
this.slots[0].stackSize--;
this.slots[2].stackSize--;
}
// this.slots[0].stackSize--;
if (this.slots[0].stackSize <= 0) this.slots[0] = null;
// this.slots[2].stackSize--;
if (this.slots[2].stackSize <= 0) this.slots[2] = null;
this.internalTank.drain(1000, true);
}
}
@Override
public void onDataPacket(NetworkManager manager, SPacketUpdateTileEntity packet) {
PacketHandler.INSTANCE.getPacketFrom(new MessageTileEntityCentrifuge(this));
}
@Override
public Sound getSound() {
return null;
}
@Override
public void readFromNBT(NBTTagCompound comp) {
super.readFromNBT(comp);
this.internalTank.readFromNBT(comp);
this.craftingAmount = comp.getByte("ProjectZedCentrifugeCraftingAmount");
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound comp) {
super.writeToNBT(comp);
this.internalTank.writeToNBT(comp);
comp.setByte("ProjectZedCentrifugeCraftingAmount", this.craftingAmount);
return comp;
}
@Override
public int fill(EnumFacing from, FluidStack resource, boolean doFill) {
if (!worldObj.isRemote) {
int fillAmount = internalTank.fill(resource, doFill);
if (doFill) {
worldObj.notifyBlockOfStateChange(pos, blockType);
this.markDirty();
if (blockType != null) worldObj.notifyNeighborsOfStateChange(pos, blockType);
FluidEvent.fireEvent(new FluidEvent.FluidFillingEvent(resource, worldObj, pos, this.internalTank, 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(internalTank.getFluid())) ? internalTank.drain(
drainFluid.amount, doDrain) : drainAmount >= 0 ? internalTank.drain(drainAmount, doDrain) : null;
if (doDrain && drainedFluid != null && drainedFluid.amount > 0) {
this.markDirty();
worldObj.notifyBlockOfStateChange(pos, blockType);
FluidEvent.fireEvent(new FluidEvent.FluidDrainingEvent(drainedFluid, worldObj, pos, this.internalTank, drainedFluid.amount));
}
return drainedFluid;
}
return null;
}
@Override
public boolean canFill(EnumFacing from, Fluid fluid) {
if (fluid != null && !isFull()) {
FluidStack tankFluid = this.internalTank.getFluid();
return tankFluid == null || tankFluid.isFluidEqual(new FluidStack(fluid, 0));
}
return false;
}
@Override
public boolean canDrain(EnumFacing from, Fluid fluid) {
if (fluid != null && this.internalTank.getFluidAmount() > 0) {
FluidStack tankFluid = this.internalTank.getFluid();
return tankFluid != null && tankFluid.isFluidEqual(new FluidStack(fluid, 0));
}
return false;
}
@Override
public FluidTankInfo[] getTankInfo(EnumFacing from) {
return new FluidTankInfo[] { this.internalTank.getInfo() };
}
/**
* Gets whether tank is full or not.
*
* @return true if full, else returns false.
*/
public boolean isFull() {
return this.internalTank.getFluidAmount() == this.internalTank.getCapacity();
}
/**
* Gets the localized name of the fluid in the tank.
*
* @return localized name of fluid in the tank.
*/
public String getLocalizedFluidName() {
return this.internalTank.getFluid() != null && this.internalTank.getFluid().getFluid() != null ?
this.internalTank.getFluid().getLocalizedName() : null;
}
}