    001    package net.minecraft.src;
    002
    003    import cpw.mods.fml.common.Side;
    004    import cpw.mods.fml.common.asm.SideOnly;
    005    import java.util.Iterator;
    006    import java.util.Random;
    007    import static net.minecraftforge.common.ForgeDirection.*;
    008
    009    public class BlockChest extends BlockContainer
    010    {
    011        private Random random = new Random();
    012
    013        protected BlockChest(int par1)
    014        {
    015            super(par1, Material.wood);
    016            this.blockIndexInTexture = 26;
    017            this.setCreativeTab(CreativeTabs.tabDecorations);
    018        }
    019
    020        /**
    021         * Is this block (a) opaque and (b) a full 1m cube?  This determines whether or not to render the shared face of two
    022         * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block.
    023         */
    024        public boolean isOpaqueCube()
    025        {
    026            return false;
    027        }
    028
    029        /**
    030         * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc)
    031         */
    032        public boolean renderAsNormalBlock()
    033        {
    034            return false;
    035        }
    036
    037        /**
    038         * The type of render function that is called for this block
    039         */
    040        public int getRenderType()
    041        {
    042            return 22;
    043        }
    044
    045        /**
    046         * Called whenever the block is added into the world. Args: world, x, y, z
    047         */
    048        public void onBlockAdded(World par1World, int par2, int par3, int par4)
    049        {
    050            super.onBlockAdded(par1World, par2, par3, par4);
    051            this.unifyAdjacentChests(par1World, par2, par3, par4);
    052            int var5 = par1World.getBlockId(par2, par3, par4 - 1);
    053            int var6 = par1World.getBlockId(par2, par3, par4 + 1);
    054            int var7 = par1World.getBlockId(par2 - 1, par3, par4);
    055            int var8 = par1World.getBlockId(par2 + 1, par3, par4);
    056
    057            if (var5 == this.blockID)
    058            {
    059                this.unifyAdjacentChests(par1World, par2, par3, par4 - 1);
    060            }
    061
    062            if (var6 == this.blockID)
    063            {
    064                this.unifyAdjacentChests(par1World, par2, par3, par4 + 1);
    065            }
    066
    067            if (var7 == this.blockID)
    068            {
    069                this.unifyAdjacentChests(par1World, par2 - 1, par3, par4);
    070            }
    071
    072            if (var8 == this.blockID)
    073            {
    074                this.unifyAdjacentChests(par1World, par2 + 1, par3, par4);
    075            }
    076        }
    077
    078        /**
    079         * Called when the block is placed in the world.
    080         */
    081        public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving)
    082        {
    083            int var6 = par1World.getBlockId(par2, par3, par4 - 1);
    084            int var7 = par1World.getBlockId(par2, par3, par4 + 1);
    085            int var8 = par1World.getBlockId(par2 - 1, par3, par4);
    086            int var9 = par1World.getBlockId(par2 + 1, par3, par4);
    087            byte var10 = 0;
    088            int var11 = MathHelper.floor_double((double)(par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3;
    089
    090            if (var11 == 0)
    091            {
    092                var10 = 2;
    093            }
    094
    095            if (var11 == 1)
    096            {
    097                var10 = 5;
    098            }
    099
    100            if (var11 == 2)
    101            {
    102                var10 = 3;
    103            }
    104
    105            if (var11 == 3)
    106            {
    107                var10 = 4;
    108            }
    109
    110            if (var6 != this.blockID && var7 != this.blockID && var8 != this.blockID && var9 != this.blockID)
    111            {
    112                par1World.setBlockMetadataWithNotify(par2, par3, par4, var10);
    113            }
    114            else
    115            {
    116                if ((var6 == this.blockID || var7 == this.blockID) && (var10 == 4 || var10 == 5))
    117                {
    118                    if (var6 == this.blockID)
    119                    {
    120                        par1World.setBlockMetadataWithNotify(par2, par3, par4 - 1, var10);
    121                    }
    122                    else
    123                    {
    124                        par1World.setBlockMetadataWithNotify(par2, par3, par4 + 1, var10);
    125                    }
    126
    127                    par1World.setBlockMetadataWithNotify(par2, par3, par4, var10);
    128                }
    129
    130                if ((var8 == this.blockID || var9 == this.blockID) && (var10 == 2 || var10 == 3))
    131                {
    132                    if (var8 == this.blockID)
    133                    {
    134                        par1World.setBlockMetadataWithNotify(par2 - 1, par3, par4, var10);
    135                    }
    136                    else
    137                    {
    138                        par1World.setBlockMetadataWithNotify(par2 + 1, par3, par4, var10);
    139                    }
    140
    141                    par1World.setBlockMetadataWithNotify(par2, par3, par4, var10);
    142                }
    143            }
    144        }
    145
    146        /**
    147         * Turns the adjacent chests to a double chest.
    148         */
    149        public void unifyAdjacentChests(World par1World, int par2, int par3, int par4)
    150        {
    151            if (!par1World.isRemote)
    152            {
    153                int var5 = par1World.getBlockId(par2, par3, par4 - 1);
    154                int var6 = par1World.getBlockId(par2, par3, par4 + 1);
    155                int var7 = par1World.getBlockId(par2 - 1, par3, par4);
    156                int var8 = par1World.getBlockId(par2 + 1, par3, par4);
    157                boolean var9 = true;
    158                int var10;
    159                int var11;
    160                boolean var12;
    161                byte var13;
    162                int var14;
    163
    164                if (var5 != this.blockID && var6 != this.blockID)
    165                {
    166                    if (var7 != this.blockID && var8 != this.blockID)
    167                    {
    168                        var13 = 3;
    169
    170                        if (Block.opaqueCubeLookup[var5] && !Block.opaqueCubeLookup[var6])
    171                        {
    172                            var13 = 3;
    173                        }
    174
    175                        if (Block.opaqueCubeLookup[var6] && !Block.opaqueCubeLookup[var5])
    176                        {
    177                            var13 = 2;
    178                        }
    179
    180                        if (Block.opaqueCubeLookup[var7] && !Block.opaqueCubeLookup[var8])
    181                        {
    182                            var13 = 5;
    183                        }
    184
    185                        if (Block.opaqueCubeLookup[var8] && !Block.opaqueCubeLookup[var7])
    186                        {
    187                            var13 = 4;
    188                        }
    189                    }
    190                    else
    191                    {
    192                        var10 = par1World.getBlockId(var7 == this.blockID ? par2 - 1 : par2 + 1, par3, par4 - 1);
    193                        var11 = par1World.getBlockId(var7 == this.blockID ? par2 - 1 : par2 + 1, par3, par4 + 1);
    194                        var13 = 3;
    195                        var12 = true;
    196
    197                        if (var7 == this.blockID)
    198                        {
    199                            var14 = par1World.getBlockMetadata(par2 - 1, par3, par4);
    200                        }
    201                        else
    202                        {
    203                            var14 = par1World.getBlockMetadata(par2 + 1, par3, par4);
    204                        }
    205
    206                        if (var14 == 2)
    207                        {
    208                            var13 = 2;
    209                        }
    210
    211                        if ((Block.opaqueCubeLookup[var5] || Block.opaqueCubeLookup[var10]) && !Block.opaqueCubeLookup[var6] && !Block.opaqueCubeLookup[var11])
    212                        {
    213                            var13 = 3;
    214                        }
    215
    216                        if ((Block.opaqueCubeLookup[var6] || Block.opaqueCubeLookup[var11]) && !Block.opaqueCubeLookup[var5] && !Block.opaqueCubeLookup[var10])
    217                        {
    218                            var13 = 2;
    219                        }
    220                    }
    221                }
    222                else
    223                {
    224                    var10 = par1World.getBlockId(par2 - 1, par3, var5 == this.blockID ? par4 - 1 : par4 + 1);
    225                    var11 = par1World.getBlockId(par2 + 1, par3, var5 == this.blockID ? par4 - 1 : par4 + 1);
    226                    var13 = 5;
    227                    var12 = true;
    228
    229                    if (var5 == this.blockID)
    230                    {
    231                        var14 = par1World.getBlockMetadata(par2, par3, par4 - 1);
    232                    }
    233                    else
    234                    {
    235                        var14 = par1World.getBlockMetadata(par2, par3, par4 + 1);
    236                    }
    237
    238                    if (var14 == 4)
    239                    {
    240                        var13 = 4;
    241                    }
    242
    243                    if ((Block.opaqueCubeLookup[var7] || Block.opaqueCubeLookup[var10]) && !Block.opaqueCubeLookup[var8] && !Block.opaqueCubeLookup[var11])
    244                    {
    245                        var13 = 5;
    246                    }
    247
    248                    if ((Block.opaqueCubeLookup[var8] || Block.opaqueCubeLookup[var11]) && !Block.opaqueCubeLookup[var7] && !Block.opaqueCubeLookup[var10])
    249                    {
    250                        var13 = 4;
    251                    }
    252                }
    253
    254                par1World.setBlockMetadataWithNotify(par2, par3, par4, var13);
    255            }
    256        }
    257
    258        @SideOnly(Side.CLIENT)
    259
    260        /**
    261         * Retrieves the block texture to use based on the display side. Args: iBlockAccess, x, y, z, side
    262         */
    263        public int getBlockTexture(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
    264        {
    265            return 4;
    266        }
    267
    268        /**
    269         * Returns the block texture based on the side being looked at.  Args: side
    270         */
    271        public int getBlockTextureFromSide(int par1)
    272        {
    273            return 4;
    274        }
    275
    276        /**
    277         * Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z
    278         */
    279        public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4)
    280        {
    281            int var5 = 0;
    282
    283            if (par1World.getBlockId(par2 - 1, par3, par4) == this.blockID)
    284            {
    285                ++var5;
    286            }
    287
    288            if (par1World.getBlockId(par2 + 1, par3, par4) == this.blockID)
    289            {
    290                ++var5;
    291            }
    292
    293            if (par1World.getBlockId(par2, par3, par4 - 1) == this.blockID)
    294            {
    295                ++var5;
    296            }
    297
    298            if (par1World.getBlockId(par2, par3, par4 + 1) == this.blockID)
    299            {
    300                ++var5;
    301            }
    302
    303            return var5 > 1 ? false : (this.isThereANeighborChest(par1World, par2 - 1, par3, par4) ? false : (this.isThereANeighborChest(par1World, par2 + 1, par3, par4) ? false : (this.isThereANeighborChest(par1World, par2, par3, par4 - 1) ? false : !this.isThereANeighborChest(par1World, par2, par3, par4 + 1))));
    304        }
    305
    306        /**
    307         * Checks the neighbor blocks to see if there is a chest there. Args: world, x, y, z
    308         */
    309        private boolean isThereANeighborChest(World par1World, int par2, int par3, int par4)
    310        {
    311            return par1World.getBlockId(par2, par3, par4) != this.blockID ? false : (par1World.getBlockId(par2 - 1, par3, par4) == this.blockID ? true : (par1World.getBlockId(par2 + 1, par3, par4) == this.blockID ? true : (par1World.getBlockId(par2, par3, par4 - 1) == this.blockID ? true : par1World.getBlockId(par2, par3, par4 + 1) == this.blockID)));
    312        }
    313
    314        /**
    315         * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are
    316         * their own) Args: x, y, z, neighbor blockID
    317         */
    318        public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5)
    319        {
    320            super.onNeighborBlockChange(par1World, par2, par3, par4, par5);
    321            TileEntityChest var6 = (TileEntityChest)par1World.getBlockTileEntity(par2, par3, par4);
    322
    323            if (var6 != null)
    324            {
    325                var6.updateContainingBlockInfo();
    326            }
    327        }
    328
    329        /**
    330         * ejects contained items into the world, and notifies neighbours of an update, as appropriate
    331         */
    332        public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6)
    333        {
    334            TileEntityChest var7 = (TileEntityChest)par1World.getBlockTileEntity(par2, par3, par4);
    335
    336            if (var7 != null)
    337            {
    338                for (int var8 = 0; var8 < var7.getSizeInventory(); ++var8)
    339                {
    340                    ItemStack var9 = var7.getStackInSlot(var8);
    341
    342                    if (var9 != null)
    343                    {
    344                        float var10 = this.random.nextFloat() * 0.8F + 0.1F;
    345                        float var11 = this.random.nextFloat() * 0.8F + 0.1F;
    346                        EntityItem var14;
    347
    348                        for (float var12 = this.random.nextFloat() * 0.8F + 0.1F; var9.stackSize > 0; par1World.spawnEntityInWorld(var14))
    349                        {
    350                            int var13 = this.random.nextInt(21) + 10;
    351
    352                            if (var13 > var9.stackSize)
    353                            {
    354                                var13 = var9.stackSize;
    355                            }
    356
    357                            var9.stackSize -= var13;
    358                            var14 = new EntityItem(par1World, (double)((float)par2 + var10), (double)((float)par3 + var11), (double)((float)par4 + var12), new ItemStack(var9.itemID, var13, var9.getItemDamage()));
    359                            float var15 = 0.05F;
    360                            var14.motionX = (double)((float)this.random.nextGaussian() * var15);
    361                            var14.motionY = (double)((float)this.random.nextGaussian() * var15 + 0.2F);
    362                            var14.motionZ = (double)((float)this.random.nextGaussian() * var15);
    363
    364                            if (var9.hasTagCompound())
    365                            {
    366                                var14.item.setTagCompound((NBTTagCompound)var9.getTagCompound().copy());
    367                            }
    368                        }
    369                    }
    370                }
    371            }
    372
    373            super.breakBlock(par1World, par2, par3, par4, par5, par6);
    374        }
    375
    376        /**
    377         * Called upon block activation (right click on the block.)
    378         */
    379        public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9)
    380        {
    381            Object var10 = (TileEntityChest)par1World.getBlockTileEntity(par2, par3, par4);
    382
    383            if (var10 == null)
    384            {
    385                return true;
    386            }
    387            else if (par1World.isBlockSolidOnSide(par2, par3 + 1, par4, DOWN))
    388            {
    389                return true;
    390            }
    391            else if (isOcelotBlockingChest(par1World, par2, par3, par4))
    392            {
    393                return true;
    394            }
    395            else if (par1World.getBlockId(par2 - 1, par3, par4) == this.blockID && (par1World.isBlockSolidOnSide(par2 - 1, par3 + 1, par4, DOWN) || isOcelotBlockingChest(par1World, par2 - 1, par3, par4)))
    396            {
    397                return true;
    398            }
    399            else if (par1World.getBlockId(par2 + 1, par3, par4) == this.blockID && (par1World.isBlockSolidOnSide(par2 + 1, par3 + 1, par4, DOWN) || isOcelotBlockingChest(par1World, par2 + 1, par3, par4)))
    400            {
    401                return true;
    402            }
    403            else if (par1World.getBlockId(par2, par3, par4 - 1) == this.blockID && (par1World.isBlockSolidOnSide(par2, par3 + 1, par4 - 1, DOWN) || isOcelotBlockingChest(par1World, par2, par3, par4 - 1)))
    404            {
    405                return true;
    406            }
    407            else if (par1World.getBlockId(par2, par3, par4 + 1) == this.blockID && (par1World.isBlockSolidOnSide(par2, par3 + 1, par4 + 1, DOWN) || isOcelotBlockingChest(par1World, par2, par3, par4 + 1)))
    408            {
    409                return true;
    410            }
    411            else
    412            {
    413                if (par1World.getBlockId(par2 - 1, par3, par4) == this.blockID)
    414                {
    415                    var10 = new InventoryLargeChest("container.chestDouble", (TileEntityChest)par1World.getBlockTileEntity(par2 - 1, par3, par4), (IInventory)var10);
    416                }
    417
    418                if (par1World.getBlockId(par2 + 1, par3, par4) == this.blockID)
    419                {
    420                    var10 = new InventoryLargeChest("container.chestDouble", (IInventory)var10, (TileEntityChest)par1World.getBlockTileEntity(par2 + 1, par3, par4));
    421                }
    422
    423                if (par1World.getBlockId(par2, par3, par4 - 1) == this.blockID)
    424                {
    425                    var10 = new InventoryLargeChest("container.chestDouble", (TileEntityChest)par1World.getBlockTileEntity(par2, par3, par4 - 1), (IInventory)var10);
    426                }
    427
    428                if (par1World.getBlockId(par2, par3, par4 + 1) == this.blockID)
    429                {
    430                    var10 = new InventoryLargeChest("container.chestDouble", (IInventory)var10, (TileEntityChest)par1World.getBlockTileEntity(par2, par3, par4 + 1));
    431                }
    432
    433                if (par1World.isRemote)
    434                {
    435                    return true;
    436                }
    437                else
    438                {
    439                    par5EntityPlayer.displayGUIChest((IInventory)var10);
    440                    return true;
    441                }
    442            }
    443        }
    444
    445        /**
    446         * Returns a new instance of a block's tile entity class. Called on placing the block.
    447         */
    448        public TileEntity createNewTileEntity(World par1World)
    449        {
    450            return new TileEntityChest();
    451        }
    452
    453        /**
    454         * Looks for a sitting ocelot within certain bounds. Such an ocelot is considered to be blocking access to the
    455         * chest.
    456         */
    457        private static boolean isOcelotBlockingChest(World par0World, int par1, int par2, int par3)
    458        {
    459            Iterator var4 = par0World.getEntitiesWithinAABB(EntityOcelot.class, AxisAlignedBB.getAABBPool().addOrModifyAABBInPool((double)par1, (double)(par2 + 1), (double)par3, (double)(par1 + 1), (double)(par2 + 2), (double)(par3 + 1))).iterator();
    460            EntityOcelot var6;
    461
    462            do
    463            {
    464                if (!var4.hasNext())
    465                {
    466                    return false;
    467                }
    468
    469                EntityOcelot var5 = (EntityOcelot)var4.next();
    470                var6 = (EntityOcelot)var5;
    471            }
    472            while (!var6.isSitting());
    473
    474            return true;
    475        }
    476    }