001 package net.minecraft.src; 002 003 import java.util.ArrayList; 004 import java.util.Iterator; 005 import java.util.List; 006 import java.util.Random; 007 008 public class Teleporter 009 { 010 private final WorldServer field_85192_a; 011 012 /** A private Random() function in Teleporter */ 013 private final Random random; 014 private final LongHashMap field_85191_c = new LongHashMap(); 015 private final List field_85190_d = new ArrayList(); 016 017 public Teleporter(WorldServer par1WorldServer) 018 { 019 this.field_85192_a = par1WorldServer; 020 this.random = new Random(par1WorldServer.getSeed()); 021 } 022 023 /** 024 * Place an entity in a nearby portal, creating one if necessary. 025 */ 026 public void placeInPortal(Entity par1Entity, double par2, double par4, double par6, float par8) 027 { 028 if (this.field_85192_a.provider.dimensionId != 1) 029 { 030 if (!this.placeInExistingPortal(par1Entity, par2, par4, par6, par8)) 031 { 032 this.func_85188_a(par1Entity); 033 this.placeInExistingPortal(par1Entity, par2, par4, par6, par8); 034 } 035 } 036 else 037 { 038 int var9 = MathHelper.floor_double(par1Entity.posX); 039 int var10 = MathHelper.floor_double(par1Entity.posY) - 1; 040 int var11 = MathHelper.floor_double(par1Entity.posZ); 041 byte var12 = 1; 042 byte var13 = 0; 043 044 for (int var14 = -2; var14 <= 2; ++var14) 045 { 046 for (int var15 = -2; var15 <= 2; ++var15) 047 { 048 for (int var16 = -1; var16 < 3; ++var16) 049 { 050 int var17 = var9 + var15 * var12 + var14 * var13; 051 int var18 = var10 + var16; 052 int var19 = var11 + var15 * var13 - var14 * var12; 053 boolean var20 = var16 < 0; 054 this.field_85192_a.setBlockWithNotify(var17, var18, var19, var20 ? Block.obsidian.blockID : 0); 055 } 056 } 057 } 058 059 par1Entity.setLocationAndAngles((double)var9, (double)var10, (double)var11, par1Entity.rotationYaw, 0.0F); 060 par1Entity.motionX = par1Entity.motionY = par1Entity.motionZ = 0.0D; 061 } 062 } 063 064 /** 065 * Place an entity in a nearby portal which already exists. 066 */ 067 public boolean placeInExistingPortal(Entity par1Entity, double par2, double par4, double par6, float par8) 068 { 069 short var9 = 128; 070 double var10 = -1.0D; 071 int var12 = 0; 072 int var13 = 0; 073 int var14 = 0; 074 int var15 = MathHelper.floor_double(par1Entity.posX); 075 int var16 = MathHelper.floor_double(par1Entity.posZ); 076 long var17 = ChunkCoordIntPair.chunkXZ2Int(var15, var16); 077 boolean var19 = true; 078 double var27; 079 int var48; 080 081 if (this.field_85191_c.containsItem(var17)) 082 { 083 PortalPosition var20 = (PortalPosition)this.field_85191_c.getValueByKey(var17); 084 var10 = 0.0D; 085 var12 = var20.posX; 086 var13 = var20.posY; 087 var14 = var20.posZ; 088 var20.field_85087_d = this.field_85192_a.getTotalWorldTime(); 089 var19 = false; 090 } 091 else 092 { 093 for (var48 = var15 - var9; var48 <= var15 + var9; ++var48) 094 { 095 double var21 = (double)var48 + 0.5D - par1Entity.posX; 096 097 for (int var23 = var16 - var9; var23 <= var16 + var9; ++var23) 098 { 099 double var24 = (double)var23 + 0.5D - par1Entity.posZ; 100 101 for (int var26 = this.field_85192_a.getActualHeight() - 1; var26 >= 0; --var26) 102 { 103 if (this.field_85192_a.getBlockId(var48, var26, var23) == Block.portal.blockID) 104 { 105 while (this.field_85192_a.getBlockId(var48, var26 - 1, var23) == Block.portal.blockID) 106 { 107 --var26; 108 } 109 110 var27 = (double)var26 + 0.5D - par1Entity.posY; 111 double var29 = var21 * var21 + var27 * var27 + var24 * var24; 112 113 if (var10 < 0.0D || var29 < var10) 114 { 115 var10 = var29; 116 var12 = var48; 117 var13 = var26; 118 var14 = var23; 119 } 120 } 121 } 122 } 123 } 124 } 125 126 if (var10 >= 0.0D) 127 { 128 if (var19) 129 { 130 this.field_85191_c.add(var17, new PortalPosition(this, var12, var13, var14, this.field_85192_a.getTotalWorldTime())); 131 this.field_85190_d.add(Long.valueOf(var17)); 132 } 133 134 double var49 = (double)var12 + 0.5D; 135 double var25 = (double)var13 + 0.5D; 136 var27 = (double)var14 + 0.5D; 137 int var50 = -1; 138 139 if (this.field_85192_a.getBlockId(var12 - 1, var13, var14) == Block.portal.blockID) 140 { 141 var50 = 2; 142 } 143 144 if (this.field_85192_a.getBlockId(var12 + 1, var13, var14) == Block.portal.blockID) 145 { 146 var50 = 0; 147 } 148 149 if (this.field_85192_a.getBlockId(var12, var13, var14 - 1) == Block.portal.blockID) 150 { 151 var50 = 3; 152 } 153 154 if (this.field_85192_a.getBlockId(var12, var13, var14 + 1) == Block.portal.blockID) 155 { 156 var50 = 1; 157 } 158 159 int var30 = par1Entity.func_82148_at(); 160 161 if (var50 > -1) 162 { 163 int var31 = Direction.field_71578_g[var50]; 164 int var32 = Direction.offsetX[var50]; 165 int var33 = Direction.offsetZ[var50]; 166 int var34 = Direction.offsetX[var31]; 167 int var35 = Direction.offsetZ[var31]; 168 boolean var36 = !this.field_85192_a.isAirBlock(var12 + var32 + var34, var13, var14 + var33 + var35) || !this.field_85192_a.isAirBlock(var12 + var32 + var34, var13 + 1, var14 + var33 + var35); 169 boolean var37 = !this.field_85192_a.isAirBlock(var12 + var32, var13, var14 + var33) || !this.field_85192_a.isAirBlock(var12 + var32, var13 + 1, var14 + var33); 170 171 if (var36 && var37) 172 { 173 var50 = Direction.footInvisibleFaceRemap[var50]; 174 var31 = Direction.footInvisibleFaceRemap[var31]; 175 var32 = Direction.offsetX[var50]; 176 var33 = Direction.offsetZ[var50]; 177 var34 = Direction.offsetX[var31]; 178 var35 = Direction.offsetZ[var31]; 179 var48 = var12 - var34; 180 var49 -= (double)var34; 181 int var22 = var14 - var35; 182 var27 -= (double)var35; 183 var36 = !this.field_85192_a.isAirBlock(var48 + var32 + var34, var13, var22 + var33 + var35) || !this.field_85192_a.isAirBlock(var48 + var32 + var34, var13 + 1, var22 + var33 + var35); 184 var37 = !this.field_85192_a.isAirBlock(var48 + var32, var13, var22 + var33) || !this.field_85192_a.isAirBlock(var48 + var32, var13 + 1, var22 + var33); 185 } 186 187 float var38 = 0.5F; 188 float var39 = 0.5F; 189 190 if (!var36 && var37) 191 { 192 var38 = 1.0F; 193 } 194 else if (var36 && !var37) 195 { 196 var38 = 0.0F; 197 } 198 else if (var36 && var37) 199 { 200 var39 = 0.0F; 201 } 202 203 var49 += (double)((float)var34 * var38 + var39 * (float)var32); 204 var27 += (double)((float)var35 * var38 + var39 * (float)var33); 205 float var40 = 0.0F; 206 float var41 = 0.0F; 207 float var42 = 0.0F; 208 float var43 = 0.0F; 209 210 if (var50 == var30) 211 { 212 var40 = 1.0F; 213 var41 = 1.0F; 214 } 215 else if (var50 == Direction.footInvisibleFaceRemap[var30]) 216 { 217 var40 = -1.0F; 218 var41 = -1.0F; 219 } 220 else if (var50 == Direction.enderEyeMetaToDirection[var30]) 221 { 222 var42 = 1.0F; 223 var43 = -1.0F; 224 } 225 else 226 { 227 var42 = -1.0F; 228 var43 = 1.0F; 229 } 230 231 double var44 = par1Entity.motionX; 232 double var46 = par1Entity.motionZ; 233 par1Entity.motionX = var44 * (double)var40 + var46 * (double)var43; 234 par1Entity.motionZ = var44 * (double)var42 + var46 * (double)var41; 235 par1Entity.rotationYaw = par8 - (float)(var30 * 90) + (float)(var50 * 90); 236 } 237 else 238 { 239 par1Entity.motionX = par1Entity.motionY = par1Entity.motionZ = 0.0D; 240 } 241 242 par1Entity.setLocationAndAngles(var49, var25, var27, par1Entity.rotationYaw, par1Entity.rotationPitch); 243 return true; 244 } 245 else 246 { 247 return false; 248 } 249 } 250 251 public boolean func_85188_a(Entity par1Entity) 252 { 253 byte var2 = 16; 254 double var3 = -1.0D; 255 int var5 = MathHelper.floor_double(par1Entity.posX); 256 int var6 = MathHelper.floor_double(par1Entity.posY); 257 int var7 = MathHelper.floor_double(par1Entity.posZ); 258 int var8 = var5; 259 int var9 = var6; 260 int var10 = var7; 261 int var11 = 0; 262 int var12 = this.random.nextInt(4); 263 int var13; 264 double var14; 265 double var17; 266 int var16; 267 int var19; 268 int var21; 269 int var20; 270 int var23; 271 int var22; 272 int var25; 273 int var24; 274 int var27; 275 int var26; 276 double var31; 277 double var32; 278 279 for (var13 = var5 - var2; var13 <= var5 + var2; ++var13) 280 { 281 var14 = (double)var13 + 0.5D - par1Entity.posX; 282 283 for (var16 = var7 - var2; var16 <= var7 + var2; ++var16) 284 { 285 var17 = (double)var16 + 0.5D - par1Entity.posZ; 286 label274: 287 288 for (var19 = this.field_85192_a.getActualHeight() - 1; var19 >= 0; --var19) 289 { 290 if (this.field_85192_a.isAirBlock(var13, var19, var16)) 291 { 292 while (var19 > 0 && this.field_85192_a.isAirBlock(var13, var19 - 1, var16)) 293 { 294 --var19; 295 } 296 297 for (var20 = var12; var20 < var12 + 4; ++var20) 298 { 299 var21 = var20 % 2; 300 var22 = 1 - var21; 301 302 if (var20 % 4 >= 2) 303 { 304 var21 = -var21; 305 var22 = -var22; 306 } 307 308 for (var23 = 0; var23 < 3; ++var23) 309 { 310 for (var24 = 0; var24 < 4; ++var24) 311 { 312 for (var25 = -1; var25 < 4; ++var25) 313 { 314 var26 = var13 + (var24 - 1) * var21 + var23 * var22; 315 var27 = var19 + var25; 316 int var28 = var16 + (var24 - 1) * var22 - var23 * var21; 317 318 if (var25 < 0 && !this.field_85192_a.getBlockMaterial(var26, var27, var28).isSolid() || var25 >= 0 && !this.field_85192_a.isAirBlock(var26, var27, var28)) 319 { 320 continue label274; 321 } 322 } 323 } 324 } 325 326 var32 = (double)var19 + 0.5D - par1Entity.posY; 327 var31 = var14 * var14 + var32 * var32 + var17 * var17; 328 329 if (var3 < 0.0D || var31 < var3) 330 { 331 var3 = var31; 332 var8 = var13; 333 var9 = var19; 334 var10 = var16; 335 var11 = var20 % 4; 336 } 337 } 338 } 339 } 340 } 341 } 342 343 if (var3 < 0.0D) 344 { 345 for (var13 = var5 - var2; var13 <= var5 + var2; ++var13) 346 { 347 var14 = (double)var13 + 0.5D - par1Entity.posX; 348 349 for (var16 = var7 - var2; var16 <= var7 + var2; ++var16) 350 { 351 var17 = (double)var16 + 0.5D - par1Entity.posZ; 352 label222: 353 354 for (var19 = this.field_85192_a.getActualHeight() - 1; var19 >= 0; --var19) 355 { 356 if (this.field_85192_a.isAirBlock(var13, var19, var16)) 357 { 358 while (var19 > 0 && this.field_85192_a.isAirBlock(var13, var19 - 1, var16)) 359 { 360 --var19; 361 } 362 363 for (var20 = var12; var20 < var12 + 2; ++var20) 364 { 365 var21 = var20 % 2; 366 var22 = 1 - var21; 367 368 for (var23 = 0; var23 < 4; ++var23) 369 { 370 for (var24 = -1; var24 < 4; ++var24) 371 { 372 var25 = var13 + (var23 - 1) * var21; 373 var26 = var19 + var24; 374 var27 = var16 + (var23 - 1) * var22; 375 376 if (var24 < 0 && !this.field_85192_a.getBlockMaterial(var25, var26, var27).isSolid() || var24 >= 0 && !this.field_85192_a.isAirBlock(var25, var26, var27)) 377 { 378 continue label222; 379 } 380 } 381 } 382 383 var32 = (double)var19 + 0.5D - par1Entity.posY; 384 var31 = var14 * var14 + var32 * var32 + var17 * var17; 385 386 if (var3 < 0.0D || var31 < var3) 387 { 388 var3 = var31; 389 var8 = var13; 390 var9 = var19; 391 var10 = var16; 392 var11 = var20 % 2; 393 } 394 } 395 } 396 } 397 } 398 } 399 } 400 401 int var29 = var8; 402 int var15 = var9; 403 var16 = var10; 404 int var30 = var11 % 2; 405 int var18 = 1 - var30; 406 407 if (var11 % 4 >= 2) 408 { 409 var30 = -var30; 410 var18 = -var18; 411 } 412 413 boolean var33; 414 415 if (var3 < 0.0D) 416 { 417 if (var9 < 70) 418 { 419 var9 = 70; 420 } 421 422 if (var9 > this.field_85192_a.getActualHeight() - 10) 423 { 424 var9 = this.field_85192_a.getActualHeight() - 10; 425 } 426 427 var15 = var9; 428 429 for (var19 = -1; var19 <= 1; ++var19) 430 { 431 for (var20 = 1; var20 < 3; ++var20) 432 { 433 for (var21 = -1; var21 < 3; ++var21) 434 { 435 var22 = var29 + (var20 - 1) * var30 + var19 * var18; 436 var23 = var15 + var21; 437 var24 = var16 + (var20 - 1) * var18 - var19 * var30; 438 var33 = var21 < 0; 439 this.field_85192_a.setBlockWithNotify(var22, var23, var24, var33 ? Block.obsidian.blockID : 0); 440 } 441 } 442 } 443 } 444 445 for (var19 = 0; var19 < 4; ++var19) 446 { 447 this.field_85192_a.editingBlocks = true; 448 449 for (var20 = 0; var20 < 4; ++var20) 450 { 451 for (var21 = -1; var21 < 4; ++var21) 452 { 453 var22 = var29 + (var20 - 1) * var30; 454 var23 = var15 + var21; 455 var24 = var16 + (var20 - 1) * var18; 456 var33 = var20 == 0 || var20 == 3 || var21 == -1 || var21 == 3; 457 this.field_85192_a.setBlockWithNotify(var22, var23, var24, var33 ? Block.obsidian.blockID : Block.portal.blockID); 458 } 459 } 460 461 this.field_85192_a.editingBlocks = false; 462 463 for (var20 = 0; var20 < 4; ++var20) 464 { 465 for (var21 = -1; var21 < 4; ++var21) 466 { 467 var22 = var29 + (var20 - 1) * var30; 468 var23 = var15 + var21; 469 var24 = var16 + (var20 - 1) * var18; 470 this.field_85192_a.notifyBlocksOfNeighborChange(var22, var23, var24, this.field_85192_a.getBlockId(var22, var23, var24)); 471 } 472 } 473 } 474 475 return true; 476 } 477 478 public void func_85189_a(long par1) 479 { 480 if (par1 % 100L == 0L) 481 { 482 Iterator var3 = this.field_85190_d.iterator(); 483 long var4 = par1 - 600L; 484 485 while (var3.hasNext()) 486 { 487 Long var6 = (Long)var3.next(); 488 PortalPosition var7 = (PortalPosition)this.field_85191_c.getValueByKey(var6.longValue()); 489 490 if (var7 == null || var7.field_85087_d < var4) 491 { 492 var3.remove(); 493 this.field_85191_c.remove(var6.longValue()); 494 } 495 } 496 } 497 } 498 }