package com.jaquadro.minecraft.gardencore.block.tile; import com.jaquadro.minecraft.gardenapi.api.GardenAPI; import com.jaquadro.minecraft.gardenapi.api.machine.ICompostMaterial; import com.jaquadro.minecraft.gardencore.api.WoodRegistry; import com.jaquadro.minecraft.gardencore.block.BlockCompostBin; import com.jaquadro.minecraft.gardencore.block.BlockGardenProxy; import com.jaquadro.minecraft.gardencore.core.ModItems; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.*; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.ISidedInventory; import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemFood; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.network.NetworkManager; import net.minecraft.network.Packet; import net.minecraft.network.play.server.S35PacketUpdateTileEntity; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.IPlantable; import net.minecraftforge.oredict.OreDictionary; public class TileEntityCompostBin extends TileEntity implements ISidedInventory { private ItemStack[] compostItemStacks = new ItemStack[10]; // The number of ticks remaining to decompose the current item public int binDecomposeTime; // The slot actively being decomposed private int currentItemSlot; // The number of ticks that a fresh copy of the currently-decomposing item would decompose for public int currentItemDecomposeTime; public int itemDecomposeCount; private String customName; public int getDecompTime () { return binDecomposeTime; } public int getCurrentItemDecompTime () { return currentItemDecomposeTime; } @Override public void readFromNBT (NBTTagCompound tag) { super.readFromNBT(tag); NBTTagList tagList = tag.getTagList("Items", 10); compostItemStacks = new ItemStack[getSizeInventory()]; for (int i = 0; i < tagList.tagCount(); i++) { NBTTagCompound itemTag = tagList.getCompoundTagAt(i); byte slot = itemTag.getByte("Slot"); if (slot >= 0 && slot < compostItemStacks.length) compostItemStacks[slot] = ItemStack.loadItemStackFromNBT(itemTag); } binDecomposeTime = tag.getShort("DecompTime"); currentItemSlot = tag.getByte("DecompSlot"); itemDecomposeCount = tag.getByte("DecompCount"); if (currentItemSlot >= 0) currentItemDecomposeTime = getItemDecomposeTime(compostItemStacks[currentItemSlot]); else currentItemDecomposeTime = 0; if (tag.hasKey("CustomName", 8)) customName = tag.getString("CustomName"); } @Override public void writeToNBT (NBTTagCompound tag) { super.writeToNBT(tag); tag.setShort("DecompTime", (short)binDecomposeTime); tag.setByte("DecompSlot", (byte)currentItemSlot); tag.setByte("DecompCount", (byte)itemDecomposeCount); NBTTagList tagList = new NBTTagList(); for (int i = 0; i < compostItemStacks.length; i++) { if (compostItemStacks[i] != null) { NBTTagCompound itemTag = new NBTTagCompound(); itemTag.setByte("Slot", (byte)i); compostItemStacks[i].writeToNBT(itemTag); tagList.appendTag(itemTag); } } tag.setTag("Items", tagList); if (hasCustomInventoryName()) tag.setString("CustomName", customName); } @Override public Packet getDescriptionPacket () { NBTTagCompound tag = new NBTTagCompound(); writeToNBT(tag); return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 5, tag); } @Override public void onDataPacket (NetworkManager net, S35PacketUpdateTileEntity pkt) { readFromNBT(pkt.func_148857_g()); getWorldObj().func_147479_m(xCoord, yCoord, zCoord); // markBlockForRenderUpdate } public boolean isDecomposing () { return binDecomposeTime > 0; } @SideOnly(Side.CLIENT) public int getDecomposeTimeRemainingScaled (int scale) { if (currentItemDecomposeTime == 0) currentItemDecomposeTime = 200; return (8 - itemDecomposeCount) * scale / 9 + (binDecomposeTime * scale / (currentItemDecomposeTime * 9)); //return binDecomposeTime * scale / currentItemDecomposeTime; } @Override public void updateEntity () { boolean isDecomposing = binDecomposeTime > 0; int decompCount = itemDecomposeCount; boolean shouldUpdate = false; if (binDecomposeTime > 0) --binDecomposeTime; if (!worldObj.isRemote) { int filledSlotCount = 0; for (int i = 0; i < 9; i++) filledSlotCount += (compostItemStacks[i] != null) ? 1 : 0; if (binDecomposeTime != 0 || filledSlotCount > 0) { if (binDecomposeTime == 0) { /*if (currentItemSlot >= 0 && compostItemStacks[currentItemSlot] != null) { --compostItemStacks[currentItemSlot].stackSize; shouldUpdate = true; if (compostItemStacks[currentItemSlot].stackSize == 0) compostItemStacks[currentItemSlot] = compostItemStacks[currentItemSlot].getItem().getContainerItem(compostItemStacks[currentItemSlot]); }*/ if (canCompost()) { compostItem(); shouldUpdate = true; } currentItemSlot = selectRandomFilledSlot(); currentItemDecomposeTime = 0; if (currentItemSlot >= 0 && (compostItemStacks[9] == null || compostItemStacks[9].stackSize < 64)) { currentItemDecomposeTime = getItemDecomposeTime(compostItemStacks[currentItemSlot]); binDecomposeTime = currentItemDecomposeTime; if (binDecomposeTime > 0) shouldUpdate = true; } } } if (isDecomposing != binDecomposeTime > 0 || decompCount != itemDecomposeCount) { shouldUpdate = true; BlockCompostBin.updateBlockState(worldObj, xCoord, yCoord, zCoord); } } if (shouldUpdate) markDirty(); } private boolean canCompost () { if (currentItemSlot == -1) return false; if (compostItemStacks[currentItemSlot] == null) return false; if (compostItemStacks[currentItemSlot].stackSize == 0) return false; if (compostItemStacks[9] == null) return true; int result = compostItemStacks[9].stackSize + 1; return result <= getInventoryStackLimit() && result <= compostItemStacks[9].getMaxStackSize(); } public void compostItem () { if (canCompost()) { if (itemDecomposeCount < 8) itemDecomposeCount++; if (itemDecomposeCount == 8) { ItemStack resultStack = new ItemStack(ModItems.compostPile); if (compostItemStacks[9] == null) compostItemStacks[9] = resultStack; else if (compostItemStacks[9].getItem() == resultStack.getItem()) compostItemStacks[9].stackSize += resultStack.stackSize; itemDecomposeCount = 0; } --compostItemStacks[currentItemSlot].stackSize; if (compostItemStacks[currentItemSlot].stackSize == 0) compostItemStacks[currentItemSlot] = null; currentItemSlot = -1; } } public boolean hasInputItems () { int filledSlotCount = 0; for (int i = 0; i < 9; i++) filledSlotCount += (compostItemStacks[i] != null) ? 1 : 0; return filledSlotCount > 0; } public boolean hasOutputItems () { return compostItemStacks[9] != null && compostItemStacks[9].stackSize > 0; } private int selectRandomFilledSlot () { int filledSlotCount = 0; for (int i = 0; i < 9; i++) filledSlotCount += (compostItemStacks[i] != null) ? 1 : 0; if (filledSlotCount == 0) return -1; int index = worldObj.rand.nextInt(filledSlotCount); for (int i = 0, c = 0; i < 9; i++) { if (compostItemStacks[i] != null) { if (c++ == index) return i; } } return -1; } public static int getItemDecomposeTime (ItemStack itemStack) { if (itemStack == null) return 0; ICompostMaterial material = GardenAPI.instance().registries().compost().getCompostMaterialInfo(itemStack); if (material == null) return 0; return material.getDecomposeTime(); } public static boolean isItemDecomposable (ItemStack itemStack) { return getItemDecomposeTime(itemStack) > 0; } @Override public int getSizeInventory () { return compostItemStacks.length; } @Override public ItemStack getStackInSlot (int slot) { return compostItemStacks[slot]; } @Override public ItemStack decrStackSize (int slot, int count) { ItemStack returnStack = null; if (compostItemStacks[slot] != null) { if (compostItemStacks[slot].stackSize <= count) { returnStack = compostItemStacks[slot]; compostItemStacks[slot] = null; } else { returnStack = compostItemStacks[slot].splitStack(count); if (compostItemStacks[slot].stackSize == 0) compostItemStacks[slot] = null; } } if (slot == 9 && compostItemStacks[slot] == null) BlockCompostBin.updateBlockState(worldObj, xCoord, yCoord, zCoord); return returnStack; } @Override public ItemStack getStackInSlotOnClosing (int slot) { return null; } @Override public void setInventorySlotContents (int slot, ItemStack itemStack) { compostItemStacks[slot] = itemStack; if (itemStack != null && itemStack.stackSize > getInventoryStackLimit()) itemStack.stackSize = getInventoryStackLimit(); } @Override public String getInventoryName () { return hasCustomInventoryName() ? customName : "container.gardencore.compostBin"; } @Override public boolean hasCustomInventoryName () { return customName != null && customName.length() > 0; } @Override public int getInventoryStackLimit () { return 64; } @Override public boolean isUseableByPlayer (EntityPlayer player) { if (worldObj.getTileEntity(xCoord, yCoord, zCoord) != this) return false; return player.getDistanceSq(xCoord + .5, yCoord + .5, zCoord + .5) <= 64; } @Override public void openInventory () { } @Override public void closeInventory () { } @Override public boolean isItemValidForSlot (int slot, ItemStack item) { if (slot >= 0 && slot < 9) return isItemDecomposable(item); return false; } private int[] accessSlots = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; @Override public int[] getAccessibleSlotsFromSide (int side) { return accessSlots; } @Override public boolean canInsertItem (int slot, ItemStack item, int side) { if (slot == 9) return false; return isItemValidForSlot(slot, item); } @Override public boolean canExtractItem (int slot, ItemStack item, int side) { if (slot != 9) return false; if (item == null) return false; return item.getItem() == ModItems.compostPile; } }