package micdoodle8.mods.galacticraft.core.tile;
import micdoodle8.mods.galacticraft.api.world.IAtmosphericGas;
import micdoodle8.mods.galacticraft.api.world.IGalacticraftWorldProvider;
import micdoodle8.mods.galacticraft.core.GCFluids;
import micdoodle8.mods.galacticraft.core.blocks.BlockOxygenCollector;
import micdoodle8.mods.galacticraft.core.energy.item.ItemElectricBase;
import micdoodle8.mods.galacticraft.core.inventory.IInventoryDefaults;
import micdoodle8.mods.galacticraft.core.util.GCCoreUtil;
import micdoodle8.mods.miccore.Annotations.NetworkedField;
import net.minecraft.block.Block;
import net.minecraft.block.BlockAir;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.chunk.Chunk;
import net.minecraftforge.common.EnumPlantType;
import net.minecraftforge.common.IPlantable;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fml.relauncher.Side;
import java.util.EnumSet;
public class TileEntityOxygenCollector extends TileEntityOxygen implements IInventoryDefaults, ISidedInventory
{
public boolean active;
public static final int OUTPUT_PER_TICK = 100;
@NetworkedField(targetSide = Side.CLIENT)
public float lastOxygenCollected;
private ItemStack[] containingItems = new ItemStack[1];
private boolean noAtmosphericOxygen = true;
private boolean isInitialised = false;
private boolean producedLastTick = false;
public TileEntityOxygenCollector()
{
super(6000, 0);
this.noRedstoneControl = true;
}
@Override
public int getCappedScaledOxygenLevel(int scale)
{
return (int) Math.max(Math.min(Math.floor((double) this.getOxygenStored() / (double) this.getMaxOxygenStored() * scale), scale), 0);
}
@Override
public void update()
{
super.update();
if (!this.worldObj.isRemote)
{
producedLastTick = this.getOxygenStored() < this.getMaxOxygenStored();
this.produceOxygen();
// if (this.getEnergyStored() > 0)
// {
// int gasToSend = Math.min(this.storedOxygen,
// GCCoreTileEntityOxygenCollector.OUTPUT_PER_TICK);
// GasStack toSend = new GasStack(GalacticraftCore.gasOxygen,
// gasToSend);
// this.storedOxygen -= GasTransmission.emitGasToNetwork(toSend,
// this, this.getOxygenOutputDirection());
//
// Vector3 thisVec = new Vector3(this);
// TileEntity tileEntity =
// thisVec.modifyPositionFromSide(this.getOxygenOutputDirection()).getTileEntity(this.worldObj);
//
// if (tileEntity instanceof IGasAcceptor)
// {
// if (((IGasAcceptor)
// tileEntity).canReceiveGas(this.getOxygenOutputDirection().getOpposite(),
// GalacticraftCore.gasOxygen))
// {
// double sendingGas = 0;
//
// if (this.storedOxygen >=
// GCCoreTileEntityOxygenCollector.OUTPUT_PER_TICK)
// {
// sendingGas = GCCoreTileEntityOxygenCollector.OUTPUT_PER_TICK;
// }
// else
// {
// sendingGas = this.storedOxygen;
// }
//
// this.storedOxygen -= sendingGas - ((IGasAcceptor)
// tileEntity).receiveGas(new GasStack(GalacticraftCore.gasOxygen,
// (int) Math.floor(sendingGas)));
// }
// }
// }
//Approximately once every 40 ticks, search out oxygen producing blocks
if (this.worldObj.rand.nextInt(10) == 0)
{
if (this.hasEnoughEnergyToRun)
{
// The later calculations are more efficient if power is a float, so
// there are fewer casts
float nearbyLeaves = 0;
if (!this.isInitialised)
{
this.noAtmosphericOxygen = (this.worldObj.provider instanceof IGalacticraftWorldProvider && !((IGalacticraftWorldProvider) this.worldObj.provider).isGasPresent(IAtmosphericGas.OXYGEN));
this.isInitialised = true;
}
if (this.noAtmosphericOxygen)
{
// Pre-test to see if close to the map edges, so code
// doesn't have to continually test for map edges inside the
// loop
if (this.getPos().getX() > -29999995 && this.getPos().getY() < 2999995 && this.getPos().getZ() > -29999995 && this.getPos().getZ() < 29999995)
{
// Test the y coordinates, so code doesn't have to keep
// testing that either
int miny = this.getPos().getY() - 5;
int maxy = this.getPos().getY() + 5;
if (miny < 0)
{
miny = 0;
}
if (maxy >= this.worldObj.getHeight())
{
maxy = this.worldObj.getHeight() - 1;
}
// Loop the x and the z first, so the y loop will be at
// fixed (x,z) coordinates meaning fixed chunk
// coordinates
for (int x = this.getPos().getX() - 5; x <= this.getPos().getX() + 5; x++)
{
int chunkx = x >> 4;
int intrachunkx = x & 15;
// Preload the first chunk for the z loop - there
// can be a maximum of 2 chunks in the z loop
int chunkz = this.getPos().getZ() - 5 >> 4;
Chunk chunk = this.worldObj.getChunkFromChunkCoords(chunkx, chunkz);
for (int z = this.getPos().getZ() - 5; z <= this.getPos().getZ() + 5; z++)
{
if (z >> 4 != chunkz)
{
// moved across z chunk boundary into a new
// chunk, so load the new chunk
chunkz = z >> 4;
chunk = this.worldObj.getChunkFromChunkCoords(chunkx, chunkz);
}
for (int y = miny; y <= maxy; y++)
{
// chunk.getBlockID is like world.getBlock
// but faster - needs to be given
// intra-chunk coordinates though
final Block block = chunk.getBlock(intrachunkx, y, z & 15);
// Test for the two most common blocks (air
// and breatheable air) without looking up
// in the blocksList
if (!(block instanceof BlockAir))
{
if (block.isLeaves(this.worldObj, new BlockPos(x, y, z)) || block instanceof IPlantable && ((IPlantable) block).getPlantType(this.worldObj, new BlockPos(x, y, z)) == EnumPlantType.Crop)
{
nearbyLeaves += 0.075F * 10F;
}
}
}
}
}
}
}
else
{
nearbyLeaves = 9.3F * 10F;
}
nearbyLeaves = (float) Math.floor(nearbyLeaves);
this.lastOxygenCollected = nearbyLeaves / 10F;
this.tank.setFluid(new FluidStack(GCFluids.fluidOxygenGas, (int) Math.max(Math.min(this.getOxygenStored() + nearbyLeaves, this.getMaxOxygenStored()), 0)));
}
else
{
this.lastOxygenCollected = 0;
}
}
}
}
@Override
public void readFromNBT(NBTTagCompound par1NBTTagCompound)
{
super.readFromNBT(par1NBTTagCompound);
final NBTTagList var2 = par1NBTTagCompound.getTagList("Items", 10);
this.containingItems = new ItemStack[this.getSizeInventory()];
for (int var3 = 0; var3 < var2.tagCount(); ++var3)
{
final NBTTagCompound var4 = var2.getCompoundTagAt(var3);
final int var5 = var4.getByte("Slot") & 255;
if (var5 < this.containingItems.length)
{
this.containingItems[var5] = ItemStack.loadItemStackFromNBT(var4);
}
}
}
@Override
public void writeToNBT(NBTTagCompound par1NBTTagCompound)
{
super.writeToNBT(par1NBTTagCompound);
final NBTTagList list = new NBTTagList();
for (int var3 = 0; var3 < this.containingItems.length; ++var3)
{
if (this.containingItems[var3] != null)
{
final NBTTagCompound var4 = new NBTTagCompound();
var4.setByte("Slot", (byte) var3);
this.containingItems[var3].writeToNBT(var4);
list.appendTag(var4);
}
}
par1NBTTagCompound.setTag("Items", list);
}
@Override
public int getSizeInventory()
{
return this.containingItems.length;
}
@Override
public ItemStack getStackInSlot(int par1)
{
return this.containingItems[par1];
}
@Override
public ItemStack decrStackSize(int par1, int par2)
{
if (this.containingItems[par1] != null)
{
ItemStack var3;
if (this.containingItems[par1].stackSize <= par2)
{
var3 = this.containingItems[par1];
this.containingItems[par1] = null;
return var3;
}
else
{
var3 = this.containingItems[par1].splitStack(par2);
if (this.containingItems[par1].stackSize == 0)
{
this.containingItems[par1] = null;
}
return var3;
}
}
else
{
return null;
}
}
@Override
public ItemStack removeStackFromSlot(int par1)
{
if (this.containingItems[par1] != null)
{
final ItemStack var2 = this.containingItems[par1];
this.containingItems[par1] = null;
return var2;
}
else
{
return null;
}
}
@Override
public void setInventorySlotContents(int par1, ItemStack par2ItemStack)
{
this.containingItems[par1] = par2ItemStack;
if (par2ItemStack != null && par2ItemStack.stackSize > this.getInventoryStackLimit())
{
par2ItemStack.stackSize = this.getInventoryStackLimit();
}
}
@Override
public String getName()
{
return GCCoreUtil.translate("container.oxygencollector.name");
}
@Override
public boolean hasCustomName()
{
return true;
}
@Override
public int getInventoryStackLimit()
{
return 64;
}
@Override
public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer)
{
return this.worldObj.getTileEntity(this.getPos()) == this && par1EntityPlayer.getDistanceSq(this.getPos().getX() + 0.5D, this.getPos().getY() + 0.5D, this.getPos().getZ() + 0.5D) <= 64.0D;
}
// ISidedInventory Implementation:
@Override
public int[] getSlotsForFace(EnumFacing side)
{
return new int[] { 0 };
}
@Override
public boolean canInsertItem(int slotID, ItemStack itemstack, EnumFacing side)
{
return this.isItemValidForSlot(slotID, itemstack);
}
@Override
public boolean canExtractItem(int slotID, ItemStack itemstack, EnumFacing side)
{
return slotID == 0;
}
@Override
public boolean isItemValidForSlot(int slotID, ItemStack itemstack)
{
return slotID == 0 && ItemElectricBase.isElectricItem(itemstack.getItem());
}
@Override
public boolean shouldUseEnergy()
{
return this.getOxygenStored() > 0F && producedLastTick;
}
@Override
public EnumFacing getFront()
{
return (this.worldObj.getBlockState(getPos()).getValue(BlockOxygenCollector.FACING));
}
@Override
public EnumFacing getElectricInputDirection()
{
return getFront().rotateY();
}
@Override
public ItemStack getBatteryInSlot()
{
return this.getStackInSlot(0);
}
@Override
public boolean shouldPullOxygen()
{
return false;
}
// @Override
// public boolean canReceiveGas(EnumFacing side, Gas type)
// {
// return false;
// }
//
// @Override
// public int receiveGas(EnumFacing side, GasStack stack, boolean doTransfer)
// {
// return 0;
// }
//
// @Override
// public int receiveGas(EnumFacing side, GasStack stack)
// {
// return 0;
// }
@Override
public boolean shouldUseOxygen()
{
return false;
}
@Override
public EnumSet<EnumFacing> getOxygenInputDirections()
{
return EnumSet.noneOf(EnumFacing.class);
}
@Override
public EnumSet<EnumFacing> getOxygenOutputDirections()
{
return EnumSet.of(this.getElectricInputDirection().getOpposite());
}
@Override
public int getOxygenProvide(EnumFacing direction)
{
return this.getOxygenOutputDirections().contains(direction) ? Math.min(TileEntityOxygenStorageModule.OUTPUT_PER_TICK, this.getOxygenStored()) : 0;
}
}