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}