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.tabDeco);
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         * each class overrdies this to return a new <className>
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        public 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    }