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 }