Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
at develop 377 lines 13 kB view raw
1package org.bukkit.craftbukkit; 2 3import net.minecraft.server.Block; 4import net.minecraft.server.WorldServer; 5import org.bukkit.Bukkit; 6import org.bukkit.Location; 7import org.bukkit.TravelAgent; 8import org.bukkit.event.world.PortalCreateEvent; 9 10import java.util.Random; 11 12public class PortalTravelAgent implements TravelAgent { 13 14 private Random random = new Random(); 15 16 private int searchRadius = 128; 17 private int creationRadius = 14; // 16 -> 14 18 private boolean canCreatePortal = true; 19 20 public PortalTravelAgent() { 21 } 22 23 public Location findOrCreate(Location location) { 24 WorldServer worldServer = ((CraftWorld) location.getWorld()).getHandle(); 25 worldServer.chunkProviderServer.forceChunkLoad = true; 26 // Attempt to find a Portal. 27 Location resultLocation = this.findPortal(location); 28 // If a Portal cannot be found we will attempt to create one. 29 if (resultLocation == null) { 30 // Attempt to create a portal, return if it was successful or not. 31 if (this.canCreatePortal && this.createPortal(location)) { 32 // Now find that portals location. 33 resultLocation = this.findPortal(location); 34 } else { 35 // Fallback onto the original location. 36 resultLocation = location; 37 } 38 } 39 worldServer.chunkProviderServer.forceChunkLoad = false; 40 // Return our resulting portal location. 41 return resultLocation; 42 } 43 44 public Location findPortal(Location location) { 45 net.minecraft.server.World world = ((CraftWorld) location.getWorld()).getHandle(); 46 // short short1 = 128; 47 double d0 = -1.0D; 48 int i = 0; 49 int j = 0; 50 int k = 0; 51 int l = location.getBlockX(); 52 int i1 = location.getBlockZ(); 53 54 double d1; 55 56 for (int j1 = l - this.searchRadius; j1 <= l + this.searchRadius; ++j1) { 57 double d2 = (double) j1 + 0.5D - location.getX(); 58 59 for (int k1 = i1 - this.searchRadius; k1 <= i1 + this.searchRadius; ++k1) { 60 double d3 = (double) k1 + 0.5D - location.getZ(); 61 62 for (int l1 = 127; l1 >= 0; --l1) { 63 if (world.getTypeId(j1, l1, k1) == Block.PORTAL.id) { 64 while (world.getTypeId(j1, l1 - 1, k1) == Block.PORTAL.id) { 65 --l1; 66 } 67 68 d1 = (double) l1 + 0.5D - location.getY(); 69 double d4 = d2 * d2 + d1 * d1 + d3 * d3; 70 71 if (d0 < 0.0D || d4 < d0) { 72 d0 = d4; 73 i = j1; 74 j = l1; 75 k = k1; 76 } 77 } 78 } 79 } 80 } 81 82 if (d0 >= 0.0D) { 83 double d5 = (double) i + 0.5D; 84 double d6 = (double) j + 0.5D; 85 86 d1 = (double) k + 0.5D; 87 if (world.getTypeId(i - 1, j, k) == Block.PORTAL.id) { 88 d5 -= 0.5D; 89 } 90 91 if (world.getTypeId(i + 1, j, k) == Block.PORTAL.id) { 92 d5 += 0.5D; 93 } 94 95 if (world.getTypeId(i, j, k - 1) == Block.PORTAL.id) { 96 d1 -= 0.5D; 97 } 98 99 if (world.getTypeId(i, j, k + 1) == Block.PORTAL.id) { 100 d1 += 0.5D; 101 } 102 103 return new Location(location.getWorld(), d5, d6, d1, location.getYaw(), location.getPitch()); 104 } else { 105 return null; 106 } 107 } 108 109 public boolean createPortal(Location location) { 110 net.minecraft.server.World world = ((CraftWorld) location.getWorld()).getHandle(); 111 // byte b0 = 16; 112 double d0 = -1.0D; 113 int i = location.getBlockX(); 114 int j = location.getBlockY(); 115 int k = location.getBlockZ(); 116 int l = i; 117 int i1 = j; 118 int j1 = k; 119 int k1 = 0; 120 int l1 = this.random.nextInt(4); 121 122 int i2; 123 double d1; 124 int j2; 125 double d2; 126 int k2; 127 int l2; 128 int i3; 129 int j3; 130 int k3; 131 int l3; 132 int i4; 133 int j4; 134 int k4; 135 double d3; 136 double d4; 137 138 for (i2 = i - this.creationRadius; i2 <= i + this.creationRadius; ++i2) { 139 d1 = (double) i2 + 0.5D - location.getX(); 140 141 for (j2 = k - this.creationRadius; j2 <= k + this.creationRadius; ++j2) { 142 d2 = (double) j2 + 0.5D - location.getZ(); 143 144 label271: 145 for (l2 = 127; l2 >= 0; --l2) { 146 if (world.isEmpty(i2, l2, j2)) { 147 while (l2 > 0 && world.isEmpty(i2, l2 - 1, j2)) { 148 --l2; 149 } 150 151 for (k2 = l1; k2 < l1 + 4; ++k2) { 152 j3 = k2 % 2; 153 i3 = 1 - j3; 154 if (k2 % 4 >= 2) { 155 j3 = -j3; 156 i3 = -i3; 157 } 158 159 for (l3 = 0; l3 < 3; ++l3) { 160 for (k3 = 0; k3 < 4; ++k3) { 161 for (j4 = -1; j4 < 5; ++j4) { 162 i4 = i2 + (k3 - 1) * j3 + l3 * i3; 163 k4 = l2 + j4; 164 int l4 = j2 + (k3 - 1) * i3 - l3 * j3; 165 166 if (j4 < 0 && !world.getMaterial(i4, k4, l4).isBuildable() || j4 >= 0 && !world.isEmpty(i4, k4, l4)) { 167 continue label271; 168 } 169 } 170 } 171 } 172 173 d3 = (double) l2 + 0.5D - location.getY(); 174 d4 = d1 * d1 + d3 * d3 + d2 * d2; 175 if (d0 < 0.0D || d4 < d0) { 176 d0 = d4; 177 l = i2; 178 i1 = l2 + 1; 179 j1 = j2; 180 k1 = k2 % 4; 181 } 182 } 183 } 184 } 185 } 186 } 187 188 if (d0 < 0.0D) { 189 for (i2 = i - this.creationRadius; i2 <= i + this.creationRadius; ++i2) { 190 d1 = (double) i2 + 0.5D - location.getX(); 191 192 for (j2 = k - this.creationRadius; j2 <= k + this.creationRadius; ++j2) { 193 d2 = (double) j2 + 0.5D - location.getZ(); 194 195 label219: 196 for (l2 = 127; l2 >= 0; --l2) { 197 if (world.isEmpty(i2, l2, j2)) { 198 while (l2 > 0 && world.isEmpty(i2, l2 - 1, j2)) { 199 --l2; 200 } 201 202 for (k2 = l1; k2 < l1 + 2; ++k2) { 203 j3 = k2 % 2; 204 i3 = 1 - j3; 205 206 for (l3 = 0; l3 < 4; ++l3) { 207 for (k3 = -1; k3 < 5; ++k3) { 208 j4 = i2 + (l3 - 1) * j3; 209 i4 = l2 + k3; 210 k4 = j2 + (l3 - 1) * i3; 211 if (k3 < 0 && !world.getMaterial(j4, i4, k4).isBuildable() || k3 >= 0 && !world.isEmpty(j4, i4, k4)) { 212 continue label219; 213 } 214 } 215 } 216 217 d3 = (double) l2 + 0.5D - location.getY(); 218 d4 = d1 * d1 + d3 * d3 + d2 * d2; 219 if (d0 < 0.0D || d4 < d0) { 220 d0 = d4; 221 l = i2; 222 i1 = l2 + 1; 223 j1 = j2; 224 k1 = k2 % 2; 225 } 226 } 227 } 228 } 229 } 230 } 231 } 232 233 int i5 = l; 234 int j5 = i1; 235 236 j2 = j1; 237 int k5 = k1 % 2; 238 int l5 = 1 - k5; 239 240 if (k1 % 4 >= 2) { 241 k5 = -k5; 242 l5 = -l5; 243 } 244 245 boolean flag; 246 247 // CraftBukkit start - portal create event 248 java.util.ArrayList<org.bukkit.block.Block> blocks = new java.util.ArrayList<org.bukkit.block.Block>(); 249 // Find out what blocks the portal is going to modify, duplicated from below 250 CraftWorld craftWorld = ((WorldServer) world).getWorld(); 251 252 if (d0 < 0.0D) { 253 if (i1 < 70) { 254 i1 = 70; 255 } 256 257 if (i1 > 118) { 258 i1 = 118; 259 } 260 261 j5 = i1; 262 263 for (l2 = -1; l2 <= 1; ++l2) { 264 for (k2 = 1; k2 < 3; ++k2) { 265 for (j3 = -1; j3 < 3; ++j3) { 266 i3 = i5 + (k2 - 1) * k5 + l2 * l5; 267 l3 = j5 + j3; 268 k3 = j2 + (k2 - 1) * l5 - l2 * k5; 269 org.bukkit.block.Block b = craftWorld.getBlockAt(i3, l3, k3); 270 if (!blocks.contains(b)) { 271 blocks.add(b); 272 } 273 } 274 } 275 } 276 } 277 278 for (l2 = 0; l2 < 4; ++l2) { 279 for (k2 = 0; k2 < 4; ++k2) { 280 for (j3 = -1; j3 < 4; ++j3) { 281 i3 = i5 + (k2 - 1) * k5; 282 l3 = j5 + j3; 283 k3 = j2 + (k2 - 1) * l5; 284 org.bukkit.block.Block b = craftWorld.getBlockAt(i3, l3, k3); 285 if (!blocks.contains(b)) { 286 blocks.add(b); 287 } 288 } 289 } 290 } 291 292 PortalCreateEvent event = new PortalCreateEvent(blocks, (org.bukkit.World) craftWorld); 293 Bukkit.getServer().getPluginManager().callEvent(event); 294 if (event.isCancelled()) { 295 return false; 296 } 297 // CraftBukkit end 298 299 if (d0 < 0.0D) { 300 if (i1 < 70) { 301 i1 = 70; 302 } 303 304 if (i1 > 118) { 305 i1 = 118; 306 } 307 308 j5 = i1; 309 310 for (l2 = -1; l2 <= 1; ++l2) { 311 for (k2 = 1; k2 < 3; ++k2) { 312 for (j3 = -1; j3 < 3; ++j3) { 313 i3 = i5 + (k2 - 1) * k5 + l2 * l5; 314 l3 = j5 + j3; 315 k3 = j2 + (k2 - 1) * l5 - l2 * k5; 316 flag = j3 < 0; 317 world.setTypeId(i3, l3, k3, flag ? Block.OBSIDIAN.id : 0); 318 } 319 } 320 } 321 } 322 323 for (l2 = 0; l2 < 4; ++l2) { 324 world.suppressPhysics = true; 325 326 for (k2 = 0; k2 < 4; ++k2) { 327 for (j3 = -1; j3 < 4; ++j3) { 328 i3 = i5 + (k2 - 1) * k5; 329 l3 = j5 + j3; 330 k3 = j2 + (k2 - 1) * l5; 331 flag = k2 == 0 || k2 == 3 || j3 == -1 || j3 == 3; 332 world.setTypeId(i3, l3, k3, flag ? Block.OBSIDIAN.id : Block.PORTAL.id); 333 } 334 } 335 336 world.suppressPhysics = false; 337 338 for (k2 = 0; k2 < 4; ++k2) { 339 for (j3 = -1; j3 < 4; ++j3) { 340 i3 = i5 + (k2 - 1) * k5; 341 l3 = j5 + j3; 342 k3 = j2 + (k2 - 1) * l5; 343 world.applyPhysics(i3, l3, k3, world.getTypeId(i3, l3, k3)); 344 } 345 } 346 } 347 348 return true; 349 } 350 351 352 public TravelAgent setSearchRadius(int radius) { 353 this.searchRadius = radius; 354 return this; 355 } 356 357 public int getSearchRadius() { 358 return this.searchRadius; 359 } 360 361 public TravelAgent setCreationRadius(int radius) { 362 this.creationRadius = radius < 2 ? 0 : radius - 2; 363 return this; 364 } 365 366 public int getCreationRadius() { 367 return this.creationRadius; 368 } 369 370 public boolean getCanCreatePortal() { 371 return this.canCreatePortal; 372 } 373 374 public void setCanCreatePortal(boolean create) { 375 this.canCreatePortal = create; 376 } 377}