refactor & make npc types not static

This commit is contained in:
Pyrbu 2023-05-21 13:45:43 +01:00
parent 3d9ca60445
commit 49e1d7f074
42 changed files with 288 additions and 267 deletions

@ -2,6 +2,6 @@ package lol.pyr.znpcsplus.api;
import lol.pyr.znpcsplus.api.npc.NpcRegistry; import lol.pyr.znpcsplus.api.npc.NpcRegistry;
public interface ZApi { public interface NpcApi {
NpcRegistry getNpcRegistry(); NpcRegistry getNpcRegistry();
} }

@ -1,13 +1,13 @@
package lol.pyr.znpcsplus.api; package lol.pyr.znpcsplus.api;
public class ZApiProvider { public class NpcApiProvider {
private static ZApi plugin = null; private static NpcApi plugin = null;
private ZApiProvider() { private NpcApiProvider() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
public static ZApi get() { public static NpcApi get() {
if (plugin == null) throw new IllegalStateException( if (plugin == null) throw new IllegalStateException(
"ZNPCsPlus plugin isn't enabled yet!\n" + "ZNPCsPlus plugin isn't enabled yet!\n" +
"Please add it to your plugin.yml as a depend or softdepend." "Please add it to your plugin.yml as a depend or softdepend."
@ -15,11 +15,11 @@ public class ZApiProvider {
return plugin; return plugin;
} }
public static void register(ZApi plugin) { public static void register(NpcApi plugin) {
ZApiProvider.plugin = plugin; NpcApiProvider.plugin = plugin;
} }
public static void unregister() { public static void unregister() {
ZApiProvider.plugin = null; NpcApiProvider.plugin = null;
} }
} }

@ -1,14 +1,14 @@
package lol.pyr.znpcsplus.api.npc; package lol.pyr.znpcsplus.api.npc;
import lol.pyr.znpcsplus.util.ZLocation; import lol.pyr.znpcsplus.util.NpcLocation;
import org.bukkit.World; import org.bukkit.World;
import java.util.Collection; import java.util.Collection;
public interface NpcRegistry { public interface NpcRegistry {
Collection<? extends NpcEntry> all(); Collection<? extends NpcEntry> getAll();
Collection<String> ids(); Collection<String> getIds();
NpcEntry create(String id, World world, NpcType type, ZLocation location); NpcEntry create(String id, World world, NpcType type, NpcLocation location);
NpcEntry get(String id); NpcEntry get(String id);
void delete(String id); void delete(String id);
} }

@ -5,14 +5,14 @@ import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.util.NumberConversions; import org.bukkit.util.NumberConversions;
public class ZLocation { public class NpcLocation {
private final double x; private final double x;
private final double y; private final double y;
private final double z; private final double z;
private final float yaw; private final float yaw;
private final float pitch; private final float pitch;
public ZLocation(double x, double y, double z, float yaw, float pitch) { public NpcLocation(double x, double y, double z, float yaw, float pitch) {
this.x = x; this.x = x;
this.y = y; this.y = y;
this.z = z; this.z = z;
@ -20,7 +20,7 @@ public class ZLocation {
this.pitch = pitch; this.pitch = pitch;
} }
public ZLocation(Location location) { public NpcLocation(Location location) {
this(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); this(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
} }
@ -60,8 +60,8 @@ public class ZLocation {
return new Location(world, this.x, this.y, this.z, this.yaw, this.pitch); return new Location(world, this.x, this.y, this.z, this.yaw, this.pitch);
} }
public ZLocation withY(double y) { public NpcLocation withY(double y) {
return new ZLocation(x, y, z, yaw, pitch); return new NpcLocation(x, y, z, yaw, pitch);
} }
public Vector3d toVector3d() { public Vector3d toVector3d() {
@ -71,16 +71,16 @@ public class ZLocation {
private static final double _2PI = 2 * Math.PI; private static final double _2PI = 2 * Math.PI;
public Location lookingAt(Location loc) { public Location lookingAt(Location loc) {
return lookingAt(new ZLocation(loc)).toBukkitLocation(loc.getWorld()); return lookingAt(new NpcLocation(loc)).toBukkitLocation(loc.getWorld());
} }
public ZLocation lookingAt(ZLocation loc) { public NpcLocation lookingAt(NpcLocation loc) {
final double x = loc.getX() - this.x; final double x = loc.getX() - this.x;
final double z = loc.getZ() - this.z; final double z = loc.getZ() - this.z;
final double y = loc.getY() - this.y; final double y = loc.getY() - this.y;
if (x == 0 && z == 0) { if (x == 0 && z == 0) {
return new ZLocation(this.x, this.y, this.z, this.yaw, y > 0 ? -90 : 90); return new NpcLocation(this.x, this.y, this.z, this.yaw, y > 0 ? -90 : 90);
} }
double x2 = NumberConversions.square(x); double x2 = NumberConversions.square(x);
@ -91,6 +91,6 @@ public class ZLocation {
float yaw = (float) Math.toDegrees((theta + _2PI) % _2PI); float yaw = (float) Math.toDegrees((theta + _2PI) % _2PI);
float pitch = (float) Math.toDegrees(Math.atan(-y / xz)); float pitch = (float) Math.toDegrees(Math.atan(-y / xz));
return new ZLocation(this.x, this.y, this.z, yaw, pitch); return new NpcLocation(this.x, this.y, this.z, yaw, pitch);
} }
} }

@ -1,10 +1,10 @@
package lol.pyr.znpcsplus; package lol.pyr.znpcsplus;
import lol.pyr.znpcsplus.api.ZApi; import lol.pyr.znpcsplus.api.NpcApi;
import lol.pyr.znpcsplus.api.npc.NpcRegistry; import lol.pyr.znpcsplus.api.npc.NpcRegistry;
import lol.pyr.znpcsplus.npc.NpcRegistryImpl; import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
public class ZNPCsPlusApi implements ZApi { public class ZNPCsPlusApi implements NpcApi {
private final NpcRegistryImpl npcRegistry; private final NpcRegistryImpl npcRegistry;
public ZNPCsPlusApi(NpcRegistryImpl npcRegistry) { public ZNPCsPlusApi(NpcRegistryImpl npcRegistry) {

@ -12,7 +12,7 @@ import lol.pyr.director.adventure.parse.primitive.BooleanParser;
import lol.pyr.director.adventure.parse.primitive.DoubleParser; import lol.pyr.director.adventure.parse.primitive.DoubleParser;
import lol.pyr.director.adventure.parse.primitive.IntegerParser; import lol.pyr.director.adventure.parse.primitive.IntegerParser;
import lol.pyr.director.common.message.Message; import lol.pyr.director.common.message.Message;
import lol.pyr.znpcsplus.api.ZApiProvider; import lol.pyr.znpcsplus.api.NpcApiProvider;
import lol.pyr.znpcsplus.commands.*; import lol.pyr.znpcsplus.commands.*;
import lol.pyr.znpcsplus.commands.action.ActionAddCommand; import lol.pyr.znpcsplus.commands.action.ActionAddCommand;
import lol.pyr.znpcsplus.commands.action.ActionDeleteCommand; import lol.pyr.znpcsplus.commands.action.ActionDeleteCommand;
@ -25,10 +25,7 @@ import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
import lol.pyr.znpcsplus.interaction.ActionRegistry; import lol.pyr.znpcsplus.interaction.ActionRegistry;
import lol.pyr.znpcsplus.interaction.InteractionPacketListener; import lol.pyr.znpcsplus.interaction.InteractionPacketListener;
import lol.pyr.znpcsplus.metadata.*; import lol.pyr.znpcsplus.metadata.*;
import lol.pyr.znpcsplus.npc.NpcEntryImpl; import lol.pyr.znpcsplus.npc.*;
import lol.pyr.znpcsplus.npc.NpcImpl;
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
import lol.pyr.znpcsplus.npc.NpcTypeImpl;
import lol.pyr.znpcsplus.packets.*; import lol.pyr.znpcsplus.packets.*;
import lol.pyr.znpcsplus.parsers.EntityPropertyParser; import lol.pyr.znpcsplus.parsers.EntityPropertyParser;
import lol.pyr.znpcsplus.parsers.NamedTextColorParser; import lol.pyr.znpcsplus.parsers.NamedTextColorParser;
@ -47,7 +44,7 @@ import lol.pyr.znpcsplus.user.UserManager;
import lol.pyr.znpcsplus.util.BungeeConnector; import lol.pyr.znpcsplus.util.BungeeConnector;
import lol.pyr.znpcsplus.util.FoliaUtil; import lol.pyr.znpcsplus.util.FoliaUtil;
import lol.pyr.znpcsplus.util.LazyLoader; import lol.pyr.znpcsplus.util.LazyLoader;
import lol.pyr.znpcsplus.util.ZLocation; import lol.pyr.znpcsplus.util.NpcLocation;
import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
@ -113,18 +110,19 @@ public class ZNpcsPlus extends JavaPlugin {
BungeeConnector bungeeConnector = new BungeeConnector(this); BungeeConnector bungeeConnector = new BungeeConnector(this);
ConfigManager configManager = new ConfigManager(getDataFolder()); ConfigManager configManager = new ConfigManager(getDataFolder());
ActionRegistry actionRegistry = new ActionRegistry(); ActionRegistry actionRegistry = new ActionRegistry();
NpcRegistryImpl npcRegistry = new NpcRegistryImpl(configManager, this, packetFactory, actionRegistry, scheduler); NpcTypeRegistry typeRegistry = new NpcTypeRegistry();
NpcRegistryImpl npcRegistry = new NpcRegistryImpl(configManager, this, packetFactory, actionRegistry, scheduler, typeRegistry);
UserManager userManager = new UserManager(); UserManager userManager = new UserManager();
SkinCache skinCache = new SkinCache(configManager); SkinCache skinCache = new SkinCache(configManager);
log(ChatColor.WHITE + " * Registerring components..."); log(ChatColor.WHITE + " * Registerring components...");
NpcTypeImpl.defineTypes(packetEvents); typeRegistry.registerDefault(packetEvents);
actionRegistry.registerTypes(npcRegistry, scheduler, adventure, bungeeConnector, textSerializer); actionRegistry.registerTypes(npcRegistry, scheduler, adventure, bungeeConnector, textSerializer);
packetEvents.getEventManager().registerListener(new InteractionPacketListener(userManager, npcRegistry), PacketListenerPriority.MONITOR); packetEvents.getEventManager().registerListener(new InteractionPacketListener(userManager, npcRegistry), PacketListenerPriority.MONITOR);
new Metrics(this, PLUGIN_ID); new Metrics(this, PLUGIN_ID);
pluginManager.registerEvents(new UserListener(userManager), this); pluginManager.registerEvents(new UserListener(userManager), this);
getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord"); getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
registerCommands(npcRegistry, skinCache, adventure, actionRegistry); registerCommands(npcRegistry, skinCache, adventure, actionRegistry, typeRegistry);
log(ChatColor.WHITE + " * Starting tasks..."); log(ChatColor.WHITE + " * Starting tasks...");
if (configManager.getConfig().checkForUpdates()) { if (configManager.getConfig().checkForUpdates()) {
@ -144,7 +142,7 @@ public class ZNpcsPlus extends JavaPlugin {
shutdownTasks.add(adventure::close); shutdownTasks.add(adventure::close);
if (configManager.getConfig().autoSaveEnabled()) shutdownTasks.add(npcRegistry::save); if (configManager.getConfig().autoSaveEnabled()) shutdownTasks.add(npcRegistry::save);
ZApiProvider.register(new ZNPCsPlusApi(npcRegistry)); NpcApiProvider.register(new ZNPCsPlusApi(npcRegistry));
enabled = true; enabled = true;
log(ChatColor.WHITE + " * Loading complete! (" + (System.currentTimeMillis() - before) + "ms)"); log(ChatColor.WHITE + " * Loading complete! (" + (System.currentTimeMillis() - before) + "ms)");
log(""); log("");
@ -153,8 +151,8 @@ public class ZNpcsPlus extends JavaPlugin {
World world = Bukkit.getWorld("world"); World world = Bukkit.getWorld("world");
if (world == null) world = Bukkit.getWorlds().get(0); if (world == null) world = Bukkit.getWorlds().get(0);
int i = 0; int i = 0;
for (NpcTypeImpl type : NpcTypeImpl.values()) { for (NpcTypeImpl type : typeRegistry.getAll()) {
NpcEntryImpl entry = npcRegistry.create("debug_npc_" + i, world, type, new ZLocation(i * 3, 200, 0, 0, 0)); NpcEntryImpl entry = npcRegistry.create("debug_npc_" + i, world, type, new NpcLocation(i * 3, 200, 0, 0, 0));
entry.setProcessed(true); entry.setProcessed(true);
NpcImpl npc = entry.getNpc(); NpcImpl npc = entry.getNpc();
npc.getHologram().addLine(Component.text("Hello, World!")); npc.getHologram().addLine(Component.text("Hello, World!"));
@ -166,7 +164,7 @@ public class ZNpcsPlus extends JavaPlugin {
@Override @Override
public void onDisable() { public void onDisable() {
if (!enabled) return; if (!enabled) return;
ZApiProvider.unregister(); NpcApiProvider.unregister();
for (Runnable runnable : shutdownTasks) runnable.run(); for (Runnable runnable : shutdownTasks) runnable.run();
} }
@ -209,12 +207,12 @@ public class ZNpcsPlus extends JavaPlugin {
} }
private void registerCommands(NpcRegistryImpl npcRegistry, SkinCache skinCache, BukkitAudiences adventure, ActionRegistry actionRegistry) { private void registerCommands(NpcRegistryImpl npcRegistry, SkinCache skinCache, BukkitAudiences adventure, ActionRegistry actionRegistry, NpcTypeRegistry typeRegistry) {
// TODO: make the messages better // TODO: make the messages better
Message<CommandContext> incorrectUsageMessage = context -> context.send(Component.text("Incorrect usage: /" + context.getUsage(), NamedTextColor.RED)); Message<CommandContext> incorrectUsageMessage = context -> context.send(Component.text("Incorrect usage: /" + context.getUsage(), NamedTextColor.RED));
CommandManager manager = new CommandManager(this, adventure, incorrectUsageMessage); CommandManager manager = new CommandManager(this, adventure, incorrectUsageMessage);
manager.registerParser(NpcTypeImpl.class, new NpcTypeParser(incorrectUsageMessage)); manager.registerParser(NpcTypeImpl.class, new NpcTypeParser(incorrectUsageMessage, typeRegistry));
manager.registerParser(NpcEntryImpl.class, new NpcEntryParser(npcRegistry, incorrectUsageMessage)); manager.registerParser(NpcEntryImpl.class, new NpcEntryParser(npcRegistry, incorrectUsageMessage));
manager.registerParser(EntityPropertyImpl.class, new EntityPropertyParser(incorrectUsageMessage)); manager.registerParser(EntityPropertyImpl.class, new EntityPropertyParser(incorrectUsageMessage));
manager.registerParser(Integer.class, new IntegerParser(incorrectUsageMessage)); manager.registerParser(Integer.class, new IntegerParser(incorrectUsageMessage));
@ -223,15 +221,15 @@ public class ZNpcsPlus extends JavaPlugin {
manager.registerParser(NamedTextColor.class, new NamedTextColorParser(incorrectUsageMessage)); manager.registerParser(NamedTextColor.class, new NamedTextColorParser(incorrectUsageMessage));
manager.registerCommand("npc", new MultiCommand() manager.registerCommand("npc", new MultiCommand()
.addSubcommand("create", new CreateCommand(npcRegistry)) .addSubcommand("create", new CreateCommand(npcRegistry, typeRegistry))
.addSubcommand("skin", new SkinCommand(skinCache, npcRegistry)) .addSubcommand("skin", new SkinCommand(skinCache, npcRegistry, typeRegistry))
.addSubcommand("delete", new DeleteCommand(npcRegistry, adventure)) .addSubcommand("delete", new DeleteCommand(npcRegistry, adventure))
.addSubcommand("move", new MoveCommand(npcRegistry)) .addSubcommand("move", new MoveCommand(npcRegistry))
.addSubcommand("properties", new PropertiesCommand(npcRegistry)) .addSubcommand("properties", new PropertiesCommand(npcRegistry))
.addSubcommand("teleport", new TeleportCommand(npcRegistry)) .addSubcommand("teleport", new TeleportCommand(npcRegistry))
.addSubcommand("list", new ListCommand(npcRegistry)) .addSubcommand("list", new ListCommand(npcRegistry))
.addSubcommand("near", new NearCommand(npcRegistry)) .addSubcommand("near", new NearCommand(npcRegistry))
.addSubcommand("type", new TypeCommand(npcRegistry)) .addSubcommand("type", new TypeCommand(npcRegistry, typeRegistry))
.addSubcommand("storage", new MultiCommand() .addSubcommand("storage", new MultiCommand()
.addSubcommand("save", new SaveAllCommand(npcRegistry)) .addSubcommand("save", new SaveAllCommand(npcRegistry))
.addSubcommand("reload", new LoadAllCommand(npcRegistry))) .addSubcommand("reload", new LoadAllCommand(npcRegistry)))

@ -6,7 +6,8 @@ import lol.pyr.director.common.command.CommandExecutionException;
import lol.pyr.znpcsplus.npc.NpcEntryImpl; import lol.pyr.znpcsplus.npc.NpcEntryImpl;
import lol.pyr.znpcsplus.npc.NpcRegistryImpl; import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
import lol.pyr.znpcsplus.npc.NpcTypeImpl; import lol.pyr.znpcsplus.npc.NpcTypeImpl;
import lol.pyr.znpcsplus.util.ZLocation; import lol.pyr.znpcsplus.npc.NpcTypeRegistry;
import lol.pyr.znpcsplus.util.NpcLocation;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -16,9 +17,11 @@ import java.util.List;
public class CreateCommand implements CommandHandler { public class CreateCommand implements CommandHandler {
private final NpcRegistryImpl npcRegistry; private final NpcRegistryImpl npcRegistry;
private final NpcTypeRegistry typeRegistry;
public CreateCommand(NpcRegistryImpl npcRegistry) { public CreateCommand(NpcRegistryImpl npcRegistry, NpcTypeRegistry typeRegistry) {
this.npcRegistry = npcRegistry; this.npcRegistry = npcRegistry;
this.typeRegistry = typeRegistry;
} }
@Override @Override
@ -30,7 +33,7 @@ public class CreateCommand implements CommandHandler {
if (npcRegistry.get(id) != null) context.halt(Component.text("NPC with that ID already exists.", NamedTextColor.RED)); if (npcRegistry.get(id) != null) context.halt(Component.text("NPC with that ID already exists.", NamedTextColor.RED));
NpcTypeImpl type = context.parse(NpcTypeImpl.class); NpcTypeImpl type = context.parse(NpcTypeImpl.class);
NpcEntryImpl entry = npcRegistry.create(id, player.getWorld(), type, new ZLocation(player.getLocation())); NpcEntryImpl entry = npcRegistry.create(id, player.getWorld(), type, new NpcLocation(player.getLocation()));
entry.enableEverything(); entry.enableEverything();
context.send(Component.text("Created a " + type.getName() + " NPC with ID " + id + ".", NamedTextColor.GREEN)); context.send(Component.text("Created a " + type.getName() + " NPC with ID " + id + ".", NamedTextColor.GREEN));
@ -38,8 +41,8 @@ public class CreateCommand implements CommandHandler {
@Override @Override
public List<String> suggest(CommandContext context) throws CommandExecutionException { public List<String> suggest(CommandContext context) throws CommandExecutionException {
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.modifiableIds()); if (context.argSize() == 1) return context.suggestCollection(npcRegistry.getModifiableIds());
if (context.argSize() == 2) return context.suggestStream(NpcTypeImpl.values().stream().map(NpcTypeImpl::getName)); if (context.argSize() == 2) return context.suggestStream(typeRegistry.getAll().stream().map(NpcTypeImpl::getName));
return Collections.emptyList(); return Collections.emptyList();
} }
} }

@ -31,7 +31,7 @@ public class DeleteCommand implements CommandHandler {
@Override @Override
public List<String> suggest(CommandContext context) throws CommandExecutionException { public List<String> suggest(CommandContext context) throws CommandExecutionException {
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.modifiableIds()); if (context.argSize() == 1) return context.suggestCollection(npcRegistry.getModifiableIds());
return Collections.emptyList(); return Collections.emptyList();
} }
} }

@ -5,7 +5,7 @@ import lol.pyr.director.adventure.command.CommandHandler;
import lol.pyr.director.common.command.CommandExecutionException; import lol.pyr.director.common.command.CommandExecutionException;
import lol.pyr.znpcsplus.npc.NpcImpl; import lol.pyr.znpcsplus.npc.NpcImpl;
import lol.pyr.znpcsplus.npc.NpcRegistryImpl; import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
import lol.pyr.znpcsplus.util.ZLocation; import lol.pyr.znpcsplus.util.NpcLocation;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.event.ClickEvent;
@ -21,9 +21,9 @@ public class ListCommand implements CommandHandler {
@Override @Override
public void run(CommandContext context) throws CommandExecutionException { public void run(CommandContext context) throws CommandExecutionException {
TextComponent.Builder component = Component.text("Npc's:\n").color(NamedTextColor.GOLD).toBuilder(); TextComponent.Builder component = Component.text("Npc's:\n").color(NamedTextColor.GOLD).toBuilder();
for (String id : npcRegistry.modifiableIds()) { for (String id : npcRegistry.getModifiableIds()) {
NpcImpl npc = npcRegistry.get(id).getNpc(); NpcImpl npc = npcRegistry.get(id).getNpc();
ZLocation location = npc.getLocation(); NpcLocation location = npc.getLocation();
component.append(Component.text("ID: " + id, NamedTextColor.GREEN)) component.append(Component.text("ID: " + id, NamedTextColor.GREEN))
.append(Component.text(" | ", NamedTextColor.GRAY)) .append(Component.text(" | ", NamedTextColor.GRAY))
.append(Component.text("Type: ", NamedTextColor.GREEN)) .append(Component.text("Type: ", NamedTextColor.GREEN))

@ -6,7 +6,7 @@ import lol.pyr.director.common.command.CommandExecutionException;
import lol.pyr.znpcsplus.npc.NpcEntryImpl; import lol.pyr.znpcsplus.npc.NpcEntryImpl;
import lol.pyr.znpcsplus.npc.NpcImpl; import lol.pyr.znpcsplus.npc.NpcImpl;
import lol.pyr.znpcsplus.npc.NpcRegistryImpl; import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
import lol.pyr.znpcsplus.util.ZLocation; import lol.pyr.znpcsplus.util.NpcLocation;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -26,13 +26,13 @@ public class MoveCommand implements CommandHandler {
context.setUsage(context.getLabel() + " move <id>"); context.setUsage(context.getLabel() + " move <id>");
Player player = context.ensureSenderIsPlayer(); Player player = context.ensureSenderIsPlayer();
NpcImpl npc = context.parse(NpcEntryImpl.class).getNpc(); NpcImpl npc = context.parse(NpcEntryImpl.class).getNpc();
npc.setLocation(new ZLocation(player.getLocation())); npc.setLocation(new NpcLocation(player.getLocation()));
context.send(Component.text("NPC moved to your current location.", NamedTextColor.GREEN)); context.send(Component.text("NPC moved to your current location.", NamedTextColor.GREEN));
} }
@Override @Override
public List<String> suggest(CommandContext context) throws CommandExecutionException { public List<String> suggest(CommandContext context) throws CommandExecutionException {
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.modifiableIds()); if (context.argSize() == 1) return context.suggestCollection(npcRegistry.getModifiableIds());
return Collections.emptyList(); return Collections.emptyList();
} }
} }

@ -24,7 +24,7 @@ public class NearCommand implements CommandHandler {
int raw = context.parse(Integer.class); int raw = context.parse(Integer.class);
double radius = Math.pow(raw, 2); double radius = Math.pow(raw, 2);
String npcs = npcRegistry.allModifiable().stream() String npcs = npcRegistry.getAllModifiable().stream()
.filter(entry -> entry.getNpc().getBukkitLocation().distanceSquared(player.getLocation()) < radius) .filter(entry -> entry.getNpc().getBukkitLocation().distanceSquared(player.getLocation()) < radius)
.map(NpcEntryImpl::getId) .map(NpcEntryImpl::getId)
.collect(Collectors.joining(", ")); .collect(Collectors.joining(", "));

@ -35,7 +35,7 @@ public class PropertiesCommand implements CommandHandler {
@Override @Override
public List<String> suggest(CommandContext context) throws CommandExecutionException { public List<String> suggest(CommandContext context) throws CommandExecutionException {
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.modifiableIds()); if (context.argSize() == 1) return context.suggestCollection(npcRegistry.getModifiableIds());
if (context.argSize() == 2) return context.suggestStream(context.suggestionParse(0, NpcEntryImpl.class) if (context.argSize() == 2) return context.suggestStream(context.suggestionParse(0, NpcEntryImpl.class)
.getNpc().getType().getAllowedProperties().stream().map(EntityPropertyImpl::getName)); .getNpc().getType().getAllowedProperties().stream().map(EntityPropertyImpl::getName));
if (context.argSize() == 3) { if (context.argSize() == 3) {

@ -1,13 +1,11 @@
package lol.pyr.znpcsplus.commands; package lol.pyr.znpcsplus.commands;
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
import lol.pyr.director.adventure.command.CommandContext; import lol.pyr.director.adventure.command.CommandContext;
import lol.pyr.director.adventure.command.CommandHandler; import lol.pyr.director.adventure.command.CommandHandler;
import lol.pyr.director.common.command.CommandExecutionException; import lol.pyr.director.common.command.CommandExecutionException;
import lol.pyr.znpcsplus.entity.EntityPropertyImpl; import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
import lol.pyr.znpcsplus.npc.NpcEntryImpl; import lol.pyr.znpcsplus.npc.*;
import lol.pyr.znpcsplus.npc.NpcImpl;
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
import lol.pyr.znpcsplus.npc.NpcTypeImpl;
import lol.pyr.znpcsplus.skin.cache.SkinCache; import lol.pyr.znpcsplus.skin.cache.SkinCache;
import lol.pyr.znpcsplus.skin.descriptor.FetchingDescriptor; import lol.pyr.znpcsplus.skin.descriptor.FetchingDescriptor;
import lol.pyr.znpcsplus.skin.descriptor.MirrorDescriptor; import lol.pyr.znpcsplus.skin.descriptor.MirrorDescriptor;
@ -21,17 +19,19 @@ import java.util.List;
public class SkinCommand implements CommandHandler { public class SkinCommand implements CommandHandler {
private final SkinCache skinCache; private final SkinCache skinCache;
private final NpcRegistryImpl npcRegistry; private final NpcRegistryImpl npcRegistry;
private final NpcTypeRegistry typeRegistry;
public SkinCommand(SkinCache skinCache, NpcRegistryImpl npcRegistry) { public SkinCommand(SkinCache skinCache, NpcRegistryImpl npcRegistry, NpcTypeRegistry typeRegistry) {
this.skinCache = skinCache; this.skinCache = skinCache;
this.npcRegistry = npcRegistry; this.npcRegistry = npcRegistry;
this.typeRegistry = typeRegistry;
} }
@Override @Override
public void run(CommandContext context) throws CommandExecutionException { public void run(CommandContext context) throws CommandExecutionException {
context.setUsage(context.getLabel() + " skin <id> <type> [value]"); context.setUsage(context.getLabel() + " skin <id> <type> [value]");
NpcImpl npc = context.parse(NpcEntryImpl.class).getNpc(); NpcImpl npc = context.parse(NpcEntryImpl.class).getNpc();
if (npc.getType() != NpcTypeImpl.byName("player")) context.halt(Component.text("The NPC must be a player to have a skin", NamedTextColor.RED)); if (npc.getType() != typeRegistry.getByEntityType(EntityTypes.PLAYER)) context.halt(Component.text("The NPC must be a player to have a skin", NamedTextColor.RED));
String type = context.popString(); String type = context.popString();
if (type.equalsIgnoreCase("mirror")) { if (type.equalsIgnoreCase("mirror")) {
@ -68,7 +68,7 @@ public class SkinCommand implements CommandHandler {
@Override @Override
public List<String> suggest(CommandContext context) throws CommandExecutionException { public List<String> suggest(CommandContext context) throws CommandExecutionException {
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.modifiableIds()); if (context.argSize() == 1) return context.suggestCollection(npcRegistry.getModifiableIds());
if (context.argSize() == 2) return context.suggestLiteral("mirror", "static", "dynamic"); if (context.argSize() == 2) return context.suggestLiteral("mirror", "static", "dynamic");
if (context.matchSuggestion("*", "static")) return context.suggestPlayers(); if (context.matchSuggestion("*", "static")) return context.suggestPlayers();
return Collections.emptyList(); return Collections.emptyList();

@ -32,7 +32,7 @@ public class TeleportCommand implements CommandHandler {
@Override @Override
public List<String> suggest(CommandContext context) throws CommandExecutionException { public List<String> suggest(CommandContext context) throws CommandExecutionException {
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.modifiableIds()); if (context.argSize() == 1) return context.suggestCollection(npcRegistry.getModifiableIds());
return Collections.emptyList(); return Collections.emptyList();
} }
} }

@ -3,10 +3,7 @@ package lol.pyr.znpcsplus.commands;
import lol.pyr.director.adventure.command.CommandContext; import lol.pyr.director.adventure.command.CommandContext;
import lol.pyr.director.adventure.command.CommandHandler; import lol.pyr.director.adventure.command.CommandHandler;
import lol.pyr.director.common.command.CommandExecutionException; import lol.pyr.director.common.command.CommandExecutionException;
import lol.pyr.znpcsplus.npc.NpcEntryImpl; import lol.pyr.znpcsplus.npc.*;
import lol.pyr.znpcsplus.npc.NpcImpl;
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
import lol.pyr.znpcsplus.npc.NpcTypeImpl;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
@ -15,9 +12,11 @@ import java.util.List;
public class TypeCommand implements CommandHandler { public class TypeCommand implements CommandHandler {
private final NpcRegistryImpl registry; private final NpcRegistryImpl registry;
private final NpcTypeRegistry typeRegistry;
public TypeCommand(NpcRegistryImpl registry) { public TypeCommand(NpcRegistryImpl registry, NpcTypeRegistry typeRegistry) {
this.registry = registry; this.registry = registry;
this.typeRegistry = typeRegistry;
} }
@Override @Override
@ -31,8 +30,8 @@ public class TypeCommand implements CommandHandler {
@Override @Override
public List<String> suggest(CommandContext context) throws CommandExecutionException { public List<String> suggest(CommandContext context) throws CommandExecutionException {
if (context.argSize() == 1) return context.suggestCollection(registry.modifiableIds()); if (context.argSize() == 1) return context.suggestCollection(registry.getModifiableIds());
if (context.argSize() == 2) return context.suggestStream(NpcTypeImpl.values().stream().map(NpcTypeImpl::getName)); if (context.argSize() == 2) return context.suggestStream(typeRegistry.getAll().stream().map(NpcTypeImpl::getName));
return Collections.emptyList(); return Collections.emptyList();
} }
} }

@ -31,7 +31,7 @@ public class ActionDeleteCommand implements CommandHandler {
@Override @Override
public List<String> suggest(CommandContext context) throws CommandExecutionException { public List<String> suggest(CommandContext context) throws CommandExecutionException {
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.modifiableIds()); if (context.argSize() == 1) return context.suggestCollection(npcRegistry.getModifiableIds());
if (context.argSize() == 2) return context.suggestStream(Stream.iterate(0, n -> n + 1) if (context.argSize() == 2) return context.suggestStream(Stream.iterate(0, n -> n + 1)
.limit(context.suggestionParse(0, NpcEntryImpl.class).getNpc().getActions().size()) .limit(context.suggestionParse(0, NpcEntryImpl.class).getNpc().getActions().size())
.map(String::valueOf)); .map(String::valueOf));

@ -33,7 +33,7 @@ public class HoloAddCommand implements CommandHandler {
@Override @Override
public List<String> suggest(CommandContext context) throws CommandExecutionException { public List<String> suggest(CommandContext context) throws CommandExecutionException {
if (context.argSize() == 1) return context.suggestCollection(registry.modifiableIds()); if (context.argSize() == 1) return context.suggestCollection(registry.getModifiableIds());
return Collections.emptyList(); return Collections.emptyList();
} }
} }

@ -32,7 +32,7 @@ public class HoloDeleteCommand implements CommandHandler {
@Override @Override
public List<String> suggest(CommandContext context) throws CommandExecutionException { public List<String> suggest(CommandContext context) throws CommandExecutionException {
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.modifiableIds()); if (context.argSize() == 1) return context.suggestCollection(npcRegistry.getModifiableIds());
if (context.argSize() == 2) return context.suggestStream(Stream.iterate(0, n -> n + 1) if (context.argSize() == 2) return context.suggestStream(Stream.iterate(0, n -> n + 1)
.limit(context.suggestionParse(0, NpcEntryImpl.class).getNpc().getHologram().getLines().size()) .limit(context.suggestionParse(0, NpcEntryImpl.class).getNpc().getHologram().getLines().size())
.map(String::valueOf)); .map(String::valueOf));

@ -32,7 +32,7 @@ public class HoloInfoCommand implements CommandHandler {
@Override @Override
public List<String> suggest(CommandContext context) throws CommandExecutionException { public List<String> suggest(CommandContext context) throws CommandExecutionException {
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.modifiableIds()); if (context.argSize() == 1) return context.suggestCollection(npcRegistry.getModifiableIds());
return Collections.emptyList(); return Collections.emptyList();
} }
} }

@ -36,7 +36,7 @@ public class HoloInsertCommand implements CommandHandler {
@Override @Override
public List<String> suggest(CommandContext context) throws CommandExecutionException { public List<String> suggest(CommandContext context) throws CommandExecutionException {
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.modifiableIds()); if (context.argSize() == 1) return context.suggestCollection(npcRegistry.getModifiableIds());
if (context.argSize() == 2) return context.suggestStream(Stream.iterate(0, n -> n + 1) if (context.argSize() == 2) return context.suggestStream(Stream.iterate(0, n -> n + 1)
.limit(context.suggestionParse(0, NpcEntryImpl.class).getNpc().getHologram().getLines().size()) .limit(context.suggestionParse(0, NpcEntryImpl.class).getNpc().getHologram().getLines().size())
.map(String::valueOf)); .map(String::valueOf));

@ -28,7 +28,7 @@ public class HoloOffsetCommand implements CommandHandler {
@Override @Override
public List<String> suggest(CommandContext context) throws CommandExecutionException { public List<String> suggest(CommandContext context) throws CommandExecutionException {
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.modifiableIds()); if (context.argSize() == 1) return context.suggestCollection(npcRegistry.getModifiableIds());
if (context.argSize() == 2) { if (context.argSize() == 2) {
HologramImpl hologram = context.suggestionParse(0, NpcEntryImpl.class).getNpc().getHologram(); HologramImpl hologram = context.suggestionParse(0, NpcEntryImpl.class).getNpc().getHologram();
return context.suggestLiteral(String.valueOf(hologram.getOffset())); return context.suggestLiteral(String.valueOf(hologram.getOffset()));

@ -37,7 +37,7 @@ public class HoloSetCommand implements CommandHandler {
@Override @Override
public List<String> suggest(CommandContext context) throws CommandExecutionException { public List<String> suggest(CommandContext context) throws CommandExecutionException {
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.modifiableIds()); if (context.argSize() == 1) return context.suggestCollection(npcRegistry.getModifiableIds());
if (context.argSize() >= 2) { if (context.argSize() >= 2) {
HologramImpl hologram = context.suggestionParse(0, NpcEntryImpl.class).getNpc().getHologram(); HologramImpl hologram = context.suggestionParse(0, NpcEntryImpl.class).getNpc().getHologram();
if (context.argSize() == 2) return context.suggestStream(Stream.iterate(0, n -> n + 1) if (context.argSize() == 2) return context.suggestStream(Stream.iterate(0, n -> n + 1)

@ -7,7 +7,7 @@ import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
import lol.pyr.znpcsplus.api.entity.PropertyHolder; import lol.pyr.znpcsplus.api.entity.PropertyHolder;
import lol.pyr.znpcsplus.packets.PacketFactory; import lol.pyr.znpcsplus.packets.PacketFactory;
import lol.pyr.znpcsplus.reflection.Reflections; import lol.pyr.znpcsplus.reflection.Reflections;
import lol.pyr.znpcsplus.util.ZLocation; import lol.pyr.znpcsplus.util.NpcLocation;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.Collection; import java.util.Collection;
@ -21,9 +21,9 @@ public class PacketEntity {
private final UUID uuid; private final UUID uuid;
private final EntityType type; private final EntityType type;
private ZLocation location; private NpcLocation location;
public PacketEntity(PacketFactory packetFactory, PropertyHolder properties, EntityType type, ZLocation location) { public PacketEntity(PacketFactory packetFactory, PropertyHolder properties, EntityType type, NpcLocation location) {
this.packetFactory = packetFactory; this.packetFactory = packetFactory;
this.properties = properties; this.properties = properties;
this.entityId = reserveEntityID(); this.entityId = reserveEntityID();
@ -36,7 +36,7 @@ public class PacketEntity {
return entityId; return entityId;
} }
public ZLocation getLocation() { public NpcLocation getLocation() {
return location; return location;
} }
@ -48,7 +48,7 @@ public class PacketEntity {
return type; return type;
} }
public void setLocation(ZLocation location, Collection<Player> viewers) { public void setLocation(NpcLocation location, Collection<Player> viewers) {
this.location = location; this.location = location;
for (Player viewer : viewers) packetFactory.teleportEntity(viewer, this); for (Player viewer : viewers) packetFactory.teleportEntity(viewer, this);
} }

@ -4,7 +4,7 @@ import lol.pyr.znpcsplus.api.hologram.Hologram;
import lol.pyr.znpcsplus.config.ConfigManager; import lol.pyr.znpcsplus.config.ConfigManager;
import lol.pyr.znpcsplus.packets.PacketFactory; import lol.pyr.znpcsplus.packets.PacketFactory;
import lol.pyr.znpcsplus.util.Viewable; import lol.pyr.znpcsplus.util.Viewable;
import lol.pyr.znpcsplus.util.ZLocation; import lol.pyr.znpcsplus.util.NpcLocation;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -17,10 +17,10 @@ public class HologramImpl extends Viewable implements Hologram {
private final PacketFactory packetFactory; private final PacketFactory packetFactory;
private double offset = 0.0; private double offset = 0.0;
private ZLocation location; private NpcLocation location;
private final List<HologramLine> lines = new ArrayList<>(); private final List<HologramLine> lines = new ArrayList<>();
public HologramImpl(ConfigManager configManager, PacketFactory packetFactory, ZLocation location) { public HologramImpl(ConfigManager configManager, PacketFactory packetFactory, NpcLocation location) {
this.configManager = configManager; this.configManager = configManager;
this.packetFactory = packetFactory; this.packetFactory = packetFactory;
this.location = location; this.location = location;
@ -69,7 +69,7 @@ public class HologramImpl extends Viewable implements Hologram {
for (HologramLine line : lines) line.hide(player); for (HologramLine line : lines) line.hide(player);
} }
public void setLocation(ZLocation location) { public void setLocation(NpcLocation location) {
this.location = location; this.location = location;
relocateLines(); relocateLines();
} }

@ -6,7 +6,7 @@ import lol.pyr.znpcsplus.api.entity.PropertyHolder;
import lol.pyr.znpcsplus.entity.EntityPropertyImpl; import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
import lol.pyr.znpcsplus.entity.PacketEntity; import lol.pyr.znpcsplus.entity.PacketEntity;
import lol.pyr.znpcsplus.packets.PacketFactory; import lol.pyr.znpcsplus.packets.PacketFactory;
import lol.pyr.znpcsplus.util.ZLocation; import lol.pyr.znpcsplus.util.NpcLocation;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -16,7 +16,7 @@ public class HologramLine implements PropertyHolder {
private Component text; private Component text;
private final PacketEntity armorStand; private final PacketEntity armorStand;
public HologramLine(PacketFactory packetFactory, ZLocation location, Component text) { public HologramLine(PacketFactory packetFactory, NpcLocation location, Component text) {
this.text = text; this.text = text;
armorStand = new PacketEntity(packetFactory, this, EntityTypes.ARMOR_STAND, location); armorStand = new PacketEntity(packetFactory, this, EntityTypes.ARMOR_STAND, location);
} }
@ -37,7 +37,7 @@ public class HologramLine implements PropertyHolder {
armorStand.despawn(player); armorStand.despawn(player);
} }
public void setLocation(ZLocation location, Collection<Player> viewers) { public void setLocation(NpcLocation location, Collection<Player> viewers) {
armorStand.setLocation(location, viewers); armorStand.setLocation(location, viewers);
} }

@ -7,7 +7,6 @@ import lol.pyr.znpcsplus.interaction.switchserver.SwitchServerActionType;
import lol.pyr.znpcsplus.npc.NpcRegistryImpl; import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
import lol.pyr.znpcsplus.scheduling.TaskScheduler; import lol.pyr.znpcsplus.scheduling.TaskScheduler;
import lol.pyr.znpcsplus.util.BungeeConnector; import lol.pyr.znpcsplus.util.BungeeConnector;
import lol.pyr.znpcsplus.util.StringSerializer;
import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
@ -50,7 +49,7 @@ public class ActionRegistry {
try { try {
String[] split = str.split(";"); String[] split = str.split(";");
Class<?> clazz = Class.forName(split[0]); Class<?> clazz = Class.forName(split[0]);
StringSerializer<T> serializer = (StringSerializer<T>) serializerMap.get(clazz); InteractionActionType<T> serializer = (InteractionActionType<T>) serializerMap.get(clazz);
if (serializer == null) return null; if (serializer == null) return null;
return serializer.deserialize(String.join(";", Arrays.copyOfRange(split, 1, split.length))); return serializer.deserialize(String.join(";", Arrays.copyOfRange(split, 1, split.length)));
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
@ -60,7 +59,7 @@ public class ActionRegistry {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T extends InteractionAction> String serialize(T action) { public <T extends InteractionAction> String serialize(T action) {
StringSerializer<T> serializer = (StringSerializer<T>) serializerMap.get(action.getClass()); InteractionActionType<T> serializer = (InteractionActionType<T>) serializerMap.get(action.getClass());
if (serializer == null) return null; if (serializer == null) return null;
return action.getClass().getName() + ";" + serializer.serialize(action); return action.getClass().getName() + ";" + serializer.serialize(action);
} }

@ -57,7 +57,7 @@ public class ConsoleCommandActionType implements InteractionActionType<ConsoleCo
@Override @Override
public List<String> suggest(CommandContext context) throws CommandExecutionException { public List<String> suggest(CommandContext context) throws CommandExecutionException {
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.modifiableIds()); if (context.argSize() == 1) return context.suggestCollection(npcRegistry.getModifiableIds());
if (context.argSize() == 2) return context.suggestLiteral("1"); if (context.argSize() == 2) return context.suggestLiteral("1");
return Collections.emptyList(); return Collections.emptyList();
} }

@ -61,7 +61,7 @@ public class MessageActionType implements InteractionActionType<MessageAction>,
@Override @Override
public List<String> suggest(CommandContext context) throws CommandExecutionException { public List<String> suggest(CommandContext context) throws CommandExecutionException {
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.modifiableIds()); if (context.argSize() == 1) return context.suggestCollection(npcRegistry.getModifiableIds());
if (context.argSize() == 2) return context.suggestLiteral("1"); if (context.argSize() == 2) return context.suggestLiteral("1");
return Collections.emptyList(); return Collections.emptyList();
} }

@ -57,7 +57,7 @@ public class PlayerCommandActionType implements InteractionActionType<PlayerComm
@Override @Override
public List<String> suggest(CommandContext context) throws CommandExecutionException { public List<String> suggest(CommandContext context) throws CommandExecutionException {
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.modifiableIds()); if (context.argSize() == 1) return context.suggestCollection(npcRegistry.getModifiableIds());
if (context.argSize() == 2) return context.suggestLiteral("1"); if (context.argSize() == 2) return context.suggestLiteral("1");
return Collections.emptyList(); return Collections.emptyList();
} }

@ -57,7 +57,7 @@ public class SwitchServerActionType implements InteractionActionType<SwitchServe
@Override @Override
public List<String> suggest(CommandContext context) throws CommandExecutionException { public List<String> suggest(CommandContext context) throws CommandExecutionException {
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.modifiableIds()); if (context.argSize() == 1) return context.suggestCollection(npcRegistry.getModifiableIds());
if (context.argSize() == 2) return context.suggestLiteral("1"); if (context.argSize() == 2) return context.suggestLiteral("1");
return Collections.emptyList(); return Collections.emptyList();
} }

@ -9,7 +9,7 @@ import lol.pyr.znpcsplus.hologram.HologramImpl;
import lol.pyr.znpcsplus.interaction.InteractionAction; import lol.pyr.znpcsplus.interaction.InteractionAction;
import lol.pyr.znpcsplus.packets.PacketFactory; import lol.pyr.znpcsplus.packets.PacketFactory;
import lol.pyr.znpcsplus.util.Viewable; import lol.pyr.znpcsplus.util.Viewable;
import lol.pyr.znpcsplus.util.ZLocation; import lol.pyr.znpcsplus.util.NpcLocation;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
@ -21,18 +21,18 @@ public class NpcImpl extends Viewable implements Npc {
private final PacketFactory packetFactory; private final PacketFactory packetFactory;
private final String worldName; private final String worldName;
private PacketEntity entity; private PacketEntity entity;
private ZLocation location; private NpcLocation location;
private NpcTypeImpl type; private NpcTypeImpl type;
private final HologramImpl hologram; private final HologramImpl hologram;
private final Map<EntityPropertyImpl<?>, Object> propertyMap = new HashMap<>(); private final Map<EntityPropertyImpl<?>, Object> propertyMap = new HashMap<>();
private final List<InteractionAction> actions = new ArrayList<>(); private final List<InteractionAction> actions = new ArrayList<>();
protected NpcImpl(ConfigManager configManager, World world, NpcTypeImpl type, ZLocation location, PacketFactory packetFactory) { protected NpcImpl(ConfigManager configManager, World world, NpcTypeImpl type, NpcLocation location, PacketFactory packetFactory) {
this(configManager, packetFactory, world.getName(), type, location); this(configManager, packetFactory, world.getName(), type, location);
} }
public NpcImpl(ConfigManager configManager, PacketFactory packetFactory, String world, NpcTypeImpl type, ZLocation location) { public NpcImpl(ConfigManager configManager, PacketFactory packetFactory, String world, NpcTypeImpl type, NpcLocation location) {
this.packetFactory = packetFactory; this.packetFactory = packetFactory;
this.worldName = world; this.worldName = world;
this.type = type; this.type = type;
@ -57,7 +57,7 @@ public class NpcImpl extends Viewable implements Npc {
return entity; return entity;
} }
public ZLocation getLocation() { public NpcLocation getLocation() {
return location; return location;
} }
@ -65,7 +65,7 @@ public class NpcImpl extends Viewable implements Npc {
return location.toBukkitLocation(getWorld()); return location.toBukkitLocation(getWorld());
} }
public void setLocation(ZLocation location) { public void setLocation(NpcLocation location) {
this.location = location; this.location = location;
entity.setLocation(location, getViewers()); entity.setLocation(location, getViewers());
hologram.setLocation(location.withY(location.getY() + type.getHologramOffset())); hologram.setLocation(location.withY(location.getY() + type.getHologramOffset()));

@ -8,7 +8,7 @@ import lol.pyr.znpcsplus.interaction.ActionRegistry;
import lol.pyr.znpcsplus.packets.PacketFactory; import lol.pyr.znpcsplus.packets.PacketFactory;
import lol.pyr.znpcsplus.scheduling.TaskScheduler; import lol.pyr.znpcsplus.scheduling.TaskScheduler;
import lol.pyr.znpcsplus.storage.NpcStorage; import lol.pyr.znpcsplus.storage.NpcStorage;
import lol.pyr.znpcsplus.util.ZLocation; import lol.pyr.znpcsplus.util.NpcLocation;
import org.bukkit.World; import org.bukkit.World;
import java.util.Collection; import java.util.Collection;
@ -22,8 +22,8 @@ public class NpcRegistryImpl implements NpcRegistry {
private final PacketFactory packetFactory; private final PacketFactory packetFactory;
private final ConfigManager configManager; private final ConfigManager configManager;
public NpcRegistryImpl(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistry actionRegistry, TaskScheduler scheduler) { public NpcRegistryImpl(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistry actionRegistry, TaskScheduler scheduler, NpcTypeRegistry typeRegistry) {
storage = configManager.getConfig().storageType().create(configManager, plugin, packetFactory, actionRegistry); storage = configManager.getConfig().storageType().create(configManager, plugin, packetFactory, actionRegistry, typeRegistry);
this.packetFactory = packetFactory; this.packetFactory = packetFactory;
this.configManager = configManager; this.configManager = configManager;
@ -48,36 +48,36 @@ public class NpcRegistryImpl implements NpcRegistry {
return npcMap.get(id.toLowerCase()); return npcMap.get(id.toLowerCase());
} }
public Collection<NpcEntryImpl> all() { public Collection<NpcEntryImpl> getAll() {
return Collections.unmodifiableCollection(npcMap.values()); return Collections.unmodifiableCollection(npcMap.values());
} }
public Collection<NpcEntryImpl> allModifiable() { public Collection<NpcEntryImpl> getAllModifiable() {
return Collections.unmodifiableCollection(npcMap.values().stream() return Collections.unmodifiableCollection(npcMap.values().stream()
.filter(NpcEntryImpl::isAllowCommandModification) .filter(NpcEntryImpl::isAllowCommandModification)
.collect(Collectors.toList())); .collect(Collectors.toList()));
} }
public NpcEntryImpl getByEntityId(int id) { public NpcEntryImpl getByEntityId(int id) {
return all().stream().filter(entry -> entry.getNpc().getEntity().getEntityId() == id).findFirst().orElse(null); return getAll().stream().filter(entry -> entry.getNpc().getEntity().getEntityId() == id).findFirst().orElse(null);
} }
public Collection<String> ids() { public Collection<String> getIds() {
return Collections.unmodifiableSet(npcMap.keySet()); return Collections.unmodifiableSet(npcMap.keySet());
} }
public Collection<String> modifiableIds() { public Collection<String> getModifiableIds() {
return Collections.unmodifiableSet(npcMap.entrySet().stream() return Collections.unmodifiableSet(npcMap.entrySet().stream()
.filter(entry -> entry.getValue().isAllowCommandModification()) .filter(entry -> entry.getValue().isAllowCommandModification())
.map(Map.Entry::getKey) .map(Map.Entry::getKey)
.collect(Collectors.toSet())); .collect(Collectors.toSet()));
} }
public NpcEntryImpl create(String id, World world, NpcType type, ZLocation location) { public NpcEntryImpl create(String id, World world, NpcType type, NpcLocation location) {
return create(id, world, (NpcTypeImpl) type, location); return create(id, world, (NpcTypeImpl) type, location);
} }
public NpcEntryImpl create(String id, World world, NpcTypeImpl type, ZLocation location) { public NpcEntryImpl create(String id, World world, NpcTypeImpl type, NpcLocation location) {
id = id.toLowerCase(); id = id.toLowerCase();
if (npcMap.containsKey(id)) throw new IllegalArgumentException("An npc with the id " + id + " already exists!"); if (npcMap.containsKey(id)) throw new IllegalArgumentException("An npc with the id " + id + " already exists!");
NpcImpl npc = new NpcImpl(configManager, world, type, location, packetFactory); NpcImpl npc = new NpcImpl(configManager, world, type, location, packetFactory);

@ -1,26 +1,13 @@
package lol.pyr.znpcsplus.npc; package lol.pyr.znpcsplus.npc;
import com.github.retrooper.packetevents.PacketEvents; import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.PacketEventsAPI;
import com.github.retrooper.packetevents.manager.server.ServerVersion; import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.entity.type.EntityType; import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
import lol.pyr.znpcsplus.entity.EntityPropertyImpl; import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
import org.bukkit.plugin.Plugin;
import java.util.*; import java.util.*;
public class NpcTypeImpl { public class NpcTypeImpl {
private final static Map<String, NpcTypeImpl> BY_NAME = new HashMap<>();
public static Collection<NpcTypeImpl> values() {
return BY_NAME.values();
}
public static NpcTypeImpl byName(String name) {
return BY_NAME.get(name.toUpperCase());
}
private final EntityType type; private final EntityType type;
private final Set<EntityPropertyImpl<?>> allowedProperties; private final Set<EntityPropertyImpl<?>> allowedProperties;
private final String name; private final String name;
@ -49,132 +36,14 @@ public class NpcTypeImpl {
return allowedProperties; return allowedProperties;
} }
private static NpcTypeImpl define(Builder builder) { protected static final class Builder {
return define(builder.build());
}
private static NpcTypeImpl define(NpcTypeImpl type) {
BY_NAME.put(type.getName(), type);
return type;
}
private static boolean defined = false;
public static void defineTypes(PacketEventsAPI<Plugin> packetEvents) {
if (defined) return;
defined = true;
ServerVersion version = packetEvents.getServerManager().getVersion();
define(new Builder("player", EntityTypes.PLAYER).setHologramOffset(-0.15D)
.addProperties(EntityPropertyImpl.SKIN, EntityPropertyImpl.SKIN_LAYERS));
define(new Builder("armor_stand", EntityTypes.ARMOR_STAND));
define(new Builder("bat", EntityTypes.BAT).setHologramOffset(-1.365));
define(new Builder("blaze", EntityTypes.BLAZE));
define(new Builder("cat", EntityTypes.CAT));
define(new Builder("cave_spider", EntityTypes.CAVE_SPIDER));
define(new Builder("chicken", EntityTypes.CHICKEN));
define(new Builder("cow", EntityTypes.COW));
define(new Builder("creeper", EntityTypes.CREEPER).setHologramOffset(-0.3D));
define(new Builder("donkey", EntityTypes.DONKEY));
define(new Builder("elder_guardian", EntityTypes.ELDER_GUARDIAN));
define(new Builder("ender_dragon", EntityTypes.ENDER_DRAGON));
define(new Builder("enderman", EntityTypes.ENDERMAN));
define(new Builder("endermite", EntityTypes.ENDERMITE));
define(new Builder("ghast", EntityTypes.GHAST));
define(new Builder("giant", EntityTypes.GIANT));
define(new Builder("guardian", EntityTypes.GUARDIAN));
define(new Builder("horse", EntityTypes.HORSE));
define(new Builder("iron_golem", EntityTypes.IRON_GOLEM));
define(new Builder("magma_cube", EntityTypes.MAGMA_CUBE));
define(new Builder("mooshroom", EntityTypes.MOOSHROOM));
define(new Builder("mule", EntityTypes.MULE));
define(new Builder("ocelot", EntityTypes.OCELOT));
define(new Builder("pig", EntityTypes.PIG));
define(new Builder("rabbit", EntityTypes.RABBIT));
define(new Builder("sheep", EntityTypes.SHEEP));
define(new Builder("silverfish", EntityTypes.SILVERFISH));
define(new Builder("skeleton", EntityTypes.SKELETON));
define(new Builder("skeleton_horse", EntityTypes.SKELETON_HORSE));
define(new Builder("slime", EntityTypes.SLIME));
define(new Builder("snow_golem", EntityTypes.SNOW_GOLEM));
define(new Builder("spider", EntityTypes.SPIDER));
define(new Builder("squid", EntityTypes.SQUID));
define(new Builder("villager", EntityTypes.VILLAGER));
define(new Builder("witch", EntityTypes.WITCH));
define(new Builder("wither", EntityTypes.WITHER));
define(new Builder("wither_skeleton", EntityTypes.WITHER_SKELETON));
define(new Builder("wolf", EntityTypes.WOLF));
define(new Builder("zombie", EntityTypes.ZOMBIE));
define(new Builder("zombie_horse", EntityTypes.ZOMBIE_HORSE));
define(new Builder("zombie_villager", EntityTypes.ZOMBIE_VILLAGER));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_9)) return;
define(new Builder("shulker", EntityTypes.SHULKER));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_10)) return;
define(new Builder("husk", EntityTypes.HUSK));
define(new Builder("polar_bear", EntityTypes.POLAR_BEAR));
define(new Builder("stray", EntityTypes.STRAY));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_11)) return;
define(new Builder("evoker", EntityTypes.EVOKER));
define(new Builder("llama", EntityTypes.LLAMA));
define(new Builder("vex", EntityTypes.VEX));
define(new Builder("vindicator", EntityTypes.VINDICATOR));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_12)) return;
define(new Builder("illusioner", EntityTypes.ILLUSIONER));
define(new Builder("parrot", EntityTypes.PARROT));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_13)) return;
define(new Builder("cod", EntityTypes.COD));
define(new Builder("dolphin", EntityTypes.DOLPHIN));
define(new Builder("drowned", EntityTypes.DROWNED));
define(new Builder("phantom", EntityTypes.PHANTOM));
define(new Builder("pufferfish", EntityTypes.PUFFERFISH));
define(new Builder("salmon", EntityTypes.SALMON));
define(new Builder("tropical_fish", EntityTypes.TROPICAL_FISH));
define(new Builder("turtle", EntityTypes.TURTLE));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_14)) return;
define(new Builder("fox", EntityTypes.FOX));
define(new Builder("panda", EntityTypes.PANDA));
define(new Builder("pillager", EntityTypes.PILLAGER));
define(new Builder("ravager", EntityTypes.RAVAGER));
define(new Builder("trader_llama", EntityTypes.TRADER_LLAMA));
define(new Builder("wandering_trader", EntityTypes.WANDERING_TRADER));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_15)) return;
define(new Builder("bee", EntityTypes.BEE));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_16)) return;
define(new Builder("hoglin", EntityTypes.HOGLIN));
define(new Builder("piglin", EntityTypes.PIGLIN));
define(new Builder("piglin_brute", EntityTypes.PIGLIN_BRUTE));
define(new Builder("strider", EntityTypes.STRIDER));
define(new Builder("zoglin", EntityTypes.ZOGLIN));
define(new Builder("zombified_piglin", EntityTypes.ZOMBIFIED_PIGLIN));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_17)) return;
define(new Builder("axolotl", EntityTypes.AXOLOTL));
define(new Builder("glow_squid", EntityTypes.GLOW_SQUID));
define(new Builder("goat", EntityTypes.GOAT));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_19)) return;
define(new Builder("allay", EntityTypes.ALLAY));
define(new Builder("frog", EntityTypes.FROG));
define(new Builder("tadpole", EntityTypes.TADPOLE));
define(new Builder("warden", EntityTypes.WARDEN));
}
private static final class Builder {
private final String name; private final String name;
private final EntityType type; private final EntityType type;
private final List<EntityPropertyImpl<?>> allowedProperties = new ArrayList<>(); private final List<EntityPropertyImpl<?>> allowedProperties = new ArrayList<>();
private boolean globalProperties = true; private boolean globalProperties = true;
private double hologramOffset = 0; private double hologramOffset = 0;
private Builder(String name, EntityType type) { Builder(String name, EntityType type) {
this.name = name; this.name = name;
this.type = type; this.type = type;
} }

@ -0,0 +1,146 @@
package lol.pyr.znpcsplus.npc;
import com.github.retrooper.packetevents.PacketEventsAPI;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
import org.bukkit.plugin.Plugin;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class NpcTypeRegistry {
private final List<NpcTypeImpl> types = new ArrayList<>();
private NpcTypeImpl define(NpcTypeImpl.Builder builder) {
return define(builder.build());
}
private NpcTypeImpl define(NpcTypeImpl type) {
types.add(type);
return type;
}
public void registerDefault(PacketEventsAPI<Plugin> packetEvents) {
ServerVersion version = packetEvents.getServerManager().getVersion();
define(new NpcTypeImpl.Builder("player", EntityTypes.PLAYER).setHologramOffset(-0.15D)
.addProperties(EntityPropertyImpl.SKIN, EntityPropertyImpl.SKIN_LAYERS));
define(new NpcTypeImpl.Builder("armor_stand", EntityTypes.ARMOR_STAND));
define(new NpcTypeImpl.Builder("bat", EntityTypes.BAT).setHologramOffset(-1.365));
define(new NpcTypeImpl.Builder("blaze", EntityTypes.BLAZE));
define(new NpcTypeImpl.Builder("cat", EntityTypes.CAT));
define(new NpcTypeImpl.Builder("cave_spider", EntityTypes.CAVE_SPIDER));
define(new NpcTypeImpl.Builder("chicken", EntityTypes.CHICKEN));
define(new NpcTypeImpl.Builder("cow", EntityTypes.COW));
define(new NpcTypeImpl.Builder("creeper", EntityTypes.CREEPER).setHologramOffset(-0.3D));
define(new NpcTypeImpl.Builder("donkey", EntityTypes.DONKEY));
define(new NpcTypeImpl.Builder("elder_guardian", EntityTypes.ELDER_GUARDIAN));
define(new NpcTypeImpl.Builder("ender_dragon", EntityTypes.ENDER_DRAGON));
define(new NpcTypeImpl.Builder("enderman", EntityTypes.ENDERMAN));
define(new NpcTypeImpl.Builder("endermite", EntityTypes.ENDERMITE));
define(new NpcTypeImpl.Builder("ghast", EntityTypes.GHAST));
define(new NpcTypeImpl.Builder("giant", EntityTypes.GIANT));
define(new NpcTypeImpl.Builder("guardian", EntityTypes.GUARDIAN));
define(new NpcTypeImpl.Builder("horse", EntityTypes.HORSE));
define(new NpcTypeImpl.Builder("iron_golem", EntityTypes.IRON_GOLEM));
define(new NpcTypeImpl.Builder("magma_cube", EntityTypes.MAGMA_CUBE));
define(new NpcTypeImpl.Builder("mooshroom", EntityTypes.MOOSHROOM));
define(new NpcTypeImpl.Builder("mule", EntityTypes.MULE));
define(new NpcTypeImpl.Builder("ocelot", EntityTypes.OCELOT));
define(new NpcTypeImpl.Builder("pig", EntityTypes.PIG));
define(new NpcTypeImpl.Builder("rabbit", EntityTypes.RABBIT));
define(new NpcTypeImpl.Builder("sheep", EntityTypes.SHEEP));
define(new NpcTypeImpl.Builder("silverfish", EntityTypes.SILVERFISH));
define(new NpcTypeImpl.Builder("skeleton", EntityTypes.SKELETON));
define(new NpcTypeImpl.Builder("skeleton_horse", EntityTypes.SKELETON_HORSE));
define(new NpcTypeImpl.Builder("slime", EntityTypes.SLIME));
define(new NpcTypeImpl.Builder("snow_golem", EntityTypes.SNOW_GOLEM));
define(new NpcTypeImpl.Builder("spider", EntityTypes.SPIDER));
define(new NpcTypeImpl.Builder("squid", EntityTypes.SQUID));
define(new NpcTypeImpl.Builder("villager", EntityTypes.VILLAGER));
define(new NpcTypeImpl.Builder("witch", EntityTypes.WITCH));
define(new NpcTypeImpl.Builder("wither", EntityTypes.WITHER));
define(new NpcTypeImpl.Builder("wither_skeleton", EntityTypes.WITHER_SKELETON));
define(new NpcTypeImpl.Builder("wolf", EntityTypes.WOLF));
define(new NpcTypeImpl.Builder("zombie", EntityTypes.ZOMBIE));
define(new NpcTypeImpl.Builder("zombie_horse", EntityTypes.ZOMBIE_HORSE));
define(new NpcTypeImpl.Builder("zombie_villager", EntityTypes.ZOMBIE_VILLAGER));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_9)) return;
define(new NpcTypeImpl.Builder("shulker", EntityTypes.SHULKER));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_10)) return;
define(new NpcTypeImpl.Builder("husk", EntityTypes.HUSK));
define(new NpcTypeImpl.Builder("polar_bear", EntityTypes.POLAR_BEAR));
define(new NpcTypeImpl.Builder("stray", EntityTypes.STRAY));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_11)) return;
define(new NpcTypeImpl.Builder("evoker", EntityTypes.EVOKER));
define(new NpcTypeImpl.Builder("llama", EntityTypes.LLAMA));
define(new NpcTypeImpl.Builder("vex", EntityTypes.VEX));
define(new NpcTypeImpl.Builder("vindicator", EntityTypes.VINDICATOR));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_12)) return;
define(new NpcTypeImpl.Builder("illusioner", EntityTypes.ILLUSIONER));
define(new NpcTypeImpl.Builder("parrot", EntityTypes.PARROT));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_13)) return;
define(new NpcTypeImpl.Builder("cod", EntityTypes.COD));
define(new NpcTypeImpl.Builder("dolphin", EntityTypes.DOLPHIN));
define(new NpcTypeImpl.Builder("drowned", EntityTypes.DROWNED));
define(new NpcTypeImpl.Builder("phantom", EntityTypes.PHANTOM));
define(new NpcTypeImpl.Builder("pufferfish", EntityTypes.PUFFERFISH));
define(new NpcTypeImpl.Builder("salmon", EntityTypes.SALMON));
define(new NpcTypeImpl.Builder("tropical_fish", EntityTypes.TROPICAL_FISH));
define(new NpcTypeImpl.Builder("turtle", EntityTypes.TURTLE));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_14)) return;
define(new NpcTypeImpl.Builder("fox", EntityTypes.FOX));
define(new NpcTypeImpl.Builder("panda", EntityTypes.PANDA));
define(new NpcTypeImpl.Builder("pillager", EntityTypes.PILLAGER));
define(new NpcTypeImpl.Builder("ravager", EntityTypes.RAVAGER));
define(new NpcTypeImpl.Builder("trader_llama", EntityTypes.TRADER_LLAMA));
define(new NpcTypeImpl.Builder("wandering_trader", EntityTypes.WANDERING_TRADER));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_15)) return;
define(new NpcTypeImpl.Builder("bee", EntityTypes.BEE));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_16)) return;
define(new NpcTypeImpl.Builder("hoglin", EntityTypes.HOGLIN));
define(new NpcTypeImpl.Builder("piglin", EntityTypes.PIGLIN));
define(new NpcTypeImpl.Builder("piglin_brute", EntityTypes.PIGLIN_BRUTE));
define(new NpcTypeImpl.Builder("strider", EntityTypes.STRIDER));
define(new NpcTypeImpl.Builder("zoglin", EntityTypes.ZOGLIN));
define(new NpcTypeImpl.Builder("zombified_piglin", EntityTypes.ZOMBIFIED_PIGLIN));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_17)) return;
define(new NpcTypeImpl.Builder("axolotl", EntityTypes.AXOLOTL));
define(new NpcTypeImpl.Builder("glow_squid", EntityTypes.GLOW_SQUID));
define(new NpcTypeImpl.Builder("goat", EntityTypes.GOAT));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_19)) return;
define(new NpcTypeImpl.Builder("allay", EntityTypes.ALLAY));
define(new NpcTypeImpl.Builder("frog", EntityTypes.FROG));
define(new NpcTypeImpl.Builder("tadpole", EntityTypes.TADPOLE));
define(new NpcTypeImpl.Builder("warden", EntityTypes.WARDEN));
}
public Collection<NpcTypeImpl> getAll() {
return Collections.unmodifiableList(types);
}
public NpcTypeImpl getByName(String name) {
for (NpcTypeImpl type : types) if (type.getName().equalsIgnoreCase(name)) return type;
return null;
}
public NpcTypeImpl getByEntityType(EntityType entityType) {
for (NpcTypeImpl type : types) if (type.getType() == entityType) return type;
return null;
}
}

@ -7,7 +7,7 @@ import lol.pyr.znpcsplus.api.entity.PropertyHolder;
import lol.pyr.znpcsplus.entity.PacketEntity; import lol.pyr.znpcsplus.entity.PacketEntity;
import lol.pyr.znpcsplus.metadata.MetadataFactory; import lol.pyr.znpcsplus.metadata.MetadataFactory;
import lol.pyr.znpcsplus.scheduling.TaskScheduler; import lol.pyr.znpcsplus.scheduling.TaskScheduler;
import lol.pyr.znpcsplus.util.ZLocation; import lol.pyr.znpcsplus.util.NpcLocation;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
@ -20,7 +20,7 @@ public class V1_14PacketFactory extends V1_10PacketFactory {
@Override @Override
public void spawnEntity(Player player, PacketEntity entity, PropertyHolder properties) { public void spawnEntity(Player player, PacketEntity entity, PropertyHolder properties) {
ZLocation location = entity.getLocation(); NpcLocation location = entity.getLocation();
sendPacket(player, new WrapperPlayServerSpawnEntity(entity.getEntityId(), Optional.of(entity.getUuid()), entity.getType(), sendPacket(player, new WrapperPlayServerSpawnEntity(entity.getEntityId(), Optional.of(entity.getUuid()), entity.getType(),
location.toVector3d(), location.getPitch(), location.getYaw(), location.getYaw(), 0, Optional.of(new Vector3d()))); location.toVector3d(), location.getPitch(), location.getYaw(), location.getYaw(), 0, Optional.of(new Vector3d())));
sendAllMetadata(player, entity, properties); sendAllMetadata(player, entity, properties);

@ -16,7 +16,7 @@ import lol.pyr.znpcsplus.entity.PacketEntity;
import lol.pyr.znpcsplus.metadata.MetadataFactory; import lol.pyr.znpcsplus.metadata.MetadataFactory;
import lol.pyr.znpcsplus.scheduling.TaskScheduler; import lol.pyr.znpcsplus.scheduling.TaskScheduler;
import lol.pyr.znpcsplus.skin.BaseSkinDescriptor; import lol.pyr.znpcsplus.skin.BaseSkinDescriptor;
import lol.pyr.znpcsplus.util.ZLocation; import lol.pyr.znpcsplus.util.NpcLocation;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -40,7 +40,7 @@ public class V1_8PacketFactory implements PacketFactory {
public void spawnPlayer(Player player, PacketEntity entity, PropertyHolder properties) { public void spawnPlayer(Player player, PacketEntity entity, PropertyHolder properties) {
addTabPlayer(player, entity, properties).thenAccept(ignored -> { addTabPlayer(player, entity, properties).thenAccept(ignored -> {
createTeam(player, entity, properties); createTeam(player, entity, properties);
ZLocation location = entity.getLocation(); NpcLocation location = entity.getLocation();
sendPacket(player, new WrapperPlayServerSpawnPlayer(entity.getEntityId(), sendPacket(player, new WrapperPlayServerSpawnPlayer(entity.getEntityId(),
entity.getUuid(), location.toVector3d(), location.getYaw(), location.getPitch(), Collections.emptyList())); entity.getUuid(), location.toVector3d(), location.getYaw(), location.getPitch(), Collections.emptyList()));
sendPacket(player, new WrapperPlayServerEntityHeadLook(entity.getEntityId(), location.getYaw())); sendPacket(player, new WrapperPlayServerEntityHeadLook(entity.getEntityId(), location.getYaw()));
@ -51,7 +51,7 @@ public class V1_8PacketFactory implements PacketFactory {
@Override @Override
public void spawnEntity(Player player, PacketEntity entity, PropertyHolder properties) { public void spawnEntity(Player player, PacketEntity entity, PropertyHolder properties) {
ZLocation location = entity.getLocation(); NpcLocation location = entity.getLocation();
EntityType type = entity.getType(); EntityType type = entity.getType();
ClientVersion clientVersion = packetEvents.getServerManager().getVersion().toClientVersion(); ClientVersion clientVersion = packetEvents.getServerManager().getVersion().toClientVersion();
sendPacket(player, type.getLegacyId(clientVersion) == -1 ? sendPacket(player, type.getLegacyId(clientVersion) == -1 ?
@ -71,7 +71,7 @@ public class V1_8PacketFactory implements PacketFactory {
@Override @Override
public void teleportEntity(Player player, PacketEntity entity) { public void teleportEntity(Player player, PacketEntity entity) {
ZLocation location = entity.getLocation(); NpcLocation location = entity.getLocation();
sendPacket(player, new WrapperPlayServerEntityTeleport(entity.getEntityId(), location.toVector3d(), location.getYaw(), location.getPitch(), true)); sendPacket(player, new WrapperPlayServerEntityTeleport(entity.getEntityId(), location.toVector3d(), location.getYaw(), location.getPitch(), true));
if (entity.getType() == EntityTypes.PLAYER) sendPacket(player, new WrapperPlayServerEntityHeadLook(entity.getEntityId(), location.getYaw())); if (entity.getType() == EntityTypes.PLAYER) sendPacket(player, new WrapperPlayServerEntityHeadLook(entity.getEntityId(), location.getYaw()));
} }

@ -5,17 +5,21 @@ import lol.pyr.director.adventure.parse.ParserType;
import lol.pyr.director.common.command.CommandExecutionException; import lol.pyr.director.common.command.CommandExecutionException;
import lol.pyr.director.common.message.Message; import lol.pyr.director.common.message.Message;
import lol.pyr.znpcsplus.npc.NpcTypeImpl; import lol.pyr.znpcsplus.npc.NpcTypeImpl;
import lol.pyr.znpcsplus.npc.NpcTypeRegistry;
import java.util.Deque; import java.util.Deque;
public class NpcTypeParser extends ParserType<NpcTypeImpl> { public class NpcTypeParser extends ParserType<NpcTypeImpl> {
public NpcTypeParser(Message<CommandContext> message) { private final NpcTypeRegistry typeRegistry;
public NpcTypeParser(Message<CommandContext> message, NpcTypeRegistry typeRegistry) {
super(message); super(message);
this.typeRegistry = typeRegistry;
} }
@Override @Override
public NpcTypeImpl parse(Deque<String> deque) throws CommandExecutionException { public NpcTypeImpl parse(Deque<String> deque) throws CommandExecutionException {
NpcTypeImpl type = NpcTypeImpl.byName(deque.pop()); NpcTypeImpl type = typeRegistry.getByName(deque.pop());
if (type == null) throw new CommandExecutionException(); if (type == null) throw new CommandExecutionException();
return type; return type;
} }

@ -9,9 +9,9 @@ import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* A class containing all of the packages of the server jar that we import classes from. * A class containing getAll of the packages of the server jar that we import classes from.
* Every line has a check for the "flattened" variable due to the fact that server jars * Every line has a check for the "flattened" variable due to the fact that server jars
* pre-1.17 had all of their classes "flattened" into one package. * pre-1.17 had getAll of their classes "flattened" into one package.
*/ */
public class ReflectionPackage { public class ReflectionPackage {
private static final String VERSION = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; private static final String VERSION = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];

@ -16,7 +16,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer; import java.util.function.Consumer;
/** /**
* Class containing all of the lazy-loaded reflections that the plugin * Class containing getAll of the lazy-loaded reflections that the plugin
* uses to access inaccessible components of the server jar. * uses to access inaccessible components of the server jar.
*/ */
public final class Reflections { public final class Reflections {

@ -3,6 +3,7 @@ package lol.pyr.znpcsplus.storage;
import lol.pyr.znpcsplus.ZNpcsPlus; import lol.pyr.znpcsplus.ZNpcsPlus;
import lol.pyr.znpcsplus.config.ConfigManager; import lol.pyr.znpcsplus.config.ConfigManager;
import lol.pyr.znpcsplus.interaction.ActionRegistry; import lol.pyr.znpcsplus.interaction.ActionRegistry;
import lol.pyr.znpcsplus.npc.NpcTypeRegistry;
import lol.pyr.znpcsplus.packets.PacketFactory; import lol.pyr.znpcsplus.packets.PacketFactory;
import lol.pyr.znpcsplus.storage.yaml.YamlStorage; import lol.pyr.znpcsplus.storage.yaml.YamlStorage;
@ -11,10 +12,10 @@ import java.io.File;
public enum NpcStorageType { public enum NpcStorageType {
YAML { YAML {
@Override @Override
public NpcStorage create(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistry actionRegistry) { public NpcStorage create(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistry actionRegistry, NpcTypeRegistry typeRegistry) {
return new YamlStorage(packetFactory, configManager, actionRegistry, new File(plugin.getDataFolder(), "data")); return new YamlStorage(packetFactory, configManager, actionRegistry, typeRegistry, new File(plugin.getDataFolder(), "data"));
} }
}; };
public abstract NpcStorage create(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistry actionRegistry); public abstract NpcStorage create(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistry actionRegistry, NpcTypeRegistry typeRegistry);
} }

@ -6,10 +6,10 @@ import lol.pyr.znpcsplus.hologram.HologramLine;
import lol.pyr.znpcsplus.interaction.ActionRegistry; import lol.pyr.znpcsplus.interaction.ActionRegistry;
import lol.pyr.znpcsplus.npc.NpcEntryImpl; import lol.pyr.znpcsplus.npc.NpcEntryImpl;
import lol.pyr.znpcsplus.npc.NpcImpl; import lol.pyr.znpcsplus.npc.NpcImpl;
import lol.pyr.znpcsplus.npc.NpcTypeImpl; import lol.pyr.znpcsplus.npc.NpcTypeRegistry;
import lol.pyr.znpcsplus.packets.PacketFactory; import lol.pyr.znpcsplus.packets.PacketFactory;
import lol.pyr.znpcsplus.storage.NpcStorage; import lol.pyr.znpcsplus.storage.NpcStorage;
import lol.pyr.znpcsplus.util.ZLocation; import lol.pyr.znpcsplus.util.NpcLocation;
import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.MiniMessage;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
@ -23,12 +23,14 @@ public class YamlStorage implements NpcStorage {
private final PacketFactory packetFactory; private final PacketFactory packetFactory;
private final ConfigManager configManager; private final ConfigManager configManager;
private final ActionRegistry actionRegistry; private final ActionRegistry actionRegistry;
private final NpcTypeRegistry typeRegistry;
private final File folder; private final File folder;
public YamlStorage(PacketFactory packetFactory, ConfigManager configManager, ActionRegistry actionRegistry, File folder) { public YamlStorage(PacketFactory packetFactory, ConfigManager configManager, ActionRegistry actionRegistry, NpcTypeRegistry typeRegistry, File folder) {
this.packetFactory = packetFactory; this.packetFactory = packetFactory;
this.configManager = configManager; this.configManager = configManager;
this.actionRegistry = actionRegistry; this.actionRegistry = actionRegistry;
this.typeRegistry = typeRegistry;
this.folder = folder; this.folder = folder;
if (!this.folder.exists()) this.folder.mkdirs(); if (!this.folder.exists()) this.folder.mkdirs();
} }
@ -41,7 +43,7 @@ public class YamlStorage implements NpcStorage {
List<NpcEntryImpl> npcs = new ArrayList<>(); List<NpcEntryImpl> npcs = new ArrayList<>();
for (File file : files) if (file.isFile() && file.getName().toLowerCase().endsWith(".yml")) { for (File file : files) if (file.isFile() && file.getName().toLowerCase().endsWith(".yml")) {
YamlConfiguration config = YamlConfiguration.loadConfiguration(file); YamlConfiguration config = YamlConfiguration.loadConfiguration(file);
NpcImpl npc = new NpcImpl(configManager, packetFactory, config.getString("world"), NpcTypeImpl.byName(config.getString("type")), NpcImpl npc = new NpcImpl(configManager, packetFactory, config.getString("world"), typeRegistry.getByName(config.getString("type")),
deserializeLocation(config.getConfigurationSection("location"))); deserializeLocation(config.getConfigurationSection("location")));
ConfigurationSection properties = config.getConfigurationSection("properties"); ConfigurationSection properties = config.getConfigurationSection("properties");
@ -101,8 +103,8 @@ public class YamlStorage implements NpcStorage {
} }
} }
public ZLocation deserializeLocation(ConfigurationSection section) { public NpcLocation deserializeLocation(ConfigurationSection section) {
return new ZLocation( return new NpcLocation(
section.getDouble("x"), section.getDouble("x"),
section.getDouble("y"), section.getDouble("y"),
section.getDouble("z"), section.getDouble("z"),
@ -111,7 +113,7 @@ public class YamlStorage implements NpcStorage {
); );
} }
public YamlConfiguration serializeLocation(ZLocation location) { public YamlConfiguration serializeLocation(NpcLocation location) {
YamlConfiguration config = new YamlConfiguration(); YamlConfiguration config = new YamlConfiguration();
config.set("x", location.getX()); config.set("x", location.getX());
config.set("y", location.getY()); config.set("y", location.getY());

@ -20,7 +20,7 @@ public class NpcVisibilityTask extends BukkitRunnable {
public void run() { public void run() {
double distSq = NumberConversions.square(configManager.getConfig().viewDistance()); double distSq = NumberConversions.square(configManager.getConfig().viewDistance());
for (NpcEntryImpl entry : npcRegistry.all()) { for (NpcEntryImpl entry : npcRegistry.getAll()) {
if (!entry.isProcessed()) continue; if (!entry.isProcessed()) continue;
NpcImpl npc = entry.getNpc(); NpcImpl npc = entry.getNpc();
for (Player player : Bukkit.getOnlinePlayers()) { for (Player player : Bukkit.getOnlinePlayers()) {