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 }