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