/* 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.block.AbstractHCoreBlock;
import com.hockeyhurd.hcorelib.api.math.Vector3;
import com.hockeyhurd.hcorelib.api.util.BlockUtils;
import com.projectzed.api.tileentity.IMultiBlockable;
import com.projectzed.api.tileentity.IWrenchable;
import com.projectzed.api.tileentity.container.AbstractTileEntityNuclearComponent;
import com.projectzed.mod.ProjectZed;
import com.projectzed.mod.block.container.BlockNuclearIOPort;
import com.projectzed.mod.handler.PacketHandler;
import com.projectzed.mod.handler.message.MessageTileEntityNuclearIOPort;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.network.NetworkRegistry.TargetPoint;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import java.util.List;
/**
* Class containing tileentity code for nuclearIOPort.
*
* @author hockeyhurd
* @version Mar 19, 2015
*/
public class TileEntityNuclearIOPort extends AbstractTileEntityNuclearComponent implements IWrenchable {
// TODO: This class should take over IO of TileEntityNuclearController. For now this TE is set to optional use.
public static final int MAX_BURN_TIME = 1600; // TODO: Should this be moved?
private byte meta;
private int burnTime;
protected boolean isInputMode;
public TileEntityNuclearIOPort() {
super("nuclearIOPort");
}
@Override
public String getInventoryName() {
return "container.nuclearIOPort";
}
@Override
protected void initContentsArray() {
this.slots = new ItemStack[2];
}
@Override
public int getSizeInventory() {
return this.slots.length;
}
@Override
public int getInventoryStackLimit() {
return 64;
}
@Override
public boolean canUpdate() {
return true;
}
@Override
public void update() {
super.update();
if (!worldObj.isRemote && worldObj.getTotalWorldTime() % 20L == 0) {
byte current = (byte) this.getBlockMetadata();
if (this.meta != current) setMetaOnUpdate(current);
PacketHandler.INSTANCE.sendToAllAround(new MessageTileEntityNuclearIOPort(this),
new TargetPoint(worldObj.provider.getDimension(), pos.getX(), pos.getY(), pos.getZ(), 0x10));
}
else if (worldObj.isRemote && burnTime > 0) {
burnTime--; // On client side, we can predict that burn time will be decreased each tick, and will be corrected via messages 1/sec.
}
}
@Override
public int[] getSlotsForFace(EnumFacing side) {
return new int[] { 0, 1 };
}
@Override
public boolean isItemValidForSlot(int slot, ItemStack stack) {
if (slot != 0 || stack == null) return false;
return stack.getItem() == ProjectZed.fuelRod || stack.getItemDamage() < stack.getMaxDamage();
}
@Override
public boolean canInsertItem(int slot, ItemStack stack, EnumFacing side) {
return this.getBlockMetadata() == 1 && isItemValidForSlot(slot, stack);
}
@Override
public boolean canExtractItem(int slot, ItemStack stack, EnumFacing side) {
return /*this.getBlockMetadata() == 2 &&*/ slot == 1;
}
/**
* Gets the item burn time for stack.
*
* @param stack stack to test.
* @return item burn time.
*/
public static int getItemBurnTime(ItemStack stack) {
if (stack == null) return 0;
else {
Item item = stack.getItem();
if (item == ProjectZed.fuelRod && stack.getItemDamage() < stack.getMaxDamage()) return MAX_BURN_TIME;
return 0;
}
}
/**
* Function used to determine if item in slot is fuel.
*
* @return true if is fuel, else returns false.
*/
public boolean isFuel() {
return getItemBurnTime(this.slots[0]) > 0;
}
/**
* Method used to consume fuel in given slot.
*
* @param ouputPort port to send empty fuel cell to if applicable.
*/
public void consumeFuel(TileEntityNuclearIOPort ouputPort) {
if (this.isFuel()) {
if (this.slots[0] == null) return;
else {
ItemStack stack = this.slots[0];
if (stack.getItemDamage() < stack.getMaxDamage() - 1) {
stack.setItemDamage(stack.getItemDamage() + 1);
this.slots[0] = stack;
}
else {
this.slots[0] = null;
// if (ouputPort == null) this.slots[1] = new ItemStack(ProjectZed.emptyFuelRod, 1, 0);
// else ouputPort.setInventorySlotContents(1, new ItemStack(ProjectZed.emptyFuelRod, 1, 0));
if (ouputPort == null) this.slots[1] = new ItemStack(ProjectZed.fuelRod, 1, 0);
else ouputPort.setInventorySlotContents(1, new ItemStack(ProjectZed.fuelRod, 1, 0));
}
}
}
}
/**
* Function to run a cycle of consuming fuel and setting/resetting applicable data values.
*
* @param ouputPort port to send resulting data to if applicable.
* @return true if successful, else returns false.
*/
public boolean runCycle(TileEntityNuclearIOPort ouputPort) {
boolean flag = false;
if (this.slots[0] != null && isFuel()) {
if (this.burnTime == 0) {
this.burnTime = getItemBurnTime(this.slots[0]);
consumeFuel(ouputPort);
flag = true;
}
}
return flag;
}
public void tickBurnTime() {
if (this.burnTime > 0) this.burnTime--;
}
/**
* Gets the current burn time for instance.
*
* @return burn time as int value.
*/
public int getBurnTime() {
return this.burnTime;
}
/**
* Setter method used for syncing with client side.
*
* @param burnTime Int burn time to set.
*/
@SideOnly(Side.CLIENT)
public void setBurnTime(int burnTime) {
this.burnTime = burnTime;
}
/*@Override
public Packet getDescriptionPacket() {
return PacketHandler.INSTANCE.getPacketFrom(new MessageTileEntityNuclearIOPort(this));
}*/
@Override
public NBTTagCompound getUpdateTag() {
PacketHandler.INSTANCE.getPacketFrom(new MessageTileEntityNuclearIOPort(this));
final NBTTagCompound comp = getTileData();
saveNBT(comp);
return comp;
}
@Override
public void readNBT(NBTTagCompound comp) {
super.readNBT(comp);
this.meta = comp.getByte("ProjectZedNuclearIOPortMeta");
this.burnTime = comp.getInteger("ProjectZedNuclearBurnTime");
}
@Override
public void saveNBT(NBTTagCompound comp) {
super.saveNBT(comp);
comp.setByte("ProjectZedNuclearIOPortMeta", this.meta);
comp.setInteger("ProjectZedNuclearBurnTime", this.burnTime);
}
/**
* @return the correct meta data for when multiblock structure is 'active'
*/
public byte getStoredMeta() {
return this.meta;
}
/**
* Sets stored meta data as byte.
*
* @param meta new meta data value.
*/
public void setMetaOnUpdate(byte meta) {
if (meta > 0) this.meta = meta;
}
@Override
public void reset() {
this.isMaster = false;
this.hasMaster = false;
this.masterVec = Vector3.zero.getVector3i();
final Vector3<Integer> vec = worldVec();
final IBlockState blockState = BlockUtils.getBlock(worldObj, vec);
setMetaOnUpdate((byte) blockState.getBlock().getMetaFromState(blockState));
((BlockNuclearIOPort) blockState).updateMeta(false, worldObj, worldVec());
}
@Override
public boolean isUnique() {
return false;
}
@Override
public boolean isSubstitutable() {
return false;
}
@Override
public List<IMultiBlockable> getSubList() {
return null;
}
@Override
public int getAmountFromSize(int width, int height, int depth) {
return 2;
}
@Override
public AbstractHCoreBlock getBlock() {
return (AbstractHCoreBlock) ProjectZed.nuclearIOPort;
}
@Override
public EnumFacing getRotatedState(EnumFacing facingDir, IBlockState blockState) {
return EnumFacing.NORTH;
}
@Override
public EnumFacing getCurrentFacing() {
return EnumFacing.NORTH;
}
@Override
public void setFrontFacing(EnumFacing facing) {
}
@Override
public boolean canRotateTE() {
return false;
}
@Override
public void onInteract(ItemStack stack, EntityPlayer player, World world, Vector3<Integer> vec) {
if (!worldObj.isRemote) isInputMode = !isInputMode;
}
@Override
public boolean canSaveDataOnPickup() {
return true;
}
}