diff --git a/main/src/main/java/net/citizensnpcs/npc/CitizensNPC.java b/main/src/main/java/net/citizensnpcs/npc/CitizensNPC.java index a5a52edea..51251c5b7 100644 --- a/main/src/main/java/net/citizensnpcs/npc/CitizensNPC.java +++ b/main/src/main/java/net/citizensnpcs/npc/CitizensNPC.java @@ -234,6 +234,10 @@ public class CitizensNPC extends AbstractNPC { prev = getEntity().getLocation(CACHE_LOCATION); despawn(DespawnReason.PENDING_RESPAWN); } + PacketNPC packet = getTraitNullable(PacketNPC.class); + if (packet != null) { + newController = packet.wrap(newController); + } entityController = newController; if (wasSpawned) { spawn(prev, SpawnReason.RESPAWN); @@ -333,7 +337,7 @@ public class CitizensNPC extends AbstractNPC { @Override public void accept(Runnable cancel) { - if (getEntity() == null || !getEntity().isValid()) { + if (getEntity() == null || (!hasTrait(PacketNPC.class) && !getEntity().isValid())) { if (timer++ > Setting.ENTITY_SPAWN_WAIT_TICKS.asInt()) { Messaging.debug("Couldn't spawn ", CitizensNPC.this, "waited", timer, "ticks but entity not added to world"); diff --git a/main/src/main/java/net/citizensnpcs/npc/ai/AStarNavigationStrategy.java b/main/src/main/java/net/citizensnpcs/npc/ai/AStarNavigationStrategy.java index 9053f71cd..ab49b827c 100644 --- a/main/src/main/java/net/citizensnpcs/npc/ai/AStarNavigationStrategy.java +++ b/main/src/main/java/net/citizensnpcs/npc/ai/AStarNavigationStrategy.java @@ -89,6 +89,7 @@ public class AStarNavigationStrategy extends AbstractPathStrategy { } plan = planner.plan; if (plan != null) { + vector = plan.getCurrentVector(); planner = null; } } @@ -97,7 +98,7 @@ public class AStarNavigationStrategy extends AbstractPathStrategy { } Location loc = npc.getEntity().getLocation(NPC_LOCATION); /* Proper door movement - gets stuck on corners at times - + Block block = currLoc.getWorld().getBlockAt(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ()); if (MinecraftBlockExaminer.isDoor(block.getType())) { Door door = (Door) block.getState().getData(); diff --git a/main/src/main/java/net/citizensnpcs/trait/PacketNPC.java b/main/src/main/java/net/citizensnpcs/trait/PacketNPC.java index dcc015c0c..17870a803 100644 --- a/main/src/main/java/net/citizensnpcs/trait/PacketNPC.java +++ b/main/src/main/java/net/citizensnpcs/trait/PacketNPC.java @@ -1,15 +1,16 @@ package net.citizensnpcs.trait; +import java.util.function.Consumer; + import org.bukkit.Location; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; -import org.bukkit.metadata.FixedMetadataValue; import net.citizensnpcs.api.CitizensAPI; +import net.citizensnpcs.api.LocationLookup.PerPlayerMetadata; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.api.trait.Trait; import net.citizensnpcs.api.trait.TraitName; -import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.EntityController; import net.citizensnpcs.util.NMS; import net.citizensnpcs.util.PlayerUpdateTask; @@ -17,6 +18,7 @@ import net.citizensnpcs.util.PlayerUpdateTask; @TraitName("packet") public class PacketNPC extends Trait { private EntityPacketTracker playerTracker; + private boolean spawned = false; public PacketNPC() { super("packet"); @@ -25,26 +27,36 @@ public class PacketNPC extends Trait { @Override public void onSpawn() { playerTracker = NMS.getPlayerTracker(npc.getEntity()); + spawned = true; } @Override public void run() { - wrap((CitizensNPC) npc); - if (!npc.isSpawned()) + if (!spawned) return; + PerPlayerMetadata ppm = CitizensAPI.getLocationLookup().registerMetadata("packetnpc", null); for (Player nearby : CitizensAPI.getLocationLookup().getNearbyPlayers(npc.getStoredLocation(), 64)) { - if (!nearby.hasMetadata(npc.getUniqueId().toString())) { + if (!ppm.has(nearby.getUniqueId(), npc.getUniqueId().toString())) { playerTracker.link(nearby); - nearby.setMetadata(npc.getUniqueId().toString(), new FixedMetadataValue(CitizensAPI.getPlugin(), true)); + ppm.set(nearby.getUniqueId(), npc.getUniqueId().toString(), true); } } playerTracker.run(); } - private void wrap(CitizensNPC npc) { - if (!(npc.getEntityController() instanceof PacketController)) { - npc.setEntityController(new PacketController(npc.getEntityController())); + public EntityController wrap(EntityController controller) { + if (!(controller instanceof PacketController)) { + return new PacketController(controller); } + return controller; + } + + public static interface EntityPacketTracker extends Runnable { + public void link(Player player); + + public void unlinkAll(Consumer callback); + + public void unlink(Player player); } private class PacketController implements EntityController { @@ -61,6 +73,13 @@ public class PacketNPC extends Trait { @Override public void die() { + base.die(); + if (!spawned) + return; + PlayerUpdateTask.deregisterPlayer(getBukkitEntity()); + PerPlayerMetadata ppm = CitizensAPI.getLocationLookup().registerMetadata("packetnpc", null); + playerTracker.unlinkAll(player -> ppm.remove(player.getUniqueId(), npc.getUniqueId().toString())); + spawned = false; } @Override @@ -70,9 +89,13 @@ public class PacketNPC extends Trait { @Override public void remove() { + if (!spawned) + return; PlayerUpdateTask.deregisterPlayer(getBukkitEntity()); - playerTracker.remove(); + PerPlayerMetadata ppm = CitizensAPI.getLocationLookup().registerMetadata("packetnpc", null); + playerTracker.unlinkAll(player -> ppm.remove(player.getUniqueId(), npc.getUniqueId().toString())); base.remove(); + spawned = false; } @Override @@ -82,12 +105,4 @@ public class PacketNPC extends Trait { return true; } } - - public static interface EntityPacketTracker extends Runnable { - public void link(Player player); - - public void remove(); - - public void unlink(Player player); - } } \ No newline at end of file diff --git a/main/src/main/java/net/citizensnpcs/trait/ShopTrait.java b/main/src/main/java/net/citizensnpcs/trait/ShopTrait.java index 3280d8234..c27834386 100644 --- a/main/src/main/java/net/citizensnpcs/trait/ShopTrait.java +++ b/main/src/main/java/net/citizensnpcs/trait/ShopTrait.java @@ -617,7 +617,7 @@ public class ShopTrait extends Trait { shop.type == ShopType.COMMAND))); } - @MenuSlot(slot = { 0, 8 }, material = Material.COMMAND_BLOCK, amount = 1) + @MenuSlot(slot = { 0, 8 }, compatMaterial = { "COMMAND_BLOCK", "COMMAND" }, amount = 1) public void onToggleRightClick(InventoryMenuSlot slot, CitizensInventoryClickEvent event) { event.setCancelled(true); if (trait == null) diff --git a/v1_10_R1/src/main/java/net/citizensnpcs/nms/v1_10_R1/util/NMSImpl.java b/v1_10_R1/src/main/java/net/citizensnpcs/nms/v1_10_R1/util/NMSImpl.java index 3ec7cd33c..b56d34022 100644 --- a/v1_10_R1/src/main/java/net/citizensnpcs/nms/v1_10_R1/util/NMSImpl.java +++ b/v1_10_R1/src/main/java/net/citizensnpcs/nms/v1_10_R1/util/NMSImpl.java @@ -15,6 +15,7 @@ import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; +import java.util.function.Consumer; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -336,9 +337,11 @@ public class NMSImpl implements NMSBridge { } @Override - public void remove() { - for (EntityPlayer link : tracker.trackedPlayers) { - unlink(link.getBukkitEntity()); + public void unlinkAll(Consumer callback) { + for (EntityPlayer link : Lists.newArrayList(tracker.trackedPlayers)) { + Player entity = link.getBukkitEntity(); + unlink(entity); + callback.accept(entity); } } diff --git a/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/util/NMSImpl.java b/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/util/NMSImpl.java index de8aaf609..66f41d1bb 100644 --- a/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/util/NMSImpl.java +++ b/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/util/NMSImpl.java @@ -15,6 +15,7 @@ import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; +import java.util.function.Consumer; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -357,9 +358,11 @@ public class NMSImpl implements NMSBridge { } @Override - public void remove() { - for (EntityPlayer link : tracker.trackedPlayers) { - unlink(link.getBukkitEntity()); + public void unlinkAll(Consumer callback) { + for (EntityPlayer link : Lists.newArrayList(tracker.trackedPlayers)) { + Player entity = link.getBukkitEntity(); + unlink(entity); + callback.accept(entity); } } diff --git a/v1_12_R1/src/main/java/net/citizensnpcs/nms/v1_12_R1/util/NMSImpl.java b/v1_12_R1/src/main/java/net/citizensnpcs/nms/v1_12_R1/util/NMSImpl.java index 2f3895f90..0e0c0004b 100644 --- a/v1_12_R1/src/main/java/net/citizensnpcs/nms/v1_12_R1/util/NMSImpl.java +++ b/v1_12_R1/src/main/java/net/citizensnpcs/nms/v1_12_R1/util/NMSImpl.java @@ -15,6 +15,7 @@ import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; +import java.util.function.Consumer; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -362,9 +363,11 @@ public class NMSImpl implements NMSBridge { } @Override - public void remove() { - for (EntityPlayer link : tracker.trackedPlayers) { - unlink(link.getBukkitEntity()); + public void unlinkAll(Consumer callback) { + for (EntityPlayer link : Lists.newArrayList(tracker.trackedPlayers)) { + Player entity = link.getBukkitEntity(); + unlink(entity); + callback.accept(entity); } } diff --git a/v1_13_R2/src/main/java/net/citizensnpcs/nms/v1_13_R2/util/NMSImpl.java b/v1_13_R2/src/main/java/net/citizensnpcs/nms/v1_13_R2/util/NMSImpl.java index 550bf3111..4469ff73c 100644 --- a/v1_13_R2/src/main/java/net/citizensnpcs/nms/v1_13_R2/util/NMSImpl.java +++ b/v1_13_R2/src/main/java/net/citizensnpcs/nms/v1_13_R2/util/NMSImpl.java @@ -15,6 +15,7 @@ import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; +import java.util.function.Consumer; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -383,9 +384,11 @@ public class NMSImpl implements NMSBridge { } @Override - public void remove() { - for (EntityPlayer link : tracker.trackedPlayers) { - unlink(link.getBukkitEntity()); + public void unlinkAll(Consumer callback) { + for (EntityPlayer link : Lists.newArrayList(tracker.trackedPlayers)) { + Player entity = link.getBukkitEntity(); + unlink(entity); + callback.accept(entity); } } diff --git a/v1_14_R1/src/main/java/net/citizensnpcs/nms/v1_14_R1/util/NMSImpl.java b/v1_14_R1/src/main/java/net/citizensnpcs/nms/v1_14_R1/util/NMSImpl.java index 848dfa2a8..f07587f97 100644 --- a/v1_14_R1/src/main/java/net/citizensnpcs/nms/v1_14_R1/util/NMSImpl.java +++ b/v1_14_R1/src/main/java/net/citizensnpcs/nms/v1_14_R1/util/NMSImpl.java @@ -15,6 +15,7 @@ import java.util.Map; import java.util.Random; import java.util.Set; import java.util.TreeMap; +import java.util.function.Consumer; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -424,9 +425,11 @@ public class NMSImpl implements NMSBridge { } @Override - public void remove() { - for (EntityPlayer link : linked) { - unlink(link.getBukkitEntity()); + public void unlinkAll(Consumer callback) { + for (EntityPlayer link : Lists.newArrayList(linked)) { + Player entity = link.getBukkitEntity(); + unlink(entity); + callback.accept(entity); } } diff --git a/v1_15_R1/src/main/java/net/citizensnpcs/nms/v1_15_R1/util/NMSImpl.java b/v1_15_R1/src/main/java/net/citizensnpcs/nms/v1_15_R1/util/NMSImpl.java index 4b9d2a94e..a00f2cd01 100644 --- a/v1_15_R1/src/main/java/net/citizensnpcs/nms/v1_15_R1/util/NMSImpl.java +++ b/v1_15_R1/src/main/java/net/citizensnpcs/nms/v1_15_R1/util/NMSImpl.java @@ -15,6 +15,7 @@ import java.util.Map; import java.util.Random; import java.util.Set; import java.util.TreeMap; +import java.util.function.Consumer; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -439,9 +440,11 @@ public class NMSImpl implements NMSBridge { } @Override - public void remove() { - for (EntityPlayer link : linked) { - unlink(link.getBukkitEntity()); + public void unlinkAll(Consumer callback) { + for (EntityPlayer link : Lists.newArrayList(linked)) { + Player entity = link.getBukkitEntity(); + unlink(entity); + callback.accept(entity); } } diff --git a/v1_16_R3/src/main/java/net/citizensnpcs/nms/v1_16_R3/util/NMSImpl.java b/v1_16_R3/src/main/java/net/citizensnpcs/nms/v1_16_R3/util/NMSImpl.java index 2faef6a77..40b607902 100644 --- a/v1_16_R3/src/main/java/net/citizensnpcs/nms/v1_16_R3/util/NMSImpl.java +++ b/v1_16_R3/src/main/java/net/citizensnpcs/nms/v1_16_R3/util/NMSImpl.java @@ -15,6 +15,7 @@ import java.util.Map; import java.util.Random; import java.util.Set; import java.util.TreeMap; +import java.util.function.Consumer; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -448,9 +449,11 @@ public class NMSImpl implements NMSBridge { } @Override - public void remove() { - for (EntityPlayer link : linked) { - unlink(link.getBukkitEntity()); + public void unlinkAll(Consumer callback) { + for (EntityPlayer link : Lists.newArrayList(linked)) { + Player entity = link.getBukkitEntity(); + unlink(entity); + callback.accept(entity); } } diff --git a/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/NMSImpl.java b/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/NMSImpl.java index 06aa7bf86..17731351a 100644 --- a/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/NMSImpl.java +++ b/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/NMSImpl.java @@ -15,6 +15,7 @@ import java.util.Map; import java.util.Random; import java.util.Set; import java.util.TreeMap; +import java.util.function.Consumer; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -464,9 +465,11 @@ public class NMSImpl implements NMSBridge { } @Override - public void remove() { - for (ServerPlayerConnection link : linked) { - unlink(link.getPlayer().getBukkitEntity()); + public void unlinkAll(Consumer callback) { + for (ServerPlayerConnection link : Lists.newArrayList(linked)) { + Player entity = link.getPlayer().getBukkitEntity(); + unlink(entity); + callback.accept(entity); } } diff --git a/v1_18_R2/src/main/java/net/citizensnpcs/nms/v1_18_R2/util/NMSImpl.java b/v1_18_R2/src/main/java/net/citizensnpcs/nms/v1_18_R2/util/NMSImpl.java index a8ce7c081..b8c9e3217 100644 --- a/v1_18_R2/src/main/java/net/citizensnpcs/nms/v1_18_R2/util/NMSImpl.java +++ b/v1_18_R2/src/main/java/net/citizensnpcs/nms/v1_18_R2/util/NMSImpl.java @@ -14,6 +14,7 @@ import java.util.Map; import java.util.Random; import java.util.Set; import java.util.TreeMap; +import java.util.function.Consumer; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -468,9 +469,11 @@ public class NMSImpl implements NMSBridge { } @Override - public void remove() { - for (ServerPlayerConnection link : linked) { - unlink(link.getPlayer().getBukkitEntity()); + public void unlinkAll(Consumer callback) { + for (ServerPlayerConnection link : Lists.newArrayList(linked)) { + Player entity = link.getPlayer().getBukkitEntity(); + unlink(entity); + callback.accept(entity); } } diff --git a/v1_19_R2/src/main/java/net/citizensnpcs/nms/v1_19_R2/util/NMSImpl.java b/v1_19_R2/src/main/java/net/citizensnpcs/nms/v1_19_R2/util/NMSImpl.java index 370b39e64..bb5c666dc 100644 --- a/v1_19_R2/src/main/java/net/citizensnpcs/nms/v1_19_R2/util/NMSImpl.java +++ b/v1_19_R2/src/main/java/net/citizensnpcs/nms/v1_19_R2/util/NMSImpl.java @@ -14,6 +14,7 @@ import java.util.Map; import java.util.Random; import java.util.Set; import java.util.TreeMap; +import java.util.function.Consumer; import java.util.stream.Collectors; import org.bukkit.Bukkit; @@ -488,9 +489,11 @@ public class NMSImpl implements NMSBridge { } @Override - public void remove() { - for (ServerPlayerConnection link : linked) { - unlink(link.getPlayer().getBukkitEntity()); + public void unlinkAll(Consumer callback) { + for (ServerPlayerConnection link : Lists.newArrayList(linked)) { + Player entity = link.getPlayer().getBukkitEntity(); + unlink(entity); + callback.accept(entity); } } diff --git a/v1_8_R3/src/main/java/net/citizensnpcs/nms/v1_8_R3/util/NMSImpl.java b/v1_8_R3/src/main/java/net/citizensnpcs/nms/v1_8_R3/util/NMSImpl.java index 8cb87bc57..917acfd97 100644 --- a/v1_8_R3/src/main/java/net/citizensnpcs/nms/v1_8_R3/util/NMSImpl.java +++ b/v1_8_R3/src/main/java/net/citizensnpcs/nms/v1_8_R3/util/NMSImpl.java @@ -15,6 +15,7 @@ import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; +import java.util.function.Consumer; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -319,9 +320,11 @@ public class NMSImpl implements NMSBridge { } @Override - public void remove() { - for (EntityPlayer link : tracker.trackedPlayers) { - unlink(link.getBukkitEntity()); + public void unlinkAll(Consumer callback) { + for (EntityPlayer link : Lists.newArrayList(tracker.trackedPlayers)) { + Player entity = link.getBukkitEntity(); + unlink(entity); + callback.accept(entity); } }