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