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