diff --git a/src/main/java/net/citizensnpcs/EventListen.java b/src/main/java/net/citizensnpcs/EventListen.java index a599886b2..1d8e92265 100644 --- a/src/main/java/net/citizensnpcs/EventListen.java +++ b/src/main/java/net/citizensnpcs/EventListen.java @@ -34,7 +34,6 @@ import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.Location; import org.bukkit.entity.EntityType; -import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -48,7 +47,6 @@ import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.event.entity.EntityTargetEvent; -import org.bukkit.event.entity.EntityTeleportEvent; import org.bukkit.event.player.PlayerChangedWorldEvent; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerQuitEvent; @@ -133,15 +131,6 @@ public class EventListen implements Listener { checkCreationEvent(event); } - @EventHandler(ignoreCancelled = true) - public void onEntityChangedWorld(EntityTeleportEvent event) { - if (event.getFrom() == null || event.getTo() == null) - return; - if (event.getFrom().getWorld() == event.getTo().getWorld() || !npcRegistry.isNPC(event.getEntity())) - return; - NMS.updateNavigationWorld((LivingEntity) event.getEntity(), event.getTo().getWorld()); - } - /* * Entity events */ diff --git a/src/main/java/net/citizensnpcs/commands/NPCCommands.java b/src/main/java/net/citizensnpcs/commands/NPCCommands.java index 8f0b9cd14..32b53e2cc 100644 --- a/src/main/java/net/citizensnpcs/commands/NPCCommands.java +++ b/src/main/java/net/citizensnpcs/commands/NPCCommands.java @@ -168,7 +168,7 @@ public class NPCCommands { Anchor anchor = trait.getAnchor(args.getFlag("assume")); if (anchor == null) throw new CommandException(Messages.ANCHOR_MISSING, args.getFlag("assume")); - npc.getBukkitEntity().teleport(anchor.getLocation()); + npc.teleport(anchor.getLocation(), TeleportCause.COMMAND); } else if (args.hasValueFlag("remove")) { if (args.getFlag("remove").isEmpty()) throw new CommandException(Messages.INVALID_ANCHOR_NAME); @@ -198,7 +198,7 @@ public class NPCCommands { return; if (sender instanceof ConsoleCommandSender) throw new ServerCommandException(); - npc.getBukkitEntity().teleport(args.getSenderLocation()); + npc.teleport(args.getSenderLocation(), TeleportCause.COMMAND); } @Command( @@ -244,7 +244,7 @@ public class NPCCommands { if (copy.isSpawned() && args.getSenderLocation() != null) { Location location = args.getSenderLocation(); location.getChunk().load(); - copy.getBukkitEntity().teleport(location); + copy.teleport(location, TeleportCause.COMMAND); copy.getTrait(CurrentLocation.class).setLocation(location); } @@ -676,7 +676,7 @@ public class NPCCommands { } } - npc.getBukkitEntity().teleport(to, TeleportCause.COMMAND); + npc.teleport(to, TeleportCause.COMMAND); Messaging.sendTr(sender, Messages.MOVETO_TELEPORTED, npc.getName(), to); } @@ -1195,7 +1195,7 @@ public class NPCCommands { npc.despawn(DespawnReason.REMOVAL); throw new CommandException(Messages.CANNOT_TELEPORT_ACROSS_WORLDS); } - npc.getBukkitEntity().teleport(args.getSenderLocation(), TeleportCause.COMMAND); + npc.teleport(args.getSenderLocation(), TeleportCause.COMMAND); } Messaging.sendTr(sender, Messages.NPC_TELEPORTED, npc.getName()); } diff --git a/src/main/java/net/citizensnpcs/npc/CitizensNPC.java b/src/main/java/net/citizensnpcs/npc/CitizensNPC.java index a3b8e1d44..31e0faeda 100644 --- a/src/main/java/net/citizensnpcs/npc/CitizensNPC.java +++ b/src/main/java/net/citizensnpcs/npc/CitizensNPC.java @@ -24,9 +24,11 @@ import net.minecraft.server.v1_6_R2.EntityLiving; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.craftbukkit.v1_6_R2.entity.CraftLivingEntity; +import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; +import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.metadata.FixedMetadataValue; import com.google.common.base.Preconditions; @@ -187,6 +189,35 @@ public class CitizensNPC extends AbstractNPC { return true; } + private void teleport(final Entity entity, Location location, boolean loaded, int delay) { + if (!loaded) + location.getBlock().getChunk(); + final Entity passenger = entity.getPassenger(); + entity.eject(); + entity.teleport(location); + if (passenger == null) + return; + teleport(passenger, location, true, delay++); + Runnable task = new Runnable() { + @Override + public void run() { + NMS.mount(entity, passenger); + } + }; + if (!location.getWorld().equals(entity.getWorld())) { + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), task, delay); + } else { + task.run(); + } + } + + @Override + public void teleport(Location location, TeleportCause cause) { + if (!this.isSpawned()) + return; + teleport(getBukkitEntity(), location, false, 5); + } + @Override public void update() { try { @@ -203,5 +234,4 @@ public class CitizensNPC extends AbstractNPC { } private static final String NPC_METADATA_MARKER = "NPC"; - } \ No newline at end of file diff --git a/src/main/java/net/citizensnpcs/npc/ai/CitizensNavigator.java b/src/main/java/net/citizensnpcs/npc/ai/CitizensNavigator.java index 361d1880e..124ef2d92 100644 --- a/src/main/java/net/citizensnpcs/npc/ai/CitizensNavigator.java +++ b/src/main/java/net/citizensnpcs/npc/ai/CitizensNavigator.java @@ -216,12 +216,14 @@ public class CitizensNavigator implements Navigator, Runnable { } private void switchStrategyTo(PathStrategy newStrategy) { - if (Messaging.isDebugging()) - Messaging.debug(npc.getId(), "changing to new PathStrategy", newStrategy); + Messaging.debug(npc.getId(), "changing to new PathStrategy", newStrategy); if (executing != null) Bukkit.getPluginManager().callEvent(new NavigationReplaceEvent(this)); executing = newStrategy; stationaryTicks = 0; + if (npc.isSpawned()) { + NMS.updateNavigationWorld(npc.getBukkitEntity(), npc.getBukkitEntity().getWorld()); + } Bukkit.getPluginManager().callEvent(new NavigationBeginEvent(this)); } diff --git a/src/main/java/net/citizensnpcs/util/NMS.java b/src/main/java/net/citizensnpcs/util/NMS.java index 59fb7b427..7c6ceda37 100644 --- a/src/main/java/net/citizensnpcs/util/NMS.java +++ b/src/main/java/net/citizensnpcs/util/NMS.java @@ -36,6 +36,7 @@ import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.craftbukkit.v1_6_R2.CraftServer; import org.bukkit.craftbukkit.v1_6_R2.CraftWorld; +import org.bukkit.craftbukkit.v1_6_R2.entity.CraftEntity; import org.bukkit.craftbukkit.v1_6_R2.entity.CraftLivingEntity; import org.bukkit.craftbukkit.v1_6_R2.entity.CraftPlayer; import org.bukkit.entity.EntityType; @@ -98,6 +99,10 @@ public class NMS { target.setOnFire(fireAspectLevel * 4); } + public static void changeWorlds(org.bukkit.entity.Entity entity, org.bukkit.World world) { + getHandle(entity).world = ((CraftWorld) world).getHandle(); + } + public static void clearGoals(PathfinderGoalSelector... goalSelectors) { if (GOAL_FIELD == null || goalSelectors == null) return; @@ -138,6 +143,10 @@ public class NMS { return ((CraftLivingEntity) entity).getHandle(); } + public static net.minecraft.server.v1_6_R2.Entity getHandle(org.bukkit.entity.Entity entity) { + return ((CraftEntity) entity).getHandle(); + } + public static float getHeadYaw(EntityLiving handle) { return handle.aP; } @@ -188,6 +197,10 @@ public class NMS { return npc == null ? baseSpeed : baseSpeed * npc.getNavigator().getLocalParameters().speedModifier(); } + public static void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) { + NMS.getHandle(passenger).mount(NMS.getHandle(entity)); + } + public static void registerEntityClass(Class clazz) { if (ENTITY_CLASS_TO_INT.containsKey(clazz)) return; @@ -399,7 +412,6 @@ public class NMS { } private static final float DEFAULT_SPEED = 1F; - private static Map, Integer> ENTITY_CLASS_TO_INT; private static final Map, Constructor> ENTITY_CONSTRUCTOR_CACHE = new WeakHashMap, Constructor>(); private static Map> ENTITY_INT_TO_CLASS;