package net.minecraft.world; import com.google.common.collect.Lists; import java.util.Iterator; import java.util.List; import java.util.Random; import net.minecraft.block.BlockPortal; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; import net.minecraft.init.Blocks; import net.minecraft.util.BlockPos; import net.minecraft.util.EnumFacing; import net.minecraft.util.LongHashMap; import net.minecraft.util.MathHelper; public class Teleporter { private final WorldServer worldServerInstance; /** A private Random() function in Teleporter */ private final Random random; /** Stores successful portal placement locations for rapid lookup. */ private final LongHashMap destinationCoordinateCache = new LongHashMap(); /** * A list of valid keys for the destinationCoordainteCache. These are based on the X & Z of the players initial * location. */ private final List destinationCoordinateKeys = Lists.newArrayList(); private static final String __OBFID = "CL_00000153"; public Teleporter(WorldServer worldIn) { this.worldServerInstance = worldIn; this.random = new Random(worldIn.getSeed()); } public void func_180266_a(Entity p_180266_1_, float p_180266_2_) { if (this.worldServerInstance.provider.getDimensionId() != 1) { if (!this.func_180620_b(p_180266_1_, p_180266_2_)) { this.makePortal(p_180266_1_); this.func_180620_b(p_180266_1_, p_180266_2_); } } else { int var3 = MathHelper.floor_double(p_180266_1_.posX); int var4 = MathHelper.floor_double(p_180266_1_.posY) - 1; int var5 = MathHelper.floor_double(p_180266_1_.posZ); byte var6 = 1; byte var7 = 0; for (int var8 = -2; var8 <= 2; ++var8) { for (int var9 = -2; var9 <= 2; ++var9) { for (int var10 = -1; var10 < 3; ++var10) { int var11 = var3 + var9 * var6 + var8 * var7; int var12 = var4 + var10; int var13 = var5 + var9 * var7 - var8 * var6; boolean var14 = var10 < 0; this.worldServerInstance.setBlockState(new BlockPos(var11, var12, var13), var14 ? Blocks.obsidian.getDefaultState() : Blocks.air.getDefaultState()); } } } p_180266_1_.setLocationAndAngles((double)var3, (double)var4, (double)var5, p_180266_1_.rotationYaw, 0.0F); p_180266_1_.motionX = p_180266_1_.motionY = p_180266_1_.motionZ = 0.0D; } } public boolean func_180620_b(Entity p_180620_1_, float p_180620_2_) { boolean var3 = true; double var4 = -1.0D; int var6 = MathHelper.floor_double(p_180620_1_.posX); int var7 = MathHelper.floor_double(p_180620_1_.posZ); boolean var8 = true; Object var9 = BlockPos.ORIGIN; long var10 = ChunkCoordIntPair.chunkXZ2Int(var6, var7); if (this.destinationCoordinateCache.containsItem(var10)) { Teleporter.PortalPosition var12 = (Teleporter.PortalPosition)this.destinationCoordinateCache.getValueByKey(var10); var4 = 0.0D; var9 = var12; var12.lastUpdateTime = this.worldServerInstance.getTotalWorldTime(); var8 = false; } else { BlockPos var34 = new BlockPos(p_180620_1_); for (int var13 = -128; var13 <= 128; ++var13) { BlockPos var16; for (int var14 = -128; var14 <= 128; ++var14) { for (BlockPos var15 = var34.add(var13, this.worldServerInstance.getActualHeight() - 1 - var34.getY(), var14); var15.getY() >= 0; var15 = var16) { var16 = var15.offsetDown(); if (this.worldServerInstance.getBlockState(var15).getBlock() == Blocks.portal) { while (this.worldServerInstance.getBlockState(var16 = var15.offsetDown()).getBlock() == Blocks.portal) { var15 = var16; } double var17 = var15.distanceSq(var34); if (var4 < 0.0D || var17 < var4) { var4 = var17; var9 = var15; } } } } } } if (var4 >= 0.0D) { if (var8) { this.destinationCoordinateCache.add(var10, new Teleporter.PortalPosition((BlockPos)var9, this.worldServerInstance.getTotalWorldTime())); this.destinationCoordinateKeys.add(Long.valueOf(var10)); } double var35 = (double)((BlockPos)var9).getX() + 0.5D; double var36 = (double)((BlockPos)var9).getY() + 0.5D; double var37 = (double)((BlockPos)var9).getZ() + 0.5D; EnumFacing var18 = null; if (this.worldServerInstance.getBlockState(((BlockPos)var9).offsetWest()).getBlock() == Blocks.portal) { var18 = EnumFacing.NORTH; } if (this.worldServerInstance.getBlockState(((BlockPos)var9).offsetEast()).getBlock() == Blocks.portal) { var18 = EnumFacing.SOUTH; } if (this.worldServerInstance.getBlockState(((BlockPos)var9).offsetNorth()).getBlock() == Blocks.portal) { var18 = EnumFacing.EAST; } if (this.worldServerInstance.getBlockState(((BlockPos)var9).offsetSouth()).getBlock() == Blocks.portal) { var18 = EnumFacing.WEST; } EnumFacing var19 = EnumFacing.getHorizontal(p_180620_1_.getTeleportDirection()); if (var18 != null) { EnumFacing var20 = var18.rotateYCCW(); BlockPos var21 = ((BlockPos)var9).offset(var18); boolean var22 = this.func_180265_a(var21); boolean var23 = this.func_180265_a(var21.offset(var20)); if (var23 && var22) { var9 = ((BlockPos)var9).offset(var20); var18 = var18.getOpposite(); var20 = var20.getOpposite(); BlockPos var24 = ((BlockPos)var9).offset(var18); var22 = this.func_180265_a(var24); var23 = this.func_180265_a(var24.offset(var20)); } float var38 = 0.5F; float var25 = 0.5F; if (!var23 && var22) { var38 = 1.0F; } else if (var23 && !var22) { var38 = 0.0F; } else if (var23) { var25 = 0.0F; } var35 = (double)((BlockPos)var9).getX() + 0.5D; var36 = (double)((BlockPos)var9).getY() + 0.5D; var37 = (double)((BlockPos)var9).getZ() + 0.5D; var35 += (double)((float)var20.getFrontOffsetX() * var38 + (float)var18.getFrontOffsetX() * var25); var37 += (double)((float)var20.getFrontOffsetZ() * var38 + (float)var18.getFrontOffsetZ() * var25); float var26 = 0.0F; float var27 = 0.0F; float var28 = 0.0F; float var29 = 0.0F; if (var18 == var19) { var26 = 1.0F; var27 = 1.0F; } else if (var18 == var19.getOpposite()) { var26 = -1.0F; var27 = -1.0F; } else if (var18 == var19.rotateY()) { var28 = 1.0F; var29 = -1.0F; } else { var28 = -1.0F; var29 = 1.0F; } double var30 = p_180620_1_.motionX; double var32 = p_180620_1_.motionZ; p_180620_1_.motionX = var30 * (double)var26 + var32 * (double)var29; p_180620_1_.motionZ = var30 * (double)var28 + var32 * (double)var27; p_180620_1_.rotationYaw = p_180620_2_ - (float)(var19.getHorizontalIndex() * 90) + (float)(var18.getHorizontalIndex() * 90); } else { p_180620_1_.motionX = p_180620_1_.motionY = p_180620_1_.motionZ = 0.0D; } p_180620_1_.setLocationAndAngles(var35, var36, var37, p_180620_1_.rotationYaw, p_180620_1_.rotationPitch); return true; } else { return false; } } private boolean func_180265_a(BlockPos p_180265_1_) { return !this.worldServerInstance.isAirBlock(p_180265_1_) || !this.worldServerInstance.isAirBlock(p_180265_1_.offsetUp()); } public boolean makePortal(Entity p_85188_1_) { byte var2 = 16; double var3 = -1.0D; int var5 = MathHelper.floor_double(p_85188_1_.posX); int var6 = MathHelper.floor_double(p_85188_1_.posY); int var7 = MathHelper.floor_double(p_85188_1_.posZ); int var8 = var5; int var9 = var6; int var10 = var7; int var11 = 0; int var12 = this.random.nextInt(4); int var13; double var14; int var16; double var17; int var19; int var20; int var21; int var22; int var23; int var24; int var25; int var26; int var27; double var32; double var33; for (var13 = var5 - var2; var13 <= var5 + var2; ++var13) { var14 = (double)var13 + 0.5D - p_85188_1_.posX; for (var16 = var7 - var2; var16 <= var7 + var2; ++var16) { var17 = (double)var16 + 0.5D - p_85188_1_.posZ; label271: for (var19 = this.worldServerInstance.getActualHeight() - 1; var19 >= 0; --var19) { if (this.worldServerInstance.isAirBlock(new BlockPos(var13, var19, var16))) { while (var19 > 0 && this.worldServerInstance.isAirBlock(new BlockPos(var13, var19 - 1, var16))) { --var19; } for (var20 = var12; var20 < var12 + 4; ++var20) { var21 = var20 % 2; var22 = 1 - var21; if (var20 % 4 >= 2) { var21 = -var21; var22 = -var22; } for (var23 = 0; var23 < 3; ++var23) { for (var24 = 0; var24 < 4; ++var24) { for (var25 = -1; var25 < 4; ++var25) { var26 = var13 + (var24 - 1) * var21 + var23 * var22; var27 = var19 + var25; int var28 = var16 + (var24 - 1) * var22 - var23 * var21; if (var25 < 0 && !this.worldServerInstance.getBlockState(new BlockPos(var26, var27, var28)).getBlock().getMaterial().isSolid() || var25 >= 0 && !this.worldServerInstance.isAirBlock(new BlockPos(var26, var27, var28))) { continue label271; } } } } var32 = (double)var19 + 0.5D - p_85188_1_.posY; var33 = var14 * var14 + var32 * var32 + var17 * var17; if (var3 < 0.0D || var33 < var3) { var3 = var33; var8 = var13; var9 = var19; var10 = var16; var11 = var20 % 4; } } } } } } if (var3 < 0.0D) { for (var13 = var5 - var2; var13 <= var5 + var2; ++var13) { var14 = (double)var13 + 0.5D - p_85188_1_.posX; for (var16 = var7 - var2; var16 <= var7 + var2; ++var16) { var17 = (double)var16 + 0.5D - p_85188_1_.posZ; label219: for (var19 = this.worldServerInstance.getActualHeight() - 1; var19 >= 0; --var19) { if (this.worldServerInstance.isAirBlock(new BlockPos(var13, var19, var16))) { while (var19 > 0 && this.worldServerInstance.isAirBlock(new BlockPos(var13, var19 - 1, var16))) { --var19; } for (var20 = var12; var20 < var12 + 2; ++var20) { var21 = var20 % 2; var22 = 1 - var21; for (var23 = 0; var23 < 4; ++var23) { for (var24 = -1; var24 < 4; ++var24) { var25 = var13 + (var23 - 1) * var21; var26 = var19 + var24; var27 = var16 + (var23 - 1) * var22; if (var24 < 0 && !this.worldServerInstance.getBlockState(new BlockPos(var25, var26, var27)).getBlock().getMaterial().isSolid() || var24 >= 0 && !this.worldServerInstance.isAirBlock(new BlockPos(var25, var26, var27))) { continue label219; } } } var32 = (double)var19 + 0.5D - p_85188_1_.posY; var33 = var14 * var14 + var32 * var32 + var17 * var17; if (var3 < 0.0D || var33 < var3) { var3 = var33; var8 = var13; var9 = var19; var10 = var16; var11 = var20 % 2; } } } } } } } int var29 = var8; int var15 = var9; var16 = var10; int var30 = var11 % 2; int var18 = 1 - var30; if (var11 % 4 >= 2) { var30 = -var30; var18 = -var18; } if (var3 < 0.0D) { var9 = MathHelper.clamp_int(var9, 70, this.worldServerInstance.getActualHeight() - 10); var15 = var9; for (var19 = -1; var19 <= 1; ++var19) { for (var20 = 1; var20 < 3; ++var20) { for (var21 = -1; var21 < 3; ++var21) { var22 = var29 + (var20 - 1) * var30 + var19 * var18; var23 = var15 + var21; var24 = var16 + (var20 - 1) * var18 - var19 * var30; boolean var34 = var21 < 0; this.worldServerInstance.setBlockState(new BlockPos(var22, var23, var24), var34 ? Blocks.obsidian.getDefaultState() : Blocks.air.getDefaultState()); } } } } IBlockState var31 = Blocks.portal.getDefaultState().withProperty(BlockPortal.field_176550_a, var30 != 0 ? EnumFacing.Axis.X : EnumFacing.Axis.Z); for (var20 = 0; var20 < 4; ++var20) { for (var21 = 0; var21 < 4; ++var21) { for (var22 = -1; var22 < 4; ++var22) { var23 = var29 + (var21 - 1) * var30; var24 = var15 + var22; var25 = var16 + (var21 - 1) * var18; boolean var35 = var21 == 0 || var21 == 3 || var22 == -1 || var22 == 3; this.worldServerInstance.setBlockState(new BlockPos(var23, var24, var25), var35 ? Blocks.obsidian.getDefaultState() : var31, 2); } } for (var21 = 0; var21 < 4; ++var21) { for (var22 = -1; var22 < 4; ++var22) { var23 = var29 + (var21 - 1) * var30; var24 = var15 + var22; var25 = var16 + (var21 - 1) * var18; this.worldServerInstance.notifyNeighborsOfStateChange(new BlockPos(var23, var24, var25), this.worldServerInstance.getBlockState(new BlockPos(var23, var24, var25)).getBlock()); } } } return true; } /** * called periodically to remove out-of-date portal locations from the cache list. Argument par1 is a * WorldServer.getTotalWorldTime() value. */ public void removeStalePortalLocations(long p_85189_1_) { if (p_85189_1_ % 100L == 0L) { Iterator var3 = this.destinationCoordinateKeys.iterator(); long var4 = p_85189_1_ - 600L; while (var3.hasNext()) { Long var6 = (Long)var3.next(); Teleporter.PortalPosition var7 = (Teleporter.PortalPosition)this.destinationCoordinateCache.getValueByKey(var6.longValue()); if (var7 == null || var7.lastUpdateTime < var4) { var3.remove(); this.destinationCoordinateCache.remove(var6.longValue()); } } } } public class PortalPosition extends BlockPos { public long lastUpdateTime; private static final String __OBFID = "CL_00000154"; public PortalPosition(BlockPos p_i45747_2_, long p_i45747_3_) { super(p_i45747_2_.getX(), p_i45747_2_.getY(), p_i45747_2_.getZ()); this.lastUpdateTime = p_i45747_3_; } } }