package pneumaticCraft.common.tileentity; import java.util.ArrayList; import java.util.List; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Items; import net.minecraft.inventory.ISidedInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Facing; import net.minecraftforge.common.util.ForgeDirection; import pneumaticCraft.common.block.Blockss; import pneumaticCraft.common.network.DescSynced; import pneumaticCraft.common.network.FilteredSynced; import pneumaticCraft.common.network.GuiSynced; import pneumaticCraft.common.network.LazySynced; import pneumaticCraft.common.util.PneumaticCraftUtils; import pneumaticCraft.lib.GuiConstants; import pneumaticCraft.lib.PneumaticValues; import pneumaticCraft.lib.Sounds; public class TileEntityPressureChamberInterface extends TileEntityPressureChamberWall implements ISidedInventory, IGUITextFieldSensitive, IRedstoneControlled{ @DescSynced @FilteredSynced(index = 0) private ItemStack[] inventory = new ItemStack[14]; @DescSynced @LazySynced public int inputProgress; public int oldInputProgress; @DescSynced @LazySynced public int outputProgress; public int oldOutputProgress; public static final int MAX_PROGRESS = 40; private static final int UPGRADE_SLOT_START = 1; private static final int UPGRADE_SLOT_END = 4; @GuiSynced public EnumInterfaceMode interfaceMode = EnumInterfaceMode.NONE; @GuiSynced private boolean enoughAir = true; @DescSynced public EnumFilterMode filterMode = EnumFilterMode.ITEM; @GuiSynced public int creativeTabID; @DescSynced public String itemNameFilter = ""; private boolean isOpeningI;//used to determine sounds. private boolean isOpeningO;//used to determine sounds. @DescSynced private boolean shouldOpenInput, shouldOpenOutput; @GuiSynced public int redstoneMode; private int inputTimeOut; private int oldItemCount; public enum EnumInterfaceMode{ NONE, IMPORT, EXPORT; } public enum EnumFilterMode{ ITEM, CREATIVE_TAB, NAME_BEGINS, NAME_CONTAINS; } public TileEntityPressureChamberInterface(){ setUpgradeSlots(new int[]{UPGRADE_SLOT_START, 2, 3, UPGRADE_SLOT_END}); } @Override public void updateEntity(){ super.updateEntity(); boolean wasOpeningI = isOpeningI; boolean wasOpeningO = isOpeningO; oldInputProgress = inputProgress; oldOutputProgress = outputProgress; TileEntityPressureChamberValve core = getCore(); if(!worldObj.isRemote) { int itemCount = inventory[0] != null ? inventory[0].stackSize : 0; if(oldItemCount != itemCount) { oldItemCount = itemCount; inputTimeOut = 0; } interfaceMode = getInterfaceMode(core); enoughAir = true; if(interfaceMode != EnumInterfaceMode.NONE) { if(inventory[0] != null && ++inputTimeOut > 10) { shouldOpenInput = false; if(inputProgress == 0) { shouldOpenOutput = true; if(outputProgress == MAX_PROGRESS) { if(interfaceMode == EnumInterfaceMode.IMPORT) { outputInChamber(); } else { exportToInventory(); } } } } else { shouldOpenOutput = false; if(outputProgress == 0) { shouldOpenInput = true; if(interfaceMode == EnumInterfaceMode.EXPORT && inputProgress == MAX_PROGRESS && redstoneAllows()) { importFromChamber(core); } } } } else { shouldOpenInput = false; shouldOpenOutput = false; } } int speed = (int)getSpeedMultiplierFromUpgrades(getUpgradeSlots()); if(shouldOpenInput) { inputProgress = Math.min(inputProgress + speed, MAX_PROGRESS); isOpeningI = true; } else { inputProgress = Math.max(inputProgress - speed, 0); isOpeningI = false; } if(shouldOpenOutput) { outputProgress = Math.min(outputProgress + speed, MAX_PROGRESS); isOpeningO = true; } else { outputProgress = Math.max(outputProgress - speed, 0); isOpeningO = false; } if(worldObj.isRemote && (wasOpeningI != isOpeningI || wasOpeningO != isOpeningO)) { worldObj.playSound(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5, Sounds.INTERFACE_DOOR, 0.1F, 1.0F, true); } } private void exportToInventory(){ ForgeDirection facing = ForgeDirection.getOrientation(getBlockMetadata()); TileEntity te = worldObj.getTileEntity(xCoord + facing.offsetX, yCoord + facing.offsetY, zCoord + facing.offsetZ); if(te != null) { ForgeDirection side = facing.getOpposite(); ItemStack leftoverStack = PneumaticCraftUtils.exportStackToInventory(te, inventory[0], side); if(leftoverStack == null || leftoverStack.stackSize == 0) { inventory[0] = null; } } } private void importFromChamber(TileEntityPressureChamberValve core){ ItemStack[] chamberStacks = core.getStacksInChamber(); for(ItemStack chamberStack : chamberStacks) { if((inventory[0] == null || inventory[0].isItemEqual(chamberStack)) && isItemValidForSlot(0, chamberStack)) { int maxAllowedItems = Math.abs(core.currentAir) / PneumaticValues.USAGE_CHAMBER_INTERFACE; if(maxAllowedItems > 0) { if(inventory[0] != null) maxAllowedItems = Math.min(maxAllowedItems, chamberStack.getMaxStackSize() - inventory[0].stackSize); int transferedItems = Math.min(chamberStack.stackSize, maxAllowedItems); core.addAir((core.currentAir > 0 ? -1 : 1) * transferedItems * PneumaticValues.USAGE_CHAMBER_INTERFACE, ForgeDirection.UNKNOWN); ItemStack transferedStack = chamberStack.copy().splitStack(transferedItems); ItemStack insertedStack = transferedStack.copy(); if(inventory[0] != null) insertedStack.stackSize += inventory[0].stackSize; setInventorySlotContents(0, insertedStack); core.clearStacksInChamber(transferedStack); } } } } private void outputInChamber(){ TileEntityPressureChamberValve valve = getCore(); if(valve != null) { for(int i = 0; i < 6; i++) { int x = xCoord + Facing.offsetsXForSide[i]; int y = yCoord + Facing.offsetsYForSide[i]; int z = zCoord + Facing.offsetsZForSide[i]; if(valve.isCoordWithinChamber(worldObj, x, y, z)) { enoughAir = Math.abs(valve.currentAir) > inventory[0].stackSize * PneumaticValues.USAGE_CHAMBER_INTERFACE; if(enoughAir) { valve.addAir((valve.currentAir > 0 ? -1 : 1) * inventory[0].stackSize * PneumaticValues.USAGE_CHAMBER_INTERFACE, ForgeDirection.UNKNOWN); EntityItem item = new EntityItem(worldObj, x + 0.5D, y + 0.5D, z + 0.5D, inventory[0].copy()); worldObj.spawnEntityInWorld(item); setInventorySlotContents(0, null); break; } } } } } /* * public void setCore(TileEntityPressureChamberValve core){ boolean * wasNotNull = teValve != null; super.setCore(core); if(worldObj.isRemote) * return; if(core != null) modeNeedsChecking = true; else if(wasNotNull) * modeNeedsChecking = true; } */ // figure out whether the Interface is exporting or importing. private EnumInterfaceMode getInterfaceMode(TileEntityPressureChamberValve core){ if(core != null) { boolean xMid = xCoord != core.multiBlockX && xCoord != core.multiBlockX + core.multiBlockSize - 1; boolean yMid = yCoord != core.multiBlockY && yCoord != core.multiBlockY + core.multiBlockSize - 1; boolean zMid = zCoord != core.multiBlockZ && zCoord != core.multiBlockZ + core.multiBlockSize - 1; int meta = getBlockMetadata(); if(xMid && yMid && meta == 2 || xMid && zMid && meta == 0 || yMid && zMid && meta == 4) { if(xCoord == core.multiBlockX || yCoord == core.multiBlockY || zCoord == core.multiBlockZ) { return EnumInterfaceMode.EXPORT; } else { return EnumInterfaceMode.IMPORT; } } else if(xMid && yMid && meta == 3 || xMid && zMid && meta == 1 || yMid && zMid && meta == 5) { if(xCoord == core.multiBlockX || yCoord == core.multiBlockY || zCoord == core.multiBlockZ) { return EnumInterfaceMode.IMPORT; } else { return EnumInterfaceMode.EXPORT; } } } return EnumInterfaceMode.NONE; } public List<String> getProblemStat(){ List<String> textList = new ArrayList<String>(); if(interfaceMode == EnumInterfaceMode.NONE) { textList.addAll(PneumaticCraftUtils.convertStringIntoList("\u00a77The Interface can't work.", GuiConstants.maxCharPerLineLeft)); textList.addAll(PneumaticCraftUtils.convertStringIntoList("\u00a70-The Interface is not in a properly formed Pressure Chamber, and/or", GuiConstants.maxCharPerLineLeft)); textList.addAll(PneumaticCraftUtils.convertStringIntoList("\u00a70-The Interface is not adjacent to an air block of the Pressure Chamber, and/or", GuiConstants.maxCharPerLineLeft)); textList.addAll(PneumaticCraftUtils.convertStringIntoList("\u00a70-The Interface isn't orientated right.", GuiConstants.maxCharPerLineLeft)); } else if(!redstoneAllows()) { textList.add("gui.tab.problems.redstoneDisallows"); } else if(!enoughAir) { textList.addAll(PneumaticCraftUtils.convertStringIntoList("\u00a77There's not enough pressure in the Pressure Chamber to move the items.", GuiConstants.maxCharPerLineLeft)); textList.addAll(PneumaticCraftUtils.convertStringIntoList("\u00a70Apply more pressure to the Pressure Chamber. The required pressure is dependent on the amount of items being transported.", GuiConstants.maxCharPerLineLeft)); } return textList; } public boolean hasEnoughPressure(){ return enoughAir; } @Override public boolean redstoneAllows(){ switch(redstoneMode){ case 0: return true; case 1: return worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord); case 2: return !worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord); } return false; } // INVENTORY METHODS- && NBT // ------------------------------------------------------------ @Override public void readFromNBT(NBTTagCompound tag){ super.readFromNBT(tag); // Read in the ItemStacks in the inventory from NBT NBTTagList tagList = tag.getTagList("Items", 10); inventory = new ItemStack[getSizeInventory()]; for(int i = 0; i < tagList.tagCount(); i++) { NBTTagCompound tagCompound = tagList.getCompoundTagAt(i); byte slot = tagCompound.getByte("Slot"); if(slot >= 0 && slot < inventory.length) { inventory[slot] = ItemStack.loadItemStackFromNBT(tagCompound); } } outputProgress = tag.getInteger("outputProgress"); inputProgress = tag.getInteger("inputProgress"); interfaceMode = EnumInterfaceMode.values()[tag.getInteger("interfaceMode")]; filterMode = EnumFilterMode.values()[tag.getInteger("filterMode")]; creativeTabID = tag.getInteger("creativeTabID"); itemNameFilter = tag.getString("itemNameFilter"); redstoneMode = tag.getInteger("redstoneMode"); } @Override public void writeToNBT(NBTTagCompound tag){ super.writeToNBT(tag); // Write the ItemStacks in the inventory to NBT NBTTagList tagList = new NBTTagList(); for(int i = 0; i < inventory.length; i++) if(inventory[i] != null) { NBTTagCompound tagCompound = new NBTTagCompound(); tagCompound.setByte("Slot", (byte)i); inventory[i].writeToNBT(tagCompound); tagList.appendTag(tagCompound); } tag.setTag("Items", tagList); tag.setInteger("outputProgress", outputProgress); tag.setInteger("inputProgress", inputProgress); tag.setInteger("interfaceMode", interfaceMode.ordinal()); tag.setInteger("filterMode", filterMode.ordinal()); tag.setInteger("creativeTabID", creativeTabID); tag.setString("itemNameFilter", itemNameFilter); tag.setInteger("redstoneMode", redstoneMode); } /** * Returns the number of slots in the inventory. */ @Override public int getSizeInventory(){ return 14; } /** * Returns the stack in slot i */ @Override public ItemStack getStackInSlot(int slot){ return inventory[slot]; } @Override public ItemStack decrStackSize(int slot, int amount){ ItemStack itemStack = getStackInSlot(slot); if(itemStack != null) { if(itemStack.stackSize <= amount) { setInventorySlotContents(slot, null); } else { itemStack = itemStack.splitStack(amount); if(itemStack.stackSize == 0) { setInventorySlotContents(slot, null); } } } return itemStack; } @Override public ItemStack getStackInSlotOnClosing(int slot){ ItemStack itemStack = getStackInSlot(slot); if(itemStack != null) { setInventorySlotContents(slot, null); } return itemStack; } @Override public void setInventorySlotContents(int slot, ItemStack itemStack){ inventory[slot] = itemStack; if(itemStack != null && itemStack.stackSize > getInventoryStackLimit()) { itemStack.stackSize = getInventoryStackLimit(); } if(!worldObj.isRemote && slot == 0) { sendDescriptionPacket(); } } @Override public int getInventoryStackLimit(){ return 64; } @Override public String getInventoryName(){ return Blockss.pressureChamberInterface.getUnlocalizedName(); } @Override public void openInventory(){} @Override public void closeInventory(){} @Override public boolean isItemValidForSlot(int slot, ItemStack iStack){ if(iStack == null) return false; switch(filterMode){ case ITEM: boolean filterEmpty = true; for(int i = 0; i < 9; i++) { ItemStack filterStack = getStackInSlot(i + 5); if(filterStack != null) { filterEmpty = false; if(iStack.isItemEqual(filterStack)) { return true; } } } return filterEmpty; case CREATIVE_TAB: try { int itemCreativeTabIndex = iStack.getItem().getCreativeTab() != null ? iStack.getItem().getCreativeTab().getTabIndex() : -1; if(itemCreativeTabIndex == creativeTabID) { return true; } } catch(Throwable e) {//when we are SMP getCreativeTab() is client only. filterMode = EnumFilterMode.NAME_BEGINS; } return false; case NAME_BEGINS: return iStack.getDisplayName().toLowerCase().startsWith(itemNameFilter.toLowerCase()); case NAME_CONTAINS: return iStack.getDisplayName().toLowerCase().contains(itemNameFilter.toLowerCase()); } return false; } @Override public boolean isUseableByPlayer(EntityPlayer entityplayer){ return true; } @Override public boolean isGuiUseableByPlayer(EntityPlayer par1EntityPlayer){ return worldObj.getTileEntity(xCoord, yCoord, zCoord) != this ? false : par1EntityPlayer.getDistanceSq(xCoord + 0.5D, yCoord + 0.5D, zCoord + 0.5D) <= 64.0D; } @Override public int[] getAccessibleSlotsFromSide(int var1){ return new int[]{0}; } @Override public boolean canInsertItem(int i, ItemStack itemstack, int j){ return inputProgress == MAX_PROGRESS && j == getRotation().getOpposite().ordinal() && redstoneAllows(); } @Override public boolean canExtractItem(int i, ItemStack itemstack, int j){ return outputProgress == MAX_PROGRESS && j == getRotation().ordinal(); } @Override public void handleGUIButtonPress(int guiID, EntityPlayer player){ if(guiID == 1) { if(filterMode.ordinal() >= EnumFilterMode.values().length - 1) { filterMode = EnumFilterMode.ITEM; } else { filterMode = EnumFilterMode.values()[filterMode.ordinal() + 1]; } isItemValidForSlot(0, new ItemStack(Items.stick));//when an SideOnly exception is thrown this method automatically will set the filter mode to Item. } else if(guiID == 2) { creativeTabID++; if(creativeTabID == 5 || creativeTabID == 11) creativeTabID++; if(creativeTabID >= CreativeTabs.creativeTabArray.length) { creativeTabID = 0; } } else if(guiID == 0) { redstoneMode++; if(redstoneMode > 2) redstoneMode = 0; } } @Override public void setText(int textFieldID, String text){ itemNameFilter = text; } @Override public String getText(int textFieldID){ return itemNameFilter; } @Override public boolean hasCustomInventoryName(){ return false; } @Override public int getRedstoneMode(){ return redstoneMode; } }