diff --git a/core/pom.xml b/core/pom.xml index 8a8fed055..9b55832c5 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -59,6 +59,12 @@ codemc-snapshots https://repo.codemc.io/repository/maven-snapshots/ + + + pyr-snapshots + Pyr's Repo + https://repo.pyr.lol/snapshots + @@ -140,6 +146,12 @@ 271b087586 provided + + lol.pyr + znpcsplus-api + 2.0.0-SNAPSHOT + provided + com.github.PikaMug Unite diff --git a/core/src/main/java/me/pikamug/quests/BukkitQuestsPlugin.java b/core/src/main/java/me/pikamug/quests/BukkitQuestsPlugin.java index fc64d2075..385b3386d 100644 --- a/core/src/main/java/me/pikamug/quests/BukkitQuestsPlugin.java +++ b/core/src/main/java/me/pikamug/quests/BukkitQuestsPlugin.java @@ -22,15 +22,7 @@ import me.pikamug.quests.convo.misc.QuestAcceptPrompt; import me.pikamug.quests.dependencies.BukkitDenizenTrigger; import me.pikamug.quests.dependencies.BukkitDependencies; import me.pikamug.quests.interfaces.ReloadCallback; -import me.pikamug.quests.listeners.BukkitBlockListener; -import me.pikamug.quests.listeners.BukkitCitizensListener; -import me.pikamug.quests.listeners.BukkitCommandManager; -import me.pikamug.quests.listeners.BukkitConvoListener; -import me.pikamug.quests.listeners.BukkitItemListener; -import me.pikamug.quests.listeners.BukkitPartiesListener; -import me.pikamug.quests.listeners.BukkitPlayerListener; -import me.pikamug.quests.listeners.BukkitUniteListener; -import me.pikamug.quests.listeners.BukkitZnpcsListener; +import me.pikamug.quests.listeners.*; import me.pikamug.quests.logging.BukkitQuestsLog4JFilter; import me.pikamug.quests.storage.implementation.jar.BukkitModuleJarStorage; import me.pikamug.quests.storage.implementation.ModuleStorageImpl; @@ -109,6 +101,7 @@ public class BukkitQuestsPlugin extends JavaPlugin implements Quests { private BukkitItemListener itemListener; private BukkitCitizensListener citizensListener; private BukkitZnpcsListener znpcsListener; + private BukkitZnpcsPlusListener znpcsPlusListener; private BukkitPlayerListener playerListener; private BukkitNpcEffectThread effectThread; private BukkitPlayerMoveThread moveThread; @@ -148,6 +141,7 @@ public class BukkitQuestsPlugin extends JavaPlugin implements Quests { itemListener = new BukkitItemListener(this); citizensListener = new BukkitCitizensListener(this); znpcsListener = new BukkitZnpcsListener(this); + znpcsPlusListener = new BukkitZnpcsPlusListener(this); playerListener = new BukkitPlayerListener(this); uniteListener = new BukkitUniteListener(); partiesListener = new BukkitPartiesListener(); @@ -222,6 +216,9 @@ public class BukkitQuestsPlugin extends JavaPlugin implements Quests { if (depends.getZnpcsPlus() != null) { getServer().getPluginManager().registerEvents(getZnpcsListener(), this); } + if (depends.getZnpcsPlusApi() != null) { + getServer().getPluginManager().registerEvents(getZNpcsPlusListener(), this); + } getServer().getPluginManager().registerEvents(getPlayerListener(), this); if (configSettings.getStrictPlayerMovement() > 0) { final long ticks = configSettings.getStrictPlayerMovement() * 20L; @@ -522,6 +519,10 @@ public class BukkitQuestsPlugin extends JavaPlugin implements Quests { return znpcsListener; } + public BukkitZnpcsPlusListener getZNpcsPlusListener() { + return znpcsPlusListener; + } + public BukkitPlayerListener getPlayerListener() { return playerListener; } @@ -606,8 +607,7 @@ public class BukkitQuestsPlugin extends JavaPlugin implements Quests { } /** - * Load quests, actions, conditions, and modules - * + * Load quests, actions, conditions, and modules
* At startup, this lets soft-depends (namely Citizens) fully load first */ private void delayLoadQuestInfo() { diff --git a/core/src/main/java/me/pikamug/quests/convo/conditions/tasks/ConditionEntityPrompt.java b/core/src/main/java/me/pikamug/quests/convo/conditions/tasks/ConditionEntityPrompt.java index cad758bd5..5300bd6ac 100644 --- a/core/src/main/java/me/pikamug/quests/convo/conditions/tasks/ConditionEntityPrompt.java +++ b/core/src/main/java/me/pikamug/quests/convo/conditions/tasks/ConditionEntityPrompt.java @@ -101,7 +101,7 @@ public class ConditionEntityPrompt extends ConditionsEditorNumericPrompt { return text.toString(); } case 2: - if (plugin.getDependencies().getCitizens() != null || plugin.getDependencies().getZnpcsPlus() != null) { + if (plugin.getDependencies().getCitizens() != null || plugin.getDependencies().getZnpcsPlus() != null || plugin.getDependencies().getZnpcsPlusApi() != null) { if (context.getSessionData(Key.C_WHILE_RIDING_NPC) == null) { return ChatColor.GRAY + "(" + BukkitLang.get("noneSet") + ")"; } else { @@ -277,6 +277,9 @@ public class ConditionEntityPrompt extends ConditionsEditorNumericPrompt { final UUID uuid = UUID.fromString(s); if (plugin.getDependencies().getNpcEntity(uuid) != null && npcs != null) { npcs.add(uuid.toString()); + } else if (plugin.getDependencies().getZnpcsPlusApi() != null && npcs!= null + && plugin.getDependencies().getZnpcsPlusApi().getNpcRegistry().getByUuid(uuid) != null) { + npcs.add(uuid.toString()); } else { context.getForWhom().sendRawMessage(ChatColor.RED + BukkitLang.get("stageEditorInvalidNPC") .replace("", s)); diff --git a/core/src/main/java/me/pikamug/quests/convo/quests/main/QuestMainPrompt.java b/core/src/main/java/me/pikamug/quests/convo/quests/main/QuestMainPrompt.java index c381c20bd..7f430b65f 100644 --- a/core/src/main/java/me/pikamug/quests/convo/quests/main/QuestMainPrompt.java +++ b/core/src/main/java/me/pikamug/quests/convo/quests/main/QuestMainPrompt.java @@ -105,7 +105,7 @@ public class QuestMainPrompt extends QuestsEditorNumericPrompt { return ChatColor.GRAY; } case 7: - if (plugin.getDependencies().getCitizens() != null || plugin.getDependencies().getZnpcsPlus() != null) { + if (plugin.getDependencies().getCitizens() != null || plugin.getDependencies().getZnpcsPlus() != null || plugin.getDependencies().getZnpcsPlusApi() != null) { return ChatColor.BLUE; } else { return ChatColor.GRAY; @@ -130,7 +130,7 @@ public class QuestMainPrompt extends QuestsEditorNumericPrompt { return ChatColor.YELLOW + BukkitLang.get("questEditorFinishMessage"); case 4: if (context.getSessionData(Key.Q_START_NPC) == null || plugin.getDependencies().getCitizens() != null - || plugin.getDependencies().getZnpcsPlus() != null) { + || plugin.getDependencies().getZnpcsPlus() != null || plugin.getDependencies().getZnpcsPlusApi() != null) { return ChatColor.YELLOW + BukkitLang.get("questEditorNPCStart"); } else { return ChatColor.GRAY + BukkitLang.get("questEditorNPCStart"); @@ -148,7 +148,7 @@ public class QuestMainPrompt extends QuestsEditorNumericPrompt { return ChatColor.GRAY + BukkitLang.get("questWGSetRegion"); } case 7: - if (plugin.getDependencies().getCitizens() != null || plugin.getDependencies().getZnpcsPlus() != null) { + if (plugin.getDependencies().getCitizens() != null || plugin.getDependencies().getZnpcsPlus() != null || plugin.getDependencies().getZnpcsPlusApi() != null) { return ChatColor.YELLOW + BukkitLang.get("questEditorSetGUI"); } else { return ChatColor.GRAY + BukkitLang.get("questEditorSetGUI"); @@ -192,9 +192,9 @@ public class QuestMainPrompt extends QuestsEditorNumericPrompt { + ChatColor.RESET + ChatColor.GRAY + ")"; case 4: if (context.getSessionData(Key.Q_START_NPC) == null && (plugin.getDependencies().getCitizens() != null - || plugin.getDependencies().getZnpcsPlus() != null)) { + || plugin.getDependencies().getZnpcsPlus() != null || plugin.getDependencies().getZnpcsPlusApi() != null)) { return ChatColor.GRAY + "(" + BukkitLang.get("noneSet") + ")"; - } else if (plugin.getDependencies().getCitizens() != null || plugin.getDependencies().getZnpcsPlus() != null) { + } else if (plugin.getDependencies().getCitizens() != null || plugin.getDependencies().getZnpcsPlus() != null || plugin.getDependencies().getZnpcsPlusApi() != null) { final UUID uuid = UUID.fromString((String) Objects.requireNonNull(context .getSessionData(Key.Q_START_NPC))); return ChatColor.GRAY + "(" + ChatColor.AQUA + plugin.getDependencies().getNpcName(uuid) @@ -224,7 +224,7 @@ public class QuestMainPrompt extends QuestsEditorNumericPrompt { return ChatColor.GRAY + "(" + BukkitLang.get("notInstalled") + ")"; } case 7: - if (plugin.getDependencies().getCitizens() != null || plugin.getDependencies().getZnpcsPlus() != null) { + if (plugin.getDependencies().getCitizens() != null || plugin.getDependencies().getZnpcsPlus() != null || plugin.getDependencies().getZnpcsPlusApi() != null) { if (context.getSessionData(Key.Q_GUIDISPLAY) == null) { return ChatColor.GRAY + "(" + BukkitLang.get("noneSet") + ")"; } else { @@ -268,7 +268,7 @@ public class QuestMainPrompt extends QuestsEditorNumericPrompt { case 3: return new QuestFinishMessagePrompt(context); case 4: - if (plugin.getDependencies().getCitizens() != null || plugin.getDependencies().getZnpcsPlus() != null) { + if (plugin.getDependencies().getCitizens() != null || plugin.getDependencies().getZnpcsPlus() != null || plugin.getDependencies().getZnpcsPlusApi() != null) { return new QuestNPCStartPrompt(context); } else { return new QuestMainPrompt(context); @@ -290,7 +290,7 @@ public class QuestMainPrompt extends QuestsEditorNumericPrompt { return new QuestMainPrompt(context); } case 7: - if (plugin.getDependencies().getCitizens() != null || plugin.getDependencies().getZnpcsPlus() != null) { + if (plugin.getDependencies().getCitizens() != null || plugin.getDependencies().getZnpcsPlus() != null || plugin.getDependencies().getZnpcsPlusApi() != null) { return new QuestGuiDisplayPrompt(context); } else { return new QuestMainPrompt(context); @@ -501,7 +501,8 @@ public class QuestMainPrompt extends QuestsEditorNumericPrompt { if (!input.equalsIgnoreCase(BukkitLang.get("cmdCancel")) && !input.equalsIgnoreCase(BukkitLang.get("cmdClear"))) { try { final UUID uuid = UUID.fromString(input); - if (plugin.getDependencies().getNpcEntity(uuid) == null) { + if (plugin.getDependencies().getNpcEntity(uuid) == null && (plugin.getDependencies().getZnpcsPlusApi() == null + || plugin.getDependencies().getZnpcsPlusApi().getNpcRegistry().getByUuid(uuid) == null)) { context.getForWhom().sendRawMessage(ChatColor.RED + BukkitLang.get("stageEditorInvalidNPC") .replace("", input)); return new QuestNPCStartPrompt(context); diff --git a/core/src/main/java/me/pikamug/quests/convo/quests/objectives/QuestNpcsPrompt.java b/core/src/main/java/me/pikamug/quests/convo/quests/objectives/QuestNpcsPrompt.java index c84b2b774..37449a139 100644 --- a/core/src/main/java/me/pikamug/quests/convo/quests/objectives/QuestNpcsPrompt.java +++ b/core/src/main/java/me/pikamug/quests/convo/quests/objectives/QuestNpcsPrompt.java @@ -93,7 +93,7 @@ public class QuestNpcsPrompt extends QuestsEditorNumericPrompt { public String getAdditionalText(final ConversationContext context, final int number) { switch(number) { case 1: - if (plugin.getDependencies().getCitizens() != null || plugin.getDependencies().getZnpcsPlus() != null) { + if (plugin.getDependencies().getCitizens() != null || plugin.getDependencies().getZnpcsPlus() != null || plugin.getDependencies().getZnpcsPlusApi() != null) { if (context.getSessionData(pref + Key.S_DELIVERY_ITEMS) == null) { return ChatColor.GRAY + "(" + BukkitLang.get("noneSet") + ")"; } else { @@ -117,7 +117,7 @@ public class QuestNpcsPrompt extends QuestsEditorNumericPrompt { return ChatColor.GRAY + " (" + BukkitLang.get("notInstalled") + ")"; } case 2: - if (plugin.getDependencies().getCitizens() != null || plugin.getDependencies().getZnpcsPlus() != null) { + if (plugin.getDependencies().getCitizens() != null || plugin.getDependencies().getZnpcsPlus() != null || plugin.getDependencies().getZnpcsPlusApi() != null) { if (context.getSessionData(pref + Key.S_NPCS_TO_TALK_TO) == null) { return ChatColor.GRAY + "(" + BukkitLang.get("noneSet") + ")"; } else { @@ -136,7 +136,7 @@ public class QuestNpcsPrompt extends QuestsEditorNumericPrompt { return ChatColor.GRAY + "(" + BukkitLang.get("notInstalled") + ")"; } case 3: - if (plugin.getDependencies().getCitizens() != null || plugin.getDependencies().getZnpcsPlus() != null) { + if (plugin.getDependencies().getCitizens() != null || plugin.getDependencies().getZnpcsPlus() != null || plugin.getDependencies().getZnpcsPlusApi() != null) { if (context.getSessionData(pref + Key.S_NPCS_TO_KILL) == null) { return ChatColor.GRAY + "(" + BukkitLang.get("noneSet") + ")"; } else { @@ -185,21 +185,21 @@ public class QuestNpcsPrompt extends QuestsEditorNumericPrompt { protected Prompt acceptValidatedInput(final @NotNull ConversationContext context, final Number input) { switch(input.intValue()) { case 1: - if (plugin.getDependencies().getCitizens() != null || plugin.getDependencies().getZnpcsPlus() != null) { + if (plugin.getDependencies().getCitizens() != null || plugin.getDependencies().getZnpcsPlus() != null || plugin.getDependencies().getZnpcsPlusApi() != null) { return new QuestNpcsDeliveryListPrompt(context); } else { context.getForWhom().sendRawMessage(ChatColor.RED + BukkitLang.get("stageEditorNoCitizens")); return new QuestStageMainPrompt(stageNum, context); } case 2: - if (plugin.getDependencies().getCitizens() != null || plugin.getDependencies().getZnpcsPlus() != null) { + if (plugin.getDependencies().getCitizens() != null || plugin.getDependencies().getZnpcsPlus() != null || plugin.getDependencies().getZnpcsPlusApi() != null) { return new QuestNpcsIdsToTalkToPrompt(context); } else { context.getForWhom().sendRawMessage(ChatColor.RED + BukkitLang.get("stageEditorNoCitizens")); return new QuestStageMainPrompt(stageNum, context); } case 3: - if (plugin.getDependencies().getCitizens() != null || plugin.getDependencies().getZnpcsPlus() != null) { + if (plugin.getDependencies().getCitizens() != null || plugin.getDependencies().getZnpcsPlus() != null || plugin.getDependencies().getZnpcsPlusApi() != null) { return new QuestNpcsKillListPrompt(context); } else { context.getForWhom().sendRawMessage(ChatColor.RED + BukkitLang.get("stageEditorNoCitizens")); @@ -454,6 +454,9 @@ public class QuestNpcsPrompt extends QuestsEditorNumericPrompt { final UUID uuid = UUID.fromString(s); if (plugin.getDependencies().getNpcEntity(uuid) != null && npcs != null) { npcs.add(uuid.toString()); + } else if (plugin.getDependencies().getZnpcsPlusApi() != null && npcs!= null + && plugin.getDependencies().getZnpcsPlusApi().getNpcRegistry().getByUuid(uuid) != null) { + npcs.add(uuid.toString()); } else { context.getForWhom().sendRawMessage(ChatColor.RED + BukkitLang.get("stageEditorInvalidNPC") .replace("", s)); @@ -570,6 +573,9 @@ public class QuestNpcsPrompt extends QuestsEditorNumericPrompt { final UUID uuid = UUID.fromString(s); if (plugin.getDependencies().getNpcEntity(uuid) != null && npcs != null) { npcs.add(uuid.toString()); + } else if (plugin.getDependencies().getZnpcsPlusApi() != null && npcs!= null + && plugin.getDependencies().getZnpcsPlusApi().getNpcRegistry().getByUuid(uuid) != null) { + npcs.add(uuid.toString()); } else { context.getForWhom().sendRawMessage(ChatColor.RED + BukkitLang.get("stageEditorInvalidNPC") .replace("", s)); @@ -648,7 +654,7 @@ public class QuestNpcsPrompt extends QuestsEditorNumericPrompt { public String getAdditionalText(final ConversationContext context, final int number) { switch(number) { case 1: - if (plugin.getDependencies().getCitizens() != null || plugin.getDependencies().getZnpcsPlus() != null) { + if (plugin.getDependencies().getCitizens() != null || plugin.getDependencies().getZnpcsPlus() != null || plugin.getDependencies().getZnpcsPlusApi() != null) { if (context.getSessionData(pref + Key.S_NPCS_TO_KILL) == null) { return ChatColor.GRAY + "(" + BukkitLang.get("noneSet") + ")"; } else { @@ -792,6 +798,9 @@ public class QuestNpcsPrompt extends QuestsEditorNumericPrompt { final UUID uuid = UUID.fromString(s); if (plugin.getDependencies().getNpcEntity(uuid) != null && npcs != null) { npcs.add(uuid.toString()); + } else if (plugin.getDependencies().getZnpcsPlusApi() != null && npcs!= null + && plugin.getDependencies().getZnpcsPlusApi().getNpcRegistry().getByUuid(uuid) != null) { + npcs.add(uuid.toString()); } else { context.getForWhom().sendRawMessage(ChatColor.RED + BukkitLang.get("stageEditorInvalidNPC") .replace("", s)); diff --git a/core/src/main/java/me/pikamug/quests/dependencies/BukkitDependencies.java b/core/src/main/java/me/pikamug/quests/dependencies/BukkitDependencies.java index ed321c482..a0c4c757d 100644 --- a/core/src/main/java/me/pikamug/quests/dependencies/BukkitDependencies.java +++ b/core/src/main/java/me/pikamug/quests/dependencies/BukkitDependencies.java @@ -21,13 +21,17 @@ import com.herocraftonline.heroes.characters.Hero; import com.herocraftonline.heroes.characters.classes.HeroClass; import io.github.znetworkw.znpcservers.npc.NPC; import lol.pyr.znpcsplus.ZNPCsPlus; +import lol.pyr.znpcsplus.api.NpcApi; +import lol.pyr.znpcsplus.api.NpcApiProvider; +import lol.pyr.znpcsplus.api.entity.EntityProperty; +import lol.pyr.znpcsplus.api.npc.Npc; +import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.pikamug.quests.BukkitQuestsPlugin; +import me.pikamug.quests.dependencies.reflect.denizen.DenizenAPI; +import me.pikamug.quests.dependencies.reflect.worldguard.WorldGuardAPI; import me.pikamug.quests.listeners.BukkitCitizensListener; import me.pikamug.quests.listeners.BukkitZnpcsListener; import me.pikamug.quests.player.Quester; -import me.pikamug.quests.dependencies.reflect.denizen.DenizenAPI; -import me.pikamug.quests.dependencies.reflect.worldguard.WorldGuardAPI; -import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.pikamug.unite.api.objects.PartyProvider; import net.citizensnpcs.api.CitizensPlugin; import net.milkbowl.vault.economy.Economy; @@ -43,12 +47,7 @@ import org.jetbrains.annotations.Nullable; import ro.niconeko.astralbooks.api.AstralBooks; import ro.niconeko.astralbooks.api.AstralBooksAPI; -import java.util.Collections; -import java.util.HashSet; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; +import java.util.*; import java.util.stream.Collectors; public class BukkitDependencies implements Dependencies { @@ -66,6 +65,7 @@ public class BukkitDependencies implements Dependencies { private static DenizenAPI denizen = null; private static AstralBooksAPI astralBooks = null; public static ZNPCsPlus znpcsPlus = null; + public static NpcApi znpcsPlusApi = null; private static PartiesAPI parties = null; private int npcEffectThread = -1; @@ -204,6 +204,7 @@ public class BukkitDependencies implements Dependencies { public void linkZnpcsPlus() { if (isPluginAvailable("ZNPCsPlus")) { try { + Class.forName("lol.pyr.znpcsplus.ZNPCsPlus"); znpcsPlus = (ZNPCsPlus) plugin.getServer().getPluginManager().getPlugin("ZNPCsPlus"); boolean found = false; for (final RegisteredListener listener : HandlerList.getRegisteredListeners(plugin)) { @@ -217,8 +218,27 @@ public class BukkitDependencies implements Dependencies { plugin.getLogger().info("Successfully linked Quests with ZNPCsPlus " + znpcsPlus.getDescription().getVersion()); } - } catch (final Exception e) { - plugin.getLogger().warning("Incompatible version of ZNPCsPlus found. ZNPCsPlus in Quests not enabled."); + } catch (Exception ignored) { + } + } + } + + public NpcApi getZnpcsPlusApi() { + if (znpcsPlusApi == null) { + linkZnpcsPlusApi(); + } + return znpcsPlusApi; + } + + public void linkZnpcsPlusApi() { + if (isPluginAvailable("ZNPCsPlus")) { + try { + Class.forName("lol.pyr.znpcsplus.ZNpcsPlus"); + znpcsPlusApi = NpcApiProvider.get(); + startNpcEffectThread(); + //noinspection ConstantConditions + plugin.getLogger().info("Successfully linked Quests with ZNPCsPlus " + plugin.getServer().getPluginManager().getPlugin("ZNPCsPlus").getDescription().getVersion()); + } catch (Exception ignored) { } } } @@ -308,6 +328,10 @@ public class BukkitDependencies implements Dependencies { if (opt.isPresent()) { return opt.get().getLocation(); } + } else if (znpcsPlusApi != null && znpcsPlusApi.getNpcRegistry().getByUuid(uuid) != null) { + Npc znpc = znpcsPlusApi.getNpcRegistry().getByUuid(uuid).getNpc(); + if (znpc.getWorld() == null) return null; + return znpc.getLocation().toBukkitLocation(znpc.getWorld()); } return null; } @@ -338,6 +362,12 @@ public class BukkitDependencies implements Dependencies { return opt.get().getNpcPojo().getHologramLines().get(0); } } + } else if (znpcsPlusApi != null && getZnpcsPlusApi().getNpcRegistry().getByUuid(uuid) != null) { + Npc znpc = getZnpcsPlusApi().getNpcRegistry().getByUuid(uuid).getNpc(); + EntityProperty displayNameProperty = getZnpcsPlusApi().getPropertyRegistry().getByName("display_name", String.class); + if (displayNameProperty != null && znpc.hasProperty(displayNameProperty)) { + return znpc.getProperty(displayNameProperty); + } } return "NPC"; } @@ -424,5 +454,6 @@ public class BukkitDependencies implements Dependencies { getVaultEconomy(); getVaultPermission(); getZnpcsPlus(); + getZnpcsPlusApi(); } } diff --git a/core/src/main/java/me/pikamug/quests/events/quester/BukkitQuesterPostViewEffectEvent.java b/core/src/main/java/me/pikamug/quests/events/quester/BukkitQuesterPostViewEffectEvent.java index a089bc0e6..7f6ee9b55 100644 --- a/core/src/main/java/me/pikamug/quests/events/quester/BukkitQuesterPostViewEffectEvent.java +++ b/core/src/main/java/me/pikamug/quests/events/quester/BukkitQuesterPostViewEffectEvent.java @@ -10,6 +10,7 @@ package me.pikamug.quests.events.quester; +import lol.pyr.znpcsplus.api.npc.Npc; import me.pikamug.quests.player.BukkitQuester; import org.bukkit.entity.Entity; import org.bukkit.event.HandlerList; @@ -18,6 +19,7 @@ import org.jetbrains.annotations.NotNull; public class BukkitQuesterPostViewEffectEvent extends BukkitQuesterEvent { private static final HandlerList HANDLERS = new HandlerList(); private final Entity entity; + private final Npc npc; private final String effect; private final boolean redoable; @@ -26,6 +28,15 @@ public class BukkitQuesterPostViewEffectEvent extends BukkitQuesterEvent { this.entity = entity; this.effect = effect; this.redoable = redoable; + this.npc=null; + } + + public BukkitQuesterPostViewEffectEvent(final BukkitQuester quester, Npc npc, String effect, boolean redoable) { + super(quester); + this.npc = npc; + this.effect = effect; + this.redoable = redoable; + this.entity = null; } /** @@ -37,6 +48,15 @@ public class BukkitQuesterPostViewEffectEvent extends BukkitQuesterEvent { return entity; } + /** + * Returns the npc involved in this event (only if using ZNPCsPlus 2.0.0 or higher) + * + * @return npc who is involved in this event + */ + public Npc getNpc() { + return npc; + } + /** * Returns the effect involved in this event * diff --git a/core/src/main/java/me/pikamug/quests/listeners/BukkitZnpcsPlusListener.java b/core/src/main/java/me/pikamug/quests/listeners/BukkitZnpcsPlusListener.java new file mode 100644 index 000000000..87ed6a2c9 --- /dev/null +++ b/core/src/main/java/me/pikamug/quests/listeners/BukkitZnpcsPlusListener.java @@ -0,0 +1,271 @@ +package me.pikamug.quests.listeners; + +import lol.pyr.znpcsplus.api.event.NpcInteractEvent; +import lol.pyr.znpcsplus.api.interaction.InteractionType; +import lol.pyr.znpcsplus.api.npc.Npc; +import me.pikamug.quests.BukkitQuestsPlugin; +import me.pikamug.quests.enums.ObjectiveType; +import me.pikamug.quests.player.BukkitQuestProgress; +import me.pikamug.quests.player.Quester; +import me.pikamug.quests.quests.BukkitQuest; +import me.pikamug.quests.quests.Quest; +import me.pikamug.quests.quests.components.BukkitStage; +import me.pikamug.quests.util.BukkitItemUtil; +import me.pikamug.quests.util.BukkitLang; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.conversations.Conversation; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.EnchantmentStorageMeta; + +import java.text.MessageFormat; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.UUID; + +public class BukkitZnpcsPlusListener implements Listener { + + private final BukkitQuestsPlugin plugin; + + public BukkitZnpcsPlusListener(final BukkitQuestsPlugin plugin) { + this.plugin = plugin; + } + + @EventHandler + public void onNPCInteract(final NpcInteractEvent event) { + if (plugin.getDependencies().getZnpcsPlusApi() == null) { + return; + } + // Needed because the NpcInteractEvent is fired async + plugin.getServer().getScheduler().runTask(plugin, () -> { + if (event.getClickType().equals(InteractionType.LEFT_CLICK)) { + if (plugin.getQuestFactory().getSelectingNpcs().contains(event.getPlayer().getUniqueId())) { + if (event.getNpc() == null) { + plugin.getLogger().severe("ZNPCsPlus was null while selecting by left-click"); + return; + } + event.getPlayer().acceptConversationInput(String.valueOf(event.getNpc().getUuid())); + } + } else if (event.getClickType().equals(InteractionType.RIGHT_CLICK)) { + if (plugin.getQuestFactory().getSelectingNpcs().contains(event.getPlayer().getUniqueId())) { + if (event.getNpc() == null) { + plugin.getLogger().severe("ZNPCsPlus was null while selecting by right-click"); + return; + } + event.getPlayer().acceptConversationInput(String.valueOf(event.getNpc().getUuid())); + } + if (!event.getPlayer().isConversing()) { + final Player player = event.getPlayer(); + final Quester quester = plugin.getQuester(player.getUniqueId()); + for (final Quest quest : quester.getCurrentQuests().keySet()) { + final BukkitStage currentStage = (BukkitStage) quester.getCurrentStage(quest); + if (currentStage.containsObjective(ObjectiveType.DELIVER_ITEM)) { + final ItemStack hand = player.getItemInHand(); + int currentIndex = -1; + final LinkedList matches = new LinkedList<>(); + int reasonCode = 0; + for (final ItemStack is : currentStage.getItemsToDeliver()) { + currentIndex++; + reasonCode = BukkitItemUtil.compareItems(is, hand, true); + if (reasonCode == 0) { + matches.add(currentIndex); + } + } + final Npc clicked = event.getNpc(); + if (!matches.isEmpty()) { + for (final Integer match : matches) { + final UUID uuid = currentStage.getItemDeliveryTargets().get(match); + if (uuid.equals(clicked.getUuid())) { + quester.deliverToNPC(quest, uuid, hand); + return; + } + } + } else if (!hand.getType().equals(Material.AIR)) { + for (final UUID uuid : currentStage.getItemDeliveryTargets()) { + if (uuid.equals(clicked.getUuid())) { + String text = ""; + final boolean hasMeta = hand.getItemMeta() != null; + if (hasMeta) { + text += ChatColor.LIGHT_PURPLE + "" + ChatColor.ITALIC + + (hand.getItemMeta().hasDisplayName() ? hand.getItemMeta().getDisplayName() + + ChatColor.GRAY + " (" : ""); + } + text += ChatColor.AQUA + "" + (hand.getDurability() != 0 ? (":" + ChatColor.BLUE + + hand.getDurability()) : "") + ChatColor.GRAY; + if (hasMeta) { + text += (hand.getItemMeta().hasDisplayName() ? ")" : ""); + } + text += " x " + ChatColor.DARK_AQUA + hand.getAmount() + ChatColor.GRAY; + if (plugin.getConfigSettings().canTranslateNames() && !hasMeta + && !hand.getItemMeta().hasDisplayName()) { + plugin.getLocaleManager().sendMessage(player, BukkitLang + .get(player, "questInvalidDeliveryItem").replace("", text), hand + .getType(), hand.getDurability(), null); + } else { + player.sendMessage(BukkitLang.get(player, "questInvalidDeliveryItem") + .replace("", text).replace("", BukkitItemUtil.getName(hand))); + } + switch (reasonCode) { + case 1: + player.sendMessage(ChatColor.GRAY + BukkitLang.get(player, "difference") + .replace("", "one item is null")); + break; + case 0: + player.sendMessage(ChatColor.GRAY + BukkitLang.get(player, "difference") + .replace("", "ERROR")); + break; + case -1: + player.sendMessage(ChatColor.GRAY + BukkitLang.get(player, "difference") + .replace("", "name")); + break; + case -2: + player.sendMessage(ChatColor.GRAY + BukkitLang.get(player, "difference") + .replace("", "amount")); + break; + case -3: + player.sendMessage(ChatColor.GRAY + BukkitLang.get(player, "difference") + .replace("", "durability")); + break; + case -4: + player.sendMessage(ChatColor.GRAY + BukkitLang.get(player, "difference") + .replace("", "display name or lore")); + break; + case -5: + player.sendMessage(ChatColor.GRAY + BukkitLang.get(player, "difference") + .replace("", "enchantments")); + break; + case -6: + player.sendMessage(ChatColor.GRAY + BukkitLang.get(player, "difference") + .replace("", "stored enchants")); + break; + case -7: + player.sendMessage(ChatColor.GRAY + BukkitLang.get(player, "difference") + .replace("", "item flags")); + break; + case -8: + player.sendMessage(ChatColor.GRAY + BukkitLang.get(player, "difference") + .replace("", "book data")); + break; + case -9: + player.sendMessage(ChatColor.GRAY + BukkitLang.get(player, "difference") + .replace("", "potion type")); + break; + case -10: + player.sendMessage(ChatColor.GRAY + BukkitLang.get(player, "difference") + .replace("", "fish variant")); + break; + default: + player.sendMessage(ChatColor.GRAY + BukkitLang.get(player, "difference") + .replace("", "unknown")); + } + if (hasMeta) { + if (hand.getType().equals(Material.ENCHANTED_BOOK)) { + final EnchantmentStorageMeta esMeta = (EnchantmentStorageMeta) hand.getItemMeta(); + if (esMeta.hasStoredEnchants()) { + for (final Map.Entry e : esMeta.getStoredEnchants() + .entrySet()) { + final HashMap single = new HashMap<>(); + single.put(e.getKey(), e.getValue()); + plugin.getLocaleManager().sendMessage(player, ChatColor.GRAY + "\u2515 " + + ChatColor.DARK_GREEN + " \n", single); + } + } + } + } + break; + } + } + } + } + } + boolean hasObjective = false; + for (final Quest quest : quester.getCurrentQuests().keySet()) { + if (!quester.meetsCondition(quest, true)) { + continue; + } + if (quester.getCurrentStage(quest).containsObjective(ObjectiveType.TALK_TO_NPC)) { + if (quester.getCurrentStage(quest).getNpcsToInteract().contains(event.getNpc().getUuid())) { + final int npcIndex = quester.getCurrentStage(quest).getNpcsToInteract().indexOf(event.getNpc() + .getUuid()); + if (quester.getQuestDataOrDefault(quest) != null && npcIndex > -1 + && !((BukkitQuestProgress) quester.getQuestDataOrDefault(quest)).npcsInteracted.get(npcIndex)) { + hasObjective = true; + } + quester.interactWithNPC(quest, event.getNpc().getUuid()); + } + } + } + if (hasObjective || !plugin.getQuestNpcUuids().contains(event.getNpc().getUuid())) { + return; + } + boolean hasAtLeastOneGUI = false; + final LinkedList npcQuests = new LinkedList<>(); + for (final Quest quest : plugin.getLoadedQuests()) { + final BukkitQuest bukkitQuest = (BukkitQuest) quest; + if (quester.getCurrentQuests().containsKey(bukkitQuest)) { + continue; + } + if (bukkitQuest.getNpcStart() != null && bukkitQuest.getNpcStart().equals(event.getNpc().getUuid())) { + if (plugin.getConfigSettings().canIgnoreLockedQuests() + && (!quester.getCompletedQuests().contains(bukkitQuest) + || bukkitQuest.getPlanner().getCooldown() > -1)) { + if (bukkitQuest.testRequirements(quester)) { + npcQuests.add(bukkitQuest); + if (bukkitQuest.getGUIDisplay() != null) { + hasAtLeastOneGUI = true; + } + } + } else if (!quester.getCompletedQuests().contains(bukkitQuest) || bukkitQuest.getPlanner().getCooldown() > -1) { + npcQuests.add(bukkitQuest); + if (bukkitQuest.getGUIDisplay() != null) { + hasAtLeastOneGUI = true; + } + } + } + } + if (npcQuests.size() == 1) { + final BukkitQuest quest = (BukkitQuest) npcQuests.get(0); + if (quester.canAcceptOffer(quest, true)) { + quester.setQuestIdToTake(quest.getId()); + if (!plugin.getConfigSettings().canConfirmAccept()) { + quester.takeQuest(quest, false); + } else { + if (quest.getGUIDisplay() != null) { + quester.showGUIDisplay(event.getNpc().getUuid(), npcQuests); + } else { + for (final String msg : extracted(quester).split("
")) { + player.sendMessage(msg); + } + plugin.getConversationFactory().buildConversation(player).begin(); + } + } + } + } else if (npcQuests.size() > 1) { + if (hasAtLeastOneGUI) { + quester.showGUIDisplay(event.getNpc().getUuid(), npcQuests); + } else { + final Conversation c = plugin.getNpcConversationFactory().buildConversation(player); + c.getContext().setSessionData("npcQuests", npcQuests); + //c.getContext().setSessionData("npc", event.getNpc().getGameProfile().getName()); + c.getContext().setSessionData("npc", plugin.getDependencies().getNpcName(event.getNpc().getUuid())); + c.begin(); + } + } else { + BukkitLang.send(player, ChatColor.YELLOW + BukkitLang.get(player, "noMoreQuest")); + } + } + } + }); + } + + private String extracted(final Quester quester) { + final Quest quest = plugin.getQuestById(quester.getQuestIdToTake()); + return MessageFormat.format("{0}- {1}{2}{3} -\n\n{4}{5}\n", ChatColor.GOLD, ChatColor.DARK_PURPLE, + quest.getName(), ChatColor.GOLD, ChatColor.RESET, quest.getDescription()); + } +} diff --git a/core/src/main/java/me/pikamug/quests/player/BukkitQuester.java b/core/src/main/java/me/pikamug/quests/player/BukkitQuester.java index 9a45457c3..6405304b9 100644 --- a/core/src/main/java/me/pikamug/quests/player/BukkitQuester.java +++ b/core/src/main/java/me/pikamug/quests/player/BukkitQuester.java @@ -15,6 +15,7 @@ import com.alessiodp.parties.api.interfaces.PartyPlayer; import com.gmail.nossr50.datatypes.skills.SkillType; import com.gmail.nossr50.util.player.UserManager; import io.github.znetworkw.znpcservers.npc.NPC; +import lol.pyr.znpcsplus.api.npc.Npc; import me.clip.placeholderapi.PlaceholderAPI; import me.pikamug.localelib.LocaleManager; import me.pikamug.quests.BukkitQuestsPlugin; @@ -568,6 +569,19 @@ public class BukkitQuester implements Quester { } return false; } + if (plugin.getDependencies().getZnpcsPlusApi() != null && + plugin.getDependencies().getZnpcsPlusApi().getNpcRegistry().getByUuid(uuid) != null) { + Npc znpc = plugin.getDependencies().getZnpcsPlusApi().getNpcRegistry().getByUuid(uuid).getNpc(); + if (znpc.getWorld() != null && znpc.getWorld().equals(getPlayer().getWorld()) && + znpc.getLocation().toBukkitLocation(znpc.getWorld()).distance(getPlayer().getLocation()) > 6.0) { + if (giveReason) { + final String msg = BukkitLang.get(getPlayer(), "mustSpeakTo") + .replace("", ChatColor.DARK_PURPLE + plugin.getDependencies().getNpcName(znpc.getUuid()) + ChatColor.YELLOW); + sendMessage(ChatColor.YELLOW + msg); + } + return false; + } + } } if (getCurrentQuests().size() >= plugin.getConfigSettings().getMaxQuests() && plugin.getConfigSettings().getMaxQuests() > 0) { @@ -3347,10 +3361,8 @@ public class BukkitQuester implements Quester { final String display = getCurrentStage(quest).getPasswordDisplays().get(index); bukkitQuestData.passwordsSaid.set(index, true); - plugin.getServer().getScheduler().runTask(plugin, () -> { - finishObjective(quest, new BukkitObjective(type, null, new ItemStack(Material.AIR, 1), - new ItemStack(Material.AIR, 1)), null, null, null, null, null, display, null); - }); + plugin.getServer().getScheduler().runTask(plugin, () -> finishObjective(quest, new BukkitObjective(type, null, new ItemStack(Material.AIR, 1), + new ItemStack(Material.AIR, 1)), null, null, null, null, null, display, null)); final int finalIndex = index; dispatchedQuestIDs.addAll(dispatchMultiplayerEverything(quest, type, @@ -4384,8 +4396,7 @@ public class BukkitQuester implements Quester { } /** - * Forcibly set Quester's current stage, then update Quest Journal - * + * Forcibly set Quester's current stage, then update Quest Journal
* Does not save changes to disk. Consider calling {@link #saveData()} followed by {@link #loadData()} * * @param key The quest to set stage of diff --git a/core/src/main/java/me/pikamug/quests/quests/BukkitQuest.java b/core/src/main/java/me/pikamug/quests/quests/BukkitQuest.java index 0d43c6be3..9bb62472d 100644 --- a/core/src/main/java/me/pikamug/quests/quests/BukkitQuest.java +++ b/core/src/main/java/me/pikamug/quests/quests/BukkitQuest.java @@ -16,6 +16,7 @@ import com.gmail.nossr50.datatypes.skills.SkillType; import com.gmail.nossr50.util.player.UserManager; import com.herocraftonline.heroes.characters.Hero; import io.github.znetworkw.znpcservers.npc.NPC; +import lol.pyr.znpcsplus.api.npc.Npc; import me.clip.placeholderapi.PlaceholderAPI; import me.pikamug.quests.BukkitQuestsPlugin; import me.pikamug.quests.actions.Action; @@ -422,6 +423,11 @@ public class BukkitQuest implements Quest { targetLocation = opt.get().getLocation(); } } + if (plugin.getDependencies().getZnpcsPlusApi() != null + && plugin.getDependencies().getZnpcsPlusApi().getNpcRegistry().getByUuid(uuid) != null) { + Npc znpc = plugin.getDependencies().getZnpcsPlusApi().getNpcRegistry().getByUuid(uuid).getNpc(); + targetLocation = znpc.getLocation().toBukkitLocation(znpc.getWorld()); + } } else if (stage.getPlayersToKill() != null && stage.getPlayersToKill() > 0) { if (quester.getPlayer() == null) { return; diff --git a/core/src/main/java/me/pikamug/quests/quests/BukkitQuestFactory.java b/core/src/main/java/me/pikamug/quests/quests/BukkitQuestFactory.java index c31fc698b..ea3bae782 100644 --- a/core/src/main/java/me/pikamug/quests/quests/BukkitQuestFactory.java +++ b/core/src/main/java/me/pikamug/quests/quests/BukkitQuestFactory.java @@ -154,7 +154,9 @@ public class BukkitQuestFactory implements QuestFactory, ConversationAbandonedLi context.setSessionData(Key.Q_NAME, bukkitQuest.getName()); context.setSessionData(Key.Q_ASK_MESSAGE, bukkitQuest.getDescription()); context.setSessionData(Key.Q_FINISH_MESSAGE, bukkitQuest.getFinished()); - if (plugin.getDependencies().getCitizens() != null) { + if (plugin.getDependencies().getCitizens() != null + || plugin.getDependencies().getZnpcsPlus() != null + || plugin.getDependencies().getZnpcsPlusApi() != null) { if (bukkitQuest.getNpcStart() != null) { context.setSessionData(Key.Q_START_NPC, bukkitQuest.getNpcStart().toString()); } diff --git a/core/src/main/java/me/pikamug/quests/tasks/BukkitNpcEffectThread.java b/core/src/main/java/me/pikamug/quests/tasks/BukkitNpcEffectThread.java index bb1a261f5..228d146bb 100644 --- a/core/src/main/java/me/pikamug/quests/tasks/BukkitNpcEffectThread.java +++ b/core/src/main/java/me/pikamug/quests/tasks/BukkitNpcEffectThread.java @@ -10,6 +10,8 @@ package me.pikamug.quests.tasks; +import lol.pyr.znpcsplus.api.npc.Npc; +import lol.pyr.znpcsplus.api.npc.NpcEntry; import me.pikamug.quests.enums.BukkitPreBuiltParticle; import me.pikamug.quests.player.BukkitQuester; import me.pikamug.quests.BukkitQuestsPlugin; @@ -20,6 +22,7 @@ import org.bukkit.Location; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; +import java.util.Collection; import java.util.List; import java.util.UUID; @@ -54,6 +57,20 @@ public class BukkitNpcEffectThread implements Runnable { } } } + if (plugin.getDependencies().getZnpcsPlusApi() != null) { + Collection znpcs = plugin.getDependencies().getZnpcsPlusApi().getNpcRegistry().getAllPlayerMade(); + for (NpcEntry npc : znpcs) { + if (npc.getNpc().getWorld() == null || player.getLocation().getWorld() == null) { + return; + } + if (npc.getNpc().getWorld().equals(player.getLocation().getWorld())) { + if (npc.getNpc().getLocation().toBukkitLocation(npc.getNpc().getWorld()) + .distanceSquared(player.getLocation()) < 24) { + showConfigEffect(plugin.getQuester(player.getUniqueId()), npc.getNpc()); + } + } + } + } } } @@ -76,11 +93,36 @@ public class BukkitNpcEffectThread implements Runnable { showEffect(quester.getPlayer(), entity, plugin.getConfigSettings().getRedoEffect()); event = new BukkitQuesterPostViewEffectEvent(quester, entity, - plugin.getConfigSettings().getEffect(), true); + plugin.getConfigSettings().getRedoEffect(), true); plugin.getServer().getPluginManager().callEvent(event); } } } + + /** + * Display config setting particle effect above an {@link Npc} one time + * @param quester Target quester to let view the effect + * @param npc Target NPC to place the effect above + */ + public void showConfigEffect(final BukkitQuester quester, final Npc npc) { + if (npc == null) return; + final BukkitQuesterPostViewEffectEvent event; + if (quester.canAcceptQuest(npc.getUuid())) { + if (npc.getWorld() == null) return; + showEffect(quester.getPlayer(), npc.getLocation().toBukkitLocation(npc.getWorld()).add(0, 2, 0), plugin.getConfigSettings().getEffect()); + + event = new BukkitQuesterPostViewEffectEvent(quester, npc, + plugin.getConfigSettings().getEffect(), false); + plugin.getServer().getPluginManager().callEvent(event); + } else if (quester.canAcceptCompletedRedoableQuest(npc.getUuid())) { + if (npc.getWorld() == null) return; + showEffect(quester.getPlayer(), npc.getLocation().toBukkitLocation(npc.getWorld()).add(0, 2, 0), plugin.getConfigSettings().getRedoEffect()); + + event = new BukkitQuesterPostViewEffectEvent(quester, npc, + plugin.getConfigSettings().getRedoEffect(), true); + plugin.getServer().getPluginManager().callEvent(event); + } + } /** * Display specified particle effect above a Citizens NPC one time @@ -111,13 +153,21 @@ public class BukkitNpcEffectThread implements Runnable { * @param effectType Value of {@link org.bukkit.Particle} or {@link BukkitPreBuiltParticle} */ public void showEffect(final Player player, final Entity entity, final String effectType) { - if (player == null || entity == null) { + showEffect(player, entity.getLocation().add(0, 2, 0), effectType); + } + + /** + * Display specified particle effect at a location one time + * @param player Target player to let view the effect + * @param location Target location to place the effect at + * @param effectType Value of {@link org.bukkit.Particle} or {@link BukkitPreBuiltParticle} + */ + public void showEffect(final Player player, final Location location, final String effectType) { + if (player == null || location == null) { return; } - final Location eyeLoc = entity.getLocation(); - eyeLoc.setY(eyeLoc.getY() + 2); try { - BukkitParticleProvider.sendToPlayer(player, eyeLoc, effectType.toUpperCase()); + BukkitParticleProvider.sendToPlayer(player, location, effectType.toUpperCase()); } catch (final NoClassDefFoundError e) { // Unsupported Minecraft version }