package pneumaticCraft.common.tileentity; import java.util.ArrayList; import java.util.List; import java.util.Random; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.passive.EntityVillager; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.AxisAlignedBB; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; import pneumaticCraft.api.recipe.IPressureChamberRecipe; import pneumaticCraft.api.recipe.PressureChamberRecipe; import pneumaticCraft.api.tileentity.IAirHandler; import pneumaticCraft.common.AchievementHandler; import pneumaticCraft.common.DamageSourcePneumaticCraft; import pneumaticCraft.common.block.Blockss; import pneumaticCraft.common.config.Config; import pneumaticCraft.common.fluid.Fluids; import pneumaticCraft.common.item.ItemMachineUpgrade; import pneumaticCraft.common.item.Itemss; import pneumaticCraft.common.network.DescSynced; import pneumaticCraft.common.network.GuiSynced; import pneumaticCraft.common.recipes.PneumaticRecipeRegistry; import pneumaticCraft.lib.PneumaticValues; public class TileEntityPressureChamberValve extends TileEntityPneumaticBase implements IInventory, IMinWorkingPressure{ @DescSynced public int multiBlockX; @DescSynced public int multiBlockY; @DescSynced public int multiBlockZ; @DescSynced public int multiBlockSize; public List<TileEntityPressureChamberValve> accessoryValves; private final List<int[]> nbtValveList; private boolean readNBT = false; @GuiSynced public boolean isValidRecipeInChamber; @GuiSynced public boolean isSufficientPressureInChamber; @GuiSynced public boolean areEntitiesDoneMoving; @GuiSynced public float recipePressure; private final Item etchingAcid = Fluids.getBucket(Fluids.etchingAcid); private ItemStack[] inventory = new ItemStack[4]; public static final int UPGRADE_SLOT_1 = 0; public static final int UPGRADE_SLOT_4 = 3; private final Random rand = new Random(); // private float oldPressure; // private int pressureUpdateTimer = 60; public TileEntityPressureChamberValve(){ super(PneumaticValues.DANGER_PRESSURE_PRESSURE_CHAMBER, PneumaticValues.MAX_PRESSURE_PRESSURE_CHAMBER, PneumaticValues.VOLUME_PRESSURE_CHAMBER); accessoryValves = new ArrayList<TileEntityPressureChamberValve>(); nbtValveList = new ArrayList<int[]>(); setUpgradeSlots(new int[]{UPGRADE_SLOT_1, 1, 2, UPGRADE_SLOT_4}); } @Override protected boolean shouldRerenderChunkOnDescUpdate(){ return true; } // pneumatic methods------------------------------------------------------- // used in the air dispersion methods. @Override public boolean isConnectedTo(ForgeDirection side){ switch(ForgeDirection.getOrientation(getBlockMetadata())){ case UP: case DOWN: return side == ForgeDirection.UP || side == ForgeDirection.DOWN; case NORTH: case SOUTH: return side == ForgeDirection.NORTH || side == ForgeDirection.SOUTH; case EAST: case WEST: return side == ForgeDirection.EAST || side == ForgeDirection.WEST; } return false; } @Override public List<Pair<ForgeDirection, IAirHandler>> getConnectedPneumatics(){ List<Pair<ForgeDirection, IAirHandler>> teList = super.getConnectedPneumatics(); if(accessoryValves != null) { for(TileEntityPressureChamberValve valve : accessoryValves) { if(valve != this) teList.add(new ImmutablePair(ForgeDirection.UNKNOWN, valve.getAirHandler())); } } return teList; } @Override protected int getVolumeFromUpgrades(int[] upgradeSlots){ return super.getVolumeFromUpgrades(getUpgradeSlots()) + (multiBlockSize > 0 ? (int)Math.pow(multiBlockSize - 2, 3) * PneumaticValues.VOLUME_PRESSURE_CHAMBER_PER_EMPTY : 0); } // main update method @Override public void updateEntity(){ if(readNBT) {// this way of doing this is needed because other TE's are // loaded after the reading of the NBT of this TE. readNBT = false; accessoryValves.clear(); for(int[] valve : nbtValveList) { TileEntity te = worldObj.getTileEntity(valve[0], valve[1], valve[2]); if(te instanceof TileEntityPressureChamberValve) { accessoryValves.add((TileEntityPressureChamberValve)te); } } if(accessoryValves.isEmpty()) {//Hacky solution for an unexplainable bug. invalidateMultiBlock(); checkIfProperlyFormed(worldObj, xCoord, yCoord, zCoord); } if(worldObj.isRemote) worldObj.markBlockRangeForRenderUpdate(xCoord, yCoord, zCoord, xCoord, yCoord, zCoord); } if(!worldObj.isRemote) { //code to check if we need to leak air. boolean[] connected = new boolean[]{true, true, true, true, true, true};//assume we are not leaking at any side switch(ForgeDirection.getOrientation(getBlockMetadata())){//take off the sides that tubes can connect to. case UP: case DOWN: connected[ForgeDirection.UP.ordinal()] = false; connected[ForgeDirection.DOWN.ordinal()] = false; break; case NORTH: case SOUTH: connected[ForgeDirection.NORTH.ordinal()] = false; connected[ForgeDirection.SOUTH.ordinal()] = false; break; case EAST: case WEST: connected[ForgeDirection.EAST.ordinal()] = false; connected[ForgeDirection.WEST.ordinal()] = false; break; } List<Pair<ForgeDirection, IAirHandler>> teList = super.getConnectedPneumatics();//we need the super method, as the overridden method adds the other valves. for(Pair<ForgeDirection, IAirHandler> entry : teList) { connected[entry.getKey().ordinal()] = true; } //retrieve the valve that is controlling the (potential) chamber. TileEntityPressureChamberValve baseValve = null; for(TileEntityPressureChamberValve valve : accessoryValves) { if(valve.multiBlockSize > 0) { baseValve = valve; break; } } //if we found one, we can scratch one side to be leaking air. if(baseValve != null) { switch(ForgeDirection.getOrientation(getBlockMetadata())){ case UP: case DOWN: if(baseValve.multiBlockY == yCoord) connected[ForgeDirection.UP.ordinal()] = true; else connected[ForgeDirection.DOWN.ordinal()] = true; break; case NORTH: case SOUTH: if(baseValve.multiBlockZ == zCoord) connected[ForgeDirection.SOUTH.ordinal()] = true; else connected[ForgeDirection.NORTH.ordinal()] = true; break; case EAST: case WEST: if(baseValve.multiBlockX == xCoord) connected[ForgeDirection.EAST.ordinal()] = true; else connected[ForgeDirection.WEST.ordinal()] = true; break; } } for(int i = 0; i < 6; i++) if(!connected[i]) airLeak(ForgeDirection.getOrientation(i)); } super.updateEntity(); /* * FIXME pressure chamber particle effects not updating properly * if(!worldObj.isRemote){ pressureUpdateTimer++; * System.out.println("timer: " + pressureUpdateTimer); * if(pressureUpdateTimer > 60){ pressureUpdateTimer = 0; * updatePressuresToClient(); } } */ if(multiBlockSize != 0 && !worldObj.isRemote) { ItemStack[] stacksInChamber = getStacksInChamber(); isValidRecipeInChamber = false; isSufficientPressureInChamber = false; recipePressure = Float.MAX_VALUE; //simple recipes for(PressureChamberRecipe recipe : PressureChamberRecipe.chamberRecipes) { boolean isValidRecipeInChamberFlag = canBeCompressed(recipe, stacksInChamber); boolean isSufficientPressureInChamberFlag = recipe.pressure <= getPressure(ForgeDirection.UNKNOWN) && recipe.pressure > 0F || recipe.pressure >= getPressure(ForgeDirection.UNKNOWN) && recipe.pressure < 0F; if(isValidRecipeInChamberFlag) { isValidRecipeInChamber = true; if(Math.abs(recipe.pressure) < Math.abs(recipePressure)) { recipePressure = recipe.pressure; } } if(isSufficientPressureInChamberFlag) isSufficientPressureInChamber = true; if(isValidRecipeInChamberFlag && isSufficientPressureInChamberFlag && areEntitiesDoneMoving) { double[] outputPosition = clearStacksInChamber(recipe.input); giveOutput(recipe.output, outputPosition); } } //special recipes for(IPressureChamberRecipe recipe : PressureChamberRecipe.specialRecipes) { ItemStack[] removedStacks = recipe.isValidRecipe(stacksInChamber); boolean isValidRecipeInChamberFlag = removedStacks != null; boolean isSufficientPressureInChamberFlag = recipe.getCraftingPressure() <= getPressure(ForgeDirection.UNKNOWN) && recipe.getCraftingPressure() > 0F || recipe.getCraftingPressure() >= getPressure(ForgeDirection.UNKNOWN) && recipe.getCraftingPressure() < 0F; if(isValidRecipeInChamberFlag) { isValidRecipeInChamber = true; if(Math.abs(recipe.getCraftingPressure()) < Math.abs(recipePressure)) { recipePressure = recipe.getCraftingPressure(); } } if(isSufficientPressureInChamberFlag) isSufficientPressureInChamber = true; if(isValidRecipeInChamberFlag && isSufficientPressureInChamberFlag && areEntitiesDoneMoving) { double[] outputPosition = clearStacksInChamber(removedStacks); giveOutput(recipe.craftRecipe(stacksInChamber, removedStacks), outputPosition); } } if(getPressure(ForgeDirection.UNKNOWN) > PneumaticValues.MAX_PRESSURE_LIVING_ENTITY) { AxisAlignedBB bbBox = AxisAlignedBB.getBoundingBox(multiBlockX + 1, multiBlockY + 1, multiBlockZ + 1, multiBlockX + multiBlockSize - 1, multiBlockY + multiBlockSize - 1, multiBlockZ + multiBlockSize - 1); List<EntityLivingBase> entities = worldObj.getEntitiesWithinAABB(EntityLivingBase.class, bbBox); for(EntityLivingBase entity : entities) { if(entity instanceof EntityVillager) { EntityVillager villager = (EntityVillager)entity; if(villager.getProfession() != Config.villagerMechanicID) { villager.setProfession(Config.villagerMechanicID); NBTTagCompound tag = new NBTTagCompound(); villager.writeEntityToNBT(tag); if(tag.hasKey("Offers")) {//reset the trade list tag.removeTag("Offers"); villager.readEntityFromNBT(tag); } } } entity.attackEntityFrom(DamageSourcePneumaticCraft.pressure, (int)(getPressure(ForgeDirection.UNKNOWN) * 2D)); } } } // move entities to eachother. AxisAlignedBB bbBox = AxisAlignedBB.getBoundingBox(multiBlockX, multiBlockY, multiBlockZ, multiBlockX + multiBlockSize, multiBlockY + multiBlockSize, multiBlockZ + multiBlockSize); List<EntityItem> entities = worldObj.getEntitiesWithinAABB(EntityItem.class, bbBox); areEntitiesDoneMoving = true; // set to true, set to false when one of // the entities is moving. for(int i = 0; i < entities.size() - 1; i++) { EntityItem lastEntity = entities.get(i); EntityItem entity = entities.get(i + 1); // XP Orb code snippet double d0 = 8.0D; double d1 = (lastEntity.posX - entity.posX) / d0; double d3 = (lastEntity.posZ - entity.posZ) / d0; double d4 = Math.sqrt(d1 * d1 + d3 * d3); double d5 = 1.0D - d4; if(d5 > 0.0D && d4 > 0.02D) { d5 *= d5; entity.motionX += d1 / d4 * d5 * 0.01D; entity.motionZ += d3 / d4 * d5 * 0.01D; lastEntity.motionX -= d1 / d4 * d5 * 0.01D; lastEntity.motionZ -= d3 / d4 * d5 * 0.01D; areEntitiesDoneMoving = false; } } boolean lifeUpgrade = getUpgrades(ItemMachineUpgrade.UPGRADE_ITEM_LIFE, getUpgradeSlots()) > 0; if(lifeUpgrade && !worldObj.isRemote) { for(EntityItem entity : entities) { entity.age--; } } // particles if(worldObj.isRemote && getPressure(ForgeDirection.UNKNOWN) > 0.2D) { int particles = (int)Math.pow(multiBlockSize - 2, 3); for(int i = 0; i < particles; i++) { if(rand.nextInt(Math.max(1, 8 - (int)(getPressure(ForgeDirection.UNKNOWN) * 2D))) == 0) { double posX = multiBlockX + 1D + rand.nextDouble() * (multiBlockSize - 2D); double posY = multiBlockY + 1D + rand.nextDouble() * (multiBlockSize - 2D); double posZ = multiBlockZ + 1D + rand.nextDouble() * (multiBlockSize - 2D); worldObj.spawnParticle("explode", posX, posY, posZ, 0D, 0D, 0D); } } } } private boolean canBeCompressed(PressureChamberRecipe recipe, ItemStack[] items){ for(Object in : recipe.input) { if(in != null) { int amount = 0; for(ItemStack item : items) { if(item != null && PneumaticRecipeRegistry.isItemEqual(in, item)) amount += item.stackSize; } if(amount < PneumaticRecipeRegistry.getItemAmount(in)) return false; } } return true; } public ItemStack[] getStacksInChamber(){ List<ItemStack> stackList = new ArrayList<ItemStack>(); // first make a // list, convert // it to an // array // afterwards. /*for(int i = 0; i < multiBlockSize - 2; i++) { for(int j = 0; j < multiBlockSize - 2; j++) { for(int k = 0; k < multiBlockSize - 2; k++) { Block blockID = worldObj.getBlock(i + multiBlockX + 1, j + multiBlockY + 1, k + multiBlockZ + 1); if(!blockID.isAir(worldObj, i + multiBlockX + 1, j + multiBlockY + 1, k + multiBlockZ + 1)) { ItemStack stack = new ItemStack(blockID, 1, worldObj.getBlockMetadata(i + multiBlockX + 1, j + multiBlockY + 1, k + multiBlockZ + 1)); if(stack.getItem() != null) addStackToList(stackList, stack);//getItem() shouldn't ever be able to be null, but still some defence cuz https://github.com/MineMaarten/PneumaticCraft-API/issues/60 } } } }*/ // add Item entities lying on the ground. AxisAlignedBB bbBox = AxisAlignedBB.getBoundingBox(multiBlockX, multiBlockY, multiBlockZ, multiBlockX + multiBlockSize, multiBlockY + multiBlockSize, multiBlockZ + multiBlockSize); List<EntityItem> entities = worldObj.getEntitiesWithinAABB(EntityItem.class, bbBox); for(EntityItem entity : entities) { if(entity.isDead) continue; stackList.add(entity.getEntityItem()); } return stackList.toArray(new ItemStack[stackList.size()]); // return an // into an // array // converted // list } public double[] clearStacksInChamber(Object... stacksToClear){ int[] stackSizes = new int[stacksToClear.length]; for(int i = 0; i < stacksToClear.length; i++) { stackSizes[i] = PneumaticRecipeRegistry.getItemAmount(stacksToClear[i]); } // default the output position to the middle of the chamber. double[] outputPosition = new double[]{multiBlockX + multiBlockSize / 2D, multiBlockY + 1.2D, multiBlockZ + multiBlockSize / 2D}; // get the in world EntityItems AxisAlignedBB bbBox = AxisAlignedBB.getBoundingBox(multiBlockX, multiBlockY, multiBlockZ, multiBlockX + multiBlockSize, multiBlockY + multiBlockSize, multiBlockZ + multiBlockSize); List<EntityItem> entities = worldObj.getEntitiesWithinAABB(EntityItem.class, bbBox); for(EntityItem entity : entities) { if(entity.isDead) continue; ItemStack entityStack = entity.getEntityItem(); for(int l = 0; l < stacksToClear.length; l++) { if(PneumaticRecipeRegistry.isItemEqual(stacksToClear[l], entityStack) && stackSizes[l] > 0) { outputPosition[0] = entity.posX; outputPosition[1] = entity.posY; outputPosition[2] = entity.posZ; int removedItems = Math.min(stackSizes[l], entityStack.stackSize); stackSizes[l] -= removedItems; entityStack.stackSize -= removedItems; if(entityStack.stackSize <= 0) entity.setDead(); break; } } } return outputPosition; } private void giveOutput(ItemStack[] output, double[] outputPosition){ for(ItemStack iStack : output) { if(iStack.getItem() == etchingAcid) { for(EntityPlayer player : (List<EntityPlayer>)worldObj.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBox(xCoord - 32, yCoord - 32, zCoord - 32, xCoord + 32, yCoord + 32, zCoord + 32))) { AchievementHandler.giveAchievement(player, new ItemStack(etchingAcid)); } } EntityItem item = new EntityItem(worldObj, outputPosition[0], outputPosition[1], outputPosition[2], iStack.copy()); worldObj.spawnEntityInWorld(item); } } // NBT methods----------------------------------------------- @Override public void readFromNBT(NBTTagCompound tag){ super.readFromNBT(tag); multiBlockX = tag.getInteger("multiBlockX"); multiBlockY = tag.getInteger("multiBlockY"); multiBlockZ = tag.getInteger("multiBlockZ"); multiBlockSize = tag.getInteger("multiBlockSize"); isSufficientPressureInChamber = tag.getBoolean("sufPressure"); isValidRecipeInChamber = tag.getBoolean("validRecipe"); recipePressure = tag.getFloat("recipePressure"); // 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); } } // Read in the accessory valves from NBT NBTTagList tagList2 = tag.getTagList("Valves", 10); nbtValveList.clear(); for(int i = 0; i < tagList2.tagCount(); ++i) { NBTTagCompound tagCompound = tagList2.getCompoundTagAt(i); if(tagCompound != null) { nbtValveList.add(new int[]{tagCompound.getInteger("xCoord"), tagCompound.getInteger("yCoord"), tagCompound.getInteger("zCoord")}); } } readNBT = true; } @Override public void writeToNBT(NBTTagCompound tag){ super.writeToNBT(tag); tag.setInteger("multiBlockX", multiBlockX); tag.setInteger("multiBlockY", multiBlockY); tag.setInteger("multiBlockZ", multiBlockZ); tag.setInteger("multiBlockSize", multiBlockSize); tag.setBoolean("sufPressure", isSufficientPressureInChamber); tag.setBoolean("validRecipe", isValidRecipeInChamber); tag.setFloat("recipePressure", recipePressure); // Write the ItemStacks in the inventory to NBT NBTTagList tagList = new NBTTagList(); for(int currentIndex = 0; currentIndex < inventory.length; ++currentIndex) { if(inventory[currentIndex] != null) { NBTTagCompound tagCompound = new NBTTagCompound(); tagCompound.setByte("Slot", (byte)currentIndex); inventory[currentIndex].writeToNBT(tagCompound); tagList.appendTag(tagCompound); } } tag.setTag("Items", tagList); // Write the accessory valve to NBT NBTTagList tagList2 = new NBTTagList(); for(TileEntityPressureChamberValve valve : accessoryValves) { NBTTagCompound tagCompound = new NBTTagCompound(); tagCompound.setInteger("xCoord", valve.xCoord); tagCompound.setInteger("yCoord", valve.yCoord); tagCompound.setInteger("zCoord", valve.zCoord); tagList2.appendTag(tagCompound); } tag.setTag("Valves", tagList2); } // Multi-block structure methods // -------------------------------------------------------- public void onMultiBlockBreak(){ dropInventory(worldObj, multiBlockX + multiBlockSize / 2D, multiBlockY + multiBlockSize / 2D, multiBlockZ + multiBlockSize / 2D); invalidateMultiBlock(); } private void dropInventory(World world, double x, double y, double z){ IInventory inventory = this; Random rand = new Random(); for(int i = 0; i < inventory.getSizeInventory(); i++) { ItemStack itemStack = inventory.getStackInSlot(i); if(itemStack != null && itemStack.stackSize > 0) { float dX = rand.nextFloat() * 0.8F - 0.4F; float dY = rand.nextFloat() * 0.8F - 0.4F; float dZ = rand.nextFloat() * 0.8F - 0.4F; EntityItem entityItem = new EntityItem(world, x + dX, y + dY, z + dZ, new ItemStack(itemStack.getItem(), itemStack.stackSize, itemStack.getItemDamage())); if(itemStack.hasTagCompound()) { entityItem.getEntityItem().setTagCompound((NBTTagCompound)itemStack.getTagCompound().copy()); } float factor = 0.05F; entityItem.motionX = rand.nextGaussian() * factor; entityItem.motionY = rand.nextGaussian() * factor + 0.2F; entityItem.motionZ = rand.nextGaussian() * factor; world.spawnEntityInWorld(entityItem); // itemStack.stackSize = 0; } } this.inventory = new ItemStack[4]; } private void invalidateMultiBlock(){ for(int x = 0; x < multiBlockSize; x++) { for(int y = 0; y < multiBlockSize; y++) { for(int z = 0; z < multiBlockSize; z++) { TileEntity te = worldObj.getTileEntity(x + multiBlockX, y + multiBlockY, z + multiBlockZ); if(te instanceof TileEntityPressureChamberWall) { TileEntityPressureChamberWall teWall = (TileEntityPressureChamberWall)te; teWall.setCore(null); // Clear the base TE's, so that // the walls can be used in a new // MultiBlock } } } } if(accessoryValves != null) { for(TileEntityPressureChamberValve valve : accessoryValves) { valve.setMultiBlockCoords(0, 0, 0, 0); if(valve != this) { valve.accessoryValves.clear(); valve.sendDescriptionPacket(); } } accessoryValves.clear(); } sendDescriptionPacket(); } public void setMultiBlockCoords(int size, int baseX, int baseY, int baseZ){ multiBlockSize = size; multiBlockX = baseX; multiBlockY = baseY; multiBlockZ = baseZ; } public static boolean checkIfProperlyFormed(World world, int x, int y, int z){ // ArrayList<int[]> blockList = getAccessoryTiles(new // ArrayList<int[]>(), world, x,y,z); for(int i = 3; i < 6; i++) { if(checkForShiftedCubeOfSize(i, world, x, y, z)) { return true; } } return false; } private static boolean checkForShiftedCubeOfSize(int size, World world, int baseX, int baseY, int baseZ){ for(int wallX = 0; wallX < size; wallX++) { for(int wallY = 0; wallY < size; wallY++) { // check every possible configuration the block can be in. if(checkForCubeOfSize(size, world, baseX, baseY - wallY, baseZ - wallX)) return true; if(checkForCubeOfSize(size, world, baseX, baseY + wallY, baseZ + wallX)) return true; if(checkForCubeOfSize(size, world, baseX - wallX, baseY - wallY, baseZ)) return true; if(checkForCubeOfSize(size, world, baseX + wallX, baseY + wallY, baseZ)) return true; if(checkForCubeOfSize(size, world, baseX - wallX, baseY, baseZ - wallY)) return true; if(checkForCubeOfSize(size, world, baseX + wallX, baseY, baseZ + wallY)) return true; if(checkForCubeOfSize(size, world, baseX - size + 1, baseY - wallY, baseZ - wallX)) return true; if(checkForCubeOfSize(size, world, baseX - size + 1, baseY + wallY, baseZ + wallX)) return true; if(checkForCubeOfSize(size, world, baseX - wallX, baseY - wallY, baseZ - size + 1)) return true; if(checkForCubeOfSize(size, world, baseX + wallX, baseY + wallY, baseZ - size + 1)) return true; if(checkForCubeOfSize(size, world, baseX - wallX, baseY - size + 1, baseZ - wallY)) return true; if(checkForCubeOfSize(size, world, baseX + wallX, baseY - size + 1, baseZ + wallY)) return true; } } return false; } private static boolean checkForCubeOfSize(int size, World world, int baseX, int baseY, int baseZ){ boolean validValveFound = false; for(int x = 0; x < size; x++) { for(int y = 0; y < size; y++) { for(int z = 0; z < size; z++) { if(x != 0 && x != size - 1 && y != 0 && y != size - 1 && z != 0 && z != size - 1) continue; if(world.getBlock(x + baseX, y + baseY, z + baseZ) != Blockss.pressureChamberWall && world.getBlock(x + baseX, y + baseY, z + baseZ) != Blockss.pressureChamberValve && world.getBlock(x + baseX, y + baseY, z + baseZ) != Blockss.pressureChamberInterface) { return false; } else if(world.getBlock(x + baseX, y + baseY, z + baseZ) == Blockss.pressureChamberValve) { boolean xMid = x != 0 && x != size - 1; boolean yMid = y != 0 && y != size - 1; boolean zMid = z != 0 && z != size - 1; ForgeDirection facing = ForgeDirection.getOrientation(world.getBlockMetadata(x + baseX, y + baseY, z + baseZ)); if(xMid && yMid && (facing == ForgeDirection.NORTH || facing == ForgeDirection.SOUTH) || xMid && zMid && (facing == ForgeDirection.UP || facing == ForgeDirection.DOWN) || yMid && zMid && (facing == ForgeDirection.EAST || facing == ForgeDirection.WEST)) { validValveFound = true; } else { return false; } } else {// when blockID == wall/interface TileEntity te = world.getTileEntity(x + baseX, y + baseY, z + baseZ); if(te instanceof TileEntityPressureChamberWall && ((TileEntityPressureChamberWall)te).getCore() != null) { return false; } } } } } // when the code makes it to here we've found a valid structure. it only // depends on whether there is a valid valve in the structure now. if(!validValveFound) return false; TileEntityPressureChamberValve teValve = null; List<TileEntityPressureChamberValve> valveList = new ArrayList<TileEntityPressureChamberValve>(); for(int x = 0; x < size; x++) { for(int y = 0; y < size; y++) { for(int z = 0; z < size; z++) { TileEntity te = world.getTileEntity(x + baseX, y + baseY, z + baseZ); if(te instanceof TileEntityPressureChamberValve) { boolean xMid = x != 0 && x != size - 1; boolean yMid = y != 0 && y != size - 1; boolean zMid = z != 0 && z != size - 1; ForgeDirection facing = ForgeDirection.getOrientation(world.getBlockMetadata(x + baseX, y + baseY, z + baseZ)); if(xMid && yMid && (facing == ForgeDirection.NORTH || facing == ForgeDirection.SOUTH) || xMid && zMid && (facing == ForgeDirection.UP || facing == ForgeDirection.DOWN) || yMid && zMid && (facing == ForgeDirection.EAST || facing == ForgeDirection.WEST)) { teValve = (TileEntityPressureChamberValve)te; valveList.add(teValve); } } } } } if(teValve == null) return false;// this line shouldn't be triggered // ever. // put the list of all the valves in the structure in all the valve // TE's. for(TileEntityPressureChamberValve valve : valveList) { valve.accessoryValves = new ArrayList<TileEntityPressureChamberValve>(valveList); valve.sendDescriptionPacket(); } // set the redirections of right clicking and breaking a wall block to // the valve. for(int x = 0; x < size; x++) { for(int y = 0; y < size; y++) { for(int z = 0; z < size; z++) { TileEntity te = world.getTileEntity(x + baseX, y + baseY, z + baseZ); if(te instanceof TileEntityPressureChamberWall) { TileEntityPressureChamberWall teWall = (TileEntityPressureChamberWall)te; teWall.setCore(teValve); // set base TE to the valve // found. } } } } // set the multi-block coords in the valve TE teValve.setMultiBlockCoords(size, baseX, baseY, baseZ); teValve.sendDescriptionPacket(); return true; } public boolean isCoordWithinChamber(World world, int x, int y, int z){ if(x > multiBlockX && x < multiBlockX + multiBlockSize - 1 && y > multiBlockY && y < multiBlockY + multiBlockSize - 1 && z > multiBlockZ && z < multiBlockZ + multiBlockSize - 1) { return true; } return false; } // INVENTORY METHODS- && NBT // ------------------------------------------------------------ /** * Returns the number of slots in the inventory. */ @Override public int getSizeInventory(){ return inventory.length; } /** * 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){ // super.setInventorySlotContents(slot, itemStack); inventory[slot] = itemStack; if(itemStack != null && itemStack.stackSize > getInventoryStackLimit()) { itemStack.stackSize = getInventoryStackLimit(); } } @Override public int getInventoryStackLimit(){ return 64; } @Override public String getInventoryName(){ return Blockss.pressureChamberValve.getUnlocalizedName(); } @Override public boolean isItemValidForSlot(int i, ItemStack itemstack){ return itemstack.getItem() == Itemss.machineUpgrade; } @Override public boolean hasCustomInventoryName(){ return false; } @Override public boolean isUseableByPlayer(EntityPlayer var1){ return isGuiUseableByPlayer(var1); } @Override public void openInventory(){} @Override public void closeInventory(){} @Override public float getMinWorkingPressure(){ return isValidRecipeInChamber ? recipePressure : -1; } }