diff --git a/main/pom.xml b/main/pom.xml index 02e08637e..b8ec50ead 100644 --- a/main/pom.xml +++ b/main/pom.xml @@ -1,157 +1,162 @@ - - 4.0.0 - - me.blackvein.quests - quests-parent - 3.8.0 - - quests-main - - - UTF-8 - - - - - - jitpack.io - https://jitpack.io - - - spigot-repo - https://hub.spigotmc.org/nexus/content/repositories/snapshots/ - - - citizens - http://repo.citizensnpcs.co/ - - - sk89q-repo - http://maven.sk89q.com/repo/ - - - placeholderapi - http://repo.extendedclip.com/content/repositories/placeholderapi/ - - - heroes-stripped - http://nexus.hc.to/content/repositories/pub_releases/ - - - Vault - http://nexus.hc.to/content/repositories/pub_releases/ - - - - - - org.bukkit - bukkit - 1.13.2-R0.1-SNAPSHOT - provided - - - net.citizensnpcs - citizens - 2.0.21-SNAPSHOT - provided - - - com.denizenscript - denizen - 1.1.0-SNAPSHOT - provided - - - net.milkbowl.vault - Vault - 1.7.1 - provided - - - com.github.mcMMO-Dev - mcMMO-Classic - master-82f97cbe04-1 - provided - - - com.herocraftonline.heroes - heroes-stripped - 4dd3dd85 - provided - - - com.sk89q.worldedit - worldedit-bukkit - 7.0.1-SNAPSHOT - provided - - - com.sk89q.worldguard - worldguard-bukkit - 7.0.1-SNAPSHOT - provided - - - me.clip - placeholderapi - 2.8.2 - provided - - - com.github.nicuch - CitizensBooks - master-SNAPSHOT - provided - - - com.github.PikaMug - PhatLoots - -SNAPSHOT - provided - - - com.github.DRE2N - DungeonsXL - -6523caa908-1 - provided - - - com.github.AlessioDP.Parties - parties-api - 2.4.6 - provided - - - - - clean package install - ${basedir}/src/main/java - - - - . - ${basedir}/src/main/resources/ - true - - lang/**/*.* - config.yml - plugin.yml - actions.yml - quests.yml - data.yml - strings.yml - - - - . - ${basedir}/ - false - - README.md - - - - - + + 4.0.0 + + me.blackvein.quests + quests-parent + 3.8.0 + + quests-main + + + UTF-8 + + + + + + jitpack.io + https://jitpack.io + + + + codemc-repo + https://repo.codemc.org/repository/maven-public/ + + + spigot-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + citizens + http://repo.citizensnpcs.co/ + + + sk89q-repo + http://maven.sk89q.com/repo/ + + + placeholderapi + http://repo.extendedclip.com/content/repositories/placeholderapi/ + + + heroes-stripped + http://nexus.hc.to/content/repositories/pub_releases/ + + + Vault + http://nexus.hc.to/content/repositories/pub_releases/ + + + + + + org.bukkit + bukkit + 1.13.2-R0.1-SNAPSHOT + provided + + + net.citizensnpcs + citizens + 2.0.21-SNAPSHOT + provided + + + com.denizenscript + denizen + 1.1.0-SNAPSHOT + provided + + + net.milkbowl.vault + Vault + 1.7.1 + provided + + + com.github.mcMMO-Dev + mcMMO-Classic + master-82f97cbe04-1 + provided + + + com.herocraftonline.heroes + heroes-stripped + 4dd3dd85 + provided + + + com.sk89q.worldedit + worldedit-bukkit + 7.0.1-SNAPSHOT + provided + + + com.sk89q.worldguard + worldguard-bukkit + 7.0.1-SNAPSHOT + provided + + + me.clip + placeholderapi + 2.8.2 + provided + + + com.github.nicuch + CitizensBooks + master-SNAPSHOT + provided + + + com.github.PikaMug + PhatLoots + -SNAPSHOT + provided + + + com.github.DRE2N + DungeonsXL + -6523caa908-1 + provided + + + com.alessiodp.parties + parties-api + 2.6.3 + provided + + + + + clean package install + ${basedir}/src/main/java + + + + . + ${basedir}/src/main/resources/ + true + + lang/**/*.* + config.yml + plugin.yml + actions.yml + quests.yml + data.yml + strings.yml + + + + . + ${basedir}/ + false + + README.md + + + + + diff --git a/main/src/main/java/me/blackvein/quests/CustomObjective.java b/main/src/main/java/me/blackvein/quests/CustomObjective.java index 5ad2ead0c..23dd696a5 100644 --- a/main/src/main/java/me/blackvein/quests/CustomObjective.java +++ b/main/src/main/java/me/blackvein/quests/CustomObjective.java @@ -18,8 +18,10 @@ import java.util.LinkedList; import java.util.Map; import java.util.Map.Entry; +import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.Listener; +import org.bukkit.inventory.ItemStack; public abstract class CustomObjective implements Listener { @@ -112,8 +114,6 @@ public abstract class CustomObjective implements Listener { /** * Check whether to let user set required amount for objective - * - * @param enableCount */ public boolean canShowCount() { return showCount; @@ -122,7 +122,7 @@ public abstract class CustomObjective implements Listener { /** * Set whether to let user set required amount for objective * - * @param enableCount + * @param showCount */ public void setShowCount(boolean showCount) { this.showCount = showCount; @@ -216,8 +216,16 @@ public abstract class CustomObjective implements Listener { } } if (index > -1) { - if (quester.getQuestData(quest).customObjectiveCounts.get(obj.getName()) >= quester.getCurrentStage(quest).customObjectiveCounts.get(index)) { - quester.finishObjective(quest, "customObj", null, null, null, null, null, null, null, null, null, obj); + int goal = quester.getCurrentStage(quest).customObjectiveCounts.get(index); + if (quester.getQuestData(quest).customObjectiveCounts.get(obj.getName()) >= goal) { + quester.finishObjective(quest, "customObj", new ItemStack(Material.AIR, 1), new ItemStack(Material.AIR, goal), null, null, null, null, null, null, null, obj); + + // Multiplayer + quester.dispatchMultiplayerObjectives(quest, quester.getCurrentStage(quest), (Quester q) -> { + q.getQuestData(quest).customObjectiveCounts.put(obj.getName(), quester.getQuestData(quest).customObjectiveCounts.get(obj.getName())); + q.finishObjective(quest, "customObj", new ItemStack(Material.AIR, 1), new ItemStack(Material.AIR, goal), null, null, null, null, null, null, null, obj); + return null; + }); } } } diff --git a/main/src/main/java/me/blackvein/quests/Options.java b/main/src/main/java/me/blackvein/quests/Options.java index f559231c7..2f3dd8158 100644 --- a/main/src/main/java/me/blackvein/quests/Options.java +++ b/main/src/main/java/me/blackvein/quests/Options.java @@ -18,6 +18,7 @@ public class Options { private boolean useDungeonsXLPlugin = false; private boolean usePartiesPlugin = true; private int shareProgressLevel = 1; + private boolean requireSameQuest = true; public boolean getAllowCommands() { return allowCommands; @@ -58,4 +59,12 @@ public class Options { public void setShareProgressLevel(int shareProgressLevel) { this.shareProgressLevel = shareProgressLevel; } + + public boolean getRequireSameQuest() { + return requireSameQuest; + } + + public void setRequireSameQuest(boolean requireSameQuest) { + this.requireSameQuest = requireSameQuest; + } } \ No newline at end of file diff --git a/main/src/main/java/me/blackvein/quests/Quest.java b/main/src/main/java/me/blackvein/quests/Quest.java index 763f1cae5..c6a1e84fd 100644 --- a/main/src/main/java/me/blackvein/quests/Quest.java +++ b/main/src/main/java/me/blackvein/quests/Quest.java @@ -1,751 +1,762 @@ -/******************************************************************************************************* - * Continued by PikaMug (formerly HappyPikachu) with permission from _Blackvein_. All rights reserved. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - *******************************************************************************************************/ - -package me.blackvein.quests; - -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Location; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemFlag; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.PlayerInventory; - -import com.codisimus.plugins.phatloots.PhatLootsAPI; -import com.codisimus.plugins.phatloots.loot.CommandLoot; -import com.codisimus.plugins.phatloots.loot.LootBundle; -import com.gmail.nossr50.datatypes.skills.SkillType; -import com.gmail.nossr50.util.player.UserManager; -import com.herocraftonline.heroes.characters.Hero; - -import me.blackvein.quests.actions.Action; -import me.blackvein.quests.events.quester.QuesterPostChangeStageEvent; -import me.blackvein.quests.events.quester.QuesterPostCompleteQuestEvent; -import me.blackvein.quests.events.quester.QuesterPostFailQuestEvent; -import me.blackvein.quests.events.quester.QuesterPreChangeStageEvent; -import me.blackvein.quests.events.quester.QuesterPreCompleteQuestEvent; -import me.blackvein.quests.events.quester.QuesterPreFailQuestEvent; -import me.blackvein.quests.exceptions.InvalidStageException; -import me.blackvein.quests.util.ItemUtil; -import me.blackvein.quests.util.Lang; -import me.clip.placeholderapi.PlaceholderAPI; -import net.citizensnpcs.api.npc.NPC; - -public class Quest { - - protected Quests plugin; - private String name; - protected String description; - protected String finished; - protected String region = null; - protected ItemStack guiDisplay = null; - private LinkedList orderedStages = new LinkedList(); - protected NPC npcStart; - protected Location blockStart; - protected Action initialAction; - private Requirements reqs = new Requirements(); - private Planner pln = new Planner(); - private Rewards rews = new Rewards(); - private Options opts = new Options(); - - public Requirements getRequirements() { - return reqs; - } - - public Planner getPlanner() { - return pln; - } - - public Rewards getRewards() { - return rews; - } - - public Options getOptions() { - return opts; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getFinished() { - return finished; - } - - public void setFinished(String finished) { - this.finished = finished; - } - - public String getRegion() { - return region; - } - - public void setRegion(String region) { - this.region = region; - } - - public ItemStack getGUIDisplay() { - return guiDisplay; - } - - public void setGUIDisplay(ItemStack guiDisplay) { - this.guiDisplay = guiDisplay; - } - - public Stage getStage(int index) { - try { - return orderedStages.get(index); - } catch (Exception e) { - return null; - } - } - - public LinkedList getStages() { - return orderedStages; - } - - public NPC getNpcStart() { - return npcStart; - } - - public void setNpcStart(NPC npcStart) { - this.npcStart = npcStart; - } - - public Location getBlockStart() { - return blockStart; - } - - public void setBlockStart(Location blockStart) { - this.blockStart = blockStart; - } - - public Action getInitialAction() { - return initialAction; - } - - public void setInitialAction(Action initialAction) { - this.initialAction = initialAction; - } - - /** - * Force player to proceed to the next ordered stage - * - * @param q Player to force - */ - public void nextStage(Quester q) { - if (q.getCurrentStage(this) == null) { - plugin.getLogger().severe("Current stage was null for quester " + q.getPlayer().getUniqueId()); - return; - } - String stageCompleteMessage = q.getCurrentStage(this).completeMessage; - if (stageCompleteMessage != null) { - q.getPlayer().sendMessage(plugin.parseStringWithPossibleLineBreaks(stageCompleteMessage, this, q.getPlayer())); - } - if (plugin.getSettings().canUseCompass()) { - q.resetCompass(); - q.findCompassTarget(); - } - if (q.getCurrentStage(this).delay < 0) { - if (q.getCurrentStage(this).finishEvent != null) { - q.getCurrentStage(this).finishEvent.fire(q, this); - } - if (q.currentQuests.get(this) == (orderedStages.size() - 1)) { - if (q.getCurrentStage(this).script != null) { - plugin.getDenizenTrigger().runDenizenScript(q.getCurrentStage(this).script, q); - } - completeQuest(q); - } else { - try { - setStage(q, q.currentQuests.get(this) + 1); - - // Multiplayer - if (opts.getShareProgressLevel() == 3) { - List mq = q.getMultiplayerQuesters(this); - if (mq != null) { - for (Quester qq : mq) { - if (qq.getCurrentQuests().containsKey(this)) { - setStage(qq, qq.currentQuests.get(this) + 1); - } - } - } - } - } catch (InvalidStageException e) { - e.printStackTrace(); - } - } - if (q.getQuestData(this) != null) { - q.getQuestData(this).delayStartTime = 0; - q.getQuestData(this).delayTimeLeft = -1; - } - } else { - q.startStageTimer(this); - } - q.updateJournal(); - } - - /** - * Force player to proceed to the specified stage - * @param quester Player to force - * @param stage Stage number to specify - * @throws InvalidStageException if stage does not exist - */ - public void setStage(Quester quester, int stage) throws InvalidStageException { - if (orderedStages.size() - 1 < stage) { - throw new InvalidStageException(this, stage); - } - Stage currentStage = quester.getCurrentStage(this); - Stage nextStage = getStage(stage); - QuesterPreChangeStageEvent preEvent = new QuesterPreChangeStageEvent(quester, this, currentStage, nextStage); - plugin.getServer().getPluginManager().callEvent(preEvent); - if (preEvent.isCancelled()) { - return; - } - quester.hardQuit(this); - quester.hardStagePut(this, stage); - quester.addEmptiesFor(this, stage); - if (currentStage.script != null) { - plugin.getDenizenTrigger().runDenizenScript(currentStage.script, quester); - } - /* - * if (quester.getCurrentStage(this).finishEvent != null) { quester.getCurrentStage(this).finishEvent.fire(quester); } - */ - if (nextStage.startEvent != null) { - nextStage.startEvent.fire(quester, this); - } - updateCompass(quester, nextStage); - String msg = Lang.get(quester.getPlayer(), "questObjectivesTitle"); - msg = msg.replace("", name); - quester.getPlayer().sendMessage(ChatColor.GOLD + msg); - plugin.showObjectives(this, quester, false); - String stageStartMessage = quester.getCurrentStage(this).startMessage; - if (stageStartMessage != null) { - quester.getPlayer().sendMessage(plugin.parseStringWithPossibleLineBreaks(stageStartMessage, this, quester.getPlayer())); - } - quester.updateJournal(); - QuesterPostChangeStageEvent postEvent = new QuesterPostChangeStageEvent(quester, this, currentStage, nextStage); - plugin.getServer().getPluginManager().callEvent(postEvent); - } - - /** - * Set location-objective target for compass.

