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