    001package net.minecraft.block;
    002
    003import cpw.mods.fml.relauncher.Side;
    004import cpw.mods.fml.relauncher.SideOnly;
    005
    006import java.util.ArrayList;
    007import java.util.Random;
    008import net.minecraft.block.material.Material;
    009import net.minecraft.entity.EntityLiving;
    010import net.minecraft.entity.boss.EntityWither;
    011import net.minecraft.entity.player.EntityPlayer;
    012import net.minecraft.item.Item;
    013import net.minecraft.item.ItemStack;
    014import net.minecraft.nbt.NBTTagCompound;
    015import net.minecraft.tileentity.TileEntity;
    016import net.minecraft.tileentity.TileEntitySkull;
    017import net.minecraft.util.AxisAlignedBB;
    018import net.minecraft.util.MathHelper;
    019import net.minecraft.world.IBlockAccess;
    020import net.minecraft.world.World;
    021
    022public 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.itemID;
    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).getSkullType() : 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.itemID, 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.getSkullType() == 3 && var8.getExtraType() != null && var8.getExtraType().length() > 0)
    175            {
    176                var7.setTagCompound(new NBTTagCompound());
    177                var7.getTagCompound().setString("SkullOwner", var8.getExtraType());
    178            }
    179            drops.add(var7);
    180        }
    181        return drops;
    182    }
    183
    184    /**
    185     * Returns the ID of the items to drop on destruction.
    186     */
    187    public int idDropped(int par1, Random par2Random, int par3)
    188    {
    189        return Item.skull.itemID;
    190    }
    191
    192    /**
    193     * This method attempts to create a wither at the given location and skull
    194     */
    195    public void makeWither(World par1World, int par2, int par3, int par4, TileEntitySkull par5TileEntitySkull)
    196    {
    197        if (par5TileEntitySkull.getSkullType() == 1 && par3 >= 2 && par1World.difficultySetting > 0)
    198        {
    199            int var6 = Block.slowSand.blockID;
    200            int var7;
    201            EntityWither var8;
    202            int var9;
    203
    204            for (var7 = -2; var7 <= 0; ++var7)
    205            {
    206                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))
    207                {
    208                    par1World.setBlockMetadata(par2, par3, par4 + var7, 8);
    209                    par1World.setBlockMetadata(par2, par3, par4 + var7 + 1, 8);
    210                    par1World.setBlockMetadata(par2, par3, par4 + var7 + 2, 8);
    211                    par1World.setBlock(par2, par3, par4 + var7, 0);
    212                    par1World.setBlock(par2, par3, par4 + var7 + 1, 0);
    213                    par1World.setBlock(par2, par3, par4 + var7 + 2, 0);
    214                    par1World.setBlock(par2, par3 - 1, par4 + var7, 0);
    215                    par1World.setBlock(par2, par3 - 1, par4 + var7 + 1, 0);
    216                    par1World.setBlock(par2, par3 - 1, par4 + var7 + 2, 0);
    217                    par1World.setBlock(par2, par3 - 2, par4 + var7 + 1, 0);
    218
    219                    if (!par1World.isRemote)
    220                    {
    221                        var8 = new EntityWither(par1World);
    222                        var8.setLocationAndAngles((double)par2 + 0.5D, (double)par3 - 1.45D, (double)(par4 + var7) + 1.5D, 90.0F, 0.0F);
    223                        var8.renderYawOffset = 90.0F;
    224                        var8.func_82206_m();
    225                        par1World.spawnEntityInWorld(var8);
    226                    }
    227
    228                    for (var9 = 0; var9 < 120; ++var9)
    229                    {
    230                        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);
    231                    }
    232
    233                    par1World.notifyBlockChange(par2, par3, par4 + var7, 0);
    234                    par1World.notifyBlockChange(par2, par3, par4 + var7 + 1, 0);
    235                    par1World.notifyBlockChange(par2, par3, par4 + var7 + 2, 0);
    236                    par1World.notifyBlockChange(par2, par3 - 1, par4 + var7, 0);
    237                    par1World.notifyBlockChange(par2, par3 - 1, par4 + var7 + 1, 0);
    238                    par1World.notifyBlockChange(par2, par3 - 1, par4 + var7 + 2, 0);
    239                    par1World.notifyBlockChange(par2, par3 - 2, par4 + var7 + 1, 0);
    240                    return;
    241                }
    242            }
    243
    244            for (var7 = -2; var7 <= 0; ++var7)
    245            {
    246                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))
    247                {
    248                    par1World.setBlockMetadata(par2 + var7, par3, par4, 8);
    249                    par1World.setBlockMetadata(par2 + var7 + 1, par3, par4, 8);
    250                    par1World.setBlockMetadata(par2 + var7 + 2, par3, par4, 8);
    251                    par1World.setBlock(par2 + var7, par3, par4, 0);
    252                    par1World.setBlock(par2 + var7 + 1, par3, par4, 0);
    253                    par1World.setBlock(par2 + var7 + 2, par3, par4, 0);
    254                    par1World.setBlock(par2 + var7, par3 - 1, par4, 0);
    255                    par1World.setBlock(par2 + var7 + 1, par3 - 1, par4, 0);
    256                    par1World.setBlock(par2 + var7 + 2, par3 - 1, par4, 0);
    257                    par1World.setBlock(par2 + var7 + 1, par3 - 2, par4, 0);
    258
    259                    if (!par1World.isRemote)
    260                    {
    261                        var8 = new EntityWither(par1World);
    262                        var8.setLocationAndAngles((double)(par2 + var7) + 1.5D, (double)par3 - 1.45D, (double)par4 + 0.5D, 0.0F, 0.0F);
    263                        var8.func_82206_m();
    264                        par1World.spawnEntityInWorld(var8);
    265                    }
    266
    267                    for (var9 = 0; var9 < 120; ++var9)
    268                    {
    269                        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);
    270                    }
    271
    272                    par1World.notifyBlockChange(par2 + var7, par3, par4, 0);
    273                    par1World.notifyBlockChange(par2 + var7 + 1, par3, par4, 0);
    274                    par1World.notifyBlockChange(par2 + var7 + 2, par3, par4, 0);
    275                    par1World.notifyBlockChange(par2 + var7, par3 - 1, par4, 0);
    276                    par1World.notifyBlockChange(par2 + var7 + 1, par3 - 1, par4, 0);
    277                    par1World.notifyBlockChange(par2 + var7 + 2, par3 - 1, par4, 0);
    278                    par1World.notifyBlockChange(par2 + var7 + 1, par3 - 2, par4, 0);
    279                    return;
    280                }
    281            }
    282        }
    283    }
    284
    285    private boolean func_82528_d(World par1World, int par2, int par3, int par4, int par5)
    286    {
    287        if (par1World.getBlockId(par2, par3, par4) != this.blockID)
    288        {
    289            return false;
    290        }
    291        else
    292        {
    293            TileEntity var6 = par1World.getBlockTileEntity(par2, par3, par4);
    294            return var6 != null && var6 instanceof TileEntitySkull ? ((TileEntitySkull)var6).getSkullType() == par5 : false;
    295        }
    296    }
    297}