package com.projectreddog.machinemod.tileentities; import com.projectreddog.machinemod.init.ModNetwork; import com.projectreddog.machinemod.network.MachineModMessageRequestTEAllInventoryToServer; import com.projectreddog.machinemod.network.MachineModMessageTEInventoryChangedToClient; import com.projectreddog.machinemod.reference.Reference; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.inventory.ISidedInventory; import net.minecraft.inventory.InventoryHelper; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.ITickable; import scala.Int; public class TileEntityCrate extends TileEntity implements ITickable, ISidedInventory { protected ItemStack[] inventory; protected ItemStack DeepStorageType; int inventorySize = 2;// slot 0 = Output (down) Slot 1 = input (up & sides) boolean shouldRequestInvetoryUpdates = true; boolean shouldSendInvetoryUpdates = true; public int rotAmt = 0; public int AmtInReserve = 0; public ItemStack HeldItem; public TileEntityCrate() { inventory = new ItemStack[inventorySize]; } @Override public int getSizeInventory() { return inventory.length; } @Override public ItemStack getStackInSlot(int slot) { return inventory[slot]; } @Override public ItemStack decrStackSize(int slot, int amt) { ItemStack stack = getStackInSlot(slot); if (stack != null) { if (stack.stackSize <= amt) { setInventorySlotContents(slot, null); } else { stack = stack.splitStack(amt); if (stack.stackSize == 0) { setInventorySlotContents(slot, null); } } } shouldSendInvetoryUpdates = true; return stack; } @Override public ItemStack removeStackFromSlot(int slot) { ItemStack stack = getStackInSlot(slot); if (stack != null) { setInventorySlotContents(slot, null); } shouldSendInvetoryUpdates = true; return stack; } @Override public void setInventorySlotContents(int slot, ItemStack stack) { inventory[slot] = stack; if (stack != null && stack.stackSize > getInventoryStackLimit()) { stack.stackSize = getInventoryStackLimit(); } shouldSendInvetoryUpdates = true; } @Override public int getInventoryStackLimit() { return Int.MaxValue(); } @Override public boolean isUseableByPlayer(EntityPlayer player) { return player.getDistanceSq(this.getPos().getX(), this.getPos().getY(), this.getPos().getZ()) < 64; } @Override public void openInventory(EntityPlayer player) { } @Override public void closeInventory(EntityPlayer player) { // TODO Auto-generated method stub } @Override public boolean isItemValidForSlot(int index, ItemStack stack) { return true; } @Override public int getField(int id) { return 0; } @Override public void setField(int id, int value) { } @Override public int getFieldCount() { return 0; } @Override public void clear() { for (int i = 0; i < inventory.length; ++i) { inventory[i] = null; } } @Override public String getName() { // TODO Auto-generated method stub return null; } @Override public boolean hasCustomName() { // TODO Auto-generated method stub return false; } @Override public int[] getSlotsForFace(EnumFacing side) { // slot 0 = Output (down) Slot 1 = input (up & sides) int[] Slots; if (side == EnumFacing.DOWN) { Slots = new int[] { 0 }; } else { Slots = new int[] { 1 }; } return Slots; } @Override public boolean canInsertItem(int slot, ItemStack itemStackIn, EnumFacing direction) { // only slot 1 is input ! // need to check item too if (itemStackIn.isItemEqual(HeldItem) || HeldItem == null) { // same input item or held item is null so accept the item ! if (slot == 1 && (direction == EnumFacing.NORTH || direction == EnumFacing.SOUTH || direction == EnumFacing.EAST || direction == EnumFacing.WEST || direction == EnumFacing.UP)) { return true; } } return false; } @Override public boolean canExtractItem(int slot, ItemStack stack, EnumFacing direction) { if (slot < inventorySize && (direction == EnumFacing.DOWN)) { return true; } return false; } @Override public void readFromNBT(NBTTagCompound compound) { super.readFromNBT(compound); // inventory AmtInReserve = compound.getInteger(Reference.MACHINE_MOD_NBT_PREFIX + "AMTINRESERVE"); NBTTagList tagList = compound.getTagList(Reference.MACHINE_MOD_NBT_PREFIX + "Inventory", compound.getId()); for (int i = 0; i < tagList.tagCount(); i++) { NBTTagCompound tag = (NBTTagCompound) tagList.getCompoundTagAt(i); byte slot = tag.getByte("Slot"); if (slot >= 0 && slot < inventory.length) { inventory[slot] = ItemStack.loadItemStackFromNBT(tag); } } } @Override public NBTTagCompound writeToNBT(NBTTagCompound compound) { super.writeToNBT(compound); // inventory compound.setInteger(Reference.MACHINE_MOD_NBT_PREFIX + "AMTINRESERVE", AmtInReserve); NBTTagList itemList = new NBTTagList(); for (int i = 0; i < inventory.length; i++) { ItemStack stack = inventory[i]; if (stack != null) { NBTTagCompound tag = new NBTTagCompound(); tag.setByte("Slot", (byte) i); stack.writeToNBT(tag); itemList.appendTag(tag); } } compound.setTag(Reference.MACHINE_MOD_NBT_PREFIX + "Inventory", itemList); return compound; } /* * */ public boolean AddStack(ItemStack stackToAdd) { if (stackToAdd.isItemEqual(HeldItem) || HeldItem == null) { processInputOutputSlots(); setInventorySlotContents(1, stackToAdd); shouldSendInvetoryUpdates = true; return true; } else { return false; } } /* * amount is ignored for now will only return full stack ! */ public boolean removeStack(int amount) { processInputOutputSlots(); if (getStackInSlot(0) == null) { processInputOutputSlots(); if (getStackInSlot(0) == null) { return false; } } InventoryHelper.spawnItemStack(this.worldObj, this.pos.getX(), this.pos.getY(), this.pos.getZ(), getStackInSlot(0)); setInventorySlotContents(0, null); processInputOutputSlots(); shouldSendInvetoryUpdates = true; return true; } public void DropItemsOnBreak() { while (AmtInReserve > 0 || getStackInSlot(0) != null) { // this will be ugly for full crates ! if (!removeStack(-1)) { // we couldnt spawn everything break the loop break; } } } public void processInputOutputSlots() { if (!worldObj.isRemote) { // server side // AmtInReserve // AmtInReserve = 999999900; if (getStackInSlot(0) != null) { if (getStackInSlot(0).stackSize == getStackInSlot(0).getMaxStackSize()) { // output full fill if input is not full if (getStackInSlot(1) != null) {// input // have stack in input and output full move to reserve if same item if (getStackInSlot(1).isItemEqual(getStackInSlot(0))) { // same item move to reserve AmtInReserve = AmtInReserve + getStackInSlot(1).stackSize; // set empty slot contents of input slot ! setInventorySlotContents(1, null); } } } else { // output not full if (getStackInSlot(1) != null) { // something in output so take it please ! if (getStackInSlot(0).getMaxStackSize() - getStackInSlot(0).stackSize >= getStackInSlot(1).stackSize) {// we can take it all so do so getStackInSlot(0).stackSize = getStackInSlot(0).stackSize + getStackInSlot(1).stackSize; setInventorySlotContents(1, null); } else { // to much input so take what we can and reserve the rest // find leftover by taking input Stack size - amt needed ( max size - curr size) int LeftOverAmt = getStackInSlot(1).stackSize - (getStackInSlot(0).getMaxStackSize() - getStackInSlot(0).stackSize); AmtInReserve = AmtInReserve + LeftOverAmt; getStackInSlot(0).stackSize = getStackInSlot(0).getMaxStackSize(); setInventorySlotContents(1, null); } } } } else { // nothing was in output stack check input if (getStackInSlot(1) != null) { // we have an item !! so lets store it in the held item for comparison purposes HeldItem = getStackInSlot(1).copy(); // move to output stack setInventorySlotContents(0, getStackInSlot(1).copy()); // clear input for more items to arrive setInventorySlotContents(1, null); } } // Need to refill output from reserve if (getStackInSlot(0) != null) { // has an item top it off if possible. if (getStackInSlot(0).stackSize < getStackInSlot(0).getMaxStackSize()) { // has room for more int amtNeeded = getStackInSlot(0).getMaxStackSize() - getStackInSlot(0).stackSize; if (amtNeeded <= AmtInReserve) { // we have enough top it off all the way ! AmtInReserve = AmtInReserve - amtNeeded; ItemStack TmpStack = getStackInSlot(0).copy(); TmpStack.stackSize = TmpStack.getMaxStackSize(); setInventorySlotContents(0, TmpStack); } else { // Do not have enough !!! Help ! ItemStack TmpStack = getStackInSlot(0).copy(); TmpStack.stackSize = TmpStack.stackSize + AmtInReserve; AmtInReserve = 0; setInventorySlotContents(0, TmpStack); } } // else already full no action needed } else { // no output stack ! // check reserve first ! if (AmtInReserve > 0) { // has reserve need to check held item ! if (HeldItem != null) { // has held item replenish the output stack then do normal checks if (AmtInReserve >= HeldItem.getMaxStackSize()) { // can create full stack ItemStack TmpStack = HeldItem.copy(); TmpStack.stackSize = TmpStack.getMaxStackSize(); AmtInReserve = AmtInReserve - TmpStack.getMaxStackSize(); setInventorySlotContents(0, TmpStack); } else { // need partial stack ItemStack TmpStack = HeldItem.copy(); ; TmpStack.stackSize = AmtInReserve; AmtInReserve = 0; setInventorySlotContents(0, TmpStack); } } } } } } @Override public void update() { // TODO Auto-generated method stub if (worldObj.isRemote) { rotAmt = rotAmt + 1; if (rotAmt > 360) { rotAmt = 0; } // client side so request inventory if (shouldRequestInvetoryUpdates) { ModNetwork.simpleNetworkWrapper.sendToServer((new MachineModMessageRequestTEAllInventoryToServer(this.getPos().getX(), this.getPos().getY(), this.getPos().getZ()))); shouldRequestInvetoryUpdates = false; } } else { processInputOutputSlots(); // server side send update if it has changed if (shouldSendInvetoryUpdates) { for (int i = 0; i < inventory.length; i++) { ModNetwork.simpleNetworkWrapper.sendToAll(new MachineModMessageTEInventoryChangedToClient(this.getPos().getX(), this.getPos().getY(), this.getPos().getZ(), i, inventory[i], this.AmtInReserve)); } shouldSendInvetoryUpdates = false; } } } public void sendAllInventoryToPlayer(EntityPlayerMP player) { for (int i = 0; i < inventory.length; i++) { ModNetwork.simpleNetworkWrapper.sendTo(new MachineModMessageTEInventoryChangedToClient(this.getPos().getX(), this.getPos().getY(), this.getPos().getZ(), i, inventory[i], this.AmtInReserve), player); } } }