001package net.minecraft.block;
002
003import cpw.mods.fml.relauncher.Side;
004import cpw.mods.fml.relauncher.SideOnly;
005import java.util.Random;
006import net.minecraft.block.material.Material;
007import net.minecraft.client.renderer.texture.IconRegister;
008import net.minecraft.creativetab.CreativeTabs;
009import net.minecraft.entity.Entity;
010import net.minecraft.util.AxisAlignedBB;
011import net.minecraft.util.DamageSource;
012import net.minecraft.util.Icon;
013import net.minecraft.world.World;
014
015import net.minecraftforge.common.EnumPlantType;
016import net.minecraftforge.common.ForgeDirection;
017import net.minecraftforge.common.IPlantable;
018
019public class BlockCactus extends Block implements IPlantable
020{
021    @SideOnly(Side.CLIENT)
022    private Icon field_94380_a;
023    @SideOnly(Side.CLIENT)
024    private Icon field_94379_b;
025
026    protected BlockCactus(int par1)
027    {
028        super(par1, Material.cactus);
029        this.setTickRandomly(true);
030        this.setCreativeTab(CreativeTabs.tabDecorations);
031    }
032
033    /**
034     * Ticks the block if it's been scheduled
035     */
036    public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random)
037    {
038        if (par1World.isAirBlock(par2, par3 + 1, par4))
039        {
040            int l;
041
042            for (l = 1; par1World.getBlockId(par2, par3 - l, par4) == this.blockID; ++l)
043            {
044                ;
045            }
046
047            if (l < 3)
048            {
049                int i1 = par1World.getBlockMetadata(par2, par3, par4);
050
051                if (i1 == 15)
052                {
053                    par1World.func_94575_c(par2, par3 + 1, par4, this.blockID);
054                    par1World.setBlockMetadataWithNotify(par2, par3, par4, 0, 4);
055                    this.onNeighborBlockChange(par1World, par2, par3 + 1, par4, this.blockID);
056                }
057                else
058                {
059                    par1World.setBlockMetadataWithNotify(par2, par3, par4, i1 + 1, 4);
060                }
061            }
062        }
063    }
064
065    /**
066     * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been
067     * cleared to be reused)
068     */
069    public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
070    {
071        float f = 0.0625F;
072        return AxisAlignedBB.getAABBPool().getAABB((double)((float)par2 + f), (double)par3, (double)((float)par4 + f), (double)((float)(par2 + 1) - f), (double)((float)(par3 + 1) - f), (double)((float)(par4 + 1) - f));
073    }
074
075    /**
076     * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc)
077     */
078    public boolean renderAsNormalBlock()
079    {
080        return false;
081    }
082
083    @SideOnly(Side.CLIENT)
084
085    /**
086     * Returns the bounding box of the wired rectangular prism to render.
087     */
088    public AxisAlignedBB getSelectedBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
089    {
090        float f = 0.0625F;
091        return AxisAlignedBB.getAABBPool().getAABB((double)((float)par2 + f), (double)par3, (double)((float)par4 + f), (double)((float)(par2 + 1) - f), (double)(par3 + 1), (double)((float)(par4 + 1) - f));
092    }
093
094    @SideOnly(Side.CLIENT)
095
096    /**
097     * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata
098     */
099    public Icon getBlockTextureFromSideAndMetadata(int par1, int par2)
100    {
101        return par1 == 1 ? this.field_94380_a : (par1 == 0 ? this.field_94379_b : this.field_94336_cN);
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     * The type of render function that is called for this block
115     */
116    public int getRenderType()
117    {
118        return 13;
119    }
120
121    /**
122     * Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z
123     */
124    public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4)
125    {
126        return !super.canPlaceBlockAt(par1World, par2, par3, par4) ? false : this.canBlockStay(par1World, par2, par3, par4);
127    }
128
129    /**
130     * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are
131     * their own) Args: x, y, z, neighbor blockID
132     */
133    public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5)
134    {
135        if (!this.canBlockStay(par1World, par2, par3, par4))
136        {
137            par1World.func_94578_a(par2, par3, par4, true);
138        }
139    }
140
141    /**
142     * Can this block stay at this position.  Similar to canPlaceBlockAt except gets checked often with plants.
143     */
144    public boolean canBlockStay(World par1World, int par2, int par3, int par4)
145    {
146        if (par1World.getBlockMaterial(par2 - 1, par3, par4).isSolid())
147        {
148            return false;
149        }
150        else if (par1World.getBlockMaterial(par2 + 1, par3, par4).isSolid())
151        {
152            return false;
153        }
154        else if (par1World.getBlockMaterial(par2, par3, par4 - 1).isSolid())
155        {
156            return false;
157        }
158        else if (par1World.getBlockMaterial(par2, par3, par4 + 1).isSolid())
159        {
160            return false;
161        }
162        else
163        {
164            int l = par1World.getBlockId(par2, par3 - 1, par4);
165            return blocksList[l] != null && blocksList[l].canSustainPlant(par1World, par2, par3 - 1, par4, ForgeDirection.UP, this);
166        }
167    }
168
169    /**
170     * Triggered whenever an entity collides with this block (enters into the block). Args: world, x, y, z, entity
171     */
172    public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity)
173    {
174        par5Entity.attackEntityFrom(DamageSource.cactus, 1);
175    }
176
177    @SideOnly(Side.CLIENT)
178    public void func_94332_a(IconRegister par1IconRegister)
179    {
180        this.field_94336_cN = par1IconRegister.func_94245_a("cactus_side");
181        this.field_94380_a = par1IconRegister.func_94245_a("cactus_top");
182        this.field_94379_b = par1IconRegister.func_94245_a("cactus_bottom");
183    }
184
185    @Override
186    public EnumPlantType getPlantType(World world, int x, int y, int z)
187    {
188        return EnumPlantType.Desert;
189    }
190
191    @Override
192    public int getPlantID(World world, int x, int y, int z)
193    {
194        return blockID;
195    }
196
197    @Override
198    public int getPlantMetadata(World world, int x, int y, int z)
199    {
200        return -1;
201    }
202}