diff --git a/src/main/java/net/citizensnpcs/Citizens.java b/src/main/java/net/citizensnpcs/Citizens.java index f9fb880eb..eeaece316 100644 --- a/src/main/java/net/citizensnpcs/Citizens.java +++ b/src/main/java/net/citizensnpcs/Citizens.java @@ -26,6 +26,7 @@ import net.citizensnpcs.api.command.Injector; import net.citizensnpcs.api.event.CitizensDisableEvent; import net.citizensnpcs.api.event.CitizensEnableEvent; +import net.citizensnpcs.api.event.CitizensPreReloadEvent; import net.citizensnpcs.api.event.CitizensReloadEvent; import net.citizensnpcs.api.event.DespawnReason; import net.citizensnpcs.api.exception.NPCLoadException; @@ -344,6 +345,8 @@ public void reload() throws NPCLoadException { despawnNPCs(); ProfileFetcher.reset(); Skin.clearCache(); + getServer().getPluginManager().callEvent(new CitizensPreReloadEvent()); + saves = createStorage(getDataFolder()); saves.loadInto(npcRegistry); diff --git a/src/main/java/net/citizensnpcs/EventListen.java b/src/main/java/net/citizensnpcs/EventListen.java index ff104f030..6284a06cc 100644 --- a/src/main/java/net/citizensnpcs/EventListen.java +++ b/src/main/java/net/citizensnpcs/EventListen.java @@ -59,7 +59,7 @@ import net.citizensnpcs.api.ai.event.NavigationBeginEvent; import net.citizensnpcs.api.ai.event.NavigationCompleteEvent; import net.citizensnpcs.api.event.CitizensDeserialiseMetaEvent; -import net.citizensnpcs.api.event.CitizensReloadEvent; +import net.citizensnpcs.api.event.CitizensPreReloadEvent; import net.citizensnpcs.api.event.CitizensSerialiseMetaEvent; import net.citizensnpcs.api.event.CommandSenderCreateNPCEvent; import net.citizensnpcs.api.event.DespawnReason; @@ -164,7 +164,7 @@ public void onChunkUnload(ChunkUnloadEvent event) { } @EventHandler(priority = EventPriority.MONITOR) - public void onCitizensReload(CitizensReloadEvent event) { + public void onCitizensReload(CitizensPreReloadEvent event) { skinUpdateTracker.reset(); toRespawn.clear(); } @@ -306,29 +306,29 @@ public void onMetaDeserialise(CitizensDeserialiseMetaEvent event) { @EventHandler public void onMetaSerialise(CitizensSerialiseMetaEvent event) { - if (event.getMeta() instanceof SkullMeta) { - SkullMeta meta = (SkullMeta) event.getMeta(); - GameProfile profile = NMS.getProfile(meta); - if (profile == null) - return; - if (profile.getName() != null) { - event.getKey().setString("skull.owner", profile.getName()); - } - if (profile.getId() != null) { - event.getKey().setString("skull.uuid", profile.getId().toString()); - } - if (profile.getProperties() != null) { - for (Entry> entry : profile.getProperties().asMap().entrySet()) { - DataKey relative = event.getKey().getRelative("skull.properties." + entry.getKey()); - int i = 0; - for (Property value : entry.getValue()) { - relative.getRelative(i).setString("name", value.getName()); - if (value.getSignature() != null) { - relative.getRelative(i).setString("signature", value.getSignature()); - } - relative.getRelative(i).setString("value", value.getValue()); - i++; + if (!(event.getMeta() instanceof SkullMeta)) + return; + SkullMeta meta = (SkullMeta) event.getMeta(); + GameProfile profile = NMS.getProfile(meta); + if (profile == null) + return; + if (profile.getName() != null) { + event.getKey().setString("skull.owner", profile.getName()); + } + if (profile.getId() != null) { + event.getKey().setString("skull.uuid", profile.getId().toString()); + } + if (profile.getProperties() != null) { + for (Entry> entry : profile.getProperties().asMap().entrySet()) { + DataKey relative = event.getKey().getRelative("skull.properties." + entry.getKey()); + int i = 0; + for (Property value : entry.getValue()) { + relative.getRelative(i).setString("name", value.getName()); + if (value.getSignature() != null) { + relative.getRelative(i).setString("signature", value.getSignature()); } + relative.getRelative(i).setString("value", value.getValue()); + i++; } } } @@ -349,6 +349,7 @@ public void onNeedsRespawn(NPCNeedsRespawnEvent event) { ChunkCoord coord = toCoord(event.getSpawnLocation()); if (toRespawn.containsEntry(coord, event.getNPC())) return; + Messaging.debug("Stored", event.getNPC().getId(), "for respawn from NPCNeedsRespawnEvent"); toRespawn.put(coord, event.getNPC()); } @@ -516,6 +517,7 @@ public void onWorldUnload(WorldUnloadEvent event) { respawnAllFromCoord(coord); } } + event.setCancelled(true); return; } if (npc.isSpawned()) { diff --git a/src/main/java/net/citizensnpcs/npc/CitizensNPC.java b/src/main/java/net/citizensnpcs/npc/CitizensNPC.java index 9c95ced48..bde88da67 100644 --- a/src/main/java/net/citizensnpcs/npc/CitizensNPC.java +++ b/src/main/java/net/citizensnpcs/npc/CitizensNPC.java @@ -79,7 +79,8 @@ public boolean despawn(DespawnReason reason) { Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) { getEntity().getLocation().getChunk(); - Messaging.debug("Couldn't despawn", getId(), "due to despawn event cancellation. Force loaded chunk."); + Messaging.debug("Couldn't despawn", getId(), "due to despawn event cancellation. Force loaded chunk.", + getEntity().isValid()); return false; } boolean keepSelected = getTrait(Spawned.class).shouldSpawn(); @@ -93,6 +94,7 @@ public boolean despawn(DespawnReason reason) { for (Trait trait : new ArrayList(traits.values())) { trait.onDespawn(); } + Messaging.debug("Despawned", getId(), "DespawnReason.", reason); entityController.remove(); return true; @@ -140,6 +142,9 @@ public void load(final DataKey root) { if (getTrait(Spawned.class).shouldSpawn() && spawnLocation.getLocation() != null) { spawn(spawnLocation.getLocation()); } + if (getTrait(Spawned.class).shouldSpawn() && spawnLocation.getLocation() == null) { + Messaging.debug("Tried to spawn", getId(), "on load but world was null"); + } navigator.load(root.getRelative("navigator")); } @@ -261,6 +266,7 @@ public boolean spawn(Location at) { NMS.replaceTrackerEntry(player); } } + Messaging.debug("Spawned", getId(), at, mcEntity.valid); return true; } diff --git a/src/main/java/net/citizensnpcs/npc/ai/MCNavigationStrategy.java b/src/main/java/net/citizensnpcs/npc/ai/MCNavigationStrategy.java index 9d40ec975..af8674a53 100644 --- a/src/main/java/net/citizensnpcs/npc/ai/MCNavigationStrategy.java +++ b/src/main/java/net/citizensnpcs/npc/ai/MCNavigationStrategy.java @@ -7,7 +7,9 @@ import net.citizensnpcs.api.ai.TargetType; import net.citizensnpcs.api.ai.event.CancelReason; import net.citizensnpcs.api.npc.NPC; +import net.citizensnpcs.api.util.Messaging; import net.citizensnpcs.util.NMS; +import net.minecraft.server.v1_10_R1.EntityHorse; import net.minecraft.server.v1_10_R1.EntityLiving; import net.minecraft.server.v1_10_R1.NavigationAbstract; @@ -29,7 +31,13 @@ public class MCNavigationStrategy extends AbstractPathStrategy { // navigation won't execute, and calling entity.move doesn't // entirely fix the problem. navigation = NMS.getNavigation(handle); + float oldWidth = handle.width; + if (handle instanceof EntityHorse) { + handle.width = Math.min(0.99f, oldWidth); + } navigation.a(dest.getX(), dest.getY(), dest.getZ(), parameters.speed()); + handle.width = oldWidth; // minecraft requires that an entity fit onto both blocks if width >= 1f, but we'd + // prefer to make it just fit on 1 so hack around it a bit. if (NMS.isNavigationFinished(navigation)) { setCancelReason(CancelReason.STUCK); } @@ -64,6 +72,7 @@ public boolean update() { if (getCancelReason() != null) return true; if (parameters.speed() != lastSpeed) { + Messaging.debug("Repathfinding " + ((NPCHolder) handle).getNPC().getId() + " due to speed change"); navigation.a(target.getX(), target.getY(), target.getZ(), parameters.speed()); lastSpeed = parameters.speed(); }