diff --git a/src/main/java/net/citizensnpcs/api/npc/AbstractNPC.java b/src/main/java/net/citizensnpcs/api/npc/AbstractNPC.java index 349a8cfd..a602b4d0 100644 --- a/src/main/java/net/citizensnpcs/api/npc/AbstractNPC.java +++ b/src/main/java/net/citizensnpcs/api/npc/AbstractNPC.java @@ -30,6 +30,7 @@ import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.metadata.FixedMetadataValue; import com.google.common.base.Function; @@ -177,6 +178,16 @@ public boolean equals(Object obj) { return true; } + @Override + @Deprecated + public LivingEntity getBukkitEntity() { + Entity entity = getEntity(); + if (entity == null || entity instanceof LivingEntity) { + return (LivingEntity) entity; + } + throw new IllegalStateException("getBukkitEntity() called on a non-living NPC"); + } + @Override public GoalController getDefaultGoalController() { return goalController; @@ -187,8 +198,9 @@ public SpeechController getDefaultSpeechController() { // TODO: Remove in future versions. // This is here to add the Speech trait to any existing NPCs // that were created pre-SpeechController, if invoked. - if (!hasTrait(Speech.class)) + if (!hasTrait(Speech.class)) { addTrait(Speech.class); + } return speechController; } @@ -211,6 +223,11 @@ public String getName() { return parsed; } + @Override + public NPCRegistry getOwningRegistry() { + return registry; + } + @Override public T getTrait(Class clazz) { Trait trait = traits.get(clazz); @@ -241,11 +258,21 @@ public boolean hasTrait(Class trait) { return traits.containsKey(trait); } + @Override + public boolean isFlyable() { + return data().get(NPC.FLYABLE_METADATA, false); + } + @Override public boolean isProtected() { return data().get(NPC.DEFAULT_PROTECTED_METADATA, true); } + @Override + public boolean isSpawned() { + return getEntity() != null; + } + @Override public void load(final DataKey root) { metadata.loadFrom(root.getRelative("metadata")); @@ -328,6 +355,11 @@ public void save(DataKey root) { removedTraits.clear(); } + @Override + public void setFlyable(boolean flyable) { + data().setPersistent(NPC.FLYABLE_METADATA, flyable); + } + @Override public void setName(String name) { this.name = name; @@ -349,6 +381,39 @@ public void setProtected(boolean isProtected) { data().setPersistent(NPC.DEFAULT_PROTECTED_METADATA, isProtected); } + 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() { + entity.setPassenger(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 (!isSpawned()) + return; + Entity entity = getEntity(); + while (entity.getVehicle() != null) { + entity = entity.getVehicle(); + } + teleport(entity, location, false, 5); + } + public void update() { for (int i = 0; i < runnables.size(); ++i) { runnables.get(i).run(); diff --git a/src/main/java/net/citizensnpcs/api/npc/NPC.java b/src/main/java/net/citizensnpcs/api/npc/NPC.java index 25bbd8d0..f28b0c84 100644 --- a/src/main/java/net/citizensnpcs/api/npc/NPC.java +++ b/src/main/java/net/citizensnpcs/api/npc/NPC.java @@ -138,6 +138,8 @@ public interface NPC extends Agent, Cloneable { */ public Navigator getNavigator(); + public NPCRegistry getOwningRegistry(); + /** * If the NPC is not spawned, then this method will return the last known * location, or null if it has never been spawned. Otherwise, it is diff --git a/src/main/java/net/citizensnpcs/api/npc/NPCRegistry.java b/src/main/java/net/citizensnpcs/api/npc/NPCRegistry.java index 81b856c7..a207c727 100644 --- a/src/main/java/net/citizensnpcs/api/npc/NPCRegistry.java +++ b/src/main/java/net/citizensnpcs/api/npc/NPCRegistry.java @@ -73,4 +73,11 @@ public interface NPCRegistry extends Iterable { * @return Whether the given entity is an NPC */ public boolean isNPC(Entity entity); + + /** + * Returns a sorted view of this registry, sorted by NPC id. + * + * @return A sorted view of the registry + */ + Iterable sorted(); } \ No newline at end of file