diff --git a/.gitignore b/.gitignore index a21785e..14a95dd 100644 --- a/.gitignore +++ b/.gitignore @@ -42,8 +42,7 @@ bin/ ### Mac OS ### .DS_Store -/run/ -/spigot/run/ +/plugin/run/ /.idea/ gradle.properties diff --git a/api/src/main/java/lol/pyr/znpcsplus/api/ZApi.java b/api/src/main/java/lol/pyr/znpcsplus/api/ZApi.java index 81bfd7f..0ecda85 100644 --- a/api/src/main/java/lol/pyr/znpcsplus/api/ZApi.java +++ b/api/src/main/java/lol/pyr/znpcsplus/api/ZApi.java @@ -1,12 +1,7 @@ package lol.pyr.znpcsplus.api; -import lol.pyr.znpcsplus.api.npc.NPC; import lol.pyr.znpcsplus.api.npc.NPCRegistry; -import lol.pyr.znpcsplus.api.npc.NPCType; -import lol.pyr.znpcsplus.util.ZLocation; -import org.bukkit.World; public interface ZApi { NPCRegistry getNPCRegistry(); - NPC createNPC(World world, NPCType type, ZLocation location); } diff --git a/api/src/main/java/lol/pyr/znpcsplus/api/npc/NPCEntry.java b/api/src/main/java/lol/pyr/znpcsplus/api/npc/NPCEntry.java new file mode 100644 index 0000000..95ec02d --- /dev/null +++ b/api/src/main/java/lol/pyr/znpcsplus/api/npc/NPCEntry.java @@ -0,0 +1,14 @@ +package lol.pyr.znpcsplus.api.npc; + +public interface NPCEntry { + NPC getNpc(); + + boolean isProcessed(); + void setProcessed(boolean value); + + boolean isSave(); + void setSave(boolean value); + + boolean isAllowCommandModification(); + void setAllowCommandModification(boolean value); +} diff --git a/api/src/main/java/lol/pyr/znpcsplus/api/npc/NPCRegistry.java b/api/src/main/java/lol/pyr/znpcsplus/api/npc/NPCRegistry.java index 39dcb96..98c360b 100644 --- a/api/src/main/java/lol/pyr/znpcsplus/api/npc/NPCRegistry.java +++ b/api/src/main/java/lol/pyr/znpcsplus/api/npc/NPCRegistry.java @@ -1,12 +1,14 @@ package lol.pyr.znpcsplus.api.npc; +import lol.pyr.znpcsplus.util.ZLocation; +import org.bukkit.World; + import java.util.Collection; public interface NPCRegistry { - NPC get(String id); - Collection all(); - NPC getByEntityId(int id); - Collection getRegisteredIds(); - void register(String id, NPC npc); - void unregister(String id); + Collection all(); + Collection ids(); + NPCEntry create(String id, World world, NPCType type, ZLocation location); + NPCEntry get(String id); + void delete(String id); } \ No newline at end of file diff --git a/plugin/build.gradle b/plugin/build.gradle index 2382f85..0fdd0e5 100644 --- a/plugin/build.gradle +++ b/plugin/build.gradle @@ -1,7 +1,7 @@ plugins { id "java" id "com.github.johnrengelman.shadow" version "8.1.1" - id "xyz.jpenilla.run-paper" version "2.0.1" + id "xyz.jpenilla.run-paper" version "2.1.0" } runServer { @@ -28,7 +28,7 @@ dependencies { implementation "com.github.retrooper.packetevents:spigot:2.0.0-SNAPSHOT" implementation "space.arim.dazzleconf:dazzleconf-ext-snakeyaml:1.2.1" - implementation "lol.pyr:director-adventure:2.0.1" + implementation "lol.pyr:director-adventure:2.0.2" implementation project(":api") } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/ZNPCsApi.java b/plugin/src/main/java/lol/pyr/znpcsplus/ZNPCsApi.java index 18b70c9..65439c6 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/ZNPCsApi.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/ZNPCsApi.java @@ -2,19 +2,11 @@ package lol.pyr.znpcsplus; import lol.pyr.znpcsplus.api.ZApi; import lol.pyr.znpcsplus.api.npc.NPCRegistry; -import lol.pyr.znpcsplus.api.npc.NPC; -import lol.pyr.znpcsplus.api.npc.NPCType; -import lol.pyr.znpcsplus.util.ZLocation; -import org.bukkit.World; +import lol.pyr.znpcsplus.npc.NPCRegistryImpl; public class ZNPCsApi implements ZApi { @Override public NPCRegistry getNPCRegistry() { - return lol.pyr.znpcsplus.npc.NPCRegistry.get(); - } - - @Override - public NPC createNPC(World world, NPCType type, ZLocation location) { - return new lol.pyr.znpcsplus.npc.NPC(world, type, location); + return NPCRegistryImpl.get(); } } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/ZNPCsPlus.java b/plugin/src/main/java/lol/pyr/znpcsplus/ZNPCsPlus.java index 58e55bc..5c00af9 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/ZNPCsPlus.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/ZNPCsPlus.java @@ -4,8 +4,8 @@ import com.github.retrooper.packetevents.PacketEvents; import com.github.retrooper.packetevents.event.PacketListenerPriority; import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes; import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder; -import lol.pyr.znpcsplus.util.BungeeUtil; import lol.pyr.director.adventure.command.CommandManager; +import lol.pyr.director.adventure.command.MultiCommand; import lol.pyr.znpcsplus.api.ZApiProvider; import lol.pyr.znpcsplus.api.entity.EntityProperty; import lol.pyr.znpcsplus.api.npc.NPCType; @@ -13,8 +13,9 @@ import lol.pyr.znpcsplus.config.Configs; import lol.pyr.znpcsplus.interaction.InteractionPacketListener; import lol.pyr.znpcsplus.interaction.types.ConsoleCommandAction; import lol.pyr.znpcsplus.interaction.types.MessageAction; -import lol.pyr.znpcsplus.npc.NPC; -import lol.pyr.znpcsplus.npc.NPCRegistry; +import lol.pyr.znpcsplus.npc.NPCEntryImpl; +import lol.pyr.znpcsplus.npc.NPCImpl; +import lol.pyr.znpcsplus.npc.NPCRegistryImpl; import lol.pyr.znpcsplus.scheduling.FoliaScheduler; import lol.pyr.znpcsplus.scheduling.SpigotScheduler; import lol.pyr.znpcsplus.scheduling.TaskScheduler; @@ -28,6 +29,7 @@ import lol.pyr.znpcsplus.updater.UpdateChecker; import lol.pyr.znpcsplus.updater.UpdateNotificationListener; import lol.pyr.znpcsplus.user.User; import lol.pyr.znpcsplus.user.UserListener; +import lol.pyr.znpcsplus.util.BungeeUtil; import lol.pyr.znpcsplus.util.FoliaUtil; import lol.pyr.znpcsplus.util.ZLocation; import net.kyori.adventure.platform.bukkit.BukkitAudiences; @@ -122,6 +124,7 @@ public class ZNPCsPlus extends JavaPlugin { SCHEDULER = FoliaUtil.isFolia() ? new FoliaScheduler(this) : new SpigotScheduler(this); BUNGEE_UTILS = new BungeeUtil(this); Bukkit.getOnlinePlayers().forEach(User::get); + registerCommands(); log(ChatColor.WHITE + " * Starting tasks..."); new NPCVisibilityTask(); @@ -141,7 +144,9 @@ public class ZNPCsPlus extends JavaPlugin { World world = Bukkit.getWorld("world"); if (world == null) world = Bukkit.getWorlds().get(0); for (NPCType type : NPCType.values()) { - NPC npc = new NPC(world, type, new ZLocation(x * 3, 200, z * 3, 0, 0)); + NPCEntryImpl entry = NPCRegistryImpl.get().create("debug_npc" + (z * wrap + x), world, type, new ZLocation(x * 3, 200, z * 3, 0, 0)); + entry.setProcessed(true); + NPCImpl npc = entry.getNpc(); if (type.getType() == EntityTypes.PLAYER) { SkinCache.fetchByName("Notch").thenAccept(skin -> npc.setProperty(EntityProperty.SKIN, new PrefetchedDescriptor(skin))); npc.setProperty(EntityProperty.INVISIBLE, true); @@ -149,21 +154,22 @@ public class ZNPCsPlus extends JavaPlugin { npc.setProperty(EntityProperty.GLOW, NamedTextColor.RED); // npc.setProperty(EntityProperty.FIRE, true); npc.getHologram().addLine(Component.text("Hello, World!")); - NPCRegistry.get().register("debug_npc" + (z * wrap + x), npc); if (x++ > wrap) { x = 0; z++; } } - NPC npc = new NPC(world, NPCType.byName("player"), new ZLocation(x * 3, 200, z * 3, 0, 0)); + NPCEntryImpl entry = NPCRegistryImpl.get().create("debug_npc" + (z * wrap + x), world, NPCType.byName("player"), new ZLocation(x * 3, 200, z * 3, 0, 0)); + entry.setProcessed(true); + NPCImpl npc = entry.getNpc(); npc.setProperty(EntityProperty.SKIN, new FetchingDescriptor("jeb_")); npc.addAction(new MessageAction(1000L, "Hi, I'm jeb!")); - NPCRegistry.get().register("debug_npc" + (z * wrap + x), npc); x++; - npc = new NPC(world, NPCType.byName("player"), new ZLocation(x * 3, 200, z * 3, 0, 0)); + entry = NPCRegistryImpl.get().create("debug_npc" + (z * wrap + x), world, NPCType.byName("player"), new ZLocation(x * 3, 200, z * 3, 0, 0)); + entry.setProcessed(true); + npc = entry.getNpc(); npc.setProperty(EntityProperty.SKIN, new MirrorDescriptor()); npc.addAction(new ConsoleCommandAction(1000L, "kick {player}")); - NPCRegistry.get().register("debug_npc" + (z * wrap + x), npc); } } @@ -178,5 +184,6 @@ public class ZNPCsPlus extends JavaPlugin { private void registerCommands() { CommandManager manager = new CommandManager(this, ADVENTURE, context -> {}); + manager.registerCommand("npc", new MultiCommand()); } } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/command/CreateCommand.java b/plugin/src/main/java/lol/pyr/znpcsplus/command/CreateCommand.java new file mode 100644 index 0000000..9157ee0 --- /dev/null +++ b/plugin/src/main/java/lol/pyr/znpcsplus/command/CreateCommand.java @@ -0,0 +1,14 @@ +package lol.pyr.znpcsplus.command; + +import lol.pyr.director.adventure.command.CommandContext; +import lol.pyr.director.adventure.command.CommandHandler; +import lol.pyr.director.common.command.CommandExecutionException; +import lol.pyr.znpcsplus.npc.NPCRegistryImpl; + +public class CreateCommand implements CommandHandler { + @Override + public void run(CommandContext context) throws CommandExecutionException { + String id = context.popString(); + NPCRegistryImpl.get().get(id); + } +} diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/hologram/Hologram.java b/plugin/src/main/java/lol/pyr/znpcsplus/hologram/HologramImpl.java similarity index 93% rename from plugin/src/main/java/lol/pyr/znpcsplus/hologram/Hologram.java rename to plugin/src/main/java/lol/pyr/znpcsplus/hologram/HologramImpl.java index 027a394..8320665 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/hologram/Hologram.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/hologram/HologramImpl.java @@ -1,5 +1,6 @@ package lol.pyr.znpcsplus.hologram; +import lol.pyr.znpcsplus.api.hologram.Hologram; import lol.pyr.znpcsplus.config.Configs; import lol.pyr.znpcsplus.util.Viewable; import lol.pyr.znpcsplus.util.ZLocation; @@ -10,11 +11,11 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -public class Hologram extends Viewable implements lol.pyr.znpcsplus.api.hologram.Hologram { +public class HologramImpl extends Viewable implements Hologram { private ZLocation location; private final List lines = new ArrayList<>(); - public Hologram(ZLocation location) { + public HologramImpl(ZLocation location) { this.location = location; } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/interaction/InteractionPacketListener.java b/plugin/src/main/java/lol/pyr/znpcsplus/interaction/InteractionPacketListener.java index 8689f3c..5b211df 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/interaction/InteractionPacketListener.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/interaction/InteractionPacketListener.java @@ -4,8 +4,9 @@ import com.github.retrooper.packetevents.event.PacketListener; import com.github.retrooper.packetevents.event.PacketReceiveEvent; import com.github.retrooper.packetevents.protocol.packettype.PacketType; import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity; -import lol.pyr.znpcsplus.npc.NPC; -import lol.pyr.znpcsplus.npc.NPCRegistry; +import lol.pyr.znpcsplus.npc.NPCEntryImpl; +import lol.pyr.znpcsplus.npc.NPCImpl; +import lol.pyr.znpcsplus.npc.NPCRegistryImpl; import lol.pyr.znpcsplus.user.User; import org.bukkit.entity.Player; @@ -19,8 +20,9 @@ public class InteractionPacketListener implements PacketListener { User user = User.get(player); if (!user.canInteract()) return; - NPC npc = NPCRegistry.get().getByEntityId(packet.getEntityId()); - if (npc == null) return; + NPCEntryImpl entry = NPCRegistryImpl.get().getByEntityId(packet.getEntityId()); + if (entry == null || !entry.isProcessed()) return; + NPCImpl npc = entry.getNpc(); for (NPCAction action : npc.getActions()) { if (action.getCooldown() > 0 && !user.actionCooldownCheck(action)) continue; diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NPCEntryImpl.java b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NPCEntryImpl.java new file mode 100644 index 0000000..712a6f1 --- /dev/null +++ b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NPCEntryImpl.java @@ -0,0 +1,57 @@ +package lol.pyr.znpcsplus.npc; + +import lol.pyr.znpcsplus.api.npc.NPCEntry; + +public class NPCEntryImpl implements NPCEntry { + private final NPCImpl npc; + + private boolean process = false; + private boolean save = false; + private boolean modify = false; + + public NPCEntryImpl(NPCImpl npc) { + this.npc = npc; + } + + @Override + public NPCImpl getNpc() { + return npc; + } + + @Override + public boolean isProcessed() { + return process; + } + + @Override + public void setProcessed(boolean value) { + if (process && !value) npc.delete(); + process = value; + } + + @Override + public boolean isSave() { + return save; + } + + @Override + public void setSave(boolean value) { + save = value; + } + + @Override + public boolean isAllowCommandModification() { + return modify; + } + + @Override + public void setAllowCommandModification(boolean value) { + modify = value; + } + + public void enableEverything() { + setSave(true); + setProcessed(true); + setAllowCommandModification(true); + } +} diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NPC.java b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NPCImpl.java similarity index 82% rename from plugin/src/main/java/lol/pyr/znpcsplus/npc/NPC.java rename to plugin/src/main/java/lol/pyr/znpcsplus/npc/NPCImpl.java index 98f4ad6..ed3134b 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NPC.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NPCImpl.java @@ -3,7 +3,7 @@ package lol.pyr.znpcsplus.npc; import lol.pyr.znpcsplus.api.entity.EntityProperty; import lol.pyr.znpcsplus.api.npc.NPCType; import lol.pyr.znpcsplus.entity.PacketEntity; -import lol.pyr.znpcsplus.hologram.Hologram; +import lol.pyr.znpcsplus.hologram.HologramImpl; import lol.pyr.znpcsplus.interaction.NPCAction; import lol.pyr.znpcsplus.util.Viewable; import lol.pyr.znpcsplus.util.ZLocation; @@ -13,26 +13,23 @@ import org.bukkit.entity.Player; import java.util.*; -public class NPC extends Viewable implements lol.pyr.znpcsplus.api.npc.NPC { - protected static final Set _ALL_NPCS = new HashSet<>(); - +public class NPCImpl extends Viewable implements lol.pyr.znpcsplus.api.npc.NPC { private final Set viewers = new HashSet<>(); private final String worldName; private PacketEntity entity; private ZLocation location; private NPCType type; - private final Hologram hologram; + private final HologramImpl hologram; private final Map, Object> propertyMap = new HashMap<>(); private final Set actions = new HashSet<>(); - public NPC(World world, NPCType type, ZLocation location) { + protected NPCImpl(World world, NPCType type, ZLocation location) { this.worldName = world.getName(); this.type = type; this.location = location; entity = new PacketEntity(this, type.getType(), location); - hologram = new Hologram(location.withY(location.getY() + type.getHologramOffset())); - _ALL_NPCS.add(this); + hologram = new HologramImpl(location.withY(location.getY() + type.getHologramOffset())); } public void setType(NPCType type) { @@ -60,7 +57,7 @@ public class NPC extends Viewable implements lol.pyr.znpcsplus.api.npc.NPC { hologram.setLocation(location.withY(location.getY() + type.getHologramOffset())); } - public Hologram getHologram() { + public HologramImpl getHologram() { return hologram; } @@ -68,16 +65,6 @@ public class NPC extends Viewable implements lol.pyr.znpcsplus.api.npc.NPC { return Bukkit.getWorld(worldName); } - @Override - public void delete() { - _ALL_NPCS.remove(this); - super.delete(); - } - - public void undelete() { - _ALL_NPCS.add(this); - } - @Override protected void _show(Player player) { entity.spawn(player); diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NPCRegistry.java b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NPCRegistry.java deleted file mode 100644 index 735c2d4..0000000 --- a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NPCRegistry.java +++ /dev/null @@ -1,46 +0,0 @@ -package lol.pyr.znpcsplus.npc; - -import lol.pyr.znpcsplus.api.npc.NPC; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -public class NPCRegistry implements lol.pyr.znpcsplus.api.npc.NPCRegistry { - private final static NPCRegistry registry = new NPCRegistry(); - - public static NPCRegistry get() { - return registry; - } - - private final Map npcMap = new HashMap<>(); - - private NPCRegistry() { - if (registry != null) throw new UnsupportedOperationException("This class can only be instanciated once!"); - } - - public NPC get(String id) { - return npcMap.get(id); - } - - public Collection all() { - return Collections.unmodifiableSet(lol.pyr.znpcsplus.npc.NPC._ALL_NPCS); - } - - public lol.pyr.znpcsplus.npc.NPC getByEntityId(int id) { - return all().stream().filter(npc -> npc.getEntity().getEntityId() == id).findFirst().orElse(null); - } - - public Collection getRegisteredIds() { - return Collections.unmodifiableSet(npcMap.keySet()); - } - - public void register(String id, NPC npc) { - npcMap.put(id, npc); - } - - public void unregister(String id) { - npcMap.remove(id); - } -} diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NPCRegistryImpl.java b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NPCRegistryImpl.java new file mode 100644 index 0000000..d6d4e48 --- /dev/null +++ b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NPCRegistryImpl.java @@ -0,0 +1,58 @@ +package lol.pyr.znpcsplus.npc; + +import lol.pyr.znpcsplus.api.npc.NPCRegistry; +import lol.pyr.znpcsplus.api.npc.NPCType; +import lol.pyr.znpcsplus.util.ZLocation; +import org.bukkit.World; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +public class NPCRegistryImpl implements NPCRegistry { + private final static NPCRegistryImpl registry = new NPCRegistryImpl(); + + public static NPCRegistryImpl get() { + return registry; + } + + private NPCRegistryImpl() { + if (registry != null) throw new UnsupportedOperationException("This class can only be instanciated once!"); + } + + private final Map npcMap = new HashMap<>(); + + public NPCEntryImpl get(String id) { + return npcMap.get(id.toUpperCase()); + } + + public Collection all() { + return Collections.unmodifiableCollection(npcMap.values()); + } + + public NPCEntryImpl getByEntityId(int id) { + return all().stream().filter(entry -> entry.getNpc().getEntity().getEntityId() == id).findFirst().orElse(null); + } + + public Collection ids() { + return Collections.unmodifiableSet(npcMap.keySet()); + } + + @Override + public NPCEntryImpl create(String id, World world, NPCType type, ZLocation location) { + id = id.toUpperCase(); + if (npcMap.containsKey(id)) throw new IllegalArgumentException("An npc with the id " + id + " already exists!"); + NPCImpl npc = new NPCImpl(world, type, location); + NPCEntryImpl entry = new NPCEntryImpl(npc); + npcMap.put(id, entry); + return entry; + } + + @Override + public void delete(String id) { + id = id.toUpperCase(); + if (!npcMap.containsKey(id)) return; + npcMap.remove(id).getNpc().delete(); + } +} diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/reflection/Reflections.java b/plugin/src/main/java/lol/pyr/znpcsplus/reflection/Reflections.java index 8977ee8..c1df534 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/reflection/Reflections.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/reflection/Reflections.java @@ -90,7 +90,3 @@ public final class Reflections { .withExpectResult(SCHEDULED_TASK_CLASS) .setStrict(FoliaUtil.isFolia())); } - -// Bukkit.getAsyncScheduler().runNow(plugin, task -> runnable.run()); -// Bukkit.getAsyncScheduler().runDelayed(plugin, task -> runnable.run(), ticks * 50, TimeUnit.MILLISECONDS); -// Bukkit.getAsyncScheduler().runAtFixedRate(plugin, task -> runnable.run(), delay * 50, ticks * 50, TimeUnit.MILLISECONDS); diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/tasks/NPCVisibilityTask.java b/plugin/src/main/java/lol/pyr/znpcsplus/tasks/NPCVisibilityTask.java index 4cd4f7e..aaadcc1 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/tasks/NPCVisibilityTask.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/tasks/NPCVisibilityTask.java @@ -2,8 +2,9 @@ package lol.pyr.znpcsplus.tasks; import lol.pyr.znpcsplus.ZNPCsPlus; import lol.pyr.znpcsplus.config.Configs; -import lol.pyr.znpcsplus.npc.NPC; -import lol.pyr.znpcsplus.npc.NPCRegistry; +import lol.pyr.znpcsplus.npc.NPCEntryImpl; +import lol.pyr.znpcsplus.npc.NPCImpl; +import lol.pyr.znpcsplus.npc.NPCRegistryImpl; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; @@ -16,10 +17,14 @@ public class NPCVisibilityTask extends BukkitRunnable { public void run() { double distSq = NumberConversions.square(Configs.config().viewDistance()); - for (NPC npc : NPCRegistry.get().all()) for (Player player : Bukkit.getOnlinePlayers()) { - boolean inRange = (player.getWorld() == npc.getWorld() && player.getLocation().distanceSquared(npc.getLocation().toBukkitLocation(npc.getWorld())) <= distSq); - if (!inRange && npc.isShown(player)) npc.hide(player); - if (inRange && !npc.isShown(player)) npc.show(player); + for (NPCEntryImpl entry : NPCRegistryImpl.get().all()) { + if (!entry.isProcessed()) continue; + NPCImpl npc = entry.getNpc(); + for (Player player : Bukkit.getOnlinePlayers()) { + boolean inRange = (player.getWorld() == npc.getWorld() && player.getLocation().distanceSquared(npc.getLocation().toBukkitLocation(npc.getWorld())) <= distSq); + if (!inRange && npc.isShown(player)) npc.hide(player); + if (inRange && !npc.isShown(player)) npc.show(player); + } } } } diff --git a/plugin/src/main/resources/plugin.yml b/plugin/src/main/resources/plugin.yml index ad35e73..ac46bf9 100644 --- a/plugin/src/main/resources/plugin.yml +++ b/plugin/src/main/resources/plugin.yml @@ -18,4 +18,12 @@ softdepend: - ViaVersion - ViaBackwards - ViaRewind - - Geyser-Spigot \ No newline at end of file + - Geyser-Spigot + +commands: + npc: + aliases: + - znpc + - znpcs + - npcs + permission: znpcsplus.command.npc