001package net.minecraft.block;
002
003import cpw.mods.fml.relauncher.Side;
004import cpw.mods.fml.relauncher.SideOnly;
005import java.util.ArrayList;
006import java.util.Random;
007import net.minecraft.client.renderer.texture.IconRegister;
008import net.minecraft.creativetab.CreativeTabs;
009import net.minecraft.item.Item;
010import net.minecraft.item.ItemStack;
011import net.minecraft.util.Icon;
012import net.minecraft.util.MathHelper;
013import net.minecraft.world.World;
014import net.minecraftforge.common.ForgeDirection;
015
016public class BlockCrops extends BlockFlower
017{
018    @SideOnly(Side.CLIENT)
019    private Icon[] iconArray;
020
021    protected BlockCrops(int par1)
022    {
023        super(par1);
024        this.setTickRandomly(true);
025        float f = 0.5F;
026        this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, 0.25F, 0.5F + f);
027        this.setCreativeTab((CreativeTabs)null);
028        this.setHardness(0.0F);
029        this.setStepSound(soundGrassFootstep);
030        this.disableStats();
031    }
032
033    /**
034     * Gets passed in the blockID of the block below and supposed to return true if its allowed to grow on the type of
035     * blockID passed in. Args: blockID
036     */
037    protected boolean canThisPlantGrowOnThisBlockID(int par1)
038    {
039        return par1 == Block.tilledField.blockID;
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        super.updateTick(par1World, par2, par3, par4, par5Random);
048
049        if (par1World.getBlockLightValue(par2, par3 + 1, par4) >= 9)
050        {
051            int l = par1World.getBlockMetadata(par2, par3, par4);
052
053            if (l < 7)
054            {
055                float f = this.getGrowthRate(par1World, par2, par3, par4);
056
057                if (par5Random.nextInt((int)(25.0F / f) + 1) == 0)
058                {
059                    ++l;
060                    par1World.setBlockMetadataWithNotify(par2, par3, par4, l, 2);
061                }
062            }
063        }
064    }
065
066    /**
067     * Apply bonemeal to the crops.
068     */
069    public void fertilize(World par1World, int par2, int par3, int par4)
070    {
071        int l = par1World.getBlockMetadata(par2, par3, par4) + MathHelper.getRandomIntegerInRange(par1World.rand, 2, 5);
072
073        if (l > 7)
074        {
075            l = 7;
076        }
077
078        par1World.setBlockMetadataWithNotify(par2, par3, par4, l, 2);
079    }
080
081    /**
082     * Gets the growth rate for the crop. Setup to encourage rows by halving growth rate if there is diagonals, crops on
083     * different sides that aren't opposing, and by adding growth for every crop next to this one (and for crop below
084     * this one). Args: x, y, z
085     */
086    private float getGrowthRate(World par1World, int par2, int par3, int par4)
087    {
088        float f = 1.0F;
089        int l = par1World.getBlockId(par2, par3, par4 - 1);
090        int i1 = par1World.getBlockId(par2, par3, par4 + 1);
091        int j1 = par1World.getBlockId(par2 - 1, par3, par4);
092        int k1 = par1World.getBlockId(par2 + 1, par3, par4);
093        int l1 = par1World.getBlockId(par2 - 1, par3, par4 - 1);
094        int i2 = par1World.getBlockId(par2 + 1, par3, par4 - 1);
095        int j2 = par1World.getBlockId(par2 + 1, par3, par4 + 1);
096        int k2 = par1World.getBlockId(par2 - 1, par3, par4 + 1);
097        boolean flag = j1 == this.blockID || k1 == this.blockID;
098        boolean flag1 = l == this.blockID || i1 == this.blockID;
099        boolean flag2 = l1 == this.blockID || i2 == this.blockID || j2 == this.blockID || k2 == this.blockID;
100
101        for (int l2 = par2 - 1; l2 <= par2 + 1; ++l2)
102        {
103            for (int i3 = par4 - 1; i3 <= par4 + 1; ++i3)
104            {
105                int j3 = par1World.getBlockId(l2, par3 - 1, i3);
106                float f1 = 0.0F;
107
108                if (blocksList[j3] != null && blocksList[j3].canSustainPlant(par1World, l2, par3 - 1, i3, ForgeDirection.UP, this))
109                {
110                    f1 = 1.0F;
111
112                    if (blocksList[j3].isFertile(par1World, l2, par3 - 1, i3))
113                    {
114                        f1 = 3.0F;
115                    }
116                }
117
118                if (l2 != par2 || i3 != par4)
119                {
120                    f1 /= 4.0F;
121                }
122
123                f += f1;
124            }
125        }
126
127        if (flag2 || flag && flag1)
128        {
129            f /= 2.0F;
130        }
131
132        return f;
133    }
134
135    @SideOnly(Side.CLIENT)
136
137    /**
138     * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata
139     */
140    public Icon getBlockTextureFromSideAndMetadata(int par1, int par2)
141    {
142        if (par2 < 0 || par2 > 7)
143        {
144            par2 = 7;
145        }
146
147        return this.iconArray[par2];
148    }
149
150    /**
151     * The type of render function that is called for this block
152     */
153    public int getRenderType()
154    {
155        return 6;
156    }
157
158    /**
159     * Generate a seed ItemStack for this crop.
160     */
161    protected int getSeedItem()
162    {
163        return Item.seeds.itemID;
164    }
165
166    /**
167     * Generate a crop produce ItemStack for this crop.
168     */
169    protected int getCropItem()
170    {
171        return Item.wheat.itemID;
172    }
173
174    /**
175     * Drops the block items with a specified chance of dropping the specified items
176     */
177    public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7)
178    {
179        super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, 0);
180    }
181
182    @Override 
183    public ArrayList<ItemStack> getBlockDropped(World world, int x, int y, int z, int metadata, int fortune)
184    {
185        ArrayList<ItemStack> ret = super.getBlockDropped(world, x, y, z, metadata, fortune);
186
187        if (metadata >= 7)
188        {
189            for (int n = 0; n < 3 + fortune; n++)
190            {
191                if (world.rand.nextInt(15) <= metadata)
192                {
193                    ret.add(new ItemStack(this.getSeedItem(), 1, 0));
194                }
195            }
196        }
197
198        return ret;
199    }
200
201    /**
202     * Returns the ID of the items to drop on destruction.
203     */
204    public int idDropped(int par1, Random par2Random, int par3)
205    {
206        return par1 == 7 ? this.getCropItem() : this.getSeedItem();
207    }
208
209    /**
210     * Returns the quantity of items to drop on block destruction.
211     */
212    public int quantityDropped(Random par1Random)
213    {
214        return 1;
215    }
216
217    @SideOnly(Side.CLIENT)
218
219    /**
220     * only called by clickMiddleMouseButton , and passed to inventory.setCurrentItem (along with isCreative)
221     */
222    public int idPicked(World par1World, int par2, int par3, int par4)
223    {
224        return this.getSeedItem();
225    }
226
227    @SideOnly(Side.CLIENT)
228
229    /**
230     * When this method is called, your block should register all the icons it needs with the given IconRegister. This
231     * is the only chance you get to register icons.
232     */
233    public void registerIcons(IconRegister par1IconRegister)
234    {
235        this.iconArray = new Icon[8];
236
237        for (int i = 0; i < this.iconArray.length; ++i)
238        {
239            this.iconArray[i] = par1IconRegister.registerIcon("crops_" + i);
240        }
241    }
242}