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 }