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.Random;
006    
007    public class BlockSkull extends BlockContainer
008    {
009        protected BlockSkull(int par1)
010        {
011            super(par1, Material.circuits);
012            this.blockIndexInTexture = 104;
013            this.setBlockBounds(0.25F, 0.0F, 0.25F, 0.75F, 0.5F, 0.75F);
014        }
015    
016        /**
017         * The type of render function that is called for this block
018         */
019        public int getRenderType()
020        {
021            return -1;
022        }
023    
024        /**
025         * Is this block (a) opaque and (b) a full 1m cube?  This determines whether or not to render the shared face of two
026         * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block.
027         */
028        public boolean isOpaqueCube()
029        {
030            return false;
031        }
032    
033        /**
034         * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc)
035         */
036        public boolean renderAsNormalBlock()
037        {
038            return false;
039        }
040    
041        /**
042         * Updates the blocks bounds based on its current state. Args: world, x, y, z
043         */
044        public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
045        {
046            int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 7;
047    
048            switch (var5)
049            {
050                case 1:
051                default:
052                    this.setBlockBounds(0.25F, 0.0F, 0.25F, 0.75F, 0.5F, 0.75F);
053                    break;
054                case 2:
055                    this.setBlockBounds(0.25F, 0.25F, 0.5F, 0.75F, 0.75F, 1.0F);
056                    break;
057                case 3:
058                    this.setBlockBounds(0.25F, 0.25F, 0.0F, 0.75F, 0.75F, 0.5F);
059                    break;
060                case 4:
061                    this.setBlockBounds(0.5F, 0.25F, 0.25F, 1.0F, 0.75F, 0.75F);
062                    break;
063                case 5:
064                    this.setBlockBounds(0.0F, 0.25F, 0.25F, 0.5F, 0.75F, 0.75F);
065            }
066        }
067    
068        /**
069         * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been
070         * cleared to be reused)
071         */
072        public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
073        {
074            this.setBlockBoundsBasedOnState(par1World, par2, par3, par4);
075            return super.getCollisionBoundingBoxFromPool(par1World, par2, par3, par4);
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 = MathHelper.floor_double((double)(par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 2.5D) & 3;
084            par1World.setBlockMetadataWithNotify(par2, par3, par4, var6);
085        }
086    
087        /**
088         * Returns a new instance of a block's tile entity class. Called on placing the block.
089         */
090        public TileEntity createNewTileEntity(World par1World)
091        {
092            return new TileEntitySkull();
093        }
094    
095        @SideOnly(Side.CLIENT)
096    
097        /**
098         * only called by clickMiddleMouseButton , and passed to inventory.setCurrentItem (along with isCreative)
099         */
100        public int idPicked(World par1World, int par2, int par3, int par4)
101        {
102            return Item.skull.shiftedIndex;
103        }
104    
105        /**
106         * Get the block's damage value (for use with pick block).
107         */
108        public int getDamageValue(World par1World, int par2, int par3, int par4)
109        {
110            TileEntity var5 = par1World.getBlockTileEntity(par2, par3, par4);
111            return var5 != null && var5 instanceof TileEntitySkull ? ((TileEntitySkull)var5).func_82117_a() : super.getDamageValue(par1World, par2, par3, par4);
112        }
113    
114        /**
115         * Determines the damage on the item the block drops. Used in cloth and wood.
116         */
117        public int damageDropped(int par1)
118        {
119            return par1;
120        }
121    
122        /**
123         * Drops the block items with a specified chance of dropping the specified items
124         */
125        public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7) {}
126    
127        /**
128         * Called when the block is attempted to be harvested
129         */
130        public void onBlockHarvested(World par1World, int par2, int par3, int par4, int par5, EntityPlayer par6EntityPlayer)
131        {
132            if (par6EntityPlayer.capabilities.isCreativeMode)
133            {
134                par5 |= 8;
135                par1World.setBlockMetadataWithNotify(par2, par3, par4, par5);
136            }
137    
138            super.onBlockHarvested(par1World, par2, par3, par4, par5, par6EntityPlayer);
139        }
140    
141        /**
142         * ejects contained items into the world, and notifies neighbours of an update, as appropriate
143         */
144        public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6)
145        {
146            if (!par1World.isRemote)
147            {
148                if ((par6 & 8) == 0)
149                {
150                    ItemStack var7 = new ItemStack(Item.skull.shiftedIndex, 1, this.getDamageValue(par1World, par2, par3, par4));
151                    TileEntitySkull var8 = (TileEntitySkull)par1World.getBlockTileEntity(par2, par3, par4);
152    
153                    if (var8.func_82117_a() == 3 && var8.func_82120_c() != null && var8.func_82120_c().length() > 0)
154                    {
155                        var7.setTagCompound(new NBTTagCompound());
156                        var7.getTagCompound().setString("SkullOwner", var8.func_82120_c());
157                    }
158    
159                    this.dropBlockAsItem_do(par1World, par2, par3, par4, var7);
160                }
161    
162                super.breakBlock(par1World, par2, par3, par4, par5, par6);
163            }
164        }
165    
166        /**
167         * Returns the ID of the items to drop on destruction.
168         */
169        public int idDropped(int par1, Random par2Random, int par3)
170        {
171            return Item.skull.shiftedIndex;
172        }
173    
174        /**
175         * This method attempts to create a wither at the given location and skull
176         */
177        public void makeWither(World par1World, int par2, int par3, int par4, TileEntitySkull par5TileEntitySkull)
178        {
179            if (par5TileEntitySkull.func_82117_a() == 1 && par3 >= 2 && par1World.difficultySetting > 0)
180            {
181                int var6 = Block.slowSand.blockID;
182                int var7;
183                EntityWither var8;
184                int var9;
185    
186                for (var7 = -2; var7 <= 0; ++var7)
187                {
188                    if (par1World.getBlockId(par2, par3 - 1, par4 + var7) == var6 && par1World.getBlockId(par2, par3 - 1, par4 + var7 + 1) == var6 && par1World.getBlockId(par2, par3 - 2, par4 + var7 + 1) == var6 && par1World.getBlockId(par2, par3 - 1, par4 + var7 + 2) == var6 && this.func_82528_d(par1World, par2, par3, par4 + var7, 1) && this.func_82528_d(par1World, par2, par3, par4 + var7 + 1, 1) && this.func_82528_d(par1World, par2, par3, par4 + var7 + 2, 1))
189                    {
190                        par1World.setBlockMetadata(par2, par3, par4 + var7, 8);
191                        par1World.setBlockMetadata(par2, par3, par4 + var7 + 1, 8);
192                        par1World.setBlockMetadata(par2, par3, par4 + var7 + 2, 8);
193                        par1World.setBlock(par2, par3, par4 + var7, 0);
194                        par1World.setBlock(par2, par3, par4 + var7 + 1, 0);
195                        par1World.setBlock(par2, par3, par4 + var7 + 2, 0);
196                        par1World.setBlock(par2, par3 - 1, par4 + var7, 0);
197                        par1World.setBlock(par2, par3 - 1, par4 + var7 + 1, 0);
198                        par1World.setBlock(par2, par3 - 1, par4 + var7 + 2, 0);
199                        par1World.setBlock(par2, par3 - 2, par4 + var7 + 1, 0);
200    
201                        if (!par1World.isRemote)
202                        {
203                            var8 = new EntityWither(par1World);
204                            var8.setLocationAndAngles((double)par2 + 0.5D, (double)par3 - 1.45D, (double)(par4 + var7) + 1.5D, 90.0F, 0.0F);
205                            var8.renderYawOffset = 90.0F;
206                            var8.func_82206_m();
207                            par1World.spawnEntityInWorld(var8);
208                        }
209    
210                        for (var9 = 0; var9 < 120; ++var9)
211                        {
212                            par1World.spawnParticle("snowballpoof", (double)par2 + par1World.rand.nextDouble(), (double)(par3 - 2) + par1World.rand.nextDouble() * 3.9D, (double)(par4 + var7 + 1) + par1World.rand.nextDouble(), 0.0D, 0.0D, 0.0D);
213                        }
214    
215                        par1World.notifyBlockChange(par2, par3, par4 + var7, 0);
216                        par1World.notifyBlockChange(par2, par3, par4 + var7 + 1, 0);
217                        par1World.notifyBlockChange(par2, par3, par4 + var7 + 2, 0);
218                        par1World.notifyBlockChange(par2, par3 - 1, par4 + var7, 0);
219                        par1World.notifyBlockChange(par2, par3 - 1, par4 + var7 + 1, 0);
220                        par1World.notifyBlockChange(par2, par3 - 1, par4 + var7 + 2, 0);
221                        par1World.notifyBlockChange(par2, par3 - 2, par4 + var7 + 1, 0);
222                        return;
223                    }
224                }
225    
226                for (var7 = -2; var7 <= 0; ++var7)
227                {
228                    if (par1World.getBlockId(par2 + var7, par3 - 1, par4) == var6 && par1World.getBlockId(par2 + var7 + 1, par3 - 1, par4) == var6 && par1World.getBlockId(par2 + var7 + 1, par3 - 2, par4) == var6 && par1World.getBlockId(par2 + var7 + 2, par3 - 1, par4) == var6 && this.func_82528_d(par1World, par2 + var7, par3, par4, 1) && this.func_82528_d(par1World, par2 + var7 + 1, par3, par4, 1) && this.func_82528_d(par1World, par2 + var7 + 2, par3, par4, 1))
229                    {
230                        par1World.setBlockMetadata(par2 + var7, par3, par4, 8);
231                        par1World.setBlockMetadata(par2 + var7 + 1, par3, par4, 8);
232                        par1World.setBlockMetadata(par2 + var7 + 2, par3, par4, 8);
233                        par1World.setBlock(par2 + var7, par3, par4, 0);
234                        par1World.setBlock(par2 + var7 + 1, par3, par4, 0);
235                        par1World.setBlock(par2 + var7 + 2, par3, par4, 0);
236                        par1World.setBlock(par2 + var7, par3 - 1, par4, 0);
237                        par1World.setBlock(par2 + var7 + 1, par3 - 1, par4, 0);
238                        par1World.setBlock(par2 + var7 + 2, par3 - 1, par4, 0);
239                        par1World.setBlock(par2 + var7 + 1, par3 - 2, par4, 0);
240    
241                        if (!par1World.isRemote)
242                        {
243                            var8 = new EntityWither(par1World);
244                            var8.setLocationAndAngles((double)(par2 + var7) + 1.5D, (double)par3 - 1.45D, (double)par4 + 0.5D, 0.0F, 0.0F);
245                            var8.func_82206_m();
246                            par1World.spawnEntityInWorld(var8);
247                        }
248    
249                        for (var9 = 0; var9 < 120; ++var9)
250                        {
251                            par1World.spawnParticle("snowballpoof", (double)(par2 + var7 + 1) + par1World.rand.nextDouble(), (double)(par3 - 2) + par1World.rand.nextDouble() * 3.9D, (double)par4 + par1World.rand.nextDouble(), 0.0D, 0.0D, 0.0D);
252                        }
253    
254                        par1World.notifyBlockChange(par2 + var7, par3, par4, 0);
255                        par1World.notifyBlockChange(par2 + var7 + 1, par3, par4, 0);
256                        par1World.notifyBlockChange(par2 + var7 + 2, par3, par4, 0);
257                        par1World.notifyBlockChange(par2 + var7, par3 - 1, par4, 0);
258                        par1World.notifyBlockChange(par2 + var7 + 1, par3 - 1, par4, 0);
259                        par1World.notifyBlockChange(par2 + var7 + 2, par3 - 1, par4, 0);
260                        par1World.notifyBlockChange(par2 + var7 + 1, par3 - 2, par4, 0);
261                        return;
262                    }
263                }
264            }
265        }
266    
267        private boolean func_82528_d(World par1World, int par2, int par3, int par4, int par5)
268        {
269            if (par1World.getBlockId(par2, par3, par4) != this.blockID)
270            {
271                return false;
272            }
273            else
274            {
275                TileEntity var6 = par1World.getBlockTileEntity(par2, par3, par4);
276                return var6 != null && var6 instanceof TileEntitySkull ? ((TileEntitySkull)var6).func_82117_a() == par5 : false;
277            }
278        }
279    }