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 extends NpcEntry> 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
}