From d834ca4c6c6dd051e49ee177eb527c7494bd47bc Mon Sep 17 00:00:00 2001 From: EdGruberman Date: Sat, 22 Dec 2012 11:46:24 -0700 Subject: [PATCH] [Bleeding] Add experimental support for entity portal traveling --- .../minecraft/server/BlockEnderPortal.java | 6 + .../java/net/minecraft/server/Entity.java | 47 +- .../net/minecraft/server/EntityHuman.java | 7 +- .../net/minecraft/server/EntityMinecart.java | 2 +- .../net/minecraft/server/EntityPlayer.java | 17 +- .../minecraft/server/PlayerConnection.java | 22 +- .../java/net/minecraft/server/PlayerList.java | 199 +++++--- .../minecraft/server/PortalTravelAgent.java | 187 ++++++-- .../net/minecraft/server/WorldServer.java | 2 +- .../bukkit/craftbukkit/CraftTravelAgent.java | 74 +++ .../bukkit/craftbukkit/PortalTravelAgent.java | 434 ------------------ 11 files changed, 427 insertions(+), 570 deletions(-) create mode 100644 src/main/java/org/bukkit/craftbukkit/CraftTravelAgent.java delete mode 100644 src/main/java/org/bukkit/craftbukkit/PortalTravelAgent.java diff --git a/src/main/java/net/minecraft/server/BlockEnderPortal.java b/src/main/java/net/minecraft/server/BlockEnderPortal.java index d55e41d0fd..6a5b27488c 100644 --- a/src/main/java/net/minecraft/server/BlockEnderPortal.java +++ b/src/main/java/net/minecraft/server/BlockEnderPortal.java @@ -3,6 +3,8 @@ package net.minecraft.server; import java.util.List; import java.util.Random; +import org.bukkit.event.entity.EntityPortalEnterEvent; // CraftBukkit + public class BlockEnderPortal extends BlockContainer { public static boolean a = false; @@ -38,6 +40,10 @@ public class BlockEnderPortal extends BlockContainer { public void a(World world, int i, int j, int k, Entity entity) { if (entity.vehicle == null && entity.passenger == null && !world.isStatic) { + // CraftBukkit start - Entity in portal + EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), i, j, k)); + world.getServer().getPluginManager().callEvent(event); + // CraftBukkit end entity.b(1); } } diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java index ebe0ed067c..e1d611ed38 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java @@ -8,7 +8,9 @@ import java.util.concurrent.Callable; import java.util.UUID; import org.bukkit.Bukkit; +import org.bukkit.Location; import org.bukkit.Server; +import org.bukkit.TravelAgent; import org.bukkit.block.BlockFace; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Painting; @@ -19,11 +21,13 @@ import org.bukkit.event.vehicle.VehicleBlockCollisionEvent; import org.bukkit.event.vehicle.VehicleEnterEvent; import org.bukkit.event.vehicle.VehicleExitEvent; import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.entity.CraftEntity; import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.event.entity.EntityCombustEvent; import org.bukkit.event.entity.EntityDamageByBlockEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityPortalEvent; import org.bukkit.plugin.PluginManager; // CraftBukkit end @@ -1378,9 +1382,9 @@ public abstract class Entity { this.setPassengerOf(entity); } - protected org.bukkit.entity.Entity bukkitEntity; + protected CraftEntity bukkitEntity; - public org.bukkit.entity.Entity getBukkitEntity() { + public CraftEntity getBukkitEntity() { if (this.bukkitEntity == null) { this.bukkitEntity = org.bukkit.craftbukkit.entity.CraftEntity.getEntity(this.world.getServer(), this); } @@ -1741,24 +1745,53 @@ public abstract class Entity { } public void b(int i) { - if (false && !this.world.isStatic && !this.dead) { // CraftBukkit - disable entity portal support for now. + if (!this.world.isStatic && !this.dead) { this.world.methodProfiler.a("changeDimension"); MinecraftServer minecraftserver = MinecraftServer.getServer(); - int j = this.dimension; - WorldServer worldserver = minecraftserver.getWorldServer(j); - WorldServer worldserver1 = minecraftserver.getWorldServer(i); + // CraftBukkit start - move logic into new function "teleportToLocation" + // int j = this.dimension; + Location enter = this.getBukkitEntity().getLocation(); + Location exit = minecraftserver.getPlayerList().calculateTarget(enter, minecraftserver.getWorldServer(i)); + + TravelAgent agent = (TravelAgent) ((CraftWorld) exit.getWorld()).getHandle().s(); + EntityPortalEvent event = new EntityPortalEvent(this.getBukkitEntity(), enter, exit, agent); + event.getEntity().getServer().getPluginManager().callEvent(event); + if (event.isCancelled() || event.getTo() == null || !this.isAlive()) { + return; + } + exit = event.useTravelAgent() ? event.getPortalTravelAgent().findOrCreate(exit) : event.getTo(); + this.teleportTo(exit, true); + } + } + + public void teleportTo(Location exit, boolean portal) { + if (true) { + WorldServer worldserver = ((CraftWorld) this.getBukkitEntity().getLocation().getWorld()).getHandle(); + WorldServer worldserver1 = ((CraftWorld) exit.getWorld()).getHandle(); + int i = worldserver1.dimension; + // CraftBukkit end this.dimension = i; this.world.kill(this); this.dead = false; this.world.methodProfiler.a("reposition"); - minecraftserver.getPlayerList().a(this, j, worldserver, worldserver1); + // CraftBukkit start - ensure chunks are loaded in case TravelAgent is not used which would initially cause chunks to load during find/create + // minecraftserver.getPlayerList().a(this, j, worldserver, worldserver1); + boolean before = worldserver1.chunkProviderServer.forceChunkLoad; + worldserver1.chunkProviderServer.forceChunkLoad = true; + worldserver1.getMinecraftServer().getPlayerList().repositionEntity(this, exit, portal); + worldserver1.chunkProviderServer.forceChunkLoad = before; + // CraftBukkit end this.world.methodProfiler.c("reloading"); Entity entity = EntityTypes.createEntityByName(EntityTypes.b(this), worldserver1); if (entity != null) { entity.a(this, true); worldserver1.addEntity(entity); + // CraftBukkit start - forward the CraftEntity to the new entity + this.getBukkitEntity().setHandle(entity); + entity.bukkitEntity = this.getBukkitEntity(); + // CraftBukkit end } this.dead = true; diff --git a/src/main/java/net/minecraft/server/EntityHuman.java b/src/main/java/net/minecraft/server/EntityHuman.java index 85663915b5..7afa68ef40 100644 --- a/src/main/java/net/minecraft/server/EntityHuman.java +++ b/src/main/java/net/minecraft/server/EntityHuman.java @@ -4,8 +4,8 @@ import java.util.Iterator; import java.util.List; // CraftBukkit start +import org.bukkit.craftbukkit.entity.CraftHumanEntity; import org.bukkit.craftbukkit.entity.CraftItem; -import org.bukkit.entity.HumanEntity; import org.bukkit.entity.Player; import org.bukkit.event.entity.EntityCombustByEntityEvent; import org.bukkit.event.player.PlayerBedEnterEvent; @@ -37,8 +37,9 @@ public abstract class EntityHuman extends EntityLiving implements ICommandListen public boolean fauxSleeping; public String spawnWorld = ""; - public HumanEntity getBukkitEntity() { - return (HumanEntity) super.getBukkitEntity(); + @Override + public CraftHumanEntity getBukkitEntity() { + return (CraftHumanEntity) super.getBukkitEntity(); } // CraftBukkit end diff --git a/src/main/java/net/minecraft/server/EntityMinecart.java b/src/main/java/net/minecraft/server/EntityMinecart.java index 712853d1d5..cabc3ce686 100644 --- a/src/main/java/net/minecraft/server/EntityMinecart.java +++ b/src/main/java/net/minecraft/server/EntityMinecart.java @@ -299,7 +299,7 @@ public class EntityMinecart extends Entity implements IInventory { i = this.z(); if (this.ao) { - if (minecraftserver.getAllowNether()) { + if (true || minecraftserver.getAllowNether()) { // CraftBukkit - multi-world should still allow teleport even if default vanilla nether disabled if (this.vehicle == null && this.ap++ >= i) { this.ap = i; this.portalCooldown = this.ab(); diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java index 99f12181ed..8d61ca63f8 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/EntityPlayer.java @@ -15,6 +15,7 @@ import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; // CraftBukkit end public class EntityPlayer extends EntityHuman implements ICrafting { @@ -321,21 +322,27 @@ public class EntityPlayer extends EntityHuman implements ICrafting { this.viewingCredits = true; this.playerConnection.sendPacket(new Packet70Bed(4, 0)); } else { - this.a((Statistic) AchievementList.B); - /* CraftBukkit start - removed to fix our handling of The End portals - ChunkCoordinates chunkcoordinates = this.server.getWorldServer(i).getDimensionSpawn(); + if (this.dimension == 1 && i == 0) { + this.a((Statistic) AchievementList.B); + // CraftBukkit start - rely on custom portal management + /* + ChunkCoordinates chunkcoordinates = this.server.getWorldServer(i).getDimensionSpawn(); if (chunkcoordinates != null) { this.netServerHandler.a((double) chunkcoordinates.x, (double) chunkcoordinates.y, (double) chunkcoordinates.z, 0.0F, 0.0F); } i = 1; + */ + // CraftBukkit end } else { this.a((Statistic) AchievementList.x); } - // CraftBukkit end */ - this.server.getPlayerList().changeDimension(this, i); + // CraftBukkit start + TeleportCause cause = (this.dimension == 1 || i == 1) ? TeleportCause.END_PORTAL : TeleportCause.NETHER_PORTAL; + this.server.getPlayerList().changeDimension(this, i, cause); + // CraftBukkit end this.lastSentExp = -1; this.cl = -1; this.cm = -1; diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java index 94b62ac94d..fac9ea5e1d 100644 --- a/src/main/java/net/minecraft/server/PlayerConnection.java +++ b/src/main/java/net/minecraft/server/PlayerConnection.java @@ -37,6 +37,7 @@ import org.bukkit.event.player.PlayerItemHeldEvent; import org.bukkit.event.player.PlayerKickEvent; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerTeleportEvent; +import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.event.player.PlayerToggleSneakEvent; import org.bukkit.event.player.PlayerToggleSprintEvent; import org.bukkit.event.inventory.*; @@ -1126,26 +1127,7 @@ public class PlayerConnection extends Connection { public void a(Packet205ClientCommand packet205clientcommand) { if (packet205clientcommand.a == 1) { if (this.player.viewingCredits) { - // CraftBukkit start - org.bukkit.craftbukkit.PortalTravelAgent pta = new org.bukkit.craftbukkit.PortalTravelAgent(); - Location toLocation; - - if (this.player.getBukkitEntity().getBedSpawnLocation() == null) { - CraftWorld cworld = (CraftWorld) this.server.getWorlds().get(0); - ChunkCoordinates chunkcoordinates = cworld.getHandle().getSpawn(); - toLocation = new Location(cworld, chunkcoordinates.x + 0.5, chunkcoordinates.y, chunkcoordinates.z + 0.5); - this.player.playerConnection.sendPacket(new Packet70Bed(0, 0)); - } else { - toLocation = this.player.getBukkitEntity().getBedSpawnLocation(); - toLocation = new Location(toLocation.getWorld(), toLocation.getX() + 0.5, toLocation.getY(), toLocation.getZ() + 0.5); - } - - PlayerPortalEvent event = new PlayerPortalEvent(this.player.getBukkitEntity(), this.player.getBukkitEntity().getLocation(), toLocation, pta, PlayerPortalEvent.TeleportCause.END_PORTAL); - event.useTravelAgent(false); - - Bukkit.getServer().getPluginManager().callEvent(event); - this.player = this.minecraftServer.getPlayerList().moveToWorld(this.player, 0, true, event.getTo()); - // CraftBukkit end + this.minecraftServer.getPlayerList().changeDimension(this.player, 0, TeleportCause.END_PORTAL); // CraftBukkit - reroute logic through custom portal management } else if (this.player.p().getWorldData().isHardcore()) { if (this.minecraftServer.I() && this.player.name.equals(this.minecraftServer.H())) { this.player.playerConnection.disconnect("You have died. Game over, man, it\'s game over!"); diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java index 04ee0de4c3..2fb83cf6cc 100644 --- a/src/main/java/net/minecraft/server/PlayerList.java +++ b/src/main/java/net/minecraft/server/PlayerList.java @@ -13,9 +13,11 @@ import java.util.logging.Logger; // CraftBukkit start import org.bukkit.Location; +import org.bukkit.TravelAgent; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.chunkio.ChunkIOExecutor; +import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerChangedWorldEvent; import org.bukkit.event.player.PlayerPortalEvent; @@ -24,6 +26,7 @@ import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerLoginEvent; import org.bukkit.event.player.PlayerRespawnEvent; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; +import org.bukkit.util.Vector; import org.bukkit.Bukkit; // CraftBukkit end @@ -419,76 +422,134 @@ public abstract class PlayerList { return entityplayer1; } - public void changeDimension(EntityPlayer entityplayer, int i) { - // CraftBukkit start -- Replaced the standard handling of portals with a more customised method. - int dimension = i; - WorldServer fromWorld = this.server.getWorldServer(entityplayer.dimension); - WorldServer toWorld = null; - if (entityplayer.dimension < 10) { - for (WorldServer world : this.server.worlds) { - if (world.dimension == dimension) { - toWorld = world; - } - } - } - - Location fromLocation = new Location(fromWorld.getWorld(), entityplayer.locX, entityplayer.locY, entityplayer.locZ, entityplayer.yaw, entityplayer.pitch); - Location toLocation = null; - - if (toWorld != null) { - if (((dimension == -1) || (dimension == 0)) && ((entityplayer.dimension == -1) || (entityplayer.dimension == 0))) { - double blockRatio = dimension == 0 ? 8 : 0.125; - - toLocation = toWorld == null ? null : new Location(toWorld.getWorld(), (entityplayer.locX * blockRatio), entityplayer.locY, (entityplayer.locZ * blockRatio), entityplayer.yaw, entityplayer.pitch); - } else { - ChunkCoordinates coords = toWorld.getDimensionSpawn(); - if (coords != null) { - toLocation = new Location(toWorld.getWorld(), coords.x, coords.y, coords.z, 90, 0); - } - } - } - - TeleportCause cause = TeleportCause.UNKNOWN; - int playerEnvironmentId = entityplayer.getBukkitEntity().getWorld().getEnvironment().getId(); - switch (dimension) { - case -1: - cause = TeleportCause.NETHER_PORTAL; - break; - case 0: - if (playerEnvironmentId == -1) { - cause = TeleportCause.NETHER_PORTAL; - } else if (playerEnvironmentId == 1) { - cause = TeleportCause.END_PORTAL; - } - - break; - case 1: - cause = TeleportCause.END_PORTAL; - break; - } - - org.bukkit.craftbukkit.PortalTravelAgent pta = new org.bukkit.craftbukkit.PortalTravelAgent(); - PlayerPortalEvent event = new PlayerPortalEvent((Player) entityplayer.getBukkitEntity(), fromLocation, toLocation, pta, cause); - - if (entityplayer.dimension == 1) { - event.useTravelAgent(false); + // CraftBukkit start - Replaced the standard handling of portals with a more customised method. + public void changeDimension(EntityPlayer entityplayer, int i, TeleportCause cause) { + WorldServer exitWorld = this.server.getWorldServer(i); + Location enter = entityplayer.getBukkitEntity().getLocation(); + Location exit = null; + if ((cause == TeleportCause.END_PORTAL) && (i == 0)) { + // THE_END -> NORMAL; use bed if available + exit = ((CraftPlayer) entityplayer.getBukkitEntity()).getBedSpawnLocation(); + } + if (exit == null) { + exit = this.calculateTarget(enter, exitWorld); } + TravelAgent agent = (TravelAgent) ((CraftWorld) exit.getWorld()).getHandle().s(); + PlayerPortalEvent event = new PlayerPortalEvent(entityplayer.getBukkitEntity(), enter, exit, agent, cause); Bukkit.getServer().getPluginManager().callEvent(event); if (event.isCancelled() || event.getTo() == null) { return; } + exit = event.useTravelAgent() ? event.getPortalTravelAgent().findOrCreate(exit) : event.getTo(); + exitWorld = ((CraftWorld) exit.getWorld()).getHandle(); - Location finalLocation = event.getTo(); - if (event.useTravelAgent()) { - finalLocation = event.getPortalTravelAgent().findOrCreate(finalLocation); + Vector velocity = entityplayer.getBukkitEntity().getVelocity(); + boolean before = exitWorld.chunkProviderServer.forceChunkLoad; + exitWorld.chunkProviderServer.forceChunkLoad = true; + exitWorld.s().adjustExit(entityplayer, exit, velocity); + exitWorld.chunkProviderServer.forceChunkLoad = before; + + this.moveToWorld(entityplayer, exitWorld.dimension, true, exit); + if (entityplayer.motX != velocity.getX() || entityplayer.motY != velocity.getY() || entityplayer.motZ != velocity.getZ()) { + entityplayer.getBukkitEntity().setVelocity(velocity); } - toWorld = ((CraftWorld) finalLocation.getWorld()).getHandle(); - this.moveToWorld(entityplayer, toWorld.dimension, true, finalLocation); // CraftBukkit end } public void a(Entity entity, int i, WorldServer worldserver, WorldServer worldserver1) { + // CraftBukkit start - split into modular functions + Location exit = this.calculateTarget(entity.getBukkitEntity().getLocation(), worldserver1); + this.repositionEntity(entity, exit, true); + } + + // copy of original a(Entity, int, WorldServer, WorldServer) method with only location calculation logic + public Location calculateTarget(Location enter, World target) { + WorldServer worldserver = ((CraftWorld) enter.getWorld()).getHandle(); + WorldServer worldserver1 = ((CraftWorld) target.getWorld()).getHandle(); + int i = worldserver.dimension; + + double y = enter.getY(); + float yaw = enter.getYaw(); + float pitch = enter.getPitch(); + double d0 = enter.getX(); + double d1 = enter.getZ(); + double d2 = 8.0D; + /* + double d3 = entity.locX; + double d4 = entity.locY; + double d5 = entity.locZ; + float f = entity.yaw; + + worldserver.methodProfiler.a("moving"); + */ + if (worldserver1.dimension == -1) { + d0 /= d2; + d1 /= d2; + /* + entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch); + if (entity.isAlive()) { + worldserver.entityJoinedWorld(entity, false); + } + */ + } else if (worldserver1.dimension == 0) { + d0 *= d2; + d1 *= d2; + /* + entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch); + if (entity.isAlive()) { + worldserver.entityJoinedWorld(entity, false); + } + */ + } else { + ChunkCoordinates chunkcoordinates; + + if (i == 1) { + chunkcoordinates = worldserver1.getSpawn(); + } else { + chunkcoordinates = worldserver1.getDimensionSpawn(); + } + + d0 = (double) chunkcoordinates.x; + y = (double) chunkcoordinates.y; + d1 = (double) chunkcoordinates.z; + yaw = 90.0F; + pitch = 0.0F; + /* + entity.setPositionRotation(d0, entity.locY, d1, 90.0F, 0.0F); + if (entity.isAlive()) { + worldserver.entityJoinedWorld(entity, false); + } + */ + } + + // worldserver.methodProfiler.b(); + if (i != 1) { + // worldserver.methodProfiler.a("placing"); + d0 = (double) MathHelper.a((int) d0, -29999872, 29999872); + d1 = (double) MathHelper.a((int) d1, -29999872, 29999872); + /* + if (entity.isAlive()) { + worldserver1.addEntity(entity); + entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch); + worldserver1.entityJoinedWorld(entity, false); + worldserver1.s().a(entity, d3, d4, d5, f); + } + + worldserver.methodProfiler.b(); + */ + } + + // entity.spawnIn(worldserver1); + return new Location(target.getWorld(), d0, y, d1, yaw, pitch); + } + + // copy of original a(Entity, int, WorldServer, WorldServer) method with only entity repositioning logic + public void repositionEntity(Entity entity, Location exit, boolean portal) { + int i = entity.dimension; + WorldServer worldserver = (WorldServer) entity.world; + WorldServer worldserver1 = ((CraftWorld) exit.getWorld()).getHandle(); + /* double d0 = entity.locX; double d1 = entity.locZ; double d2 = 8.0D; @@ -496,8 +557,14 @@ public abstract class PlayerList { double d4 = entity.locY; double d5 = entity.locZ; float f = entity.yaw; + */ worldserver.methodProfiler.a("moving"); + entity.setPositionRotation(exit.getX(), exit.getY(), exit.getZ(), exit.getYaw(), exit.getPitch()); + if (entity.isAlive()) { + worldserver.entityJoinedWorld(entity, false); + } + /* if (entity.dimension == -1) { d0 /= d2; d1 /= d2; @@ -529,23 +596,35 @@ public abstract class PlayerList { worldserver.entityJoinedWorld(entity, false); } } + */ worldserver.methodProfiler.b(); if (i != 1) { worldserver.methodProfiler.a("placing"); + /* d0 = (double) MathHelper.a((int) d0, -29999872, 29999872); d1 = (double) MathHelper.a((int) d1, -29999872, 29999872); + */ if (entity.isAlive()) { worldserver1.addEntity(entity); - entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch); + // entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch) worldserver1.entityJoinedWorld(entity, false); - worldserver1.s().a(entity, d3, d4, d5, f); + // worldserver1.s().a(entity, d3, d4, d5, f); + if (portal) { + Vector velocity = entity.getBukkitEntity().getVelocity(); + worldserver1.s().adjustExit(entity, exit, velocity); + entity.setPositionRotation(exit.getX(), exit.getY(), exit.getZ(), exit.getYaw(), exit.getPitch()); + if (entity.motX != velocity.getX() || entity.motY != velocity.getY() || entity.motZ != velocity.getZ()) { + entity.getBukkitEntity().setVelocity(velocity); + } + } } worldserver.methodProfiler.b(); } entity.spawnIn(worldserver1); + // CraftBukkit end } public void tick() { diff --git a/src/main/java/net/minecraft/server/PortalTravelAgent.java b/src/main/java/net/minecraft/server/PortalTravelAgent.java index e7df5c202d..7733e8068d 100644 --- a/src/main/java/net/minecraft/server/PortalTravelAgent.java +++ b/src/main/java/net/minecraft/server/PortalTravelAgent.java @@ -6,13 +6,9 @@ import java.util.List; import java.util.Random; // CraftBukkit start -/* - * HEAR ME, HE WHOM WISHES TO COMMAND THE UPDATERING - * - * FOR SOME REASON WE HAVE OUR OWN PORTAL TRAVEL AGENT IN OBC, WE NEED TO UPDATE - * THAT WITH ANY NEW UPDATES TO THIS FILE. THIS FILE LEFT HERE AS A REMINDER. - * - */ +import org.bukkit.Location; +import org.bukkit.event.entity.EntityPortalExitEvent; +import org.bukkit.util.Vector; // CraftBukkit end public class PortalTravelAgent { @@ -34,9 +30,19 @@ public class PortalTravelAgent { this.b(entity, d0, d1, d2, f); } } else { - int i = MathHelper.floor(entity.locX); - int j = MathHelper.floor(entity.locY) - 1; - int k = MathHelper.floor(entity.locZ); + // CraftBukkit start - modularize end portal creation + ChunkCoordinates created = this.createEndPortal(d0, d1, d2); + entity.setPositionRotation((double) created.x, (double) created.y, (double) created.z, entity.yaw, 0.0F); + entity.motX = entity.motY = entity.motZ = 0.0D; + } + } + + // split out from original a(Entity, double, double, double, float) method in order to enable being called from createPortal + private ChunkCoordinates createEndPortal(double x, double y, double z) { + int i = MathHelper.floor(x); + int j = MathHelper.floor(y) - 1; + int k = MathHelper.floor(z); + // CraftBukkit end byte b0 = 1; byte b1 = 0; @@ -53,19 +59,66 @@ public class PortalTravelAgent { } } - entity.setPositionRotation((double) i, (double) j, (double) k, entity.yaw, 0.0F); - entity.motX = entity.motY = entity.motZ = 0.0D; - } + // CraftBukkit start + return new ChunkCoordinates(i, j, k); } + // use logic based on creation to verify end portal + private ChunkCoordinates findEndPortal(ChunkCoordinates portal) { + int i = portal.x; + int j = portal.y - 1; + int k = portal.z; + byte b0 = 1; + byte b1 = 0; + + for (int l = -2; l <= 2; ++l) { + for (int i1 = -2; i1 <= 2; ++i1) { + for (int j1 = -1; j1 < 3; ++j1) { + int k1 = i + i1 * b0 + l * b1; + int l1 = j + j1; + int i2 = k + i1 * b1 - l * b0; + boolean flag = j1 < 0; + + if (this.a.getTypeId(k1, l1, i2) != (flag ? Block.OBSIDIAN.id : 0)) { + return null; + } + } + } + } + return new ChunkCoordinates(i, j, k); + } + // CraftBukkit end + public boolean b(Entity entity, double d0, double d1, double d2, float f) { - short short1 = 128; + // CraftBukkit start - modularize portal search process and entity teleportation + ChunkCoordinates found = this.findPortal(entity.locX, entity.locY, entity.locZ, 128); + if (found == null) { + return false; + } + + Location exit = new Location(this.a.getWorld(), found.x, found.y, found.z, f, entity.pitch); + Vector velocity = entity.getBukkitEntity().getVelocity(); + this.adjustExit(entity, exit, velocity); + entity.setPositionRotation(exit.getX(), exit.getY(), exit.getZ(), exit.getYaw(), exit.getPitch()); + if (entity.motX != velocity.getX() || entity.motY != velocity.getY() || entity.motZ != velocity.getZ()) { + entity.getBukkitEntity().setVelocity(velocity); + } + return true; + } + + public ChunkCoordinates findPortal(double x, double y, double z, int short1) { + if (this.a.getWorld().getEnvironment() == org.bukkit.World.Environment.THE_END) { + return this.findEndPortal(this.a.worldProvider.h()); + } + // CraftBukkit end double d3 = -1.0D; int i = 0; int j = 0; int k = 0; - int l = MathHelper.floor(entity.locX); - int i1 = MathHelper.floor(entity.locZ); + // CraftBukkit start + int l = MathHelper.floor(x); + int i1 = MathHelper.floor(z); + // CraftBukkit end long j1 = ChunkCoordIntPair.a(l, i1); boolean flag = true; double d4; @@ -82,10 +135,10 @@ public class PortalTravelAgent { flag = false; } else { for (k1 = l - short1; k1 <= l + short1; ++k1) { - double d5 = (double) k1 + 0.5D - entity.locX; + double d5 = (double) k1 + 0.5D - x; // CraftBukkit for (int l1 = i1 - short1; l1 <= i1 + short1; ++l1) { - double d6 = (double) l1 + 0.5D - entity.locZ; + double d6 = (double) l1 + 0.5D - z; // CraftBukkit for (int i2 = this.a.P() - 1; i2 >= 0; --i2) { if (this.a.getTypeId(k1, i2, l1) == Block.PORTAL.id) { @@ -93,7 +146,7 @@ public class PortalTravelAgent { --i2; } - d4 = (double) i2 + 0.5D - entity.locY; + d4 = (double) i2 + 0.5D - y; // CraftBukkit double d7 = d5 * d5 + d4 * d4 + d6 * d6; if (d3 < 0.0D || d7 < d3) { @@ -113,6 +166,32 @@ public class PortalTravelAgent { this.c.put(j1, new ChunkCoordinatesPortal(this, i, j, k, this.a.getTime())); this.d.add(Long.valueOf(j1)); } + // CraftBukkit start - moved entity teleportation logic into exit + return new ChunkCoordinates(i, j, k); + } else { + return null; + } + } + // entity repositioning logic split out from original b method and combined with repositioning logic for The End from original a method + public void adjustExit(Entity entity, Location position, Vector velocity) { + Location from = position.clone(); + Vector before = velocity.clone(); + int i = position.getBlockX(); + int j = position.getBlockY(); + int k = position.getBlockZ(); + float f = position.getYaw(); + + if (this.a.getWorld().getEnvironment() == org.bukkit.World.Environment.THE_END) { + // entity.setPositionRotation((double) i, (double) j, (double) k, entity.yaw, 0.0F); + // entity.motX = entity.motY = entity.motZ = 0.0D; + position.setPitch(0.0F); + position.setX(0); + position.setY(0); + position.setZ(0); + } else { + double d4; + int k1; + // CraftBukkit end double d8 = (double) i + 0.5D; double d9 = (double) j + 0.5D; @@ -195,29 +274,59 @@ public class PortalTravelAgent { f6 = 1.0F; } - double d10 = entity.motX; - double d11 = entity.motZ; + // CraftBukkit start + double d10 = velocity.getX(); + double d11 = velocity.getZ(); + // CraftBukkit end - entity.motX = d10 * (double) f3 + d11 * (double) f6; - entity.motZ = d10 * (double) f5 + d11 * (double) f4; - entity.yaw = f - (float) (k2 * 90) + (float) (j2 * 90); + // CraftBukkit start - adjust position and velocity instances instead of entity + velocity.setX(d10 * (double) f3 + d11 * (double) f6); + velocity.setZ(d10 * (double) f5 + d11 * (double) f4); + f = f - (float) (k2 * 90) + (float) (j2 * 90); } else { - entity.motX = entity.motY = entity.motZ = 0.0D; + // entity.motX = entity.motY = entity.motZ = 0.0D; + velocity.setX(0); + velocity.setY(0); + velocity.setZ(0); } - entity.setPositionRotation(d8, d9, d4, entity.yaw, entity.pitch); - return true; - } else { - return false; + // entity.setPositionRotation(d8, d9, d4, entity.yaw, entity.pitch); + position.setX(d8); + position.setY(d9); + position.setZ(d4); + position.setYaw(f); } + + EntityPortalExitEvent event = new EntityPortalExitEvent(entity.getBukkitEntity(), from, position, before, velocity); + this.a.getServer().getPluginManager().callEvent(event); + Location to = event.getTo(); + if (event.isCancelled() || to == null || !entity.isAlive()) { + position = from; + velocity = before; + } else { + position = to; + velocity = event.getAfter(); + } + // CraftBukkit end } public boolean a(Entity entity) { - byte b0 = 16; + // CraftBukkit start - allow for portal creation to be based on coordinates instead of entity + return this.createPortal(entity.locX, entity.locY, entity.locZ, 16); + } + + public boolean createPortal(double x, double y, double z, int b0) { + if (this.a.getWorld().getEnvironment() == org.bukkit.World.Environment.THE_END) { + this.createEndPortal(x, y, z); + return true; + } + // CraftBukkit end double d0 = -1.0D; - int i = MathHelper.floor(entity.locX); - int j = MathHelper.floor(entity.locY); - int k = MathHelper.floor(entity.locZ); + // CraftBukkit start + int i = MathHelper.floor(x); + int j = MathHelper.floor(y); + int k = MathHelper.floor(z); + // CraftBukkit end int l = i; int i1 = j; int j1 = k; @@ -241,10 +350,10 @@ public class PortalTravelAgent { double d4; for (i2 = i - b0; i2 <= i + b0; ++i2) { - d1 = (double) i2 + 0.5D - entity.locX; + d1 = (double) i2 + 0.5D - x; // CraftBukkit for (j2 = k - b0; j2 <= k + b0; ++j2) { - d2 = (double) j2 + 0.5D - entity.locZ; + d2 = (double) j2 + 0.5D - z; // CraftBukkit label274: for (k2 = this.a.P() - 1; k2 >= 0; --k2) { @@ -275,7 +384,7 @@ public class PortalTravelAgent { } } - d3 = (double) k2 + 0.5D - entity.locY; + d3 = (double) k2 + 0.5D - y; // CraftBukkit d4 = d1 * d1 + d3 * d3 + d2 * d2; if (d0 < 0.0D || d4 < d0) { d0 = d4; @@ -292,10 +401,10 @@ public class PortalTravelAgent { if (d0 < 0.0D) { for (i2 = i - b0; i2 <= i + b0; ++i2) { - d1 = (double) i2 + 0.5D - entity.locX; + d1 = (double) i2 + 0.5D - x; // CraftBukkit for (j2 = k - b0; j2 <= k + b0; ++j2) { - d2 = (double) j2 + 0.5D - entity.locZ; + d2 = (double) j2 + 0.5D - z; // CraftBukkit label222: for (k2 = this.a.P() - 1; k2 >= 0; --k2) { @@ -319,7 +428,7 @@ public class PortalTravelAgent { } } - d3 = (double) k2 + 0.5D - entity.locY; + d3 = (double) k2 + 0.5D - y; // CraftBukkit d4 = d1 * d1 + d3 * d3 + d2 * d2; if (d0 < 0.0D || d4 < d0) { d0 = d4; diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java index b426d5d963..3f73ef9776 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java @@ -59,7 +59,7 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate this.M = new TreeSet(); } - this.P = new PortalTravelAgent(this); + this.P = new org.bukkit.craftbukkit.CraftTravelAgent(this); // CraftBukkit } // CraftBukkit start diff --git a/src/main/java/org/bukkit/craftbukkit/CraftTravelAgent.java b/src/main/java/org/bukkit/craftbukkit/CraftTravelAgent.java new file mode 100644 index 0000000000..b21714e5f2 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/CraftTravelAgent.java @@ -0,0 +1,74 @@ +package org.bukkit.craftbukkit; + +import net.minecraft.server.ChunkCoordinates; +import net.minecraft.server.PortalTravelAgent; +import net.minecraft.server.WorldServer; + +import org.bukkit.Location; +import org.bukkit.TravelAgent; + +public class CraftTravelAgent extends PortalTravelAgent implements TravelAgent { + + private int searchRadius = 128; + private int creationRadius = 16; + private boolean canCreatePortal = true; + + public CraftTravelAgent(WorldServer worldserver) { + super(worldserver); + } + + public Location findOrCreate(Location target) { + WorldServer worldServer = ((CraftWorld) target.getWorld()).getHandle(); + boolean before = worldServer.chunkProviderServer.forceChunkLoad; + worldServer.chunkProviderServer.forceChunkLoad = true; + + Location found = this.findPortal(target); + if (found == null) { + if (this.getCanCreatePortal() && this.createPortal(target)) { + found = this.findPortal(target); + } else { + found = target; // fallback to original if unable to find or create + } + } + + worldServer.chunkProviderServer.forceChunkLoad = before; + return found; + } + + public Location findPortal(Location location) { + PortalTravelAgent pta = ((CraftWorld) location.getWorld()).getHandle().s(); + ChunkCoordinates found = pta.findPortal(location.getX(), location.getY(), location.getZ(), this.getSearchRadius()); + return found != null ? new Location(location.getWorld(), found.x, found.y, found.z, location.getYaw(), location.getPitch()) : null; + } + + public boolean createPortal(Location location) { + PortalTravelAgent pta = ((CraftWorld) location.getWorld()).getHandle().s(); + return pta.createPortal(location.getX(), location.getY(), location.getZ(), this.getCreationRadius()); + } + + public TravelAgent setSearchRadius(int radius) { + this.searchRadius = radius; + return this; + } + + public int getSearchRadius() { + return this.searchRadius; + } + + public TravelAgent setCreationRadius(int radius) { + this.creationRadius = radius < 2 ? 0 : radius; + return this; + } + + public int getCreationRadius() { + return this.creationRadius; + } + + public boolean getCanCreatePortal() { + return this.canCreatePortal; + } + + public void setCanCreatePortal(boolean create) { + this.canCreatePortal = create; + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/PortalTravelAgent.java b/src/main/java/org/bukkit/craftbukkit/PortalTravelAgent.java deleted file mode 100644 index 8202371631..0000000000 --- a/src/main/java/org/bukkit/craftbukkit/PortalTravelAgent.java +++ /dev/null @@ -1,434 +0,0 @@ -package org.bukkit.craftbukkit; - -import java.util.Random; - -import net.minecraft.server.Block; -import net.minecraft.server.MathHelper; -import net.minecraft.server.WorldServer; - -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.TravelAgent; -import org.bukkit.World.Environment; -import org.bukkit.event.world.PortalCreateEvent; - -public class PortalTravelAgent implements TravelAgent { - - private Random random = new Random(); - - private int searchRadius = 128; - private int creationRadius = 14; // 16 -> 14 - private boolean canCreatePortal = true; - - public PortalTravelAgent() { } - - public Location findOrCreate(Location location) { - WorldServer worldServer = ((CraftWorld) location.getWorld()).getHandle(); - boolean wasEnabled = worldServer.chunkProviderServer.forceChunkLoad; - if (!wasEnabled) { - worldServer.chunkProviderServer.forceChunkLoad = true; - } - // Attempt to find a Portal. - Location resultLocation = this.findPortal(location); - // If a Portal cannot be found we will attempt to create one. - if (resultLocation == null) { - // Attempt to create a portal, return if it was successful or not. - if (this.canCreatePortal && this.createPortal(location)) { - // Now find that portals location. - resultLocation = this.findPortal(location); - } else { - // Fallback onto the original location. - resultLocation = location; - } - } - - if (!wasEnabled) { - worldServer.chunkProviderServer.forceChunkLoad = false; - } - // Return our resulting portal location. - return resultLocation; - } - - public Location findPortal(Location location) { - net.minecraft.server.World world = ((CraftWorld) location.getWorld()).getHandle(); - - if (location.getWorld().getEnvironment() == Environment.THE_END) { - int i = MathHelper.floor(location.getBlockX()); - int j = MathHelper.floor(location.getBlockY()) - 1; - int k = MathHelper.floor(location.getBlockZ()); - byte b0 = 1; - byte b1 = 0; - - for (int l = -2; l <= 2; ++l) { - for (int i1 = -2; i1 <= 2; ++i1) { - for (int j1 = -1; j1 < 3; ++j1) { - int k1 = i + i1 * b0 + l * b1; - int l1 = j + j1; - int i2 = k + i1 * b1 - l * b0; - boolean flag = j1 < 0; - - if (world.getTypeId(k1, l1, i2) != (flag ? Block.OBSIDIAN.id : 0)) { - return null; - } - } - } - } - - return location; - } - - // short short1 = 128; - double d0 = -1.0D; - int i = 0; - int j = 0; - int k = 0; - int l = location.getBlockX(); - int i1 = location.getBlockZ(); - - double d1; - - for (int j1 = l - this.searchRadius; j1 <= l + this.searchRadius; ++j1) { - double d2 = (double) j1 + 0.5D - location.getX(); - - for (int k1 = i1 - this.searchRadius; k1 <= i1 + this.searchRadius; ++k1) { - double d3 = (double) k1 + 0.5D - location.getZ(); - - for (int l1 = world.P() - 1; l1 >= 0; --l1) { - if (world.getTypeId(j1, l1, k1) == Block.PORTAL.id) { - while (world.getTypeId(j1, l1 - 1, k1) == Block.PORTAL.id) { - --l1; - } - - d1 = (double) l1 + 0.5D - location.getY(); - double d4 = d2 * d2 + d1 * d1 + d3 * d3; - - if (d0 < 0.0D || d4 < d0) { - d0 = d4; - i = j1; - j = l1; - k = k1; - } - } - } - } - } - - if (d0 >= 0.0D) { - double d5 = (double) i + 0.5D; - double d6 = (double) j + 0.5D; - - d1 = (double) k + 0.5D; - if (world.getTypeId(i - 1, j, k) == Block.PORTAL.id) { - d5 -= 0.5D; - } - - if (world.getTypeId(i + 1, j, k) == Block.PORTAL.id) { - d5 += 0.5D; - } - - if (world.getTypeId(i, j, k - 1) == Block.PORTAL.id) { - d1 -= 0.5D; - } - - if (world.getTypeId(i, j, k + 1) == Block.PORTAL.id) { - d1 += 0.5D; - } - - return new Location(location.getWorld(), d5, d6, d1, location.getYaw(), location.getPitch()); - } else { - return null; - } - } - - public boolean createPortal(Location location) { - net.minecraft.server.World world = ((CraftWorld) location.getWorld()).getHandle(); - - if (location.getWorld().getEnvironment() == Environment.THE_END) { - int i = MathHelper.floor(location.getBlockX()); - int j = MathHelper.floor(location.getBlockY()) - 1; - int k = MathHelper.floor(location.getBlockZ()); - byte b0 = 1; - byte b1 = 0; - - for (int l = -2; l <= 2; ++l) { - for (int i1 = -2; i1 <= 2; ++i1) { - for (int j1 = -1; j1 < 3; ++j1) { - int k1 = i + i1 * b0 + l * b1; - int l1 = j + j1; - int i2 = k + i1 * b1 - l * b0; - boolean flag = j1 < 0; - - world.setTypeId(k1, l1, i2, flag ? Block.OBSIDIAN.id : 0); - } - } - } - - return true; - } - - // byte b0 = 16; - double d0 = -1.0D; - int i = location.getBlockX(); - int j = location.getBlockY(); - int k = location.getBlockZ(); - int l = i; - int i1 = j; - int j1 = k; - int k1 = 0; - int l1 = this.random.nextInt(4); - - int i2; - double d1; - int j2; - double d2; - int k2; - int l2; - int i3; - int j3; - int k3; - int l3; - int i4; - int j4; - int k4; - double d3; - double d4; - - for (i2 = i - this.creationRadius; i2 <= i + this.creationRadius; ++i2) { - d1 = (double) i2 + 0.5D - location.getX(); - - for (j2 = k - this.creationRadius; j2 <= k + this.creationRadius; ++j2) { - d2 = (double) j2 + 0.5D - location.getZ(); - - label271: - for (l2 = world.P() - 1; l2 >= 0; --l2) { - if (world.isEmpty(i2, l2, j2)) { - while (l2 > 0 && world.isEmpty(i2, l2 - 1, j2)) { - --l2; - } - - for (k2 = l1; k2 < l1 + 4; ++k2) { - j3 = k2 % 2; - i3 = 1 - j3; - if (k2 % 4 >= 2) { - j3 = -j3; - i3 = -i3; - } - - for (l3 = 0; l3 < 3; ++l3) { - for (k3 = 0; k3 < 4; ++k3) { - for (j4 = -1; j4 < 5; ++j4) { - i4 = i2 + (k3 - 1) * j3 + l3 * i3; - k4 = l2 + j4; - int l4 = j2 + (k3 - 1) * i3 - l3 * j3; - - if (j4 < 0 && !world.getMaterial(i4, k4, l4).isBuildable() || j4 >= 0 && !world.isEmpty(i4, k4, l4)) { - continue label271; - } - } - } - } - - d3 = (double) l2 + 0.5D - location.getY(); - d4 = d1 * d1 + d3 * d3 + d2 * d2; - if (d0 < 0.0D || d4 < d0) { - d0 = d4; - l = i2; - i1 = l2 + 1; - j1 = j2; - k1 = k2 % 4; - } - } - } - } - } - } - - if (d0 < 0.0D) { - for (i2 = i - this.creationRadius; i2 <= i + this.creationRadius; ++i2) { - d1 = (double) i2 + 0.5D - location.getX(); - - for (j2 = k - this.creationRadius; j2 <= k + this.creationRadius; ++j2) { - d2 = (double) j2 + 0.5D - location.getZ(); - - label219: - for (l2 = world.P() - 1; l2 >= 0; --l2) { - if (world.isEmpty(i2, l2, j2)) { - while (l2 > 0 && world.isEmpty(i2, l2 - 1, j2)) { - --l2; - } - - for (k2 = l1; k2 < l1 + 2; ++k2) { - j3 = k2 % 2; - i3 = 1 - j3; - - for (l3 = 0; l3 < 4; ++l3) { - for (k3 = -1; k3 < 5; ++k3) { - j4 = i2 + (l3 - 1) * j3; - i4 = l2 + k3; - k4 = j2 + (l3 - 1) * i3; - if (k3 < 0 && !world.getMaterial(j4, i4, k4).isBuildable() || k3 >= 0 && !world.isEmpty(j4, i4, k4)) { - continue label219; - } - } - } - - d3 = (double) l2 + 0.5D - location.getY(); - d4 = d1 * d1 + d3 * d3 + d2 * d2; - if (d0 < 0.0D || d4 < d0) { - d0 = d4; - l = i2; - i1 = l2 + 1; - j1 = j2; - k1 = k2 % 2; - } - } - } - } - } - } - } - - int i5 = l; - int j5 = i1; - - j2 = j1; - int k5 = k1 % 2; - int l5 = 1 - k5; - - if (k1 % 4 >= 2) { - k5 = -k5; - l5 = -l5; - } - - boolean flag; - - // CraftBukkit start - portal create event - java.util.ArrayList blocks = new java.util.ArrayList(); - // Find out what blocks the portal is going to modify, duplicated from below - CraftWorld craftWorld = ((WorldServer) world).getWorld(); - - if (d0 < 0.0D) { - if (i1 < 70) { - i1 = 70; - } - - if (i1 > world.P() - 10) { - i1 = world.P() - 10; - } - - j5 = i1; - - for (l2 = -1; l2 <= 1; ++l2) { - for (k2 = 1; k2 < 3; ++k2) { - for (j3 = -1; j3 < 3; ++j3) { - i3 = i5 + (k2 - 1) * k5 + l2 * l5; - l3 = j5 + j3; - k3 = j2 + (k2 - 1) * l5 - l2 * k5; - org.bukkit.block.Block b = craftWorld.getBlockAt(i3, l3, k3); - if (!blocks.contains(b)) { - blocks.add(b); - } - } - } - } - } - - for (l2 = 0; l2 < 4; ++l2) { - for (k2 = 0; k2 < 4; ++k2) { - for (j3 = -1; j3 < 4; ++j3) { - i3 = i5 + (k2 - 1) * k5; - l3 = j5 + j3; - k3 = j2 + (k2 - 1) * l5; - org.bukkit.block.Block b = craftWorld.getBlockAt(i3, l3, k3); - if (!blocks.contains(b)) { - blocks.add(b); - } - } - } - } - - PortalCreateEvent event = new PortalCreateEvent(blocks, (org.bukkit.World) craftWorld, PortalCreateEvent.CreateReason.OBC_DESTINATION); - Bukkit.getServer().getPluginManager().callEvent(event); - if (event.isCancelled()) { - return false; - } - // CraftBukkit end - - if (d0 < 0.0D) { - if (i1 < 70) { - i1 = 70; - } - - if (i1 > 118) { - i1 = 118; - } - - j5 = i1; - - for (l2 = -1; l2 <= 1; ++l2) { - for (k2 = 1; k2 < 3; ++k2) { - for (j3 = -1; j3 < 3; ++j3) { - i3 = i5 + (k2 - 1) * k5 + l2 * l5; - l3 = j5 + j3; - k3 = j2 + (k2 - 1) * l5 - l2 * k5; - flag = j3 < 0; - world.setTypeId(i3, l3, k3, flag ? Block.OBSIDIAN.id : 0); - } - } - } - } - - for (l2 = 0; l2 < 4; ++l2) { - world.suppressPhysics = true; - - for (k2 = 0; k2 < 4; ++k2) { - for (j3 = -1; j3 < 4; ++j3) { - i3 = i5 + (k2 - 1) * k5; - l3 = j5 + j3; - k3 = j2 + (k2 - 1) * l5; - flag = k2 == 0 || k2 == 3 || j3 == -1 || j3 == 3; - world.setTypeId(i3, l3, k3, flag ? Block.OBSIDIAN.id : Block.PORTAL.id); - } - } - - world.suppressPhysics = false; - - for (k2 = 0; k2 < 4; ++k2) { - for (j3 = -1; j3 < 4; ++j3) { - i3 = i5 + (k2 - 1) * k5; - l3 = j5 + j3; - k3 = j2 + (k2 - 1) * l5; - world.applyPhysics(i3, l3, k3, world.getTypeId(i3, l3, k3)); - } - } - } - - return true; - } - - public TravelAgent setSearchRadius(int radius) { - this.searchRadius = radius; - return this; - } - - public int getSearchRadius() { - return this.searchRadius; - } - - public TravelAgent setCreationRadius(int radius) { - this.creationRadius = radius < 2 ? 0 : radius - 2; - return this; - } - - public int getCreationRadius() { - return this.creationRadius; - } - - public boolean getCanCreatePortal() { - return this.canCreatePortal; - } - - public void setCanCreatePortal(boolean create) { - this.canCreatePortal = create; - } -}