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.client.renderer.texture.IconRegister; 009import net.minecraft.creativetab.CreativeTabs; 010import net.minecraft.item.Item; 011import net.minecraft.item.ItemStack; 012import net.minecraft.util.Icon; 013import net.minecraft.util.MathHelper; 014import net.minecraft.world.IBlockAccess; 015import net.minecraft.world.World; 016 017import net.minecraftforge.common.ForgeDirection; 018 019public class BlockStem extends BlockFlower 020{ 021 /** Defines if it is a Melon or a Pumpkin that the stem is producing. */ 022 private final Block fruitType; 023 @SideOnly(Side.CLIENT) 024 private Icon field_94369_b; 025 026 protected BlockStem(int par1, Block par2Block) 027 { 028 super(par1); 029 this.fruitType = par2Block; 030 this.setTickRandomly(true); 031 float f = 0.125F; 032 this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, 0.25F, 0.5F + f); 033 this.setCreativeTab((CreativeTabs)null); 034 } 035 036 /** 037 * Gets passed in the blockID of the block below and supposed to return true if its allowed to grow on the type of 038 * blockID passed in. Args: blockID 039 */ 040 protected boolean canThisPlantGrowOnThisBlockID(int par1) 041 { 042 return par1 == Block.tilledField.blockID; 043 } 044 045 /** 046 * Ticks the block if it's been scheduled 047 */ 048 public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) 049 { 050 super.updateTick(par1World, par2, par3, par4, par5Random); 051 052 if (par1World.getBlockLightValue(par2, par3 + 1, par4) >= 9) 053 { 054 float f = this.getGrowthModifier(par1World, par2, par3, par4); 055 056 if (par5Random.nextInt((int)(25.0F / f) + 1) == 0) 057 { 058 int l = par1World.getBlockMetadata(par2, par3, par4); 059 060 if (l < 7) 061 { 062 ++l; 063 par1World.setBlockMetadataWithNotify(par2, par3, par4, l, 2); 064 } 065 else 066 { 067 if (par1World.getBlockId(par2 - 1, par3, par4) == this.fruitType.blockID) 068 { 069 return; 070 } 071 072 if (par1World.getBlockId(par2 + 1, par3, par4) == this.fruitType.blockID) 073 { 074 return; 075 } 076 077 if (par1World.getBlockId(par2, par3, par4 - 1) == this.fruitType.blockID) 078 { 079 return; 080 } 081 082 if (par1World.getBlockId(par2, par3, par4 + 1) == this.fruitType.blockID) 083 { 084 return; 085 } 086 087 int i1 = par5Random.nextInt(4); 088 int j1 = par2; 089 int k1 = par4; 090 091 if (i1 == 0) 092 { 093 j1 = par2 - 1; 094 } 095 096 if (i1 == 1) 097 { 098 ++j1; 099 } 100 101 if (i1 == 2) 102 { 103 k1 = par4 - 1; 104 } 105 106 if (i1 == 3) 107 { 108 ++k1; 109 } 110 111 int l1 = par1World.getBlockId(j1, par3 - 1, k1); 112 113 boolean isSoil = (blocksList[l1] != null && blocksList[l1].canSustainPlant(par1World, j1, par3 - 1, k1, ForgeDirection.UP, this)); 114 if (par1World.getBlockId(j1, par3, k1) == 0 && (isSoil || l1 == Block.dirt.blockID || l1 == Block.grass.blockID)) 115 { 116 par1World.func_94575_c(j1, par3, k1, this.fruitType.blockID); 117 } 118 } 119 } 120 } 121 } 122 123 public void fertilizeStem(World par1World, int par2, int par3, int par4) 124 { 125 int l = par1World.getBlockMetadata(par2, par3, par4) + MathHelper.getRandomIntegerInRange(par1World.rand, 2, 5); 126 127 if (l > 7) 128 { 129 l = 7; 130 } 131 132 par1World.setBlockMetadataWithNotify(par2, par3, par4, l, 2); 133 } 134 135 private float getGrowthModifier(World par1World, int par2, int par3, int par4) 136 { 137 float f = 1.0F; 138 int l = par1World.getBlockId(par2, par3, par4 - 1); 139 int i1 = par1World.getBlockId(par2, par3, par4 + 1); 140 int j1 = par1World.getBlockId(par2 - 1, par3, par4); 141 int k1 = par1World.getBlockId(par2 + 1, par3, par4); 142 int l1 = par1World.getBlockId(par2 - 1, par3, par4 - 1); 143 int i2 = par1World.getBlockId(par2 + 1, par3, par4 - 1); 144 int j2 = par1World.getBlockId(par2 + 1, par3, par4 + 1); 145 int k2 = par1World.getBlockId(par2 - 1, par3, par4 + 1); 146 boolean flag = j1 == this.blockID || k1 == this.blockID; 147 boolean flag1 = l == this.blockID || i1 == this.blockID; 148 boolean flag2 = l1 == this.blockID || i2 == this.blockID || j2 == this.blockID || k2 == this.blockID; 149 150 for (int l2 = par2 - 1; l2 <= par2 + 1; ++l2) 151 { 152 for (int i3 = par4 - 1; i3 <= par4 + 1; ++i3) 153 { 154 int j3 = par1World.getBlockId(l2, par3 - 1, i3); 155 float f1 = 0.0F; 156 157 if (blocksList[j3] != null && blocksList[j3].canSustainPlant(par1World, l2, par3 - 1, i3, ForgeDirection.UP, this)) 158 { 159 f1 = 1.0F; 160 161 if (blocksList[j3].isFertile(par1World, l2, par3 - 1, i3)) 162 { 163 f1 = 3.0F; 164 } 165 } 166 167 if (l2 != par2 || i3 != par4) 168 { 169 f1 /= 4.0F; 170 } 171 172 f += f1; 173 } 174 } 175 176 if (flag2 || flag && flag1) 177 { 178 f /= 2.0F; 179 } 180 181 return f; 182 } 183 184 @SideOnly(Side.CLIENT) 185 186 /** 187 * Returns the color this block should be rendered. Used by leaves. 188 */ 189 public int getRenderColor(int par1) 190 { 191 int j = par1 * 32; 192 int k = 255 - par1 * 8; 193 int l = par1 * 4; 194 return j << 16 | k << 8 | l; 195 } 196 197 @SideOnly(Side.CLIENT) 198 199 /** 200 * Returns a integer with hex for 0xrrggbb with this color multiplied against the blocks color. Note only called 201 * when first determining what to render. 202 */ 203 public int colorMultiplier(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) 204 { 205 return this.getRenderColor(par1IBlockAccess.getBlockMetadata(par2, par3, par4)); 206 } 207 208 /** 209 * Sets the block's bounds for rendering it as an item 210 */ 211 public void setBlockBoundsForItemRender() 212 { 213 float f = 0.125F; 214 this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, 0.25F, 0.5F + f); 215 } 216 217 /** 218 * Updates the blocks bounds based on its current state. Args: world, x, y, z 219 */ 220 public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) 221 { 222 this.maxY = (double)((float)(par1IBlockAccess.getBlockMetadata(par2, par3, par4) * 2 + 2) / 16.0F); 223 float f = 0.125F; 224 this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, (float)this.maxY, 0.5F + f); 225 } 226 227 /** 228 * The type of render function that is called for this block 229 */ 230 public int getRenderType() 231 { 232 return 19; 233 } 234 235 @SideOnly(Side.CLIENT) 236 237 /** 238 * Returns the current state of the stem. Returns -1 if the stem is not fully grown, or a value between 0 and 3 239 * based on the direction the stem is facing. 240 */ 241 public int getState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) 242 { 243 int l = par1IBlockAccess.getBlockMetadata(par2, par3, par4); 244 return l < 7 ? -1 : (par1IBlockAccess.getBlockId(par2 - 1, par3, par4) == this.fruitType.blockID ? 0 : (par1IBlockAccess.getBlockId(par2 + 1, par3, par4) == this.fruitType.blockID ? 1 : (par1IBlockAccess.getBlockId(par2, par3, par4 - 1) == this.fruitType.blockID ? 2 : (par1IBlockAccess.getBlockId(par2, par3, par4 + 1) == this.fruitType.blockID ? 3 : -1)))); 245 } 246 247 /** 248 * Drops the block items with a specified chance of dropping the specified items 249 */ 250 public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7) 251 { 252 super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, par7); 253 } 254 255 @Override 256 public ArrayList<ItemStack> getBlockDropped(World world, int x, int y, int z, int metadata, int fortune) 257 { 258 ArrayList<ItemStack> ret = new ArrayList<ItemStack>(); 259 260 for (int i = 0; i < 3; i++) 261 { 262 if (world.rand.nextInt(15) <= metadata) 263 { 264 ret.add(new ItemStack(fruitType == pumpkin ? Item.pumpkinSeeds : Item.melonSeeds)); 265 } 266 } 267 268 return ret; 269 } 270 271 /** 272 * Returns the ID of the items to drop on destruction. 273 */ 274 public int idDropped(int par1, Random par2Random, int par3) 275 { 276 return -1; 277 } 278 279 /** 280 * Returns the quantity of items to drop on block destruction. 281 */ 282 public int quantityDropped(Random par1Random) 283 { 284 return 1; 285 } 286 287 @SideOnly(Side.CLIENT) 288 289 /** 290 * only called by clickMiddleMouseButton , and passed to inventory.setCurrentItem (along with isCreative) 291 */ 292 public int idPicked(World par1World, int par2, int par3, int par4) 293 { 294 return this.fruitType == Block.pumpkin ? Item.pumpkinSeeds.itemID : (this.fruitType == Block.melon ? Item.melonSeeds.itemID : 0); 295 } 296 297 @SideOnly(Side.CLIENT) 298 public void func_94332_a(IconRegister par1IconRegister) 299 { 300 this.field_94336_cN = par1IconRegister.func_94245_a("stem_straight"); 301 this.field_94369_b = par1IconRegister.func_94245_a("stem_bent"); 302 } 303 304 @SideOnly(Side.CLIENT) 305 public Icon func_94368_p() 306 { 307 return this.field_94369_b; 308 } 309}