001 package net.minecraft.block; 002 003 import cpw.mods.fml.relauncher.Side; 004 import cpw.mods.fml.relauncher.SideOnly; 005 import net.minecraft.block.material.Material; 006 import net.minecraft.creativetab.CreativeTabs; 007 import net.minecraft.entity.EntityLiving; 008 import net.minecraft.entity.player.EntityPlayer; 009 import net.minecraft.util.AxisAlignedBB; 010 import net.minecraft.util.MathHelper; 011 import net.minecraft.world.IBlockAccess; 012 import net.minecraft.world.World; 013 014 public class BlockFenceGate extends BlockDirectional 015 { 016 public BlockFenceGate(int par1, int par2) 017 { 018 super(par1, par2, Material.wood); 019 this.setCreativeTab(CreativeTabs.tabRedstone); 020 } 021 022 /** 023 * Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z 024 */ 025 public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) 026 { 027 return !par1World.getBlockMaterial(par2, par3 - 1, par4).isSolid() ? false : super.canPlaceBlockAt(par1World, par2, par3, par4); 028 } 029 030 /** 031 * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been 032 * cleared to be reused) 033 */ 034 public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) 035 { 036 int var5 = par1World.getBlockMetadata(par2, par3, par4); 037 return isFenceGateOpen(var5) ? null : (var5 != 2 && var5 != 0 ? AxisAlignedBB.getAABBPool().addOrModifyAABBInPool((double)((float)par2 + 0.375F), (double)par3, (double)par4, (double)((float)par2 + 0.625F), (double)((float)par3 + 1.5F), (double)(par4 + 1)) : AxisAlignedBB.getAABBPool().addOrModifyAABBInPool((double)par2, (double)par3, (double)((float)par4 + 0.375F), (double)(par2 + 1), (double)((float)par3 + 1.5F), (double)((float)par4 + 0.625F))); 038 } 039 040 /** 041 * Updates the blocks bounds based on its current state. Args: world, x, y, z 042 */ 043 public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) 044 { 045 int var5 = getDirection(par1IBlockAccess.getBlockMetadata(par2, par3, par4)); 046 047 if (var5 != 2 && var5 != 0) 048 { 049 this.setBlockBounds(0.375F, 0.0F, 0.0F, 0.625F, 1.0F, 1.0F); 050 } 051 else 052 { 053 this.setBlockBounds(0.0F, 0.0F, 0.375F, 1.0F, 1.0F, 0.625F); 054 } 055 } 056 057 /** 058 * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two 059 * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. 060 */ 061 public boolean isOpaqueCube() 062 { 063 return false; 064 } 065 066 /** 067 * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc) 068 */ 069 public boolean renderAsNormalBlock() 070 { 071 return false; 072 } 073 074 public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) 075 { 076 return isFenceGateOpen(par1IBlockAccess.getBlockMetadata(par2, par3, par4)); 077 } 078 079 /** 080 * The type of render function that is called for this block 081 */ 082 public int getRenderType() 083 { 084 return 21; 085 } 086 087 /** 088 * Called when the block is placed in the world. 089 */ 090 public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving) 091 { 092 int var6 = (MathHelper.floor_double((double)(par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3) % 4; 093 par1World.setBlockMetadataWithNotify(par2, par3, par4, var6); 094 } 095 096 /** 097 * Called upon block activation (right click on the block.) 098 */ 099 public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) 100 { 101 int var10 = par1World.getBlockMetadata(par2, par3, par4); 102 103 if (isFenceGateOpen(var10)) 104 { 105 par1World.setBlockMetadataWithNotify(par2, par3, par4, var10 & -5); 106 } 107 else 108 { 109 int var11 = (MathHelper.floor_double((double)(par5EntityPlayer.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3) % 4; 110 int var12 = getDirection(var10); 111 112 if (var12 == (var11 + 2) % 4) 113 { 114 var10 = var11; 115 } 116 117 par1World.setBlockMetadataWithNotify(par2, par3, par4, var10 | 4); 118 } 119 120 par1World.playAuxSFXAtEntity(par5EntityPlayer, 1003, par2, par3, par4, 0); 121 return true; 122 } 123 124 /** 125 * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are 126 * their own) Args: x, y, z, neighbor blockID 127 */ 128 public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) 129 { 130 if (!par1World.isRemote) 131 { 132 int var6 = par1World.getBlockMetadata(par2, par3, par4); 133 boolean var7 = par1World.isBlockIndirectlyGettingPowered(par2, par3, par4); 134 135 if (var7 || par5 > 0 && Block.blocksList[par5].canProvidePower() || par5 == 0) 136 { 137 if (var7 && !isFenceGateOpen(var6)) 138 { 139 par1World.setBlockMetadataWithNotify(par2, par3, par4, var6 | 4); 140 par1World.playAuxSFXAtEntity((EntityPlayer)null, 1003, par2, par3, par4, 0); 141 } 142 else if (!var7 && isFenceGateOpen(var6)) 143 { 144 par1World.setBlockMetadataWithNotify(par2, par3, par4, var6 & -5); 145 par1World.playAuxSFXAtEntity((EntityPlayer)null, 1003, par2, par3, par4, 0); 146 } 147 } 148 } 149 } 150 151 /** 152 * Returns if the fence gate is open according to its metadata. 153 */ 154 public static boolean isFenceGateOpen(int par0) 155 { 156 return (par0 & 4) != 0; 157 } 158 159 @SideOnly(Side.CLIENT) 160 161 /** 162 * Returns true if the given side of this block type should be rendered, if the adjacent block is at the given 163 * coordinates. Args: blockAccess, x, y, z, side 164 */ 165 public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) 166 { 167 return true; 168 } 169 }