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