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.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 }