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.Random; 006 007 public class BlockPortal extends BlockBreakable 008 { 009 public BlockPortal(int par1, int par2) 010 { 011 super(par1, par2, Material.portal, false); 012 this.setTickRandomly(true); 013 } 014 015 /** 016 * Ticks the block if it's been scheduled 017 */ 018 public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) 019 { 020 super.updateTick(par1World, par2, par3, par4, par5Random); 021 022 if (par1World.provider.isSurfaceWorld() && par5Random.nextInt(2000) < par1World.difficultySetting) 023 { 024 int var6; 025 026 for (var6 = par3; !par1World.doesBlockHaveSolidTopSurface(par2, var6, par4) && var6 > 0; --var6) 027 { 028 ; 029 } 030 031 if (var6 > 0 && !par1World.isBlockNormalCube(par2, var6 + 1, par4)) 032 { 033 ItemMonsterPlacer.spawnCreature(par1World, 57, (double)par2 + 0.5D, (double)var6 + 1.1D, (double)par4 + 0.5D); 034 } 035 } 036 } 037 038 /** 039 * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been 040 * cleared to be reused) 041 */ 042 public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) 043 { 044 return null; 045 } 046 047 /** 048 * Updates the blocks bounds based on its current state. Args: world, x, y, z 049 */ 050 public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) 051 { 052 float var5; 053 float var6; 054 055 if (par1IBlockAccess.getBlockId(par2 - 1, par3, par4) != this.blockID && par1IBlockAccess.getBlockId(par2 + 1, par3, par4) != this.blockID) 056 { 057 var5 = 0.125F; 058 var6 = 0.5F; 059 this.setBlockBounds(0.5F - var5, 0.0F, 0.5F - var6, 0.5F + var5, 1.0F, 0.5F + var6); 060 } 061 else 062 { 063 var5 = 0.5F; 064 var6 = 0.125F; 065 this.setBlockBounds(0.5F - var5, 0.0F, 0.5F - var6, 0.5F + var5, 1.0F, 0.5F + var6); 066 } 067 } 068 069 /** 070 * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two 071 * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. 072 */ 073 public boolean isOpaqueCube() 074 { 075 return false; 076 } 077 078 /** 079 * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc) 080 */ 081 public boolean renderAsNormalBlock() 082 { 083 return false; 084 } 085 086 /** 087 * Checks to see if this location is valid to create a portal and will return True if it does. Args: world, x, y, z 088 */ 089 public boolean tryToCreatePortal(World par1World, int par2, int par3, int par4) 090 { 091 byte var5 = 0; 092 byte var6 = 0; 093 094 if (par1World.getBlockId(par2 - 1, par3, par4) == Block.obsidian.blockID || par1World.getBlockId(par2 + 1, par3, par4) == Block.obsidian.blockID) 095 { 096 var5 = 1; 097 } 098 099 if (par1World.getBlockId(par2, par3, par4 - 1) == Block.obsidian.blockID || par1World.getBlockId(par2, par3, par4 + 1) == Block.obsidian.blockID) 100 { 101 var6 = 1; 102 } 103 104 if (var5 == var6) 105 { 106 return false; 107 } 108 else 109 { 110 if (par1World.getBlockId(par2 - var5, par3, par4 - var6) == 0) 111 { 112 par2 -= var5; 113 par4 -= var6; 114 } 115 116 int var7; 117 int var8; 118 119 for (var7 = -1; var7 <= 2; ++var7) 120 { 121 for (var8 = -1; var8 <= 3; ++var8) 122 { 123 boolean var9 = var7 == -1 || var7 == 2 || var8 == -1 || var8 == 3; 124 125 if (var7 != -1 && var7 != 2 || var8 != -1 && var8 != 3) 126 { 127 int var10 = par1World.getBlockId(par2 + var5 * var7, par3 + var8, par4 + var6 * var7); 128 129 if (var9) 130 { 131 if (var10 != Block.obsidian.blockID) 132 { 133 return false; 134 } 135 } 136 else if (var10 != 0 && var10 != Block.fire.blockID) 137 { 138 return false; 139 } 140 } 141 } 142 } 143 144 par1World.editingBlocks = true; 145 146 for (var7 = 0; var7 < 2; ++var7) 147 { 148 for (var8 = 0; var8 < 3; ++var8) 149 { 150 par1World.setBlockWithNotify(par2 + var5 * var7, par3 + var8, par4 + var6 * var7, Block.portal.blockID); 151 } 152 } 153 154 par1World.editingBlocks = false; 155 return true; 156 } 157 } 158 159 /** 160 * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are 161 * their own) Args: x, y, z, neighbor blockID 162 */ 163 public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) 164 { 165 byte var6 = 0; 166 byte var7 = 1; 167 168 if (par1World.getBlockId(par2 - 1, par3, par4) == this.blockID || par1World.getBlockId(par2 + 1, par3, par4) == this.blockID) 169 { 170 var6 = 1; 171 var7 = 0; 172 } 173 174 int var8; 175 176 for (var8 = par3; par1World.getBlockId(par2, var8 - 1, par4) == this.blockID; --var8) 177 { 178 ; 179 } 180 181 if (par1World.getBlockId(par2, var8 - 1, par4) != Block.obsidian.blockID) 182 { 183 par1World.setBlockWithNotify(par2, par3, par4, 0); 184 } 185 else 186 { 187 int var9; 188 189 for (var9 = 1; var9 < 4 && par1World.getBlockId(par2, var8 + var9, par4) == this.blockID; ++var9) 190 { 191 ; 192 } 193 194 if (var9 == 3 && par1World.getBlockId(par2, var8 + var9, par4) == Block.obsidian.blockID) 195 { 196 boolean var10 = par1World.getBlockId(par2 - 1, par3, par4) == this.blockID || par1World.getBlockId(par2 + 1, par3, par4) == this.blockID; 197 boolean var11 = par1World.getBlockId(par2, par3, par4 - 1) == this.blockID || par1World.getBlockId(par2, par3, par4 + 1) == this.blockID; 198 199 if (var10 && var11) 200 { 201 par1World.setBlockWithNotify(par2, par3, par4, 0); 202 } 203 else 204 { 205 if ((par1World.getBlockId(par2 + var6, par3, par4 + var7) != Block.obsidian.blockID || par1World.getBlockId(par2 - var6, par3, par4 - var7) != this.blockID) && (par1World.getBlockId(par2 - var6, par3, par4 - var7) != Block.obsidian.blockID || par1World.getBlockId(par2 + var6, par3, par4 + var7) != this.blockID)) 206 { 207 par1World.setBlockWithNotify(par2, par3, par4, 0); 208 } 209 } 210 } 211 else 212 { 213 par1World.setBlockWithNotify(par2, par3, par4, 0); 214 } 215 } 216 } 217 218 /** 219 * Returns the quantity of items to drop on block destruction. 220 */ 221 public int quantityDropped(Random par1Random) 222 { 223 return 0; 224 } 225 226 /** 227 * Triggered whenever an entity collides with this block (enters into the block). Args: world, x, y, z, entity 228 */ 229 public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity) 230 { 231 if (par5Entity.ridingEntity == null && par5Entity.riddenByEntity == null) 232 { 233 par5Entity.setInPortal(); 234 } 235 } 236 237 @SideOnly(Side.CLIENT) 238 239 /** 240 * Returns true if the given side of this block type should be rendered, if the adjacent block is at the given 241 * coordinates. Args: blockAccess, x, y, z, side 242 */ 243 public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) 244 { 245 if (par1IBlockAccess.getBlockId(par2, par3, par4) == this.blockID) 246 { 247 return false; 248 } 249 else 250 { 251 boolean var6 = par1IBlockAccess.getBlockId(par2 - 1, par3, par4) == this.blockID && par1IBlockAccess.getBlockId(par2 - 2, par3, par4) != this.blockID; 252 boolean var7 = par1IBlockAccess.getBlockId(par2 + 1, par3, par4) == this.blockID && par1IBlockAccess.getBlockId(par2 + 2, par3, par4) != this.blockID; 253 boolean var8 = par1IBlockAccess.getBlockId(par2, par3, par4 - 1) == this.blockID && par1IBlockAccess.getBlockId(par2, par3, par4 - 2) != this.blockID; 254 boolean var9 = par1IBlockAccess.getBlockId(par2, par3, par4 + 1) == this.blockID && par1IBlockAccess.getBlockId(par2, par3, par4 + 2) != this.blockID; 255 boolean var10 = var6 || var7; 256 boolean var11 = var8 || var9; 257 return var10 && par5 == 4 ? true : (var10 && par5 == 5 ? true : (var11 && par5 == 2 ? true : var11 && par5 == 3)); 258 } 259 } 260 261 @SideOnly(Side.CLIENT) 262 263 /** 264 * Returns which pass should this block be rendered on. 0 for solids and 1 for alpha 265 */ 266 public int getRenderBlockPass() 267 { 268 return 1; 269 } 270 271 @SideOnly(Side.CLIENT) 272 273 /** 274 * A randomly called display update to be able to add particles or other items for display 275 */ 276 public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random) 277 { 278 if (par5Random.nextInt(100) == 0) 279 { 280 par1World.playSound((double)par2 + 0.5D, (double)par3 + 0.5D, (double)par4 + 0.5D, "portal.portal", 0.5F, par5Random.nextFloat() * 0.4F + 0.8F); 281 } 282 283 for (int var6 = 0; var6 < 4; ++var6) 284 { 285 double var7 = (double)((float)par2 + par5Random.nextFloat()); 286 double var9 = (double)((float)par3 + par5Random.nextFloat()); 287 double var11 = (double)((float)par4 + par5Random.nextFloat()); 288 double var13 = 0.0D; 289 double var15 = 0.0D; 290 double var17 = 0.0D; 291 int var19 = par5Random.nextInt(2) * 2 - 1; 292 var13 = ((double)par5Random.nextFloat() - 0.5D) * 0.5D; 293 var15 = ((double)par5Random.nextFloat() - 0.5D) * 0.5D; 294 var17 = ((double)par5Random.nextFloat() - 0.5D) * 0.5D; 295 296 if (par1World.getBlockId(par2 - 1, par3, par4) != this.blockID && par1World.getBlockId(par2 + 1, par3, par4) != this.blockID) 297 { 298 var7 = (double)par2 + 0.5D + 0.25D * (double)var19; 299 var13 = (double)(par5Random.nextFloat() * 2.0F * (float)var19); 300 } 301 else 302 { 303 var11 = (double)par4 + 0.5D + 0.25D * (double)var19; 304 var17 = (double)(par5Random.nextFloat() * 2.0F * (float)var19); 305 } 306 307 par1World.spawnParticle("portal", var7, var9, var11, var13, var15, var17); 308 } 309 } 310 311 @SideOnly(Side.CLIENT) 312 313 /** 314 * only called by clickMiddleMouseButton , and passed to inventory.setCurrentItem (along with isCreative) 315 */ 316 public int idPicked(World par1World, int par2, int par3, int par4) 317 { 318 return 0; 319 } 320 }