001 package net.minecraft.src;
002
003 import net.minecraftforge.common.ForgeDirection;
004 import cpw.mods.fml.common.Side;
005 import cpw.mods.fml.common.asm.SideOnly;
006
007 public class BlockTrapDoor extends Block
008 {
009 /** Set this to allow trapdoors to remain free-floating */
010 public static boolean disableValidation = false;
011
012 protected BlockTrapDoor(int par1, Material par2Material)
013 {
014 super(par1, par2Material);
015 this.blockIndexInTexture = 84;
016
017 if (par2Material == Material.iron)
018 {
019 ++this.blockIndexInTexture;
020 }
021
022 float var3 = 0.5F;
023 float var4 = 1.0F;
024 this.setBlockBounds(0.5F - var3, 0.0F, 0.5F - var3, 0.5F + var3, var4, 0.5F + var3);
025 this.setCreativeTab(CreativeTabs.tabRedstone);
026 }
027
028 /**
029 * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two
030 * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block.
031 */
032 public boolean isOpaqueCube()
033 {
034 return false;
035 }
036
037 /**
038 * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc)
039 */
040 public boolean renderAsNormalBlock()
041 {
042 return false;
043 }
044
045 public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
046 {
047 return !isTrapdoorOpen(par1IBlockAccess.getBlockMetadata(par2, par3, par4));
048 }
049
050 /**
051 * The type of render function that is called for this block
052 */
053 public int getRenderType()
054 {
055 return 0;
056 }
057
058 @SideOnly(Side.CLIENT)
059
060 /**
061 * Returns the bounding box of the wired rectangular prism to render.
062 */
063 public AxisAlignedBB getSelectedBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
064 {
065 this.setBlockBoundsBasedOnState(par1World, par2, par3, par4);
066 return super.getSelectedBoundingBoxFromPool(par1World, par2, par3, par4);
067 }
068
069 /**
070 * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been
071 * cleared to be reused)
072 */
073 public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
074 {
075 this.setBlockBoundsBasedOnState(par1World, par2, par3, par4);
076 return super.getCollisionBoundingBoxFromPool(par1World, par2, par3, par4);
077 }
078
079 /**
080 * Updates the blocks bounds based on its current state. Args: world, x, y, z
081 */
082 public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
083 {
084 this.setBlockBoundsForBlockRender(par1IBlockAccess.getBlockMetadata(par2, par3, par4));
085 }
086
087 /**
088 * Sets the block's bounds for rendering it as an item
089 */
090 public void setBlockBoundsForItemRender()
091 {
092 float var1 = 0.1875F;
093 this.setBlockBounds(0.0F, 0.5F - var1 / 2.0F, 0.0F, 1.0F, 0.5F + var1 / 2.0F, 1.0F);
094 }
095
096 public void setBlockBoundsForBlockRender(int par1)
097 {
098 float var2 = 0.1875F;
099 this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, var2, 1.0F);
100
101 if (isTrapdoorOpen(par1))
102 {
103 if ((par1 & 3) == 0)
104 {
105 this.setBlockBounds(0.0F, 0.0F, 1.0F - var2, 1.0F, 1.0F, 1.0F);
106 }
107
108 if ((par1 & 3) == 1)
109 {
110 this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, var2);
111 }
112
113 if ((par1 & 3) == 2)
114 {
115 this.setBlockBounds(1.0F - var2, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
116 }
117
118 if ((par1 & 3) == 3)
119 {
120 this.setBlockBounds(0.0F, 0.0F, 0.0F, var2, 1.0F, 1.0F);
121 }
122 }
123 }
124
125 /**
126 * Called when the block is clicked by a player. Args: x, y, z, entityPlayer
127 */
128 public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer)
129 {
130 this.onBlockActivated(par1World, par2, par3, par4, par5EntityPlayer, 0, 0.0F, 0.0F, 0.0F);
131 }
132
133 /**
134 * Called upon block activation (right click on the block.)
135 */
136 public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9)
137 {
138 if (this.blockMaterial == Material.iron)
139 {
140 return true;
141 }
142 else
143 {
144 int var10 = par1World.getBlockMetadata(par2, par3, par4);
145 par1World.setBlockMetadataWithNotify(par2, par3, par4, var10 ^ 4);
146 par1World.playAuxSFXAtEntity(par5EntityPlayer, 1003, par2, par3, par4, 0);
147 return true;
148 }
149 }
150
151 public void onPoweredBlockChange(World par1World, int par2, int par3, int par4, boolean par5)
152 {
153 int var6 = par1World.getBlockMetadata(par2, par3, par4);
154 boolean var7 = (var6 & 4) > 0;
155
156 if (var7 != par5)
157 {
158 par1World.setBlockMetadataWithNotify(par2, par3, par4, var6 ^ 4);
159 par1World.playAuxSFXAtEntity((EntityPlayer)null, 1003, par2, par3, par4, 0);
160 }
161 }
162
163 /**
164 * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are
165 * their own) Args: x, y, z, neighbor blockID
166 */
167 public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5)
168 {
169 if (!par1World.isRemote)
170 {
171 int var6 = par1World.getBlockMetadata(par2, par3, par4);
172 int var7 = par2;
173 int var8 = par4;
174
175 if ((var6 & 3) == 0)
176 {
177 var8 = par4 + 1;
178 }
179
180 if ((var6 & 3) == 1)
181 {
182 --var8;
183 }
184
185 if ((var6 & 3) == 2)
186 {
187 var7 = par2 + 1;
188 }
189
190 if ((var6 & 3) == 3)
191 {
192 --var7;
193 }
194
195 if (!(isValidSupportBlock(par1World.getBlockId(var7, par3, var8)) || par1World.isBlockSolidOnSide(var7, par3, var8, ForgeDirection.getOrientation((var6 & 3) + 2))))
196 {
197 par1World.setBlockWithNotify(par2, par3, par4, 0);
198 this.dropBlockAsItem(par1World, par2, par3, par4, var6, 0);
199 }
200
201 boolean var9 = par1World.isBlockIndirectlyGettingPowered(par2, par3, par4);
202
203 if (var9 || par5 > 0 && Block.blocksList[par5].canProvidePower() || par5 == 0)
204 {
205 this.onPoweredBlockChange(par1World, par2, par3, par4, var9);
206 }
207 }
208 }
209
210 /**
211 * Ray traces through the blocks collision from start vector to end vector returning a ray trace hit. Args: world,
212 * x, y, z, startVec, endVec
213 */
214 public MovingObjectPosition collisionRayTrace(World par1World, int par2, int par3, int par4, Vec3 par5Vec3, Vec3 par6Vec3)
215 {
216 this.setBlockBoundsBasedOnState(par1World, par2, par3, par4);
217 return super.collisionRayTrace(par1World, par2, par3, par4, par5Vec3, par6Vec3);
218 }
219
220 /**
221 * called before onBlockPlacedBy by ItemBlock and ItemReed
222 */
223 public void updateBlockMetadata(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8)
224 {
225 byte var9 = 0;
226
227 if (par5 == 2)
228 {
229 var9 = 0;
230 }
231
232 if (par5 == 3)
233 {
234 var9 = 1;
235 }
236
237 if (par5 == 4)
238 {
239 var9 = 2;
240 }
241
242 if (par5 == 5)
243 {
244 var9 = 3;
245 }
246
247 par1World.setBlockMetadataWithNotify(par2, par3, par4, var9);
248 }
249
250 /**
251 * checks to see if you can place this block can be placed on that side of a block: BlockLever overrides
252 */
253 public boolean canPlaceBlockOnSide(World par1World, int par2, int par3, int par4, int par5)
254 {
255 if (disableValidation)
256 {
257 return true;
258 }
259 if (par5 == 0)
260 {
261 return false;
262 }
263 else if (par5 == 1)
264 {
265 return false;
266 }
267 else
268 {
269 if (par5 == 2)
270 {
271 ++par4;
272 }
273
274 if (par5 == 3)
275 {
276 --par4;
277 }
278
279 if (par5 == 4)
280 {
281 ++par2;
282 }
283
284 if (par5 == 5)
285 {
286 --par2;
287 }
288
289 return isValidSupportBlock(par1World.getBlockId(par2, par3, par4)) || par1World.isBlockSolidOnSide(par2, par3, par4, ForgeDirection.UP);
290 }
291 }
292
293 public static boolean isTrapdoorOpen(int par0)
294 {
295 return (par0 & 4) != 0;
296 }
297
298 /**
299 * Checks if the block ID is a valid support block for the trap door to connect with. If it is not the trapdoor is
300 * dropped into the world.
301 */
302 private static boolean isValidSupportBlock(int par0)
303 {
304 if (disableValidation)
305 {
306 return true;
307 }
308 if (par0 <= 0)
309 {
310 return false;
311 }
312 else
313 {
314 Block var1 = Block.blocksList[par0];
315 return var1 != null && var1.blockMaterial.isOpaque() && var1.renderAsNormalBlock() || var1 == Block.glowStone;
316 }
317 }
318 }