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.entity.Entity; 009import net.minecraft.entity.player.EntityPlayer; 010import net.minecraft.util.AxisAlignedBB; 011import net.minecraft.util.Icon; 012import net.minecraft.world.World; 013 014import net.minecraftforge.common.ForgeDirection; 015import net.minecraftforge.common.IPlantable; 016 017public class BlockFarmland extends Block 018{ 019 @SideOnly(Side.CLIENT) 020 private Icon field_94441_a; 021 @SideOnly(Side.CLIENT) 022 private Icon field_94440_b; 023 024 protected BlockFarmland(int par1) 025 { 026 super(par1, Material.ground); 027 this.setTickRandomly(true); 028 this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.9375F, 1.0F); 029 this.setLightOpacity(255); 030 } 031 032 /** 033 * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been 034 * cleared to be reused) 035 */ 036 public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) 037 { 038 return AxisAlignedBB.getAABBPool().getAABB((double)(par2 + 0), (double)(par3 + 0), (double)(par4 + 0), (double)(par2 + 1), (double)(par3 + 1), (double)(par4 + 1)); 039 } 040 041 /** 042 * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two 043 * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. 044 */ 045 public boolean isOpaqueCube() 046 { 047 return false; 048 } 049 050 /** 051 * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc) 052 */ 053 public boolean renderAsNormalBlock() 054 { 055 return false; 056 } 057 058 @SideOnly(Side.CLIENT) 059 060 /** 061 * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata 062 */ 063 public Icon getBlockTextureFromSideAndMetadata(int par1, int par2) 064 { 065 return par1 == 1 ? (par2 > 0 ? this.field_94441_a : this.field_94440_b) : Block.dirt.getBlockTextureFromSide(par1); 066 } 067 068 /** 069 * Ticks the block if it's been scheduled 070 */ 071 public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) 072 { 073 if (!this.isWaterNearby(par1World, par2, par3, par4) && !par1World.canLightningStrikeAt(par2, par3 + 1, par4)) 074 { 075 int l = par1World.getBlockMetadata(par2, par3, par4); 076 077 if (l > 0) 078 { 079 par1World.setBlockMetadataWithNotify(par2, par3, par4, l - 1, 2); 080 } 081 else if (!this.isCropsNearby(par1World, par2, par3, par4)) 082 { 083 par1World.func_94575_c(par2, par3, par4, Block.dirt.blockID); 084 } 085 } 086 else 087 { 088 par1World.setBlockMetadataWithNotify(par2, par3, par4, 7, 2); 089 } 090 } 091 092 /** 093 * Block's chance to react to an entity falling on it. 094 */ 095 public void onFallenUpon(World par1World, int par2, int par3, int par4, Entity par5Entity, float par6) 096 { 097 if (!par1World.isRemote && par1World.rand.nextFloat() < par6 - 0.5F) 098 { 099 if (!(par5Entity instanceof EntityPlayer) && !par1World.getGameRules().getGameRuleBooleanValue("mobGriefing")) 100 { 101 return; 102 } 103 104 par1World.func_94575_c(par2, par3, par4, Block.dirt.blockID); 105 } 106 } 107 108 /** 109 * returns true if there is at least one cropblock nearby (x-1 to x+1, y+1, z-1 to z+1) 110 */ 111 private boolean isCropsNearby(World par1World, int par2, int par3, int par4) 112 { 113 byte b0 = 0; 114 115 for (int l = par2 - b0; l <= par2 + b0; ++l) 116 { 117 for (int i1 = par4 - b0; i1 <= par4 + b0; ++i1) 118 { 119 int j1 = par1World.getBlockId(l, par3 + 1, i1); 120 121 Block plant = blocksList[j1]; 122 if (plant instanceof IPlantable && canSustainPlant(par1World, par2, par3, par4, ForgeDirection.UP, (IPlantable)plant)) 123 { 124 return true; 125 } 126 } 127 } 128 129 return false; 130 } 131 132 /** 133 * returns true if there's water nearby (x-4 to x+4, y to y+1, k-4 to k+4) 134 */ 135 private boolean isWaterNearby(World par1World, int par2, int par3, int par4) 136 { 137 for (int l = par2 - 4; l <= par2 + 4; ++l) 138 { 139 for (int i1 = par3; i1 <= par3 + 1; ++i1) 140 { 141 for (int j1 = par4 - 4; j1 <= par4 + 4; ++j1) 142 { 143 if (par1World.getBlockMaterial(l, i1, j1) == Material.water) 144 { 145 return true; 146 } 147 } 148 } 149 } 150 151 return false; 152 } 153 154 /** 155 * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are 156 * their own) Args: x, y, z, neighbor blockID 157 */ 158 public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) 159 { 160 super.onNeighborBlockChange(par1World, par2, par3, par4, par5); 161 Material material = par1World.getBlockMaterial(par2, par3 + 1, par4); 162 163 if (material.isSolid()) 164 { 165 par1World.func_94575_c(par2, par3, par4, Block.dirt.blockID); 166 } 167 } 168 169 /** 170 * Returns the ID of the items to drop on destruction. 171 */ 172 public int idDropped(int par1, Random par2Random, int par3) 173 { 174 return Block.dirt.idDropped(0, par2Random, par3); 175 } 176 177 @SideOnly(Side.CLIENT) 178 179 /** 180 * only called by clickMiddleMouseButton , and passed to inventory.setCurrentItem (along with isCreative) 181 */ 182 public int idPicked(World par1World, int par2, int par3, int par4) 183 { 184 return Block.dirt.blockID; 185 } 186 187 @SideOnly(Side.CLIENT) 188 public void func_94332_a(IconRegister par1IconRegister) 189 { 190 this.field_94441_a = par1IconRegister.func_94245_a("farmland_wet"); 191 this.field_94440_b = par1IconRegister.func_94245_a("farmland_dry"); 192 } 193}