package blusunrize.immersiveengineering.common.blocks.metal; import blusunrize.immersiveengineering.common.Config.IEConfig; import blusunrize.immersiveengineering.common.IEContent; import blusunrize.immersiveengineering.common.blocks.BlockTypes_MetalsAll; import blusunrize.immersiveengineering.common.blocks.IEBlockInterfaces.IComparatorOverride; import blusunrize.immersiveengineering.common.blocks.TileEntityMultiblockPart; import blusunrize.immersiveengineering.common.blocks.wooden.BlockTypes_WoodenDecoration; import blusunrize.immersiveengineering.common.util.Utils; import net.minecraft.block.Block; import net.minecraft.entity.item.EntityItem; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing.Axis; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTank; import net.minecraftforge.fluids.IFluidTank; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.ItemHandlerHelper; public class TileEntitySilo extends TileEntityMultiblockPart<TileEntitySilo> implements IComparatorOverride //IDeepStorageUnit { public ItemStack identStack; public int storageAmount = 0; static int maxStorage = 41472; // ItemStack inputStack; // ItemStack outputStack; // ItemStack prevInputStack; // ItemStack prevOutputStack; boolean lockItem = false; private int[] oldComps = new int[6]; private int masterCompOld; private boolean forceUpdate = false; @Override public void update() { // if(pos==4 && !worldObj.isRemote && this.outputStack==null && storageAmount>0 && identStack!=null) // this.markDirty(); if(pos==4 && !worldObj.isRemote && this.identStack!=null && storageAmount>0 && worldObj.isBlockIndirectlyGettingPowered(getPos())>0 && worldObj.getTotalWorldTime()%8==0) { updateComparatorValuesPart1(); for(EnumFacing f : EnumFacing.values()) if(f!=EnumFacing.UP) { TileEntity inventory = this.worldObj.getTileEntity(getPos().offset(f)); ItemStack stack = Utils.copyStackWithAmount(identStack,1); stack = Utils.insertStackIntoInventory(inventory, stack, f.getOpposite()); if(stack==null) { storageAmount--; if(storageAmount<=0) identStack = null; this.markDirty(); markContainingBlockForUpdate(null); if(storageAmount<=0) break; } } updateComparatorValuesPart2(); } } @Override public void readCustomNBT(NBTTagCompound nbt, boolean descPacket) { super.readCustomNBT(nbt, descPacket); if(nbt.hasKey("identStack")) { NBTTagCompound t = nbt.getCompoundTag("identStack"); this.identStack = ItemStack.loadItemStackFromNBT(t); } else this.identStack = null; storageAmount = nbt.getInteger("storageAmount"); lockItem = nbt.getBoolean("lockItem"); } @Override public void writeCustomNBT(NBTTagCompound nbt, boolean descPacket) { super.writeCustomNBT(nbt, descPacket); if(this.identStack!=null) { NBTTagCompound t = this.identStack.writeToNBT(new NBTTagCompound()); nbt.setTag("identStack", t); } nbt.setInteger("storageAmount", storageAmount); nbt.setBoolean("lockItem", lockItem); } @Override protected IFluidTank[] getAccessibleFluidTanks(EnumFacing side) { return new FluidTank[0]; } @Override protected boolean canFillTankFrom(int iTank, EnumFacing side, FluidStack resources) { return false; } @Override protected boolean canDrainTankFrom(int iTank, EnumFacing side) { return false; } @Override public float[] getBlockBounds() { if(pos==0||pos==2||pos==6||pos==8) { float xMin = (facing.getAxis() == Axis.X ? (pos > 2 ^ facing == EnumFacing.EAST) : (pos % 3 == 2 ^ facing == EnumFacing.SOUTH)) ? .75f : 0; float xMax = (facing.getAxis() == Axis.X ? (pos < 3 ^ facing == EnumFacing.EAST) : (pos % 3 == 0 ^ facing == EnumFacing.SOUTH)) ? .25f : 1; float zMin = (facing.getAxis() == Axis.X ? (pos % 3 == 2 ^ facing == EnumFacing.EAST) : (pos < 3 ^ facing == EnumFacing.SOUTH)) ? .75f : 0; float zMax = (facing.getAxis() == Axis.X ? (pos % 3 == 0 ^ facing == EnumFacing.EAST) : (pos > 2 ^ facing == EnumFacing.SOUTH)) ? .25f : 1; return new float[]{xMin, 0, zMin, xMax, 1, zMax}; } return new float[]{0,0,0,1,1,1}; } @Override public ItemStack getOriginalBlock() { return pos==0||pos==2||pos==6||pos==8?new ItemStack(IEContent.blockWoodenDecoration,1,BlockTypes_WoodenDecoration.FENCE.getMeta()):new ItemStack(IEContent.blockSheetmetal,1,BlockTypes_MetalsAll.IRON.getMeta()); } @Override public void disassemble() { super.invalidate(); if(formed && !worldObj.isRemote) { BlockPos startPos = this.getPos().add(-offset[0],-offset[1],-offset[2]); if(!(offset[0]==0&&offset[1]==0&&offset[2]==0) && !(worldObj.getTileEntity(startPos) instanceof TileEntitySilo)) return; for(int yy=0;yy<=6;yy++) for(int xx=-1;xx<=1;xx++) for(int zz=-1;zz<=1;zz++) { ItemStack s = null; TileEntity te = worldObj.getTileEntity(startPos.add(xx, yy, zz)); if(te instanceof TileEntitySilo) { s = ((TileEntitySilo)te).getOriginalBlock(); ((TileEntitySilo)te).formed=false; } if(startPos.add(xx, yy, zz).equals(getPos())) s = this.getOriginalBlock(); if(s!=null && Block.getBlockFromItem(s.getItem())!=null) { if(startPos.add(xx, yy, zz).equals(getPos())) worldObj.spawnEntityInWorld(new EntityItem(worldObj, getPos().getX()+.5,getPos().getY()+.5,getPos().getZ()+.5, s)); else { if(Block.getBlockFromItem(s.getItem())==IEContent.blockMetalMultiblock) worldObj.setBlockToAir(startPos.add(xx, yy, zz)); worldObj.setBlockState(startPos.add(xx, yy, zz), Block.getBlockFromItem(s.getItem()).getStateFromMeta(s.getItemDamage())); } } } } } @SideOnly(Side.CLIENT) private AxisAlignedBB renderAABB; @Override @SideOnly(Side.CLIENT) public AxisAlignedBB getRenderBoundingBox() { if(renderAABB==null) if(pos==4) renderAABB = new AxisAlignedBB(getPos().add(-1,0,-1), getPos().add(2,7,2)); else renderAABB = new AxisAlignedBB(getPos(),getPos()); return renderAABB; } @Override @SideOnly(Side.CLIENT) public double getMaxRenderDistanceSquared() { return super.getMaxRenderDistanceSquared()* IEConfig.increasedTileRenderdistance; } /* //DEEP STORAGE @Override public ItemStack getStoredItemType() { TileEntitySilo mast = master(); if (mast!=null) return mast.getStoredItemType(); if(this.identStack != null) return Utils.copyStackWithAmount(identStack, storageAmount); return null; } @Override public void setStoredItemCount(int amount) { TileEntitySilo mast = master(); if (mast!=null) { mast.setStoredItemCount(amount); return; } updateComparatorValuesPart1(); if(amount > maxStorage) amount = maxStorage; this.storageAmount = amount; this.forceUpdate = true; this.markDirty(); updateComparatorValuesPart2(); } @Override public void setStoredItemType(ItemStack type, int amount) { TileEntitySilo mast = master(); if (mast!=null) { mast.setStoredItemType(type, amount); return; } updateComparatorValuesPart1(); this.identStack = Utils.copyStackWithAmount(type, 0); if(amount > maxStorage) amount = maxStorage; this.storageAmount = amount; this.forceUpdate = true; this.markDirty(); updateComparatorValuesPart2(); } @Override public int getMaxStoredCount() { return maxStorage; } */ @Override public boolean hasCapability(Capability<?> capability, EnumFacing facing) { if((pos==4||pos==58) && capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return true; // if(pos>30&&pos<44 && pos%5>0&&pos%5<4 ) // return true; return super.hasCapability(capability, facing); } IItemHandler insertionHandler = new SiloInventoryHandler(this); @Override public <T> T getCapability(Capability<T> capability, EnumFacing facing) { if((pos==4||pos==58) && capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return (T)insertionHandler; return super.getCapability(capability, facing); } public static class SiloInventoryHandler implements IItemHandlerModifiable { TileEntitySilo silo; public SiloInventoryHandler(TileEntitySilo silo) { this.silo = silo; } @Override public int getSlots() { return 2; } @Override public ItemStack getStackInSlot(int slot) { return slot==0?Utils.copyStackWithAmount(silo.identStack,Math.min(silo.storageAmount,1)):Utils.copyStackWithAmount(silo.identStack,Math.min(silo.storageAmount,64)); } @Override public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { stack = stack.copy(); TileEntitySilo silo = this.silo.master(); int space = maxStorage-silo.storageAmount; if(slot!=0 || space<1 || stack==null || (silo.identStack!=null && !ItemHandlerHelper.canItemStacksStack(silo.identStack,stack))) return stack; int accepted = Math.min(space, stack.stackSize); if(!simulate) { silo.updateComparatorValuesPart1(); silo.storageAmount += accepted; if(silo.identStack==null) silo.identStack = stack.copy(); silo.markDirty(); silo.markContainingBlockForUpdate(null); silo.updateComparatorValuesPart2(); } stack.stackSize -= accepted; if(stack.stackSize<1) stack = null; return stack; } @Override public ItemStack extractItem(int slot, int amount, boolean simulate) { TileEntitySilo silo = this.silo.master(); if(slot!=1 || silo.storageAmount<1 || amount<1 || silo.identStack==null) return null; ItemStack out; if(silo.identStack.stackSize>amount) out = Utils.copyStackWithAmount(silo.identStack, amount); else out = silo.identStack.copy(); if(!simulate) { silo.updateComparatorValuesPart1(); silo.storageAmount -= out.stackSize; if(silo.storageAmount<=0 && !silo.lockItem) silo.identStack = null; silo.markDirty(); silo.markContainingBlockForUpdate(null); silo.updateComparatorValuesPart2(); } return out; } @Override public void setStackInSlot(int slot, ItemStack stack) { } } @Override public int getComparatorInputOverride() { if(pos==4) return (15*storageAmount)/maxStorage; TileEntitySilo master = master(); if (offset[1]>=1&&offset[1]<=6&&master!=null) //6 layers of storage { int layer = offset[1]-1; int vol = maxStorage/6; int filled = master.storageAmount-layer*vol; int ret = Math.min(15, Math.max(0, (15*filled)/vol)); return ret; } return 0; } private void updateComparatorValuesPart1() { int vol = maxStorage / 6; for(int i=0; i<6; i++) { int filled = storageAmount - i * vol; oldComps[i] = Math.min(15, Math.max((15*filled)/vol, 0)); } masterCompOld = (15*storageAmount)/maxStorage; } private void updateComparatorValuesPart2() { int vol = maxStorage / 6; if((15*storageAmount)/maxStorage!=masterCompOld) worldObj.notifyNeighborsOfStateChange(getPos(), getBlockType()); for(int i=0; i<6; i++) { int filled = storageAmount - i * vol; int now = Math.min(15, Math.max((15*filled)/vol, 0)); if(now!=oldComps[i]) { for(int x=-1; x<=1; x++) for(int z=-1; z<=1; z++) { BlockPos pos = getPos().add(-offset[0]+x, -offset[1]+i+1, -offset[2]+z); worldObj.notifyNeighborsOfStateChange(pos, worldObj.getBlockState(pos).getBlock()); } } } } }