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 }