001 package net.minecraft.src;
002
003 import cpw.mods.fml.common.Side;
004 import cpw.mods.fml.common.asm.SideOnly;
005 import java.util.List;
006 import java.util.Random;
007
008 public class BlockStairs extends Block
009 {
010 private static final int[][] field_72159_a = new int[][] {{2, 6}, {3, 7}, {2, 3}, {6, 7}, {0, 4}, {1, 5}, {0, 1}, {4, 5}};
011
012 /** The block that is used as model for the stair. */
013 private final Block modelBlock;
014 private final int field_72158_c;
015 private boolean field_72156_cr = false;
016 private int field_72160_cs = 0;
017
018 protected BlockStairs(int par1, Block par2Block, int par3)
019 {
020 super(par1, par2Block.blockIndexInTexture, par2Block.blockMaterial);
021 this.modelBlock = par2Block;
022 this.field_72158_c = par3;
023 this.setHardness(par2Block.blockHardness);
024 this.setResistance(par2Block.blockResistance / 3.0F);
025 this.setStepSound(par2Block.stepSound);
026 this.setLightOpacity(255);
027 this.setCreativeTab(CreativeTabs.tabBlock);
028 }
029
030 /**
031 * Updates the blocks bounds based on its current state. Args: world, x, y, z
032 */
033 public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
034 {
035 if (this.field_72156_cr)
036 {
037 this.setBlockBounds(0.5F * (float)(this.field_72160_cs % 2), 0.5F * (float)(this.field_72160_cs / 2 % 2), 0.5F * (float)(this.field_72160_cs / 4 % 2), 0.5F + 0.5F * (float)(this.field_72160_cs % 2), 0.5F + 0.5F * (float)(this.field_72160_cs / 2 % 2), 0.5F + 0.5F * (float)(this.field_72160_cs / 4 % 2));
038 }
039 else
040 {
041 this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
042 }
043 }
044
045 /**
046 * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two
047 * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block.
048 */
049 public boolean isOpaqueCube()
050 {
051 return false;
052 }
053
054 /**
055 * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc)
056 */
057 public boolean renderAsNormalBlock()
058 {
059 return false;
060 }
061
062 /**
063 * The type of render function that is called for this block
064 */
065 public int getRenderType()
066 {
067 return 10;
068 }
069
070 /**
071 * if the specified block is in the given AABB, add its collision bounding box to the given list
072 */
073 public void addCollidingBlockToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, List par6List, Entity par7Entity)
074 {
075 int var8 = par1World.getBlockMetadata(par2, par3, par4);
076 int var9 = var8 & 3;
077 float var10 = 0.0F;
078 float var11 = 0.5F;
079 float var12 = 0.5F;
080 float var13 = 1.0F;
081
082 if ((var8 & 4) != 0)
083 {
084 var10 = 0.5F;
085 var11 = 1.0F;
086 var12 = 0.0F;
087 var13 = 0.5F;
088 }
089
090 this.setBlockBounds(0.0F, var10, 0.0F, 1.0F, var11, 1.0F);
091 super.addCollidingBlockToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
092
093 if (var9 == 0)
094 {
095 this.setBlockBounds(0.5F, var12, 0.0F, 1.0F, var13, 1.0F);
096 super.addCollidingBlockToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
097 }
098 else if (var9 == 1)
099 {
100 this.setBlockBounds(0.0F, var12, 0.0F, 0.5F, var13, 1.0F);
101 super.addCollidingBlockToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
102 }
103 else if (var9 == 2)
104 {
105 this.setBlockBounds(0.0F, var12, 0.5F, 1.0F, var13, 1.0F);
106 super.addCollidingBlockToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
107 }
108 else if (var9 == 3)
109 {
110 this.setBlockBounds(0.0F, var12, 0.0F, 1.0F, var13, 0.5F);
111 super.addCollidingBlockToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
112 }
113
114 this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
115 }
116
117 @SideOnly(Side.CLIENT)
118
119 /**
120 * A randomly called display update to be able to add particles or other items for display
121 */
122 public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random)
123 {
124 this.modelBlock.randomDisplayTick(par1World, par2, par3, par4, par5Random);
125 }
126
127 /**
128 * Called when the block is clicked by a player. Args: x, y, z, entityPlayer
129 */
130 public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer)
131 {
132 this.modelBlock.onBlockClicked(par1World, par2, par3, par4, par5EntityPlayer);
133 }
134
135 /**
136 * Called right before the block is destroyed by a player. Args: world, x, y, z, metaData
137 */
138 public void onBlockDestroyedByPlayer(World par1World, int par2, int par3, int par4, int par5)
139 {
140 this.modelBlock.onBlockDestroyedByPlayer(par1World, par2, par3, par4, par5);
141 }
142
143 @SideOnly(Side.CLIENT)
144
145 /**
146 * Goes straight to getLightBrightnessForSkyBlocks for Blocks, does some fancy computing for Fluids
147 */
148 public int getMixedBrightnessForBlock(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
149 {
150 return this.modelBlock.getMixedBrightnessForBlock(par1IBlockAccess, par2, par3, par4);
151 }
152
153 @SideOnly(Side.CLIENT)
154
155 /**
156 * How bright to render this block based on the light its receiving. Args: iBlockAccess, x, y, z
157 */
158 public float getBlockBrightness(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
159 {
160 return this.modelBlock.getBlockBrightness(par1IBlockAccess, par2, par3, par4);
161 }
162
163 /**
164 * Returns how much this block can resist explosions from the passed in entity.
165 */
166 public float getExplosionResistance(Entity par1Entity)
167 {
168 return this.modelBlock.getExplosionResistance(par1Entity);
169 }
170
171 /**
172 * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata
173 */
174 public int getBlockTextureFromSideAndMetadata(int par1, int par2)
175 {
176 return this.modelBlock.getBlockTextureFromSideAndMetadata(par1, this.field_72158_c);
177 }
178
179 /**
180 * Returns the block texture based on the side being looked at. Args: side
181 */
182 public int getBlockTextureFromSide(int par1)
183 {
184 return this.modelBlock.getBlockTextureFromSideAndMetadata(par1, this.field_72158_c);
185 }
186
187 @SideOnly(Side.CLIENT)
188
189 /**
190 * Returns which pass should this block be rendered on. 0 for solids and 1 for alpha
191 */
192 public int getRenderBlockPass()
193 {
194 return this.modelBlock.getRenderBlockPass();
195 }
196
197 /**
198 * How many world ticks before ticking
199 */
200 public int tickRate()
201 {
202 return this.modelBlock.tickRate();
203 }
204
205 @SideOnly(Side.CLIENT)
206
207 /**
208 * Returns the bounding box of the wired rectangular prism to render.
209 */
210 public AxisAlignedBB getSelectedBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
211 {
212 return this.modelBlock.getSelectedBoundingBoxFromPool(par1World, par2, par3, par4);
213 }
214
215 /**
216 * Can add to the passed in vector for a movement vector to be applied to the entity. Args: x, y, z, entity, vec3d
217 */
218 public void velocityToAddToEntity(World par1World, int par2, int par3, int par4, Entity par5Entity, Vec3 par6Vec3)
219 {
220 this.modelBlock.velocityToAddToEntity(par1World, par2, par3, par4, par5Entity, par6Vec3);
221 }
222
223 /**
224 * Returns if this block is collidable (only used by Fire). Args: x, y, z
225 */
226 public boolean isCollidable()
227 {
228 return this.modelBlock.isCollidable();
229 }
230
231 /**
232 * Returns whether this block is collideable based on the arguments passed in Args: blockMetaData, unknownFlag
233 */
234 public boolean canCollideCheck(int par1, boolean par2)
235 {
236 return this.modelBlock.canCollideCheck(par1, par2);
237 }
238
239 /**
240 * Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z
241 */
242 public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4)
243 {
244 return this.modelBlock.canPlaceBlockAt(par1World, par2, par3, par4);
245 }
246
247 /**
248 * Called whenever the block is added into the world. Args: world, x, y, z
249 */
250 public void onBlockAdded(World par1World, int par2, int par3, int par4)
251 {
252 this.onNeighborBlockChange(par1World, par2, par3, par4, 0);
253 this.modelBlock.onBlockAdded(par1World, par2, par3, par4);
254 }
255
256 /**
257 * ejects contained items into the world, and notifies neighbours of an update, as appropriate
258 */
259 public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6)
260 {
261 this.modelBlock.breakBlock(par1World, par2, par3, par4, par5, par6);
262 }
263
264 /**
265 * Called whenever an entity is walking on top of this block. Args: world, x, y, z, entity
266 */
267 public void onEntityWalking(World par1World, int par2, int par3, int par4, Entity par5Entity)
268 {
269 this.modelBlock.onEntityWalking(par1World, par2, par3, par4, par5Entity);
270 }
271
272 /**
273 * Ticks the block if it's been scheduled
274 */
275 public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random)
276 {
277 this.modelBlock.updateTick(par1World, par2, par3, par4, par5Random);
278 }
279
280 /**
281 * Called upon block activation (right click on the block.)
282 */
283 public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9)
284 {
285 return this.modelBlock.onBlockActivated(par1World, par2, par3, par4, par5EntityPlayer, 0, 0.0F, 0.0F, 0.0F);
286 }
287
288 /**
289 * Called upon the block being destroyed by an explosion
290 */
291 public void onBlockDestroyedByExplosion(World par1World, int par2, int par3, int par4)
292 {
293 this.modelBlock.onBlockDestroyedByExplosion(par1World, par2, par3, par4);
294 }
295
296 /**
297 * Called when the block is placed in the world.
298 */
299 public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving)
300 {
301 int var6 = MathHelper.floor_double((double)(par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3;
302 int var7 = par1World.getBlockMetadata(par2, par3, par4) & 4;
303
304 if (var6 == 0)
305 {
306 par1World.setBlockMetadataWithNotify(par2, par3, par4, 2 | var7);
307 }
308
309 if (var6 == 1)
310 {
311 par1World.setBlockMetadataWithNotify(par2, par3, par4, 1 | var7);
312 }
313
314 if (var6 == 2)
315 {
316 par1World.setBlockMetadataWithNotify(par2, par3, par4, 3 | var7);
317 }
318
319 if (var6 == 3)
320 {
321 par1World.setBlockMetadataWithNotify(par2, par3, par4, 0 | var7);
322 }
323 }
324
325 /**
326 * called before onBlockPlacedBy by ItemBlock and ItemReed
327 */
328 public void updateBlockMetadata(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8)
329 {
330 if (par5 == 0 || par5 != 1 && (double)par7 > 0.5D)
331 {
332 int var9 = par1World.getBlockMetadata(par2, par3, par4);
333 par1World.setBlockMetadataWithNotify(par2, par3, par4, var9 | 4);
334 }
335 }
336
337 /**
338 * Ray traces through the blocks collision from start vector to end vector returning a ray trace hit. Args: world,
339 * x, y, z, startVec, endVec
340 */
341 public MovingObjectPosition collisionRayTrace(World par1World, int par2, int par3, int par4, Vec3 par5Vec3, Vec3 par6Vec3)
342 {
343 MovingObjectPosition[] var7 = new MovingObjectPosition[8];
344 int var8 = par1World.getBlockMetadata(par2, par3, par4);
345 int var9 = var8 & 3;
346 boolean var10 = (var8 & 4) == 4;
347 int[] var11 = field_72159_a[var9 + (var10 ? 4 : 0)];
348 this.field_72156_cr = true;
349 int var14;
350 int var15;
351 int var16;
352
353 for (int var12 = 0; var12 < 8; ++var12)
354 {
355 this.field_72160_cs = var12;
356 int[] var13 = var11;
357 var14 = var11.length;
358
359 for (var15 = 0; var15 < var14; ++var15)
360 {
361 var16 = var13[var15];
362
363 if (var16 == var12)
364 {
365 ;
366 }
367 }
368
369 var7[var12] = super.collisionRayTrace(par1World, par2, par3, par4, par5Vec3, par6Vec3);
370 }
371
372 int[] var21 = var11;
373 int var24 = var11.length;
374
375 for (var14 = 0; var14 < var24; ++var14)
376 {
377 var15 = var21[var14];
378 var7[var15] = null;
379 }
380
381 MovingObjectPosition var23 = null;
382 double var22 = 0.0D;
383 MovingObjectPosition[] var25 = var7;
384 var16 = var7.length;
385
386 for (int var17 = 0; var17 < var16; ++var17)
387 {
388 MovingObjectPosition var18 = var25[var17];
389
390 if (var18 != null)
391 {
392 double var19 = var18.hitVec.squareDistanceTo(par6Vec3);
393
394 if (var19 > var22)
395 {
396 var23 = var18;
397 var22 = var19;
398 }
399 }
400 }
401
402 return var23;
403 }
404 }