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