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