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.client.renderer.texture.IconRegister; 010import net.minecraft.entity.EntityLiving; 011import net.minecraft.item.Item; 012import net.minecraft.item.ItemStack; 013import net.minecraft.util.AxisAlignedBB; 014import net.minecraft.util.Direction; 015import net.minecraft.util.Icon; 016import net.minecraft.util.MathHelper; 017import net.minecraft.world.IBlockAccess; 018import net.minecraft.world.World; 019 020public class BlockCocoa extends BlockDirectional 021{ 022 public static final String[] cocoaIcons = new String[] {"cocoa_0", "cocoa_1", "cocoa_2"}; 023 @SideOnly(Side.CLIENT) 024 private Icon[] iconArray; 025 026 public BlockCocoa(int par1) 027 { 028 super(par1, Material.plants); 029 this.setTickRandomly(true); 030 } 031 032 @SideOnly(Side.CLIENT) 033 034 /** 035 * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata 036 */ 037 public Icon getIcon(int par1, int par2) 038 { 039 return this.iconArray[2]; 040 } 041 042 /** 043 * Ticks the block if it's been scheduled 044 */ 045 public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) 046 { 047 if (!this.canBlockStay(par1World, par2, par3, par4)) 048 { 049 this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); 050 par1World.setBlockToAir(par2, par3, par4); 051 } 052 else if (par1World.rand.nextInt(5) == 0) 053 { 054 int l = par1World.getBlockMetadata(par2, par3, par4); 055 int i1 = func_72219_c(l); 056 057 if (i1 < 2) 058 { 059 ++i1; 060 par1World.setBlockMetadataWithNotify(par2, par3, par4, i1 << 2 | getDirection(l), 2); 061 } 062 } 063 } 064 065 @SideOnly(Side.CLIENT) 066 public Icon func_94468_i_(int par1) 067 { 068 if (par1 < 0 || par1 >= this.iconArray.length) 069 { 070 par1 = this.iconArray.length - 1; 071 } 072 073 return this.iconArray[par1]; 074 } 075 076 /** 077 * Can this block stay at this position. Similar to canPlaceBlockAt except gets checked often with plants. 078 */ 079 public boolean canBlockStay(World par1World, int par2, int par3, int par4) 080 { 081 int l = getDirection(par1World.getBlockMetadata(par2, par3, par4)); 082 par2 += Direction.offsetX[l]; 083 par4 += Direction.offsetZ[l]; 084 int i1 = par1World.getBlockId(par2, par3, par4); 085 return i1 == Block.wood.blockID && BlockLog.limitToValidMetadata(par1World.getBlockMetadata(par2, par3, par4)) == 3; 086 } 087 088 /** 089 * The type of render function that is called for this block 090 */ 091 public int getRenderType() 092 { 093 return 28; 094 } 095 096 /** 097 * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc) 098 */ 099 public boolean renderAsNormalBlock() 100 { 101 return false; 102 } 103 104 /** 105 * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two 106 * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. 107 */ 108 public boolean isOpaqueCube() 109 { 110 return false; 111 } 112 113 /** 114 * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been 115 * cleared to be reused) 116 */ 117 public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) 118 { 119 this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); 120 return super.getCollisionBoundingBoxFromPool(par1World, par2, par3, par4); 121 } 122 123 @SideOnly(Side.CLIENT) 124 125 /** 126 * Returns the bounding box of the wired rectangular prism to render. 127 */ 128 public AxisAlignedBB getSelectedBoundingBoxFromPool(World par1World, int par2, int par3, int par4) 129 { 130 this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); 131 return super.getSelectedBoundingBoxFromPool(par1World, par2, par3, par4); 132 } 133 134 /** 135 * Updates the blocks bounds based on its current state. Args: world, x, y, z 136 */ 137 public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) 138 { 139 int l = par1IBlockAccess.getBlockMetadata(par2, par3, par4); 140 int i1 = getDirection(l); 141 int j1 = func_72219_c(l); 142 int k1 = 4 + j1 * 2; 143 int l1 = 5 + j1 * 2; 144 float f = (float)k1 / 2.0F; 145 146 switch (i1) 147 { 148 case 0: 149 this.setBlockBounds((8.0F - f) / 16.0F, (12.0F - (float)l1) / 16.0F, (15.0F - (float)k1) / 16.0F, (8.0F + f) / 16.0F, 0.75F, 0.9375F); 150 break; 151 case 1: 152 this.setBlockBounds(0.0625F, (12.0F - (float)l1) / 16.0F, (8.0F - f) / 16.0F, (1.0F + (float)k1) / 16.0F, 0.75F, (8.0F + f) / 16.0F); 153 break; 154 case 2: 155 this.setBlockBounds((8.0F - f) / 16.0F, (12.0F - (float)l1) / 16.0F, 0.0625F, (8.0F + f) / 16.0F, 0.75F, (1.0F + (float)k1) / 16.0F); 156 break; 157 case 3: 158 this.setBlockBounds((15.0F - (float)k1) / 16.0F, (12.0F - (float)l1) / 16.0F, (8.0F - f) / 16.0F, 0.9375F, 0.75F, (8.0F + f) / 16.0F); 159 } 160 } 161 162 /** 163 * Called when the block is placed in the world. 164 */ 165 public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, ItemStack par6ItemStack) 166 { 167 int l = ((MathHelper.floor_double((double)(par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3) + 0) % 4; 168 par1World.setBlockMetadataWithNotify(par2, par3, par4, l, 2); 169 } 170 171 /** 172 * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, side, hitX, hitY, hitZ, block metadata 173 */ 174 public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8, int par9) 175 { 176 if (par5 == 1 || par5 == 0) 177 { 178 par5 = 2; 179 } 180 181 return Direction.rotateOpposite[Direction.facingToDirection[par5]]; 182 } 183 184 /** 185 * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are 186 * their own) Args: x, y, z, neighbor blockID 187 */ 188 public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) 189 { 190 if (!this.canBlockStay(par1World, par2, par3, par4)) 191 { 192 this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); 193 par1World.setBlockToAir(par2, par3, par4); 194 } 195 } 196 197 public static int func_72219_c(int par0) 198 { 199 return (par0 & 12) >> 2; 200 } 201 202 /** 203 * Drops the block items with a specified chance of dropping the specified items 204 */ 205 public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7) 206 { 207 super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, 0); 208 } 209 210 @Override 211 public ArrayList<ItemStack> getBlockDropped(World world, int x, int y, int z, int metadata, int fortune) 212 { 213 ArrayList<ItemStack> dropped = super.getBlockDropped(world, x, y, z, metadata, fortune); 214 int j1 = func_72219_c(metadata); 215 byte b0 = 1; 216 217 if (j1 >= 2) 218 { 219 b0 = 3; 220 } 221 222 for (int k1 = 0; k1 < b0; ++k1) 223 { 224 dropped.add(new ItemStack(Item.dyePowder, 1, 3)); 225 } 226 return dropped; 227 } 228 229 @SideOnly(Side.CLIENT) 230 231 /** 232 * only called by clickMiddleMouseButton , and passed to inventory.setCurrentItem (along with isCreative) 233 */ 234 public int idPicked(World par1World, int par2, int par3, int par4) 235 { 236 return Item.dyePowder.itemID; 237 } 238 239 /** 240 * Get the block's damage value (for use with pick block). 241 */ 242 public int getDamageValue(World par1World, int par2, int par3, int par4) 243 { 244 return 3; 245 } 246 247 @SideOnly(Side.CLIENT) 248 249 /** 250 * When this method is called, your block should register all the icons it needs with the given IconRegister. This 251 * is the only chance you get to register icons. 252 */ 253 public void registerIcons(IconRegister par1IconRegister) 254 { 255 this.iconArray = new Icon[cocoaIcons.length]; 256 257 for (int i = 0; i < this.iconArray.length; ++i) 258 { 259 this.iconArray[i] = par1IconRegister.registerIcon(cocoaIcons[i]); 260 } 261 } 262 263 @Override 264 public int idDropped(int par1, Random par2Random, int par3) 265 { 266 return 0; 267 } 268}