diff --git a/src/main/java/net/citizensnpcs/EventListen.java b/src/main/java/net/citizensnpcs/EventListen.java index d20e7b018..340a861f7 100644 --- a/src/main/java/net/citizensnpcs/EventListen.java +++ b/src/main/java/net/citizensnpcs/EventListen.java @@ -29,8 +29,7 @@ import net.citizensnpcs.trait.Controllable; import net.citizensnpcs.trait.CurrentLocation; import net.citizensnpcs.util.Messages; import net.citizensnpcs.util.NMS; -import net.minecraft.server.v1_8_R1.EnumPlayerInfoAction; -import net.minecraft.server.v1_8_R1.PacketPlayOutPlayerInfo; +import net.minecraft.server.v1_8_R1.*; import org.bukkit.Bukkit; import org.bukkit.Chunk; @@ -50,10 +49,7 @@ 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.player.PlayerChangedWorldEvent; -import org.bukkit.event.player.PlayerInteractEntityEvent; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.*; import org.bukkit.event.vehicle.VehicleEnterEvent; import org.bukkit.event.world.ChunkLoadEvent; import org.bukkit.event.world.ChunkUnloadEvent; @@ -277,13 +273,55 @@ public class EventListen implements Listener { } @EventHandler(ignoreCancelled = true) - public void onPlayerJoin(PlayerJoinEvent event) { + public void onPlayerJoin(final PlayerJoinEvent event) { for (NPC npc : getAllNPCs()) { if (npc.isSpawned() && npc.getEntity().getType() == EntityType.PLAYER) { - NMS.sendToOnline(new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.ADD_PLAYER, ((CraftPlayer) npc + ((CraftPlayer)event.getPlayer()).getHandle().playerConnection.sendPacket( + new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.ADD_PLAYER, ((CraftPlayer) npc .getEntity()).getHandle())); } } + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() { + @Override + public void run() { + for (NPC npc : getAllNPCs()) { + if (npc.isSpawned() && npc.getEntity().getType() == EntityType.PLAYER) { + ((CraftPlayer)event.getPlayer()).getHandle().playerConnection.sendPacket( + new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.REMOVE_PLAYER, ((CraftPlayer) npc + .getEntity()).getHandle())); + } + } + } + }, 60); + } + + @EventHandler + public void onPlayerWalks(final PlayerMoveEvent event) { + if (event.getFrom().getY() > 255 || event.getFrom().getY() < 0 + || event.getTo().getY() > 255 || event.getTo().getY() < 0) { + return; // Don't fire if players go outside the world, as that would be more difficult to handle. + } + Location from = event.getFrom().getBlock().getLocation(); + Location to = event.getTo().getBlock().getLocation(); + if (from.equals(to)) { + return; // Don't fire on every movement, just full block+. + } + int maxRad = 50 * 50; // TODO: Adjust me to perfection + for (final NPC npc: getAllNPCs()) { + if (npc.isSpawned() && npc.getEntity().getType() == EntityType.PLAYER) { + if (npc.getEntity().getLocation().distanceSquared(to) < maxRad && + npc.getEntity().getLocation().distanceSquared(from) > maxRad) { + // TODO: Replicate this with packets! + npc.despawn(); + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() { + @Override + public void run() { + npc.spawn(npc.getStoredLocation()); + } + }, 1); + } + } + } } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) diff --git a/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java b/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java index 91c31cc2c..5b3eed33d 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java @@ -35,7 +35,6 @@ import net.minecraft.server.v1_8_R1.NetworkManager; import net.minecraft.server.v1_8_R1.Packet; import net.minecraft.server.v1_8_R1.PacketPlayOutEntityEquipment; import net.minecraft.server.v1_8_R1.PacketPlayOutEntityHeadRotation; -import net.minecraft.server.v1_8_R1.PacketPlayOutPlayerInfo; import net.minecraft.server.v1_8_R1.PlayerInteractManager; import net.minecraft.server.v1_8_R1.WorldServer; @@ -143,11 +142,6 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder { return controllerMove; } - private Packet getListPacket(Player player, boolean removeFromPlayerList) { - return new PacketPlayOutPlayerInfo(removeFromPlayerList ? EnumPlayerInfoAction.REMOVE_PLAYER - : EnumPlayerInfoAction.ADD_PLAYER, ((CraftPlayer) player).getHandle()); - } - public NavigationAbstract getNavigation() { return navigation; } diff --git a/src/main/java/net/citizensnpcs/npc/entity/HumanController.java b/src/main/java/net/citizensnpcs/npc/entity/HumanController.java index 6587202be..5d3ccb54c 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/HumanController.java +++ b/src/main/java/net/citizensnpcs/npc/entity/HumanController.java @@ -29,6 +29,7 @@ import org.bukkit.craftbukkit.v1_8_R1.CraftServer; import org.bukkit.craftbukkit.v1_8_R1.CraftWorld; import org.bukkit.craftbukkit.v1_8_R1.entity.CraftPlayer; import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import com.google.common.collect.Iterables; @@ -66,7 +67,7 @@ public class HumanController extends AbstractEntityController { if (uuid.version() == 4) { // clear version long msb = uuid.getMostSignificantBits(); msb &= ~0x0000000000004000L; - msb |= 0x0000000000002000L; + msb |= 0x0000000000002000L; uuid = new UUID(msb, uuid.getLeastSignificantBits()); } @@ -86,6 +87,16 @@ public class HumanController extends AbstractEntityController { }, 1); handle.getBukkitEntity().setSleepingIgnored(true); NMS.sendToOnline(new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.ADD_PLAYER, handle)); + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() { + @Override + public void run() { + // Double check that we're still spawned and haven't changed type. + if (npc.isSpawned() && npc.getEntity().getType() == EntityType.PLAYER) { + NMS.sendToOnline(new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.REMOVE_PLAYER, + ((CraftPlayer) getBukkitEntity()).getHandle())); + } + } + }, 60); return handle.getBukkitEntity(); }