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)
014        {
015            if (par1World.provider.dimensionId != 1)
016            {
017                if (!this.placeInExistingPortal(par1World, par2Entity))
018                {
019                    this.createPortal(par1World, par2Entity);
020                    this.placeInExistingPortal(par1World, par2Entity);
021                }
022            }
023            else
024            {
025                int var3 = MathHelper.floor_double(par2Entity.posX);
026                int var4 = MathHelper.floor_double(par2Entity.posY) - 1;
027                int var5 = MathHelper.floor_double(par2Entity.posZ);
028                byte var6 = 1;
029                byte var7 = 0;
030    
031                for (int var8 = -2; var8 <= 2; ++var8)
032                {
033                    for (int var9 = -2; var9 <= 2; ++var9)
034                    {
035                        for (int var10 = -1; var10 < 3; ++var10)
036                        {
037                            int var11 = var3 + var9 * var6 + var8 * var7;
038                            int var12 = var4 + var10;
039                            int var13 = var5 + var9 * var7 - var8 * var6;
040                            boolean var14 = var10 < 0;
041                            par1World.setBlockWithNotify(var11, var12, var13, var14 ? Block.obsidian.blockID : 0);
042                        }
043                    }
044                }
045    
046                par2Entity.setLocationAndAngles((double)var3, (double)var4, (double)var5, 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)
055        {
056            short var3 = 128;
057            double var4 = -1.0D;
058            int var6 = 0;
059            int var7 = 0;
060            int var8 = 0;
061            int var9 = MathHelper.floor_double(par2Entity.posX);
062            int var10 = MathHelper.floor_double(par2Entity.posZ);
063            double var18;
064    
065            for (int var11 = var9 - var3; var11 <= var9 + var3; ++var11)
066            {
067                double var12 = (double)var11 + 0.5D - par2Entity.posX;
068    
069                for (int var14 = var10 - var3; var14 <= var10 + var3; ++var14)
070                {
071                    double var15 = (double)var14 + 0.5D - par2Entity.posZ;
072    
073                    for (int var17 = par1World.getActualHeight() - 1; var17 >= 0; --var17)
074                    {
075                        if (par1World.getBlockId(var11, var17, var14) == Block.portal.blockID)
076                        {
077                            while (par1World.getBlockId(var11, var17 - 1, var14) == Block.portal.blockID)
078                            {
079                                --var17;
080                            }
081    
082                            var18 = (double)var17 + 0.5D - par2Entity.posY;
083                            double var20 = var12 * var12 + var18 * var18 + var15 * var15;
084    
085                            if (var4 < 0.0D || var20 < var4)
086                            {
087                                var4 = var20;
088                                var6 = var11;
089                                var7 = var17;
090                                var8 = var14;
091                            }
092                        }
093                    }
094                }
095            }
096    
097            if (var4 >= 0.0D)
098            {
099                double var22 = (double)var6 + 0.5D;
100                double var16 = (double)var7 + 0.5D;
101                var18 = (double)var8 + 0.5D;
102    
103                if (par1World.getBlockId(var6 - 1, var7, var8) == Block.portal.blockID)
104                {
105                    var22 -= 0.5D;
106                }
107    
108                if (par1World.getBlockId(var6 + 1, var7, var8) == Block.portal.blockID)
109                {
110                    var22 += 0.5D;
111                }
112    
113                if (par1World.getBlockId(var6, var7, var8 - 1) == Block.portal.blockID)
114                {
115                    var18 -= 0.5D;
116                }
117    
118                if (par1World.getBlockId(var6, var7, var8 + 1) == Block.portal.blockID)
119                {
120                    var18 += 0.5D;
121                }
122    
123                par2Entity.setLocationAndAngles(var22, var16, var18, par2Entity.rotationYaw, 0.0F);
124                par2Entity.motionX = par2Entity.motionY = par2Entity.motionZ = 0.0D;
125                return true;
126            }
127            else
128            {
129                return false;
130            }
131        }
132    
133        /**
134         * Create a new portal near an entity.
135         */
136        public boolean createPortal(World par1World, Entity par2Entity)
137        {
138            byte var3 = 16;
139            double var4 = -1.0D;
140            int var6 = MathHelper.floor_double(par2Entity.posX);
141            int var7 = MathHelper.floor_double(par2Entity.posY);
142            int var8 = MathHelper.floor_double(par2Entity.posZ);
143            int var9 = var6;
144            int var10 = var7;
145            int var11 = var8;
146            int var12 = 0;
147            int var13 = this.random.nextInt(4);
148            int var14;
149            double var15;
150            int var17;
151            double var18;
152            int var21;
153            int var20;
154            int var23;
155            int var22;
156            int var25;
157            int var24;
158            int var27;
159            int var26;
160            int var28;
161            double var34;
162            double var32;
163    
164            for (var14 = var6 - var3; var14 <= var6 + var3; ++var14)
165            {
166                var15 = (double)var14 + 0.5D - par2Entity.posX;
167    
168                for (var17 = var8 - var3; var17 <= var8 + var3; ++var17)
169                {
170                    var18 = (double)var17 + 0.5D - par2Entity.posZ;
171                    label274:
172    
173                    for (var20 = par1World.getActualHeight() - 1; var20 >= 0; --var20)
174                    {
175                        if (par1World.isAirBlock(var14, var20, var17))
176                        {
177                            while (var20 > 0 && par1World.isAirBlock(var14, var20 - 1, var17))
178                            {
179                                --var20;
180                            }
181    
182                            for (var21 = var13; var21 < var13 + 4; ++var21)
183                            {
184                                var22 = var21 % 2;
185                                var23 = 1 - var22;
186    
187                                if (var21 % 4 >= 2)
188                                {
189                                    var22 = -var22;
190                                    var23 = -var23;
191                                }
192    
193                                for (var24 = 0; var24 < 3; ++var24)
194                                {
195                                    for (var25 = 0; var25 < 4; ++var25)
196                                    {
197                                        for (var26 = -1; var26 < 4; ++var26)
198                                        {
199                                            var27 = var14 + (var25 - 1) * var22 + var24 * var23;
200                                            var28 = var20 + var26;
201                                            int var29 = var17 + (var25 - 1) * var23 - var24 * var22;
202    
203                                            if (var26 < 0 && !par1World.getBlockMaterial(var27, var28, var29).isSolid() || var26 >= 0 && !par1World.isAirBlock(var27, var28, var29))
204                                            {
205                                                continue label274;
206                                            }
207                                        }
208                                    }
209                                }
210    
211                                var32 = (double)var20 + 0.5D - par2Entity.posY;
212                                var34 = var15 * var15 + var32 * var32 + var18 * var18;
213    
214                                if (var4 < 0.0D || var34 < var4)
215                                {
216                                    var4 = var34;
217                                    var9 = var14;
218                                    var10 = var20;
219                                    var11 = var17;
220                                    var12 = var21 % 4;
221                                }
222                            }
223                        }
224                    }
225                }
226            }
227    
228            if (var4 < 0.0D)
229            {
230                for (var14 = var6 - var3; var14 <= var6 + var3; ++var14)
231                {
232                    var15 = (double)var14 + 0.5D - par2Entity.posX;
233    
234                    for (var17 = var8 - var3; var17 <= var8 + var3; ++var17)
235                    {
236                        var18 = (double)var17 + 0.5D - par2Entity.posZ;
237                        label222:
238    
239                        for (var20 = par1World.getActualHeight() - 1; var20 >= 0; --var20)
240                        {
241                            if (par1World.isAirBlock(var14, var20, var17))
242                            {
243                                while (var20 > 0 && par1World.isAirBlock(var14, var20 - 1, var17))
244                                {
245                                    --var20;
246                                }
247    
248                                for (var21 = var13; var21 < var13 + 2; ++var21)
249                                {
250                                    var22 = var21 % 2;
251                                    var23 = 1 - var22;
252    
253                                    for (var24 = 0; var24 < 4; ++var24)
254                                    {
255                                        for (var25 = -1; var25 < 4; ++var25)
256                                        {
257                                            var26 = var14 + (var24 - 1) * var22;
258                                            var27 = var20 + var25;
259                                            var28 = var17 + (var24 - 1) * var23;
260    
261                                            if (var25 < 0 && !par1World.getBlockMaterial(var26, var27, var28).isSolid() || var25 >= 0 && !par1World.isAirBlock(var26, var27, var28))
262                                            {
263                                                continue label222;
264                                            }
265                                        }
266                                    }
267    
268                                    var32 = (double)var20 + 0.5D - par2Entity.posY;
269                                    var34 = var15 * var15 + var32 * var32 + var18 * var18;
270    
271                                    if (var4 < 0.0D || var34 < var4)
272                                    {
273                                        var4 = var34;
274                                        var9 = var14;
275                                        var10 = var20;
276                                        var11 = var17;
277                                        var12 = var21 % 2;
278                                    }
279                                }
280                            }
281                        }
282                    }
283                }
284            }
285    
286            int var30 = var9;
287            int var16 = var10;
288            var17 = var11;
289            int var31 = var12 % 2;
290            int var19 = 1 - var31;
291    
292            if (var12 % 4 >= 2)
293            {
294                var31 = -var31;
295                var19 = -var19;
296            }
297    
298            boolean var33;
299    
300            if (var4 < 0.0D)
301            {
302                if (var10 < 70)
303                {
304                    var10 = 70;
305                }
306    
307                if (var10 > par1World.getActualHeight() - 10)
308                {
309                    var10 = par1World.getActualHeight() - 10;
310                }
311    
312                var16 = var10;
313    
314                for (var20 = -1; var20 <= 1; ++var20)
315                {
316                    for (var21 = 1; var21 < 3; ++var21)
317                    {
318                        for (var22 = -1; var22 < 3; ++var22)
319                        {
320                            var23 = var30 + (var21 - 1) * var31 + var20 * var19;
321                            var24 = var16 + var22;
322                            var25 = var17 + (var21 - 1) * var19 - var20 * var31;
323                            var33 = var22 < 0;
324                            par1World.setBlockWithNotify(var23, var24, var25, var33 ? Block.obsidian.blockID : 0);
325                        }
326                    }
327                }
328            }
329    
330            for (var20 = 0; var20 < 4; ++var20)
331            {
332                par1World.editingBlocks = true;
333    
334                for (var21 = 0; var21 < 4; ++var21)
335                {
336                    for (var22 = -1; var22 < 4; ++var22)
337                    {
338                        var23 = var30 + (var21 - 1) * var31;
339                        var24 = var16 + var22;
340                        var25 = var17 + (var21 - 1) * var19;
341                        var33 = var21 == 0 || var21 == 3 || var22 == -1 || var22 == 3;
342                        par1World.setBlockWithNotify(var23, var24, var25, var33 ? Block.obsidian.blockID : Block.portal.blockID);
343                    }
344                }
345    
346                par1World.editingBlocks = false;
347    
348                for (var21 = 0; var21 < 4; ++var21)
349                {
350                    for (var22 = -1; var22 < 4; ++var22)
351                    {
352                        var23 = var30 + (var21 - 1) * var31;
353                        var24 = var16 + var22;
354                        var25 = var17 + (var21 - 1) * var19;
355                        par1World.notifyBlocksOfNeighborChange(var23, var24, var25, par1World.getBlockId(var23, var24, var25));
356                    }
357                }
358            }
359    
360            return true;
361        }
362    }