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        public void func_82529_a(World par1World, int par2, int par3, int par4, TileEntitySkull par5TileEntitySkull)
175        {
176            if (par5TileEntitySkull.func_82117_a() == 1 && par3 >= 2 && par1World.difficultySetting > 0)
177            {
178                int var6 = Block.slowSand.blockID;
179                int var7;
180                EntityWither var8;
181                int var9;
182    
183                for (var7 = -2; var7 <= 0; ++var7)
184                {
185                    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))
186                    {
187                        par1World.setBlockMetadata(par2, par3, par4 + var7, 8);
188                        par1World.setBlockMetadata(par2, par3, par4 + var7 + 1, 8);
189                        par1World.setBlockMetadata(par2, par3, par4 + var7 + 2, 8);
190                        par1World.setBlock(par2, par3, par4 + var7, 0);
191                        par1World.setBlock(par2, par3, par4 + var7 + 1, 0);
192                        par1World.setBlock(par2, par3, par4 + var7 + 2, 0);
193                        par1World.setBlock(par2, par3 - 1, par4 + var7, 0);
194                        par1World.setBlock(par2, par3 - 1, par4 + var7 + 1, 0);
195                        par1World.setBlock(par2, par3 - 1, par4 + var7 + 2, 0);
196                        par1World.setBlock(par2, par3 - 2, par4 + var7 + 1, 0);
197    
198                        if (!par1World.isRemote)
199                        {
200                            var8 = new EntityWither(par1World);
201                            var8.setLocationAndAngles((double)par2 + 0.5D, (double)par3 - 1.45D, (double)(par4 + var7) + 1.5D, 90.0F, 0.0F);
202                            var8.renderYawOffset = 90.0F;
203                            var8.func_82206_m();
204                            par1World.spawnEntityInWorld(var8);
205                        }
206    
207                        for (var9 = 0; var9 < 120; ++var9)
208                        {
209                            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);
210                        }
211    
212                        par1World.notifyBlockChange(par2, par3, par4 + var7, 0);
213                        par1World.notifyBlockChange(par2, par3, par4 + var7 + 1, 0);
214                        par1World.notifyBlockChange(par2, par3, par4 + var7 + 2, 0);
215                        par1World.notifyBlockChange(par2, par3 - 1, par4 + var7, 0);
216                        par1World.notifyBlockChange(par2, par3 - 1, par4 + var7 + 1, 0);
217                        par1World.notifyBlockChange(par2, par3 - 1, par4 + var7 + 2, 0);
218                        par1World.notifyBlockChange(par2, par3 - 2, par4 + var7 + 1, 0);
219                        return;
220                    }
221                }
222    
223                for (var7 = -2; var7 <= 0; ++var7)
224                {
225                    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))
226                    {
227                        par1World.setBlockMetadata(par2 + var7, par3, par4, 8);
228                        par1World.setBlockMetadata(par2 + var7 + 1, par3, par4, 8);
229                        par1World.setBlockMetadata(par2 + var7 + 2, par3, par4, 8);
230                        par1World.setBlock(par2 + var7, par3, par4, 0);
231                        par1World.setBlock(par2 + var7 + 1, par3, par4, 0);
232                        par1World.setBlock(par2 + var7 + 2, par3, par4, 0);
233                        par1World.setBlock(par2 + var7, par3 - 1, par4, 0);
234                        par1World.setBlock(par2 + var7 + 1, par3 - 1, par4, 0);
235                        par1World.setBlock(par2 + var7 + 2, par3 - 1, par4, 0);
236                        par1World.setBlock(par2 + var7 + 1, par3 - 2, par4, 0);
237    
238                        if (!par1World.isRemote)
239                        {
240                            var8 = new EntityWither(par1World);
241                            var8.setLocationAndAngles((double)(par2 + var7) + 1.5D, (double)par3 - 1.45D, (double)par4 + 0.5D, 0.0F, 0.0F);
242                            var8.func_82206_m();
243                            par1World.spawnEntityInWorld(var8);
244                        }
245    
246                        for (var9 = 0; var9 < 120; ++var9)
247                        {
248                            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);
249                        }
250    
251                        par1World.notifyBlockChange(par2 + var7, par3, par4, 0);
252                        par1World.notifyBlockChange(par2 + var7 + 1, par3, par4, 0);
253                        par1World.notifyBlockChange(par2 + var7 + 2, par3, par4, 0);
254                        par1World.notifyBlockChange(par2 + var7, par3 - 1, par4, 0);
255                        par1World.notifyBlockChange(par2 + var7 + 1, par3 - 1, par4, 0);
256                        par1World.notifyBlockChange(par2 + var7 + 2, par3 - 1, par4, 0);
257                        par1World.notifyBlockChange(par2 + var7 + 1, par3 - 2, par4, 0);
258                        return;
259                    }
260                }
261            }
262        }
263    
264        private boolean func_82528_d(World par1World, int par2, int par3, int par4, int par5)
265        {
266            if (par1World.getBlockId(par2, par3, par4) != this.blockID)
267            {
268                return false;
269            }
270            else
271            {
272                TileEntity var6 = par1World.getBlockTileEntity(par2, par3, par4);
273                return var6 != null && var6 instanceof TileEntitySkull ? ((TileEntitySkull)var6).func_82117_a() == par5 : false;
274            }
275        }
276    }