From 1fba0d9ff0af756048b51e70ff3a52a31762a67e Mon Sep 17 00:00:00 2001 From: MrMicky Date: Wed, 25 Apr 2018 14:17:52 +0200 Subject: [PATCH 1/8] Correct errors on world change --- .../jitse/npclib/listeners/ChunkListener.java | 6 ++++- .../npclib/listeners/PlayerListener.java | 23 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/net/jitse/npclib/listeners/ChunkListener.java b/src/net/jitse/npclib/listeners/ChunkListener.java index 8b82b2d..06ace8f 100644 --- a/src/net/jitse/npclib/listeners/ChunkListener.java +++ b/src/net/jitse/npclib/listeners/ChunkListener.java @@ -51,7 +51,7 @@ public class ChunkListener implements Listener { for (NPC npc : NPCManager.getAllNPCs()) { Chunk npcChunk = npc.getLocation().getChunk(); - if (chunk.getX() == npcChunk.getX() && chunk.getZ() == npcChunk.getZ()) { + if (chunk == npcChunk) { // Loaded chunk with NPC in it. Showing it to the players again. for (UUID uuid : npc.getShown()) { @@ -62,6 +62,10 @@ public class ChunkListener implements Listener { Player player = Bukkit.getPlayer(uuid); + if (npcChunk.getWorld() != player.getWorld()) { + continue; // Player and NPC are not in the same world + } + double hideDistance = npc.getAutoHideDistance(); double distanceSquared = player.getLocation().distanceSquared(npc.getLocation()); boolean inRange = distanceSquared <= (hideDistance * hideDistance) || distanceSquared <= (Bukkit.getViewDistance() << 4); diff --git a/src/net/jitse/npclib/listeners/PlayerListener.java b/src/net/jitse/npclib/listeners/PlayerListener.java index 29e9f15..48da8e2 100644 --- a/src/net/jitse/npclib/listeners/PlayerListener.java +++ b/src/net/jitse/npclib/listeners/PlayerListener.java @@ -8,9 +8,11 @@ import net.jitse.npclib.NPCManager; import net.jitse.npclib.api.NPC; import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerChangedWorldEvent; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerTeleportEvent; @@ -34,6 +36,22 @@ public class PlayerListener implements Listener { } } + @EventHandler + public void onPlayerChangedWorld(PlayerChangedWorldEvent event) { + Player player = event.getPlayer(); + World from = event.getFrom(); + + // The PlayerTeleportEvent is call, and will handle visiiblity in the new world + for (NPC npc : NPCManager.getAllNPCs()) { + if (npc.getLocation().getWorld() == from) { + if (!npc.getAutoHidden().contains(player.getUniqueId())) { + npc.getAutoHidden().add(player.getUniqueId()); + npc.hide(player, true); + } + } + } + } + @EventHandler public void onPlayerMove(PlayerMoveEvent event) { Location from = event.getFrom(); @@ -52,11 +70,16 @@ public class PlayerListener implements Listener { } private void handleMove(Player player) { + World world = player.getWorld(); for (NPC npc : NPCManager.getAllNPCs()) { if (!npc.getShown().contains(player.getUniqueId())) { continue; // NPC was never supposed to be shown to the player. } + if (npc.getLocation().getWorld() != world) { + continue; // NPC is not in the same world + } + // If Bukkit doesn't track the NPC entity anymore, bypass the hiding distance variable. // This will cause issues otherwise (e.g. custom skin disappearing). double hideDistance = npc.getAutoHideDistance(); From 2d3f6e46a3e39e2f7cc3a9d9b26cc4e54c47ac2b Mon Sep 17 00:00:00 2001 From: MrMicky Date: Wed, 25 Apr 2018 14:38:50 +0200 Subject: [PATCH 2/8] Fix errors on world change --- src/net/jitse/npclib/api/NPC.java | 2 +- src/net/jitse/npclib/listeners/PlayerListener.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/net/jitse/npclib/api/NPC.java b/src/net/jitse/npclib/api/NPC.java index 8553e31..8a2bc23 100644 --- a/src/net/jitse/npclib/api/NPC.java +++ b/src/net/jitse/npclib/api/NPC.java @@ -150,7 +150,7 @@ public abstract class NPC { shown.remove(player.getUniqueId()); - if (player.getLocation().distance(location) <= autoHideDistance) { + if (player.getWorld() == location.getWorld() && player.getLocation().distance(location) <= autoHideDistance) { sendHidePackets(player); } else { if (autoHidden.contains(player.getUniqueId())) { diff --git a/src/net/jitse/npclib/listeners/PlayerListener.java b/src/net/jitse/npclib/listeners/PlayerListener.java index 48da8e2..9d2ae3a 100644 --- a/src/net/jitse/npclib/listeners/PlayerListener.java +++ b/src/net/jitse/npclib/listeners/PlayerListener.java @@ -30,8 +30,8 @@ public class PlayerListener implements Listener { npc.getAutoHidden().remove(player.getUniqueId()); } - if (npc.isActuallyShown(player)) { - npc.hide(player); + if (npc.getShown().contains(player.getUniqueId())) { + npc.getShown().remove(player.getUniqueId()); } } } From 41821c8783003e06b38e40e89602e1dac2b74f4a Mon Sep 17 00:00:00 2001 From: MrMicky Date: Wed, 25 Apr 2018 14:41:24 +0200 Subject: [PATCH 3/8] Fix armor stands spawn in nether and end + Reflection --- .../jitse/npclib/nms/holograms/Hologram.java | 104 +++++++++--------- 1 file changed, 55 insertions(+), 49 deletions(-) diff --git a/src/net/jitse/npclib/nms/holograms/Hologram.java b/src/net/jitse/npclib/nms/holograms/Hologram.java index 20c18cb..6512eb5 100644 --- a/src/net/jitse/npclib/nms/holograms/Hologram.java +++ b/src/net/jitse/npclib/nms/holograms/Hologram.java @@ -6,6 +6,7 @@ package net.jitse.npclib.nms.holograms; import com.comphenix.tinyprotocol.Reflection; import org.bukkit.Location; +import org.bukkit.World; import org.bukkit.entity.Player; import java.util.ArrayList; @@ -25,49 +26,49 @@ public class Hologram { private Set destroyPackets = new HashSet<>(); // Classes: - private final Class entityArmorStandClazz = Reflection.getMinecraftClass("EntityArmorStand"); - private final Class entityLivingClazz = Reflection.getMinecraftClass("EntityLiving"); - private final Class entityClazz = Reflection.getMinecraftClass("Entity"); - private final Class craftWorldClazz = Reflection.getCraftBukkitClass("CraftWorld"); - private final Class craftPlayerClazz = Reflection.getCraftBukkitClass("entity.CraftPlayer"); - private final Class packetPlayOutSpawnEntityLivingClazz = Reflection.getMinecraftClass( + private static final Class ENTITY_ARMOR_STAND_CLAZZ = Reflection.getMinecraftClass("EntityArmorStand"); + private static final Class ENTITY_LIVING_CLAZZ = Reflection.getMinecraftClass("EntityLiving"); + private static final Class ENTITY_CLAZZ = Reflection.getMinecraftClass("Entity"); + private static final Class CRAFT_BUKKIT_CLASS = Reflection.getCraftBukkitClass("CraftWorld"); + private static final Class CRAFT_PLAYER_CLAZZ = Reflection.getCraftBukkitClass("entity.CraftPlayer"); + private static final Class PACKET_PLAY_OUT_SPAWN_ENTITY_LIVING_CLAZZ = Reflection.getMinecraftClass( "PacketPlayOutSpawnEntityLiving"); - private final Class packetPlayOutEntityDestroyClazz = Reflection.getMinecraftClass( + private static final Class PACKET_PLAY_OUT_ENTITY_DESTROY_CLAZZ = Reflection.getMinecraftClass( "PacketPlayOutEntityDestroy"); - private final Class entityPlayerClazz = Reflection.getMinecraftClass("EntityPlayer"); - private final Class playerConnectionClazz = Reflection.getMinecraftClass("PlayerConnection"); - private final Class packetClazz = Reflection.getMinecraftClass("Packet"); + private static final Class ENTITY_PLAYER_CLAZZ = Reflection.getMinecraftClass("EntityPlayer"); + private static final Class PLAYER_CONNECTION_CLAZZ = Reflection.getMinecraftClass("PlayerConnection"); + private static final Class PACKET_CLAZZ = Reflection.getMinecraftClass("Packet"); // Constructors: - private final Reflection.ConstructorInvoker packetPlayOutSpawnEntityLivingConstructor = Reflection - .getConstructor(packetPlayOutSpawnEntityLivingClazz, entityLivingClazz); - private final Reflection.ConstructorInvoker packetPlayOutEntityDestroyConstructor = Reflection - .getConstructor(packetPlayOutEntityDestroyClazz, int[].class); + private static final Reflection.ConstructorInvoker PACKET_PLAY_OUT_SPAWN_ENTITY_LIVING_CONSTRUCTOR = Reflection + .getConstructor(PACKET_PLAY_OUT_SPAWN_ENTITY_LIVING_CLAZZ, ENTITY_LIVING_CLAZZ); + private static final Reflection.ConstructorInvoker PACKET_PLAY_OUT_ENTITY_DESTROY_CONSTRUCTOR = Reflection + .getConstructor(PACKET_PLAY_OUT_ENTITY_DESTROY_CLAZZ, int[].class); // Fields: - private final Reflection.FieldAccessor playerConnectionField = Reflection.getField(entityPlayerClazz, - "playerConnection", playerConnectionClazz); + private static final Reflection.FieldAccessor playerConnectionField = Reflection.getField(ENTITY_PLAYER_CLAZZ, + "playerConnection", PLAYER_CONNECTION_CLAZZ); // Methods: - private final Reflection.MethodInvoker setLocationMethod = Reflection.getMethod(entityArmorStandClazz, + private static final Reflection.MethodInvoker SET_LOCATION_METHOD = Reflection.getMethod(ENTITY_ARMOR_STAND_CLAZZ, "setLocation", double.class, double.class, double.class, float.class, float.class); - private final Reflection.MethodInvoker setCustomNameMethod = Reflection.getMethod(entityArmorStandClazz, + private static final Reflection.MethodInvoker SET_CUSTOM_NAME_METHOD = Reflection.getMethod(ENTITY_ARMOR_STAND_CLAZZ, "setCustomName", String.class); - private final Reflection.MethodInvoker setCustomNameVisibleMethod = Reflection.getMethod(entityArmorStandClazz, + private static final Reflection.MethodInvoker SET_CUSTOM_NAME_VISIBLE_METHOD = Reflection.getMethod(ENTITY_ARMOR_STAND_CLAZZ, "setCustomNameVisible", boolean.class); - private final Reflection.MethodInvoker setSmallMethod = Reflection.getMethod(entityArmorStandClazz, + private static final Reflection.MethodInvoker SET_SMALL_METHOD = Reflection.getMethod(ENTITY_ARMOR_STAND_CLAZZ, "setSmall", boolean.class); - private final Reflection.MethodInvoker setInvisibleMethod = Reflection.getMethod(entityArmorStandClazz, + private static final Reflection.MethodInvoker SET_INVISIBLE_METHOD = Reflection.getMethod(ENTITY_ARMOR_STAND_CLAZZ, "setInvisible", boolean.class); - private final Reflection.MethodInvoker setBasePlateMethod = Reflection.getMethod(entityArmorStandClazz, + private static final Reflection.MethodInvoker SET_BASE_PLATE_METHOD = Reflection.getMethod(ENTITY_ARMOR_STAND_CLAZZ, "setBasePlate", boolean.class); - private final Reflection.MethodInvoker setArmsMethod = Reflection.getMethod(entityArmorStandClazz, + private static final Reflection.MethodInvoker SET_ARMS_METHOD = Reflection.getMethod(ENTITY_ARMOR_STAND_CLAZZ, "setArms", boolean.class); - private final Reflection.MethodInvoker playerGetHandleMethod = Reflection.getMethod(craftPlayerClazz, + private static final Reflection.MethodInvoker PLAYER_GET_HANDLE_METHOD = Reflection.getMethod(CRAFT_PLAYER_CLAZZ, "getHandle"); - private final Reflection.MethodInvoker sendPacketMethod = Reflection.getMethod(playerConnectionClazz, - "sendPacket", packetClazz); - private final Reflection.MethodInvoker getIdMethod = Reflection.getMethod(entityArmorStandClazz, + private static final Reflection.MethodInvoker SEND_PACKET_METHOD = Reflection.getMethod(PLAYER_CONNECTION_CLAZZ, + "sendPacket", PACKET_CLAZZ); + private static final Reflection.MethodInvoker GET_ID_METHOD = Reflection.getMethod(ENTITY_ARMOR_STAND_CLAZZ, "getId"); private final Location start; @@ -78,32 +79,37 @@ public class Hologram { this.start = location; this.lines = lines; - this.worldServer = Reflection.getMethod(craftWorldClazz, "getHandle") - .invoke(craftWorldClazz.cast(location.getWorld())); + this.worldServer = Reflection.getMethod(CRAFT_BUKKIT_CLASS, "getHandle") + .invoke(CRAFT_BUKKIT_CLASS.cast(location.getWorld())); } public void generatePackets(boolean above1_9_r2) { - Reflection.MethodInvoker gravityMethod = (above1_9_r2 ? Reflection.getMethod(entityClazz, - "setNoGravity", boolean.class) : Reflection.getMethod(entityArmorStandClazz, + Reflection.MethodInvoker gravityMethod = (above1_9_r2 ? Reflection.getMethod(ENTITY_CLAZZ, + "setNoGravity", boolean.class) : Reflection.getMethod(ENTITY_ARMOR_STAND_CLAZZ, "setGravity", boolean.class)); Location location = start.clone().add(0, delta * lines.size(), 0); + Class worldClass = worldServer.getClass().getSuperclass(); + + if (start.getWorld().getEnvironment() != World.Environment.NORMAL) { + worldClass = worldClass.getSuperclass(); + } Reflection.ConstructorInvoker entityArmorStandConstructor = Reflection - .getConstructor(entityArmorStandClazz, worldServer.getClass().getSuperclass()); + .getConstructor(ENTITY_ARMOR_STAND_CLAZZ, worldClass); for (String line : lines) { Object entityArmorStand = entityArmorStandConstructor.invoke(worldServer); - setLocationMethod.invoke(entityArmorStand, location.getX(), location.getY(), location.getZ(), 0, 0); - setCustomNameMethod.invoke(entityArmorStand, line); - setCustomNameVisibleMethod.invoke(entityArmorStand, true); - gravityMethod.invoke(entityArmorStand, (above1_9_r2 ? true : false)); - setSmallMethod.invoke(entityArmorStand, true); - setInvisibleMethod.invoke(entityArmorStand, true); - setBasePlateMethod.invoke(entityArmorStand, false); - setArmsMethod.invoke(entityArmorStand, false); + SET_LOCATION_METHOD.invoke(entityArmorStand, location.getX(), location.getY(), location.getZ(), 0, 0); + SET_CUSTOM_NAME_METHOD.invoke(entityArmorStand, line); + SET_CUSTOM_NAME_VISIBLE_METHOD.invoke(entityArmorStand, true); + gravityMethod.invoke(entityArmorStand, above1_9_r2); + SET_SMALL_METHOD.invoke(entityArmorStand, true); + SET_INVISIBLE_METHOD.invoke(entityArmorStand, true); + SET_BASE_PLATE_METHOD.invoke(entityArmorStand, false); + SET_ARMS_METHOD.invoke(entityArmorStand, false); location.subtract(0, delta, 0); @@ -113,30 +119,30 @@ public class Hologram { armorStands.add(entityArmorStand); - Object spawnPacket = packetPlayOutSpawnEntityLivingConstructor.invoke(entityArmorStand); + Object spawnPacket = PACKET_PLAY_OUT_SPAWN_ENTITY_LIVING_CONSTRUCTOR.invoke(entityArmorStand); spawnPackets.add(spawnPacket); - Object destroyPacket = packetPlayOutEntityDestroyConstructor - .invoke(new int[]{(int) getIdMethod.invoke(entityArmorStand)}); + Object destroyPacket = PACKET_PLAY_OUT_ENTITY_DESTROY_CONSTRUCTOR + .invoke(new int[]{(int) GET_ID_METHOD.invoke(entityArmorStand)}); destroyPackets.add(destroyPacket); } } public void spawn(Player player) { - Object playerConnection = playerConnectionField.get(playerGetHandleMethod - .invoke(craftPlayerClazz.cast(player))); + Object playerConnection = playerConnectionField.get(PLAYER_GET_HANDLE_METHOD + .invoke(CRAFT_PLAYER_CLAZZ.cast(player))); for (Object packet : spawnPackets) { - sendPacketMethod.invoke(playerConnection, packet); + SEND_PACKET_METHOD.invoke(playerConnection, packet); } } public void destroy(Player player) { - Object playerConnection = playerConnectionField.get(playerGetHandleMethod - .invoke(craftPlayerClazz.cast(player))); + Object playerConnection = playerConnectionField.get(PLAYER_GET_HANDLE_METHOD + .invoke(CRAFT_PLAYER_CLAZZ.cast(player))); for (Object packet : destroyPackets) { - sendPacketMethod.invoke(playerConnection, packet); + SEND_PACKET_METHOD.invoke(playerConnection, packet); } } } From c51f5228748a9088668d4e456d984d21ee0f4fb3 Mon Sep 17 00:00:00 2001 From: JitseB Date: Wed, 25 Apr 2018 15:32:00 +0200 Subject: [PATCH 4/8] Punctuation and spelling fix. --- src/net/jitse/npclib/listeners/ChunkListener.java | 2 +- src/net/jitse/npclib/listeners/PlayerListener.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/net/jitse/npclib/listeners/ChunkListener.java b/src/net/jitse/npclib/listeners/ChunkListener.java index 06ace8f..f3bc724 100644 --- a/src/net/jitse/npclib/listeners/ChunkListener.java +++ b/src/net/jitse/npclib/listeners/ChunkListener.java @@ -63,7 +63,7 @@ public class ChunkListener implements Listener { Player player = Bukkit.getPlayer(uuid); if (npcChunk.getWorld() != player.getWorld()) { - continue; // Player and NPC are not in the same world + continue; // Player and NPC are not in the same world. } double hideDistance = npc.getAutoHideDistance(); diff --git a/src/net/jitse/npclib/listeners/PlayerListener.java b/src/net/jitse/npclib/listeners/PlayerListener.java index 9d2ae3a..5e7f7d7 100644 --- a/src/net/jitse/npclib/listeners/PlayerListener.java +++ b/src/net/jitse/npclib/listeners/PlayerListener.java @@ -30,6 +30,7 @@ public class PlayerListener implements Listener { npc.getAutoHidden().remove(player.getUniqueId()); } + // Don't need to use NPC#hide since the entity is not registered in the NMS server. if (npc.getShown().contains(player.getUniqueId())) { npc.getShown().remove(player.getUniqueId()); } @@ -41,7 +42,7 @@ public class PlayerListener implements Listener { Player player = event.getPlayer(); World from = event.getFrom(); - // The PlayerTeleportEvent is call, and will handle visiiblity in the new world + // The PlayerTeleportEvent is call, and will handle visibility in the new world. for (NPC npc : NPCManager.getAllNPCs()) { if (npc.getLocation().getWorld() == from) { if (!npc.getAutoHidden().contains(player.getUniqueId())) { From 5f9467e265c2741320f4bc75c6d47277fdb0f50d Mon Sep 17 00:00:00 2001 From: JitseB Date: Wed, 25 Apr 2018 15:37:56 +0200 Subject: [PATCH 5/8] Refactored chunk object comparison. Object#equals checks values inside the object. == only returns true if they refer to the same object. --- src/net/jitse/npclib/listeners/ChunkListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/net/jitse/npclib/listeners/ChunkListener.java b/src/net/jitse/npclib/listeners/ChunkListener.java index f3bc724..2bb3e04 100644 --- a/src/net/jitse/npclib/listeners/ChunkListener.java +++ b/src/net/jitse/npclib/listeners/ChunkListener.java @@ -51,7 +51,7 @@ public class ChunkListener implements Listener { for (NPC npc : NPCManager.getAllNPCs()) { Chunk npcChunk = npc.getLocation().getChunk(); - if (chunk == npcChunk) { + if (chunk.equals(npcChunk)) { // Loaded chunk with NPC in it. Showing it to the players again. for (UUID uuid : npc.getShown()) { From 612c48496204af658aa0217b7ccdec49e92b1e01 Mon Sep 17 00:00:00 2001 From: JitseB Date: Wed, 25 Apr 2018 15:39:33 +0200 Subject: [PATCH 6/8] Changed world object comparison from == to equals. --- src/net/jitse/npclib/listeners/PlayerListener.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/net/jitse/npclib/listeners/PlayerListener.java b/src/net/jitse/npclib/listeners/PlayerListener.java index 5e7f7d7..3b7228b 100644 --- a/src/net/jitse/npclib/listeners/PlayerListener.java +++ b/src/net/jitse/npclib/listeners/PlayerListener.java @@ -44,7 +44,7 @@ public class PlayerListener implements Listener { // The PlayerTeleportEvent is call, and will handle visibility in the new world. for (NPC npc : NPCManager.getAllNPCs()) { - if (npc.getLocation().getWorld() == from) { + if (npc.getLocation().getWorld().equals(from)) { if (!npc.getAutoHidden().contains(player.getUniqueId())) { npc.getAutoHidden().add(player.getUniqueId()); npc.hide(player, true); @@ -77,7 +77,7 @@ public class PlayerListener implements Listener { continue; // NPC was never supposed to be shown to the player. } - if (npc.getLocation().getWorld() != world) { + if (!npc.getLocation().getWorld().equals(world)) { continue; // NPC is not in the same world } From 44b066ae3d7f7e47cfa77d14dff2023ea3cf7af6 Mon Sep 17 00:00:00 2001 From: JitseB Date: Wed, 25 Apr 2018 15:39:47 +0200 Subject: [PATCH 7/8] Puctuation change. --- src/net/jitse/npclib/listeners/PlayerListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/net/jitse/npclib/listeners/PlayerListener.java b/src/net/jitse/npclib/listeners/PlayerListener.java index 3b7228b..cff5a98 100644 --- a/src/net/jitse/npclib/listeners/PlayerListener.java +++ b/src/net/jitse/npclib/listeners/PlayerListener.java @@ -78,7 +78,7 @@ public class PlayerListener implements Listener { } if (!npc.getLocation().getWorld().equals(world)) { - continue; // NPC is not in the same world + continue; // NPC is not in the same world. } // If Bukkit doesn't track the NPC entity anymore, bypass the hiding distance variable. From 9c392e70df512e64de2234ebb8a3d9a1f15a7890 Mon Sep 17 00:00:00 2001 From: JitseB Date: Wed, 25 Apr 2018 15:42:57 +0200 Subject: [PATCH 8/8] Few more comparison changes. --- src/net/jitse/npclib/api/NPC.java | 2 +- src/net/jitse/npclib/listeners/ChunkListener.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/net/jitse/npclib/api/NPC.java b/src/net/jitse/npclib/api/NPC.java index 8a2bc23..ca7b90b 100644 --- a/src/net/jitse/npclib/api/NPC.java +++ b/src/net/jitse/npclib/api/NPC.java @@ -150,7 +150,7 @@ public abstract class NPC { shown.remove(player.getUniqueId()); - if (player.getWorld() == location.getWorld() && player.getLocation().distance(location) <= autoHideDistance) { + if (player.getWorld().equals(location.getWorld()) && player.getLocation().distance(location) <= autoHideDistance) { sendHidePackets(player); } else { if (autoHidden.contains(player.getUniqueId())) { diff --git a/src/net/jitse/npclib/listeners/ChunkListener.java b/src/net/jitse/npclib/listeners/ChunkListener.java index 2bb3e04..4094128 100644 --- a/src/net/jitse/npclib/listeners/ChunkListener.java +++ b/src/net/jitse/npclib/listeners/ChunkListener.java @@ -28,7 +28,7 @@ public class ChunkListener implements Listener { for (NPC npc : NPCManager.getAllNPCs()) { Chunk npcChunk = npc.getLocation().getChunk(); - if (chunk.getX() == npcChunk.getX() && chunk.getZ() == npcChunk.getZ()) { + if (chunk.equals(npcChunk)) { // Unloaded chunk with NPC in it. Hiding it from all players currently shown to. for (UUID uuid : npc.getShown()) { @@ -62,7 +62,7 @@ public class ChunkListener implements Listener { Player player = Bukkit.getPlayer(uuid); - if (npcChunk.getWorld() != player.getWorld()) { + if (!npcChunk.getWorld().equals(player.getWorld())) { continue; // Player and NPC are not in the same world. }