- * - * Method may be called as often as needed. - * - * @param quester The quester to have their compass updated - * @param nextStage The stage to process for targets - * @return true if successful - */ - public boolean updateCompass(Quester quester, Stage nextStage) { - if (!plugin.getSettings().canUseCompass()) { - return false; - } - if (quester == null) { - return false; - } - if (nextStage == null) { - return false; - } - Location targetLocation = null; - if (nextStage.citizensToInteract != null && nextStage.citizensToInteract.size() > 0) { - targetLocation = plugin.getNPCLocation(nextStage.citizensToInteract.getFirst()); - } else if (nextStage.citizensToKill != null && nextStage.citizensToKill.size() > 0) { - targetLocation = plugin.getNPCLocation(nextStage.citizensToKill.getFirst()); - } else if (nextStage.locationsToReach != null && nextStage.locationsToReach.size() > 0) { - targetLocation = nextStage.locationsToReach.getFirst(); - } else if (nextStage.itemDeliveryTargets != null && nextStage.itemDeliveryTargets.size() > 0) { - NPC npc = plugin.getDependencies().getCitizens().getNPCRegistry().getById(nextStage.itemDeliveryTargets.getFirst()); - targetLocation = npc.getStoredLocation(); - } - if (targetLocation != null && targetLocation.getWorld() != null) { - if (targetLocation.getWorld().getName().equals(quester.getPlayer().getWorld().getName())) { - quester.getPlayer().setCompassTarget(targetLocation); - } - } - return targetLocation != null; - } - - /** - * Check that a quester has met all Requirements to accept this quest - * - * @param quester The quester to check - * @return true if all Requirements have been met - */ - public boolean testRequirements(Quester quester) { - return testRequirements(quester.getPlayer()); - } - - /** - * Check that a player has met all Requirements to accept this quest - * - * @param player The player to check - * @return true if all Requirements have been met - */ - protected boolean testRequirements(Player player) { - Quester quester = plugin.getQuester(player.getUniqueId()); - if (reqs.getMoney() != 0 && plugin.getDependencies().getVaultEconomy() != null) { - if (plugin.getDependencies().getVaultEconomy().getBalance(Bukkit.getOfflinePlayer(player.getUniqueId())) < reqs.getMoney()) { - return false; - } - } - PlayerInventory inventory = player.getInventory(); - int num = 0; - for (ItemStack is : reqs.getItems()) { - for (ItemStack stack : inventory.getContents()) { - if (stack != null) { - if (ItemUtil.compareItems(is, stack, true) == 0) { - num += stack.getAmount(); - } - } - } - if (num < is.getAmount()) { - return false; - } - num = 0; - } - for (String s : reqs.getPermissions()) { - if (player.hasPermission(s) == false) { - return false; - } - } - for (String s : reqs.getMcmmoSkills()) { - final SkillType st = Quests.getMcMMOSkill(s); - final int lvl = reqs.getMcmmoAmounts().get(reqs.getMcmmoSkills().indexOf(s)); - if (UserManager.getPlayer(player).getProfile().getSkillLevel(st) < lvl) { - return false; - } - } - if (reqs.getHeroesPrimaryClass() != null) { - if (plugin.testPrimaryHeroesClass(reqs.getHeroesPrimaryClass(), player.getUniqueId()) == false) { - return false; - } - } - if (reqs.getHeroesSecondaryClass() != null) { - if (plugin.testSecondaryHeroesClass(reqs.getHeroesSecondaryClass(), player.getUniqueId()) == false) { - return false; - } - } - for (String s : reqs.getCustomRequirements().keySet()) { - CustomRequirement found = null; - for (CustomRequirement cr : plugin.getCustomRequirements()) { - if (cr.getName().equalsIgnoreCase(s)) { - found = cr; - break; - } - } - if (found != null) { - if (found.testRequirement(player, reqs.getCustomRequirements().get(s)) == false) { - return false; - } - } else { - plugin.getLogger().warning("Quester \"" + player.getName() + "\" attempted to take Quest \"" + name + "\", but the Custom Requirement \"" + s - + "\" could not be found. Does it still exist?"); - } - } - if (quester.questPoints < reqs.getQuestPoints()) { - return false; - } - if (quester.completedQuests.containsAll(reqs.getNeededQuests()) == false) { - return false; - } - for (String q : reqs.getBlockQuests()) { - Quest questObject = new Quest(); - questObject.name = q; - if (quester.completedQuests.contains(q) || quester.currentQuests.containsKey(questObject)) { - return false; - } - } - return true; - } - - /** - * Proceed to finish this quest, issuing any rewards - * - * @param q The quester finishing this quest - */ - @SuppressWarnings("deprecation") - public void completeQuest(Quester q) { - QuesterPreCompleteQuestEvent preEvent = new QuesterPreCompleteQuestEvent(q, this); - plugin.getServer().getPluginManager().callEvent(preEvent); - if (preEvent.isCancelled()) { - return; - } - final Player player = plugin.getServer().getPlayer(q.getUUID()); - q.hardQuit(this); - if (!q.completedQuests.contains(name)) { - q.completedQuests.add(name); - } - String none = ChatColor.GRAY + "- (" + Lang.get(player, "none") + ")"; - final String[] ps = plugin.parseStringWithPossibleLineBreaks(ChatColor.AQUA + finished, this, player); - for (Map.Entry entry : q.timers.entrySet()) { - if (entry.getValue().getName().equals(getName())) { - plugin.getServer().getScheduler().cancelTask(entry.getKey()); - q.timers.remove(entry.getKey()); - } - } - Bukkit.getScheduler().runTaskLater(plugin, new Runnable() { - - @Override - public void run() { - player.sendMessage(ps); - } - }, 40); - if (rews.getMoney() > 0 && plugin.getDependencies().getVaultEconomy() != null) { - plugin.getDependencies().getVaultEconomy().depositPlayer(q.getOfflinePlayer(), rews.getMoney()); - none = null; - } - if (pln.getCooldown() > -1) { - q.completedTimes.put(this.name, System.currentTimeMillis()); - if (q.amountsCompleted.containsKey(this.name)) { - q.amountsCompleted.put(this.name, q.amountsCompleted.get(this.name) + 1); - } else { - q.amountsCompleted.put(this.name, 1); - } - } - for (ItemStack i : rews.getItems()) { - try { - Quests.addItem(player, i); - } catch (Exception e) { - plugin.getLogger().severe("Unable to add null reward item to inventory of " - + player.getName() + " upon completion of quest " + name); - player.sendMessage(ChatColor.RED + "Quests encountered a problem with an item. " - + "Please contact an administrator."); - } - none = null; - } - for (String s : rews.getCommands()) { - String temp = s.replace("", player.getName()); - if (plugin.getDependencies().getPlaceholderApi() != null) { - temp = PlaceholderAPI.setPlaceholders(player, temp); - } - final String command = temp; - if (Bukkit.isPrimaryThread()) { - Bukkit.getServer().dispatchCommand(plugin.getServer().getConsoleSender(), command); - } else { - Bukkit.getScheduler().runTask(plugin, new Runnable() { - - @Override - public void run() { - Bukkit.getServer().dispatchCommand(plugin.getServer().getConsoleSender(), command); - } - }); - } - none = null; - } - for (String s : rews.getPermissions()) { - if (plugin.getDependencies().getVaultPermission() != null) { - plugin.getDependencies().getVaultPermission().playerAdd(player, s); - } - none = null; - } - for (String s : rews.getMcmmoSkills()) { - UserManager.getPlayer(player).getProfile().addLevels(Quests.getMcMMOSkill(s), rews.getMcmmoAmounts().get(rews.getMcmmoSkills().indexOf(s))); - none = null; - } - for (String s : rews.getHeroesClasses()) { - Hero hero = plugin.getHero(player.getUniqueId()); - hero.addExp(rews.getHeroesAmounts().get(rews.getHeroesClasses().indexOf(s)), plugin.getDependencies().getHeroes().getClassManager().getClass(s), player.getLocation()); - none = null; - } - LinkedList phatLootItems = new LinkedList(); - int phatLootExp = 0; - LinkedList phatLootMessages = new LinkedList(); - for (String s : rews.getPhatLoots()) { - LootBundle lb = PhatLootsAPI.getPhatLoot(s).rollForLoot(); - if (lb.getExp() > 0) { - phatLootExp += lb.getExp(); - player.giveExp(lb.getExp()); - } - if (lb.getMoney() > 0) { - if (plugin.getDependencies().getVaultEconomy() != null) { - plugin.getDependencies().getVaultEconomy().depositPlayer(Bukkit.getOfflinePlayer(player.getUniqueId()), lb.getMoney()); - } - } - if (lb.getItemList().isEmpty() == false) { - phatLootItems.addAll(lb.getItemList()); - for (ItemStack is : lb.getItemList()) { - try { - Quests.addItem(player, is); - } catch (Exception e) { - plugin.getLogger().severe("Unable to add PhatLoots item to inventory of " - + player.getName() + " upon completion of quest " + name); - player.sendMessage(ChatColor.RED + "Quests encountered a problem with an item. " - + "Please contact an administrator."); - } - } - } - if (lb.getCommandList().isEmpty() == false) { - for (CommandLoot cl : lb.getCommandList()) { - cl.execute(player); - } - } - if (lb.getMessageList().isEmpty() == false) { - phatLootMessages.addAll(lb.getMessageList()); - } - } - if (rews.getExp() > 0) { - player.giveExp(rews.getExp()); - none = null; - } - String complete = Lang.get(player, "questCompleteTitle"); - complete = complete.replace("", ChatColor.YELLOW + name + ChatColor.GOLD); - player.sendMessage(ChatColor.GOLD + complete); - player.sendMessage(ChatColor.GREEN + Lang.get(player, "questRewardsTitle")); - if (plugin.getSettings().canShowQuestTitles()) { - Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "title " + player.getName() - + " title " + "{\"text\":\"" + Lang.get(player, "quest") + " " + Lang.get(player, "complete") + "\",\"color\":\"gold\"}"); - Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "title " + player.getName() - + " subtitle " + "{\"text\":\"" + name + "\",\"color\":\"yellow\"}"); - } - if (rews.getQuestPoints() > 0) { - player.sendMessage("- " + ChatColor.DARK_GREEN + rews.getQuestPoints() + " " + Lang.get(player, "questPoints")); - q.questPoints += rews.getQuestPoints(); - none = null; - } - for (ItemStack i : rews.getItems()) { - String text = "error"; - if (i.hasItemMeta() && i.getItemMeta().hasDisplayName()) { - if (i.getEnchantments().isEmpty()) { - text = "- " + ChatColor.DARK_AQUA + ChatColor.ITALIC + i.getItemMeta().getDisplayName() + ChatColor.RESET + ChatColor.GRAY + " x " + i.getAmount(); - } else { - text = "- " + ChatColor.DARK_AQUA + ChatColor.ITALIC + i.getItemMeta().getDisplayName() + ChatColor.RESET; - try { - if (!i.getItemMeta().hasItemFlag(ItemFlag.HIDE_ENCHANTS)) { - text += ChatColor.GRAY + " " + Lang.get(player, "with") + ChatColor.DARK_PURPLE; - for (Entry e : i.getEnchantments().entrySet()) { - text += " " + ItemUtil.getPrettyEnchantmentName(e.getKey()) + ":" + e.getValue(); - } - } - } catch (Throwable tr) { - // Do nothing, hasItemFlag() not introduced until 1.8.6 - } - text += ChatColor.GRAY + " x " + i.getAmount(); - } - } else if (i.getDurability() != 0) { - if (i.getEnchantments().isEmpty()) { - text = "- " + ChatColor.DARK_GREEN + ItemUtil.getName(i) + ":" + i.getDurability() + ChatColor.GRAY + " x " + i.getAmount(); - } else { - text = "- " + ChatColor.DARK_GREEN + ItemUtil.getName(i) + ":" + i.getDurability() + ChatColor.GRAY + " " + Lang.get(player, "with"); - for (Entry e : i.getEnchantments().entrySet()) { - text += " " + ItemUtil.getPrettyEnchantmentName(e.getKey()) + ":" + e.getValue(); - } - text += ChatColor.GRAY + " x " + i.getAmount(); - } - } else { - if (i.getEnchantments().isEmpty()) { - text = "- " + ChatColor.DARK_GREEN + ItemUtil.getName(i) + ChatColor.GRAY + " x " + i.getAmount(); - } else { - text = "- " + ChatColor.DARK_GREEN + ItemUtil.getName(i); - try { - if (!i.getItemMeta().hasItemFlag(ItemFlag.HIDE_ENCHANTS)) { - text += ChatColor.GRAY + " " + Lang.get(player, "with"); - for (Entry e : i.getEnchantments().entrySet()) { - text += " " + ItemUtil.getPrettyEnchantmentName(e.getKey()) + ":" + e.getValue(); - } - } - } catch (Throwable tr) { - // Do nothing, hasItemFlag() not introduced until 1.8.6 - } - text += ChatColor.GRAY + " x " + i.getAmount(); - } - } - player.sendMessage(text); - none = null; - } - for (ItemStack i : phatLootItems) { - if (i.hasItemMeta() && i.getItemMeta().hasDisplayName()) { - if (i.getEnchantments().isEmpty()) { - player.sendMessage("- " + ChatColor.DARK_AQUA + ChatColor.ITALIC + i.getItemMeta().getDisplayName() + ChatColor.RESET + ChatColor.GRAY + " x " + i.getAmount()); - } else { - player.sendMessage("- " + ChatColor.DARK_AQUA + ChatColor.ITALIC + i.getItemMeta().getDisplayName() + ChatColor.RESET + ChatColor.GRAY + " x " + i.getAmount() + ChatColor.DARK_PURPLE + " " + Lang.get(player, "enchantedItem")); - } - } else if (i.getDurability() != 0) { - if (i.getEnchantments().isEmpty()) { - player.sendMessage("- " + ChatColor.DARK_GREEN + ItemUtil.getName(i) + ":" + i.getDurability() + ChatColor.GRAY + " x " + i.getAmount()); - } else { - player.sendMessage("- " + ChatColor.DARK_GREEN + ItemUtil.getName(i) + ":" + i.getDurability() + ChatColor.GRAY + " x " + i.getAmount() + ChatColor.DARK_PURPLE + " " + Lang.get(player, "enchantedItem")); - } - } else { - if (i.getEnchantments().isEmpty()) { - player.sendMessage("- " + ChatColor.DARK_GREEN + ItemUtil.getName(i) + ChatColor.GRAY + " x " + i.getAmount()); - } else { - player.sendMessage("- " + ChatColor.DARK_GREEN + ItemUtil.getName(i) + ChatColor.GRAY + " x " + i.getAmount() + ChatColor.DARK_PURPLE + " " + Lang.get(player, "enchantedItem")); - } - } - none = null; - } - if (rews.getMoney() > 1) { - player.sendMessage("- " + ChatColor.DARK_GREEN + rews.getMoney() + " " + ChatColor.DARK_PURPLE + plugin.getCurrency(true)); - none = null; - } else if (rews.getMoney() == 1) { - player.sendMessage("- " + ChatColor.DARK_GREEN + rews.getMoney() + " " + ChatColor.DARK_PURPLE + plugin.getCurrency(false)); - none = null; - } - if (rews.getExp() > 0 || phatLootExp > 0) { - int tot = rews.getExp() + phatLootExp; - player.sendMessage("- " + ChatColor.DARK_GREEN + tot + ChatColor.DARK_PURPLE + " " + Lang.get(player, "experience")); - none = null; - } - if (rews.getCommands().isEmpty() == false) { - int index = 0; - for (String s : rews.getCommands()) { - if (rews.getCommandsOverrideDisplay().isEmpty() == false && rews.getCommandsOverrideDisplay().size() >= index) { - if (rews.getCommandsOverrideDisplay().size() > index) { - if (!rews.getCommandsOverrideDisplay().get(index).trim().equals("")) { - player.sendMessage("- " + ChatColor.DARK_GREEN + rews.getCommandsOverrideDisplay().get(index)); - } - } - } else { - player.sendMessage("- " + ChatColor.DARK_GREEN + s); - } - index++; - } - none = null; - } - if (rews.getMcmmoSkills().isEmpty() == false) { - for (String s : rews.getMcmmoSkills()) { - player.sendMessage("- " + ChatColor.DARK_GREEN + rews.getMcmmoAmounts().get(rews.getMcmmoSkills().indexOf(s)) + " " + ChatColor.DARK_PURPLE + s + " " + Lang.get(player, "experience")); - } - none = null; - } - if (rews.getHeroesClasses().isEmpty() == false) { - for (String s : rews.getHeroesClasses()) { - player.sendMessage("- " + ChatColor.AQUA + rews.getHeroesAmounts().get(rews.getHeroesClasses().indexOf(s)) + " " + ChatColor.BLUE + s + " " + Lang.get(player, "experience")); - } - none = null; - } - if (phatLootMessages.isEmpty() == false) { - for (String s : phatLootMessages) { - player.sendMessage("- " + s); - } - none = null; - } - for (String s : rews.getCustomRewards().keySet()) { - CustomReward found = null; - for (CustomReward cr : plugin.getCustomRewards()) { - if (cr.getName().equalsIgnoreCase(s)) { - found = cr; - break; - } - } - if (found != null) { - Map datamap = rews.getCustomRewards().get(found.getName()); - String message = found.getRewardName(); - if (message != null) { - for (String key : datamap.keySet()) { - message = message.replace("%" + key + "%", datamap.get(key).toString()); - } - player.sendMessage("- " + ChatColor.GOLD + message); - } else { - plugin.getLogger().warning("Failed to notify player: Custom Reward does not have an assigned name"); - } - found.giveReward(player, rews.getCustomRewards().get(s)); - } else { - plugin.getLogger().warning("Quester \"" + player.getName() + "\" completed the Quest \"" + name + "\", but the Custom Reward \"" + s + "\" could not be found. Does it still exist?"); - } - none = null; - } - if (none != null) { - player.sendMessage(none); - } - q.saveData(); - player.updateInventory(); - q.updateJournal(); - q.findCompassTarget(); - QuesterPostCompleteQuestEvent postEvent = new QuesterPostCompleteQuestEvent(q, this); - plugin.getServer().getPluginManager().callEvent(postEvent); - - // Multiplayer - if (opts.getShareProgressLevel() == 4) { - List mq = q.getMultiplayerQuesters(this); - if (mq != null) { - for (Quester qq : mq) { - if (qq.getCurrentQuests().containsKey(this)) { - completeQuest(qq); - } - } - } - } - } - - /** - * Force player to quit quest and inform them of their failure - * - * @param q The player to ejected - */ - @SuppressWarnings("deprecation") - public void failQuest(Quester q) { - QuesterPreFailQuestEvent preEvent = new QuesterPreFailQuestEvent(q, this); - plugin.getServer().getPluginManager().callEvent(preEvent); - if (preEvent.isCancelled()) { - return; - } - if (plugin.getServer().getPlayer(q.getUUID()) != null) { - Player player = plugin.getServer().getPlayer(q.getUUID()); - player.sendMessage(ChatColor.GOLD + Lang.get(player, "questObjectivesTitle").replace("", name)); - player.sendMessage(ChatColor.RED + Lang.get(player, "questFailed")); - q.hardQuit(this); - q.saveData(); - player.updateInventory(); - } else { - q.hardQuit(this); - q.saveData(); - } - q.updateJournal(); - QuesterPostFailQuestEvent postEvent = new QuesterPostFailQuestEvent(q, this); - plugin.getServer().getPluginManager().callEvent(postEvent); - } - - /** - * Checks if quester is in WorldGuard region - * - * @param quester The quester to check - * @return true if quester is in region - */ - public boolean isInRegion(Quester quester) { - return isInRegion(quester.getPlayer()); - } - - /** - * Checks if player is in WorldGuard region - * - * @param player The player to check - * @return true if player is in region - */ - private boolean isInRegion(Player player) { - if (region == null) { - return false; - } - if (plugin.getDependencies().getWorldGuardApi().getApplicableRegionsIDs(player.getWorld(), player.getLocation()).contains(region)) { - return true; - } - return false; - } +/******************************************************************************************************* + * Continued by PikaMug (formerly HappyPikachu) with permission from _Blackvein_. All rights reserved. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *******************************************************************************************************/ + +package me.blackvein.quests; + +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; + +import com.codisimus.plugins.phatloots.PhatLootsAPI; +import com.codisimus.plugins.phatloots.loot.CommandLoot; +import com.codisimus.plugins.phatloots.loot.LootBundle; +import com.gmail.nossr50.datatypes.skills.SkillType; +import com.gmail.nossr50.util.player.UserManager; +import com.herocraftonline.heroes.characters.Hero; + +import me.blackvein.quests.actions.Action; +import me.blackvein.quests.events.quester.QuesterPostChangeStageEvent; +import me.blackvein.quests.events.quester.QuesterPostCompleteQuestEvent; +import me.blackvein.quests.events.quester.QuesterPostFailQuestEvent; +import me.blackvein.quests.events.quester.QuesterPreChangeStageEvent; +import me.blackvein.quests.events.quester.QuesterPreCompleteQuestEvent; +import me.blackvein.quests.events.quester.QuesterPreFailQuestEvent; +import me.blackvein.quests.exceptions.InvalidStageException; +import me.blackvein.quests.util.ItemUtil; +import me.blackvein.quests.util.Lang; +import me.clip.placeholderapi.PlaceholderAPI; +import net.citizensnpcs.api.npc.NPC; + +public class Quest { + + protected Quests plugin; + protected String id; + private String name; + protected String description; + protected String finished; + protected String region = null; + protected ItemStack guiDisplay = null; + private LinkedList orderedStages = new LinkedList(); + protected NPC npcStart; + protected Location blockStart; + protected Action initialAction; + private Requirements reqs = new Requirements(); + private Planner pln = new Planner(); + private Rewards rews = new Rewards(); + private Options opts = new Options(); + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getFinished() { + return finished; + } + + public void setFinished(String finished) { + this.finished = finished; + } + + public String getRegion() { + return region; + } + + public void setRegion(String region) { + this.region = region; + } + + public ItemStack getGUIDisplay() { + return guiDisplay; + } + + public void setGUIDisplay(ItemStack guiDisplay) { + this.guiDisplay = guiDisplay; + } + + public Stage getStage(int index) { + try { + return orderedStages.get(index); + } catch (Exception e) { + return null; + } + } + + public LinkedList getStages() { + return orderedStages; + } + + public NPC getNpcStart() { + return npcStart; + } + + public void setNpcStart(NPC npcStart) { + this.npcStart = npcStart; + } + + public Location getBlockStart() { + return blockStart; + } + + public void setBlockStart(Location blockStart) { + this.blockStart = blockStart; + } + + public Action getInitialAction() { + return initialAction; + } + + public void setInitialAction(Action initialAction) { + this.initialAction = initialAction; + } + + public Requirements getRequirements() { + return reqs; + } + + public Planner getPlanner() { + return pln; + } + + public Rewards getRewards() { + return rews; + } + + public Options getOptions() { + return opts; + } + + /** + * Force player to proceed to the next ordered stage + * + * @param quester Player to force + * @deprecated Use nextStage(Quester, boolean) + */ + public void nextStage(Quester quester) { + nextStage(quester, false); + } + + /** + * Force player to proceed to the next ordered stage + * + * @param quester Player to force + * @param allowSharedProgress Whether to distribute progress to fellow questers + */ + public void nextStage(Quester quester, boolean allowSharedProgress) { + Stage currentStage = quester.getCurrentStage(this); + if (currentStage == null) { + plugin.getLogger().severe("Current stage was null for quester " + quester.getPlayer().getUniqueId()); + return; + } + String stageCompleteMessage = currentStage.completeMessage; + if (stageCompleteMessage != null) { + quester.getPlayer().sendMessage(plugin.parseStringWithPossibleLineBreaks(stageCompleteMessage, this, quester.getPlayer())); + } + if (plugin.getSettings().canUseCompass()) { + quester.resetCompass(); + quester.findCompassTarget(); + } + if (currentStage.delay < 0) { + if (currentStage.finishEvent != null) { + currentStage.finishEvent.fire(quester, this); + } + if (quester.currentQuests.get(this) == (orderedStages.size() - 1)) { + if (currentStage.script != null) { + plugin.getDenizenTrigger().runDenizenScript(currentStage.script, quester); + } + completeQuest(quester); + } else { + try { + setStage(quester, quester.currentQuests.get(this) + 1); + } catch (InvalidStageException e) { + e.printStackTrace(); + } + } + if (quester.getQuestData(this) != null) { + quester.getQuestData(this).delayStartTime = 0; + quester.getQuestData(this).delayTimeLeft = -1; + } + + // Multiplayer + if (opts.getShareProgressLevel() == 3) { + List mq = quester.getMultiplayerQuesters(this); + for (Quester qq : mq) { + if (currentStage.equals(qq.getCurrentStage(this))) { + nextStage(qq, allowSharedProgress); + } + } + } + } else { + quester.startStageTimer(this); + } + quester.updateJournal(); + } + + /** + * Force player to proceed to the specified stage + * @param quester Player to force + * @param stage Stage number to specify + * @throws InvalidStageException if stage does not exist + */ + public void setStage(Quester quester, int stage) throws InvalidStageException { + if (orderedStages.size() - 1 < stage) { + throw new InvalidStageException(this, stage); + } + Stage currentStage = quester.getCurrentStage(this); + Stage nextStage = getStage(stage); + QuesterPreChangeStageEvent preEvent = new QuesterPreChangeStageEvent(quester, this, currentStage, nextStage); + plugin.getServer().getPluginManager().callEvent(preEvent); + if (preEvent.isCancelled()) { + return; + } + quester.hardQuit(this); + quester.hardStagePut(this, stage); + quester.addEmptiesFor(this, stage); + if (currentStage.script != null) { + plugin.getDenizenTrigger().runDenizenScript(quester.getCurrentStage(this).script, quester); + } + /* + * if (quester.getCurrentStage(this).finishEvent != null) { quester.getCurrentStage(this).finishEvent.fire(quester); } + */ + if (nextStage.startEvent != null) { + nextStage.startEvent.fire(quester, this); + } + updateCompass(quester, nextStage); + String msg = Lang.get(quester.getPlayer(), "questObjectivesTitle"); + msg = msg.replace("", name); + quester.getPlayer().sendMessage(ChatColor.GOLD + msg); + plugin.showObjectives(this, quester, false); + String stageStartMessage = quester.getCurrentStage(this).startMessage; + if (stageStartMessage != null) { + quester.getPlayer().sendMessage(plugin.parseStringWithPossibleLineBreaks(stageStartMessage, this, quester.getPlayer())); + } + quester.updateJournal(); + QuesterPostChangeStageEvent postEvent = new QuesterPostChangeStageEvent(quester, this, currentStage, nextStage); + plugin.getServer().getPluginManager().callEvent(postEvent); + } + + /** + * Set location-objective target for compass.

+ * + * Method may be called as often as needed. + * + * @param quester The quester to have their compass updated + * @param nextStage The stage to process for targets + * @return true if successful + */ + public boolean updateCompass(Quester quester, Stage nextStage) { + if (!plugin.getSettings().canUseCompass()) { + return false; + } + if (quester == null) { + return false; + } + if (nextStage == null) { + return false; + } + Location targetLocation = null; + if (nextStage.citizensToInteract != null && nextStage.citizensToInteract.size() > 0) { + targetLocation = plugin.getNPCLocation(nextStage.citizensToInteract.getFirst()); + } else if (nextStage.citizensToKill != null && nextStage.citizensToKill.size() > 0) { + targetLocation = plugin.getNPCLocation(nextStage.citizensToKill.getFirst()); + } else if (nextStage.locationsToReach != null && nextStage.locationsToReach.size() > 0) { + targetLocation = nextStage.locationsToReach.getFirst(); + } else if (nextStage.itemDeliveryTargets != null && nextStage.itemDeliveryTargets.size() > 0) { + NPC npc = plugin.getDependencies().getCitizens().getNPCRegistry().getById(nextStage.itemDeliveryTargets.getFirst()); + targetLocation = npc.getStoredLocation(); + } + if (targetLocation != null && targetLocation.getWorld() != null) { + if (targetLocation.getWorld().getName().equals(quester.getPlayer().getWorld().getName())) { + quester.getPlayer().setCompassTarget(targetLocation); + } + } + return targetLocation != null; + } + + /** + * Check that a quester has met all Requirements to accept this quest + * + * @param quester The quester to check + * @return true if all Requirements have been met + */ + public boolean testRequirements(Quester quester) { + return testRequirements(quester.getPlayer()); + } + + /** + * Check that a player has met all Requirements to accept this quest + * + * @param player The player to check + * @return true if all Requirements have been met + */ + protected boolean testRequirements(Player player) { + Quester quester = plugin.getQuester(player.getUniqueId()); + if (reqs.getMoney() != 0 && plugin.getDependencies().getVaultEconomy() != null) { + if (plugin.getDependencies().getVaultEconomy().getBalance(Bukkit.getOfflinePlayer(player.getUniqueId())) < reqs.getMoney()) { + return false; + } + } + PlayerInventory inventory = player.getInventory(); + int num = 0; + for (ItemStack is : reqs.getItems()) { + for (ItemStack stack : inventory.getContents()) { + if (stack != null) { + if (ItemUtil.compareItems(is, stack, true) == 0) { + num += stack.getAmount(); + } + } + } + if (num < is.getAmount()) { + return false; + } + num = 0; + } + for (String s : reqs.getPermissions()) { + if (player.hasPermission(s) == false) { + return false; + } + } + for (String s : reqs.getMcmmoSkills()) { + final SkillType st = Quests.getMcMMOSkill(s); + final int lvl = reqs.getMcmmoAmounts().get(reqs.getMcmmoSkills().indexOf(s)); + if (UserManager.getPlayer(player).getProfile().getSkillLevel(st) < lvl) { + return false; + } + } + if (reqs.getHeroesPrimaryClass() != null) { + if (plugin.testPrimaryHeroesClass(reqs.getHeroesPrimaryClass(), player.getUniqueId()) == false) { + return false; + } + } + if (reqs.getHeroesSecondaryClass() != null) { + if (plugin.testSecondaryHeroesClass(reqs.getHeroesSecondaryClass(), player.getUniqueId()) == false) { + return false; + } + } + for (String s : reqs.getCustomRequirements().keySet()) { + CustomRequirement found = null; + for (CustomRequirement cr : plugin.getCustomRequirements()) { + if (cr.getName().equalsIgnoreCase(s)) { + found = cr; + break; + } + } + if (found != null) { + if (found.testRequirement(player, reqs.getCustomRequirements().get(s)) == false) { + return false; + } + } else { + plugin.getLogger().warning("Quester \"" + player.getName() + "\" attempted to take Quest \"" + name + "\", but the Custom Requirement \"" + s + + "\" could not be found. Does it still exist?"); + } + } + if (quester.questPoints < reqs.getQuestPoints()) { + return false; + } + if (quester.completedQuests.containsAll(reqs.getNeededQuests()) == false) { + return false; + } + for (String q : reqs.getBlockQuests()) { + Quest questObject = new Quest(); + questObject.name = q; + if (quester.completedQuests.contains(q) || quester.currentQuests.containsKey(questObject)) { + return false; + } + } + return true; + } + + /** + * Proceed to finish this quest, issuing any rewards + * + * @param q The quester finishing this quest + */ + @SuppressWarnings("deprecation") + public void completeQuest(Quester q) { + QuesterPreCompleteQuestEvent preEvent = new QuesterPreCompleteQuestEvent(q, this); + plugin.getServer().getPluginManager().callEvent(preEvent); + if (preEvent.isCancelled()) { + return; + } + final Player player = plugin.getServer().getPlayer(q.getUUID()); + q.hardQuit(this); + if (!q.completedQuests.contains(name)) { + q.completedQuests.add(name); + } + String none = ChatColor.GRAY + "- (" + Lang.get(player, "none") + ")"; + final String[] ps = plugin.parseStringWithPossibleLineBreaks(ChatColor.AQUA + finished, this, player); + for (Map.Entry entry : q.timers.entrySet()) { + if (entry.getValue().getName().equals(getName())) { + plugin.getServer().getScheduler().cancelTask(entry.getKey()); + q.timers.remove(entry.getKey()); + } + } + Bukkit.getScheduler().runTaskLater(plugin, new Runnable() { + + @Override + public void run() { + player.sendMessage(ps); + } + }, 40); + if (rews.getMoney() > 0 && plugin.getDependencies().getVaultEconomy() != null) { + plugin.getDependencies().getVaultEconomy().depositPlayer(q.getOfflinePlayer(), rews.getMoney()); + none = null; + } + if (pln.getCooldown() > -1) { + q.completedTimes.put(this.name, System.currentTimeMillis()); + if (q.amountsCompleted.containsKey(this.name)) { + q.amountsCompleted.put(this.name, q.amountsCompleted.get(this.name) + 1); + } else { + q.amountsCompleted.put(this.name, 1); + } + } + for (ItemStack i : rews.getItems()) { + try { + Quests.addItem(player, i); + } catch (Exception e) { + plugin.getLogger().severe("Unable to add null reward item to inventory of " + + player.getName() + " upon completion of quest " + name); + player.sendMessage(ChatColor.RED + "Quests encountered a problem with an item. " + + "Please contact an administrator."); + } + none = null; + } + for (String s : rews.getCommands()) { + String temp = s.replace("", player.getName()); + if (plugin.getDependencies().getPlaceholderApi() != null) { + temp = PlaceholderAPI.setPlaceholders(player, temp); + } + final String command = temp; + if (Bukkit.isPrimaryThread()) { + Bukkit.getServer().dispatchCommand(plugin.getServer().getConsoleSender(), command); + } else { + Bukkit.getScheduler().runTask(plugin, new Runnable() { + + @Override + public void run() { + Bukkit.getServer().dispatchCommand(plugin.getServer().getConsoleSender(), command); + } + }); + } + none = null; + } + for (String s : rews.getPermissions()) { + if (plugin.getDependencies().getVaultPermission() != null) { + plugin.getDependencies().getVaultPermission().playerAdd(player, s); + } + none = null; + } + for (String s : rews.getMcmmoSkills()) { + UserManager.getPlayer(player).getProfile().addLevels(Quests.getMcMMOSkill(s), rews.getMcmmoAmounts().get(rews.getMcmmoSkills().indexOf(s))); + none = null; + } + for (String s : rews.getHeroesClasses()) { + Hero hero = plugin.getHero(player.getUniqueId()); + hero.addExp(rews.getHeroesAmounts().get(rews.getHeroesClasses().indexOf(s)), plugin.getDependencies().getHeroes().getClassManager().getClass(s), player.getLocation()); + none = null; + } + LinkedList phatLootItems = new LinkedList(); + int phatLootExp = 0; + LinkedList phatLootMessages = new LinkedList(); + for (String s : rews.getPhatLoots()) { + LootBundle lb = PhatLootsAPI.getPhatLoot(s).rollForLoot(); + if (lb.getExp() > 0) { + phatLootExp += lb.getExp(); + player.giveExp(lb.getExp()); + } + if (lb.getMoney() > 0) { + if (plugin.getDependencies().getVaultEconomy() != null) { + plugin.getDependencies().getVaultEconomy().depositPlayer(Bukkit.getOfflinePlayer(player.getUniqueId()), lb.getMoney()); + } + } + if (lb.getItemList().isEmpty() == false) { + phatLootItems.addAll(lb.getItemList()); + for (ItemStack is : lb.getItemList()) { + try { + Quests.addItem(player, is); + } catch (Exception e) { + plugin.getLogger().severe("Unable to add PhatLoots item to inventory of " + + player.getName() + " upon completion of quest " + name); + player.sendMessage(ChatColor.RED + "Quests encountered a problem with an item. " + + "Please contact an administrator."); + } + } + } + if (lb.getCommandList().isEmpty() == false) { + for (CommandLoot cl : lb.getCommandList()) { + cl.execute(player); + } + } + if (lb.getMessageList().isEmpty() == false) { + phatLootMessages.addAll(lb.getMessageList()); + } + } + if (rews.getExp() > 0) { + player.giveExp(rews.getExp()); + none = null; + } + String complete = Lang.get(player, "questCompleteTitle"); + complete = complete.replace("", ChatColor.YELLOW + name + ChatColor.GOLD); + player.sendMessage(ChatColor.GOLD + complete); + player.sendMessage(ChatColor.GREEN + Lang.get(player, "questRewardsTitle")); + if (plugin.getSettings().canShowQuestTitles()) { + Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "title " + player.getName() + + " title " + "{\"text\":\"" + Lang.get(player, "quest") + " " + Lang.get(player, "complete") + "\",\"color\":\"gold\"}"); + Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "title " + player.getName() + + " subtitle " + "{\"text\":\"" + name + "\",\"color\":\"yellow\"}"); + } + if (rews.getQuestPoints() > 0) { + player.sendMessage("- " + ChatColor.DARK_GREEN + rews.getQuestPoints() + " " + Lang.get(player, "questPoints")); + q.questPoints += rews.getQuestPoints(); + none = null; + } + for (ItemStack i : rews.getItems()) { + String text = "error"; + if (i.hasItemMeta() && i.getItemMeta().hasDisplayName()) { + if (i.getEnchantments().isEmpty()) { + text = "- " + ChatColor.DARK_AQUA + ChatColor.ITALIC + i.getItemMeta().getDisplayName() + ChatColor.RESET + ChatColor.GRAY + " x " + i.getAmount(); + } else { + text = "- " + ChatColor.DARK_AQUA + ChatColor.ITALIC + i.getItemMeta().getDisplayName() + ChatColor.RESET; + try { + if (!i.getItemMeta().hasItemFlag(ItemFlag.HIDE_ENCHANTS)) { + text += ChatColor.GRAY + " " + Lang.get(player, "with") + ChatColor.DARK_PURPLE; + for (Entry e : i.getEnchantments().entrySet()) { + text += " " + ItemUtil.getPrettyEnchantmentName(e.getKey()) + ":" + e.getValue(); + } + } + } catch (Throwable tr) { + // Do nothing, hasItemFlag() not introduced until 1.8.6 + } + text += ChatColor.GRAY + " x " + i.getAmount(); + } + } else if (i.getDurability() != 0) { + if (i.getEnchantments().isEmpty()) { + text = "- " + ChatColor.DARK_GREEN + ItemUtil.getName(i) + ":" + i.getDurability() + ChatColor.GRAY + " x " + i.getAmount(); + } else { + text = "- " + ChatColor.DARK_GREEN + ItemUtil.getName(i) + ":" + i.getDurability() + ChatColor.GRAY + " " + Lang.get(player, "with"); + for (Entry e : i.getEnchantments().entrySet()) { + text += " " + ItemUtil.getPrettyEnchantmentName(e.getKey()) + ":" + e.getValue(); + } + text += ChatColor.GRAY + " x " + i.getAmount(); + } + } else { + if (i.getEnchantments().isEmpty()) { + text = "- " + ChatColor.DARK_GREEN + ItemUtil.getName(i) + ChatColor.GRAY + " x " + i.getAmount(); + } else { + text = "- " + ChatColor.DARK_GREEN + ItemUtil.getName(i); + try { + if (!i.getItemMeta().hasItemFlag(ItemFlag.HIDE_ENCHANTS)) { + text += ChatColor.GRAY + " " + Lang.get(player, "with"); + for (Entry e : i.getEnchantments().entrySet()) { + text += " " + ItemUtil.getPrettyEnchantmentName(e.getKey()) + ":" + e.getValue(); + } + } + } catch (Throwable tr) { + // Do nothing, hasItemFlag() not introduced until 1.8.6 + } + text += ChatColor.GRAY + " x " + i.getAmount(); + } + } + player.sendMessage(text); + none = null; + } + for (ItemStack i : phatLootItems) { + if (i.hasItemMeta() && i.getItemMeta().hasDisplayName()) { + if (i.getEnchantments().isEmpty()) { + player.sendMessage("- " + ChatColor.DARK_AQUA + ChatColor.ITALIC + i.getItemMeta().getDisplayName() + ChatColor.RESET + ChatColor.GRAY + " x " + i.getAmount()); + } else { + player.sendMessage("- " + ChatColor.DARK_AQUA + ChatColor.ITALIC + i.getItemMeta().getDisplayName() + ChatColor.RESET + ChatColor.GRAY + " x " + i.getAmount() + ChatColor.DARK_PURPLE + " " + Lang.get(player, "enchantedItem")); + } + } else if (i.getDurability() != 0) { + if (i.getEnchantments().isEmpty()) { + player.sendMessage("- " + ChatColor.DARK_GREEN + ItemUtil.getName(i) + ":" + i.getDurability() + ChatColor.GRAY + " x " + i.getAmount()); + } else { + player.sendMessage("- " + ChatColor.DARK_GREEN + ItemUtil.getName(i) + ":" + i.getDurability() + ChatColor.GRAY + " x " + i.getAmount() + ChatColor.DARK_PURPLE + " " + Lang.get(player, "enchantedItem")); + } + } else { + if (i.getEnchantments().isEmpty()) { + player.sendMessage("- " + ChatColor.DARK_GREEN + ItemUtil.getName(i) + ChatColor.GRAY + " x " + i.getAmount()); + } else { + player.sendMessage("- " + ChatColor.DARK_GREEN + ItemUtil.getName(i) + ChatColor.GRAY + " x " + i.getAmount() + ChatColor.DARK_PURPLE + " " + Lang.get(player, "enchantedItem")); + } + } + none = null; + } + if (rews.getMoney() > 1) { + player.sendMessage("- " + ChatColor.DARK_GREEN + rews.getMoney() + " " + ChatColor.DARK_PURPLE + plugin.getCurrency(true)); + none = null; + } else if (rews.getMoney() == 1) { + player.sendMessage("- " + ChatColor.DARK_GREEN + rews.getMoney() + " " + ChatColor.DARK_PURPLE + plugin.getCurrency(false)); + none = null; + } + if (rews.getExp() > 0 || phatLootExp > 0) { + int tot = rews.getExp() + phatLootExp; + player.sendMessage("- " + ChatColor.DARK_GREEN + tot + ChatColor.DARK_PURPLE + " " + Lang.get(player, "experience")); + none = null; + } + if (rews.getCommands().isEmpty() == false) { + int index = 0; + for (String s : rews.getCommands()) { + if (rews.getCommandsOverrideDisplay().isEmpty() == false && rews.getCommandsOverrideDisplay().size() >= index) { + if (rews.getCommandsOverrideDisplay().size() > index) { + if (!rews.getCommandsOverrideDisplay().get(index).trim().equals("")) { + player.sendMessage("- " + ChatColor.DARK_GREEN + rews.getCommandsOverrideDisplay().get(index)); + } + } + } else { + player.sendMessage("- " + ChatColor.DARK_GREEN + s); + } + index++; + } + none = null; + } + if (rews.getMcmmoSkills().isEmpty() == false) { + for (String s : rews.getMcmmoSkills()) { + player.sendMessage("- " + ChatColor.DARK_GREEN + rews.getMcmmoAmounts().get(rews.getMcmmoSkills().indexOf(s)) + " " + ChatColor.DARK_PURPLE + s + " " + Lang.get(player, "experience")); + } + none = null; + } + if (rews.getHeroesClasses().isEmpty() == false) { + for (String s : rews.getHeroesClasses()) { + player.sendMessage("- " + ChatColor.AQUA + rews.getHeroesAmounts().get(rews.getHeroesClasses().indexOf(s)) + " " + ChatColor.BLUE + s + " " + Lang.get(player, "experience")); + } + none = null; + } + if (phatLootMessages.isEmpty() == false) { + for (String s : phatLootMessages) { + player.sendMessage("- " + s); + } + none = null; + } + for (String s : rews.getCustomRewards().keySet()) { + CustomReward found = null; + for (CustomReward cr : plugin.getCustomRewards()) { + if (cr.getName().equalsIgnoreCase(s)) { + found = cr; + break; + } + } + if (found != null) { + Map datamap = rews.getCustomRewards().get(found.getName()); + String message = found.getRewardName(); + if (message != null) { + for (String key : datamap.keySet()) { + message = message.replace("%" + key + "%", datamap.get(key).toString()); + } + player.sendMessage("- " + ChatColor.GOLD + message); + } else { + plugin.getLogger().warning("Failed to notify player: Custom Reward does not have an assigned name"); + } + found.giveReward(player, rews.getCustomRewards().get(s)); + } else { + plugin.getLogger().warning("Quester \"" + player.getName() + "\" completed the Quest \"" + name + "\", but the Custom Reward \"" + s + "\" could not be found. Does it still exist?"); + } + none = null; + } + if (none != null) { + player.sendMessage(none); + } + q.saveData(); + player.updateInventory(); + q.updateJournal(); + q.findCompassTarget(); + QuesterPostCompleteQuestEvent postEvent = new QuesterPostCompleteQuestEvent(q, this); + plugin.getServer().getPluginManager().callEvent(postEvent); + + // Multiplayer + if (opts.getShareProgressLevel() == 4) { + List mq = q.getMultiplayerQuesters(this); + for (Quester qq : mq) { + completeQuest(qq); + } + } + } + + /** + * Force player to quit quest and inform them of their failure + * + * @param q The player to ejected + */ + @SuppressWarnings("deprecation") + public void failQuest(Quester q) { + QuesterPreFailQuestEvent preEvent = new QuesterPreFailQuestEvent(q, this); + plugin.getServer().getPluginManager().callEvent(preEvent); + if (preEvent.isCancelled()) { + return; + } + if (plugin.getServer().getPlayer(q.getUUID()) != null) { + Player player = plugin.getServer().getPlayer(q.getUUID()); + player.sendMessage(ChatColor.GOLD + Lang.get(player, "questObjectivesTitle").replace("", name)); + player.sendMessage(ChatColor.RED + Lang.get(player, "questFailed")); + q.hardQuit(this); + q.saveData(); + player.updateInventory(); + } else { + q.hardQuit(this); + q.saveData(); + } + q.updateJournal(); + QuesterPostFailQuestEvent postEvent = new QuesterPostFailQuestEvent(q, this); + plugin.getServer().getPluginManager().callEvent(postEvent); + } + + /** + * Checks if quester is in WorldGuard region + * + * @param quester The quester to check + * @return true if quester is in region + */ + public boolean isInRegion(Quester quester) { + return isInRegion(quester.getPlayer()); + } + + /** + * Checks if player is in WorldGuard region + * + * @param player The player to check + * @return true if player is in region + */ + private boolean isInRegion(Player player) { + if (region == null) { + return false; + } + if (plugin.getDependencies().getWorldGuardApi().getApplicableRegionsIDs(player.getWorld(), player.getLocation()).contains(region)) { + return true; + } + return false; + } } \ No newline at end of file diff --git a/main/src/main/java/me/blackvein/quests/QuestFactory.java b/main/src/main/java/me/blackvein/quests/QuestFactory.java index 685773d13..4f2f31e26 100644 --- a/main/src/main/java/me/blackvein/quests/QuestFactory.java +++ b/main/src/main/java/me/blackvein/quests/QuestFactory.java @@ -999,6 +999,7 @@ public class QuestFactory implements ConversationAbandonedListener { boolean useDungeonsXLPluginOpt = false; boolean usePartiesPluginOpt = true; Integer shareProgressLevelOpt = 1; + boolean requireSameQuestOpt = true; if (cc.getSessionData(CK.Q_START_NPC) != null) { npcStart = (Integer) cc.getSessionData(CK.Q_START_NPC); } @@ -1129,6 +1130,9 @@ public class QuestFactory implements ConversationAbandonedListener { if (cc.getSessionData(CK.OPT_SHARE_PROGRESS_LEVEL) != null) { shareProgressLevelOpt = (Integer) cc.getSessionData(CK.OPT_SHARE_PROGRESS_LEVEL); } + if (cc.getSessionData(CK.OPT_USE_PARTIES_PLUGIN) != null) { + requireSameQuestOpt = (Boolean) cc.getSessionData(CK.OPT_REQUIRE_SAME_QUEST); + } cs.set("name", name); cs.set("npc-giver-id", npcStart); cs.set("block-start", blockStart); @@ -1593,6 +1597,7 @@ public class QuestFactory implements ConversationAbandonedListener { sch.set("use-dungeonsxl-plugin", useDungeonsXLPluginOpt); sch.set("use-parties-plugin", usePartiesPluginOpt); sch.set("share-progress-level", shareProgressLevelOpt); + sch.set("require-same-quest", requireSameQuestOpt); } @SuppressWarnings("deprecation") @@ -1713,6 +1718,7 @@ public class QuestFactory implements ConversationAbandonedListener { cc.setSessionData(CK.OPT_USE_DUNGEONSXL_PLUGIN, opt.getUseDungeonsXLPlugin()); cc.setSessionData(CK.OPT_USE_PARTIES_PLUGIN, opt.getUsePartiesPlugin()); cc.setSessionData(CK.OPT_SHARE_PROGRESS_LEVEL, opt.getShareProgressLevel()); + cc.setSessionData(CK.OPT_REQUIRE_SAME_QUEST, opt.getRequireSameQuest()); // Stages (Objectives) int index = 1; for (Stage stage : q.getStages()) { diff --git a/main/src/main/java/me/blackvein/quests/Quester.java b/main/src/main/java/me/blackvein/quests/Quester.java index 64c28dcab..4a7c1a143 100644 --- a/main/src/main/java/me/blackvein/quests/Quester.java +++ b/main/src/main/java/me/blackvein/quests/Quester.java @@ -26,6 +26,7 @@ import java.util.Random; import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -932,8 +933,9 @@ public class Quester { * Check if player's current stage has the specified objective

* * Accepted strings are: breakBlock, damageBlock, placeBlock, useBlock, - * cutBlock, catchFish, enchantItem, killMob, deliverItem, killPlayer, - * talkToNPC, killNPC, tameMob, shearSheep, password, reachLocation + * cutBlock, craftItem, smeltItem, enchantItem, brewItem, catchFish, + * killMob, deliverItem, killPlayer, talkToNPC, killNPC, tameMob, + * shearSheep, password, reachLocation * * @deprecated Use containsObjective() instead * @param quest The quest to check objectives of @@ -948,8 +950,9 @@ public class Quester { * Check if player's current stage has the specified objective

* * Accepted strings are: breakBlock, damageBlock, placeBlock, useBlock, - * cutBlock, catchFish, enchantItem, killMob, deliverItem, killPlayer, - * talkToNPC, killNPC, tameMob, shearSheep, password, reachLocation + * cutBlock, craftItem, smeltItem, enchantItem, brewItem, catchFish, + * killMob, deliverItem, killPlayer, talkToNPC, killNPC, tameMob, + * shearSheep, password, reachLocation * * @param quest The quest to check objectives of * @param s The type of objective to check for @@ -1068,24 +1071,21 @@ public class Quester { } } if (broken.getAmount() < toBreak.getAmount()) { - ItemStack newBroken = broken; + final ItemStack newBroken = broken; newBroken.setAmount(broken.getAmount() + 1); if (getQuestData(quest).blocksBroken.contains(broken)) { getQuestData(quest).blocksBroken.set(getQuestData(quest).blocksBroken.indexOf(broken), newBroken); if (broken.getAmount() == toBreak.getAmount()) { finishObjective(quest, "breakBlock", m, toBreak, null, null, null, null, null, null, null, null); - } - } - } - - // Multiplayer - if (quest.getOptions().getShareProgressLevel() == 1) { - List mq = getMultiplayerQuesters(quest); - if (mq != null) { - for (Quester q : mq) { - if (q.getCurrentQuests().containsKey(quest)) { - q.breakBlock(quest, m); - } + + // Multiplayer + final ItemStack finalBroken = broken; + final ItemStack finalToBreak = toBreak; + dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (Quester q) -> { + q.getQuestData(quest).blocksBroken.set(getQuestData(quest).blocksBroken.indexOf(finalBroken), newBroken); + q.finishObjective(quest, "breakBlock", m, finalToBreak, null, null, null, null, null, null, null, null); + return null; + }); } } } @@ -1136,12 +1136,21 @@ public class Quester { } } if (damaged.getAmount() < toDamage.getAmount()) { - ItemStack newDamaged = damaged; + final ItemStack newDamaged = damaged; newDamaged.setAmount(damaged.getAmount() + 1); if (getQuestData(quest).blocksDamaged.contains(damaged)) { getQuestData(quest).blocksDamaged.set(getQuestData(quest).blocksDamaged.indexOf(damaged), newDamaged); if (damaged.getAmount() == toDamage.getAmount()) { finishObjective(quest, "damageBlock", m, toDamage, null, null, null, null, null, null, null, null); + + // Multiplayer + final ItemStack finalDamaged = damaged; + final ItemStack finalToDamage = toDamage; + dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (Quester q) -> { + q.getQuestData(quest).blocksDamaged.set(getQuestData(quest).blocksDamaged.indexOf(finalDamaged), newDamaged); + q.finishObjective(quest, "damageBlock", m, finalToDamage, null, null, null, null, null, null, null, null); + return null; + }); } } } @@ -1192,12 +1201,21 @@ public class Quester { } } if (placed.getAmount() < toPlace.getAmount()) { - ItemStack newplaced = placed; + final ItemStack newplaced = placed; newplaced.setAmount(placed.getAmount() + 1); if (getQuestData(quest).blocksPlaced.contains(placed)) { getQuestData(quest).blocksPlaced.set(getQuestData(quest).blocksPlaced.indexOf(placed), newplaced); if (placed.getAmount() == toPlace.getAmount()) { finishObjective(quest, "placeBlock", m, toPlace, null, null, null, null, null, null, null, null); + + // Multiplayer + final ItemStack finalPlaced = placed; + final ItemStack finalToPlace = toPlace; + dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (Quester q) -> { + q.getQuestData(quest).blocksPlaced.set(getQuestData(quest).blocksPlaced.indexOf(finalPlaced), newplaced); + q.finishObjective(quest, "damageBlock", m, finalToPlace, null, null, null, null, null, null, null, null); + return null; + }); } } } @@ -1248,12 +1266,21 @@ public class Quester { } } if (used.getAmount() < toUse.getAmount()) { - ItemStack newUsed = used; + final ItemStack newUsed = used; newUsed.setAmount(used.getAmount() + 1); if (getQuestData(quest).blocksUsed.contains(used)) { getQuestData(quest).blocksUsed.set(getQuestData(quest).blocksUsed.indexOf(used), newUsed); if (used.getAmount() == toUse.getAmount()) { finishObjective(quest, "useBlock", m, toUse, null, null, null, null, null, null, null, null); + + // Multiplayer + final ItemStack finalUsed = used; + final ItemStack finalToUse = toUse; + dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (Quester q) -> { + q.getQuestData(quest).blocksUsed.set(getQuestData(quest).blocksUsed.indexOf(finalUsed), newUsed); + q.finishObjective(quest, "useBlock", m, finalToUse, null, null, null, null, null, null, null, null); + return null; + }); } } } @@ -1304,12 +1331,21 @@ public class Quester { } } if (cut.getAmount() < toCut.getAmount()) { - ItemStack newCut = cut; + final ItemStack newCut = cut; newCut.setAmount(cut.getAmount() + 1); if (getQuestData(quest).blocksCut.contains(cut)) { getQuestData(quest).blocksCut.set(getQuestData(quest).blocksCut.indexOf(cut), newCut); if (cut.getAmount() == toCut.getAmount()) { finishObjective(quest, "cutBlock", m, toCut, null, null, null, null, null, null, null, null); + + // Multiplayer + final ItemStack finalCut = cut; + final ItemStack finalToCut = toCut; + dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (Quester q) -> { + q.getQuestData(quest).blocksCut.set(getQuestData(quest).blocksCut.indexOf(finalCut), newCut); + q.finishObjective(quest, "cutBlock", m, finalToCut, null, null, null, null, null, null, null, null); + return null; + }); } } } @@ -1345,6 +1381,14 @@ public class Quester { if ((i.getAmount() + amount) >= req) { getQuestData(quest).itemsCrafted.put(found, req); finishObjective(quest, "craftItem", new ItemStack(m, 1), found, null, null, null, null, null, null, null, null); + + // Multiplayer + final ItemStack finalFound = found; + dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (Quester q) -> { + q.getQuestData(quest).itemsCrafted.put(finalFound, req); + q.finishObjective(quest, "craftItem", new ItemStack(m, 1), finalFound, null, null, null, null, null, null, null, null); + return null; + }); } else { getQuestData(quest).itemsCrafted.put(found, (amount + i.getAmount())); } @@ -1382,6 +1426,14 @@ public class Quester { if ((i.getAmount() + amount) >= req) { getQuestData(quest).itemsSmelted.put(found, req); finishObjective(quest, "smeltItem", new ItemStack(m, 1), found, null, null, null, null, null, null, null, null); + + // Multiplayer + final ItemStack finalFound = found; + dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (Quester q) -> { + q.getQuestData(quest).itemsSmelted.put(finalFound, req); + q.finishObjective(quest, "smeltItem", new ItemStack(m, 1), finalFound, null, null, null, null, null, null, null, null); + return null; + }); } else { getQuestData(quest).itemsSmelted.put(found, (amount + i.getAmount())); } @@ -1405,7 +1457,16 @@ public class Quester { Integer num = entry.getValue() + 1; getQuestData(quest).itemsEnchanted.put(entry.getKey(), num); if (num.equals(entry2.getValue())) { - finishObjective(quest, "enchantItem", new ItemStack(m, 1), null, e, null, null, null, null, null, null, null); + final ItemStack finalToEnchant = new ItemStack(m, entry.getValue()); + + finishObjective(quest, "enchantItem", new ItemStack(m, 1), finalToEnchant, e, null, null, null, null, null, null, null); + + // Multiplayer + dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (Quester q) -> { + q.getQuestData(quest).itemsEnchanted.put(entry.getKey(), num); + q.finishObjective(quest, "enchantItem", new ItemStack(m, 1), finalToEnchant, null, null, null, null, null, null, null, null); + return null; + }); } } break; @@ -1446,6 +1507,14 @@ public class Quester { if ((i.getAmount() + amount) >= req) { getQuestData(quest).itemsBrewed.put(found, req); finishObjective(quest, "brewItem", new ItemStack(m, 1), found, null, null, null, null, null, null, null, null); + + // Multiplayer + final ItemStack finalFound = found; + dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (Quester q) -> { + q.getQuestData(quest).itemsBrewed.put(finalFound, req); + q.finishObjective(quest, "brewItem", new ItemStack(m, 1), finalFound, null, null, null, null, null, null, null, null); + return null; + }); } else { getQuestData(quest).itemsBrewed.put(found, (amount + i.getAmount())); } @@ -1459,10 +1528,19 @@ public class Quester { * @param quest The quest for which the fish is being caught */ public void catchFish(Quest quest) { - if (getQuestData(quest).getFishCaught() < getCurrentStage(quest).fishToCatch) { + final int fishToCatch = getCurrentStage(quest).fishToCatch; + if (getQuestData(quest).getFishCaught() < fishToCatch) { getQuestData(quest).setFishCaught(getQuestData(quest).getFishCaught() + 1); - if (((Integer) getQuestData(quest).getFishCaught()).equals(getCurrentStage(quest).fishToCatch)) { - finishObjective(quest, "catchFish", null, null, null, null, null, null, null, null, null, null); + + if (getQuestData(quest).getFishCaught() == fishToCatch) { + finishObjective(quest, "catchFish", new ItemStack(Material.AIR, 1), new ItemStack(Material.AIR, fishToCatch), null, null, null, null, null, null, null, null); + + // Multiplayer + dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (Quester q) -> { + q.getQuestData(quest).setFishCaught(fishToCatch); + q.finishObjective(quest, "catchFish", new ItemStack(Material.AIR, 1), new ItemStack(Material.AIR, fishToCatch), null, null, null, null, null, null, null, null); + return null; + }); } } } @@ -1479,10 +1557,10 @@ public class Quester { if (e == null) { return; } - if (questData.mobsKilled.contains(e) == false) { + Stage currentStage = getCurrentStage(quest); + if (currentStage.mobsToKill.contains(e) == false) { return; } - Stage currentStage = getCurrentStage(quest); int indexOfMobKilled = questData.mobsKilled.indexOf(e); int numberOfSpecificMobKilled = questData.mobNumKilled.get(indexOfMobKilled); int numberOfSpecificMobNeedsToBeKilledInCurrentStage = currentStage.mobNumToKill.get(indexOfMobKilled); @@ -1505,10 +1583,19 @@ public class Quester { } } if (numberOfSpecificMobKilled < numberOfSpecificMobNeedsToBeKilledInCurrentStage) { - Integer newNumberOfSpecificMobKilled = numberOfSpecificMobKilled + 1; + int newNumberOfSpecificMobKilled = numberOfSpecificMobKilled + 1; questData.mobNumKilled.set(indexOfMobKilled, newNumberOfSpecificMobKilled); - if ((newNumberOfSpecificMobKilled).equals(numberOfSpecificMobNeedsToBeKilledInCurrentStage)) { - finishObjective(quest, "killMob", null, null, null, e, null, null, null, null, null, null); + if (newNumberOfSpecificMobKilled == numberOfSpecificMobNeedsToBeKilledInCurrentStage) { + finishObjective(quest, "killMob", new ItemStack(Material.AIR, 1), + new ItemStack(Material.AIR, numberOfSpecificMobNeedsToBeKilledInCurrentStage), null, e, null, null, null, null, null, null); + + // Multiplayer + dispatchMultiplayerObjectives(quest, currentStage, (Quester q) -> { + q.getQuestData(quest).mobNumKilled.set(indexOfMobKilled, newNumberOfSpecificMobKilled); + q.finishObjective(quest, "killMob", new ItemStack(Material.AIR, 1), + new ItemStack(Material.AIR, numberOfSpecificMobNeedsToBeKilledInCurrentStage), null, e, null, null, null, null, null, null); + return null; + }); } } } @@ -1520,10 +1607,18 @@ public class Quester { * @param player The player to be killed */ public void killPlayer(Quest quest, Player player) { - if (getQuestData(quest).getPlayersKilled() < getCurrentStage(quest).playersToKill) { + final int playersToKill = getCurrentStage(quest).playersToKill; + if (getQuestData(quest).getPlayersKilled() < playersToKill) { getQuestData(quest).setPlayersKilled(getQuestData(quest).getPlayersKilled() + 1); - if (((Integer) getQuestData(quest).getPlayersKilled()).equals(getCurrentStage(quest).playersToKill)) { - finishObjective(quest, "killPlayer", null, null, null, null, null, null, null, null, null, null); + if (getQuestData(quest).getPlayersKilled() == playersToKill) { + finishObjective(quest, "killPlayer", new ItemStack(Material.AIR, 1), new ItemStack(Material.AIR, playersToKill), null, null, null, null, null, null, null, null); + + // Multiplayer + dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (Quester q) -> { + q.getQuestData(quest).setPlayersKilled(getQuestData(quest).getPlayersKilled()); + q.finishObjective(quest, "killPlayer", new ItemStack(Material.AIR, 1), new ItemStack(Material.AIR, playersToKill), null, null, null, null, null, null, null, null); + return null; + }); } } } @@ -1565,17 +1660,23 @@ public class Quester { + " when delivering for quest " + quest.getName()); return; } - if ((i.getAmount() + amount) > req) { + if ((i.getAmount() + amount) >= req) { getQuestData(quest).itemsDelivered.put(found, req); - i.setAmount(i.getAmount() - (req - amount)); // Take away the remaining amount needed to be delivered - player.getInventory().setItem(index, i); - player.updateInventory(); - finishObjective(quest, "deliverItem", new ItemStack(m, 1), found, null, null, null, null, null, null, null, null); - } else if ((i.getAmount() + amount) == req) { - getQuestData(quest).itemsDelivered.put(found, req); - player.getInventory().setItem(index, null); + if ((i.getAmount() + amount) >= req) { + i.setAmount(i.getAmount() - (req - amount)); // Take away the remaining amount needed to be delivered + player.getInventory().setItem(index, i); + } else { + player.getInventory().setItem(index, null); + } player.updateInventory(); finishObjective(quest, "deliverItem", new ItemStack(m, 1), found, null, null, null, null, null, null, null, null); + + // Multiplayer + dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (Quester q) -> { + q.getQuestData(quest).itemsDelivered.put(found, req); + q.finishObjective(quest, "deliverItem", new ItemStack(m, 1), found, null, null, null, null, null, null, null, null); + return null; + }); } else { getQuestData(quest).itemsDelivered.put(found, (amount + i.getAmount())); player.getInventory().setItem(index, null); @@ -1620,16 +1721,23 @@ public class Quester { if (amount < req) { if ((i.getAmount() + amount) > req) { getQuestData(quest).itemsDelivered.put(found, req); - int index = player.getInventory().first(i); - i.setAmount(i.getAmount() - (req - amount)); // Take away the remaining amount needed to be delivered - player.getInventory().setItem(index, i); - player.updateInventory(); - finishObjective(quest, "deliverItem", new ItemStack(m, 1), found, null, null, null, null, null, null, null, null); - } else if ((i.getAmount() + amount) == req) { - getQuestData(quest).itemsDelivered.put(found, req); - player.getInventory().setItem(player.getInventory().first(i), null); + if ((i.getAmount() + amount) > req) { + int index = player.getInventory().first(i); + i.setAmount(i.getAmount() - (req - amount)); // Take away the remaining amount needed to be delivered + player.getInventory().setItem(index, i); + } else { + player.getInventory().setItem(player.getInventory().first(i), null); + } player.updateInventory(); finishObjective(quest, "deliverItem", new ItemStack(m, 1), found, null, null, null, null, null, null, null, null); + + // Multiplayer + final ItemStack finalFound = found; + dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (Quester q) -> { + q.getQuestData(quest).itemsDelivered.put(finalFound, req); + q.finishObjective(quest, "deliverItem", new ItemStack(m, 1), finalFound, null, null, null, null, null, null, null, null); + return null; + }); } else { getQuestData(quest).itemsDelivered.put(found, (amount + i.getAmount())); player.getInventory().setItem(player.getInventory().first(i), null); @@ -1654,7 +1762,14 @@ public class Quester { Boolean b = getQuestData(quest).citizensInteracted.get(n.getId()); if (b != null && !b) { getQuestData(quest).citizensInteracted.put(n.getId(), true); - finishObjective(quest, "talkToNPC", null, null, null, null, null, n, null, null, null, null); + finishObjective(quest, "talkToNPC", new ItemStack(Material.AIR, 1), new ItemStack(Material.AIR, 1), null, null, null, n, null, null, null, null); + + // Multiplayer + dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (Quester q) -> { + q.getQuestData(quest).citizensInteracted.put(n.getId(), true); + q.finishObjective(quest, "talkToNPC", new ItemStack(Material.AIR, 1), new ItemStack(Material.AIR, 1), null, null, null, n, null, null, null, null); + return null; + }); } } } @@ -1668,10 +1783,18 @@ public class Quester { public void killNPC(Quest quest, NPC n) { if (getQuestData(quest).citizensKilled.contains(n.getId())) { int index = getQuestData(quest).citizensKilled.indexOf(n.getId()); - if (getQuestData(quest).citizenNumKilled.get(index) < getCurrentStage(quest).citizenNumToKill.get(index)) { + final int npcsToKill = getCurrentStage(quest).citizenNumToKill.get(index); + if (getQuestData(quest).citizenNumKilled.get(index) < npcsToKill) { getQuestData(quest).citizenNumKilled.set(index, getQuestData(quest).citizenNumKilled.get(index) + 1); - if (getQuestData(quest).citizenNumKilled.get(index) == getCurrentStage(quest).citizenNumToKill.get(index)) { - finishObjective(quest, "killNPC", null, null, null, null, null, n, null, null, null, null); + if (getQuestData(quest).citizenNumKilled.get(index).equals(npcsToKill)) { + finishObjective(quest, "killNPC", new ItemStack(Material.AIR, 1), new ItemStack(Material.AIR, npcsToKill), null, null, null, n, null, null, null, null); + + // Multiplayer + dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (Quester q) -> { + q.getQuestData(quest).citizenNumKilled.set(index, getQuestData(quest).citizenNumKilled.get(index)); + q.finishObjective(quest, "killNPC", new ItemStack(Material.AIR, 1), new ItemStack(Material.AIR, npcsToKill), null, null, null, n, null, null, null, null); + return null; + }); } } } @@ -1681,7 +1804,7 @@ public class Quester { * Mark location as reached if the Quester has such an objective * * @param quest The quest for which the location is being reached - * @param n The location being reached + * @param l The location being reached */ public void reachLocation(Quest quest, Location l) { if (getQuestData(quest).locationsReached == null) { @@ -1708,7 +1831,19 @@ public class Quester { } else { getQuestData(quest).hasReached.set(index, true); } - finishObjective(quest, "reachLocation", null, null, null, null, null, null, location, null, null, null); + finishObjective(quest, "reachLocation", new ItemStack(Material.AIR, 1), new ItemStack(Material.AIR, 1), null, null, null, null, location, null, null, null); + + // Multiplayer + final int finalIndex = index; + dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (Quester q) -> { + if (finalIndex >= getQuestData(quest).hasReached.size()) { + q.getQuestData(quest).hasReached.add(true); + } else { + q.getQuestData(quest).hasReached.set(finalIndex, true); + } + q.finishObjective(quest, "reachLocation", new ItemStack(Material.AIR, 1), new ItemStack(Material.AIR, 1), null, null, null, null, location, null, null, null); + return null; + }); } } } @@ -1735,8 +1870,16 @@ public class Quester { public void tameMob(Quest quest, EntityType entity) { if (getQuestData(quest).mobsTamed.containsKey(entity)) { getQuestData(quest).mobsTamed.put(entity, (getQuestData(quest).mobsTamed.get(entity) + 1)); - if (getQuestData(quest).mobsTamed.get(entity).equals(getCurrentStage(quest).mobsToTame.get(entity))) { - finishObjective(quest, "tameMob", null, null, null, entity, null, null, null, null, null, null); + final int mobsToTame = getCurrentStage(quest).mobsToTame.get(entity); + if (getQuestData(quest).mobsTamed.get(entity).equals(mobsToTame)) { + finishObjective(quest, "tameMob", new ItemStack(Material.AIR, 1), new ItemStack(Material.AIR, mobsToTame), null, entity, null, null, null, null, null, null); + + // Multiplayer + dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (Quester q) -> { + q.getQuestData(quest).mobsTamed.put(entity, getQuestData(quest).mobsTamed.get(entity)); + q.finishObjective(quest, "tameMob", new ItemStack(Material.AIR, 1), new ItemStack(Material.AIR, mobsToTame), null, entity, null, null, null, null, null, null); + return null; + }); } } } @@ -1750,8 +1893,16 @@ public class Quester { public void shearSheep(Quest quest, DyeColor color) { if (getQuestData(quest).sheepSheared.containsKey(color)) { getQuestData(quest).sheepSheared.put(color, (getQuestData(quest).sheepSheared.get(color) + 1)); - if (getQuestData(quest).sheepSheared.get(color).equals(getCurrentStage(quest).sheepToShear.get(color))) { - finishObjective(quest, "shearSheep", null, null, null, null, null, null, null, color, null, null); + final int sheepToShear = getCurrentStage(quest).sheepToShear.get(color); + if (getQuestData(quest).sheepSheared.get(color).equals(sheepToShear)) { + finishObjective(quest, "shearSheep", new ItemStack(Material.AIR, 1), new ItemStack(Material.AIR, sheepToShear), null, null, null, null, null, color, null, null); + + // Multiplayer + dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (Quester q) -> { + q.getQuestData(quest).sheepSheared.put(color, getQuestData(quest).sheepSheared.get(color)); + q.finishObjective(quest, "shearSheep", new ItemStack(Material.AIR, 1), new ItemStack(Material.AIR, sheepToShear), null, null, null, null, null, color, null, null); + return null; + }); } } } @@ -1772,12 +1923,15 @@ public class Quester { String display = getCurrentStage(quest).passwordDisplays.get(getCurrentStage(quest).passwordPhrases.indexOf(passes)); getQuestData(quest).passwordsSaid.put(display, true); done = true; - plugin.getServer().getScheduler().runTask(plugin, new Runnable() { - - @Override - public void run() { - finishObjective(quest, "password", null, null, null, null, null, null, null, null, display, null); - } + plugin.getServer().getScheduler().runTask(plugin, () -> { + finishObjective(quest, "password", new ItemStack(Material.AIR, 1), new ItemStack(Material.AIR, 1), null, null, null, null, null, null, display, null); + + // Multiplayer + dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (Quester q) -> { + q.getQuestData(quest).passwordsSaid.put(display, true); + q.finishObjective(quest, "password", new ItemStack(Material.AIR, 1), new ItemStack(Material.AIR, 1), null, null, null, null, null, null, display, null); + return null; + }); }); break; } @@ -1891,7 +2045,7 @@ public class Quester { ench.put(enchantment, enchantment.getStartLevel()); for (Map map : getCurrentStage(quest).itemsToEnchant.keySet()) { if (map.containsKey(enchantment)) { - message = message + " " + getCurrentStage(quest).itemsToEnchant.get(map) + "/" + getCurrentStage(quest).itemsToEnchant.get(map); + message = message + " " + goal.getAmount() + "/" + goal.getAmount(); break; } } @@ -1922,11 +2076,11 @@ public class Quester { } } else if (objective.equalsIgnoreCase("catchFish")) { String message = ChatColor.GREEN + "(" + Lang.get(p, "completed") + ") " + Lang.get(p, "catchFish") + " "; - message = message + " " + getCurrentStage(quest).fishToCatch + "/" + getCurrentStage(quest).fishToCatch; + message = message + " " + goal.getAmount() + "/" + goal.getAmount(); p.sendMessage(message); } else if (objective.equalsIgnoreCase("killMob")) { String message = ChatColor.GREEN + "(" + Lang.get(p, "completed") + ") " + Lang.get(p, "kill") + " "; - message = message + " " + getCurrentStage(quest).mobNumToKill.get(getCurrentStage(quest).mobsToKill.indexOf(mob)) + "/" + getCurrentStage(quest).mobNumToKill.get(getCurrentStage(quest).mobsToKill.indexOf(mob)); + message = message + " " + goal.getAmount() + "/" + goal.getAmount(); if (plugin.getSettings().canTranslateItems()) { plugin.getLocaleQuery().sendMessage(p, message, mob, extra); } else { @@ -1934,7 +2088,7 @@ public class Quester { } } else if (objective.equalsIgnoreCase("killPlayer")) { String message = ChatColor.GREEN + "(" + Lang.get(p, "completed") + ") " + Lang.get(p, "killPlayer"); - message = message + " " + getCurrentStage(quest).playersToKill + "/" + getCurrentStage(quest).playersToKill; + message = message + " " + goal.getAmount() + "/" + goal.getAmount(); p.sendMessage(message); } else if (objective.equalsIgnoreCase("talkToNPC")) { String obj = Lang.get(p, "talkTo"); @@ -1943,11 +2097,11 @@ public class Quester { p.sendMessage(message); } else if (objective.equalsIgnoreCase("killNPC")) { String message = ChatColor.GREEN + "(" + Lang.get(p, "completed") + ") " + Lang.get(p, "kill") + " " + npc.getName(); - message = message + " " + getCurrentStage(quest).citizenNumToKill.get(getCurrentStage(quest).citizensToKill.indexOf(npc.getId())) + "/" + getCurrentStage(quest).citizenNumToKill.get(getCurrentStage(quest).citizensToKill.indexOf(npc.getId())); + message = message + " " + goal.getAmount() + "/" + goal.getAmount(); p.sendMessage(message); } else if (objective.equalsIgnoreCase("tameMob")) { String message = ChatColor.GREEN + "(" + Lang.get(p, "completed") + ") " + Lang.get(p, "tame") + " "; - message = message + " " + getCurrentStage(quest).mobsToTame.get(mob) + "/" + getCurrentStage(quest).mobsToTame.get(mob); + message = message + " " + goal.getAmount() + "/" + goal.getAmount(); if (plugin.getSettings().canTranslateItems()) { plugin.getLocaleQuery().sendMessage(p, message, mob, extra); } else { @@ -1957,7 +2111,7 @@ public class Quester { String obj = Lang.get(p, "shearSheep"); obj = obj.replace("", color.name().toLowerCase()); String message = ChatColor.GREEN + "(" + Lang.get(p, "completed") + ") " + obj; - message = message + " " + getCurrentStage(quest).sheepToShear.get(color) + "/" + getCurrentStage(quest).sheepToShear.get(color); + message = message + " " + goal.getAmount() + "/" + goal.getAmount(); p.sendMessage(message); } else if (objective.equalsIgnoreCase("reachLocation")) { String obj = Lang.get(p, "goTo"); @@ -1982,24 +2136,12 @@ public class Quester { } if (co.canShowCount()) { - message = message.replace("%count%", getCurrentStage(quest).customObjectiveCounts.get(index) + "/" + getCurrentStage(quest).customObjectiveCounts.get(index)); + message = message.replace("%count%", goal.getAmount() + "/" + goal.getAmount()); } p.sendMessage(message); } if (testComplete(quest)) { - quest.nextStage(this); - } - - // Multiplayer - if (quest.getOptions().getShareProgressLevel() == 2) { - List mq = getMultiplayerQuesters(quest); - if (mq != null) { - for (Quester q : mq) { - if (q.getCurrentQuests().containsKey(quest)) { - quest.nextStage(q); - } - } - } + quest.nextStage(this, true); } } @@ -3124,21 +3266,67 @@ public class Quester { return playerAmount >= is.getAmount(); } + /** + * Dispatch player event to fellow questers

+ * + * Accepted strings are: breakBlock, damageBlock, placeBlock, useBlock, + * cutBlock, craftItem, smeltItem, enchantItem, brewItem, catchFish, + * killMob, deliverItem, killPlayer, talkToNPC, killNPC, tameMob, + * shearSheep, password, reachLocation + * + * @param objectiveType The type of objective to progress + * @param fun The function to execute, the event call + */ + public void dispatchMultiplayerEverything(Quest quest, String objectiveType, Function fun) { + if (quest.getOptions().getShareProgressLevel() == 1) { + List mq = getMultiplayerQuesters(quest); + if (mq == null) { + return; + } + for (Quester q : mq) { + if (q.containsObjective(quest, objectiveType)) { + if (!quest.getOptions().getRequireSameQuest() || this.containsObjective(quest, objectiveType)) { + fun.apply(q); + } + } + } + } + } + + /** + * Dispatch finish objective to fellow questers + * + * @param quest The current quest + * @param currentStage The current stage of the quest + * @param fun The function to execute, the event call + */ + public void dispatchMultiplayerObjectives(Quest quest, Stage currentStage, Function fun) { + if (quest.getOptions().getShareProgressLevel() == 2) { + List mq = getMultiplayerQuesters(quest); + for (Quester q : mq) { + if ((q.getCurrentQuests().containsKey(quest) && currentStage.equals(q.getCurrentStage(quest))) + || !quest.getOptions().getRequireSameQuest()) { + fun.apply(q); + } + } + } + } + /** * Get a list of follow Questers in a party or group * * @param quest The quest which uses a linked plugin, i.e. Parties or DungeonsXL - * @return null if quest is null, no linked plugins, or party/group is null + * @return Potentially empty list of Questers or null for invalid quest */ public List getMultiplayerQuesters(Quest quest) { if (quest == null) { return null; } + List mq = new LinkedList(); if (plugin.getDependencies().getPartiesApi() != null) { if (quest.getOptions().getUsePartiesPlugin()) { Party party = plugin.getDependencies().getPartiesApi().getParty(plugin.getDependencies().getPartiesApi().getPartyPlayer(getUUID()).getPartyName()); if (party != null) { - List mq = new LinkedList(); for (UUID id : party.getMembers()) { if (!id.equals(getUUID())) { mq.add(plugin.getQuester(id)); @@ -3152,7 +3340,6 @@ public class Quester { if (quest.getOptions().getUseDungeonsXLPlugin()) { DGroup group = DGroup.getByPlayer(getPlayer()); if (group != null) { - List mq = new LinkedList(); for (UUID id : group.getPlayers()) { if (!id.equals(getUUID())) { mq.add(plugin.getQuester(id)); @@ -3162,7 +3349,7 @@ public class Quester { } } } - return null; + return mq; } /** diff --git a/main/src/main/java/me/blackvein/quests/Quests.java b/main/src/main/java/me/blackvein/quests/Quests.java index d40f069bc..e69378348 100644 --- a/main/src/main/java/me/blackvein/quests/Quests.java +++ b/main/src/main/java/me/blackvein/quests/Quests.java @@ -1339,9 +1339,12 @@ public class Quests extends JavaPlugin implements ConversationAbandonedListener } /** - * Reload quests, player data, actions, config settings, lang and modules, in that order + * Reload quests, actions, config settings, lang and modules, and player data */ public void reloadQuests() { + for (Quester quester : questers) { + quester.saveData(); + } quests.clear(); events.clear(); @@ -1360,6 +1363,7 @@ public class Quests extends JavaPlugin implements ConversationAbandonedListener } loadModules(); for (Quester quester : questers) { + quester.loadData(); for (Quest q : quester.currentQuests.keySet()) { quester.checkQuest(q); } @@ -1465,6 +1469,7 @@ public class Quests extends JavaPlugin implements ConversationAbandonedListener try { // main "skip quest" try/catch block Quest quest = new Quest(); failedToLoad = false; + quest.id = questKey; if (config.contains("quests." + questKey + ".name")) { quest.setName(parseString(config.getString("quests." + questKey + ".name"), quest)); } else { @@ -1946,6 +1951,9 @@ public class Quests extends JavaPlugin implements ConversationAbandonedListener if (config.contains("quests." + questKey + ".options.share-progress-level")) { opts.setShareProgressLevel(config.getInt("quests." + questKey + ".options.share-progress-level")); } + if (config.contains("quests." + questKey + ".options.require-same-quest")) { + opts.setRequireSameQuest(config.getBoolean("quests." + questKey + ".options.require-same-quest")); + } } private void skipQuestProcess(String[] msgs) throws SkipQuest { diff --git a/main/src/main/java/me/blackvein/quests/listeners/CmdExecutor.java b/main/src/main/java/me/blackvein/quests/listeners/CmdExecutor.java index dbe109558..4f5597aa3 100644 --- a/main/src/main/java/me/blackvein/quests/listeners/CmdExecutor.java +++ b/main/src/main/java/me/blackvein/quests/listeners/CmdExecutor.java @@ -1,1382 +1,1388 @@ -/******************************************************************************************************* - * Continued by PikaMug (formerly HappyPikachu) with permission from _Blackvein_. All rights reserved. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - *******************************************************************************************************/ - -package me.blackvein.quests.listeners; - -import java.io.File; -import java.io.IOException; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.Map.Entry; - -import me.blackvein.quests.Quest; -import me.blackvein.quests.Quester; -import me.blackvein.quests.Quests; -import me.blackvein.quests.Requirements; -import me.blackvein.quests.Stage; -import me.blackvein.quests.events.command.QuestsCommandPreQuestsJournalEvent; -import me.blackvein.quests.events.editor.quests.QuestsEditorPreOpenMainPromptEvent; -import me.blackvein.quests.events.quest.QuestQuitEvent; -import me.blackvein.quests.exceptions.InvalidStageException; -import me.blackvein.quests.util.ItemUtil; -import me.blackvein.quests.util.Lang; -import me.blackvein.quests.util.MiscUtil; - -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.configuration.InvalidConfigurationException; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.conversations.Conversable; -import org.bukkit.conversations.Conversation; -import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -public class CmdExecutor implements CommandExecutor { - private final Quests plugin; - public HashMap commands = new HashMap(); - public HashMap adminCommands = new HashMap(); - - public CmdExecutor(Quests plugin) { - this.plugin = plugin; - init(); - } - - @Override - public boolean onCommand(CommandSender cs, Command cmd, String label, String[] args) { - if (cs instanceof Player) { - if (!plugin.canUseQuests(((Player) cs).getUniqueId())) { - cs.sendMessage(ChatColor.RED + Lang.get((Player) cs, "noPermission")); - return true; - } - } - String error = checkCommand(cmd.getName(), args); - if (error != null) { - cs.sendMessage(error); - return true; - } - if (cmd.getName().equalsIgnoreCase("quest")) { - return questCommandHandler(cs, args); - } else if (cmd.getName().equalsIgnoreCase("quests")) { - return questsCommandHandler(cs, args); - } else if (cmd.getName().equalsIgnoreCase("questadmin")) { - return questAdminCommandHandler(cs, args); - } - return false; - } - - private void init() { - // [] - required - // {} - optional - if (plugin.getSettings().canTranslateSubCommands()) { - commands.put(Lang.get("COMMAND_LIST"), 1); // list {page} - commands.put(Lang.get("COMMAND_TAKE"), 2); // take [quest] - commands.put(Lang.get("COMMAND_QUIT"), 2); // quit [quest] - commands.put(Lang.get("COMMAND_EDITOR"), 1); // editor - commands.put(Lang.get("COMMAND_EVENTS_EDITOR"), 1); // events - commands.put(Lang.get("COMMAND_STATS"), 1); // stats - commands.put(Lang.get("COMMAND_TOP"), 2); // top {number} - commands.put(Lang.get("COMMAND_INFO"), 1); // info - commands.put(Lang.get("COMMAND_JOURNAL"), 1); // journal - adminCommands.put(Lang.get("COMMAND_QUESTADMIN_STATS"), 2); // stats [player] - adminCommands.put(Lang.get("COMMAND_QUESTADMIN_GIVE"), 3); // give [player] [quest] - adminCommands.put(Lang.get("COMMAND_QUESTADMIN_QUIT"), 3); // quit [player] [quest] - adminCommands.put(Lang.get("COMMAND_QUESTADMIN_REMOVE"), 3); // remove [player] [quest] - adminCommands.put(Lang.get("COMMAND_QUESTADMIN_POINTS"), 3); // points [player] [amount] - adminCommands.put(Lang.get("COMMAND_QUESTADMIN_TAKEPOINTS"), 3); // takepoints [player] [amount] - adminCommands.put(Lang.get("COMMAND_QUESTADMIN_GIVEPOINTS"), 3); // givepoints [player] [amount] - adminCommands.put(Lang.get("COMMAND_QUESTADMIN_POINTSALL"), 2); // pointsall [amount] - adminCommands.put(Lang.get("COMMAND_QUESTADMIN_FINISH"), 3); // finish [player] [quest] - adminCommands.put(Lang.get("COMMAND_QUESTADMIN_NEXTSTAGE"), 3); // nextstage [player] [quest] - adminCommands.put(Lang.get("COMMAND_QUESTADMIN_SETSTAGE"), 4); // setstage [player] [quest] [stage] - adminCommands.put(Lang.get("COMMAND_QUESTADMIN_RESET"), 2); // reset [player] - adminCommands.put(Lang.get("COMMAND_QUESTADMIN_RELOAD"), 1); // reload - } else { - commands.put("list", 1); // list {page} - commands.put("take", 2); // take [quest] - commands.put("quit", 2); // quit [quest] - commands.put("editor", 1); // editor - commands.put("actions", 1); // actions - commands.put("events", 1); // LEGACY - events - commands.put("stats", 1); // stats - commands.put("top", 2); // top [number] - commands.put("info", 1); // info - commands.put("journal", 1); // journal - adminCommands.put("stats", 2); // stats [player] - adminCommands.put("give", 3); // give [player] [quest] - adminCommands.put("quit", 3); // quit [player] [quest] - adminCommands.put("remove", 3); // remove [player] [quest] - adminCommands.put("points", 3); // points [player] [amount] - adminCommands.put("takepoints", 3); // takepoints [player] [amount] - adminCommands.put("givepoints", 3); // givepoints [player] [amount] - adminCommands.put("pointsall", 2); // pointsall [amount] - adminCommands.put("finish", 3); // finish [player] [quest] - adminCommands.put("nextstage", 3); // nextstage [player] [quest] - adminCommands.put("setstage", 4); // setstage [player] [quest] [stage] - adminCommands.put("reset", 2); // reset [player] - adminCommands.put("reload", 1); // reload - } - } - - public String checkCommand(String cmd, String[] args) { - if (cmd.equalsIgnoreCase("quest") || args.length == 0) { - return null; - } - if (cmd.equalsIgnoreCase("quests")) { - if (commands.containsKey(args[0].toLowerCase())) { - int min = commands.get(args[0].toLowerCase()); - if (args.length < min) { - return getQuestsCommandUsage(args[0]); - } else { - return null; - } - } - return ChatColor.YELLOW + Lang.get("questsUnknownCommand"); - } else if (cmd.equalsIgnoreCase("questsadmin") || cmd.equalsIgnoreCase("questadmin")) { - if (adminCommands.containsKey(args[0].toLowerCase())) { - int min = adminCommands.get(args[0].toLowerCase()); - if (args.length < min) { - return getQuestadminCommandUsage(args[0]); - } else { - return null; - } - } - return ChatColor.YELLOW + Lang.get("questsUnknownAdminCommand"); - } - return "NULL"; - } - - private boolean questCommandHandler(final CommandSender cs, String[] args) { - if (cs instanceof Player) { - if (((Player) cs).hasPermission("quests.quest")) { - if (args.length == 0) { - Player player = (Player) cs; - Quester quester = plugin.getQuester(player.getUniqueId()); - if (quester.getCurrentQuests().isEmpty() == false) { - for (Quest q : quester.getCurrentQuests().keySet()) { - Stage stage = quester.getCurrentStage(q); - q.updateCompass(quester, stage); - if (plugin.getQuester(player.getUniqueId()).getQuestData(q).delayStartTime == 0) { - String msg = Lang.get(player, "questObjectivesTitle"); - msg = msg.replace("", q.getName()); - player.sendMessage(ChatColor.GOLD + msg); - plugin.showObjectives(q, quester, false); - } else { - long time = plugin.getQuester(player.getUniqueId()).getStageTime(q); - String msg = ChatColor.YELLOW + "(" + Lang.get(player, "delay") + ") " + ChatColor.RED + Lang.get(player, "plnTooEarly"); - msg = msg.replace("", q.getName()); - msg = msg.replace("