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;
public interface ZApi {
public interface NpcApi {
NpcRegistry getNpcRegistry();
}

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

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

@ -5,14 +5,14 @@ import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.util.NumberConversions;
public class ZLocation {
public class NpcLocation {
private final double x;
private final double y;
private final double z;
private final float yaw;
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.y = y;
this.z = z;
@ -20,7 +20,7 @@ public class ZLocation {
this.pitch = pitch;
}
public ZLocation(Location location) {
public NpcLocation(Location location) {
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);
}
public ZLocation withY(double y) {
return new ZLocation(x, y, z, yaw, pitch);
public NpcLocation withY(double y) {
return new NpcLocation(x, y, z, yaw, pitch);
}
public Vector3d toVector3d() {
@ -71,16 +71,16 @@ public class ZLocation {
private static final double _2PI = 2 * Math.PI;
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 z = loc.getZ() - this.z;
final double y = loc.getY() - this.y;
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);
@ -91,6 +91,6 @@ public class ZLocation {
float yaw = (float) Math.toDegrees((theta + _2PI) % _2PI);
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;
import lol.pyr.znpcsplus.api.ZApi;
import lol.pyr.znpcsplus.api.NpcApi;
import lol.pyr.znpcsplus.api.npc.NpcRegistry;
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
public class ZNPCsPlusApi implements ZApi {
public class ZNPCsPlusApi implements NpcApi {
private final 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.IntegerParser;
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.action.ActionAddCommand;
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.InteractionPacketListener;
import lol.pyr.znpcsplus.metadata.*;
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
import lol.pyr.znpcsplus.npc.NpcImpl;
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
import lol.pyr.znpcsplus.npc.NpcTypeImpl;
import lol.pyr.znpcsplus.npc.*;
import lol.pyr.znpcsplus.packets.*;
import lol.pyr.znpcsplus.parsers.EntityPropertyParser;
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.FoliaUtil;
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.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
@ -113,18 +110,19 @@ public class ZNpcsPlus extends JavaPlugin {
BungeeConnector bungeeConnector = new BungeeConnector(this);
ConfigManager configManager = new ConfigManager(getDataFolder());
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();
SkinCache skinCache = new SkinCache(configManager);
log(ChatColor.WHITE + " * Registerring components...");
NpcTypeImpl.defineTypes(packetEvents);
typeRegistry.registerDefault(packetEvents);
actionRegistry.registerTypes(npcRegistry, scheduler, adventure, bungeeConnector, textSerializer);
packetEvents.getEventManager().registerListener(new InteractionPacketListener(userManager, npcRegistry), PacketListenerPriority.MONITOR);
new Metrics(this, PLUGIN_ID);
pluginManager.registerEvents(new UserListener(userManager), this);
getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
registerCommands(npcRegistry, skinCache, adventure, actionRegistry);
registerCommands(npcRegistry, skinCache, adventure, actionRegistry, typeRegistry);
log(ChatColor.WHITE + " * Starting tasks...");
if (configManager.getConfig().checkForUpdates()) {
@ -144,7 +142,7 @@ public class ZNpcsPlus extends JavaPlugin {
shutdownTasks.add(adventure::close);
if (configManager.getConfig().autoSaveEnabled()) shutdownTasks.add(npcRegistry::save);
ZApiProvider.register(new ZNPCsPlusApi(npcRegistry));
NpcApiProvider.register(new ZNPCsPlusApi(npcRegistry));
enabled = true;
log(ChatColor.WHITE + " * Loading complete! (" + (System.currentTimeMillis() - before) + "ms)");
log("");
@ -153,8 +151,8 @@ public class ZNpcsPlus extends JavaPlugin {
World world = Bukkit.getWorld("world");
if (world == null) world = Bukkit.getWorlds().get(0);
int i = 0;
for (NpcTypeImpl type : NpcTypeImpl.values()) {
NpcEntryImpl entry = npcRegistry.create("debug_npc_" + i, world, type, new ZLocation(i * 3, 200, 0, 0, 0));
for (NpcTypeImpl type : typeRegistry.getAll()) {
NpcEntryImpl entry = npcRegistry.create("debug_npc_" + i, world, type, new NpcLocation(i * 3, 200, 0, 0, 0));
entry.setProcessed(true);
NpcImpl npc = entry.getNpc();
npc.getHologram().addLine(Component.text("Hello, World!"));
@ -166,7 +164,7 @@ public class ZNpcsPlus extends JavaPlugin {
@Override
public void onDisable() {
if (!enabled) return;
ZApiProvider.unregister();
NpcApiProvider.unregister();
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
Message<CommandContext> incorrectUsageMessage = context -> context.send(Component.text("Incorrect usage: /" + context.getUsage(), NamedTextColor.RED));
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(EntityPropertyImpl.class, new EntityPropertyParser(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.registerCommand("npc", new MultiCommand()
.addSubcommand("create", new CreateCommand(npcRegistry))
.addSubcommand("skin", new SkinCommand(skinCache, npcRegistry))
.addSubcommand("create", new CreateCommand(npcRegistry, typeRegistry))
.addSubcommand("skin", new SkinCommand(skinCache, npcRegistry, typeRegistry))
.addSubcommand("delete", new DeleteCommand(npcRegistry, adventure))
.addSubcommand("move", new MoveCommand(npcRegistry))
.addSubcommand("properties", new PropertiesCommand(npcRegistry))
.addSubcommand("teleport", new TeleportCommand(npcRegistry))
.addSubcommand("list", new ListCommand(npcRegistry))
.addSubcommand("near", new NearCommand(npcRegistry))
.addSubcommand("type", new TypeCommand(npcRegistry))
.addSubcommand("type", new TypeCommand(npcRegistry, typeRegistry))
.addSubcommand("storage", new MultiCommand()
.addSubcommand("save", new SaveAllCommand(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.NpcRegistryImpl;
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.format.NamedTextColor;
import org.bukkit.entity.Player;
@ -16,9 +17,11 @@ import java.util.List;
public class CreateCommand implements CommandHandler {
private final NpcRegistryImpl npcRegistry;
private final NpcTypeRegistry typeRegistry;
public CreateCommand(NpcRegistryImpl npcRegistry) {
public CreateCommand(NpcRegistryImpl npcRegistry, NpcTypeRegistry typeRegistry) {
this.npcRegistry = npcRegistry;
this.typeRegistry = typeRegistry;
}
@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));
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();
context.send(Component.text("Created a " + type.getName() + " NPC with ID " + id + ".", NamedTextColor.GREEN));
@ -38,8 +41,8 @@ public class CreateCommand implements CommandHandler {
@Override
public List<String> suggest(CommandContext context) throws CommandExecutionException {
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.modifiableIds());
if (context.argSize() == 2) return context.suggestStream(NpcTypeImpl.values().stream().map(NpcTypeImpl::getName));
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.getModifiableIds());
if (context.argSize() == 2) return context.suggestStream(typeRegistry.getAll().stream().map(NpcTypeImpl::getName));
return Collections.emptyList();
}
}

@ -31,7 +31,7 @@ public class DeleteCommand implements CommandHandler {
@Override
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();
}
}

@ -5,7 +5,7 @@ import lol.pyr.director.adventure.command.CommandHandler;
import lol.pyr.director.common.command.CommandExecutionException;
import lol.pyr.znpcsplus.npc.NpcImpl;
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.TextComponent;
import net.kyori.adventure.text.event.ClickEvent;
@ -21,9 +21,9 @@ public class ListCommand implements CommandHandler {
@Override
public void run(CommandContext context) throws CommandExecutionException {
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();
ZLocation location = npc.getLocation();
NpcLocation location = npc.getLocation();
component.append(Component.text("ID: " + id, NamedTextColor.GREEN))
.append(Component.text(" | ", NamedTextColor.GRAY))
.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.NpcImpl;
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.format.NamedTextColor;
import org.bukkit.entity.Player;
@ -26,13 +26,13 @@ public class MoveCommand implements CommandHandler {
context.setUsage(context.getLabel() + " move <id>");
Player player = context.ensureSenderIsPlayer();
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));
}
@Override
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();
}
}

@ -24,7 +24,7 @@ public class NearCommand implements CommandHandler {
int raw = context.parse(Integer.class);
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)
.map(NpcEntryImpl::getId)
.collect(Collectors.joining(", "));

@ -35,7 +35,7 @@ public class PropertiesCommand implements CommandHandler {
@Override
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)
.getNpc().getType().getAllowedProperties().stream().map(EntityPropertyImpl::getName));
if (context.argSize() == 3) {

@ -1,13 +1,11 @@
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.CommandHandler;
import lol.pyr.director.common.command.CommandExecutionException;
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
import lol.pyr.znpcsplus.npc.NpcImpl;
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
import lol.pyr.znpcsplus.npc.NpcTypeImpl;
import lol.pyr.znpcsplus.npc.*;
import lol.pyr.znpcsplus.skin.cache.SkinCache;
import lol.pyr.znpcsplus.skin.descriptor.FetchingDescriptor;
import lol.pyr.znpcsplus.skin.descriptor.MirrorDescriptor;
@ -21,17 +19,19 @@ import java.util.List;
public class SkinCommand implements CommandHandler {
private final SkinCache skinCache;
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.npcRegistry = npcRegistry;
this.typeRegistry = typeRegistry;
}
@Override
public void run(CommandContext context) throws CommandExecutionException {
context.setUsage(context.getLabel() + " skin <id> <type> [value]");
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();
if (type.equalsIgnoreCase("mirror")) {
@ -68,7 +68,7 @@ public class SkinCommand implements CommandHandler {
@Override
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.matchSuggestion("*", "static")) return context.suggestPlayers();
return Collections.emptyList();

@ -32,7 +32,7 @@ public class TeleportCommand implements CommandHandler {
@Override
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();
}
}

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

@ -31,7 +31,7 @@ public class ActionDeleteCommand implements CommandHandler {
@Override
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)
.limit(context.suggestionParse(0, NpcEntryImpl.class).getNpc().getActions().size())
.map(String::valueOf));

@ -33,7 +33,7 @@ public class HoloAddCommand implements CommandHandler {
@Override
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();
}
}

@ -32,7 +32,7 @@ public class HoloDeleteCommand implements CommandHandler {
@Override
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)
.limit(context.suggestionParse(0, NpcEntryImpl.class).getNpc().getHologram().getLines().size())
.map(String::valueOf));

@ -32,7 +32,7 @@ public class HoloInfoCommand implements CommandHandler {
@Override
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();
}
}

@ -36,7 +36,7 @@ public class HoloInsertCommand implements CommandHandler {
@Override
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)
.limit(context.suggestionParse(0, NpcEntryImpl.class).getNpc().getHologram().getLines().size())
.map(String::valueOf));

@ -28,7 +28,7 @@ public class HoloOffsetCommand implements CommandHandler {
@Override
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) {
HologramImpl hologram = context.suggestionParse(0, NpcEntryImpl.class).getNpc().getHologram();
return context.suggestLiteral(String.valueOf(hologram.getOffset()));

@ -37,7 +37,7 @@ public class HoloSetCommand implements CommandHandler {
@Override
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) {
HologramImpl hologram = context.suggestionParse(0, NpcEntryImpl.class).getNpc().getHologram();
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.packets.PacketFactory;
import lol.pyr.znpcsplus.reflection.Reflections;
import lol.pyr.znpcsplus.util.ZLocation;
import lol.pyr.znpcsplus.util.NpcLocation;
import org.bukkit.entity.Player;
import java.util.Collection;
@ -21,9 +21,9 @@ public class PacketEntity {
private final UUID uuid;
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.properties = properties;
this.entityId = reserveEntityID();
@ -36,7 +36,7 @@ public class PacketEntity {
return entityId;
}
public ZLocation getLocation() {
public NpcLocation getLocation() {
return location;
}
@ -48,7 +48,7 @@ public class PacketEntity {
return type;
}
public void setLocation(ZLocation location, Collection<Player> viewers) {
public void setLocation(NpcLocation location, Collection<Player> viewers) {
this.location = location;
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.packets.PacketFactory;
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 org.bukkit.entity.Player;
@ -17,10 +17,10 @@ public class HologramImpl extends Viewable implements Hologram {
private final PacketFactory packetFactory;
private double offset = 0.0;
private ZLocation location;
private NpcLocation location;
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.packetFactory = packetFactory;
this.location = location;
@ -69,7 +69,7 @@ public class HologramImpl extends Viewable implements Hologram {
for (HologramLine line : lines) line.hide(player);
}
public void setLocation(ZLocation location) {
public void setLocation(NpcLocation location) {
this.location = location;
relocateLines();
}

@ -6,7 +6,7 @@ import lol.pyr.znpcsplus.api.entity.PropertyHolder;
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
import lol.pyr.znpcsplus.entity.PacketEntity;
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 org.bukkit.entity.Player;
@ -16,7 +16,7 @@ public class HologramLine implements PropertyHolder {
private Component text;
private final PacketEntity armorStand;
public HologramLine(PacketFactory packetFactory, ZLocation location, Component text) {
public HologramLine(PacketFactory packetFactory, NpcLocation location, Component text) {
this.text = text;
armorStand = new PacketEntity(packetFactory, this, EntityTypes.ARMOR_STAND, location);
}
@ -37,7 +37,7 @@ public class HologramLine implements PropertyHolder {
armorStand.despawn(player);
}
public void setLocation(ZLocation location, Collection<Player> viewers) {
public void setLocation(NpcLocation location, Collection<Player> 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.scheduling.TaskScheduler;
import lol.pyr.znpcsplus.util.BungeeConnector;
import lol.pyr.znpcsplus.util.StringSerializer;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
@ -50,7 +49,7 @@ public class ActionRegistry {
try {
String[] split = str.split(";");
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;
return serializer.deserialize(String.join(";", Arrays.copyOfRange(split, 1, split.length)));
} catch (ClassNotFoundException e) {
@ -60,7 +59,7 @@ public class ActionRegistry {
@SuppressWarnings("unchecked")
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;
return action.getClass().getName() + ";" + serializer.serialize(action);
}

@ -57,7 +57,7 @@ public class ConsoleCommandActionType implements InteractionActionType<ConsoleCo
@Override
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");
return Collections.emptyList();
}

@ -61,7 +61,7 @@ public class MessageActionType implements InteractionActionType<MessageAction>,
@Override
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");
return Collections.emptyList();
}

@ -57,7 +57,7 @@ public class PlayerCommandActionType implements InteractionActionType<PlayerComm
@Override
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");
return Collections.emptyList();
}

@ -57,7 +57,7 @@ public class SwitchServerActionType implements InteractionActionType<SwitchServe
@Override
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");
return Collections.emptyList();
}

@ -9,7 +9,7 @@ import lol.pyr.znpcsplus.hologram.HologramImpl;
import lol.pyr.znpcsplus.interaction.InteractionAction;
import lol.pyr.znpcsplus.packets.PacketFactory;
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.Location;
import org.bukkit.World;
@ -21,18 +21,18 @@ public class NpcImpl extends Viewable implements Npc {
private final PacketFactory packetFactory;
private final String worldName;
private PacketEntity entity;
private ZLocation location;
private NpcLocation location;
private NpcTypeImpl type;
private final HologramImpl hologram;
private final Map<EntityPropertyImpl<?>, Object> propertyMap = new HashMap<>();
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);
}
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.worldName = world;
this.type = type;
@ -57,7 +57,7 @@ public class NpcImpl extends Viewable implements Npc {
return entity;
}
public ZLocation getLocation() {
public NpcLocation getLocation() {
return location;
}
@ -65,7 +65,7 @@ public class NpcImpl extends Viewable implements Npc {
return location.toBukkitLocation(getWorld());
}
public void setLocation(ZLocation location) {
public void setLocation(NpcLocation location) {
this.location = location;
entity.setLocation(location, getViewers());
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.scheduling.TaskScheduler;
import lol.pyr.znpcsplus.storage.NpcStorage;
import lol.pyr.znpcsplus.util.ZLocation;
import lol.pyr.znpcsplus.util.NpcLocation;
import org.bukkit.World;
import java.util.Collection;
@ -22,8 +22,8 @@ public class NpcRegistryImpl implements NpcRegistry {
private final PacketFactory packetFactory;
private final ConfigManager configManager;
public NpcRegistryImpl(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistry actionRegistry, TaskScheduler scheduler) {
storage = configManager.getConfig().storageType().create(configManager, plugin, packetFactory, actionRegistry);
public NpcRegistryImpl(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistry actionRegistry, TaskScheduler scheduler, NpcTypeRegistry typeRegistry) {
storage = configManager.getConfig().storageType().create(configManager, plugin, packetFactory, actionRegistry, typeRegistry);
this.packetFactory = packetFactory;
this.configManager = configManager;
@ -48,36 +48,36 @@ public class NpcRegistryImpl implements NpcRegistry {
return npcMap.get(id.toLowerCase());
}
public Collection<NpcEntryImpl> all() {
public Collection<NpcEntryImpl> getAll() {
return Collections.unmodifiableCollection(npcMap.values());
}
public Collection<NpcEntryImpl> allModifiable() {
public Collection<NpcEntryImpl> getAllModifiable() {
return Collections.unmodifiableCollection(npcMap.values().stream()
.filter(NpcEntryImpl::isAllowCommandModification)
.collect(Collectors.toList()));
}
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());
}
public Collection<String> modifiableIds() {
public Collection<String> getModifiableIds() {
return Collections.unmodifiableSet(npcMap.entrySet().stream()
.filter(entry -> entry.getValue().isAllowCommandModification())
.map(Map.Entry::getKey)
.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);
}
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();
if (npcMap.containsKey(id)) throw new IllegalArgumentException("An npc with the id " + id + " already exists!");
NpcImpl npc = new NpcImpl(configManager, world, type, location, packetFactory);

@ -1,26 +1,13 @@
package lol.pyr.znpcsplus.npc;
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.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.*;
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 Set<EntityPropertyImpl<?>> allowedProperties;
private final String name;
@ -49,132 +36,14 @@ public class NpcTypeImpl {
return allowedProperties;
}
private static NpcTypeImpl define(Builder 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 {
protected static final class Builder {
private final String name;
private final EntityType type;
private final List<EntityPropertyImpl<?>> allowedProperties = new ArrayList<>();
private boolean globalProperties = true;
private double hologramOffset = 0;
private Builder(String name, EntityType type) {
Builder(String name, EntityType type) {
this.name = name;
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.metadata.MetadataFactory;
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.plugin.Plugin;
@ -20,7 +20,7 @@ public class V1_14PacketFactory extends V1_10PacketFactory {
@Override
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(),
location.toVector3d(), location.getPitch(), location.getYaw(), location.getYaw(), 0, Optional.of(new Vector3d())));
sendAllMetadata(player, entity, properties);

@ -16,7 +16,7 @@ import lol.pyr.znpcsplus.entity.PacketEntity;
import lol.pyr.znpcsplus.metadata.MetadataFactory;
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
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.format.NamedTextColor;
import org.bukkit.entity.Player;
@ -40,7 +40,7 @@ public class V1_8PacketFactory implements PacketFactory {
public void spawnPlayer(Player player, PacketEntity entity, PropertyHolder properties) {
addTabPlayer(player, entity, properties).thenAccept(ignored -> {
createTeam(player, entity, properties);
ZLocation location = entity.getLocation();
NpcLocation location = entity.getLocation();
sendPacket(player, new WrapperPlayServerSpawnPlayer(entity.getEntityId(),
entity.getUuid(), location.toVector3d(), location.getYaw(), location.getPitch(), Collections.emptyList()));
sendPacket(player, new WrapperPlayServerEntityHeadLook(entity.getEntityId(), location.getYaw()));
@ -51,7 +51,7 @@ public class V1_8PacketFactory implements PacketFactory {
@Override
public void spawnEntity(Player player, PacketEntity entity, PropertyHolder properties) {
ZLocation location = entity.getLocation();
NpcLocation location = entity.getLocation();
EntityType type = entity.getType();
ClientVersion clientVersion = packetEvents.getServerManager().getVersion().toClientVersion();
sendPacket(player, type.getLegacyId(clientVersion) == -1 ?
@ -71,7 +71,7 @@ public class V1_8PacketFactory implements PacketFactory {
@Override
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));
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.message.Message;
import lol.pyr.znpcsplus.npc.NpcTypeImpl;
import lol.pyr.znpcsplus.npc.NpcTypeRegistry;
import java.util.Deque;
public class NpcTypeParser extends ParserType<NpcTypeImpl> {
public NpcTypeParser(Message<CommandContext> message) {
private final NpcTypeRegistry typeRegistry;
public NpcTypeParser(Message<CommandContext> message, NpcTypeRegistry typeRegistry) {
super(message);
this.typeRegistry = typeRegistry;
}
@Override
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();
return type;
}

@ -9,9 +9,9 @@ import java.util.Objects;
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
* 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 {
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;
/**
* 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.
*/
public final class Reflections {

@ -3,6 +3,7 @@ package lol.pyr.znpcsplus.storage;
import lol.pyr.znpcsplus.ZNpcsPlus;
import lol.pyr.znpcsplus.config.ConfigManager;
import lol.pyr.znpcsplus.interaction.ActionRegistry;
import lol.pyr.znpcsplus.npc.NpcTypeRegistry;
import lol.pyr.znpcsplus.packets.PacketFactory;
import lol.pyr.znpcsplus.storage.yaml.YamlStorage;
@ -11,10 +12,10 @@ import java.io.File;
public enum NpcStorageType {
YAML {
@Override
public NpcStorage create(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistry actionRegistry) {
return new YamlStorage(packetFactory, configManager, actionRegistry, new File(plugin.getDataFolder(), "data"));
public NpcStorage create(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistry actionRegistry, NpcTypeRegistry typeRegistry) {
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.npc.NpcEntryImpl;
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.storage.NpcStorage;
import lol.pyr.znpcsplus.util.ZLocation;
import lol.pyr.znpcsplus.util.NpcLocation;
import net.kyori.adventure.text.minimessage.MiniMessage;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
@ -23,12 +23,14 @@ public class YamlStorage implements NpcStorage {
private final PacketFactory packetFactory;
private final ConfigManager configManager;
private final ActionRegistry actionRegistry;
private final NpcTypeRegistry typeRegistry;
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.configManager = configManager;
this.actionRegistry = actionRegistry;
this.typeRegistry = typeRegistry;
this.folder = folder;
if (!this.folder.exists()) this.folder.mkdirs();
}
@ -41,7 +43,7 @@ public class YamlStorage implements NpcStorage {
List<NpcEntryImpl> npcs = new ArrayList<>();
for (File file : files) if (file.isFile() && file.getName().toLowerCase().endsWith(".yml")) {
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")));
ConfigurationSection properties = config.getConfigurationSection("properties");
@ -101,8 +103,8 @@ public class YamlStorage implements NpcStorage {
}
}
public ZLocation deserializeLocation(ConfigurationSection section) {
return new ZLocation(
public NpcLocation deserializeLocation(ConfigurationSection section) {
return new NpcLocation(
section.getDouble("x"),
section.getDouble("y"),
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();
config.set("x", location.getX());
config.set("y", location.getY());

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