package micdoodle8.mods.galacticraft.core.tile;
import micdoodle8.mods.galacticraft.core.GalacticraftCore;
import micdoodle8.mods.galacticraft.core.inventory.IInventoryDefaults;
import micdoodle8.mods.galacticraft.core.inventory.PersistantInventoryCrafting;
import micdoodle8.mods.galacticraft.core.network.PacketDynamicInventory;
import micdoodle8.mods.galacticraft.core.util.GCCoreUtil;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.CraftingManager;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
public class TileEntityCrafting extends TileEntity implements IInventoryDefaults, ISidedInventory
{
private static final int SIZEINVENTORY = 9;
public PersistantInventoryCrafting craftMatrix = new PersistantInventoryCrafting();
public ItemStack[] memory = new ItemStack[SIZEINVENTORY];
public TileEntityCrafting()
{
}
@Override
public void onLoad()
{
if (this.worldObj.isRemote)
{
//Request size + contents information from server
GalacticraftCore.packetPipeline.sendToServer(new PacketDynamicInventory(this));
}
}
@Override
public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newSate)
{
return oldState.getBlock() != newSate.getBlock();
}
public void updateMemory()
{
if (CraftingManager.getInstance().findMatchingRecipe(this.craftMatrix, this.getWorld()) == null) return;
for (int i = 0; i < SIZEINVENTORY; i++)
{
ItemStack stack = this.craftMatrix.getStackInSlot(i);
if (stack == null)
{
this.memory[i] = null;
}
else
{
ItemStack stack2 = stack.copy();
stack2.stackSize = 0;
this.memory[i] = stack2;
}
}
}
public ItemStack getMemory(int i)
{
return this.memory[i];
}
@Override
public int getSizeInventory()
{
return SIZEINVENTORY;
}
@Override
public ItemStack getStackInSlot(int par1)
{
if (par1 < SIZEINVENTORY)
return this.craftMatrix.getStackInSlot(par1);
return CraftingManager.getInstance().findMatchingRecipe(this.craftMatrix, this.getWorld());
}
@Override
public ItemStack decrStackSize(int par1, int par2)
{
if (par1 >= 0 && par1 < SIZEINVENTORY)
{
ItemStack result = this.craftMatrix.decrStackSize(par1, par2);
return result;
}
else if (par1 == SIZEINVENTORY)
{
boolean stillMatchesRecipe = true;
for (int i = 0; i < SIZEINVENTORY; i++)
{
ItemStack stack = this.craftMatrix.getStackInSlot(i);
ItemStack targetOther = this.memory[i];
if (targetOther == null && stack == null)
continue;
if (targetOther == null || stack == null || stack.stackSize <= 0 || !sameItem(targetOther, stack))
{
stillMatchesRecipe = false;
break;
}
}
if (stillMatchesRecipe)
{
ItemStack craftingResult = CraftingManager.getInstance().findMatchingRecipe(this.craftMatrix, this.getWorld());
if (craftingResult != null)
{
ItemStack[] aitemstack = CraftingManager.getInstance().func_180303_b(this.craftMatrix, this.worldObj);
for (int i = 0; i < aitemstack.length; ++i)
{
ItemStack itemstack = this.craftMatrix.getStackInSlot(i);
ItemStack itemstack1 = aitemstack[i];
if (itemstack != null)
{
this.craftMatrix.decrStackSize(i, 1);
}
if (itemstack1 != null)
{
if (this.craftMatrix.getStackInSlot(i) == null)
{
this.craftMatrix.setInventorySlotContents(i, itemstack1);
}
else
{
//TODO - things like buckets which can't go back into this - drop?
}
}
}
return craftingResult;
}
}
}
return null;
}
@Override
public ItemStack removeStackFromSlot(int par1)
{
if (par1 >= 0)
{
return this.craftMatrix.removeStackFromSlot(par1);
}
else
{
return null;
}
}
@Override
public void setInventorySlotContents(int par1, ItemStack par2ItemStack)
{
if (par1 >= 0 && par1 < SIZEINVENTORY)
{
this.craftMatrix.setInventorySlotContents(par1, par2ItemStack);
}
}
@Override
public String getName()
{
return GCCoreUtil.translate("container.magneticcrafting.name");
}
@Override
public boolean hasCustomName()
{
return true;
}
@Override
public void readFromNBT(NBTTagCompound nbt)
{
super.readFromNBT(nbt);
this.craftMatrix.clear();
for (int i = 0; i < SIZEINVENTORY; ++i)
this.memory[i] = null;
NBTTagList contents = nbt.getTagList("Items", 10);
if (contents != null && contents.tagCount() > 0)
{
for (int i = 0; i < contents.tagCount(); ++i)
{
NBTTagCompound var4 = contents.getCompoundTagAt(i);
int slot = var4.getByte("Slot") & 255;
if (slot < SIZEINVENTORY)
{
this.craftMatrix.setInventorySlotContents(slot, ItemStack.loadItemStackFromNBT(var4));
}
else if (slot < 18)
{
this.memory[slot - SIZEINVENTORY] = ItemStack.loadItemStackFromNBT(var4);
}
}
}
}
@Override
public void writeToNBT(NBTTagCompound nbt)
{
super.writeToNBT(nbt);
NBTTagList var2 = new NBTTagList();
for (int i = 0; i < SIZEINVENTORY; ++i)
{
if (this.craftMatrix.getStackInSlot(i) != null)
{
NBTTagCompound var4 = new NBTTagCompound();
var4.setByte("Slot", (byte) (i));
this.craftMatrix.getStackInSlot(i).writeToNBT(var4);
var2.appendTag(var4);
}
}
for (int i = 0; i < SIZEINVENTORY; ++i)
{
if (this.memory[i] != null)
{
NBTTagCompound var4 = new NBTTagCompound();
var4.setByte("Slot", (byte) (i + SIZEINVENTORY));
this.memory[i].writeToNBT(var4);
var2.appendTag(var4);
}
}
nbt.setTag("Items", var2);
}
@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;
}
@Override
public boolean isItemValidForSlot(int par1, ItemStack par2ItemStack)
{
return true;
}
@Override
public void invalidate()
{
super.invalidate();
this.updateContainingBlockInfo();
}
@Override
public int[] getSlotsForFace(EnumFacing side)
{
return new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
}
@Override
public boolean canInsertItem(int index, ItemStack stack, EnumFacing direction)
{
if (index >= SIZEINVENTORY) return false;
boolean override = this.overriddenMemory();
ItemStack target = override ? ItemStack.copyItemStack(this.craftMatrix.getStackInSlot(index)) : this.memory[index];
if (target != null && stack != null && sameItem(target, stack))
{
ItemStack is3 = this.getStackInSlot(index);
if (is3 == null) return true;
int currentSize = is3.stackSize;
//If any other slot matching this item has a smaller stacksize, return false (and hopefully that slot will be filled instead)
for (int i = 0; i < SIZEINVENTORY; i++)
{
if (i == index) continue;
ItemStack targetOther = override ? ItemStack.copyItemStack(this.craftMatrix.getStackInSlot(i)) : this.memory[i];
if (targetOther == null) continue;
//It's another memory slot matching this item
if (sameItem(targetOther, stack))
{
ItemStack itemstack2 = this.craftMatrix.getStackInSlot(i);
if (itemstack2 == null)
return false;
if (sameItem(stack, itemstack2))
{
if (itemstack2.stackSize < currentSize)
return false;
}
}
}
return true;
}
return false;
}
@Override
public boolean canExtractItem(int index, ItemStack stack, EnumFacing direction)
{
return index == SIZEINVENTORY;
}
/**
* Does not include a null check, do a null check first
*/
private boolean sameItem(ItemStack target, ItemStack stack)
{
return target.getItem() == stack.getItem() && (!stack.getHasSubtypes() || stack.getMetadata() == target.getMetadata()) && ItemStack.areItemStackTagsEqual(stack, target);
}
public boolean overrideMemory(ItemStack itemstack1, ItemStack[] memory2)
{
if (CraftingManager.getInstance().findMatchingRecipe(this.craftMatrix, this.getWorld()) != null)
{
//Valid recipe on the table. Does it fuzzy match this tile's memory (empty slots which should have recipe components are OK)
boolean fuzzyMatch = true;
for (int i = 0; i < 9; i++)
{
if (this.craftMatrix.getStackInSlot(i) != null && !matchingStacks(this.craftMatrix.getStackInSlot(i), this.getMemory(i)))
{
fuzzyMatch = false;
break;
}
}
//If it's a valid recipe and CAN'T match the memory, then override the remembered recipe
if (!fuzzyMatch)
{
for (int i = 0; i < 9; i++)
{
if (matchingStacks(itemstack1, this.craftMatrix.getStackInSlot(i)))
{
for (int j = 0; j < 9; j++)
{
memory2[j] = ItemStack.copyItemStack(this.craftMatrix.getStackInSlot(j));
}
return true;
}
}
}
}
return false;
}
public boolean overriddenMemory()
{
if (CraftingManager.getInstance().findMatchingRecipe(this.craftMatrix, this.getWorld()) != null)
{
//Valid recipe on the table. Does it fuzzy match this tile's memory (empty slots which should have recipe components are OK)
for (int i = 0; i < 9; i++)
{
if (this.craftMatrix.getStackInSlot(i) != null && !matchingStacks(this.craftMatrix.getStackInSlot(i), this.getMemory(i)))
{
return true;
}
}
}
return false;
}
private boolean matchingStacks(ItemStack stack, ItemStack target)
{
return target != null && target.getItem() == stack.getItem() && (!stack.getHasSubtypes() || stack.getMetadata() == target.getMetadata()) && ItemStack.areItemStackTagsEqual(stack, target) && target.isStackable() && target.stackSize < target.getMaxStackSize();
}
}