2021-08-16 06:11:42 +02:00
|
|
|
/*
|
2021-01-24 07:22:04 +01:00
|
|
|
* Copyright (c) 2014 PikaMug and contributors. All rights reserved.
|
2021-08-16 06:11:42 +02:00
|
|
|
*
|
2020-04-16 01:18:06 +02:00
|
|
|
* 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.
|
2021-08-16 06:11:42 +02:00
|
|
|
*/
|
2020-04-16 01:18:06 +02:00
|
|
|
|
|
|
|
package me.blackvein.quests;
|
|
|
|
|
|
|
|
import com.codisimus.plugins.phatloots.PhatLootsAPI;
|
|
|
|
import com.gmail.nossr50.datatypes.skills.SkillType;
|
|
|
|
import com.herocraftonline.heroes.characters.classes.HeroClass;
|
|
|
|
import me.blackvein.quests.actions.Action;
|
|
|
|
import me.blackvein.quests.actions.ActionFactory;
|
2022-01-12 21:10:01 +01:00
|
|
|
import me.blackvein.quests.actions.BukkitActionFactory;
|
2022-01-23 00:42:06 +01:00
|
|
|
import me.blackvein.quests.actions.IAction;
|
2022-01-19 03:15:49 +01:00
|
|
|
import me.blackvein.quests.conditions.BukkitConditionFactory;
|
2020-07-13 06:35:28 +02:00
|
|
|
import me.blackvein.quests.conditions.Condition;
|
|
|
|
import me.blackvein.quests.conditions.ConditionFactory;
|
2022-01-23 00:42:06 +01:00
|
|
|
import me.blackvein.quests.conditions.ICondition;
|
2022-01-19 03:15:49 +01:00
|
|
|
import me.blackvein.quests.config.ISettings;
|
2021-07-23 09:37:26 +02:00
|
|
|
import me.blackvein.quests.convo.misc.MiscStringPrompt;
|
|
|
|
import me.blackvein.quests.convo.misc.NpcOfferQuestPrompt;
|
2022-01-13 17:02:43 +01:00
|
|
|
import me.blackvein.quests.dependencies.DenizenTrigger;
|
2022-01-19 03:15:49 +01:00
|
|
|
import me.blackvein.quests.dependencies.IDependencies;
|
2022-01-12 21:10:01 +01:00
|
|
|
import me.blackvein.quests.entity.BukkitQuestMob;
|
|
|
|
import me.blackvein.quests.entity.QuestMob;
|
2021-07-22 13:02:07 +02:00
|
|
|
import me.blackvein.quests.events.misc.MiscPostQuestAcceptEvent;
|
2020-04-16 01:18:06 +02:00
|
|
|
import me.blackvein.quests.exceptions.ActionFormatException;
|
2020-07-13 06:35:28 +02:00
|
|
|
import me.blackvein.quests.exceptions.ConditionFormatException;
|
2020-04-16 01:18:06 +02:00
|
|
|
import me.blackvein.quests.exceptions.QuestFormatException;
|
|
|
|
import me.blackvein.quests.exceptions.StageFormatException;
|
|
|
|
import me.blackvein.quests.interfaces.ReloadCallback;
|
2020-04-20 08:25:13 +02:00
|
|
|
import me.blackvein.quests.listeners.BlockListener;
|
2022-06-13 09:25:05 +02:00
|
|
|
import me.blackvein.quests.listeners.CitizensListener;
|
2022-02-16 13:38:09 +01:00
|
|
|
import me.blackvein.quests.listeners.CommandManager;
|
2021-12-02 23:06:20 +01:00
|
|
|
import me.blackvein.quests.listeners.ConvoListener;
|
2020-04-20 08:25:13 +02:00
|
|
|
import me.blackvein.quests.listeners.ItemListener;
|
2020-04-16 01:18:06 +02:00
|
|
|
import me.blackvein.quests.listeners.PartiesListener;
|
|
|
|
import me.blackvein.quests.listeners.PlayerListener;
|
2021-08-19 15:43:48 +02:00
|
|
|
import me.blackvein.quests.listeners.UniteListener;
|
2022-06-04 09:47:44 +02:00
|
|
|
import me.blackvein.quests.listeners.ZnpcsListener;
|
2022-01-23 00:42:06 +01:00
|
|
|
import me.blackvein.quests.logging.QuestsLog4JFilter;
|
2022-01-19 03:15:49 +01:00
|
|
|
import me.blackvein.quests.module.ICustomObjective;
|
|
|
|
import me.blackvein.quests.player.IQuester;
|
2022-01-12 21:10:01 +01:00
|
|
|
import me.blackvein.quests.quests.BukkitQuestFactory;
|
2022-01-19 03:15:49 +01:00
|
|
|
import me.blackvein.quests.quests.IQuest;
|
2022-01-26 06:41:49 +01:00
|
|
|
import me.blackvein.quests.quests.IStage;
|
2022-01-19 03:15:49 +01:00
|
|
|
import me.blackvein.quests.quests.Options;
|
|
|
|
import me.blackvein.quests.quests.Planner;
|
|
|
|
import me.blackvein.quests.quests.QuestFactory;
|
|
|
|
import me.blackvein.quests.quests.Requirements;
|
|
|
|
import me.blackvein.quests.quests.Rewards;
|
2021-02-18 05:27:09 +01:00
|
|
|
import me.blackvein.quests.statistics.Metrics;
|
2020-11-15 03:30:46 +01:00
|
|
|
import me.blackvein.quests.storage.Storage;
|
|
|
|
import me.blackvein.quests.storage.StorageFactory;
|
2020-04-16 01:18:06 +02:00
|
|
|
import me.blackvein.quests.tasks.NpcEffectThread;
|
|
|
|
import me.blackvein.quests.tasks.PlayerMoveThread;
|
|
|
|
import me.blackvein.quests.util.ConfigUtil;
|
|
|
|
import me.blackvein.quests.util.ItemUtil;
|
|
|
|
import me.blackvein.quests.util.Lang;
|
|
|
|
import me.blackvein.quests.util.MiscUtil;
|
2021-01-05 20:27:39 +01:00
|
|
|
import me.blackvein.quests.util.RomanNumeral;
|
2021-09-22 07:39:22 +02:00
|
|
|
import me.blackvein.quests.util.UpdateChecker;
|
2020-04-16 01:18:06 +02:00
|
|
|
import me.clip.placeholderapi.PlaceholderAPI;
|
2021-01-13 06:17:50 +01:00
|
|
|
import me.pikamug.localelib.LocaleManager;
|
2020-04-16 01:18:06 +02:00
|
|
|
import net.citizensnpcs.api.CitizensAPI;
|
|
|
|
import net.citizensnpcs.api.npc.NPC;
|
2021-11-01 08:29:36 +01:00
|
|
|
import net.md_5.bungee.api.chat.ClickEvent;
|
|
|
|
import net.md_5.bungee.api.chat.TextComponent;
|
2022-01-23 00:42:06 +01:00
|
|
|
import org.apache.logging.log4j.LogManager;
|
2021-07-10 01:48:00 +02:00
|
|
|
import org.bukkit.Bukkit;
|
|
|
|
import org.bukkit.ChatColor;
|
|
|
|
import org.bukkit.Color;
|
|
|
|
import org.bukkit.DyeColor;
|
|
|
|
import org.bukkit.Effect;
|
|
|
|
import org.bukkit.Location;
|
|
|
|
import org.bukkit.Material;
|
|
|
|
import org.bukkit.World;
|
|
|
|
import org.bukkit.block.Biome;
|
|
|
|
import org.bukkit.command.CommandExecutor;
|
2022-03-10 23:22:11 +01:00
|
|
|
import org.bukkit.command.TabExecutor;
|
2021-07-10 01:48:00 +02:00
|
|
|
import org.bukkit.configuration.ConfigurationSection;
|
|
|
|
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.ConversationContext;
|
|
|
|
import org.bukkit.conversations.ConversationFactory;
|
|
|
|
import org.bukkit.conversations.Prompt;
|
|
|
|
import org.bukkit.enchantments.Enchantment;
|
2021-08-19 15:43:48 +02:00
|
|
|
import org.bukkit.entity.Entity;
|
2021-07-10 01:48:00 +02:00
|
|
|
import org.bukkit.entity.EntityType;
|
|
|
|
import org.bukkit.entity.Player;
|
|
|
|
import org.bukkit.entity.Tameable;
|
|
|
|
import org.bukkit.event.HandlerList;
|
|
|
|
import org.bukkit.inventory.ItemStack;
|
|
|
|
import org.bukkit.permissions.Permission;
|
|
|
|
import org.bukkit.plugin.java.JavaPlugin;
|
|
|
|
import org.bukkit.potion.PotionEffect;
|
|
|
|
import org.bukkit.potion.PotionEffectType;
|
2021-08-19 15:43:48 +02:00
|
|
|
import org.jetbrains.annotations.NotNull;
|
2021-07-10 01:48:00 +02:00
|
|
|
|
|
|
|
import java.io.File;
|
|
|
|
import java.io.FileInputStream;
|
|
|
|
import java.io.FileOutputStream;
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.InputStream;
|
|
|
|
import java.io.InputStreamReader;
|
|
|
|
import java.io.OutputStream;
|
|
|
|
import java.lang.reflect.Constructor;
|
|
|
|
import java.net.URISyntaxException;
|
|
|
|
import java.net.URL;
|
|
|
|
import java.net.URLClassLoader;
|
2021-08-19 15:43:48 +02:00
|
|
|
import java.nio.charset.StandardCharsets;
|
2021-07-10 01:48:00 +02:00
|
|
|
import java.util.AbstractMap;
|
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.Enumeration;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.HashSet;
|
|
|
|
import java.util.LinkedList;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Map.Entry;
|
2021-08-11 13:44:29 +02:00
|
|
|
import java.util.Objects;
|
2021-07-10 01:48:00 +02:00
|
|
|
import java.util.Optional;
|
|
|
|
import java.util.Set;
|
|
|
|
import java.util.UUID;
|
|
|
|
import java.util.concurrent.ConcurrentSkipListSet;
|
|
|
|
import java.util.jar.JarEntry;
|
|
|
|
import java.util.jar.JarFile;
|
|
|
|
import java.util.logging.Level;
|
2022-03-20 13:39:06 +01:00
|
|
|
import java.util.logging.Logger;
|
2020-04-16 01:18:06 +02:00
|
|
|
|
2022-01-06 16:59:21 +01:00
|
|
|
public class Quests extends JavaPlugin implements QuestsAPI {
|
2020-04-16 01:18:06 +02:00
|
|
|
|
|
|
|
private boolean loading = true;
|
|
|
|
private String bukkitVersion = "0";
|
2022-01-19 03:15:49 +01:00
|
|
|
private IDependencies depends;
|
|
|
|
private ISettings settings;
|
|
|
|
private final List<ICustomObjective> customObjectives = new LinkedList<>();
|
2021-08-19 15:43:48 +02:00
|
|
|
private final List<CustomRequirement> customRequirements = new LinkedList<>();
|
|
|
|
private final List<CustomReward> customRewards = new LinkedList<>();
|
2022-01-19 03:15:49 +01:00
|
|
|
private Collection<IQuester> questers = new ConcurrentSkipListSet<>();
|
|
|
|
private final Collection<IQuest> quests = new ConcurrentSkipListSet<>();
|
|
|
|
private Collection<IAction> actions = new ConcurrentSkipListSet<>();
|
|
|
|
private Collection<ICondition> conditions = new ConcurrentSkipListSet<>();
|
2022-05-15 19:11:37 +02:00
|
|
|
private Collection<UUID> questNpcUuids = new ConcurrentSkipListSet<>();
|
2022-03-10 23:22:11 +01:00
|
|
|
private TabExecutor cmdExecutor;
|
2020-04-16 01:18:06 +02:00
|
|
|
private ConversationFactory conversationFactory;
|
|
|
|
private ConversationFactory npcConversationFactory;
|
|
|
|
private QuestFactory questFactory;
|
2020-07-13 06:35:28 +02:00
|
|
|
private ActionFactory actionFactory;
|
|
|
|
private ConditionFactory conditionFactory;
|
2021-12-02 23:06:20 +01:00
|
|
|
private ConvoListener convoListener;
|
2020-04-20 08:25:13 +02:00
|
|
|
private BlockListener blockListener;
|
|
|
|
private ItemListener itemListener;
|
2022-06-04 09:47:44 +02:00
|
|
|
private CitizensListener citizensListener;
|
|
|
|
private ZnpcsListener znpcsListener;
|
2020-04-20 08:25:13 +02:00
|
|
|
private PlayerListener playerListener;
|
2021-01-15 05:57:49 +01:00
|
|
|
private NpcEffectThread effectThread;
|
2020-04-16 01:18:06 +02:00
|
|
|
private PlayerMoveThread moveThread;
|
2021-08-11 13:44:29 +02:00
|
|
|
private UniteListener uniteListener;
|
2020-04-16 01:18:06 +02:00
|
|
|
private PartiesListener partiesListener;
|
|
|
|
private DenizenTrigger trigger;
|
2021-01-13 06:17:50 +01:00
|
|
|
private LocaleManager localeManager;
|
2020-11-15 03:30:46 +01:00
|
|
|
private Storage storage;
|
2020-04-16 01:18:06 +02:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onEnable() {
|
2021-07-10 01:48:00 +02:00
|
|
|
/*----> WARNING: ORDER OF STEPS MATTERS <----*/
|
2020-04-16 01:18:06 +02:00
|
|
|
|
2022-01-23 06:29:15 +01:00
|
|
|
((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger()).addFilter(new QuestsLog4JFilter());
|
|
|
|
|
2020-04-16 01:18:06 +02:00
|
|
|
// 1 - Initialize variables
|
|
|
|
bukkitVersion = Bukkit.getServer().getBukkitVersion().split("-")[0];
|
|
|
|
settings = new Settings(this);
|
2021-09-16 06:46:48 +02:00
|
|
|
try {
|
2021-09-17 08:44:21 +02:00
|
|
|
Class.forName("me.blackvein.quests.libs.localelib.LocaleManager");
|
2021-09-16 06:46:48 +02:00
|
|
|
localeManager = new LocaleManager();
|
2021-10-09 08:38:57 +02:00
|
|
|
} catch (final Exception ignored) {
|
2021-09-16 06:46:48 +02:00
|
|
|
getLogger().info("LocaleLib not present. Is this a debug environment?");
|
|
|
|
}
|
2021-12-02 23:06:20 +01:00
|
|
|
convoListener = new ConvoListener();
|
2020-04-20 08:25:13 +02:00
|
|
|
blockListener = new BlockListener(this);
|
|
|
|
itemListener = new ItemListener(this);
|
2022-06-04 09:47:44 +02:00
|
|
|
citizensListener = new CitizensListener(this);
|
|
|
|
znpcsListener = new ZnpcsListener(this);
|
2020-04-20 08:25:13 +02:00
|
|
|
playerListener = new PlayerListener(this);
|
2021-08-11 13:44:29 +02:00
|
|
|
uniteListener = new UniteListener();
|
2020-04-16 01:18:06 +02:00
|
|
|
partiesListener = new PartiesListener();
|
2021-01-15 05:57:49 +01:00
|
|
|
effectThread = new NpcEffectThread(this);
|
2020-04-20 08:25:13 +02:00
|
|
|
moveThread = new PlayerMoveThread(this);
|
2022-01-12 21:10:01 +01:00
|
|
|
questFactory = new BukkitQuestFactory(this);
|
|
|
|
actionFactory = new BukkitActionFactory(this);
|
|
|
|
conditionFactory = new BukkitConditionFactory(this);
|
2020-04-16 01:18:06 +02:00
|
|
|
depends = new Dependencies(this);
|
|
|
|
trigger = new DenizenTrigger(this);
|
|
|
|
|
|
|
|
// 2 - Load main config
|
|
|
|
settings.init();
|
2022-06-13 09:25:05 +02:00
|
|
|
if (settings.getLanguage().contains("-")) {
|
|
|
|
final Metrics metrics = new Metrics(this);
|
|
|
|
metrics.addCustomChart(new Metrics.SimplePie("language", () -> settings.getLanguage()));
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
|
|
|
|
// 3 - Setup language files
|
|
|
|
try {
|
|
|
|
setupLang();
|
2021-08-11 13:44:29 +02:00
|
|
|
} catch (final IOException | URISyntaxException e) {
|
2020-04-16 01:18:06 +02:00
|
|
|
e.printStackTrace();
|
|
|
|
}
|
2021-08-11 13:44:29 +02:00
|
|
|
|
2020-04-16 01:18:06 +02:00
|
|
|
// 4 - Load command executor
|
2022-02-16 13:38:09 +01:00
|
|
|
cmdExecutor = new CommandManager(this);
|
2020-04-16 01:18:06 +02:00
|
|
|
|
|
|
|
// 5 - Load soft-depends
|
|
|
|
depends.init();
|
|
|
|
|
|
|
|
// 6 - Save resources from jar
|
|
|
|
saveResourceAs("quests.yml", "quests.yml", false);
|
|
|
|
saveResourceAs("actions.yml", "actions.yml", false);
|
2020-07-13 06:35:28 +02:00
|
|
|
saveResourceAs("conditions.yml", "conditions.yml", false);
|
2020-04-16 01:18:06 +02:00
|
|
|
|
|
|
|
// 7 - Save config with any new options
|
|
|
|
getConfig().options().copyDefaults(true);
|
|
|
|
saveConfig();
|
2020-11-15 03:30:46 +01:00
|
|
|
final StorageFactory storageFactory = new StorageFactory(this);
|
|
|
|
storage = storageFactory.getInstance();
|
2020-04-16 01:18:06 +02:00
|
|
|
|
|
|
|
// 8 - Setup commands
|
2021-08-11 13:44:29 +02:00
|
|
|
if (getCommand("quests") != null) {
|
2022-03-10 23:22:11 +01:00
|
|
|
Objects.requireNonNull(getCommand("quests")).setExecutor(getTabExecutor());
|
|
|
|
Objects.requireNonNull(getCommand("quests")).setTabCompleter(getTabExecutor());
|
2021-08-11 13:44:29 +02:00
|
|
|
}
|
|
|
|
if (getCommand("questadmin") != null) {
|
2022-03-10 23:22:11 +01:00
|
|
|
Objects.requireNonNull(getCommand("questadmin")).setExecutor(getTabExecutor());
|
|
|
|
Objects.requireNonNull(getCommand("questadmin")).setTabCompleter(getTabExecutor());
|
2021-08-11 13:44:29 +02:00
|
|
|
}
|
|
|
|
if (getCommand("quest") != null) {
|
2022-03-10 23:22:11 +01:00
|
|
|
Objects.requireNonNull(getCommand("quest")).setExecutor(getTabExecutor());
|
|
|
|
Objects.requireNonNull(getCommand("quest")).setTabCompleter(getTabExecutor());
|
2021-08-11 13:44:29 +02:00
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
|
|
|
|
// 9 - Build conversation factories
|
|
|
|
this.conversationFactory = new ConversationFactory(this).withModality(false)
|
2021-08-19 15:43:48 +02:00
|
|
|
.withPrefix(context -> ChatColor.GRAY.toString())
|
2020-04-16 01:18:06 +02:00
|
|
|
.withFirstPrompt(new QuestAcceptPrompt()).withTimeout(settings.getAcceptTimeout())
|
|
|
|
.thatExcludesNonPlayersWithMessage("Console may not perform this conversation!")
|
2021-12-02 23:06:20 +01:00
|
|
|
.addConversationAbandonedListener(convoListener);
|
2020-04-16 01:18:06 +02:00
|
|
|
this.npcConversationFactory = new ConversationFactory(this).withModality(false)
|
2020-07-28 22:48:51 +02:00
|
|
|
.withFirstPrompt(new NpcOfferQuestPrompt()).withTimeout(settings.getAcceptTimeout())
|
2021-12-02 23:06:20 +01:00
|
|
|
.withLocalEcho(false).addConversationAbandonedListener(convoListener);
|
2021-07-23 09:37:26 +02:00
|
|
|
|
2020-04-16 01:18:06 +02:00
|
|
|
// 10 - Register listeners
|
2021-11-08 09:17:03 +01:00
|
|
|
getServer().getPluginManager().registerEvents(getBlockListener(), this);
|
|
|
|
getServer().getPluginManager().registerEvents(getItemListener(), this);
|
2021-02-05 04:33:52 +01:00
|
|
|
depends.linkCitizens();
|
2022-06-04 09:47:44 +02:00
|
|
|
if (depends.getZnpcs() != null) {
|
|
|
|
getServer().getPluginManager().registerEvents(getZnpcsListener(), this);
|
|
|
|
}
|
2021-11-08 09:17:03 +01:00
|
|
|
getServer().getPluginManager().registerEvents(getPlayerListener(), this);
|
2020-04-16 01:18:06 +02:00
|
|
|
if (settings.getStrictPlayerMovement() > 0) {
|
2021-07-10 01:48:00 +02:00
|
|
|
final long ticks = settings.getStrictPlayerMovement() * 20L;
|
2021-11-08 09:17:03 +01:00
|
|
|
getServer().getScheduler().scheduleSyncRepeatingTask(this, getPlayerMoveThread(), ticks, ticks);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-08-11 13:44:29 +02:00
|
|
|
if (depends.getPartyProvider() != null) {
|
2021-11-08 09:17:03 +01:00
|
|
|
getServer().getPluginManager().registerEvents(getUniteListener(), this);
|
2021-08-11 13:44:29 +02:00
|
|
|
} else if (depends.getPartiesApi() != null) {
|
2021-11-08 09:17:03 +01:00
|
|
|
getServer().getPluginManager().registerEvents(getPartiesListener(), this);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2021-09-22 07:39:22 +02:00
|
|
|
// 11 - Attempt to check for updates
|
|
|
|
new UpdateChecker(this, 3711).getVersion(version -> {
|
|
|
|
if (!getDescription().getVersion().split("-")[0].equalsIgnoreCase(version)) {
|
|
|
|
getLogger().info(ChatColor.DARK_GREEN + Lang.get("updateTo").replace("<version>",
|
|
|
|
version).replace("<url>", ChatColor.AQUA + getDescription().getWebsite()));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2022-03-20 13:39:06 +01:00
|
|
|
// 12 - Delay loading of quests, actions and modules
|
2021-08-19 15:43:48 +02:00
|
|
|
delayLoadQuestInfo();
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2020-04-16 01:18:06 +02:00
|
|
|
@Override
|
|
|
|
public void onDisable() {
|
|
|
|
getLogger().info("Saving Quester data...");
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final Player p : getServer().getOnlinePlayers()) {
|
2022-09-01 02:57:34 +02:00
|
|
|
getQuester(p.getUniqueId()).saveData();
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-08-11 13:44:29 +02:00
|
|
|
Bukkit.getScheduler().cancelTasks(this);
|
2020-11-18 11:09:18 +01:00
|
|
|
getLogger().info("Closing storage...");
|
2021-08-11 13:44:29 +02:00
|
|
|
if (storage != null) {
|
|
|
|
storage.close();
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2020-04-16 01:18:06 +02:00
|
|
|
public boolean isLoading() {
|
|
|
|
return loading;
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2022-03-20 13:39:06 +01:00
|
|
|
public File getPluginDataFolder() {
|
|
|
|
return getDataFolder();
|
|
|
|
}
|
|
|
|
|
|
|
|
public Logger getPluginLogger() {
|
|
|
|
return getLogger();
|
|
|
|
}
|
|
|
|
|
|
|
|
public InputStream getPluginResource(String filename) {
|
|
|
|
return getResource(filename);
|
|
|
|
}
|
|
|
|
|
2022-01-13 17:02:43 +01:00
|
|
|
public String getDetectedServerSoftwareVersion() {
|
2020-04-16 01:18:06 +02:00
|
|
|
return bukkitVersion;
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2020-04-16 01:18:06 +02:00
|
|
|
public Dependencies getDependencies() {
|
2022-01-19 03:15:49 +01:00
|
|
|
return (Dependencies) depends;
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2020-04-16 01:18:06 +02:00
|
|
|
public Settings getSettings() {
|
2022-01-19 03:15:49 +01:00
|
|
|
return (Settings) settings;
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2022-01-06 16:59:21 +01:00
|
|
|
@Override
|
2022-01-19 03:15:49 +01:00
|
|
|
public List<ICustomObjective> getCustomObjectives() {
|
2022-01-06 16:59:21 +01:00
|
|
|
return customObjectives;
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2022-01-19 03:15:49 +01:00
|
|
|
public Optional<ICustomObjective> getCustomObjective(final String className) {
|
|
|
|
for (final ICustomObjective co : customObjectives) {
|
2022-01-06 16:59:21 +01:00
|
|
|
if (co.getClass().getName().equals(className)) {
|
|
|
|
return Optional.of(co);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Optional.empty();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-04-16 01:18:06 +02:00
|
|
|
public List<CustomRequirement> getCustomRequirements() {
|
|
|
|
return customRequirements;
|
|
|
|
}
|
|
|
|
|
2020-08-06 11:32:43 +02:00
|
|
|
public Optional<CustomRequirement> getCustomRequirement(final String className) {
|
2021-08-19 15:43:48 +02:00
|
|
|
for (final CustomRequirement cr : customRequirements) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (cr.getClass().getName().equals(className)) {
|
|
|
|
return Optional.of(cr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Optional.empty();
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2022-01-06 16:59:21 +01:00
|
|
|
@Override
|
2020-04-16 01:18:06 +02:00
|
|
|
public List<CustomReward> getCustomRewards() {
|
|
|
|
return customRewards;
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2020-08-06 11:32:43 +02:00
|
|
|
public Optional<CustomReward> getCustomReward(final String className) {
|
2021-07-10 01:48:00 +02:00
|
|
|
for (final CustomReward cr : customRewards) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (cr.getClass().getName().equals(className)) {
|
|
|
|
return Optional.of(cr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Optional.empty();
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2021-05-12 21:03:32 +02:00
|
|
|
/**
|
|
|
|
* Get every Quest loaded in memory
|
2021-08-19 15:43:48 +02:00
|
|
|
*
|
2021-05-12 21:03:32 +02:00
|
|
|
* @deprecated Use {@link #getLoadedQuests()}
|
|
|
|
* @return a list of all Quests
|
|
|
|
*/
|
|
|
|
@Deprecated
|
2020-04-16 01:18:06 +02:00
|
|
|
public LinkedList<Quest> getQuests() {
|
2022-01-19 03:15:49 +01:00
|
|
|
final LinkedList<Quest> list = new LinkedList<>();
|
|
|
|
for (IQuest q : quests) {
|
|
|
|
list.add((Quest) q);
|
|
|
|
}
|
|
|
|
return list;
|
2021-05-12 21:03:32 +02:00
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2021-05-12 21:03:32 +02:00
|
|
|
/**
|
|
|
|
* Get every Quest loaded in memory
|
2021-08-19 15:43:48 +02:00
|
|
|
*
|
2021-05-12 21:03:32 +02:00
|
|
|
* @return a collection of all Quests
|
|
|
|
*/
|
2022-01-19 03:15:49 +01:00
|
|
|
public Collection<IQuest> getLoadedQuests() {
|
2020-04-16 01:18:06 +02:00
|
|
|
return quests;
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2021-05-12 21:03:32 +02:00
|
|
|
/**
|
|
|
|
* Get every Action loaded in memory
|
2021-08-19 15:43:48 +02:00
|
|
|
*
|
2021-05-12 21:03:32 +02:00
|
|
|
* @deprecated Use {@link #getLoadedActions()}
|
|
|
|
* @return a list of all Actions
|
|
|
|
*/
|
|
|
|
@Deprecated
|
2020-04-16 01:18:06 +02:00
|
|
|
public LinkedList<Action> getActions() {
|
2022-01-19 03:15:49 +01:00
|
|
|
final LinkedList<Action> list = new LinkedList<>();
|
|
|
|
for (IAction a : actions) {
|
|
|
|
list.add((Action) a);
|
|
|
|
}
|
|
|
|
return list;
|
2021-05-12 21:03:32 +02:00
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2021-05-12 21:03:32 +02:00
|
|
|
/**
|
2022-01-19 03:15:49 +01:00
|
|
|
* Get every IAction loaded in memory
|
2021-08-19 15:43:48 +02:00
|
|
|
*
|
2021-05-12 21:03:32 +02:00
|
|
|
* @return a collection of all Actions
|
|
|
|
*/
|
2022-01-19 03:15:49 +01:00
|
|
|
public Collection<IAction> getLoadedActions() {
|
2020-04-16 01:18:06 +02:00
|
|
|
return actions;
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2021-05-12 21:03:32 +02:00
|
|
|
/**
|
2022-01-19 03:15:49 +01:00
|
|
|
* Set every IAction loaded in memory
|
2021-08-19 15:43:48 +02:00
|
|
|
*
|
2021-06-21 07:02:35 +02:00
|
|
|
* @deprecated Use {@link #setLoadedActions(Collection)}
|
2021-05-12 21:03:32 +02:00
|
|
|
*/
|
|
|
|
@Deprecated
|
2022-01-19 03:15:49 +01:00
|
|
|
public void setActions(final LinkedList<IAction> actions) {
|
2020-04-16 01:18:06 +02:00
|
|
|
this.actions = actions;
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2021-05-12 21:03:32 +02:00
|
|
|
/**
|
2022-01-19 03:15:49 +01:00
|
|
|
* Set every IAction loaded in memory
|
2021-08-19 15:43:48 +02:00
|
|
|
*
|
2021-05-12 21:03:32 +02:00
|
|
|
*/
|
2022-01-19 03:15:49 +01:00
|
|
|
public void setLoadedActions(final Collection<IAction> actions) {
|
2021-05-12 21:03:32 +02:00
|
|
|
this.actions = actions;
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2021-05-12 21:03:32 +02:00
|
|
|
/**
|
|
|
|
* Get every Condition loaded in memory
|
2021-08-19 15:43:48 +02:00
|
|
|
*
|
2021-05-12 21:03:32 +02:00
|
|
|
* @deprecated Use {@link #getLoadedConditions()}
|
2022-01-19 03:15:49 +01:00
|
|
|
* @return a list of all Actions
|
2021-05-12 21:03:32 +02:00
|
|
|
*/
|
|
|
|
@Deprecated
|
2020-07-13 06:35:28 +02:00
|
|
|
public LinkedList<Condition> getConditions() {
|
2022-01-19 03:15:49 +01:00
|
|
|
final LinkedList<Condition> list = new LinkedList<>();
|
|
|
|
for (ICondition c : conditions) {
|
|
|
|
list.add((Condition) c);
|
|
|
|
}
|
|
|
|
return list;
|
2021-05-12 21:03:32 +02:00
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2021-05-12 21:03:32 +02:00
|
|
|
/**
|
2022-01-19 03:15:49 +01:00
|
|
|
* Get every ICondition loaded in memory
|
2021-08-19 15:43:48 +02:00
|
|
|
*
|
2021-05-12 21:03:32 +02:00
|
|
|
* @return a collection of all Conditions
|
|
|
|
*/
|
2022-01-19 03:15:49 +01:00
|
|
|
public Collection<ICondition> getLoadedConditions() {
|
2020-07-13 06:35:28 +02:00
|
|
|
return conditions;
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2021-05-12 21:03:32 +02:00
|
|
|
/**
|
2022-01-19 03:15:49 +01:00
|
|
|
* Set every ICondition loaded in memory
|
2021-08-19 15:43:48 +02:00
|
|
|
*
|
2021-06-21 07:02:35 +02:00
|
|
|
* @deprecated Use {@link #setLoadedConditions(Collection)}
|
2021-05-12 21:03:32 +02:00
|
|
|
*/
|
|
|
|
@Deprecated
|
2022-01-19 03:15:49 +01:00
|
|
|
public void setConditions(final LinkedList<ICondition> conditions) {
|
2020-07-13 06:35:28 +02:00
|
|
|
this.conditions = conditions;
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2021-05-12 21:03:32 +02:00
|
|
|
/**
|
2022-01-19 03:15:49 +01:00
|
|
|
* Set every ICondition loaded in memory
|
2021-08-19 15:43:48 +02:00
|
|
|
*
|
2021-05-12 21:03:32 +02:00
|
|
|
*/
|
2022-01-19 03:15:49 +01:00
|
|
|
public void setLoadedConditions(final Collection<ICondition> conditions) {
|
2021-05-12 21:03:32 +02:00
|
|
|
this.conditions = conditions;
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2020-11-05 21:17:13 +01:00
|
|
|
/**
|
2020-11-27 02:11:11 +01:00
|
|
|
* Get Quester from player UUID
|
2021-08-19 15:43:48 +02:00
|
|
|
*
|
2020-11-27 02:11:11 +01:00
|
|
|
* @param id Player UUID
|
|
|
|
* @return Quester, or null if UUID is null
|
2020-11-05 21:17:13 +01:00
|
|
|
*/
|
2020-11-27 02:11:11 +01:00
|
|
|
public Quester getQuester(final UUID id) {
|
|
|
|
if (id == null) {
|
|
|
|
return null;
|
|
|
|
}
|
2022-01-19 03:15:49 +01:00
|
|
|
final ConcurrentSkipListSet<IQuester> set = (ConcurrentSkipListSet<IQuester>) questers;
|
2022-07-09 09:05:56 +02:00
|
|
|
for (final IQuester q : set) {
|
2020-11-27 02:11:11 +01:00
|
|
|
if (q != null && q.getUUID().equals(id)) {
|
2022-01-19 03:15:49 +01:00
|
|
|
return (Quester) q;
|
2020-11-27 02:11:11 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
final Quester quester = new Quester(this, id);
|
|
|
|
if (depends.getCitizens() != null) {
|
|
|
|
if (depends.getCitizens().getNPCRegistry().getByUniqueId(id) != null) {
|
|
|
|
return quester;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
final Quester q = new Quester(this, id);
|
|
|
|
questers.add(q);
|
|
|
|
return q;
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2020-11-27 02:11:11 +01:00
|
|
|
/**
|
|
|
|
* Get every online Quester playing on this server
|
2021-08-19 15:43:48 +02:00
|
|
|
*
|
2020-11-27 02:11:11 +01:00
|
|
|
* @return a collection of all online Questers
|
|
|
|
*/
|
2022-01-19 03:15:49 +01:00
|
|
|
public Collection<IQuester> getOnlineQuesters() {
|
|
|
|
final Collection<IQuester> questers = new ConcurrentSkipListSet<>();
|
|
|
|
for (final IQuester q : getOfflineQuesters()) {
|
2020-11-27 02:11:11 +01:00
|
|
|
if (q.getOfflinePlayer().isOnline()) {
|
|
|
|
// Workaround for issues with the compass on fast join
|
|
|
|
q.findCompassTarget();
|
|
|
|
questers.add(q);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return questers;
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2020-11-27 02:11:11 +01:00
|
|
|
/**
|
2021-05-12 21:03:32 +02:00
|
|
|
* Get every Quester that has ever played on this server
|
2021-08-19 15:43:48 +02:00
|
|
|
*
|
2020-11-27 02:11:11 +01:00
|
|
|
* @return a collection of all Questers
|
|
|
|
*/
|
2022-01-19 03:15:49 +01:00
|
|
|
public Collection<IQuester> getOfflineQuesters() {
|
2020-11-27 02:11:11 +01:00
|
|
|
return questers;
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2020-11-27 02:11:11 +01:00
|
|
|
/**
|
2021-05-12 21:03:32 +02:00
|
|
|
* Set every Quester that has ever played on this server
|
2021-08-19 15:43:48 +02:00
|
|
|
*
|
2020-11-27 02:11:11 +01:00
|
|
|
* @param questers a collection of Questers
|
|
|
|
*/
|
2022-01-19 03:15:49 +01:00
|
|
|
public void setOfflineQuesters(final Collection<IQuester> questers) {
|
2020-11-27 02:11:11 +01:00
|
|
|
this.questers = new ConcurrentSkipListSet<>(questers);
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2022-05-15 19:11:37 +02:00
|
|
|
/**
|
|
|
|
* Get every NPC UUID which sees use a quest giver, talk target, or kill target
|
|
|
|
*
|
|
|
|
* @return a collection of all UUIDs
|
|
|
|
*/
|
|
|
|
public Collection<UUID> getQuestNpcUuids() {
|
|
|
|
return questNpcUuids;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set every NPC UUID which sees use a quest giver, talk target, or kill target
|
|
|
|
*
|
|
|
|
* @param questNpcUuids a collection of UUIDs
|
|
|
|
*/
|
|
|
|
public void setQuestNpcUuids(final Collection<UUID> questNpcUuids) {
|
|
|
|
this.questNpcUuids = new ConcurrentSkipListSet<>(questNpcUuids);
|
|
|
|
}
|
|
|
|
|
2021-08-19 15:43:48 +02:00
|
|
|
public CommandExecutor getCommandExecutor() {
|
|
|
|
return cmdExecutor;
|
|
|
|
}
|
|
|
|
|
2022-03-10 23:22:11 +01:00
|
|
|
public TabExecutor getTabExecutor() {
|
|
|
|
return cmdExecutor;
|
|
|
|
}
|
|
|
|
|
2020-04-16 01:18:06 +02:00
|
|
|
public ConversationFactory getConversationFactory() {
|
|
|
|
return conversationFactory;
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2020-04-16 01:18:06 +02:00
|
|
|
public ConversationFactory getNpcConversationFactory() {
|
|
|
|
return npcConversationFactory;
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2020-04-16 01:18:06 +02:00
|
|
|
public QuestFactory getQuestFactory() {
|
|
|
|
return questFactory;
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2020-04-16 01:18:06 +02:00
|
|
|
public ActionFactory getActionFactory() {
|
2020-07-13 06:35:28 +02:00
|
|
|
return actionFactory;
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2020-07-13 06:35:28 +02:00
|
|
|
public ConditionFactory getConditionFactory() {
|
|
|
|
return conditionFactory;
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2021-12-02 23:06:20 +01:00
|
|
|
public ConvoListener getConvoListener() {
|
|
|
|
return convoListener;
|
|
|
|
}
|
|
|
|
|
2020-04-20 10:19:17 +02:00
|
|
|
public BlockListener getBlockListener() {
|
|
|
|
return blockListener;
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2020-04-20 08:25:13 +02:00
|
|
|
public ItemListener getItemListener() {
|
|
|
|
return itemListener;
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2022-06-04 09:47:44 +02:00
|
|
|
public CitizensListener getCitizensListener() {
|
|
|
|
return citizensListener;
|
|
|
|
}
|
|
|
|
|
|
|
|
public ZnpcsListener getZnpcsListener() {
|
|
|
|
return znpcsListener;
|
2020-04-20 08:25:13 +02:00
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2020-04-16 01:18:06 +02:00
|
|
|
public PlayerListener getPlayerListener() {
|
|
|
|
return playerListener;
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2021-08-11 13:44:29 +02:00
|
|
|
public UniteListener getUniteListener() {
|
|
|
|
return uniteListener;
|
2020-04-20 08:25:13 +02:00
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2021-01-15 05:57:49 +01:00
|
|
|
public NpcEffectThread getNpcEffectThread() {
|
|
|
|
return effectThread;
|
|
|
|
}
|
2021-08-11 13:44:29 +02:00
|
|
|
|
2021-08-19 15:43:48 +02:00
|
|
|
public PlayerMoveThread getPlayerMoveThread() {
|
|
|
|
return moveThread;
|
|
|
|
}
|
|
|
|
|
2021-08-11 13:44:29 +02:00
|
|
|
public PartiesListener getPartiesListener() {
|
|
|
|
return partiesListener;
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2020-04-16 01:18:06 +02:00
|
|
|
public DenizenTrigger getDenizenTrigger() {
|
|
|
|
return trigger;
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2021-01-13 06:17:50 +01:00
|
|
|
public LocaleManager getLocaleManager() {
|
|
|
|
return localeManager;
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
2020-11-15 03:30:46 +01:00
|
|
|
public Storage getStorage() {
|
|
|
|
return storage;
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
|
2021-07-23 09:37:26 +02:00
|
|
|
public class QuestAcceptPrompt extends MiscStringPrompt {
|
|
|
|
|
|
|
|
private ConversationContext cc;
|
|
|
|
|
|
|
|
public QuestAcceptPrompt() {
|
|
|
|
super(null);
|
|
|
|
}
|
|
|
|
|
|
|
|
public QuestAcceptPrompt(final ConversationContext context) {
|
|
|
|
super(context);
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
|
2021-07-22 13:02:07 +02:00
|
|
|
private final int size = 2;
|
|
|
|
|
|
|
|
public int getSize() {
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getTitle(final ConversationContext context) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public ChatColor getNumberColor(final ConversationContext context, final int number) {
|
|
|
|
switch (number) {
|
|
|
|
case 1:
|
|
|
|
return ChatColor.GREEN;
|
|
|
|
case 2:
|
|
|
|
return ChatColor.RED;
|
|
|
|
default:
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getSelectionText(final ConversationContext context, final int number) {
|
|
|
|
switch (number) {
|
|
|
|
case 1:
|
|
|
|
return ChatColor.GREEN + Lang.get("yesWord");
|
|
|
|
case 2:
|
|
|
|
return ChatColor.RED + Lang.get("noWord");
|
|
|
|
default:
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getQueryText(final ConversationContext context) {
|
|
|
|
return Lang.get("acceptQuest");
|
|
|
|
}
|
|
|
|
|
2020-04-16 01:18:06 +02:00
|
|
|
@Override
|
2021-08-19 15:43:48 +02:00
|
|
|
public @NotNull String getPromptText(final @NotNull ConversationContext context) {
|
2021-07-23 09:37:26 +02:00
|
|
|
this.cc = context;
|
|
|
|
|
2021-07-22 13:02:07 +02:00
|
|
|
final MiscPostQuestAcceptEvent event = new MiscPostQuestAcceptEvent(context, this);
|
|
|
|
getServer().getPluginManager().callEvent(event);
|
|
|
|
|
2021-12-16 09:50:36 +01:00
|
|
|
if (!getSettings().canClickablePrompts()) {
|
|
|
|
return ChatColor.YELLOW + getQueryText(context) + " " + ChatColor.GREEN
|
|
|
|
+ getSelectionText(context, 1) + ChatColor.RESET + " / " + getSelectionText(context, 2);
|
|
|
|
}
|
|
|
|
|
2021-11-01 08:29:36 +01:00
|
|
|
final TextComponent component = new TextComponent("");
|
|
|
|
component.addExtra(ChatColor.YELLOW + getQueryText(context) + " " + ChatColor.GREEN);
|
|
|
|
final TextComponent yes = new TextComponent(getSelectionText(context, 1));
|
2022-09-24 06:10:12 +02:00
|
|
|
yes.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/quests choice " + Lang.get("yesWord")));
|
2021-11-01 08:29:36 +01:00
|
|
|
component.addExtra(yes);
|
|
|
|
component.addExtra(ChatColor.RESET + " / ");
|
|
|
|
final TextComponent no = new TextComponent(getSelectionText(context, 2));
|
2022-09-24 06:10:12 +02:00
|
|
|
no.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/quests choice " + Lang.get("noWord")));
|
2021-11-01 08:29:36 +01:00
|
|
|
component.addExtra(no);
|
|
|
|
|
|
|
|
((Player)context.getForWhom()).spigot().sendMessage(component);
|
|
|
|
return "";
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2021-08-19 15:43:48 +02:00
|
|
|
public Prompt acceptInput(final @NotNull ConversationContext context, final String input) {
|
2021-07-22 09:22:33 +02:00
|
|
|
if (input == null) {
|
|
|
|
getLogger().severe("Ended conversation because input for " + getName() + "was null");
|
|
|
|
return Prompt.END_OF_CONVERSATION;
|
|
|
|
}
|
2020-06-05 06:57:08 +02:00
|
|
|
final Player player = (Player) context.getForWhom();
|
2021-11-01 08:29:36 +01:00
|
|
|
if (input.equalsIgnoreCase("1") || input.equalsIgnoreCase("y")
|
|
|
|
|| input.equalsIgnoreCase(Lang.get(player, "yesWord"))) {
|
2022-01-19 03:15:49 +01:00
|
|
|
IQuester quester = getQuester(player.getUniqueId());
|
2020-06-05 06:57:08 +02:00
|
|
|
if (quester == null) {
|
|
|
|
// Must be new player
|
2020-11-30 05:17:59 +01:00
|
|
|
quester = new Quester(Quests.this, player.getUniqueId());
|
2020-06-05 06:57:08 +02:00
|
|
|
if (quester.saveData()) {
|
|
|
|
getLogger().info("Created new data for player " + player.getName());
|
|
|
|
} else {
|
2021-07-11 11:06:13 +02:00
|
|
|
Lang.send(player, ChatColor.RED + Lang.get(player, "questSaveError"));
|
2020-06-05 06:57:08 +02:00
|
|
|
}
|
|
|
|
}
|
2022-01-12 21:10:01 +01:00
|
|
|
final String questIdToTake = quester.getQuestIdToTake();
|
2020-04-16 01:18:06 +02:00
|
|
|
try {
|
2022-02-04 12:41:23 +01:00
|
|
|
if (getQuestByIdTemp(questIdToTake) == null) {
|
2020-11-21 08:46:53 +01:00
|
|
|
getLogger().info(player.getName() + " attempted to take quest ID \"" + questIdToTake
|
2020-04-16 01:18:06 +02:00
|
|
|
+ "\" but something went wrong");
|
|
|
|
player.sendMessage(ChatColor.RED
|
|
|
|
+ "Something went wrong! Please report issue to an administrator.");
|
|
|
|
} else {
|
2022-02-04 12:41:23 +01:00
|
|
|
getQuester(player.getUniqueId()).takeQuest(getQuestByIdTemp(questIdToTake), false);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2020-08-06 11:32:43 +02:00
|
|
|
} catch (final Exception e) {
|
2020-04-16 01:18:06 +02:00
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
return Prompt.END_OF_CONVERSATION;
|
2021-11-01 08:29:36 +01:00
|
|
|
} else if (input.equalsIgnoreCase("2") || input.equalsIgnoreCase("n")
|
|
|
|
|| input.equalsIgnoreCase(Lang.get("noWord"))) {
|
2021-07-11 11:06:13 +02:00
|
|
|
Lang.send(player, ChatColor.YELLOW + Lang.get("cancelled"));
|
2020-04-16 01:18:06 +02:00
|
|
|
return Prompt.END_OF_CONVERSATION;
|
|
|
|
} else {
|
2020-08-06 11:32:43 +02:00
|
|
|
final String msg = Lang.get(player, "questInvalidChoice")
|
2020-04-16 01:18:06 +02:00
|
|
|
.replace("<yes>", Lang.get(player, "yesWord"))
|
|
|
|
.replace("<no>", Lang.get(player, "noWord"));
|
2021-07-11 11:06:13 +02:00
|
|
|
Lang.send(player, ChatColor.RED + msg);
|
2021-07-23 09:37:26 +02:00
|
|
|
return new QuestAcceptPrompt(context);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-03-20 13:39:06 +01:00
|
|
|
|
2020-04-16 01:18:06 +02:00
|
|
|
/**
|
2022-06-13 09:25:05 +02:00
|
|
|
* Transfer language files from jar to disk, then initialize default
|
2020-04-16 01:18:06 +02:00
|
|
|
*/
|
|
|
|
private void setupLang() throws IOException, URISyntaxException {
|
|
|
|
final String path = "lang";
|
2021-10-26 23:26:01 +02:00
|
|
|
final File jarFile = new File(getClass().getProtectionDomain().getCodeSource().getLocation().toURI());
|
2021-09-06 04:34:05 +02:00
|
|
|
if (jarFile.isFile()) {
|
2020-04-16 01:18:06 +02:00
|
|
|
final JarFile jar = new JarFile(jarFile);
|
|
|
|
final Enumeration<JarEntry> entries = jar.entries();
|
2021-08-19 15:43:48 +02:00
|
|
|
final Set<String> results = new HashSet<>();
|
2021-10-26 05:36:25 +02:00
|
|
|
while (entries.hasMoreElements()) {
|
2020-04-16 01:18:06 +02:00
|
|
|
final String name = entries.nextElement().getName();
|
|
|
|
if (name.startsWith(path + "/") && name.contains("strings.yml")) {
|
|
|
|
results.add(name);
|
|
|
|
}
|
|
|
|
}
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final String resourcePath : results) {
|
2020-04-16 01:18:06 +02:00
|
|
|
saveResourceAs(resourcePath, resourcePath, false);
|
|
|
|
saveResourceAs(resourcePath, resourcePath.replace(".yml", "_new.yml"), true);
|
|
|
|
}
|
|
|
|
jar.close();
|
|
|
|
}
|
|
|
|
try {
|
2022-06-13 09:25:05 +02:00
|
|
|
Lang.init(this, settings.getLanguage());
|
2020-08-06 11:32:43 +02:00
|
|
|
} catch (final InvalidConfigurationException e) {
|
2020-04-16 01:18:06 +02:00
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Save a Quests plugin resource to a specific path in the filesystem
|
|
|
|
*
|
|
|
|
* @param resourcePath jar file location starting from resource folder, i.e. "lang/el-GR/strings.yml"
|
|
|
|
* @param outputPath file destination starting from Quests folder, i.e. "lang/el-GR/strings.yml"
|
|
|
|
* @param replace whether or not to replace the destination file
|
|
|
|
*/
|
2020-08-06 11:32:43 +02:00
|
|
|
public void saveResourceAs(String resourcePath, final String outputPath, final boolean replace) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (resourcePath == null || resourcePath.equals("")) {
|
|
|
|
throw new IllegalArgumentException("ResourcePath cannot be null or empty");
|
|
|
|
}
|
|
|
|
|
|
|
|
resourcePath = resourcePath.replace('\\', '/');
|
2020-08-06 11:32:43 +02:00
|
|
|
final InputStream in = getResource(resourcePath);
|
2020-04-16 01:18:06 +02:00
|
|
|
if (in == null) {
|
|
|
|
throw new IllegalArgumentException("The embedded resource '" + resourcePath
|
|
|
|
+ "' cannot be found in Quests jar");
|
|
|
|
}
|
|
|
|
|
2020-08-06 11:32:43 +02:00
|
|
|
final String outPath = outputPath.replace('/', File.separatorChar).replace('\\', File.separatorChar);
|
|
|
|
final File outFile = new File(getDataFolder(), outPath);
|
|
|
|
final File outDir = new File(outFile.getPath().replace(outFile.getName(), ""));
|
2020-04-16 01:18:06 +02:00
|
|
|
|
|
|
|
if (!outDir.exists()) {
|
|
|
|
if (!outDir.mkdirs()) {
|
|
|
|
getLogger().log(Level.SEVERE, "Failed to make directories for " + outFile.getName() + " (canWrite= "
|
|
|
|
+ outDir.canWrite() + ")");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
if (!outFile.exists() || replace) {
|
2020-08-06 11:32:43 +02:00
|
|
|
final OutputStream out = new FileOutputStream(outFile);
|
|
|
|
final byte[] buf = new byte[1024];
|
2020-04-16 01:18:06 +02:00
|
|
|
int len;
|
|
|
|
while ((len = in.read(buf)) > 0) {
|
|
|
|
out.write(buf, 0, len);
|
|
|
|
}
|
|
|
|
out.close();
|
|
|
|
in.close();
|
|
|
|
if (!outFile.exists()) {
|
|
|
|
getLogger().severe("Unable to copy " + outFile.getName() + " (canWrite= " + outFile.canWrite()
|
|
|
|
+ ")");
|
|
|
|
}
|
|
|
|
}
|
2020-08-06 11:32:43 +02:00
|
|
|
} catch (final IOException ex) {
|
2020-04-16 01:18:06 +02:00
|
|
|
getLogger().log(Level.SEVERE, "Could not save " + outFile.getName() + " to " + outFile, ex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2021-08-19 15:43:48 +02:00
|
|
|
* Load quests, actions, conditions, and modules
|
2020-04-16 01:18:06 +02:00
|
|
|
*
|
|
|
|
* At startup, this lets soft-depends (namely Citizens) fully load first
|
|
|
|
*/
|
2021-08-19 15:43:48 +02:00
|
|
|
private void delayLoadQuestInfo() {
|
|
|
|
getServer().getScheduler().scheduleSyncDelayedTask(this, () -> {
|
|
|
|
loadQuests();
|
|
|
|
loadActions();
|
|
|
|
loadConditions();
|
|
|
|
getLogger().log(Level.INFO, "Loaded " + quests.size() + " Quest(s), " + actions.size() + " Action(s), "
|
|
|
|
+ conditions.size() + " Condition(s) and " + Lang.size() + " Phrase(s)");
|
|
|
|
for (final Player p : getServer().getOnlinePlayers()) {
|
2022-01-19 03:15:49 +01:00
|
|
|
final IQuester quester = new Quester(Quests.this, p.getUniqueId());
|
2021-08-19 15:43:48 +02:00
|
|
|
if (!quester.hasData()) {
|
|
|
|
quester.saveData();
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
// Workaround for issues with the compass on fast join
|
|
|
|
quester.findCompassTarget();
|
|
|
|
questers.add(quester);
|
|
|
|
}
|
|
|
|
if (depends.getCitizens() != null) {
|
|
|
|
if (depends.getCitizens().getNPCRegistry() == null) {
|
|
|
|
getLogger().log(Level.SEVERE,
|
|
|
|
"Citizens was enabled but NPCRegistry was null. Disabling linkage.");
|
|
|
|
depends.unlinkCitizens();
|
2020-10-11 09:38:56 +02:00
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
loadModules();
|
|
|
|
importQuests();
|
|
|
|
if (getSettings().canDisableCommandFeedback()) {
|
|
|
|
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "gamerule sendCommandFeedback false");
|
|
|
|
}
|
|
|
|
loading = false;
|
|
|
|
}, 5L);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
|
2020-12-30 09:50:17 +01:00
|
|
|
private void importQuests() {
|
|
|
|
final File f = new File(this.getDataFolder(), "import");
|
|
|
|
if (f.exists() && f.isDirectory()) {
|
|
|
|
final File[] imports = f.listFiles();
|
|
|
|
if (imports != null) {
|
|
|
|
for (final File file : imports) {
|
2021-07-10 01:48:00 +02:00
|
|
|
if (!file.isDirectory() && file.getName().endsWith(".yml")) {
|
2020-12-30 09:50:17 +01:00
|
|
|
importQuest(file);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
} else if (!f.mkdir()) {
|
|
|
|
getLogger().warning("Unable to create import directory");
|
2020-12-30 09:50:17 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void importQuest(final File file) {
|
|
|
|
FileConfiguration config = null;
|
|
|
|
try {
|
2021-08-19 15:43:48 +02:00
|
|
|
config = YamlConfiguration.loadConfiguration(new InputStreamReader(new FileInputStream(file),
|
|
|
|
StandardCharsets.UTF_8));
|
2020-12-30 09:50:17 +01:00
|
|
|
} catch (final IOException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
if (config != null) {
|
|
|
|
final ConfigurationSection questsSection = config.getConfigurationSection("quests");
|
|
|
|
if (questsSection == null) {
|
2021-07-10 01:48:00 +02:00
|
|
|
getLogger().severe("Missing 'quests' section marker, canceled import of file " + file.getName());
|
2020-12-30 09:50:17 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
int count = 0;
|
|
|
|
for (final String questKey : questsSection.getKeys(false)) {
|
|
|
|
try {
|
2022-01-19 03:15:49 +01:00
|
|
|
for (final IQuest lq : getLoadedQuests()) {
|
2021-05-12 21:03:32 +02:00
|
|
|
if (lq.getId().equals(questKey)) {
|
2020-12-30 09:50:17 +01:00
|
|
|
throw new QuestFormatException("id already exists", questKey);
|
|
|
|
}
|
|
|
|
}
|
2022-01-19 03:15:49 +01:00
|
|
|
final IQuest quest = loadQuest(config, questKey);
|
2020-12-30 09:50:17 +01:00
|
|
|
if (config.contains("quests." + questKey + ".requirements")) {
|
|
|
|
loadQuestRequirements(config, questsSection, quest, questKey);
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".planner")) {
|
2021-08-19 15:43:48 +02:00
|
|
|
loadQuestPlanner(config, quest, questKey);
|
2020-12-30 09:50:17 +01:00
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".options")) {
|
2021-08-19 15:43:48 +02:00
|
|
|
loadQuestOptions(config, quest, questKey);
|
2020-12-30 09:50:17 +01:00
|
|
|
}
|
2022-01-13 17:02:43 +01:00
|
|
|
quest.setPlugin(this);
|
2020-12-30 09:50:17 +01:00
|
|
|
loadQuestStages(quest, config, questKey);
|
|
|
|
loadQuestRewards(config, quest, questKey);
|
|
|
|
quests.add(quest);
|
|
|
|
count++;
|
2021-08-19 15:43:48 +02:00
|
|
|
} catch (final QuestFormatException | StageFormatException | ActionFormatException
|
|
|
|
| ConditionFormatException e) {
|
2020-12-30 09:50:17 +01:00
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (count > 0) {
|
|
|
|
getLogger().info("Imported " + count + " Quests from " + file.getName());
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
getLogger().severe("Unable to import quest file " + file.getName());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-16 01:18:06 +02:00
|
|
|
/**
|
|
|
|
* Load modules from file
|
|
|
|
*/
|
|
|
|
public void loadModules() {
|
2020-08-06 11:32:43 +02:00
|
|
|
final File f = new File(this.getDataFolder(), "modules");
|
2020-04-16 01:18:06 +02:00
|
|
|
if (f.exists() && f.isDirectory()) {
|
2020-08-06 11:32:43 +02:00
|
|
|
final File[] modules = f.listFiles();
|
2020-04-16 01:18:06 +02:00
|
|
|
if (modules != null) {
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final File module : modules) {
|
2021-07-10 01:48:00 +02:00
|
|
|
if (!module.isDirectory() && module.getName().endsWith(".jar")) {
|
2020-04-16 01:18:06 +02:00
|
|
|
loadModule(module);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
} else if (!f.mkdir()) {
|
|
|
|
getLogger().warning("Unable to create module directory");
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
FileConfiguration config = null;
|
2020-08-06 11:32:43 +02:00
|
|
|
final File file = new File(this.getDataFolder(), "quests.yml");
|
2020-04-16 01:18:06 +02:00
|
|
|
try {
|
2021-08-19 15:43:48 +02:00
|
|
|
config = YamlConfiguration.loadConfiguration(new InputStreamReader(new FileInputStream(file),
|
|
|
|
StandardCharsets.UTF_8));
|
2020-08-06 11:32:43 +02:00
|
|
|
} catch (final IOException e) {
|
2020-04-16 01:18:06 +02:00
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
if (config != null) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final ConfigurationSection questsSection;
|
2020-04-16 01:18:06 +02:00
|
|
|
if (config.contains("quests")) {
|
|
|
|
questsSection = config.getConfigurationSection("quests");
|
2021-08-19 15:43:48 +02:00
|
|
|
if (questsSection != null) {
|
|
|
|
for (final String questKey : questsSection.getKeys(false)) {
|
|
|
|
try {
|
|
|
|
if (config.contains("quests." + questKey)) {
|
2022-02-04 12:41:23 +01:00
|
|
|
loadCustomSections(getQuestByIdTemp(questKey), config, questKey);
|
2021-08-19 15:43:48 +02:00
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Unable to load custom sections", questKey);
|
|
|
|
}
|
|
|
|
} catch (final QuestFormatException | StageFormatException ex) {
|
|
|
|
ex.printStackTrace();
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
getLogger().severe("Unable to load module data from quests.yml");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Load the specified jar as a module
|
|
|
|
*
|
|
|
|
* @param jar A custom reward/requirement/objective jar
|
|
|
|
*/
|
2020-08-06 11:32:43 +02:00
|
|
|
public void loadModule(final File jar) {
|
2020-04-16 01:18:06 +02:00
|
|
|
try {
|
|
|
|
@SuppressWarnings("resource")
|
2021-10-09 08:38:57 +02:00
|
|
|
final JarFile jarFile = new JarFile(jar);
|
2021-09-07 20:51:36 +02:00
|
|
|
final Enumeration<JarEntry> entry = jarFile.entries();
|
2020-08-06 11:32:43 +02:00
|
|
|
final URL[] urls = { new URL("jar:file:" + jar.getPath() + "!/") };
|
|
|
|
final ClassLoader cl = URLClassLoader.newInstance(urls, getClassLoader());
|
2020-04-16 01:18:06 +02:00
|
|
|
int count = 0;
|
2021-09-07 20:51:36 +02:00
|
|
|
while (entry.hasMoreElements()) {
|
|
|
|
final JarEntry je = entry.nextElement();
|
2020-04-16 01:18:06 +02:00
|
|
|
if (je.isDirectory() || !je.getName().endsWith(".class")) {
|
|
|
|
continue;
|
|
|
|
}
|
2021-09-07 20:51:36 +02:00
|
|
|
final String className = je.getName().substring(0, je.getName().length() - 6).replace('/', '.');
|
|
|
|
Class<?> c = null;
|
|
|
|
try {
|
|
|
|
c = Class.forName(className, true, cl);
|
|
|
|
} catch (final NoClassDefFoundError e) {
|
|
|
|
getLogger().severe("Module error! Seek help from developer of module:");
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
if (c != null) {
|
|
|
|
if (CustomRequirement.class.isAssignableFrom(c)) {
|
|
|
|
final Class<? extends CustomRequirement> requirementClass = c.asSubclass(CustomRequirement.class);
|
2021-10-09 08:38:57 +02:00
|
|
|
final Constructor<? extends CustomRequirement> constructor = requirementClass.getConstructor();
|
|
|
|
final CustomRequirement requirement = constructor.newInstance();
|
2022-01-13 17:02:43 +01:00
|
|
|
final Optional<CustomRequirement> oo = getCustomRequirement(requirement.getClass().getName());
|
2021-09-07 20:51:36 +02:00
|
|
|
oo.ifPresent(customRequirements::remove);
|
|
|
|
customRequirements.add(requirement);
|
|
|
|
final String name = requirement.getName() == null ? "[" + jar.getName() + "]" : requirement.getName();
|
|
|
|
final String author = requirement.getAuthor() == null ? "[Unknown]" : requirement.getAuthor();
|
|
|
|
count++;
|
2021-10-09 08:38:57 +02:00
|
|
|
getLogger().info("Loaded \"" + name + "\" by " + author);
|
2021-09-07 20:51:36 +02:00
|
|
|
} else if (CustomReward.class.isAssignableFrom(c)) {
|
|
|
|
final Class<? extends CustomReward> rewardClass = c.asSubclass(CustomReward.class);
|
2021-10-09 08:38:57 +02:00
|
|
|
final Constructor<? extends CustomReward> constructor = rewardClass.getConstructor();
|
|
|
|
final CustomReward reward = constructor.newInstance();
|
2022-01-13 17:02:43 +01:00
|
|
|
final Optional<CustomReward> oo = getCustomReward(reward.getClass().getName());
|
2021-09-07 20:51:36 +02:00
|
|
|
oo.ifPresent(customRewards::remove);
|
|
|
|
customRewards.add(reward);
|
|
|
|
final String name = reward.getName() == null ? "[" + jar.getName() + "]" : reward.getName();
|
|
|
|
final String author = reward.getAuthor() == null ? "[Unknown]" : reward.getAuthor();
|
|
|
|
count++;
|
2021-10-09 08:38:57 +02:00
|
|
|
getLogger().info("Loaded \"" + name + "\" by " + author);
|
2022-01-19 03:15:49 +01:00
|
|
|
} else if (ICustomObjective.class.isAssignableFrom(c)) {
|
2021-09-07 20:51:36 +02:00
|
|
|
final Class<? extends CustomObjective> objectiveClass = c.asSubclass(CustomObjective.class);
|
2021-10-09 08:38:57 +02:00
|
|
|
final Constructor<? extends CustomObjective> constructor = objectiveClass.getConstructor();
|
|
|
|
final CustomObjective objective = constructor.newInstance();
|
2022-01-19 03:15:49 +01:00
|
|
|
final Optional<ICustomObjective> oo = getCustomObjective(objective.getClass().getName());
|
|
|
|
if (oo.isPresent() && oo.get() instanceof CustomObjective) {
|
|
|
|
HandlerList.unregisterAll((CustomObjective)oo.get());
|
2021-09-07 20:51:36 +02:00
|
|
|
customObjectives.remove(oo.get());
|
|
|
|
}
|
|
|
|
customObjectives.add(objective);
|
|
|
|
final String name = objective.getName() == null ? "[" + jar.getName() + "]" : objective.getName();
|
|
|
|
final String author = objective.getAuthor() == null ? "[Unknown]" : objective.getAuthor();
|
|
|
|
count++;
|
2021-10-09 08:38:57 +02:00
|
|
|
getLogger().info("Loaded \"" + name + "\" by " + author);
|
2021-09-07 20:51:36 +02:00
|
|
|
try {
|
|
|
|
getServer().getPluginManager().registerEvents(objective, this);
|
|
|
|
getLogger().info("Registered events for custom objective \"" + name + "\"");
|
|
|
|
} catch (final Exception ex) {
|
|
|
|
getLogger().warning("Failed to register events for custom objective \"" + name
|
|
|
|
+ "\". Does the objective class listen for events?");
|
|
|
|
ex.printStackTrace();
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (count == 0) {
|
|
|
|
getLogger().severe("Unable to load module from file: " + jar.getName()
|
2021-10-09 08:38:57 +02:00
|
|
|
+ ", file is not a valid module!");
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2020-08-06 11:32:43 +02:00
|
|
|
} catch (final Exception e) {
|
2020-04-16 01:18:06 +02:00
|
|
|
getLogger().severe("Unable to load module from file: " + jar.getName());
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Show all of a player's objectives for the current stage of a quest.<p>
|
|
|
|
*
|
|
|
|
* Respects PlaceholderAPI and translations, when enabled.
|
|
|
|
*
|
|
|
|
* @param quest The quest to get current stage objectives of
|
|
|
|
* @param quester The player to show current stage objectives to
|
|
|
|
* @param ignoreOverrides Whether to ignore objective-overrides
|
|
|
|
*/
|
|
|
|
@SuppressWarnings("deprecation")
|
2022-01-19 03:15:49 +01:00
|
|
|
public void showObjectives(final IQuest quest, final IQuester quester, final boolean ignoreOverrides) {
|
2021-02-25 06:06:07 +01:00
|
|
|
if (quest == null) {
|
|
|
|
getLogger().severe("Quest was null when getting objectives for " + quester.getLastKnownName());
|
|
|
|
return;
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
if (quester.getQuestData(quest) == null) {
|
|
|
|
getLogger().warning("Quest data was null when showing objectives for " + quest.getName());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (quester.getCurrentStage(quest) == null) {
|
|
|
|
getLogger().warning("Current stage was null when showing objectives for " + quest.getName());
|
|
|
|
return;
|
|
|
|
}
|
2022-01-12 21:10:01 +01:00
|
|
|
if (!ignoreOverrides && !quester.getCurrentStage(quest).getObjectiveOverrides().isEmpty()) {
|
|
|
|
for (final String s: quester.getCurrentStage(quest).getObjectiveOverrides()) {
|
2021-01-09 07:55:31 +01:00
|
|
|
String message = ChatColor.GREEN + (s.trim().length() > 0 ? "- " : "") + ConfigUtil
|
2021-09-07 20:51:36 +02:00
|
|
|
.parseString(s, quest, quester.getPlayer());
|
2020-04-16 01:18:06 +02:00
|
|
|
if (depends.getPlaceholderApi() != null) {
|
|
|
|
message = PlaceholderAPI.setPlaceholders(quester.getPlayer(), message);
|
|
|
|
}
|
2021-01-09 07:55:31 +01:00
|
|
|
quester.sendMessage(message);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2020-08-06 11:32:43 +02:00
|
|
|
final QuestData data = quester.getQuestData(quest);
|
2022-01-23 06:29:15 +01:00
|
|
|
final IStage stage = quester.getCurrentStage(quest);
|
2022-01-12 21:10:01 +01:00
|
|
|
for (final ItemStack e : stage.getBlocksToBreak()) {
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final ItemStack e2 : data.blocksBroken) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (e2.getType().equals(e.getType()) && e2.getDurability() == e.getDurability()) {
|
2020-08-06 11:32:43 +02:00
|
|
|
final ChatColor color = e2.getAmount() < e.getAmount() ? ChatColor.GREEN : ChatColor.GRAY;
|
2021-01-09 07:55:31 +01:00
|
|
|
String message = color + "- " + Lang.get(quester.getPlayer(), "break");
|
2020-12-15 06:22:55 +01:00
|
|
|
if (message.contains("<count>")) {
|
|
|
|
message = message.replace("<count>", "" + color + e2.getAmount() + "/" + e.getAmount());
|
|
|
|
} else {
|
|
|
|
// Legacy
|
|
|
|
message += " <item>" + color + ": " + e2.getAmount() + "/" + e.getAmount();
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
if (depends.getPlaceholderApi() != null) {
|
|
|
|
message = PlaceholderAPI.setPlaceholders(quester.getPlayer(), message);
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
if (getSettings().canTranslateNames() && !e.hasItemMeta()) {
|
2021-01-13 06:17:50 +01:00
|
|
|
localeManager.sendMessage(quester.getPlayer(), message, e.getType(), e.getDurability(), null);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
2021-01-09 07:55:31 +01:00
|
|
|
quester.sendMessage(message.replace("<item>", ItemUtil.getName(e)));
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-01-12 21:10:01 +01:00
|
|
|
for (final ItemStack e : stage.getBlocksToDamage()) {
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final ItemStack e2 : data.blocksDamaged) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (e2.getType().equals(e.getType()) && e2.getDurability() == e.getDurability()) {
|
2020-08-06 11:32:43 +02:00
|
|
|
final ChatColor color = e2.getAmount() < e.getAmount() ? ChatColor.GREEN : ChatColor.GRAY;
|
2021-01-09 07:55:31 +01:00
|
|
|
String message = color + "- " + Lang.get(quester.getPlayer(), "damage");
|
2020-12-15 06:22:55 +01:00
|
|
|
if (message.contains("<count>")) {
|
|
|
|
message = message.replace("<count>", "" + color + e2.getAmount() + "/" + e.getAmount());
|
|
|
|
} else {
|
|
|
|
// Legacy
|
|
|
|
message += " <item>" + color + ": " + e2.getAmount() + "/" + e.getAmount();
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
if (depends.getPlaceholderApi() != null) {
|
|
|
|
message = PlaceholderAPI.setPlaceholders(quester.getPlayer(), message);
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
if (getSettings().canTranslateNames() && !e.hasItemMeta()) {
|
2021-01-13 06:17:50 +01:00
|
|
|
localeManager.sendMessage(quester.getPlayer(), message, e.getType(), e.getDurability(), null);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
2021-01-09 07:55:31 +01:00
|
|
|
quester.sendMessage(message.replace("<item>", ItemUtil.getName(e)));
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-01-12 21:10:01 +01:00
|
|
|
for (final ItemStack e : stage.getBlocksToPlace()) {
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final ItemStack e2 : data.blocksPlaced) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (e2.getType().equals(e.getType()) && e2.getDurability() == e.getDurability()) {
|
2020-08-06 11:32:43 +02:00
|
|
|
final ChatColor color = e2.getAmount() < e.getAmount() ? ChatColor.GREEN : ChatColor.GRAY;
|
2021-01-09 07:55:31 +01:00
|
|
|
String message = color + "- " + Lang.get(quester.getPlayer(), "place");
|
2020-12-15 06:22:55 +01:00
|
|
|
if (message.contains("<count>")) {
|
|
|
|
message = message.replace("<count>", "" + color + e2.getAmount() + "/" + e.getAmount());
|
|
|
|
} else {
|
|
|
|
// Legacy
|
|
|
|
message += " <item>" + color + ": " + e2.getAmount() + "/" + e.getAmount();
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
if (depends.getPlaceholderApi() != null) {
|
|
|
|
message = PlaceholderAPI.setPlaceholders(quester.getPlayer(), message);
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
if (getSettings().canTranslateNames() && !e.hasItemMeta()) {
|
2021-01-13 06:17:50 +01:00
|
|
|
localeManager.sendMessage(quester.getPlayer(), message, e.getType(), e.getDurability(), null);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
2021-01-09 07:55:31 +01:00
|
|
|
quester.sendMessage(message.replace("<item>", ItemUtil.getName(e)));
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-01-12 21:10:01 +01:00
|
|
|
for (final ItemStack e : stage.getBlocksToUse()) {
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final ItemStack e2 : data.blocksUsed) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (e2.getType().equals(e.getType()) && e2.getDurability() == e.getDurability()) {
|
2020-08-06 11:32:43 +02:00
|
|
|
final ChatColor color = e2.getAmount() < e.getAmount() ? ChatColor.GREEN : ChatColor.GRAY;
|
2021-01-09 07:55:31 +01:00
|
|
|
String message = color + "- " + Lang.get(quester.getPlayer(), "use");
|
2020-12-15 06:22:55 +01:00
|
|
|
if (message.contains("<count>")) {
|
|
|
|
message = message.replace("<count>", "" + color + e2.getAmount() + "/" + e.getAmount());
|
|
|
|
} else {
|
|
|
|
// Legacy
|
|
|
|
message += " <item>" + color + ": " + e2.getAmount() + "/" + e.getAmount();
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
if (depends.getPlaceholderApi() != null) {
|
|
|
|
message = PlaceholderAPI.setPlaceholders(quester.getPlayer(), message);
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
if (getSettings().canTranslateNames() && !e.hasItemMeta()) {
|
2021-01-13 06:17:50 +01:00
|
|
|
localeManager.sendMessage(quester.getPlayer(), message, e.getType(), e.getDurability(), null);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
2021-01-09 07:55:31 +01:00
|
|
|
quester.sendMessage(message.replace("<item>", ItemUtil.getName(e)));
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-01-12 21:10:01 +01:00
|
|
|
for (final ItemStack e : stage.getBlocksToCut()) {
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final ItemStack e2 : data.blocksCut) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (e2.getType().equals(e.getType()) && e2.getDurability() == e.getDurability()) {
|
2020-08-06 11:32:43 +02:00
|
|
|
final ChatColor color = e2.getAmount() < e.getAmount() ? ChatColor.GREEN : ChatColor.GRAY;
|
2021-01-09 07:55:31 +01:00
|
|
|
String message = color + "- " + Lang.get(quester.getPlayer(), "cut");
|
2020-12-15 06:22:55 +01:00
|
|
|
if (message.contains("<count>")) {
|
|
|
|
message = message.replace("<count>", "" + color + e2.getAmount() + "/" + e.getAmount());
|
|
|
|
} else {
|
|
|
|
// Legacy
|
|
|
|
message += " <item>" + color + ": " + e2.getAmount() + "/" + e.getAmount();
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
if (depends.getPlaceholderApi() != null) {
|
|
|
|
message = PlaceholderAPI.setPlaceholders(quester.getPlayer(), message);
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
if (getSettings().canTranslateNames() && !e.hasItemMeta()) {
|
2021-01-13 06:17:50 +01:00
|
|
|
localeManager.sendMessage(quester.getPlayer(), message, e.getType(), e.getDurability(), null);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
2021-01-09 07:55:31 +01:00
|
|
|
quester.sendMessage(message.replace("<item>", ItemUtil.getName(e)));
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-06-21 07:02:35 +02:00
|
|
|
int craftIndex = 0;
|
2022-01-12 21:10:01 +01:00
|
|
|
for (final ItemStack is : stage.getItemsToCraft()) {
|
2020-04-16 01:18:06 +02:00
|
|
|
int crafted = 0;
|
2021-06-21 07:02:35 +02:00
|
|
|
if (data.itemsCrafted.size() > craftIndex) {
|
|
|
|
crafted = data.itemsCrafted.get(craftIndex).getAmount();
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2020-08-06 11:32:43 +02:00
|
|
|
final int amt = is.getAmount();
|
|
|
|
final ChatColor color = crafted < amt ? ChatColor.GREEN : ChatColor.GRAY;
|
2021-01-09 07:55:31 +01:00
|
|
|
String message = color + "- " + Lang.get(quester.getPlayer(), "craftItem");
|
2020-12-15 06:22:55 +01:00
|
|
|
if (message.contains("<count>")) {
|
|
|
|
message = message.replace("<count>", "" + color + crafted + "/" + is.getAmount());
|
|
|
|
} else {
|
2021-01-03 09:00:00 +01:00
|
|
|
// Legacy
|
2020-12-15 06:22:55 +01:00
|
|
|
message += color + ": " + crafted + "/" + is.getAmount();
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
if (depends.getPlaceholderApi() != null) {
|
|
|
|
message = PlaceholderAPI.setPlaceholders(quester.getPlayer(), message);
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
if (getSettings().canTranslateNames() && !is.hasItemMeta()) {
|
2021-01-13 06:17:50 +01:00
|
|
|
localeManager.sendMessage(quester.getPlayer(), message, is.getType(), is.getDurability(),
|
2020-04-16 01:18:06 +02:00
|
|
|
is.getEnchantments());
|
|
|
|
} else {
|
2021-01-09 07:55:31 +01:00
|
|
|
quester.sendMessage(message.replace("<item>", ItemUtil.getName(is)));
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-07-10 01:48:00 +02:00
|
|
|
craftIndex++;
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-06-21 07:02:35 +02:00
|
|
|
int smeltIndex = 0;
|
2022-01-12 21:10:01 +01:00
|
|
|
for (final ItemStack is : stage.getItemsToSmelt()) {
|
2020-04-16 01:18:06 +02:00
|
|
|
int smelted = 0;
|
2021-06-21 07:02:35 +02:00
|
|
|
if (data.itemsSmelted.size() > smeltIndex) {
|
|
|
|
smelted = data.itemsSmelted.get(smeltIndex).getAmount();
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2020-08-06 11:32:43 +02:00
|
|
|
final int amt = is.getAmount();
|
|
|
|
final ChatColor color = smelted < amt ? ChatColor.GREEN : ChatColor.GRAY;
|
2021-01-09 07:55:31 +01:00
|
|
|
String message = color + "- " + Lang.get(quester.getPlayer(), "smeltItem");
|
2020-12-15 06:22:55 +01:00
|
|
|
if (message.contains("<count>")) {
|
|
|
|
message = message.replace("<count>", "" + color + smelted + "/" + is.getAmount());
|
|
|
|
} else {
|
2021-01-03 09:00:00 +01:00
|
|
|
// Legacy
|
2020-12-15 06:22:55 +01:00
|
|
|
message += color + ": " + smelted + "/" + is.getAmount();
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
if (depends.getPlaceholderApi() != null) {
|
|
|
|
message = PlaceholderAPI.setPlaceholders(quester.getPlayer(), message);
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
if (getSettings().canTranslateNames() && !is.hasItemMeta()) {
|
2021-01-13 06:17:50 +01:00
|
|
|
localeManager.sendMessage(quester.getPlayer(), message, is.getType(), is.getDurability(),
|
2020-04-16 01:18:06 +02:00
|
|
|
is.getEnchantments());
|
|
|
|
} else {
|
2021-01-09 07:55:31 +01:00
|
|
|
quester.sendMessage(message.replace("<item>", ItemUtil.getName(is)));
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-07-10 01:48:00 +02:00
|
|
|
smeltIndex++;
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-06-21 07:02:35 +02:00
|
|
|
int enchantIndex = 0;
|
2022-01-12 21:10:01 +01:00
|
|
|
for (final ItemStack is : stage.getItemsToEnchant()) {
|
2020-10-19 09:43:01 +02:00
|
|
|
int enchanted = 0;
|
2021-06-21 07:02:35 +02:00
|
|
|
if (data.itemsEnchanted.size() > enchantIndex) {
|
|
|
|
enchanted = data.itemsEnchanted.get(enchantIndex).getAmount();
|
2020-10-19 09:43:01 +02:00
|
|
|
}
|
|
|
|
final int amt = is.getAmount();
|
|
|
|
final ChatColor color = enchanted < amt ? ChatColor.GREEN : ChatColor.GRAY;
|
2021-01-09 07:55:31 +01:00
|
|
|
String message = color + "- " + Lang.get(quester.getPlayer(), "enchItem");
|
2020-12-15 06:22:55 +01:00
|
|
|
if (message.contains("<count>")) {
|
|
|
|
message = message.replace("<count>", "" + color + enchanted + "/" + is.getAmount());
|
|
|
|
} else {
|
2021-01-03 09:00:00 +01:00
|
|
|
// Legacy
|
2020-12-15 06:22:55 +01:00
|
|
|
message += color + ": " + enchanted + "/" + is.getAmount();
|
|
|
|
}
|
2020-10-19 09:43:01 +02:00
|
|
|
if (depends.getPlaceholderApi() != null) {
|
|
|
|
message = PlaceholderAPI.setPlaceholders(quester.getPlayer(), message);
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
if (getSettings().canTranslateNames() && is.hasItemMeta()) {
|
2021-01-05 20:27:39 +01:00
|
|
|
// Bukkit version is 1.9+
|
2021-01-13 06:17:50 +01:00
|
|
|
localeManager.sendMessage(quester.getPlayer(), message, is.getType(), is.getDurability(),
|
2021-01-05 20:27:39 +01:00
|
|
|
is.getEnchantments(), is.getItemMeta());
|
|
|
|
} else if (getSettings().canTranslateNames() && !is.hasItemMeta()
|
|
|
|
&& Material.getMaterial("LINGERING_POTION") == null) {
|
|
|
|
// Bukkit version is below 1.9
|
2021-01-13 06:17:50 +01:00
|
|
|
localeManager.sendMessage(quester.getPlayer(), message, is.getType(), is.getDurability(),
|
2021-01-05 20:27:39 +01:00
|
|
|
is.getEnchantments());
|
|
|
|
} else {
|
|
|
|
if (is.getEnchantments().isEmpty()) {
|
2021-01-09 07:55:31 +01:00
|
|
|
quester.sendMessage(message.replace("<item>", ItemUtil.getName(is))
|
2021-01-05 20:27:39 +01:00
|
|
|
.replace("<enchantment>", "")
|
|
|
|
.replace("<level>", "")
|
|
|
|
.replaceAll("\\s+", " "));
|
2020-10-19 09:43:01 +02:00
|
|
|
} else {
|
2021-01-05 20:27:39 +01:00
|
|
|
for (final Entry<Enchantment, Integer> e : is.getEnchantments().entrySet()) {
|
2021-01-09 07:55:31 +01:00
|
|
|
quester.sendMessage(message.replace("<item>", ItemUtil.getName(is))
|
2021-01-05 20:27:39 +01:00
|
|
|
.replace("<enchantment>", ItemUtil.getPrettyEnchantmentName(e.getKey()))
|
|
|
|
.replace("<level>", RomanNumeral.getNumeral(e.getValue())));
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
2021-07-10 01:48:00 +02:00
|
|
|
enchantIndex++;
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-06-21 07:02:35 +02:00
|
|
|
int brewIndex = 0;
|
2022-01-12 21:10:01 +01:00
|
|
|
for (final ItemStack is : stage.getItemsToBrew()) {
|
2020-04-16 01:18:06 +02:00
|
|
|
int brewed = 0;
|
2021-06-21 07:02:35 +02:00
|
|
|
if (data.itemsBrewed.size() > brewIndex) {
|
|
|
|
brewed = data.itemsBrewed.get(brewIndex).getAmount();
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2020-08-06 11:32:43 +02:00
|
|
|
final int amt = is.getAmount();
|
|
|
|
final ChatColor color = brewed < amt ? ChatColor.GREEN : ChatColor.GRAY;
|
2021-01-09 07:55:31 +01:00
|
|
|
String message = color + "- " + Lang.get(quester.getPlayer(), "brewItem");
|
2020-12-15 06:22:55 +01:00
|
|
|
if (message.contains("<count>")) {
|
|
|
|
message = message.replace("<count>", "" + color + brewed + "/" + is.getAmount());
|
|
|
|
} else {
|
2021-01-03 09:00:00 +01:00
|
|
|
// Legacy
|
2020-12-15 06:22:55 +01:00
|
|
|
message += color + ": " + brewed + "/" + is.getAmount();
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
if (depends.getPlaceholderApi() != null) {
|
|
|
|
message = PlaceholderAPI.setPlaceholders(quester.getPlayer(), message);
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
if (getSettings().canTranslateNames() && is.hasItemMeta()) {
|
2021-01-05 20:27:39 +01:00
|
|
|
// Bukkit version is 1.9+
|
2021-10-31 11:26:36 +01:00
|
|
|
localeManager.sendMessage(quester.getPlayer(), message, is.getType(), is.getDurability(),
|
2021-01-05 20:27:39 +01:00
|
|
|
is.getEnchantments(), is.getItemMeta());
|
|
|
|
} else if (getSettings().canTranslateNames() && !is.hasItemMeta()
|
|
|
|
&& Material.getMaterial("LINGERING_POTION") == null) {
|
|
|
|
// Bukkit version is below 1.9
|
2021-01-13 06:17:50 +01:00
|
|
|
localeManager.sendMessage(quester.getPlayer(), message, is.getType(), is.getDurability(),
|
2021-01-05 20:27:39 +01:00
|
|
|
is.getEnchantments());
|
|
|
|
} else {
|
2021-01-09 07:55:31 +01:00
|
|
|
quester.sendMessage(message.replace("<item>", ItemUtil.getName(is)));
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-07-10 01:48:00 +02:00
|
|
|
brewIndex++;
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-05-13 10:19:18 +02:00
|
|
|
int consumeIndex = 0;
|
2022-01-12 21:10:01 +01:00
|
|
|
for (final ItemStack is : stage.getItemsToConsume()) {
|
2020-04-20 10:19:17 +02:00
|
|
|
int consumed = 0;
|
2021-05-13 10:19:18 +02:00
|
|
|
if (data.itemsConsumed.size() > consumeIndex) {
|
|
|
|
consumed = data.itemsConsumed.get(consumeIndex).getAmount();
|
2020-04-20 10:19:17 +02:00
|
|
|
}
|
2020-08-06 11:32:43 +02:00
|
|
|
final int amt = is.getAmount();
|
|
|
|
final ChatColor color = consumed < amt ? ChatColor.GREEN : ChatColor.GRAY;
|
2021-01-09 07:55:31 +01:00
|
|
|
String message = color + "- " + Lang.get(quester.getPlayer(), "consumeItem");
|
2020-12-15 06:22:55 +01:00
|
|
|
if (message.contains("<count>")) {
|
|
|
|
message = message.replace("<count>", "" + color + consumed + "/" + is.getAmount());
|
|
|
|
} else {
|
2021-01-03 09:00:00 +01:00
|
|
|
// Legacy
|
2020-12-15 06:22:55 +01:00
|
|
|
message += color + ": " + consumed + "/" + is.getAmount();
|
|
|
|
}
|
2020-04-20 10:19:17 +02:00
|
|
|
if (depends.getPlaceholderApi() != null) {
|
|
|
|
message = PlaceholderAPI.setPlaceholders(quester.getPlayer(), message);
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
if (getSettings().canTranslateNames() && is.hasItemMeta()) {
|
2021-01-20 23:20:57 +01:00
|
|
|
// Bukkit version is 1.9+
|
|
|
|
localeManager.sendMessage(quester.getPlayer(), message, is.getType(), is.getDurability(),
|
|
|
|
is.getEnchantments(), is.getItemMeta());
|
|
|
|
} else if (getSettings().canTranslateNames() && !is.hasItemMeta()
|
|
|
|
&& Material.getMaterial("LINGERING_POTION") == null) {
|
|
|
|
// Bukkit version is below 1.9
|
2021-01-13 06:17:50 +01:00
|
|
|
localeManager.sendMessage(quester.getPlayer(), message, is.getType(), is.getDurability(),
|
2020-04-20 10:19:17 +02:00
|
|
|
is.getEnchantments());
|
|
|
|
} else {
|
2021-01-09 07:55:31 +01:00
|
|
|
quester.sendMessage(message.replace("<item>", ItemUtil.getName(is)));
|
2020-04-20 10:19:17 +02:00
|
|
|
}
|
2021-07-10 01:48:00 +02:00
|
|
|
consumeIndex++;
|
2020-04-20 10:19:17 +02:00
|
|
|
}
|
2021-07-10 01:48:00 +02:00
|
|
|
int deliverIndex = 0;
|
2022-01-12 21:10:01 +01:00
|
|
|
for (final ItemStack is : stage.getItemsToDeliver()) {
|
2021-05-13 10:19:18 +02:00
|
|
|
int delivered = 0;
|
2021-07-10 01:48:00 +02:00
|
|
|
if (data.itemsDelivered.size() > deliverIndex) {
|
|
|
|
delivered = data.itemsDelivered.get(deliverIndex).getAmount();
|
2021-05-13 10:19:18 +02:00
|
|
|
}
|
|
|
|
final int toDeliver = is.getAmount();
|
2022-04-18 01:28:23 +02:00
|
|
|
final UUID npc = stage.getItemDeliveryTargets().get(deliverIndex);
|
2021-05-13 10:19:18 +02:00
|
|
|
final ChatColor color = delivered < toDeliver ? ChatColor.GREEN : ChatColor.GRAY;
|
2022-06-04 09:47:44 +02:00
|
|
|
String message = color + "- " + Lang.get(quester.getPlayer(), "deliver")
|
|
|
|
.replace("<npc>", depends.getNPCName(npc));
|
2021-05-13 10:19:18 +02:00
|
|
|
if (message.contains("<count>")) {
|
|
|
|
message = message.replace("<count>", "" + color + delivered + "/" + toDeliver);
|
|
|
|
} else {
|
|
|
|
// Legacy
|
|
|
|
message += color + ": " + delivered + "/" + toDeliver;
|
|
|
|
}
|
|
|
|
if (depends.getPlaceholderApi() != null) {
|
|
|
|
message = PlaceholderAPI.setPlaceholders(quester.getPlayer(), message);
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
if (getSettings().canTranslateNames() && !is.hasItemMeta()) {
|
2021-05-13 10:19:18 +02:00
|
|
|
localeManager.sendMessage(quester.getPlayer(), message, is.getType(), is.getDurability(),
|
|
|
|
is.getEnchantments());
|
|
|
|
} else {
|
|
|
|
quester.sendMessage(message.replace("<item>", ItemUtil.getName(is)));
|
|
|
|
}
|
2021-07-10 01:48:00 +02:00
|
|
|
deliverIndex++;
|
2021-05-13 10:19:18 +02:00
|
|
|
}
|
2021-07-10 01:48:00 +02:00
|
|
|
int interactIndex = 0;
|
2022-04-18 01:28:23 +02:00
|
|
|
for (final UUID uuid : stage.getNpcsToInteract()) {
|
2021-07-10 01:48:00 +02:00
|
|
|
boolean interacted = false;
|
2022-04-18 01:28:23 +02:00
|
|
|
if (data.npcsInteracted.size() > interactIndex) {
|
|
|
|
interacted = data.npcsInteracted.get(interactIndex);
|
2021-05-13 10:19:18 +02:00
|
|
|
}
|
2021-07-10 01:48:00 +02:00
|
|
|
final ChatColor color = !interacted ? ChatColor.GREEN : ChatColor.GRAY;
|
|
|
|
String message = color + "- " + Lang.get(quester.getPlayer(), "talkTo")
|
2022-04-18 01:28:23 +02:00
|
|
|
.replace("<npc>", depends.getNPCName(uuid));
|
2021-07-10 01:48:00 +02:00
|
|
|
if (depends.getPlaceholderApi() != null) {
|
|
|
|
message = PlaceholderAPI.setPlaceholders(quester.getPlayer(), message);
|
|
|
|
}
|
|
|
|
quester.sendMessage(message);
|
|
|
|
interactIndex++;
|
2021-05-13 10:19:18 +02:00
|
|
|
}
|
2021-07-10 01:48:00 +02:00
|
|
|
int npcKillIndex = 0;
|
2022-04-18 01:28:23 +02:00
|
|
|
for (final UUID uuid : stage.getNpcsToKill()) {
|
2021-07-10 01:48:00 +02:00
|
|
|
int npcKilled = 0;
|
2022-04-18 01:28:23 +02:00
|
|
|
if (data.npcsNumKilled.size() > npcKillIndex) {
|
|
|
|
npcKilled = data.npcsNumKilled.get(npcKillIndex);
|
2021-07-10 01:48:00 +02:00
|
|
|
}
|
2022-04-18 01:28:23 +02:00
|
|
|
final int toNpcKill = stage.getNpcNumToKill().get(npcKillIndex);
|
2021-07-10 01:48:00 +02:00
|
|
|
final ChatColor color = npcKilled < toNpcKill ? ChatColor.GREEN : ChatColor.GRAY;
|
|
|
|
String message = color + "- " + Lang.get(quester.getPlayer(), "kill");
|
|
|
|
if (message.contains("<mob>")) {
|
2022-04-18 01:28:23 +02:00
|
|
|
message = message.replace("<mob>", depends.getNPCName(uuid));
|
2021-07-10 01:48:00 +02:00
|
|
|
} else {
|
2022-04-18 01:28:23 +02:00
|
|
|
message += " " + depends.getNPCName(uuid);
|
2021-05-13 10:19:18 +02:00
|
|
|
}
|
2020-12-15 06:22:55 +01:00
|
|
|
if (message.contains("<count>")) {
|
2021-07-10 01:48:00 +02:00
|
|
|
message = message.replace("<count>", "" + color + npcKilled + "/" + toNpcKill);
|
2020-12-15 06:22:55 +01:00
|
|
|
} else {
|
2021-01-03 09:00:00 +01:00
|
|
|
// Legacy
|
2021-07-10 01:48:00 +02:00
|
|
|
message += color + ": " + npcKilled + "/" + toNpcKill;
|
2020-12-15 06:22:55 +01:00
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
if (depends.getPlaceholderApi() != null) {
|
|
|
|
message = PlaceholderAPI.setPlaceholders(quester.getPlayer(), message);
|
|
|
|
}
|
2021-01-09 07:55:31 +01:00
|
|
|
quester.sendMessage(message);
|
2021-07-10 01:48:00 +02:00
|
|
|
npcKillIndex++;
|
|
|
|
}
|
|
|
|
int mobKillIndex = 0;
|
2022-01-12 21:10:01 +01:00
|
|
|
for (final EntityType e : stage.getMobsToKill()) {
|
2021-07-10 01:48:00 +02:00
|
|
|
int mobKilled = 0;
|
|
|
|
if (data.mobNumKilled.size() > mobKillIndex) {
|
|
|
|
mobKilled = data.mobNumKilled.get(mobKillIndex);
|
|
|
|
}
|
2022-01-12 21:10:01 +01:00
|
|
|
final int toMobKill = stage.getMobNumToKill().get(mobKillIndex);
|
2021-07-10 01:48:00 +02:00
|
|
|
final ChatColor color = mobKilled < toMobKill ? ChatColor.GREEN : ChatColor.GRAY;
|
|
|
|
String message = color + "- ";
|
2022-01-12 21:10:01 +01:00
|
|
|
if (stage.getLocationsToKillWithin().isEmpty()) {
|
2021-07-10 01:48:00 +02:00
|
|
|
message += Lang.get(quester.getPlayer(), "kill");
|
|
|
|
if (message.contains("<count>")) {
|
|
|
|
message = message.replace("<count>", "" + color + mobKilled + "/" + toMobKill);
|
|
|
|
} else {
|
|
|
|
// Legacy
|
|
|
|
message += ChatColor.AQUA + " <mob>" + color + ": " + mobKilled + "/" + toMobKill;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
message += Lang.get(quester.getPlayer(), "killAtLocation").replace("<location>",
|
2022-01-12 21:10:01 +01:00
|
|
|
stage.getKillNames().get(stage.getMobsToKill().indexOf(e)));
|
2021-07-10 01:48:00 +02:00
|
|
|
if (message.contains("<count>")) {
|
|
|
|
message = message.replace("<count>", "" + color + mobKilled + "/" + toMobKill);
|
|
|
|
} else {
|
|
|
|
message += color + ": " + mobKilled + "/" + toMobKill;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (depends.getPlaceholderApi() != null) {
|
|
|
|
message = PlaceholderAPI.setPlaceholders(quester.getPlayer(), message);
|
|
|
|
}
|
|
|
|
if (getSettings().canTranslateNames()) {
|
|
|
|
localeManager.sendMessage(quester.getPlayer(), message, e, null);
|
|
|
|
} else {
|
|
|
|
quester.sendMessage(message.replace("<mob>", MiscUtil.getProperMobName(e)));
|
|
|
|
}
|
|
|
|
mobKillIndex++;
|
|
|
|
}
|
|
|
|
int tameIndex = 0;
|
2022-01-12 21:10:01 +01:00
|
|
|
for (final int toTame : stage.getMobNumToTame()) {
|
2021-07-10 01:48:00 +02:00
|
|
|
int tamed = 0;
|
|
|
|
if (data.mobsTamed.size() > tameIndex) {
|
|
|
|
tamed = data.mobsTamed.get(tameIndex);
|
|
|
|
}
|
|
|
|
final ChatColor color = tamed < toTame ? ChatColor.GREEN : ChatColor.GRAY;
|
|
|
|
String message = color + "- " + Lang.get(quester.getPlayer(), "tame");
|
|
|
|
if (!message.contains("<mob>")) {
|
|
|
|
message += " <mob>";
|
|
|
|
}
|
|
|
|
if (message.contains("<count>")) {
|
|
|
|
message = message.replace("<count>", "" + color + tamed + "/" + toTame);
|
|
|
|
} else {
|
|
|
|
// Legacy
|
|
|
|
message += color + ": " + tamed + "/" + toTame;
|
|
|
|
}
|
|
|
|
if (getSettings().canTranslateNames()) {
|
2022-01-12 21:10:01 +01:00
|
|
|
localeManager.sendMessage(quester.getPlayer(), message, stage.getMobsToTame().get(tameIndex), null);
|
2021-07-10 01:48:00 +02:00
|
|
|
} else {
|
|
|
|
quester.sendMessage(message.replace("<mob>",
|
2022-01-12 21:10:01 +01:00
|
|
|
MiscUtil.getProperMobName(stage.getMobsToTame().get(tameIndex))));
|
2021-07-10 01:48:00 +02:00
|
|
|
}
|
|
|
|
tameIndex++;
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2022-01-12 21:10:01 +01:00
|
|
|
if (stage.getFishToCatch() != null) {
|
|
|
|
final ChatColor color = data.getFishCaught() < stage.getFishToCatch() ? ChatColor.GREEN : ChatColor.GRAY;
|
2021-01-09 07:55:31 +01:00
|
|
|
String message = color + "- " + Lang.get(quester.getPlayer(), "catchFish");
|
2020-12-15 06:22:55 +01:00
|
|
|
if (message.contains("<count>")) {
|
2022-01-12 21:10:01 +01:00
|
|
|
message = message.replace("<count>", "" + color + data.getFishCaught() + "/" + stage.getFishToCatch());
|
2020-12-15 06:22:55 +01:00
|
|
|
} else {
|
2021-01-03 09:00:00 +01:00
|
|
|
// Legacy
|
2022-01-12 21:10:01 +01:00
|
|
|
message += color + ": " + data.getFishCaught() + "/" + stage.getFishToCatch();
|
2020-12-15 06:22:55 +01:00
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
if (depends.getPlaceholderApi() != null) {
|
|
|
|
message = PlaceholderAPI.setPlaceholders(quester.getPlayer(), message);
|
|
|
|
}
|
2021-01-09 07:55:31 +01:00
|
|
|
quester.sendMessage(message);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2022-01-12 21:10:01 +01:00
|
|
|
if (stage.getCowsToMilk() != null) {
|
|
|
|
final ChatColor color = data.getCowsMilked() < stage.getCowsToMilk() ? ChatColor.GREEN : ChatColor.GRAY;
|
2021-07-10 01:48:00 +02:00
|
|
|
String message = color + "- " + Lang.get(quester.getPlayer(), "milkCow");
|
|
|
|
if (message.contains("<count>")) {
|
2022-01-12 21:10:01 +01:00
|
|
|
message = message.replace("<count>", "" + color + data.getCowsMilked() + "/" + stage.getCowsToMilk());
|
2021-07-10 01:48:00 +02:00
|
|
|
} else {
|
|
|
|
// Legacy
|
2022-01-12 21:10:01 +01:00
|
|
|
message += color + ": " + data.getCowsMilked() + "/" + stage.getCowsToMilk();
|
2021-07-10 01:48:00 +02:00
|
|
|
}
|
|
|
|
if (depends.getPlaceholderApi() != null) {
|
|
|
|
message = PlaceholderAPI.setPlaceholders(quester.getPlayer(), message);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-07-10 01:48:00 +02:00
|
|
|
quester.sendMessage(message);
|
|
|
|
}
|
|
|
|
int shearIndex = 0;
|
2022-01-12 21:10:01 +01:00
|
|
|
for (final int toShear : stage.getSheepNumToShear()) {
|
2021-07-10 01:48:00 +02:00
|
|
|
int sheared = 0;
|
|
|
|
if (data.sheepSheared.size() > shearIndex) {
|
|
|
|
sheared = data.sheepSheared.get(shearIndex);
|
|
|
|
}
|
|
|
|
final ChatColor color = sheared < toShear ? ChatColor.GREEN : ChatColor.GRAY;
|
|
|
|
String message = color + "- " + Lang.get(quester.getPlayer(), "shearSheep");
|
2022-01-12 21:10:01 +01:00
|
|
|
message = message.replace("<color>", MiscUtil.getPrettyDyeColorName(stage.getSheepToShear()
|
|
|
|
.get(shearIndex)));
|
2021-07-10 01:48:00 +02:00
|
|
|
if (message.contains("<count>")) {
|
|
|
|
message = message.replace("<count>", "" + color + sheared + "/" + toShear);
|
|
|
|
} else {
|
|
|
|
// Legacy
|
|
|
|
message += color + ": " + sheared + "/" + toShear;
|
|
|
|
}
|
|
|
|
quester.sendMessage(message);
|
|
|
|
shearIndex++;
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2022-01-12 21:10:01 +01:00
|
|
|
if (stage.getPlayersToKill() != null) {
|
|
|
|
final ChatColor color = data.getPlayersKilled() < stage.getPlayersToKill() ? ChatColor.GREEN
|
|
|
|
: ChatColor.GRAY;
|
2021-01-09 07:55:31 +01:00
|
|
|
String message = color + "- " + Lang.get(quester.getPlayer(), "killPlayer");
|
2020-12-15 06:22:55 +01:00
|
|
|
if (message.contains("<count>")) {
|
2022-01-12 21:10:01 +01:00
|
|
|
message = message.replace("<count>", "" + color + data.getPlayersKilled() + "/"
|
|
|
|
+ stage.getPlayersToKill());
|
2020-12-15 06:22:55 +01:00
|
|
|
} else {
|
2021-01-03 09:00:00 +01:00
|
|
|
// Legacy
|
2022-01-12 21:10:01 +01:00
|
|
|
message += color + ": " + data.getPlayersKilled() + "/" + stage.getPlayersToKill();
|
2020-12-15 06:22:55 +01:00
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
if (depends.getPlaceholderApi() != null) {
|
|
|
|
message = PlaceholderAPI.setPlaceholders(quester.getPlayer(), message);
|
|
|
|
}
|
2021-01-09 07:55:31 +01:00
|
|
|
quester.sendMessage(message);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2022-01-12 21:10:01 +01:00
|
|
|
for (int i = 0 ; i < stage.getLocationsToReach().size(); i++) {
|
2021-07-10 01:48:00 +02:00
|
|
|
if (i < data.locationsReached.size()) {
|
|
|
|
final ChatColor color = !data.locationsReached.get(i) ? ChatColor.GREEN : ChatColor.GRAY;
|
2022-05-04 12:16:25 +02:00
|
|
|
String message = color + "- " + Lang.get(quester.getPlayer(), "goTo");
|
2022-01-12 21:10:01 +01:00
|
|
|
message = message.replace("<location>", stage.getLocationNames().get(i));
|
2021-06-04 12:21:50 +02:00
|
|
|
quester.sendMessage(message);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
2021-07-10 01:48:00 +02:00
|
|
|
int passIndex = 0;
|
2022-01-12 21:10:01 +01:00
|
|
|
for (final String s : stage.getPasswordDisplays()) {
|
2021-07-10 01:48:00 +02:00
|
|
|
boolean said = false;
|
|
|
|
if (data.passwordsSaid.size() > passIndex) {
|
|
|
|
said = data.passwordsSaid.get(passIndex);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-07-10 01:48:00 +02:00
|
|
|
final ChatColor color = !said ? ChatColor.GREEN : ChatColor.GRAY;
|
|
|
|
final String message = color + "- " + s;
|
|
|
|
quester.sendMessage(message);
|
|
|
|
passIndex++;
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-07-10 01:48:00 +02:00
|
|
|
int customIndex = 0;
|
2022-01-19 03:15:49 +01:00
|
|
|
for (final ICustomObjective co : stage.getCustomObjectives()) {
|
2021-07-10 01:48:00 +02:00
|
|
|
int cleared = 0;
|
|
|
|
if (data.customObjectiveCounts.size() > customIndex) {
|
2021-07-27 06:36:56 +02:00
|
|
|
cleared = data.customObjectiveCounts.get(customIndex);
|
2021-07-10 01:48:00 +02:00
|
|
|
}
|
2022-01-12 21:10:01 +01:00
|
|
|
final int toClear = stage.getCustomObjectiveCounts().get(customIndex);
|
2021-07-10 01:48:00 +02:00
|
|
|
final ChatColor color = cleared < toClear ? ChatColor.GREEN : ChatColor.GRAY;
|
|
|
|
String message = color + "- " + co.getDisplay();
|
|
|
|
for (final Entry<String,Object> prompt : co.getData()) {
|
|
|
|
final String replacement = "%" + prompt.getKey() + "%";
|
|
|
|
try {
|
2022-01-12 21:10:01 +01:00
|
|
|
for (final Entry<String, Object> e : stage.getCustomObjectiveData()) {
|
2021-07-10 01:48:00 +02:00
|
|
|
if (e.getKey().equals(prompt.getKey())) {
|
|
|
|
if (message.contains(replacement)) {
|
|
|
|
message = message.replace(replacement, ((String) e.getValue()));
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-07-10 01:48:00 +02:00
|
|
|
} catch (final NullPointerException ne) {
|
|
|
|
getLogger().severe("Unable to fetch display for " + co.getName() + " on "
|
|
|
|
+ quest.getName());
|
|
|
|
ne.printStackTrace();
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
2021-07-10 01:48:00 +02:00
|
|
|
if (co.canShowCount()) {
|
|
|
|
message = message.replace("%count%", cleared + "/" + toClear);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-09-07 20:51:36 +02:00
|
|
|
quester.sendMessage(ConfigUtil.parseString(message));
|
2021-07-10 01:48:00 +02:00
|
|
|
customIndex++;
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-04-27 11:24:27 +02:00
|
|
|
* Show the player a list of their available quests
|
2020-04-16 01:18:06 +02:00
|
|
|
*
|
|
|
|
* @param quester Quester to show the list
|
|
|
|
* @param page Page to display, with 7 quests per page
|
|
|
|
*/
|
2022-01-19 03:15:49 +01:00
|
|
|
public void listQuests(final IQuester quester, final int page) {
|
2020-04-16 01:18:06 +02:00
|
|
|
// Although we could copy the quests list to a new object, we instead opt to
|
|
|
|
// duplicate code to improve efficiency if ignore-locked-quests is set to 'false'
|
2020-08-06 11:32:43 +02:00
|
|
|
final int rows = 7;
|
|
|
|
final Player player = quester.getPlayer();
|
2020-04-16 01:18:06 +02:00
|
|
|
if (getSettings().canIgnoreLockedQuests()) {
|
2022-01-19 03:15:49 +01:00
|
|
|
final LinkedList<IQuest> available = new LinkedList<>();
|
|
|
|
for (final IQuest q : quests) {
|
2022-02-04 12:41:23 +01:00
|
|
|
if (!quester.getCompletedQuestsTemp().contains(q)) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (q.testRequirements(player)) {
|
|
|
|
available.add(q);
|
|
|
|
}
|
2020-07-24 11:03:53 +02:00
|
|
|
} else if (q.getPlanner().hasCooldown() && quester.getRemainingCooldown(q) < 0) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (q.testRequirements(player)) {
|
|
|
|
available.add(q);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((available.size() + rows) <= (page * rows) || available.size() == 0) {
|
2021-07-11 11:06:13 +02:00
|
|
|
Lang.send(player, ChatColor.YELLOW + Lang.get(player, "pageNotExist"));
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
2021-07-11 11:06:13 +02:00
|
|
|
Lang.send(player, ChatColor.GOLD + Lang.get(player, "questListTitle"));
|
2020-04-16 01:18:06 +02:00
|
|
|
int fromOrder = (page - 1) * rows;
|
2022-01-19 03:15:49 +01:00
|
|
|
final List<IQuest> subQuests;
|
2020-04-16 01:18:06 +02:00
|
|
|
if (available.size() >= (fromOrder + rows)) {
|
|
|
|
subQuests = available.subList((fromOrder), (fromOrder + rows));
|
|
|
|
} else {
|
|
|
|
subQuests = available.subList((fromOrder), available.size());
|
|
|
|
}
|
|
|
|
fromOrder++;
|
2022-01-19 03:15:49 +01:00
|
|
|
for (final IQuest q : subQuests) {
|
2020-09-28 21:39:32 +02:00
|
|
|
if (quester.canAcceptOffer(q, false)) {
|
2021-01-09 07:55:31 +01:00
|
|
|
quester.sendMessage(ChatColor.YELLOW + Integer.toString(fromOrder) + ". " + q.getName());
|
2020-09-28 21:39:32 +02:00
|
|
|
} else {
|
2021-01-09 07:55:31 +01:00
|
|
|
quester.sendMessage(ChatColor.GRAY + Integer.toString(fromOrder) + ". " + q.getName());
|
2020-09-28 21:39:32 +02:00
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
fromOrder++;
|
|
|
|
}
|
2020-08-06 11:32:43 +02:00
|
|
|
final int numPages = (int) Math.ceil(((double) available.size()) / ((double) rows));
|
2020-04-16 01:18:06 +02:00
|
|
|
String msg = Lang.get(player, "pageFooter");
|
|
|
|
msg = msg.replace("<current>", String.valueOf(page));
|
|
|
|
msg = msg.replace("<all>", String.valueOf(numPages));
|
2021-07-11 11:06:13 +02:00
|
|
|
Lang.send(player, ChatColor.GOLD + msg);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ((quests.size() + rows) <= (page * rows) || quests.size() == 0) {
|
2021-07-11 11:06:13 +02:00
|
|
|
Lang.send(player, ChatColor.YELLOW + Lang.get(player, "pageNotExist"));
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
2021-07-11 11:06:13 +02:00
|
|
|
Lang.send(player, ChatColor.GOLD + Lang.get(player, "questListTitle"));
|
2020-04-16 01:18:06 +02:00
|
|
|
int fromOrder = (page - 1) * rows;
|
2022-01-19 03:15:49 +01:00
|
|
|
final List<IQuest> subQuests;
|
2020-04-16 01:18:06 +02:00
|
|
|
if (quests.size() >= (fromOrder + rows)) {
|
2022-01-13 17:02:43 +01:00
|
|
|
subQuests = new LinkedList<>(getLoadedQuests()).subList((fromOrder), (fromOrder + rows));
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
2022-01-13 17:02:43 +01:00
|
|
|
subQuests = new LinkedList<>(getLoadedQuests()).subList((fromOrder), quests.size());
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
fromOrder++;
|
2022-01-19 03:15:49 +01:00
|
|
|
for (final IQuest q : subQuests) {
|
2020-09-28 21:39:32 +02:00
|
|
|
if (quester.canAcceptOffer(q, false)) {
|
2021-07-11 11:06:13 +02:00
|
|
|
Lang.send(player, ChatColor.YELLOW + Integer.toString(fromOrder) + ". " + q.getName());
|
2020-09-28 21:39:32 +02:00
|
|
|
} else {
|
2021-07-11 11:06:13 +02:00
|
|
|
Lang.send(player, ChatColor.GRAY + Integer.toString(fromOrder) + ". " + q.getName());
|
2020-09-28 21:39:32 +02:00
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
fromOrder++;
|
|
|
|
}
|
2020-08-06 11:32:43 +02:00
|
|
|
final int numPages = (int) Math.ceil(((double) quests.size()) / ((double) rows));
|
2020-04-16 01:18:06 +02:00
|
|
|
String msg = Lang.get(player, "pageFooter");
|
|
|
|
msg = msg.replace("<current>", String.valueOf(page));
|
|
|
|
msg = msg.replace("<all>", String.valueOf(numPages));
|
2021-07-11 11:06:13 +02:00
|
|
|
Lang.send(player, ChatColor.GOLD + msg);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-07-09 09:05:56 +02:00
|
|
|
* Reload quests, actions, conditions, config settings, lang, modules, and player data
|
2020-04-16 01:18:06 +02:00
|
|
|
*/
|
|
|
|
public void reload(final ReloadCallback<Boolean> callback) {
|
2022-01-04 10:51:14 +01:00
|
|
|
if (loading) {
|
|
|
|
getLogger().warning(ChatColor.YELLOW + Lang.get("errorLoading"));
|
|
|
|
return;
|
|
|
|
}
|
2020-11-18 20:29:43 +01:00
|
|
|
loading = true;
|
2020-04-16 01:18:06 +02:00
|
|
|
reloadConfig();
|
2021-08-19 15:43:48 +02:00
|
|
|
Bukkit.getScheduler().runTaskAsynchronously(this, () -> {
|
|
|
|
try {
|
2022-09-01 02:57:34 +02:00
|
|
|
getStorage().saveOfflineQuesters().get();
|
2021-08-19 15:43:48 +02:00
|
|
|
Lang.clear();
|
|
|
|
settings.init();
|
2022-06-13 09:25:05 +02:00
|
|
|
Lang.init(Quests.this, settings.getLanguage());
|
2021-08-19 15:43:48 +02:00
|
|
|
quests.clear();
|
|
|
|
actions.clear();
|
|
|
|
conditions.clear();
|
|
|
|
loadQuests();
|
|
|
|
loadActions();
|
|
|
|
loadConditions();
|
2022-09-01 02:57:34 +02:00
|
|
|
for (final IQuester quester : questers) {
|
|
|
|
final IQuester loaded = getStorage().loadQuester(quester.getUUID()).get();
|
|
|
|
for (final IQuest quest : loaded.getCurrentQuestsTemp().keySet()) {
|
|
|
|
loaded.checkQuest(quest);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2022-09-01 02:57:34 +02:00
|
|
|
}
|
|
|
|
loadModules();
|
|
|
|
importQuests();
|
|
|
|
finishLoading(callback, true, null);
|
2021-08-19 15:43:48 +02:00
|
|
|
} catch (final Exception e) {
|
2022-01-04 10:51:14 +01:00
|
|
|
finishLoading(callback, false, e);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
loading = false;
|
2020-04-16 01:18:06 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-01-04 10:51:14 +01:00
|
|
|
/**
|
|
|
|
* Execute finishing task and print provided exception
|
|
|
|
*
|
|
|
|
* @param callback Callback to execute
|
|
|
|
* @param result Result to pass through callback
|
|
|
|
* @param exception Exception to print, or null
|
|
|
|
*/
|
|
|
|
private void finishLoading(final ReloadCallback<Boolean> callback, boolean result, final Exception exception) {
|
|
|
|
if (exception != null) {
|
|
|
|
exception.printStackTrace();
|
|
|
|
}
|
|
|
|
if (callback != null) {
|
|
|
|
Bukkit.getScheduler().runTask(Quests.this, () -> {
|
|
|
|
loading = false;
|
|
|
|
callback.execute(result);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-16 01:18:06 +02:00
|
|
|
/**
|
|
|
|
* Load quests from file
|
|
|
|
*/
|
|
|
|
public void loadQuests() {
|
|
|
|
boolean needsSaving = false;
|
|
|
|
FileConfiguration config = null;
|
2020-08-06 11:32:43 +02:00
|
|
|
final File file = new File(this.getDataFolder(), "quests.yml");
|
2020-04-16 01:18:06 +02:00
|
|
|
try {
|
2021-08-19 15:43:48 +02:00
|
|
|
config = YamlConfiguration.loadConfiguration(new InputStreamReader(new FileInputStream(file),
|
|
|
|
StandardCharsets.UTF_8));
|
2020-08-06 11:32:43 +02:00
|
|
|
} catch (final IOException e) {
|
2020-04-16 01:18:06 +02:00
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
if (config != null) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final ConfigurationSection questsSection;
|
2020-04-16 01:18:06 +02:00
|
|
|
if (config.contains("quests")) {
|
|
|
|
questsSection = config.getConfigurationSection("quests");
|
|
|
|
} else {
|
|
|
|
questsSection = config.createSection("quests");
|
|
|
|
needsSaving = true;
|
|
|
|
}
|
|
|
|
if (questsSection == null) {
|
2021-07-10 01:48:00 +02:00
|
|
|
getLogger().severe("Missing 'quests' section marker within quests.yml, canceled loading");
|
2020-04-16 01:18:06 +02:00
|
|
|
return;
|
|
|
|
}
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final String questKey : questsSection.getKeys(false)) {
|
2020-04-16 01:18:06 +02:00
|
|
|
try {
|
2022-01-19 03:15:49 +01:00
|
|
|
final IQuest quest = loadQuest(config, questKey);
|
2020-04-16 01:18:06 +02:00
|
|
|
if (config.contains("quests." + questKey + ".requirements")) {
|
|
|
|
loadQuestRequirements(config, questsSection, quest, questKey);
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".planner")) {
|
2021-08-19 15:43:48 +02:00
|
|
|
loadQuestPlanner(config, quest, questKey);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".options")) {
|
2021-08-19 15:43:48 +02:00
|
|
|
loadQuestOptions(config, quest, questKey);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2022-01-12 21:10:01 +01:00
|
|
|
quest.setPlugin(this);
|
2020-04-16 01:18:06 +02:00
|
|
|
loadQuestStages(quest, config, questKey);
|
|
|
|
loadQuestRewards(config, quest, questKey);
|
|
|
|
quests.add(quest);
|
|
|
|
if (needsSaving) {
|
|
|
|
try {
|
|
|
|
config.save(file);
|
2020-08-06 11:32:43 +02:00
|
|
|
} catch (final IOException e) {
|
2020-04-16 01:18:06 +02:00
|
|
|
getLogger().log(Level.SEVERE, "Failed to save Quest \"" + questKey + "\"");
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
} catch (final QuestFormatException | StageFormatException | ActionFormatException
|
|
|
|
| ConditionFormatException e) {
|
2020-07-13 06:35:28 +02:00
|
|
|
e.printStackTrace();
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
getLogger().severe("Unable to load quests.yml");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-19 15:43:48 +02:00
|
|
|
@SuppressWarnings("deprecation")
|
2022-01-19 03:15:49 +01:00
|
|
|
private IQuest loadQuest(final FileConfiguration config, final String questKey) throws QuestFormatException,
|
2020-12-30 09:50:17 +01:00
|
|
|
ActionFormatException {
|
2022-01-19 03:15:49 +01:00
|
|
|
final IQuest quest = new Quest(this);
|
2022-01-12 21:10:01 +01:00
|
|
|
quest.setId(questKey);
|
2020-12-30 09:50:17 +01:00
|
|
|
if (config.contains("quests." + questKey + ".name")) {
|
|
|
|
quest.setName(ConfigUtil.parseString(config.getString("quests." + questKey + ".name"), quest));
|
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("name is missing", questKey);
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".ask-message")) {
|
2022-01-12 21:10:01 +01:00
|
|
|
quest.setDescription(ConfigUtil.parseString(config.getString("quests." + questKey
|
|
|
|
+ ".ask-message"), quest));
|
2020-12-30 09:50:17 +01:00
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("ask-message is missing", questKey);
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".finish-message")) {
|
2022-01-12 21:10:01 +01:00
|
|
|
quest.setFinished(ConfigUtil.parseString(config.getString("quests." + questKey
|
|
|
|
+ ".finish-message"), quest));
|
2020-12-30 09:50:17 +01:00
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("finish-message is missing", questKey);
|
|
|
|
}
|
2022-06-04 09:47:44 +02:00
|
|
|
if (config.contains("quests." + questKey + ".npc-giver-uuid")) {
|
2022-04-18 01:28:23 +02:00
|
|
|
final UUID uuid = UUID.fromString(Objects.requireNonNull(config.getString("quests." + questKey
|
|
|
|
+ ".npc-giver-uuid")));
|
2022-06-04 09:47:44 +02:00
|
|
|
quest.setNpcStart(uuid);
|
|
|
|
questNpcUuids.add(uuid);
|
2022-04-18 01:28:23 +02:00
|
|
|
} else if (depends.getCitizens() != null && config.contains("quests." + questKey + ".npc-giver-id")) {
|
|
|
|
// Legacy
|
2022-04-26 22:57:47 +02:00
|
|
|
final int id = config.getInt("quests." + questKey + ".npc-giver-id");
|
|
|
|
if (CitizensAPI.getNPCRegistry().getById(id) != null) {
|
2022-05-15 19:11:37 +02:00
|
|
|
final NPC npc = CitizensAPI.getNPCRegistry().getById(id);
|
2022-06-04 09:47:44 +02:00
|
|
|
quest.setNpcStart(npc.getUniqueId());
|
2022-05-15 19:11:37 +02:00
|
|
|
questNpcUuids.add(npc.getUniqueId());
|
2020-12-30 09:50:17 +01:00
|
|
|
} else {
|
2022-04-26 22:57:47 +02:00
|
|
|
throw new QuestFormatException("npc-giver-id has invalid NPC ID " + id, questKey);
|
2020-12-30 09:50:17 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".block-start")) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final String blockStart = config.getString("quests." + questKey + ".block-start");
|
|
|
|
if (blockStart != null) {
|
|
|
|
final Location location = ConfigUtil.getLocation(blockStart);
|
|
|
|
if (location != null) {
|
2022-01-12 21:10:01 +01:00
|
|
|
quest.setBlockStart(location);
|
2021-08-19 15:43:48 +02:00
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("block-start has invalid location", questKey);
|
|
|
|
}
|
2020-12-30 09:50:17 +01:00
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("block-start has invalid location format", questKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".region")
|
|
|
|
&& getDependencies().getWorldGuardApi() != null) {
|
|
|
|
final String region = config.getString("quests." + questKey + ".region");
|
2021-08-19 15:43:48 +02:00
|
|
|
if (region != null) {
|
|
|
|
boolean exists = false;
|
|
|
|
for (final World world : getServer().getWorlds()) {
|
|
|
|
if (world != null && getDependencies().getWorldGuardApi().getRegionManager(world) != null) {
|
|
|
|
if (Objects.requireNonNull(getDependencies().getWorldGuardApi().getRegionManager(world))
|
|
|
|
.hasRegion(region)) {
|
2022-01-12 21:10:01 +01:00
|
|
|
quest.setRegionStart(region);
|
2021-08-19 15:43:48 +02:00
|
|
|
exists = true;
|
|
|
|
break;
|
|
|
|
}
|
2020-12-30 09:50:17 +01:00
|
|
|
}
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
if (!exists) {
|
|
|
|
throw new QuestFormatException("region has invalid WorldGuard region name", questKey);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("region has invalid WorldGuard region", questKey);
|
2020-12-30 09:50:17 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".gui-display")) {
|
|
|
|
ItemStack stack = config.getItemStack("quests." + questKey + ".gui-display");
|
|
|
|
if (stack == null) {
|
|
|
|
// Legacy
|
|
|
|
final String item = config.getString("quests." + questKey + ".gui-display");
|
|
|
|
try {
|
|
|
|
stack = ItemUtil.readItemStack(item);
|
|
|
|
} catch (final Exception e) {
|
|
|
|
throw new QuestFormatException("items has invalid formatting for " + item, questKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (stack != null) {
|
2022-01-12 21:10:01 +01:00
|
|
|
quest.setGUIDisplay(stack);
|
2020-12-30 09:50:17 +01:00
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("gui-display has invalid item format", questKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".redo-delay")) {
|
|
|
|
// Legacy
|
|
|
|
if (config.getInt("quests." + questKey + ".redo-delay", -999) != -999) {
|
2021-07-10 01:48:00 +02:00
|
|
|
quest.getPlanner().setCooldown(config.getInt("quests." + questKey + ".redo-delay") * 1000L);
|
2020-12-30 09:50:17 +01:00
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("redo-delay is not a number", questKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".action")) {
|
2022-01-19 03:15:49 +01:00
|
|
|
final IAction action = loadAction(config.getString("quests." + questKey + ".action"));
|
2020-12-30 09:50:17 +01:00
|
|
|
if (action != null) {
|
2022-01-12 21:10:01 +01:00
|
|
|
quest.setInitialAction(action);
|
2020-12-30 09:50:17 +01:00
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("action failed to load", questKey);
|
|
|
|
}
|
|
|
|
} else if (config.contains("quests." + questKey + ".event")) {
|
2022-01-19 03:15:49 +01:00
|
|
|
final IAction action = loadAction(config.getString("quests." + questKey + ".event"));
|
2020-12-30 09:50:17 +01:00
|
|
|
if (action != null) {
|
2022-01-12 21:10:01 +01:00
|
|
|
quest.setInitialAction(action);
|
2020-12-30 09:50:17 +01:00
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("action failed to load", questKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return quest;
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
|
|
|
@SuppressWarnings({"unchecked", "deprecation"})
|
2022-01-19 03:15:49 +01:00
|
|
|
private void loadQuestRewards(final FileConfiguration config, final IQuest quest, final String questKey)
|
2021-08-19 15:43:48 +02:00
|
|
|
throws QuestFormatException {
|
2021-09-06 04:34:05 +02:00
|
|
|
final Rewards rewards = quest.getRewards();
|
2020-04-16 01:18:06 +02:00
|
|
|
if (config.contains("quests." + questKey + ".rewards.items")) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final LinkedList<ItemStack> temp = new LinkedList<>();
|
2020-08-06 11:32:43 +02:00
|
|
|
final List<ItemStack> stackList = (List<ItemStack>) config.get("quests." + questKey + ".rewards.items");
|
2020-04-16 01:18:06 +02:00
|
|
|
if (ConfigUtil.checkList(stackList, ItemStack.class)) {
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final ItemStack stack : stackList) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (stack != null) {
|
|
|
|
temp.add(stack);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Legacy
|
|
|
|
if (ConfigUtil.checkList(stackList, String.class)) {
|
2020-08-06 11:32:43 +02:00
|
|
|
final List<String> items = config.getStringList("quests." + questKey + ".rewards.items");
|
|
|
|
for (final String item : items) {
|
2020-04-16 01:18:06 +02:00
|
|
|
try {
|
2020-08-06 11:32:43 +02:00
|
|
|
final ItemStack stack = ItemUtil.readItemStack(item);
|
2020-04-16 01:18:06 +02:00
|
|
|
if (stack != null) {
|
|
|
|
temp.add(stack);
|
|
|
|
}
|
2020-08-06 11:32:43 +02:00
|
|
|
} catch (final Exception e) {
|
2020-04-16 01:18:06 +02:00
|
|
|
throw new QuestFormatException("Reward items has invalid formatting for " + item, questKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Reward items has invalid formatting", questKey);
|
|
|
|
}
|
|
|
|
}
|
2021-09-06 04:34:05 +02:00
|
|
|
rewards.setItems(temp);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".rewards.money")) {
|
|
|
|
if (config.getInt("quests." + questKey + ".rewards.money", -999) != -999) {
|
2021-09-06 04:34:05 +02:00
|
|
|
rewards.setMoney(config.getInt("quests." + questKey + ".rewards.money"));
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Reward money is not a number", questKey);
|
|
|
|
}
|
|
|
|
}
|
2022-04-12 05:52:07 +02:00
|
|
|
if (config.contains("quests." + questKey + ".rewards.quest-points")) {
|
|
|
|
if (config.getInt("quests." + questKey + ".rewards.quest-points", -999) != -999) {
|
|
|
|
rewards.setQuestPoints(config.getInt("quests." + questKey + ".rewards.quest-points"));
|
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Reward quest-points is not a number", questKey);
|
|
|
|
}
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
if (config.contains("quests." + questKey + ".rewards.exp")) {
|
|
|
|
if (config.getInt("quests." + questKey + ".rewards.exp", -999) != -999) {
|
2021-09-06 04:34:05 +02:00
|
|
|
rewards.setExp(config.getInt("quests." + questKey + ".rewards.exp"));
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Reward exp is not a number", questKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".rewards.commands")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".rewards.commands"), String.class)) {
|
2021-09-06 04:34:05 +02:00
|
|
|
rewards.setCommands(config.getStringList("quests." + questKey + ".rewards.commands"));
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Reward commands is not a list of commands", questKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".rewards.commands-override-display")) {
|
|
|
|
// Legacy
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".rewards.commands-override-display"),
|
|
|
|
String.class)) {
|
2021-09-06 04:34:05 +02:00
|
|
|
rewards.setCommandsOverrideDisplay(config.getStringList("quests." + questKey
|
2020-04-16 01:18:06 +02:00
|
|
|
+ ".rewards.commands-override-display"));
|
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Reward commands-override-display is not a list of strings", questKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".rewards.permissions")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".rewards.permissions"), String.class)) {
|
2021-09-06 04:34:05 +02:00
|
|
|
rewards.setPermissions(config.getStringList("quests." + questKey + ".rewards.permissions"));
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Reward permissions is not a list of permissions", questKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".rewards.permission-worlds")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey
|
|
|
|
+ ".rewards.permission-worlds"), String.class)) {
|
2021-09-06 04:34:05 +02:00
|
|
|
rewards.setPermissionWorlds(config.getStringList("quests." + questKey + ".rewards.permission-worlds"));
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Reward permissions is not a list of worlds", questKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (depends.isPluginAvailable("mcMMO")) {
|
|
|
|
if (config.contains("quests." + questKey + ".rewards.mcmmo-skills")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".rewards.mcmmo-skills"),
|
|
|
|
String.class)) {
|
|
|
|
if (config.contains("quests." + questKey + ".rewards.mcmmo-levels")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".rewards.mcmmo-levels"),
|
|
|
|
Integer.class)) {
|
2021-08-19 15:43:48 +02:00
|
|
|
for (final String skill : config.getStringList("quests." + questKey
|
|
|
|
+ ".rewards.mcmmo-skills")) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (depends.getMcmmoClassic() == null) {
|
|
|
|
throw new QuestFormatException("Reward mcMMO not found for mcmmo-skills", questKey);
|
|
|
|
} else if (Quests.getMcMMOSkill(skill) == null) {
|
2021-08-19 15:43:48 +02:00
|
|
|
throw new QuestFormatException("Reward mcmmo-skills has invalid skill name "
|
|
|
|
+ skill, questKey);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
2021-09-06 04:34:05 +02:00
|
|
|
rewards.setMcmmoSkills(config.getStringList("quests." + questKey
|
|
|
|
+ ".rewards.mcmmo-skills"));
|
|
|
|
rewards.setMcmmoAmounts(config.getIntegerList("quests." + questKey
|
|
|
|
+ ".rewards.mcmmo-levels"));
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Reward mcmmo-levels is not a list of numbers", questKey);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Reward mcmmo-levels is missing!", questKey);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Reward mcmmo-skills is not a list of mcMMO skill names", questKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (depends.isPluginAvailable("Heroes")) {
|
|
|
|
if (config.contains("quests." + questKey + ".rewards.heroes-exp-classes")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".rewards.heroes-exp-classes"),
|
|
|
|
String.class)) {
|
|
|
|
if (config.contains("quests." + questKey + ".rewards.heroes-exp-amounts")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".rewards.heroes-exp-amounts"),
|
|
|
|
Double.class)) {
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final String heroClass : config.getStringList("quests." + questKey
|
2020-04-16 01:18:06 +02:00
|
|
|
+ ".rewards.heroes-exp-classes")) {
|
|
|
|
if (depends.getHeroes() == null) {
|
|
|
|
throw new QuestFormatException("Heroes not found for heroes-exp-classes", questKey);
|
|
|
|
} else if (depends.getHeroes().getClassManager().getClass(heroClass) == null) {
|
|
|
|
throw new QuestFormatException("Reward heroes-exp-classes has invalid class name "
|
|
|
|
+ heroClass, questKey);
|
|
|
|
}
|
|
|
|
}
|
2021-09-06 04:34:05 +02:00
|
|
|
rewards.setHeroesClasses(config.getStringList("quests." + questKey
|
2020-04-16 01:18:06 +02:00
|
|
|
+ ".rewards.heroes-exp-classes"));
|
2021-09-06 04:34:05 +02:00
|
|
|
rewards.setHeroesAmounts(config.getDoubleList("quests." + questKey
|
2020-04-16 01:18:06 +02:00
|
|
|
+ ".rewards.heroes-exp-amounts"));
|
|
|
|
} else {
|
2021-08-19 15:43:48 +02:00
|
|
|
throw new QuestFormatException("Reward heroes-exp-amounts is not a list of decimal numbers",
|
|
|
|
questKey);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Reward heroes-exp-amounts is missing", questKey);
|
|
|
|
}
|
|
|
|
} else {
|
2021-08-19 15:43:48 +02:00
|
|
|
throw new QuestFormatException("Reward heroes-exp-classes is not a list of Heroes classes",
|
|
|
|
questKey);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
Parties 3.0.0 support (#1555)
* Updated Parties support
* Fixed multiplayer everything
* Add missing space for legacy string, fixes #1516
* Address formatting problems in initial menu prompts
* Do not proceed on invalid entity type, fixes #1520
* Click to register NPC listener if Citizens link failed at startup
* Populate objective goals when retrieving fresh quest data, fixes #1515
* Fixed typo in quest points log
* Added new Parties options for offline players and distance
* Added Parties experience reward
* Fix error on last stage completion
* Fixed Parties distance calculation
* Reworked how multiplayer sharing 1 works and require same quest
* Properly store repeat/cooldown values greater than max int, fixes #1523
* New Crowdin updates (#1524)
* New translations strings.yml (Thai)
* New translations strings.yml (Estonian)
* New translations strings.yml (Thai)
* New translations strings.yml (Thai)
* New translations strings.yml (Thai)
* Update quest main prompt strings
* Update quest main prompt strings, part 2
* Update quest main prompt strings, part 3
* New Crowdin updates (#1525)
* New translations strings.yml (Pirate English)
* New translations strings.yml (Hindi)
* New translations strings.yml (Serbian (Latin))
* New translations strings.yml (Estonian)
* New translations strings.yml (Norwegian Bokmal)
* New translations strings.yml (English)
* New translations strings.yml (Arabic)
* New translations strings.yml (Serbian (Cyrillic))
* New translations strings.yml (Sinhala)
* New translations strings.yml (Pirate English)
* New translations strings.yml (Hindi)
* New translations strings.yml (Serbian (Latin))
* New translations strings.yml (Estonian)
* New translations strings.yml (Norwegian Bokmal)
* New translations strings.yml (English)
* New translations strings.yml (Arabic)
* New translations strings.yml (Serbian (Cyrillic))
* New translations strings.yml (Sinhala)
* Update README.md
* NEW load shared quests to memory via /import folder
* Provide additional context for failed requirement quests, fixes #1530
* Use quest IDs instead of names for YAML implementation of quester data
* Remove initial action from main quests prompt, functional as legacy only
* New Crowdin updates (#1533)
* New translations strings.yml (Polish)
* New translations strings.yml (Pirate English)
* New translations strings.yml (Vietnamese)
* New translations strings.yml (Portuguese, Brazilian)
* New translations strings.yml (Indonesian)
* New translations strings.yml (Thai)
* New translations strings.yml (Croatian)
* New translations strings.yml (Hindi)
* New translations strings.yml (Filipino)
* New translations strings.yml (Chinese Simplified)
* New translations strings.yml (Serbian (Latin))
* New translations strings.yml (LOLCAT)
* New translations strings.yml (Spanish)
* New translations strings.yml (Chinese Traditional)
* New translations strings.yml (Estonian)
* New translations strings.yml (Norwegian Bokmal)
* New translations strings.yml (English)
* New translations strings.yml (Turkish)
* New translations strings.yml (Romanian)
* New translations strings.yml (Hungarian)
* New translations strings.yml (French)
* New translations strings.yml (Arabic)
* New translations strings.yml (Czech)
* New translations strings.yml (Danish)
* New translations strings.yml (German)
* New translations strings.yml (Finnish)
* New translations strings.yml (Italian)
* New translations strings.yml (Swedish)
* New translations strings.yml (Japanese)
* New translations strings.yml (Korean)
* New translations strings.yml (Dutch)
* New translations strings.yml (Portuguese)
* New translations strings.yml (Russian)
* New translations strings.yml (Serbian (Cyrillic))
* New translations strings.yml (Sinhala)
* New translations strings.yml (English)
* New translations strings.yml (Pirate English)
* Call password objective event on sync to prevent exception
* Address certain objectives not progressing, fixes #1535
* Update quest completion messages to adhere to modern strings
* Correct erroneous enchantment string functionality, fixes #1538
* New Crowdin updates (#1543)
* New translations strings.yml (Thai)
* New translations strings.yml (Croatian)
* New translations strings.yml (Hindi)
* New translations strings.yml (Serbian (Latin))
* New translations strings.yml (Estonian)
* New translations strings.yml (Norwegian Bokmal)
* New translations strings.yml (Romanian)
* New translations strings.yml (Arabic)
* New translations strings.yml (Finnish)
* New translations strings.yml (Swedish)
* New translations strings.yml (Japanese)
* New translations strings.yml (Portuguese)
* New translations strings.yml (Serbian (Cyrillic))
* New translations strings.yml (Sinhala)
* New Crowdin updates (#1544)
* New translations strings.yml (Polish)
* New translations strings.yml (Pirate English)
* New translations strings.yml (Vietnamese)
* New translations strings.yml (Portuguese, Brazilian)
* New translations strings.yml (Indonesian)
* New translations strings.yml (Filipino)
* New translations strings.yml (Chinese Simplified)
* New translations strings.yml (LOLCAT)
* New translations strings.yml (Spanish)
* New translations strings.yml (Chinese Traditional)
* New translations strings.yml (English)
* New translations strings.yml (Turkish)
* New translations strings.yml (Hungarian)
* New translations strings.yml (French)
* New translations strings.yml (Czech)
* New translations strings.yml (Danish)
* New translations strings.yml (German)
* New translations strings.yml (Italian)
* New translations strings.yml (Korean)
* New translations strings.yml (Dutch)
* New translations strings.yml (Russian)
* Bump version
* Add missing disable-command-feedback config check (#1547)
* Translate quest item reward name if applicable, fixes #1548
* Prevent sending of most empty quester strings, fixes #1545
* New Crowdin updates (#1551)
* New translations strings.yml (Polish)
* New translations strings.yml (Pirate English)
* New translations strings.yml (Vietnamese)
* New translations strings.yml (Portuguese, Brazilian)
* New translations strings.yml (Indonesian)
* New translations strings.yml (Thai)
* New translations strings.yml (Croatian)
* New translations strings.yml (Hindi)
* New translations strings.yml (Filipino)
* New translations strings.yml (Chinese Simplified)
* New translations strings.yml (Serbian (Latin))
* New translations strings.yml (LOLCAT)
* New translations strings.yml (Spanish)
* New translations strings.yml (Chinese Traditional)
* New translations strings.yml (Estonian)
* New translations strings.yml (Norwegian Bokmal)
* New translations strings.yml (English)
* New translations strings.yml (Turkish)
* New translations strings.yml (Romanian)
* New translations strings.yml (Hungarian)
* New translations strings.yml (French)
* New translations strings.yml (Arabic)
* New translations strings.yml (Czech)
* New translations strings.yml (Danish)
* New translations strings.yml (German)
* New translations strings.yml (Finnish)
* New translations strings.yml (Italian)
* New translations strings.yml (Swedish)
* New translations strings.yml (Japanese)
* New translations strings.yml (Korean)
* New translations strings.yml (Dutch)
* New translations strings.yml (Portuguese)
* New translations strings.yml (Russian)
* New translations strings.yml (Serbian (Cyrillic))
* New translations strings.yml (Sinhala)
* New translations strings.yml (Polish)
* New translations strings.yml (Vietnamese)
* New translations strings.yml (Portuguese, Brazilian)
* New translations strings.yml (Indonesian)
* New translations strings.yml (Thai)
* New translations strings.yml (Filipino)
* New translations strings.yml (Chinese Simplified)
* New translations strings.yml (LOLCAT)
* New translations strings.yml (Spanish)
* New translations strings.yml (Chinese Traditional)
* New translations strings.yml (Estonian)
* New translations strings.yml (Turkish)
* New translations strings.yml (Hungarian)
* New translations strings.yml (French)
* New translations strings.yml (Czech)
* New translations strings.yml (Danish)
* New translations strings.yml (German)
* New translations strings.yml (Italian)
* New translations strings.yml (Korean)
* New translations strings.yml (Dutch)
* New translations strings.yml (Russian)
* Fixed multiplayer everything
* Reworked how multiplayer sharing 1 works and require same quest
* Updated Parties dependency
* Improved Parties messages on join/leave
* Further fixes about multiplayer sharing
* Wrong method fix
* Fixed documentation about deprecated method
Co-authored-by: PikaMug <2267126+PikaMug@users.noreply.github.com>
Co-authored-by: datatags <datatags@users.noreply.github.com>
2021-01-11 05:15:58 +01:00
|
|
|
if (depends.isPluginAvailable("Parties")) {
|
|
|
|
if (config.contains("quests." + questKey + ".rewards.parties-experience")) {
|
|
|
|
if (config.getInt("quests." + questKey + ".rewards.parties-experience", -999) != -999) {
|
2021-09-06 04:34:05 +02:00
|
|
|
rewards.setPartiesExperience(config.getInt("quests." + questKey + ".rewards.parties-experience"));
|
Parties 3.0.0 support (#1555)
* Updated Parties support
* Fixed multiplayer everything
* Add missing space for legacy string, fixes #1516
* Address formatting problems in initial menu prompts
* Do not proceed on invalid entity type, fixes #1520
* Click to register NPC listener if Citizens link failed at startup
* Populate objective goals when retrieving fresh quest data, fixes #1515
* Fixed typo in quest points log
* Added new Parties options for offline players and distance
* Added Parties experience reward
* Fix error on last stage completion
* Fixed Parties distance calculation
* Reworked how multiplayer sharing 1 works and require same quest
* Properly store repeat/cooldown values greater than max int, fixes #1523
* New Crowdin updates (#1524)
* New translations strings.yml (Thai)
* New translations strings.yml (Estonian)
* New translations strings.yml (Thai)
* New translations strings.yml (Thai)
* New translations strings.yml (Thai)
* Update quest main prompt strings
* Update quest main prompt strings, part 2
* Update quest main prompt strings, part 3
* New Crowdin updates (#1525)
* New translations strings.yml (Pirate English)
* New translations strings.yml (Hindi)
* New translations strings.yml (Serbian (Latin))
* New translations strings.yml (Estonian)
* New translations strings.yml (Norwegian Bokmal)
* New translations strings.yml (English)
* New translations strings.yml (Arabic)
* New translations strings.yml (Serbian (Cyrillic))
* New translations strings.yml (Sinhala)
* New translations strings.yml (Pirate English)
* New translations strings.yml (Hindi)
* New translations strings.yml (Serbian (Latin))
* New translations strings.yml (Estonian)
* New translations strings.yml (Norwegian Bokmal)
* New translations strings.yml (English)
* New translations strings.yml (Arabic)
* New translations strings.yml (Serbian (Cyrillic))
* New translations strings.yml (Sinhala)
* Update README.md
* NEW load shared quests to memory via /import folder
* Provide additional context for failed requirement quests, fixes #1530
* Use quest IDs instead of names for YAML implementation of quester data
* Remove initial action from main quests prompt, functional as legacy only
* New Crowdin updates (#1533)
* New translations strings.yml (Polish)
* New translations strings.yml (Pirate English)
* New translations strings.yml (Vietnamese)
* New translations strings.yml (Portuguese, Brazilian)
* New translations strings.yml (Indonesian)
* New translations strings.yml (Thai)
* New translations strings.yml (Croatian)
* New translations strings.yml (Hindi)
* New translations strings.yml (Filipino)
* New translations strings.yml (Chinese Simplified)
* New translations strings.yml (Serbian (Latin))
* New translations strings.yml (LOLCAT)
* New translations strings.yml (Spanish)
* New translations strings.yml (Chinese Traditional)
* New translations strings.yml (Estonian)
* New translations strings.yml (Norwegian Bokmal)
* New translations strings.yml (English)
* New translations strings.yml (Turkish)
* New translations strings.yml (Romanian)
* New translations strings.yml (Hungarian)
* New translations strings.yml (French)
* New translations strings.yml (Arabic)
* New translations strings.yml (Czech)
* New translations strings.yml (Danish)
* New translations strings.yml (German)
* New translations strings.yml (Finnish)
* New translations strings.yml (Italian)
* New translations strings.yml (Swedish)
* New translations strings.yml (Japanese)
* New translations strings.yml (Korean)
* New translations strings.yml (Dutch)
* New translations strings.yml (Portuguese)
* New translations strings.yml (Russian)
* New translations strings.yml (Serbian (Cyrillic))
* New translations strings.yml (Sinhala)
* New translations strings.yml (English)
* New translations strings.yml (Pirate English)
* Call password objective event on sync to prevent exception
* Address certain objectives not progressing, fixes #1535
* Update quest completion messages to adhere to modern strings
* Correct erroneous enchantment string functionality, fixes #1538
* New Crowdin updates (#1543)
* New translations strings.yml (Thai)
* New translations strings.yml (Croatian)
* New translations strings.yml (Hindi)
* New translations strings.yml (Serbian (Latin))
* New translations strings.yml (Estonian)
* New translations strings.yml (Norwegian Bokmal)
* New translations strings.yml (Romanian)
* New translations strings.yml (Arabic)
* New translations strings.yml (Finnish)
* New translations strings.yml (Swedish)
* New translations strings.yml (Japanese)
* New translations strings.yml (Portuguese)
* New translations strings.yml (Serbian (Cyrillic))
* New translations strings.yml (Sinhala)
* New Crowdin updates (#1544)
* New translations strings.yml (Polish)
* New translations strings.yml (Pirate English)
* New translations strings.yml (Vietnamese)
* New translations strings.yml (Portuguese, Brazilian)
* New translations strings.yml (Indonesian)
* New translations strings.yml (Filipino)
* New translations strings.yml (Chinese Simplified)
* New translations strings.yml (LOLCAT)
* New translations strings.yml (Spanish)
* New translations strings.yml (Chinese Traditional)
* New translations strings.yml (English)
* New translations strings.yml (Turkish)
* New translations strings.yml (Hungarian)
* New translations strings.yml (French)
* New translations strings.yml (Czech)
* New translations strings.yml (Danish)
* New translations strings.yml (German)
* New translations strings.yml (Italian)
* New translations strings.yml (Korean)
* New translations strings.yml (Dutch)
* New translations strings.yml (Russian)
* Bump version
* Add missing disable-command-feedback config check (#1547)
* Translate quest item reward name if applicable, fixes #1548
* Prevent sending of most empty quester strings, fixes #1545
* New Crowdin updates (#1551)
* New translations strings.yml (Polish)
* New translations strings.yml (Pirate English)
* New translations strings.yml (Vietnamese)
* New translations strings.yml (Portuguese, Brazilian)
* New translations strings.yml (Indonesian)
* New translations strings.yml (Thai)
* New translations strings.yml (Croatian)
* New translations strings.yml (Hindi)
* New translations strings.yml (Filipino)
* New translations strings.yml (Chinese Simplified)
* New translations strings.yml (Serbian (Latin))
* New translations strings.yml (LOLCAT)
* New translations strings.yml (Spanish)
* New translations strings.yml (Chinese Traditional)
* New translations strings.yml (Estonian)
* New translations strings.yml (Norwegian Bokmal)
* New translations strings.yml (English)
* New translations strings.yml (Turkish)
* New translations strings.yml (Romanian)
* New translations strings.yml (Hungarian)
* New translations strings.yml (French)
* New translations strings.yml (Arabic)
* New translations strings.yml (Czech)
* New translations strings.yml (Danish)
* New translations strings.yml (German)
* New translations strings.yml (Finnish)
* New translations strings.yml (Italian)
* New translations strings.yml (Swedish)
* New translations strings.yml (Japanese)
* New translations strings.yml (Korean)
* New translations strings.yml (Dutch)
* New translations strings.yml (Portuguese)
* New translations strings.yml (Russian)
* New translations strings.yml (Serbian (Cyrillic))
* New translations strings.yml (Sinhala)
* New translations strings.yml (Polish)
* New translations strings.yml (Vietnamese)
* New translations strings.yml (Portuguese, Brazilian)
* New translations strings.yml (Indonesian)
* New translations strings.yml (Thai)
* New translations strings.yml (Filipino)
* New translations strings.yml (Chinese Simplified)
* New translations strings.yml (LOLCAT)
* New translations strings.yml (Spanish)
* New translations strings.yml (Chinese Traditional)
* New translations strings.yml (Estonian)
* New translations strings.yml (Turkish)
* New translations strings.yml (Hungarian)
* New translations strings.yml (French)
* New translations strings.yml (Czech)
* New translations strings.yml (Danish)
* New translations strings.yml (German)
* New translations strings.yml (Italian)
* New translations strings.yml (Korean)
* New translations strings.yml (Dutch)
* New translations strings.yml (Russian)
* Fixed multiplayer everything
* Reworked how multiplayer sharing 1 works and require same quest
* Updated Parties dependency
* Improved Parties messages on join/leave
* Further fixes about multiplayer sharing
* Wrong method fix
* Fixed documentation about deprecated method
Co-authored-by: PikaMug <2267126+PikaMug@users.noreply.github.com>
Co-authored-by: datatags <datatags@users.noreply.github.com>
2021-01-11 05:15:58 +01:00
|
|
|
} else {
|
2021-01-11 07:00:04 +01:00
|
|
|
throw new QuestFormatException("Reward parties-experience is not a number", questKey);
|
Parties 3.0.0 support (#1555)
* Updated Parties support
* Fixed multiplayer everything
* Add missing space for legacy string, fixes #1516
* Address formatting problems in initial menu prompts
* Do not proceed on invalid entity type, fixes #1520
* Click to register NPC listener if Citizens link failed at startup
* Populate objective goals when retrieving fresh quest data, fixes #1515
* Fixed typo in quest points log
* Added new Parties options for offline players and distance
* Added Parties experience reward
* Fix error on last stage completion
* Fixed Parties distance calculation
* Reworked how multiplayer sharing 1 works and require same quest
* Properly store repeat/cooldown values greater than max int, fixes #1523
* New Crowdin updates (#1524)
* New translations strings.yml (Thai)
* New translations strings.yml (Estonian)
* New translations strings.yml (Thai)
* New translations strings.yml (Thai)
* New translations strings.yml (Thai)
* Update quest main prompt strings
* Update quest main prompt strings, part 2
* Update quest main prompt strings, part 3
* New Crowdin updates (#1525)
* New translations strings.yml (Pirate English)
* New translations strings.yml (Hindi)
* New translations strings.yml (Serbian (Latin))
* New translations strings.yml (Estonian)
* New translations strings.yml (Norwegian Bokmal)
* New translations strings.yml (English)
* New translations strings.yml (Arabic)
* New translations strings.yml (Serbian (Cyrillic))
* New translations strings.yml (Sinhala)
* New translations strings.yml (Pirate English)
* New translations strings.yml (Hindi)
* New translations strings.yml (Serbian (Latin))
* New translations strings.yml (Estonian)
* New translations strings.yml (Norwegian Bokmal)
* New translations strings.yml (English)
* New translations strings.yml (Arabic)
* New translations strings.yml (Serbian (Cyrillic))
* New translations strings.yml (Sinhala)
* Update README.md
* NEW load shared quests to memory via /import folder
* Provide additional context for failed requirement quests, fixes #1530
* Use quest IDs instead of names for YAML implementation of quester data
* Remove initial action from main quests prompt, functional as legacy only
* New Crowdin updates (#1533)
* New translations strings.yml (Polish)
* New translations strings.yml (Pirate English)
* New translations strings.yml (Vietnamese)
* New translations strings.yml (Portuguese, Brazilian)
* New translations strings.yml (Indonesian)
* New translations strings.yml (Thai)
* New translations strings.yml (Croatian)
* New translations strings.yml (Hindi)
* New translations strings.yml (Filipino)
* New translations strings.yml (Chinese Simplified)
* New translations strings.yml (Serbian (Latin))
* New translations strings.yml (LOLCAT)
* New translations strings.yml (Spanish)
* New translations strings.yml (Chinese Traditional)
* New translations strings.yml (Estonian)
* New translations strings.yml (Norwegian Bokmal)
* New translations strings.yml (English)
* New translations strings.yml (Turkish)
* New translations strings.yml (Romanian)
* New translations strings.yml (Hungarian)
* New translations strings.yml (French)
* New translations strings.yml (Arabic)
* New translations strings.yml (Czech)
* New translations strings.yml (Danish)
* New translations strings.yml (German)
* New translations strings.yml (Finnish)
* New translations strings.yml (Italian)
* New translations strings.yml (Swedish)
* New translations strings.yml (Japanese)
* New translations strings.yml (Korean)
* New translations strings.yml (Dutch)
* New translations strings.yml (Portuguese)
* New translations strings.yml (Russian)
* New translations strings.yml (Serbian (Cyrillic))
* New translations strings.yml (Sinhala)
* New translations strings.yml (English)
* New translations strings.yml (Pirate English)
* Call password objective event on sync to prevent exception
* Address certain objectives not progressing, fixes #1535
* Update quest completion messages to adhere to modern strings
* Correct erroneous enchantment string functionality, fixes #1538
* New Crowdin updates (#1543)
* New translations strings.yml (Thai)
* New translations strings.yml (Croatian)
* New translations strings.yml (Hindi)
* New translations strings.yml (Serbian (Latin))
* New translations strings.yml (Estonian)
* New translations strings.yml (Norwegian Bokmal)
* New translations strings.yml (Romanian)
* New translations strings.yml (Arabic)
* New translations strings.yml (Finnish)
* New translations strings.yml (Swedish)
* New translations strings.yml (Japanese)
* New translations strings.yml (Portuguese)
* New translations strings.yml (Serbian (Cyrillic))
* New translations strings.yml (Sinhala)
* New Crowdin updates (#1544)
* New translations strings.yml (Polish)
* New translations strings.yml (Pirate English)
* New translations strings.yml (Vietnamese)
* New translations strings.yml (Portuguese, Brazilian)
* New translations strings.yml (Indonesian)
* New translations strings.yml (Filipino)
* New translations strings.yml (Chinese Simplified)
* New translations strings.yml (LOLCAT)
* New translations strings.yml (Spanish)
* New translations strings.yml (Chinese Traditional)
* New translations strings.yml (English)
* New translations strings.yml (Turkish)
* New translations strings.yml (Hungarian)
* New translations strings.yml (French)
* New translations strings.yml (Czech)
* New translations strings.yml (Danish)
* New translations strings.yml (German)
* New translations strings.yml (Italian)
* New translations strings.yml (Korean)
* New translations strings.yml (Dutch)
* New translations strings.yml (Russian)
* Bump version
* Add missing disable-command-feedback config check (#1547)
* Translate quest item reward name if applicable, fixes #1548
* Prevent sending of most empty quester strings, fixes #1545
* New Crowdin updates (#1551)
* New translations strings.yml (Polish)
* New translations strings.yml (Pirate English)
* New translations strings.yml (Vietnamese)
* New translations strings.yml (Portuguese, Brazilian)
* New translations strings.yml (Indonesian)
* New translations strings.yml (Thai)
* New translations strings.yml (Croatian)
* New translations strings.yml (Hindi)
* New translations strings.yml (Filipino)
* New translations strings.yml (Chinese Simplified)
* New translations strings.yml (Serbian (Latin))
* New translations strings.yml (LOLCAT)
* New translations strings.yml (Spanish)
* New translations strings.yml (Chinese Traditional)
* New translations strings.yml (Estonian)
* New translations strings.yml (Norwegian Bokmal)
* New translations strings.yml (English)
* New translations strings.yml (Turkish)
* New translations strings.yml (Romanian)
* New translations strings.yml (Hungarian)
* New translations strings.yml (French)
* New translations strings.yml (Arabic)
* New translations strings.yml (Czech)
* New translations strings.yml (Danish)
* New translations strings.yml (German)
* New translations strings.yml (Finnish)
* New translations strings.yml (Italian)
* New translations strings.yml (Swedish)
* New translations strings.yml (Japanese)
* New translations strings.yml (Korean)
* New translations strings.yml (Dutch)
* New translations strings.yml (Portuguese)
* New translations strings.yml (Russian)
* New translations strings.yml (Serbian (Cyrillic))
* New translations strings.yml (Sinhala)
* New translations strings.yml (Polish)
* New translations strings.yml (Vietnamese)
* New translations strings.yml (Portuguese, Brazilian)
* New translations strings.yml (Indonesian)
* New translations strings.yml (Thai)
* New translations strings.yml (Filipino)
* New translations strings.yml (Chinese Simplified)
* New translations strings.yml (LOLCAT)
* New translations strings.yml (Spanish)
* New translations strings.yml (Chinese Traditional)
* New translations strings.yml (Estonian)
* New translations strings.yml (Turkish)
* New translations strings.yml (Hungarian)
* New translations strings.yml (French)
* New translations strings.yml (Czech)
* New translations strings.yml (Danish)
* New translations strings.yml (German)
* New translations strings.yml (Italian)
* New translations strings.yml (Korean)
* New translations strings.yml (Dutch)
* New translations strings.yml (Russian)
* Fixed multiplayer everything
* Reworked how multiplayer sharing 1 works and require same quest
* Updated Parties dependency
* Improved Parties messages on join/leave
* Further fixes about multiplayer sharing
* Wrong method fix
* Fixed documentation about deprecated method
Co-authored-by: PikaMug <2267126+PikaMug@users.noreply.github.com>
Co-authored-by: datatags <datatags@users.noreply.github.com>
2021-01-11 05:15:58 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
if (depends.isPluginAvailable("PhatLoots")) {
|
|
|
|
if (config.contains("quests." + questKey + ".rewards.phat-loots")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".rewards.phat-loots"), String.class)) {
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final String loot : config.getStringList("quests." + questKey + ".rewards.phat-loots")) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (depends.getPhatLoots() == null) {
|
|
|
|
throw new QuestFormatException("PhatLoots not found for phat-loots", questKey);
|
|
|
|
} else if (PhatLootsAPI.getPhatLoot(loot) == null) {
|
2021-08-19 15:43:48 +02:00
|
|
|
throw new QuestFormatException("Reward phat-loots has invalid PhatLoot name " + loot,
|
|
|
|
questKey);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
2021-09-06 04:34:05 +02:00
|
|
|
rewards.setPhatLoots(config.getStringList("quests." + questKey + ".rewards.phat-loots"));
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Reward phat-loots is not a list of PhatLoots", questKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".rewards.details-override")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey
|
|
|
|
+ ".rewards.details-override"), String.class)) {
|
2021-09-06 04:34:05 +02:00
|
|
|
rewards.setDetailsOverride(config.getStringList("quests." + questKey + ".rewards.details-override"));
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Reward details-override is not a list of strings", questKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-19 15:43:48 +02:00
|
|
|
@SuppressWarnings({ "unchecked", "deprecation" })
|
|
|
|
private void loadQuestRequirements(final FileConfiguration config, final ConfigurationSection questsSection,
|
2022-01-19 03:15:49 +01:00
|
|
|
final IQuest quest, final String questKey) throws QuestFormatException {
|
2021-09-06 04:34:05 +02:00
|
|
|
final Requirements requires = quest.getRequirements();
|
2020-04-16 01:18:06 +02:00
|
|
|
if (config.contains("quests." + questKey + ".requirements.fail-requirement-message")) {
|
2020-08-06 11:32:43 +02:00
|
|
|
final Object o = config.get("quests." + questKey + ".requirements.fail-requirement-message");
|
2020-04-16 01:18:06 +02:00
|
|
|
if (o instanceof List) {
|
2021-09-06 04:34:05 +02:00
|
|
|
requires.setDetailsOverride(config.getStringList("quests." + questKey
|
2020-04-16 01:18:06 +02:00
|
|
|
+ ".requirements.fail-requirement-message"));
|
|
|
|
} else {
|
|
|
|
// Legacy
|
2021-08-19 15:43:48 +02:00
|
|
|
final List<String> override = new LinkedList<>();
|
2020-04-16 01:18:06 +02:00
|
|
|
override.add((String) o);
|
2021-09-06 04:34:05 +02:00
|
|
|
requires.setDetailsOverride(override);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".requirements.items")) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final List<ItemStack> temp = new LinkedList<>();
|
|
|
|
final List<ItemStack> stackList = (List<ItemStack>) config.get("quests." + questKey
|
|
|
|
+ ".requirements.items");
|
2020-04-16 01:18:06 +02:00
|
|
|
if (ConfigUtil.checkList(stackList, ItemStack.class)) {
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final ItemStack stack : stackList) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (stack != null) {
|
|
|
|
temp.add(stack);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Legacy
|
2020-08-06 11:32:43 +02:00
|
|
|
final List<String> items = config.getStringList("quests." + questKey + ".requirements.items");
|
2020-04-16 01:18:06 +02:00
|
|
|
if (ConfigUtil.checkList(items, String.class)) {
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final String item : items) {
|
2020-04-16 01:18:06 +02:00
|
|
|
try {
|
2020-08-06 11:32:43 +02:00
|
|
|
final ItemStack stack = ItemUtil.readItemStack(item);
|
2020-04-16 01:18:06 +02:00
|
|
|
if (stack != null) {
|
|
|
|
temp.add(stack);
|
|
|
|
}
|
2020-08-06 11:32:43 +02:00
|
|
|
} catch (final Exception e) {
|
2021-08-19 15:43:48 +02:00
|
|
|
throw new QuestFormatException("Requirement items has invalid formatting for " + item,
|
|
|
|
questKey);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Requirement items has invalid formatting", questKey);
|
|
|
|
}
|
|
|
|
}
|
2021-09-06 04:34:05 +02:00
|
|
|
requires.setItems(temp);
|
2020-04-16 01:18:06 +02:00
|
|
|
if (config.contains("quests." + questKey + ".requirements.remove-items")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".requirements.remove-items"),
|
|
|
|
Boolean.class)) {
|
2021-09-06 04:34:05 +02:00
|
|
|
requires.setRemoveItems(config.getBooleanList("quests." + questKey + ".requirements.remove-items"));
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
2021-08-19 15:43:48 +02:00
|
|
|
throw new QuestFormatException("Requirement remove-items is not a list of true/false values",
|
|
|
|
questKey);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Requirement remove-items is missing", questKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".requirements.money")) {
|
|
|
|
if (config.getInt("quests." + questKey + ".requirements.money", -999) != -999) {
|
2021-09-06 04:34:05 +02:00
|
|
|
requires.setMoney(config.getInt("quests." + questKey + ".requirements.money"));
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Requirement money is not a number", questKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".requirements.quest-points")) {
|
|
|
|
if (config.getInt("quests." + questKey + ".requirements.quest-points", -999) != -999) {
|
2021-09-06 04:34:05 +02:00
|
|
|
requires.setQuestPoints(config.getInt("quests." + questKey + ".requirements.quest-points"));
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Requirement quest-points is not a number", questKey);
|
2022-04-12 05:52:07 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".requirements.exp")) {
|
|
|
|
if (config.getInt("quests." + questKey + ".requirements.exp", -999) != -999) {
|
|
|
|
requires.setExp(config.getInt("quests." + questKey + ".requirements.exp"));
|
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Requirement exp is not a number", questKey);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".requirements.quest-blocks")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".requirements.quest-blocks"),
|
|
|
|
String.class)) {
|
2021-09-06 04:34:05 +02:00
|
|
|
final List<String> nodes = config.getStringList("quests." + questKey + ".requirements.quest-blocks");
|
2020-04-16 01:18:06 +02:00
|
|
|
boolean failed = false;
|
|
|
|
String failedQuest = "NULL";
|
2022-01-19 03:15:49 +01:00
|
|
|
final List<IQuest> temp = new LinkedList<>();
|
2021-09-06 04:34:05 +02:00
|
|
|
for (final String node : nodes) {
|
2020-04-16 01:18:06 +02:00
|
|
|
boolean done = false;
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final String id : questsSection.getKeys(false)) {
|
2021-09-06 04:34:05 +02:00
|
|
|
final String node2 = config.getString("quests." + id + ".name");
|
|
|
|
if (node2 != null && (id.equals(node) || node2.equalsIgnoreCase(node)
|
|
|
|
|| ChatColor.stripColor(node2).equalsIgnoreCase(ChatColor.stripColor(node)))) {
|
2022-02-04 12:41:23 +01:00
|
|
|
if (getQuestTemp(node) != null) {
|
|
|
|
temp.add(getQuestTemp(node));
|
|
|
|
} else if (getQuestByIdTemp(node) != null) {
|
|
|
|
temp.add(getQuestByIdTemp(node));
|
2020-12-13 05:37:12 +01:00
|
|
|
} else {
|
2021-09-06 04:34:05 +02:00
|
|
|
throw new QuestFormatException("Requirement quest-blocks has unknown quest name/id "
|
|
|
|
+ node + ", place it earlier in file so it loads first", questKey);
|
2020-12-13 05:37:12 +01:00
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
done = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!done) {
|
|
|
|
failed = true;
|
2021-09-06 04:34:05 +02:00
|
|
|
failedQuest = node;
|
2020-04-16 01:18:06 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2021-09-06 04:34:05 +02:00
|
|
|
requires.setBlockQuests(temp);
|
2020-04-16 01:18:06 +02:00
|
|
|
if (failed) {
|
2021-09-06 04:34:05 +02:00
|
|
|
throw new QuestFormatException("Requirement quest-blocks has invalid quest name/id " + failedQuest,
|
2021-08-19 15:43:48 +02:00
|
|
|
questKey);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Requirement quest-blocks is not a list of quest names", questKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".requirements.quests")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".requirements.quests"), String.class)) {
|
2021-09-06 04:34:05 +02:00
|
|
|
final List<String> nodes = config.getStringList("quests." + questKey + ".requirements.quests");
|
2020-04-16 01:18:06 +02:00
|
|
|
boolean failed = false;
|
|
|
|
String failedQuest = "NULL";
|
2022-01-19 03:15:49 +01:00
|
|
|
final List<IQuest> temp = new LinkedList<>();
|
2021-09-06 04:34:05 +02:00
|
|
|
for (final String node : nodes) {
|
2020-04-16 01:18:06 +02:00
|
|
|
boolean done = false;
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final String id : questsSection.getKeys(false)) {
|
2021-09-06 04:34:05 +02:00
|
|
|
final String node2 = config.getString("quests." + id + ".name");
|
|
|
|
if (node2 != null && (id.equals(node) || node2.equalsIgnoreCase(node)
|
|
|
|
|| ChatColor.stripColor(node2).equalsIgnoreCase(ChatColor.stripColor(node)))) {
|
2022-02-04 12:41:23 +01:00
|
|
|
if (getQuestTemp(node) != null) {
|
|
|
|
temp.add(getQuestTemp(node));
|
|
|
|
} else if (getQuestByIdTemp(node) != null) {
|
|
|
|
temp.add(getQuestByIdTemp(node));
|
2020-12-13 05:37:12 +01:00
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Requirement quests has unknown quest name "
|
2021-09-06 04:34:05 +02:00
|
|
|
+ node + ", place it earlier in file so it loads first", questKey);
|
2020-12-13 05:37:12 +01:00
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
done = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!done) {
|
|
|
|
failed = true;
|
2021-09-06 04:34:05 +02:00
|
|
|
failedQuest = node;
|
2020-04-16 01:18:06 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2021-09-06 04:34:05 +02:00
|
|
|
requires.setNeededQuests(temp);
|
2020-04-16 01:18:06 +02:00
|
|
|
if (failed) {
|
2021-09-06 04:34:05 +02:00
|
|
|
throw new QuestFormatException("Requirement quests has invalid quest name/id "
|
2020-12-13 05:37:12 +01:00
|
|
|
+ failedQuest, questKey);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Requirement quests is not a list of quest names", questKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".requirements.permissions")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".requirements.permissions"),
|
|
|
|
String.class)) {
|
2021-09-06 04:34:05 +02:00
|
|
|
requires.setPermissions(config.getStringList("quests." + questKey + ".requirements.permissions"));
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Requirement permissions is not a list of permissions", questKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".requirements.mcmmo-skills")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".requirements.mcmmo-skills"),
|
|
|
|
String.class)) {
|
|
|
|
if (config.contains("quests." + questKey + ".requirements.mcmmo-amounts")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".requirements.mcmmo-amounts"),
|
|
|
|
Integer.class)) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final List<String> skills = config.getStringList("quests." + questKey
|
|
|
|
+ ".requirements.mcmmo-skills");
|
2020-08-06 11:32:43 +02:00
|
|
|
final List<Integer> amounts = config.getIntegerList("quests." + questKey
|
2020-04-16 01:18:06 +02:00
|
|
|
+ ".requirements.mcmmo-amounts");
|
|
|
|
if (skills.size() != amounts.size()) {
|
2021-08-19 15:43:48 +02:00
|
|
|
throw new QuestFormatException("Requirement mcmmo-skills: and mcmmo-amounts are not the " +
|
|
|
|
"same size", questKey);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-09-06 04:34:05 +02:00
|
|
|
requires.setMcmmoSkills(skills);
|
|
|
|
requires.setMcmmoAmounts(amounts);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Requirement mcmmo-amounts is not a list of numbers", questKey);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Requirement mcmmo-amounts is missing", questKey);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Requirement mcmmo-skills is not a list of skills", questKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".requirements.heroes-primary-class")) {
|
2020-08-06 11:32:43 +02:00
|
|
|
final String className = config.getString("quests." + questKey + ".requirements.heroes-primary-class");
|
|
|
|
final HeroClass hc = depends.getHeroes().getClassManager().getClass(className);
|
2020-04-16 01:18:06 +02:00
|
|
|
if (hc != null && hc.isPrimary()) {
|
2021-09-06 04:34:05 +02:00
|
|
|
requires.setHeroesPrimaryClass(hc.getName());
|
2020-04-16 01:18:06 +02:00
|
|
|
} else if (hc != null) {
|
2021-08-19 15:43:48 +02:00
|
|
|
throw new QuestFormatException("Requirement heroes-primary-class is not a primary Heroes class",
|
|
|
|
questKey);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Requirement heroes-primary-class has invalid Heroes class", questKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".requirements.heroes-secondary-class")) {
|
2020-08-06 11:32:43 +02:00
|
|
|
final String className = config.getString("quests." + questKey + ".requirements.heroes-secondary-class");
|
|
|
|
final HeroClass hc = depends.getHeroes().getClassManager().getClass(className);
|
2020-04-16 01:18:06 +02:00
|
|
|
if (hc != null && hc.isSecondary()) {
|
2021-09-06 04:34:05 +02:00
|
|
|
requires.setHeroesSecondaryClass(hc.getName());
|
2020-04-16 01:18:06 +02:00
|
|
|
} else if (hc != null) {
|
2021-08-19 15:43:48 +02:00
|
|
|
throw new QuestFormatException("Requirement heroes-secondary-class is not a secondary Heroes class",
|
|
|
|
questKey);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Requirement heroes-secondary-class has invalid Heroes class", questKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".requirements.details-override")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey
|
|
|
|
+ ".requirements.details-override"), String.class)) {
|
2021-09-06 04:34:05 +02:00
|
|
|
requires.setDetailsOverride(config.getStringList("quests." + questKey + ".requirements.details-override"));
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Requirement details-override is not a list of strings", questKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-19 03:15:49 +01:00
|
|
|
private void loadQuestPlanner(final FileConfiguration config, final IQuest quest, final String questKey)
|
2021-08-19 15:43:48 +02:00
|
|
|
throws QuestFormatException {
|
2020-08-06 11:32:43 +02:00
|
|
|
final Planner pln = quest.getPlanner();
|
2020-04-16 01:18:06 +02:00
|
|
|
if (config.contains("quests." + questKey + ".planner.start")) {
|
|
|
|
pln.setStart(config.getString("quests." + questKey + ".planner.start"));
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".planner.end")) {
|
|
|
|
pln.setEnd(config.getString("quests." + questKey + ".planner.end"));
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".planner.repeat")) {
|
|
|
|
if (config.getInt("quests." + questKey + ".planner.repeat", -999) != -999) {
|
2021-07-10 01:48:00 +02:00
|
|
|
pln.setRepeat(config.getInt("quests." + questKey + ".planner.repeat") * 1000L);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Requirement repeat is not a number", questKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".planner.cooldown")) {
|
|
|
|
if (config.getInt("quests." + questKey + ".planner.cooldown", -999) != -999) {
|
2021-07-10 01:48:00 +02:00
|
|
|
pln.setCooldown(config.getInt("quests." + questKey + ".planner.cooldown") * 1000L);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new QuestFormatException("Requirement cooldown is not a number", questKey);
|
|
|
|
}
|
|
|
|
}
|
2020-07-24 11:03:53 +02:00
|
|
|
if (config.contains("quests." + questKey + ".planner.override")) {
|
|
|
|
pln.setOverride(config.getBoolean("quests." + questKey + ".planner.override"));
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
|
2022-01-19 03:15:49 +01:00
|
|
|
private void loadQuestOptions(final FileConfiguration config, final IQuest quest, final String questKey)
|
2021-08-19 15:43:48 +02:00
|
|
|
throws QuestFormatException {
|
2020-08-06 11:32:43 +02:00
|
|
|
final Options opts = quest.getOptions();
|
2020-04-16 01:18:06 +02:00
|
|
|
if (config.contains("quests." + questKey + ".options.allow-commands")) {
|
|
|
|
opts.setAllowCommands(config.getBoolean("quests." + questKey + ".options.allow-commands"));
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".options.allow-quitting")) {
|
|
|
|
opts.setAllowQuitting(config.getBoolean("quests." + questKey + ".options.allow-quitting"));
|
|
|
|
} else if (getConfig().contains("allow-quitting")) {
|
|
|
|
// Legacy
|
|
|
|
opts.setAllowQuitting(getConfig().getBoolean("allow-quitting"));
|
|
|
|
}
|
2020-10-16 09:16:44 +02:00
|
|
|
if (config.contains("quests." + questKey + ".options.ignore-silk-touch")) {
|
|
|
|
opts.setIgnoreSilkTouch(config.getBoolean("quests." + questKey + ".options.ignore-silk-touch"));
|
|
|
|
}
|
2021-10-12 09:20:22 +02:00
|
|
|
if (config.contains("quests." + questKey + ".options.external-party-plugin")) {
|
|
|
|
opts.setExternalPartyPlugin(config.getString("quests." + questKey + ".external-party-plugin"));
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".options.use-parties-plugin")) {
|
|
|
|
opts.setUsePartiesPlugin(config.getBoolean("quests." + questKey + ".options.use-parties-plugin"));
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".options.share-progress-level")) {
|
|
|
|
opts.setShareProgressLevel(config.getInt("quests." + questKey + ".options.share-progress-level"));
|
|
|
|
}
|
2021-01-11 07:00:04 +01:00
|
|
|
if (config.contains("quests." + questKey + ".options.same-quest-only")) {
|
|
|
|
opts.setShareSameQuestOnly(config.getBoolean("quests." + questKey + ".options.same-quest-only"));
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-01-24 07:22:04 +01:00
|
|
|
if (config.contains("quests." + questKey + ".options.share-distance")) {
|
|
|
|
opts.setShareDistance(config.getDouble("quests." + questKey + ".options.share-distance"));
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".options.handle-offline-players")) {
|
|
|
|
opts.setHandleOfflinePlayers(config.getBoolean("quests." + questKey + ".options.handle-offline-players"));
|
|
|
|
}
|
2022-05-15 18:19:07 +02:00
|
|
|
if (config.contains("quests." + questKey + ".options.ignore-block-replace")) {
|
|
|
|
opts.setIgnoreBlockReplace(config.getBoolean("quests." + questKey + ".options.ignore-block-replace"));
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
|
2021-08-19 15:43:48 +02:00
|
|
|
@SuppressWarnings({ "unchecked", "unused", "deprecation" })
|
2022-01-19 03:15:49 +01:00
|
|
|
private void loadQuestStages(final IQuest quest, final FileConfiguration config, final String questKey)
|
2020-07-13 06:35:28 +02:00
|
|
|
throws StageFormatException, ActionFormatException, ConditionFormatException {
|
2021-08-19 15:43:48 +02:00
|
|
|
final ConfigurationSection questStages = config.getConfigurationSection("quests." + questKey
|
|
|
|
+ ".stages.ordered");
|
2020-07-17 06:05:15 +02:00
|
|
|
if (questStages == null) {
|
|
|
|
getLogger().severe(ChatColor.RED + questKey + " must have at least one stage!");
|
|
|
|
return;
|
|
|
|
}
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final String stage : questStages.getKeys(false)) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final int stageNum;
|
2020-04-16 01:18:06 +02:00
|
|
|
try {
|
2021-07-10 01:48:00 +02:00
|
|
|
stageNum = Integer.parseInt(stage);
|
2020-08-06 11:32:43 +02:00
|
|
|
} catch (final NumberFormatException e) {
|
2022-01-23 06:29:15 +01:00
|
|
|
getLogger().severe("IStage key " + stage + "must be a number!");
|
2020-04-16 01:18:06 +02:00
|
|
|
continue;
|
|
|
|
}
|
2020-08-06 11:32:43 +02:00
|
|
|
final Stage oStage = new Stage();
|
2021-08-19 15:43:48 +02:00
|
|
|
List<String> breakNames = new LinkedList<>();
|
|
|
|
List<Integer> breakAmounts = new LinkedList<>();
|
|
|
|
List<Short> breakDurability = new LinkedList<>();
|
|
|
|
List<String> damageNames = new LinkedList<>();
|
|
|
|
List<Integer> damageAmounts = new LinkedList<>();
|
|
|
|
List<Short> damageDurability = new LinkedList<>();
|
|
|
|
List<String> placeNames = new LinkedList<>();
|
|
|
|
List<Integer> placeAmounts = new LinkedList<>();
|
|
|
|
List<Short> placeDurability = new LinkedList<>();
|
|
|
|
List<String> useNames = new LinkedList<>();
|
|
|
|
List<Integer> useAmounts = new LinkedList<>();
|
|
|
|
List<Short> useDurability = new LinkedList<>();
|
|
|
|
List<String> cutNames = new LinkedList<>();
|
|
|
|
List<Integer> cutAmounts = new LinkedList<>();
|
|
|
|
List<Short> cutDurability = new LinkedList<>();
|
|
|
|
final List<EntityType> mobsToKill = new LinkedList<>();
|
2022-01-12 21:10:01 +01:00
|
|
|
final List<Integer> mobNumsToKill = new LinkedList<>();
|
2021-08-19 15:43:48 +02:00
|
|
|
final List<Location> locationsToKillWithin = new LinkedList<>();
|
|
|
|
final List<Integer> radiiToKillWithin = new LinkedList<>();
|
|
|
|
final List<String> areaNames = new LinkedList<>();
|
|
|
|
final List<ItemStack> itemsToCraft;
|
|
|
|
final List<ItemStack> itemsToSmelt;
|
|
|
|
final List<ItemStack> itemsToEnchant;
|
|
|
|
final List<ItemStack> itemsToBrew;
|
|
|
|
final List<ItemStack> itemsToConsume;
|
2022-04-18 01:28:23 +02:00
|
|
|
final List<String> npcUuidsToTalkTo;
|
2021-08-19 15:43:48 +02:00
|
|
|
final List<Integer> npcIdsToTalkTo;
|
|
|
|
final List<ItemStack> itemsToDeliver;
|
2022-04-18 01:28:23 +02:00
|
|
|
final List<String> itemDeliveryTargetUuids;
|
2021-08-19 15:43:48 +02:00
|
|
|
final List<Integer> itemDeliveryTargetIds;
|
|
|
|
final List<String> deliveryMessages;
|
2022-04-18 01:28:23 +02:00
|
|
|
final List<String> npcUuidsToKill;
|
2021-08-19 15:43:48 +02:00
|
|
|
final List<Integer> npcIdsToKill;
|
|
|
|
final List<Integer> npcAmountsToKill;
|
2020-04-16 01:18:06 +02:00
|
|
|
// Legacy Denizen script load
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".script-to-run")) {
|
2020-04-24 06:31:09 +02:00
|
|
|
if (getDependencies().getDenizenApi().containsScript(config.getString("quests." + questKey
|
2020-04-16 01:18:06 +02:00
|
|
|
+ ".stages.ordered." + stageNum + ".script-to-run"))) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.setScript(config.getString("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".script-to-run"));
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new StageFormatException("script-to-run is not a valid Denizen script", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".break-block-names")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".break-block-names"), String.class)) {
|
|
|
|
breakNames = config.getStringList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".break-block-names");
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("break-block-names is not a list of strings", quest, stageNum);
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".break-block-amounts")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".break-block-amounts"), Integer.class)) {
|
|
|
|
breakAmounts = config.getIntegerList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".break-block-amounts");
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("break-block-amounts is not a list of numbers", quest, stageNum);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("break-block-amounts is missing", quest, stageNum);
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".break-block-durability")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".break-block-durability"), Integer.class)) {
|
|
|
|
breakDurability = config.getShortList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".break-block-durability");
|
|
|
|
} else {
|
2020-04-20 10:19:17 +02:00
|
|
|
throw new StageFormatException("break-block-durability is not a list of numbers", quest,
|
|
|
|
stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("break-block-durability is missing", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
int breakIndex = 0;
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final String s : breakNames) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final ItemStack is;
|
2020-12-18 23:19:14 +01:00
|
|
|
if (breakIndex < breakDurability.size() && breakDurability.get(breakIndex) != -1) {
|
2020-04-16 01:18:06 +02:00
|
|
|
is = ItemUtil.processItemStack(s, breakAmounts.get(breakIndex), breakDurability.get(breakIndex));
|
|
|
|
} else {
|
|
|
|
// Legacy
|
|
|
|
is = ItemUtil.processItemStack(s, breakAmounts.get(breakIndex), (short) 0);
|
|
|
|
}
|
|
|
|
if (Material.matchMaterial(s) != null) {
|
2022-01-13 17:02:43 +01:00
|
|
|
oStage.addBlockToBreak(is);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new StageFormatException("break-block-names has invalid item name " + s, quest, stageNum);
|
|
|
|
}
|
|
|
|
breakIndex++;
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".damage-block-names")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".damage-block-names"), String.class)) {
|
|
|
|
damageNames = config.getStringList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".damage-block-names");
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("damage-block-names is not a list of strings", quest, stageNum);
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".damage-block-amounts")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".damage-block-amounts"), Integer.class)) {
|
|
|
|
damageAmounts = config.getIntegerList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".damage-block-amounts");
|
|
|
|
} else {
|
2020-04-20 10:19:17 +02:00
|
|
|
throw new StageFormatException("damage-block-amounts is not a list of numbers", quest,
|
|
|
|
stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("damage-block-amounts is missing", quest, stageNum);
|
|
|
|
}
|
2020-04-20 10:19:17 +02:00
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".damage-block-durability")) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".damage-block-durability"), Integer.class)) {
|
|
|
|
damageDurability = config.getShortList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".damage-block-durability");
|
|
|
|
} else {
|
2020-04-20 10:19:17 +02:00
|
|
|
throw new StageFormatException("damage-block-durability is not a list of numbers", quest,
|
|
|
|
stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("damage-block-durability is missing", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
int damageIndex = 0;
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final String s : damageNames) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final ItemStack is;
|
2020-12-18 23:19:14 +01:00
|
|
|
if (damageIndex < damageDurability.size() && damageDurability.get(damageIndex) != -1) {
|
2020-04-16 01:18:06 +02:00
|
|
|
is = ItemUtil.processItemStack(s, damageAmounts.get(damageIndex),
|
|
|
|
damageDurability.get(damageIndex));
|
|
|
|
} else {
|
|
|
|
// Legacy
|
|
|
|
is = ItemUtil.processItemStack(s, damageAmounts.get(damageIndex), (short) 0);
|
|
|
|
}
|
|
|
|
if (Material.matchMaterial(s) != null) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.addBlockToDamage(is);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new StageFormatException("damage-block-names has invalid item name " + s, quest, stageNum);
|
|
|
|
}
|
|
|
|
damageIndex++;
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".place-block-names")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".place-block-names"), String.class)) {
|
|
|
|
placeNames = config.getStringList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".place-block-names");
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("place-block-names is not a list of strings", quest, stageNum);
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".place-block-amounts")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".place-block-amounts"), Integer.class)) {
|
|
|
|
placeAmounts = config.getIntegerList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".place-block-amounts");
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("place-block-amounts is not a list of numbers", quest, stageNum);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("place-block-amounts is missing", quest, stageNum);
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".place-block-durability")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".place-block-durability"), Integer.class)) {
|
|
|
|
placeDurability = config.getShortList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".place-block-durability");
|
|
|
|
} else {
|
2020-04-20 10:19:17 +02:00
|
|
|
throw new StageFormatException("place-block-durability is not a list of numbers", quest,
|
|
|
|
stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("place-block-durability is missing", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
int placeIndex = 0;
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final String s : placeNames) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final ItemStack is;
|
2020-12-18 23:19:14 +01:00
|
|
|
if (placeIndex < placeDurability.size() && placeDurability.get(placeIndex) != -1) {
|
2020-04-16 01:18:06 +02:00
|
|
|
is = ItemUtil.processItemStack(s, placeAmounts.get(placeIndex), placeDurability.get(placeIndex));
|
|
|
|
} else {
|
|
|
|
// Legacy
|
|
|
|
is = ItemUtil.processItemStack(s, placeAmounts.get(placeIndex), (short) 0);
|
|
|
|
}
|
|
|
|
if (Material.matchMaterial(s) != null) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.addBlockToPlace(is);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new StageFormatException("place-block-names has invalid item name " + s, quest, stageNum);
|
|
|
|
}
|
|
|
|
placeIndex++;
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".use-block-names")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".use-block-names"), String.class)) {
|
|
|
|
useNames = config.getStringList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".use-block-names");
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("use-block-names is not a list of strings", quest, stageNum);
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".use-block-amounts")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".use-block-amounts"),Integer.class)) {
|
|
|
|
useAmounts = config.getIntegerList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".use-block-amounts");
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("use-block-amounts is not a list of numbers", quest, stageNum);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("use-block-amounts is missing", quest, stageNum);
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".use-block-durability")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".use-block-durability"), Integer.class)) {
|
|
|
|
useDurability = config.getShortList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".use-block-durability");
|
|
|
|
} else {
|
2020-04-20 10:19:17 +02:00
|
|
|
throw new StageFormatException("use-block-durability is not a list of numbers", quest,
|
|
|
|
stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("use-block-durability is missing", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
int useIndex = 0;
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final String s : useNames) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final ItemStack is;
|
2020-12-18 23:19:14 +01:00
|
|
|
if (useIndex < useDurability.size() && useDurability.get(useIndex) != -1) {
|
2020-04-16 01:18:06 +02:00
|
|
|
is = ItemUtil.processItemStack(s, useAmounts.get(useIndex), useDurability.get(useIndex));
|
|
|
|
} else {
|
|
|
|
// Legacy
|
|
|
|
is = ItemUtil.processItemStack(s, useAmounts.get(useIndex), (short) 0);
|
|
|
|
}
|
|
|
|
if (Material.matchMaterial(s) != null) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.addBlockToUse(is);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new StageFormatException("use-block-names has invalid item name " + s, quest, stageNum);
|
|
|
|
}
|
|
|
|
useIndex++;
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".cut-block-names")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".cut-block-names"), String.class)) {
|
|
|
|
cutNames = config.getStringList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".cut-block-names");
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("cut-block-names is not a list of strings", quest, stageNum);
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".cut-block-amounts")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".cut-block-amounts"), Integer.class)) {
|
|
|
|
cutAmounts = config.getIntegerList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".cut-block-amounts");
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("cut-block-amounts is not a list of numbers", quest, stageNum);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("cut-block-amounts is missing", quest, stageNum);
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".cut-block-durability")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".cut-block-durability"), Integer.class)) {
|
|
|
|
cutDurability = config.getShortList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".cut-block-durability");
|
|
|
|
} else {
|
2020-04-20 10:19:17 +02:00
|
|
|
throw new StageFormatException("cut-block-durability is not a list of numbers", quest,
|
|
|
|
stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("cut-block-durability is missing", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
int cutIndex = 0;
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final String s : cutNames) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final ItemStack is;
|
2020-12-18 23:19:14 +01:00
|
|
|
if (cutIndex < cutDurability.size() && cutDurability.get(cutIndex) != -1) {
|
2020-04-16 01:18:06 +02:00
|
|
|
is = ItemUtil.processItemStack(s, cutAmounts.get(cutIndex), cutDurability.get(cutIndex));
|
|
|
|
} else {
|
|
|
|
// Legacy
|
|
|
|
is = ItemUtil.processItemStack(s, cutAmounts.get(cutIndex), (short) 0);
|
|
|
|
}
|
|
|
|
if (Material.matchMaterial(s) != null) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.addBlockToCut(is);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new StageFormatException("cut-block-names has invalid item name " + s, quest, stageNum);
|
|
|
|
}
|
|
|
|
cutIndex++;
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".items-to-craft")) {
|
|
|
|
itemsToCraft = (List<ItemStack>) config.get("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".items-to-craft");
|
|
|
|
if (ConfigUtil.checkList(itemsToCraft, ItemStack.class)) {
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final ItemStack stack : itemsToCraft) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (stack != null) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.addItemToCraft(stack);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
2021-08-19 15:43:48 +02:00
|
|
|
throw new StageFormatException("items-to-craft has invalid formatting", quest, stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Legacy
|
2020-08-06 11:32:43 +02:00
|
|
|
final List<String> items = config.getStringList("quests." + questKey + ".stages.ordered." + stageNum
|
2020-04-16 01:18:06 +02:00
|
|
|
+ ".items-to-craft");
|
|
|
|
if (ConfigUtil.checkList(items, String.class)) {
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final String item : items) {
|
|
|
|
final ItemStack is = ItemUtil.readItemStack("" + item);
|
2020-04-16 01:18:06 +02:00
|
|
|
if (is != null) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.addItemToCraft(is);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
2020-04-20 10:19:17 +02:00
|
|
|
throw new StageFormatException("Legacy items-to-craft has invalid formatting "
|
|
|
|
+ item, quest, stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("items-to-craft is not formatted properly", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".items-to-smelt")) {
|
|
|
|
itemsToSmelt = (List<ItemStack>) config.get("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".items-to-smelt");
|
|
|
|
if (ConfigUtil.checkList(itemsToSmelt, ItemStack.class)) {
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final ItemStack stack : itemsToSmelt) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (stack != null) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.addItemToSmelt(stack);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
2021-08-19 15:43:48 +02:00
|
|
|
throw new StageFormatException("items-to-smelt has invalid formatting", quest, stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Legacy
|
2020-08-06 11:32:43 +02:00
|
|
|
final List<String> items = config.getStringList("quests." + questKey + ".stages.ordered." + stageNum
|
2020-04-16 01:18:06 +02:00
|
|
|
+ ".items-to-smelt");
|
|
|
|
if (ConfigUtil.checkList(items, String.class)) {
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final String item : items) {
|
|
|
|
final ItemStack is = ItemUtil.readItemStack("" + item);
|
2020-04-16 01:18:06 +02:00
|
|
|
if (is != null) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.addItemToSmelt(is);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
2020-04-20 10:19:17 +02:00
|
|
|
throw new StageFormatException("Legacy items-to-smelt has invalid formatting "
|
|
|
|
+ item, quest, stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("items-to-smelt is not formatted properly", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-10-19 09:43:01 +02:00
|
|
|
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".items-to-enchant")) {
|
|
|
|
itemsToEnchant = (List<ItemStack>) config.get("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".items-to-enchant");
|
|
|
|
if (ConfigUtil.checkList(itemsToEnchant, ItemStack.class)) {
|
|
|
|
for (final ItemStack stack : itemsToEnchant) {
|
|
|
|
if (stack != null) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.addItemToEnchant(stack);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
2021-08-19 15:43:48 +02:00
|
|
|
throw new StageFormatException("items-to-enchant has invalid formatting", quest, stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2020-10-19 09:43:01 +02:00
|
|
|
// Legacy
|
2021-08-19 15:43:48 +02:00
|
|
|
final LinkedList<Material> types = new LinkedList<>();
|
|
|
|
final LinkedList<Enchantment> enchs = new LinkedList<>();
|
|
|
|
final LinkedList<Integer> amts;
|
2020-10-19 09:43:01 +02:00
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".enchantments")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".enchantments"), String.class)) {
|
|
|
|
for (final String enchant : config.getStringList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".enchantments")) {
|
|
|
|
final Enchantment e = ItemUtil.getEnchantmentFromProperName(enchant);
|
|
|
|
if (e != null) {
|
|
|
|
enchs.add(e);
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("enchantments has invalid enchantment "
|
|
|
|
+ enchant, quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("enchantments is not a list of enchantment names", quest, stageNum);
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".enchantment-item-names")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".enchantment-item-names"), String.class)) {
|
|
|
|
for (final String item : config.getStringList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".enchantment-item-names")) {
|
|
|
|
if (Material.matchMaterial(item) != null) {
|
|
|
|
types.add(Material.matchMaterial(item));
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("enchantment-item-names has invalid item name "
|
|
|
|
+ item, quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
2020-10-19 09:43:01 +02:00
|
|
|
throw new StageFormatException("enchantment-item-names has invalid item name", quest, stageNum);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("enchantment-item-names is missing", quest, stageNum);
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".enchantment-amounts")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".enchantment-amounts"), Integer.class)) {
|
2021-08-19 15:43:48 +02:00
|
|
|
amts = new LinkedList<>(config.getIntegerList("quests." + questKey + ".stages.ordered."
|
|
|
|
+ stageNum + ".enchantment-amounts"));
|
2020-10-19 09:43:01 +02:00
|
|
|
} else {
|
|
|
|
throw new StageFormatException("enchantment-amounts is not a list of numbers", quest, stageNum);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("enchantment-amounts is missing", quest, stageNum);
|
|
|
|
}
|
|
|
|
if (!enchs.isEmpty() && !types.isEmpty() && !amts.isEmpty()) {
|
|
|
|
for (int i = 0; i < enchs.size(); i++) {
|
|
|
|
final ItemStack stack = new ItemStack(types.get(i), amts.get(i));
|
|
|
|
stack.addEnchantment(enchs.get(0), 1);
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.addItemToEnchant(stack);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".items-to-brew")) {
|
|
|
|
itemsToBrew = (List<ItemStack>) config.get("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".items-to-brew");
|
|
|
|
if (ConfigUtil.checkList(itemsToBrew, ItemStack.class)) {
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final ItemStack stack : itemsToBrew) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (stack != null) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.addItemsToBrew(stack);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
2021-08-19 15:43:48 +02:00
|
|
|
throw new StageFormatException("items-to-brew has invalid formatting", quest, stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Legacy
|
2020-08-06 11:32:43 +02:00
|
|
|
final List<String> items = config.getStringList("quests." + questKey + ".stages.ordered." + stageNum
|
2020-04-16 01:18:06 +02:00
|
|
|
+ ".items-to-brew");
|
|
|
|
if (ConfigUtil.checkList(items, String.class)) {
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final String item : items) {
|
|
|
|
final ItemStack is = ItemUtil.readItemStack("" + item);
|
2020-04-16 01:18:06 +02:00
|
|
|
if (is != null) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.addItemsToBrew(is);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
2021-08-19 15:43:48 +02:00
|
|
|
throw new StageFormatException("Legacy items-to-brew has invalid formatting", quest,
|
|
|
|
stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("items-to-brew has invalid formatting", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-04-20 10:19:17 +02:00
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".items-to-consume")) {
|
|
|
|
itemsToConsume = (List<ItemStack>) config.get("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".items-to-consume");
|
|
|
|
if (ConfigUtil.checkList(itemsToConsume, ItemStack.class)) {
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final ItemStack stack : itemsToConsume) {
|
2020-04-20 10:19:17 +02:00
|
|
|
if (stack != null) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.addItemToConsume(stack);
|
2020-04-20 10:19:17 +02:00
|
|
|
} else {
|
2021-08-19 15:43:48 +02:00
|
|
|
throw new StageFormatException("items-to-consume has invalid formatting", quest, stageNum);
|
2020-04-20 10:19:17 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".cows-to-milk")) {
|
2020-04-20 10:19:17 +02:00
|
|
|
if (config.getInt("quests." + questKey + ".stages.ordered." + stageNum + ".cows-to-milk", -999)
|
|
|
|
!= -999) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.setCowsToMilk(config.getInt("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".cows-to-milk"));
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new StageFormatException("cows-to-milk is not a number", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".fish-to-catch")) {
|
2020-04-20 10:19:17 +02:00
|
|
|
if (config.getInt("quests." + questKey + ".stages.ordered." + stageNum + ".fish-to-catch", -999)
|
|
|
|
!= -999) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.setFishToCatch(config.getInt("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".fish-to-catch"));
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new StageFormatException("fish-to-catch is not a number", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".players-to-kill")) {
|
2020-04-20 10:19:17 +02:00
|
|
|
if (config.getInt("quests." + questKey + ".stages.ordered." + stageNum + ".players-to-kill", -999)
|
|
|
|
!= -999) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.setPlayersToKill(config.getInt("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".players-to-kill"));
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new StageFormatException("players-to-kill is not a number", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
2022-04-18 01:28:23 +02:00
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".npc-uuids-to-talk-to")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".npc-uuids-to-talk-to"), String.class)) {
|
|
|
|
npcUuidsToTalkTo = config.getStringList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".npc-uuids-to-talk-to");
|
|
|
|
for (final String s : npcUuidsToTalkTo) {
|
|
|
|
final UUID uuid = UUID.fromString(s);
|
2022-06-04 09:47:44 +02:00
|
|
|
oStage.addNpcToInteract(uuid);
|
|
|
|
questNpcUuids.add(uuid);
|
2022-04-18 01:28:23 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("npc-ids-to-talk-to is not a list of numbers", quest, stageNum);
|
|
|
|
}
|
|
|
|
} else if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".npc-ids-to-talk-to")) {
|
|
|
|
// Legacy
|
2020-04-16 01:18:06 +02:00
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".npc-ids-to-talk-to"), Integer.class)) {
|
|
|
|
npcIdsToTalkTo = config.getIntegerList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".npc-ids-to-talk-to");
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final int i : npcIdsToTalkTo) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (getDependencies().getCitizens() != null) {
|
2022-04-18 01:28:23 +02:00
|
|
|
final NPC npc = CitizensAPI.getNPCRegistry().getById(i);
|
|
|
|
if (npc != null) {
|
|
|
|
final UUID npcUuid = npc.getUniqueId();
|
|
|
|
oStage.addNpcToInteract(npcUuid);
|
2022-05-15 19:11:37 +02:00
|
|
|
questNpcUuids.add(npcUuid);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
2020-04-20 10:19:17 +02:00
|
|
|
throw new StageFormatException("npc-ids-to-talk-to has invalid NPC ID of " + i, quest,
|
|
|
|
stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
} else {
|
2020-04-20 10:19:17 +02:00
|
|
|
throw new StageFormatException("Citizens not found for npc-ids-to-talk-to", quest,
|
|
|
|
stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("npc-ids-to-talk-to is not a list of numbers", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".items-to-deliver")) {
|
2022-04-18 01:28:23 +02:00
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".npc-delivery-uuids")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".npc-delivery-uuids"), String.class)) {
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum
|
2020-04-20 10:19:17 +02:00
|
|
|
+ ".delivery-messages")) {
|
2022-04-18 01:28:23 +02:00
|
|
|
itemsToDeliver = (List<ItemStack>) config.get("quests." + questKey + ".stages.ordered."
|
2020-04-16 01:18:06 +02:00
|
|
|
+ stageNum + ".items-to-deliver");
|
2022-04-18 01:28:23 +02:00
|
|
|
itemDeliveryTargetUuids = config.getStringList("quests." + questKey + ".stages.ordered."
|
|
|
|
+ stageNum + ".npc-delivery-uuids");
|
|
|
|
deliveryMessages = config.getStringList("quests." + questKey + ".stages.ordered."
|
2020-08-18 23:24:47 +02:00
|
|
|
+ stageNum + ".delivery-messages");
|
2020-04-16 01:18:06 +02:00
|
|
|
int index = 0;
|
|
|
|
if (ConfigUtil.checkList(itemsToDeliver, ItemStack.class)) {
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final ItemStack stack : itemsToDeliver) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (stack != null) {
|
2022-04-18 01:28:23 +02:00
|
|
|
final UUID npcUuid = UUID.fromString(itemDeliveryTargetUuids.get(index));
|
|
|
|
final String msg = deliveryMessages.size() > index
|
|
|
|
? deliveryMessages.get(index)
|
2020-08-18 23:24:47 +02:00
|
|
|
: deliveryMessages.get(deliveryMessages.size() - 1);
|
2020-04-16 01:18:06 +02:00
|
|
|
index++;
|
2022-06-04 09:47:44 +02:00
|
|
|
oStage.addItemToDeliver(stack);
|
|
|
|
oStage.addItemDeliveryTarget(npcUuid);
|
|
|
|
oStage.addDeliverMessage(msg);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2022-04-18 01:28:23 +02:00
|
|
|
throw new StageFormatException("items-to-deliver has invalid formatting", quest,
|
|
|
|
stageNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("npc-delivery-ids is not a list of numbers", quest, stageNum);
|
|
|
|
}
|
|
|
|
} else if (config.contains("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".npc-delivery-ids")) {
|
|
|
|
// Legacy
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".npc-delivery-ids"), Integer.class)) {
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".delivery-messages")) {
|
|
|
|
itemsToDeliver = (List<ItemStack>) config.get("quests." + questKey + ".stages.ordered."
|
|
|
|
+ stageNum + ".items-to-deliver");
|
|
|
|
itemDeliveryTargetIds = config.getIntegerList("quests." + questKey + ".stages.ordered."
|
|
|
|
+ stageNum + ".npc-delivery-ids");
|
|
|
|
deliveryMessages = config.getStringList("quests." + questKey + ".stages.ordered."
|
|
|
|
+ stageNum + ".delivery-messages");
|
|
|
|
int index = 0;
|
|
|
|
if (ConfigUtil.checkList(itemsToDeliver, ItemStack.class)) {
|
|
|
|
for (final ItemStack stack : itemsToDeliver) {
|
|
|
|
if (stack != null) {
|
|
|
|
final int npcId = itemDeliveryTargetIds.get(index);
|
|
|
|
final String msg = deliveryMessages.size() > index
|
|
|
|
? deliveryMessages.get(index)
|
|
|
|
: deliveryMessages.get(deliveryMessages.size() - 1);
|
|
|
|
index++;
|
|
|
|
if (getDependencies().getCitizens() != null) {
|
|
|
|
final NPC npc = CitizensAPI.getNPCRegistry().getById(npcId);
|
|
|
|
if (npc != null) {
|
|
|
|
oStage.addItemToDeliver(stack);
|
|
|
|
oStage.addItemDeliveryTarget(npc.getUniqueId());
|
|
|
|
oStage.addDeliverMessage(msg);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
2022-04-18 01:28:23 +02:00
|
|
|
throw new StageFormatException("npc-delivery-ids has invalid NPC " +
|
|
|
|
"ID of " + npcId, quest, stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
} else {
|
2022-04-18 01:28:23 +02:00
|
|
|
throw new StageFormatException(
|
|
|
|
"Citizens not found for npc-delivery-ids", quest, stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-04-18 01:28:23 +02:00
|
|
|
} else {
|
|
|
|
throw new StageFormatException("items-to-deliver has invalid formatting", quest,
|
|
|
|
stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("npc-delivery-ids is not a list of numbers", quest, stageNum);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("npc-delivery-id is missing", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
2022-04-18 01:28:23 +02:00
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".npc-uuids-to-kill")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".npc-uuids-to-kill"), String.class)) {
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".npc-kill-amounts")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".npc-kill-amounts"), Integer.class)) {
|
|
|
|
npcUuidsToKill = config.getStringList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".npc-uuids-to-kill");
|
|
|
|
npcAmountsToKill = config.getIntegerList("quests." + questKey + ".stages.ordered."
|
|
|
|
+ stageNum + ".npc-kill-amounts");
|
|
|
|
for (final String s : npcUuidsToKill) {
|
|
|
|
final UUID npcUuid = UUID.fromString(s);
|
2022-06-04 09:47:44 +02:00
|
|
|
if (npcAmountsToKill.get(npcUuidsToKill.indexOf(s)) > 0) {
|
|
|
|
oStage.addNpcToKill(npcUuid);
|
|
|
|
oStage.addNpcNumToKill(npcAmountsToKill.get(npcUuidsToKill.indexOf(s)));
|
|
|
|
questNpcUuids.add(npcUuid);
|
2022-04-18 01:28:23 +02:00
|
|
|
} else {
|
2022-06-04 09:47:44 +02:00
|
|
|
throw new StageFormatException("npc-kill-amounts is not a positive number",
|
2022-04-18 01:28:23 +02:00
|
|
|
quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("npc-kill-amounts is not a list of numbers", quest,
|
|
|
|
stageNum);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("npc-kill-amounts is missing", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".npc-ids-to-kill")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
2020-04-16 01:18:06 +02:00
|
|
|
+ ".npc-ids-to-kill"), Integer.class)) {
|
2022-04-18 01:28:23 +02:00
|
|
|
// Legacy
|
2020-04-16 01:18:06 +02:00
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".npc-kill-amounts")) {
|
2022-04-18 01:28:23 +02:00
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
2020-04-16 01:18:06 +02:00
|
|
|
+ ".npc-kill-amounts"), Integer.class)) {
|
2022-04-18 01:28:23 +02:00
|
|
|
npcIdsToKill = config.getIntegerList("quests." + questKey + ".stages.ordered." + stageNum
|
2020-04-16 01:18:06 +02:00
|
|
|
+ ".npc-ids-to-kill");
|
2022-04-18 01:28:23 +02:00
|
|
|
npcAmountsToKill = config.getIntegerList("quests." + questKey + ".stages.ordered."
|
2020-04-20 10:19:17 +02:00
|
|
|
+ stageNum + ".npc-kill-amounts");
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final int i : npcIdsToKill) {
|
2022-04-18 01:28:23 +02:00
|
|
|
final NPC npc = CitizensAPI.getNPCRegistry().getById(i);
|
|
|
|
if (npc != null) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (npcAmountsToKill.get(npcIdsToKill.indexOf(i)) > 0) {
|
2022-04-18 01:28:23 +02:00
|
|
|
final UUID npcUuid = npc.getUniqueId();
|
|
|
|
oStage.addNpcToKill(npcUuid);
|
|
|
|
oStage.addNpcNumToKill(npcAmountsToKill.get(npcIdsToKill.indexOf(i)));
|
2022-05-15 19:11:37 +02:00
|
|
|
questNpcUuids.add(npcUuid);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
2022-04-18 01:28:23 +02:00
|
|
|
throw new StageFormatException("npc-kill-amounts is not a positive number",
|
2020-04-20 10:19:17 +02:00
|
|
|
quest, stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
} else {
|
2020-04-20 10:19:17 +02:00
|
|
|
throw new StageFormatException("npc-ids-to-kill has invalid NPC ID of " + i, quest,
|
|
|
|
stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2022-04-18 01:28:23 +02:00
|
|
|
throw new StageFormatException("npc-kill-amounts is not a list of numbers", quest,
|
2020-04-20 10:19:17 +02:00
|
|
|
stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("npc-kill-amounts is missing", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".mobs-to-kill")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".mobs-to-kill"), String.class)) {
|
2020-08-18 23:24:47 +02:00
|
|
|
final List<String> mobNames = config.getStringList("quests." + questKey + ".stages.ordered."
|
|
|
|
+ stageNum + ".mobs-to-kill");
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final String mob : mobNames) {
|
|
|
|
final EntityType type = MiscUtil.getProperMobType(mob);
|
2020-04-16 01:18:06 +02:00
|
|
|
if (type != null) {
|
|
|
|
mobsToKill.add(type);
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("mobs-to-kill has invalid mob name " + mob, quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("mobs-to-kill is not a list of mob names", quest, stageNum);
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".mob-amounts")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".mob-amounts"), Integer.class)) {
|
2022-01-12 21:10:01 +01:00
|
|
|
mobNumsToKill.addAll(config.getIntegerList("quests." + questKey + ".stages.ordered." + stageNum
|
2021-08-19 15:43:48 +02:00
|
|
|
+ ".mob-amounts"));
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new StageFormatException("mob-amounts is not a list of numbers", quest, stageNum);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("mob-amounts is missing", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".locations-to-kill")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".locations-to-kill"), String.class)) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final List<String> locations = config.getStringList("quests." + questKey + ".stages.ordered."
|
|
|
|
+ stageNum + ".locations-to-kill");
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final String loc : locations) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (ConfigUtil.getLocation(loc) != null) {
|
|
|
|
locationsToKillWithin.add(ConfigUtil.getLocation(loc));
|
|
|
|
} else {
|
2020-04-20 10:19:17 +02:00
|
|
|
throw new StageFormatException("locations-to-kill has invalid formatting " + loc, quest,
|
|
|
|
stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("locations-to-kill is not a list of locations", quest, stageNum);
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".kill-location-radii")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".kill-location-radii"), Integer.class)) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final List<Integer> radii = config.getIntegerList("quests." + questKey + ".stages.ordered."
|
|
|
|
+ stageNum + ".kill-location-radii");
|
|
|
|
radiiToKillWithin.addAll(radii);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new StageFormatException("kill-location-radii is not a list of numbers", quest, stageNum);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("kill-location-radii is missing", quest, stageNum);
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".kill-location-names")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".kill-location-names"), String.class)) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final List<String> locationNames = config.getStringList("quests." + questKey
|
|
|
|
+ ".stages.ordered." + stageNum + ".kill-location-names");
|
|
|
|
areaNames.addAll(locationNames);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new StageFormatException("kill-location-names is not a list of names", quest, stageNum);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("kill-location-names is missing", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
2022-01-12 21:10:01 +01:00
|
|
|
for (EntityType mobToKill : mobsToKill) {
|
|
|
|
oStage.addMobToKill(mobToKill);
|
|
|
|
}
|
|
|
|
for (Integer mobNumToKill : mobNumsToKill) {
|
|
|
|
oStage.addMobNumToKill(mobNumToKill);
|
|
|
|
}
|
|
|
|
for (Location locationToKillWithin : locationsToKillWithin) {
|
|
|
|
oStage.addLocationToKillWithin(locationToKillWithin);
|
|
|
|
}
|
|
|
|
for (Integer radiusToKillWithin : radiiToKillWithin) {
|
|
|
|
oStage.addRadiusToKillWithin(radiusToKillWithin);
|
|
|
|
}
|
|
|
|
for (String killName : areaNames) {
|
|
|
|
oStage.addKillName(killName);
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".locations-to-reach")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".locations-to-reach"), String.class)) {
|
2020-08-06 11:32:43 +02:00
|
|
|
final List<String> locations = config.getStringList("quests." + questKey + ".stages.ordered." + stageNum
|
2020-04-16 01:18:06 +02:00
|
|
|
+ ".locations-to-reach");
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final String loc : locations) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (ConfigUtil.getLocation(loc) != null) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.addLocationToReach(ConfigUtil.getLocation(loc));
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
2020-04-20 10:19:17 +02:00
|
|
|
throw new StageFormatException("locations-to-reach has invalid formatting" + loc, quest,
|
|
|
|
stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("locations-to-reach is not a list of locations", quest, stageNum);
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".reach-location-radii")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".reach-location-radii"), Integer.class)) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final List<Integer> radii = config.getIntegerList("quests." + questKey + ".stages.ordered."
|
|
|
|
+ stageNum + ".reach-location-radii");
|
2022-01-12 21:10:01 +01:00
|
|
|
for (Integer radius : radii) {
|
|
|
|
oStage.addRadiusToReachWithin(radius);
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
2020-04-20 10:19:17 +02:00
|
|
|
throw new StageFormatException("reach-location-radii is not a list of numbers", quest,
|
|
|
|
stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("reach-location-radii is missing", quest, stageNum);
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".reach-location-names")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".reach-location-names"), String.class)) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final List<String> locationNames = config.getStringList("quests." + questKey
|
|
|
|
+ ".stages.ordered." + stageNum + ".reach-location-names");
|
2022-01-12 21:10:01 +01:00
|
|
|
for (String locationName : locationNames) {
|
|
|
|
oStage.addLocationName(locationName);
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new StageFormatException("reach-location-names is not a list of names", quest, stageNum);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("reach-location-names is missing", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".mobs-to-tame")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".mobs-to-tame"), String.class)) {
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".mob-tame-amounts")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".mob-tame-amounts"), Integer.class)) {
|
2020-08-06 11:32:43 +02:00
|
|
|
final List<String> mobs = config.getStringList("quests." + questKey + ".stages.ordered."
|
2020-04-20 10:19:17 +02:00
|
|
|
+ stageNum + ".mobs-to-tame");
|
2020-08-06 11:32:43 +02:00
|
|
|
final List<Integer> mobAmounts = config.getIntegerList("quests." + questKey + ".stages.ordered."
|
2020-04-16 01:18:06 +02:00
|
|
|
+ stageNum + ".mob-tame-amounts");
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final String mob : mobs) {
|
2021-08-19 15:43:48 +02:00
|
|
|
if (mob != null) {
|
|
|
|
final Class<? extends Entity> ec = EntityType.valueOf(mob.toUpperCase())
|
|
|
|
.getEntityClass();
|
|
|
|
if (ec != null && Tameable.class.isAssignableFrom(ec)) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.addMobToTame(EntityType.valueOf(mob.toUpperCase()));
|
|
|
|
oStage.addMobNumToTame(mobAmounts.get(mobs.indexOf(mob)));
|
2021-08-19 15:43:48 +02:00
|
|
|
} else {
|
|
|
|
throw new StageFormatException("mobs-to-tame has invalid tameable mob " + mob,
|
|
|
|
quest, stageNum);
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
2021-08-19 15:43:48 +02:00
|
|
|
throw new StageFormatException("mobs-to-tame has invalid mob", quest, stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2020-04-20 10:19:17 +02:00
|
|
|
throw new StageFormatException("mob-tame-amounts is not a list of numbers", quest,
|
|
|
|
stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("mob-tame-amounts is missing", quest, stageNum);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("mobs-to-tame is not a list of mob names", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".sheep-to-shear")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".sheep-to-shear"), String.class)) {
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".sheep-amounts")) {
|
|
|
|
if (ConfigUtil.checkList(config.getList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".sheep-amounts"), Integer.class)) {
|
2020-08-06 11:32:43 +02:00
|
|
|
final List<String> sheep = config.getStringList("quests." + questKey + ".stages.ordered."
|
2020-04-20 10:19:17 +02:00
|
|
|
+ stageNum + ".sheep-to-shear");
|
2021-08-19 15:43:48 +02:00
|
|
|
final List<Integer> shearAmounts = config.getIntegerList("quests." + questKey
|
|
|
|
+ ".stages.ordered." + stageNum + ".sheep-amounts");
|
2022-01-14 22:16:33 +01:00
|
|
|
for (String sheepColor : sheep) {
|
|
|
|
final String originalColor = sheepColor;
|
2020-04-17 08:55:02 +02:00
|
|
|
DyeColor dc = null;
|
2022-01-14 22:16:33 +01:00
|
|
|
if (sheepColor.equalsIgnoreCase("NULL")) {
|
2020-04-17 08:55:02 +02:00
|
|
|
dc = DyeColor.WHITE;
|
2020-04-17 05:48:42 +02:00
|
|
|
}
|
2022-01-14 22:16:33 +01:00
|
|
|
sheepColor = sheepColor.replace(" ", "_");
|
2020-04-16 01:18:06 +02:00
|
|
|
try {
|
|
|
|
if (dc == null) {
|
2021-11-08 05:34:12 +01:00
|
|
|
for (final DyeColor val : DyeColor.values()) {
|
2022-01-14 22:16:33 +01:00
|
|
|
if (val.name().replace("_", "").equalsIgnoreCase(sheepColor
|
|
|
|
.replace("_", ""))) {
|
2021-11-08 05:34:12 +01:00
|
|
|
dc = val;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2020-08-06 11:32:43 +02:00
|
|
|
} catch (final IllegalArgumentException e) {
|
2020-04-16 01:18:06 +02:00
|
|
|
// Fail silently
|
|
|
|
}
|
|
|
|
if (dc != null) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.addSheepToShear(dc);
|
2022-01-23 20:59:05 +01:00
|
|
|
// Legacy start -->
|
2022-01-14 22:16:33 +01:00
|
|
|
} else if (sheepColor.equalsIgnoreCase(Lang.get("COLOR_BLACK"))) {
|
2022-01-23 20:59:05 +01:00
|
|
|
oStage.addSheepToShear(DyeColor.BLACK);
|
2022-01-14 22:16:33 +01:00
|
|
|
} else if (sheepColor.equalsIgnoreCase(Lang.get("COLOR_BLUE"))) {
|
2022-01-23 20:59:05 +01:00
|
|
|
oStage.addSheepToShear(DyeColor.BLUE);
|
2022-01-14 22:16:33 +01:00
|
|
|
} else if (sheepColor.equalsIgnoreCase(Lang.get("COLOR_BROWN"))) {
|
2022-01-23 20:59:05 +01:00
|
|
|
oStage.addSheepToShear(DyeColor.BROWN);
|
2022-01-14 22:16:33 +01:00
|
|
|
} else if (sheepColor.equalsIgnoreCase(Lang.get("COLOR_CYAN"))) {
|
2022-01-23 20:59:05 +01:00
|
|
|
oStage.addSheepToShear(DyeColor.CYAN);
|
2022-01-14 22:16:33 +01:00
|
|
|
} else if (sheepColor.equalsIgnoreCase(Lang.get("COLOR_GRAY"))) {
|
2022-01-23 20:59:05 +01:00
|
|
|
oStage.addSheepToShear(DyeColor.GRAY);
|
2022-01-14 22:16:33 +01:00
|
|
|
} else if (sheepColor.equalsIgnoreCase(Lang.get("COLOR_GREEN"))) {
|
2022-01-23 20:59:05 +01:00
|
|
|
oStage.addSheepToShear(DyeColor.GREEN);
|
2022-01-14 22:16:33 +01:00
|
|
|
} else if (sheepColor.equalsIgnoreCase(Lang.get("COLOR_LIGHT_BLUE"))) {
|
2022-01-23 20:59:05 +01:00
|
|
|
oStage.addSheepToShear(DyeColor.LIGHT_BLUE);
|
2022-01-14 22:16:33 +01:00
|
|
|
} else if (sheepColor.equalsIgnoreCase(Lang.get("COLOR_LIME"))) {
|
2022-01-23 20:59:05 +01:00
|
|
|
oStage.addSheepToShear(DyeColor.LIME);
|
2022-01-14 22:16:33 +01:00
|
|
|
} else if (sheepColor.equalsIgnoreCase(Lang.get("COLOR_MAGENTA"))) {
|
2022-01-23 20:59:05 +01:00
|
|
|
oStage.addSheepToShear(DyeColor.MAGENTA);
|
2022-01-14 22:16:33 +01:00
|
|
|
} else if (sheepColor.equalsIgnoreCase(Lang.get("COLOR_ORANGE"))) {
|
2022-01-23 20:59:05 +01:00
|
|
|
oStage.addSheepToShear(DyeColor.ORANGE);
|
2022-01-14 22:16:33 +01:00
|
|
|
} else if (sheepColor.equalsIgnoreCase(Lang.get("COLOR_PINK"))) {
|
2022-01-23 20:59:05 +01:00
|
|
|
oStage.addSheepToShear(DyeColor.PINK);
|
2022-01-14 22:16:33 +01:00
|
|
|
} else if (sheepColor.equalsIgnoreCase(Lang.get("COLOR_PURPLE"))) {
|
2022-01-23 20:59:05 +01:00
|
|
|
oStage.addSheepToShear(DyeColor.PURPLE);
|
2022-01-14 22:16:33 +01:00
|
|
|
} else if (sheepColor.equalsIgnoreCase(Lang.get("COLOR_RED"))) {
|
2022-01-23 20:59:05 +01:00
|
|
|
oStage.addSheepToShear(DyeColor.RED);
|
2022-01-14 22:16:33 +01:00
|
|
|
} else if (sheepColor.equalsIgnoreCase(Lang.get("COLOR_SILVER"))) {
|
2020-04-16 01:18:06 +02:00
|
|
|
// 1.13 changed DyeColor.SILVER -> DyeColor.LIGHT_GRAY
|
2022-01-23 20:59:05 +01:00
|
|
|
oStage.addSheepToShear(DyeColor.getByColor(Color.SILVER));
|
2022-01-14 22:16:33 +01:00
|
|
|
} else if (sheepColor.equalsIgnoreCase(Lang.get("COLOR_WHITE"))) {
|
2022-01-23 20:59:05 +01:00
|
|
|
oStage.addSheepToShear(DyeColor.WHITE);
|
2022-01-14 22:16:33 +01:00
|
|
|
} else if (sheepColor.equalsIgnoreCase(Lang.get("COLOR_YELLOW"))) {
|
2022-01-23 20:59:05 +01:00
|
|
|
oStage.addSheepToShear(DyeColor.YELLOW);
|
|
|
|
// <-- Legacy end
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
2022-01-14 22:16:33 +01:00
|
|
|
throw new StageFormatException("sheep-to-shear has invalid color " + sheepColor,
|
|
|
|
quest, stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2022-01-23 20:07:59 +01:00
|
|
|
oStage.addSheepNumToShear(shearAmounts.get(sheep.indexOf(originalColor)));
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("sheep-amounts is not a list of numbers", quest, stageNum);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("sheep-amounts is missing", quest, stageNum);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("sheep-to-shear is not a list of colors", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".password-displays")) {
|
2020-08-06 11:32:43 +02:00
|
|
|
final List<String> displays = config.getStringList("quests." + questKey + ".stages.ordered." + stageNum
|
2020-04-16 01:18:06 +02:00
|
|
|
+ ".password-displays");
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".password-phrases")) {
|
2022-01-14 22:16:33 +01:00
|
|
|
final List<String> phrases = config.getStringList("quests." + questKey + ".stages.ordered."
|
|
|
|
+ stageNum + ".password-phrases");
|
2020-04-16 01:18:06 +02:00
|
|
|
if (displays.size() == phrases.size()) {
|
|
|
|
for (int passIndex = 0; passIndex < displays.size(); passIndex++) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.addPasswordDisplay(displays.get(passIndex));
|
|
|
|
oStage.addPasswordPhrase(phrases.get(passIndex));
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
} else {
|
2020-04-20 10:19:17 +02:00
|
|
|
throw new StageFormatException("password-displays and password-phrases are not the same size",
|
|
|
|
quest, stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("password-phrases is missing", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".objective-override")) {
|
2020-08-06 11:32:43 +02:00
|
|
|
final Object o = config.get("quests." + questKey + ".stages.ordered." + stageNum
|
2020-04-16 01:18:06 +02:00
|
|
|
+ ".objective-override");
|
|
|
|
if (o instanceof List) {
|
2022-01-12 21:10:01 +01:00
|
|
|
for (String objectiveOverride : config.getStringList("quests." + questKey
|
|
|
|
+ ".stages.ordered." + stageNum + ".objective-override")) {
|
|
|
|
oStage.addObjectiveOverride(objectiveOverride);
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
// Legacy
|
2020-08-06 11:32:43 +02:00
|
|
|
final String s = config.getString("quests." + questKey + ".stages.ordered." + stageNum
|
2020-04-16 01:18:06 +02:00
|
|
|
+ ".objective-override");
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.addObjectiveOverride(s);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".start-event")) {
|
2022-01-19 03:15:49 +01:00
|
|
|
final Action action = loadAction(config.getString("quests." + questKey + ".stages.ordered." + stageNum
|
2020-04-16 01:18:06 +02:00
|
|
|
+ ".start-event"));
|
|
|
|
if (action != null) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.setStartAction(action);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new StageFormatException("start-event failed to load", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".finish-event")) {
|
2022-01-19 03:15:49 +01:00
|
|
|
final Action action = loadAction(config.getString("quests." + questKey + ".stages.ordered." + stageNum
|
2020-04-16 01:18:06 +02:00
|
|
|
+ ".finish-event"));
|
|
|
|
if (action != null) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.setFinishAction(action);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new StageFormatException("finish-event failed to load", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
2020-08-28 07:38:29 +02:00
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".fail-event")) {
|
2022-01-19 03:15:49 +01:00
|
|
|
final Action action = loadAction(config.getString("quests." + questKey + ".stages.ordered." + stageNum
|
2020-08-28 07:38:29 +02:00
|
|
|
+ ".fail-event"));
|
|
|
|
if (action != null) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.setFailAction(action);
|
2020-08-28 07:38:29 +02:00
|
|
|
} else {
|
|
|
|
throw new StageFormatException("fail-event failed to load", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".death-event")) {
|
2022-01-19 03:15:49 +01:00
|
|
|
final Action action = loadAction(config.getString("quests." + questKey + ".stages.ordered." + stageNum
|
2020-04-16 01:18:06 +02:00
|
|
|
+ ".death-event"));
|
|
|
|
if (action != null) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.setDeathAction(action);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new StageFormatException("death-event failed to load", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".disconnect-event")) {
|
2022-01-19 03:15:49 +01:00
|
|
|
final Action action = loadAction(config.getString("quests." + questKey + ".stages.ordered." + stageNum
|
2020-04-16 01:18:06 +02:00
|
|
|
+ ".disconnect-event"));
|
|
|
|
if (action != null) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.setDisconnectAction(action);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
|
|
|
throw new StageFormatException("disconnect-event failed to load", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".chat-events")) {
|
|
|
|
if (config.isList("quests." + questKey + ".stages.ordered." + stageNum + ".chat-events")) {
|
2020-04-20 10:19:17 +02:00
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".chat-event-triggers")) {
|
|
|
|
if (config.isList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".chat-event-triggers")) {
|
2022-01-12 21:10:01 +01:00
|
|
|
final List<String> chatEvents = config.getStringList("quests." + questKey
|
|
|
|
+ ".stages.ordered." + stageNum + ".chat-events");
|
2020-08-06 11:32:43 +02:00
|
|
|
final List<String> chatEventTriggers = config.getStringList("quests." + questKey
|
2020-04-16 01:18:06 +02:00
|
|
|
+ ".stages.ordered." + stageNum + ".chat-event-triggers");
|
|
|
|
for (int i = 0; i < chatEvents.size(); i++) {
|
2020-08-06 11:32:43 +02:00
|
|
|
final Action action = loadAction(chatEvents.get(i));
|
2020-04-16 01:18:06 +02:00
|
|
|
if (action != null) {
|
2020-04-29 00:04:39 +02:00
|
|
|
if (i < chatEventTriggers.size()) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.addChatAction(new AbstractMap.SimpleEntry<>(chatEventTriggers.get(i),
|
|
|
|
action));
|
2020-04-29 00:04:39 +02:00
|
|
|
} else {
|
|
|
|
throw new StageFormatException("chat-event-triggers list is too small",
|
|
|
|
quest, stageNum);
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
2020-04-20 10:19:17 +02:00
|
|
|
throw new StageFormatException("chat-events failed to load " + chatEvents.get(i),
|
|
|
|
quest, stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2020-04-20 10:19:17 +02:00
|
|
|
throw new StageFormatException("chat-event-triggers is not in list format", quest,
|
|
|
|
stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("chat-event-triggers is missing", quest, stageNum);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("chat-events is not in list format", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".command-events")) {
|
|
|
|
if (config.isList("quests." + questKey + ".stages.ordered." + stageNum + ".command-events")) {
|
2020-04-20 10:19:17 +02:00
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".command-event-triggers")) {
|
|
|
|
if (config.isList("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".command-event-triggers")) {
|
2022-01-12 21:10:01 +01:00
|
|
|
final List<String> commandEvents = config.getStringList("quests." + questKey
|
|
|
|
+ ".stages.ordered." + stageNum + ".command-events");
|
2020-08-06 11:32:43 +02:00
|
|
|
final List<String> commandEventTriggers = config.getStringList("quests." + questKey
|
2020-04-16 01:18:06 +02:00
|
|
|
+ ".stages.ordered." + stageNum + ".command-event-triggers");
|
|
|
|
for (int i = 0; i < commandEvents.size(); i++) {
|
2020-08-06 11:32:43 +02:00
|
|
|
final Action action = loadAction(commandEvents.get(i));
|
2020-04-16 01:18:06 +02:00
|
|
|
if (action != null) {
|
2020-04-29 00:04:39 +02:00
|
|
|
if (i < commandEventTriggers.size()) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.addCommandAction(new AbstractMap.SimpleEntry<>(commandEventTriggers
|
|
|
|
.get(i), action));
|
2020-04-29 00:04:39 +02:00
|
|
|
} else {
|
|
|
|
throw new StageFormatException("command-event-triggers list is too small",
|
|
|
|
quest, stageNum);
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
2020-04-20 10:19:17 +02:00
|
|
|
throw new StageFormatException("command-events failed to load "
|
|
|
|
+ commandEvents.get(i), quest, stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2020-04-20 10:19:17 +02:00
|
|
|
throw new StageFormatException("command-event-triggers is not in list format", quest,
|
|
|
|
stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("command-event-triggers is missing", quest, stageNum);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new StageFormatException("command-events is not in list format", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
2020-07-13 06:35:28 +02:00
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".condition")) {
|
2022-01-19 03:15:49 +01:00
|
|
|
final Condition condition = loadCondition(config.getString("quests." + questKey + ".stages.ordered."
|
2020-07-13 06:35:28 +02:00
|
|
|
+ stageNum + ".condition"));
|
|
|
|
if (condition != null) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.setCondition(condition);
|
2020-07-13 06:35:28 +02:00
|
|
|
} else {
|
|
|
|
throw new StageFormatException("condition failed to load", quest, stageNum);
|
|
|
|
}
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".delay")) {
|
2022-01-14 21:21:11 +01:00
|
|
|
final int delay = config.getInt("quests." + questKey + ".stages.ordered." + stageNum + ".delay", -999);
|
|
|
|
if (delay > 0) {
|
2022-01-23 20:07:59 +01:00
|
|
|
oStage.setDelay(delay * 1000L);
|
2022-01-14 21:21:11 +01:00
|
|
|
} else if (delay != -999) {
|
|
|
|
throw new StageFormatException("delay is not a positive number", quest, stageNum);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".delay-message")) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.setDelayMessage(config.getString("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".delay-message"));
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".start-message")) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.setStartMessage(config.getString("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".start-message"));
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".complete-message")) {
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.setCompleteMessage(config.getString("quests." + questKey + ".stages.ordered." + stageNum
|
|
|
|
+ ".complete-message"));
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
quest.getStages().add(oStage);
|
|
|
|
}
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
|
|
|
|
@SuppressWarnings({ "unchecked", "deprecation" })
|
2020-08-06 11:32:43 +02:00
|
|
|
protected Action loadAction(final String name) throws ActionFormatException {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (name == null) {
|
|
|
|
return null;
|
|
|
|
}
|
2020-08-06 11:32:43 +02:00
|
|
|
final File legacy = new File(getDataFolder(), "events.yml");
|
|
|
|
final File actions = new File(getDataFolder(), "actions.yml");
|
|
|
|
final FileConfiguration data = new YamlConfiguration();
|
2020-04-16 01:18:06 +02:00
|
|
|
try {
|
|
|
|
if (actions.isFile()) {
|
|
|
|
data.load(actions);
|
|
|
|
} else {
|
|
|
|
data.load(legacy);
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
} catch (final IOException | InvalidConfigurationException e) {
|
2020-04-16 01:18:06 +02:00
|
|
|
e.printStackTrace();
|
|
|
|
}
|
2020-08-06 11:32:43 +02:00
|
|
|
final String legacyName = "events." + name;
|
2020-04-16 01:18:06 +02:00
|
|
|
String actionKey = "actions." + name + ".";
|
|
|
|
if (data.contains(legacyName)) {
|
|
|
|
actionKey = legacyName + ".";
|
|
|
|
}
|
2020-08-06 11:32:43 +02:00
|
|
|
final Action action = new Action(this);
|
2020-04-16 01:18:06 +02:00
|
|
|
action.setName(name);
|
|
|
|
if (data.contains(actionKey + "message")) {
|
|
|
|
action.setMessage(ConfigUtil.parseString(data.getString(actionKey + "message")));
|
|
|
|
}
|
|
|
|
if (data.contains(actionKey + "open-book")) {
|
|
|
|
action.setBook(data.getString(actionKey + "open-book"));
|
|
|
|
}
|
|
|
|
if (data.contains(actionKey + "clear-inventory")) {
|
|
|
|
if (data.isBoolean(actionKey + "clear-inventory")) {
|
|
|
|
action.setClearInv(data.getBoolean(actionKey + "clear-inventory"));
|
|
|
|
} else {
|
|
|
|
throw new ActionFormatException("clear-inventory is not a true/false value", actionKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (data.contains(actionKey + "fail-quest")) {
|
|
|
|
if (data.isBoolean(actionKey + "fail-quest")) {
|
|
|
|
action.setFailQuest(data.getBoolean(actionKey + "fail-quest"));
|
|
|
|
} else {
|
|
|
|
throw new ActionFormatException("fail-quest is not a true/false value", actionKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (data.contains(actionKey + "explosions")) {
|
|
|
|
if (ConfigUtil.checkList(data.getList(actionKey + "explosions"), String.class)) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final LinkedList<Location> explosions = new LinkedList<>();
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final String s : data.getStringList(actionKey + "explosions")) {
|
|
|
|
final Location loc = ConfigUtil.getLocation(s);
|
2020-04-16 01:18:06 +02:00
|
|
|
if (loc == null) {
|
2020-04-20 10:19:17 +02:00
|
|
|
throw new ActionFormatException("explosions is not in proper \"WorldName x y z\" format",
|
|
|
|
actionKey);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
explosions.add(loc);
|
|
|
|
}
|
|
|
|
action.setExplosions(explosions);
|
|
|
|
} else {
|
|
|
|
throw new ActionFormatException("explosions is not a list of locations", actionKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (data.contains(actionKey + "effects")) {
|
|
|
|
if (ConfigUtil.checkList(data.getList(actionKey + "effects"), String.class)) {
|
|
|
|
if (data.contains(actionKey + "effect-locations")) {
|
|
|
|
if (ConfigUtil.checkList(data.getList(actionKey + "effect-locations"), String.class)) {
|
2020-08-06 11:32:43 +02:00
|
|
|
final List<String> effectList = data.getStringList(actionKey + "effects");
|
|
|
|
final List<String> effectLocs = data.getStringList(actionKey + "effect-locations");
|
2021-08-19 15:43:48 +02:00
|
|
|
final Map<Location, Effect> effects = new HashMap<>();
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final String s : effectList) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final Effect effect;
|
2020-04-16 01:18:06 +02:00
|
|
|
try {
|
|
|
|
effect = Effect.valueOf(s.toUpperCase());
|
2020-08-06 11:32:43 +02:00
|
|
|
} catch (final IllegalArgumentException e) {
|
2020-08-24 03:13:40 +02:00
|
|
|
throw new ActionFormatException(s + " is not a valid effect name",
|
2020-04-16 01:18:06 +02:00
|
|
|
actionKey);
|
|
|
|
}
|
2020-08-06 11:32:43 +02:00
|
|
|
final Location l = ConfigUtil.getLocation(effectLocs.get(effectList.indexOf(s)));
|
2020-04-16 01:18:06 +02:00
|
|
|
if (l == null) {
|
|
|
|
throw new ActionFormatException("effect-locations is not in proper \"WorldName x y z\""
|
|
|
|
+ "format", actionKey);
|
|
|
|
}
|
|
|
|
effects.put(l, effect);
|
|
|
|
}
|
|
|
|
action.setEffects(effects);
|
|
|
|
} else {
|
|
|
|
throw new ActionFormatException("effect-locations is not a list of locations", actionKey);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new ActionFormatException("effect-locations is missing", actionKey);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new ActionFormatException("effects is not a list of effects", actionKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (data.contains(actionKey + "items")) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final LinkedList<ItemStack> temp = new LinkedList<>();
|
|
|
|
final List<ItemStack> stackList = (List<ItemStack>) data.get(actionKey + "items");
|
2020-04-16 01:18:06 +02:00
|
|
|
if (ConfigUtil.checkList(stackList, ItemStack.class)) {
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final ItemStack stack : stackList) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (stack != null) {
|
|
|
|
temp.add(stack);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Legacy
|
|
|
|
if (ConfigUtil.checkList(stackList, String.class)) {
|
2020-08-06 11:32:43 +02:00
|
|
|
final List<String> items = data.getStringList(actionKey + "items");
|
|
|
|
for (final String item : items) {
|
2020-04-16 01:18:06 +02:00
|
|
|
try {
|
2020-08-06 11:32:43 +02:00
|
|
|
final ItemStack stack = ItemUtil.readItemStack(item);
|
2020-04-16 01:18:06 +02:00
|
|
|
if (stack != null) {
|
|
|
|
temp.add(stack);
|
|
|
|
}
|
2020-08-06 11:32:43 +02:00
|
|
|
} catch (final Exception e) {
|
2020-04-16 01:18:06 +02:00
|
|
|
throw new ActionFormatException("items is not formatted properly", actionKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new ActionFormatException("items is not a list of items", actionKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
action.setItems(temp);
|
|
|
|
}
|
|
|
|
if (data.contains(actionKey + "storm-world")) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final String world = data.getString(actionKey + "storm-world");
|
|
|
|
if (world != null) {
|
|
|
|
final World stormWorld = getServer().getWorld(world);
|
|
|
|
if (stormWorld == null) {
|
|
|
|
throw new ActionFormatException("storm-world is not a valid world name", actionKey);
|
|
|
|
}
|
|
|
|
if (data.contains(actionKey + "storm-duration")) {
|
|
|
|
if (data.getInt(actionKey + "storm-duration", -999) != -999) {
|
|
|
|
action.setStormDuration(data.getInt(actionKey + "storm-duration") * 1000);
|
|
|
|
} else {
|
|
|
|
throw new ActionFormatException("storm-duration is not a number", actionKey);
|
|
|
|
}
|
|
|
|
action.setStormWorld(stormWorld);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
2021-08-19 15:43:48 +02:00
|
|
|
throw new ActionFormatException("storm-duration is missing", actionKey);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
} else {
|
2021-08-19 15:43:48 +02:00
|
|
|
throw new ActionFormatException("storm-world is not a valid world", actionKey);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (data.contains(actionKey + "thunder-world")) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final String world = data.getString(actionKey + "thunder-world");
|
|
|
|
if (world != null) {
|
|
|
|
final World thunderWorld = getServer().getWorld(world);
|
|
|
|
if (thunderWorld == null) {
|
|
|
|
throw new ActionFormatException("thunder-world is not a valid world name", actionKey);
|
|
|
|
}
|
|
|
|
if (data.contains(actionKey + "thunder-duration")) {
|
|
|
|
if (data.getInt(actionKey + "thunder-duration", -999) != -999) {
|
|
|
|
action.setThunderDuration(data.getInt(actionKey + "thunder-duration"));
|
|
|
|
} else {
|
|
|
|
throw new ActionFormatException("thunder-duration is not a number", actionKey);
|
|
|
|
}
|
|
|
|
action.setThunderWorld(thunderWorld);
|
2020-04-16 01:18:06 +02:00
|
|
|
} else {
|
2021-08-19 15:43:48 +02:00
|
|
|
throw new ActionFormatException("thunder-duration is missing", actionKey);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
} else {
|
2021-08-19 15:43:48 +02:00
|
|
|
throw new ActionFormatException("thunder-world is not a valid world", actionKey);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (data.contains(actionKey + "mob-spawns")) {
|
2020-08-06 11:32:43 +02:00
|
|
|
final ConfigurationSection section = data.getConfigurationSection(actionKey + "mob-spawns");
|
2021-07-10 01:48:00 +02:00
|
|
|
if (section != null) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final LinkedList<QuestMob> mobSpawns = new LinkedList<>();
|
2021-07-10 01:48:00 +02:00
|
|
|
for (final String s : section.getKeys(false)) {
|
|
|
|
final String mobName = section.getString(s + ".name");
|
2021-08-19 15:43:48 +02:00
|
|
|
final String location = section.getString(s + ".spawn-location");
|
|
|
|
if (location != null) {
|
|
|
|
final Location spawnLocation = ConfigUtil.getLocation(location);
|
|
|
|
final EntityType type = MiscUtil.getProperMobType(section.getString(s + ".mob-type"));
|
|
|
|
final int mobAmount = section.getInt(s + ".spawn-amounts");
|
|
|
|
if (spawnLocation == null) {
|
|
|
|
throw new ActionFormatException("mob-spawn-locations is not in proper \"WorldName x y z\" format",
|
|
|
|
actionKey);
|
|
|
|
}
|
|
|
|
if (type == null) {
|
|
|
|
throw new ActionFormatException("mob-spawn-types is not a list of mob types", actionKey);
|
|
|
|
}
|
|
|
|
final ItemStack[] inventory = new ItemStack[5];
|
|
|
|
final Float[] dropChances = new Float[5];
|
|
|
|
inventory[0] = ItemUtil.readItemStack(section.getString(s + ".held-item"));
|
|
|
|
dropChances[0] = (float) section.getDouble(s + ".held-item-drop-chance");
|
|
|
|
inventory[1] = ItemUtil.readItemStack(section.getString(s + ".boots"));
|
|
|
|
dropChances[1] = (float) section.getDouble(s + ".boots-drop-chance");
|
|
|
|
inventory[2] = ItemUtil.readItemStack(section.getString(s + ".leggings"));
|
|
|
|
dropChances[2] = (float) section.getDouble(s + ".leggings-drop-chance");
|
|
|
|
inventory[3] = ItemUtil.readItemStack(section.getString(s + ".chest-plate"));
|
|
|
|
dropChances[3] = (float) section.getDouble(s + ".chest-plate-drop-chance");
|
|
|
|
inventory[4] = ItemUtil.readItemStack(section.getString(s + ".helmet"));
|
|
|
|
dropChances[4] = (float) section.getDouble(s + ".helmet-drop-chance");
|
2022-01-12 21:10:01 +01:00
|
|
|
final QuestMob questMob = new BukkitQuestMob(type, spawnLocation, mobAmount);
|
2021-08-19 15:43:48 +02:00
|
|
|
questMob.setInventory(inventory);
|
|
|
|
questMob.setDropChances(dropChances);
|
|
|
|
questMob.setName(mobName);
|
|
|
|
mobSpawns.add(questMob);
|
|
|
|
} else {
|
|
|
|
throw new ActionFormatException("mob-spawn-locations contains an invalid location", actionKey);
|
2021-07-10 01:48:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
action.setMobSpawns(mobSpawns);
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
if (data.contains(actionKey + "lightning-strikes")) {
|
|
|
|
if (ConfigUtil.checkList(data.getList(actionKey + "lightning-strikes"), String.class)) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final LinkedList<Location> lightningStrikes = new LinkedList<>();
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final String s : data.getStringList(actionKey + "lightning-strikes")) {
|
|
|
|
final Location loc = ConfigUtil.getLocation(s);
|
2020-04-16 01:18:06 +02:00
|
|
|
if (loc == null) {
|
|
|
|
throw new ActionFormatException("lightning-strikes is not in proper \"WorldName x y z\" format",
|
|
|
|
actionKey);
|
|
|
|
}
|
|
|
|
lightningStrikes.add(loc);
|
|
|
|
}
|
|
|
|
action.setLightningStrikes(lightningStrikes);
|
|
|
|
} else {
|
|
|
|
throw new ActionFormatException("lightning-strikes is not a list of locations", actionKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (data.contains(actionKey + "commands")) {
|
|
|
|
if (ConfigUtil.checkList(data.getList(actionKey + "commands"), String.class)) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final LinkedList<String> commands = new LinkedList<>();
|
2020-04-16 01:18:06 +02:00
|
|
|
for (String s : data.getStringList(actionKey + "commands")) {
|
|
|
|
if (s.startsWith("/")) {
|
|
|
|
s = s.replaceFirst("/", "");
|
|
|
|
}
|
|
|
|
commands.add(s);
|
|
|
|
}
|
|
|
|
action.setCommands(commands);
|
|
|
|
} else {
|
|
|
|
throw new ActionFormatException("commands is not a list of commands", actionKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (data.contains(actionKey + "potion-effect-types")) {
|
|
|
|
if (ConfigUtil.checkList(data.getList(actionKey + "potion-effect-types"), String.class)) {
|
|
|
|
if (data.contains(actionKey + "potion-effect-durations")) {
|
|
|
|
if (ConfigUtil.checkList(data.getList(actionKey + "potion-effect-durations"), Integer.class)) {
|
|
|
|
if (data.contains(actionKey + "potion-effect-amplifiers")) {
|
|
|
|
if (ConfigUtil.checkList(data.getList(actionKey + "potion-effect-amplifiers"),
|
|
|
|
Integer.class)) {
|
2020-08-06 11:32:43 +02:00
|
|
|
final List<String> types = data.getStringList(actionKey + "potion-effect-types");
|
|
|
|
final List<Integer> durations = data.getIntegerList(actionKey + "potion-effect-durations");
|
|
|
|
final List<Integer> amplifiers = data.getIntegerList(actionKey + "potion-effect-amplifiers");
|
2021-08-19 15:43:48 +02:00
|
|
|
final LinkedList<PotionEffect> potionEffects = new LinkedList<>();
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final String s : types) {
|
|
|
|
final PotionEffectType type = PotionEffectType.getByName(s);
|
2020-04-16 01:18:06 +02:00
|
|
|
if (type == null) {
|
|
|
|
throw new ActionFormatException("potion-effect-types is not a list of potion "
|
|
|
|
+ "effect types", actionKey);
|
|
|
|
}
|
2020-08-06 11:32:43 +02:00
|
|
|
final PotionEffect effect = new PotionEffect(type, durations
|
2020-04-16 01:18:06 +02:00
|
|
|
.get(types.indexOf(s)), amplifiers.get(types.indexOf(s)));
|
|
|
|
potionEffects.add(effect);
|
|
|
|
}
|
|
|
|
action.setPotionEffects(potionEffects);
|
|
|
|
} else {
|
|
|
|
throw new ActionFormatException("potion-effect-amplifiers is not a list of numbers",
|
|
|
|
actionKey);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new ActionFormatException("potion-effect-amplifiers is missing", actionKey);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new ActionFormatException("potion-effect-durations is not a list of numbers", actionKey);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new ActionFormatException("potion-effect-durations is missing", actionKey);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new ActionFormatException("potion-effect-types is not a list of potion effects", actionKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (data.contains(actionKey + "hunger")) {
|
|
|
|
if (data.getInt(actionKey + "hunger", -999) != -999) {
|
|
|
|
action.setHunger(data.getInt(actionKey + "hunger"));
|
|
|
|
} else {
|
|
|
|
throw new ActionFormatException("hunger is not a number", actionKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (data.contains(actionKey + "saturation")) {
|
|
|
|
if (data.getInt(actionKey + "saturation", -999) != -999) {
|
|
|
|
action.setSaturation(data.getInt(actionKey + "saturation"));
|
|
|
|
} else {
|
|
|
|
throw new ActionFormatException("saturation is not a number", actionKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (data.contains(actionKey + "health")) {
|
|
|
|
if (data.getInt(actionKey + "health", -999) != -999) {
|
|
|
|
action.setHealth(data.getInt(actionKey + "health"));
|
|
|
|
} else {
|
|
|
|
throw new ActionFormatException("health is not a number", actionKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (data.contains(actionKey + "teleport-location")) {
|
|
|
|
if (data.isString(actionKey + "teleport-location")) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final String location = data.getString(actionKey + "teleport-location");
|
|
|
|
if (location != null) {
|
|
|
|
final Location teleport = ConfigUtil.getLocation(location);
|
|
|
|
if (teleport == null) {
|
|
|
|
throw new ActionFormatException("teleport-location is not in proper \"WorldName x y z\" format",
|
|
|
|
actionKey);
|
|
|
|
}
|
|
|
|
action.setTeleport(teleport);
|
|
|
|
} else {
|
|
|
|
throw new ActionFormatException("teleport-location has invalid location", actionKey);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new ActionFormatException("teleport-location is not a location", actionKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (data.contains(actionKey + "timer")) {
|
|
|
|
if (data.isInt(actionKey + "timer")) {
|
|
|
|
action.setTimer(data.getInt(actionKey + "timer"));
|
|
|
|
} else {
|
|
|
|
throw new ActionFormatException("timer is not a number", actionKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (data.contains(actionKey + "cancel-timer")) {
|
|
|
|
if (data.isBoolean(actionKey + "cancel-timer")) {
|
|
|
|
action.setCancelTimer(data.getBoolean(actionKey + "cancel-timer"));
|
|
|
|
} else {
|
|
|
|
throw new ActionFormatException("cancel-timer is not a true/false value", actionKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (data.contains(actionKey + "denizen-script")) {
|
|
|
|
action.setDenizenScript(data.getString(actionKey + "denizen-script"));
|
|
|
|
}
|
|
|
|
return action;
|
|
|
|
}
|
|
|
|
|
2020-08-06 11:32:43 +02:00
|
|
|
protected Condition loadCondition(final String name) throws ConditionFormatException {
|
2020-07-13 06:35:28 +02:00
|
|
|
if (name == null) {
|
|
|
|
return null;
|
|
|
|
}
|
2020-08-06 11:32:43 +02:00
|
|
|
final File conditions = new File(getDataFolder(), "conditions.yml");
|
|
|
|
final FileConfiguration data = new YamlConfiguration();
|
2020-07-13 06:35:28 +02:00
|
|
|
try {
|
|
|
|
if (conditions.isFile()) {
|
|
|
|
data.load(conditions);
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
} catch (final IOException | InvalidConfigurationException e) {
|
2020-07-13 06:35:28 +02:00
|
|
|
e.printStackTrace();
|
|
|
|
}
|
2020-08-06 11:32:43 +02:00
|
|
|
final String conditionKey = "conditions." + name + ".";
|
|
|
|
final Condition condition = new Condition(this);
|
2020-07-13 06:35:28 +02:00
|
|
|
condition.setName(name);
|
|
|
|
if (data.contains(conditionKey + "fail-quest")) {
|
|
|
|
if (data.isBoolean(conditionKey + "fail-quest")) {
|
|
|
|
condition.setFailQuest(data.getBoolean(conditionKey + "fail-quest"));
|
|
|
|
} else {
|
|
|
|
throw new ConditionFormatException("fail-quest is not a true/false value", conditionKey);
|
|
|
|
}
|
2020-10-13 10:19:18 +02:00
|
|
|
}
|
|
|
|
if (data.contains(conditionKey + "ride-entity")) {
|
|
|
|
if (ConfigUtil.checkList(data.getList(conditionKey + "ride-entity"), String.class)) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final LinkedList<String> entities = new LinkedList<>();
|
2020-10-13 10:19:18 +02:00
|
|
|
for (final String s : data.getStringList(conditionKey + "ride-entity")) {
|
|
|
|
final EntityType e = MiscUtil.getProperMobType(s);
|
|
|
|
if (e == null) {
|
|
|
|
throw new ConditionFormatException("ride-entity is not a valid entity type",
|
|
|
|
conditionKey);
|
|
|
|
}
|
|
|
|
entities.add(s);
|
|
|
|
}
|
|
|
|
condition.setEntitiesWhileRiding(entities);
|
|
|
|
} else {
|
|
|
|
throw new ConditionFormatException("ride-entity is not a list of entity types", conditionKey);
|
|
|
|
}
|
2020-10-17 02:40:38 +02:00
|
|
|
}
|
2022-04-26 22:57:47 +02:00
|
|
|
if (data.contains(conditionKey + "ride-npc-uuid")) {
|
|
|
|
if (ConfigUtil.checkList(data.getList(conditionKey + "ride-npc-uuid"), String.class)) {
|
|
|
|
final LinkedList<UUID> npcList = new LinkedList<>();
|
|
|
|
for (final String s : data.getStringList(conditionKey + "ride-npc-uuid")) {
|
|
|
|
final UUID u = UUID.fromString(s);
|
2022-06-04 09:47:44 +02:00
|
|
|
npcList.add(u);
|
2021-01-15 23:18:43 +01:00
|
|
|
}
|
2021-09-27 21:56:22 +02:00
|
|
|
condition.setNpcsWhileRiding(npcList);
|
2022-04-26 22:57:47 +02:00
|
|
|
}
|
|
|
|
} else if (data.contains(conditionKey + "ride-npc")) {
|
|
|
|
// Legacy
|
|
|
|
if (ConfigUtil.checkList(data.getList(conditionKey + "ride-npc"), Integer.class)) {
|
|
|
|
final LinkedList<UUID> npcList = new LinkedList<>();
|
|
|
|
if (getDependencies().getCitizens() != null) {
|
|
|
|
for (final int i : data.getIntegerList(conditionKey + "ride-npc")) {
|
|
|
|
final NPC npc = CitizensAPI.getNPCRegistry().getById(i);
|
|
|
|
if (npc != null) {
|
|
|
|
npcList.add(npc.getUniqueId());
|
|
|
|
} else {
|
|
|
|
throw new ConditionFormatException("ride-npc is not a valid NPC ID",
|
|
|
|
conditionKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
condition.setNpcsWhileRiding(npcList);
|
|
|
|
} else {
|
|
|
|
throw new ConditionFormatException("Citizens not found for ride-npc", conditionKey);
|
|
|
|
}
|
2021-01-15 23:18:43 +01:00
|
|
|
} else {
|
|
|
|
throw new ConditionFormatException("ride-npc is not a list of NPC IDs", conditionKey);
|
|
|
|
}
|
|
|
|
}
|
2020-10-17 02:40:38 +02:00
|
|
|
if (data.contains(conditionKey + "permission")) {
|
|
|
|
if (ConfigUtil.checkList(data.getList(conditionKey + "permission"), String.class)) {
|
2021-09-27 21:56:22 +02:00
|
|
|
final LinkedList<String> permissions
|
|
|
|
= new LinkedList<>(data.getStringList(conditionKey + "permission"));
|
|
|
|
condition.setPermissions(permissions);
|
2020-10-17 02:40:38 +02:00
|
|
|
} else {
|
|
|
|
throw new ConditionFormatException("permission is not a list of permissions", conditionKey);
|
|
|
|
}
|
2020-07-13 06:35:28 +02:00
|
|
|
}
|
|
|
|
if (data.contains(conditionKey + "hold-main-hand")) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final LinkedList<ItemStack> temp = new LinkedList<>();
|
2020-07-13 06:35:28 +02:00
|
|
|
@SuppressWarnings("unchecked")
|
2021-09-27 21:56:22 +02:00
|
|
|
final List<ItemStack> stackList = (List<ItemStack>) data.get(conditionKey + "hold-main-hand");
|
2020-07-13 06:35:28 +02:00
|
|
|
if (ConfigUtil.checkList(stackList, ItemStack.class)) {
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final ItemStack stack : stackList) {
|
2020-07-13 06:35:28 +02:00
|
|
|
if (stack != null) {
|
|
|
|
temp.add(stack);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
condition.setItemsWhileHoldingMainHand(temp);
|
|
|
|
}
|
2020-07-15 19:22:19 +02:00
|
|
|
if (data.contains(conditionKey + "stay-within-world")) {
|
|
|
|
if (ConfigUtil.checkList(data.getList(conditionKey + "stay-within-world"), String.class)) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final LinkedList<String> worlds = new LinkedList<>();
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final String s : data.getStringList(conditionKey + "stay-within-world")) {
|
|
|
|
final World w = getServer().getWorld(s);
|
2020-07-15 19:22:19 +02:00
|
|
|
if (w == null) {
|
|
|
|
throw new ConditionFormatException("stay-within-world is not a valid world",
|
|
|
|
conditionKey);
|
|
|
|
}
|
|
|
|
worlds.add(s);
|
|
|
|
}
|
|
|
|
condition.setWorldsWhileStayingWithin(worlds);
|
|
|
|
} else {
|
|
|
|
throw new ConditionFormatException("stay-within-world is not a list of worlds", conditionKey);
|
|
|
|
}
|
|
|
|
}
|
2020-07-15 00:20:20 +02:00
|
|
|
if (data.contains(conditionKey + "stay-within-biome")) {
|
|
|
|
if (ConfigUtil.checkList(data.getList(conditionKey + "stay-within-biome"), String.class)) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final LinkedList<String> biomes = new LinkedList<>();
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final String s : data.getStringList(conditionKey + "stay-within-biome")) {
|
|
|
|
final Biome b = MiscUtil.getProperBiome(s);
|
2020-07-15 00:20:20 +02:00
|
|
|
if (b == null) {
|
|
|
|
throw new ConditionFormatException("stay-within-biome is not a valid biome",
|
|
|
|
conditionKey);
|
|
|
|
}
|
|
|
|
biomes.add(s);
|
|
|
|
}
|
|
|
|
condition.setBiomesWhileStayingWithin(biomes);
|
|
|
|
} else {
|
|
|
|
throw new ConditionFormatException("stay-within-biome is not a list of biomes", conditionKey);
|
|
|
|
}
|
|
|
|
}
|
2020-10-23 02:15:25 +02:00
|
|
|
if (data.contains(conditionKey + "stay-within-region")) {
|
|
|
|
if (ConfigUtil.checkList(data.getList(conditionKey + "stay-within-region"), String.class)) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final LinkedList<String> regions = new LinkedList<>();
|
|
|
|
for (final String region : data.getStringList(conditionKey + "stay-within-region")) {
|
|
|
|
if (region != null) {
|
|
|
|
boolean exists = false;
|
|
|
|
for (final World world : getServer().getWorlds()) {
|
|
|
|
if (world != null && getDependencies().getWorldGuardApi().getRegionManager(world) != null) {
|
|
|
|
if (Objects.requireNonNull(getDependencies().getWorldGuardApi().getRegionManager(world))
|
|
|
|
.hasRegion(region)) {
|
|
|
|
regions.add(region);
|
|
|
|
exists = true;
|
|
|
|
break;
|
|
|
|
}
|
2020-10-23 02:15:25 +02:00
|
|
|
}
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
if (!exists) {
|
|
|
|
throw new ConditionFormatException("region has invalid WorldGuard region name", conditionKey);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new ConditionFormatException("region has invalid WorldGuard region", conditionKey);
|
2020-10-23 02:15:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
condition.setRegionsWhileStayingWithin(regions);
|
|
|
|
} else {
|
|
|
|
throw new ConditionFormatException("stay-within-region is not a list of regions", conditionKey);
|
|
|
|
}
|
|
|
|
}
|
2020-10-27 11:05:15 +01:00
|
|
|
if (data.contains(conditionKey + "check-placeholder-id")) {
|
|
|
|
if (ConfigUtil.checkList(data.getList(conditionKey + "check-placeholder-id"), String.class)) {
|
2021-09-21 20:44:35 +02:00
|
|
|
final LinkedList<String> id = new LinkedList<>(data.getStringList(conditionKey
|
|
|
|
+ "check-placeholder-id"));
|
|
|
|
condition.setPlaceholdersCheckIdentifier(id);
|
2020-10-27 11:05:15 +01:00
|
|
|
} else {
|
|
|
|
throw new ConditionFormatException("check-placeholder-id is not a list of identifiers", conditionKey);
|
|
|
|
}
|
2021-09-21 20:44:35 +02:00
|
|
|
if (ConfigUtil.checkList(data.getList(conditionKey + "check-placeholder-value"), String.class)) {
|
|
|
|
final LinkedList<String> val = new LinkedList<>(data.getStringList(conditionKey
|
|
|
|
+ "check-placeholder-value"));
|
|
|
|
condition.setPlaceholdersCheckValue(val);
|
|
|
|
} else {
|
|
|
|
throw new ConditionFormatException("check-placeholder-value is not a list of values", conditionKey);
|
|
|
|
}
|
2020-10-27 11:05:15 +01:00
|
|
|
}
|
2020-07-13 06:35:28 +02:00
|
|
|
return condition;
|
|
|
|
}
|
|
|
|
|
2022-01-19 03:15:49 +01:00
|
|
|
private void loadCustomSections(final IQuest quest, final FileConfiguration config, final String questKey)
|
2020-04-16 01:18:06 +02:00
|
|
|
throws StageFormatException, QuestFormatException {
|
2022-02-18 07:40:02 +01:00
|
|
|
final ConfigurationSection questStages = config.getConfigurationSection("quests." + questKey
|
|
|
|
+ ".stages.ordered");
|
2021-07-10 01:48:00 +02:00
|
|
|
if (questStages != null) {
|
|
|
|
for (final String stageNum : questStages.getKeys(false)) {
|
|
|
|
if (quest == null) {
|
2022-02-18 07:40:02 +01:00
|
|
|
getLogger().warning("Unable to consider custom objectives because quest for " + questKey
|
|
|
|
+ " was null");
|
2021-07-10 01:48:00 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (quest.getStage(Integer.parseInt(stageNum) - 1) == null) {
|
2022-02-18 07:40:02 +01:00
|
|
|
getLogger().severe("Unable to load custom objectives because stage" + (Integer.parseInt(stageNum)
|
|
|
|
- 1) + " for " + quest.getName() + " was null");
|
2021-07-10 01:48:00 +02:00
|
|
|
return;
|
|
|
|
}
|
2022-01-23 06:29:15 +01:00
|
|
|
final IStage oStage = quest.getStage(Integer.parseInt(stageNum) - 1);
|
2022-01-12 21:10:01 +01:00
|
|
|
oStage.clearCustomObjectives();
|
|
|
|
oStage.clearCustomObjectiveCounts();
|
|
|
|
oStage.clearCustomObjectiveData();
|
|
|
|
oStage.clearCustomObjectiveDisplays();
|
2021-07-10 01:48:00 +02:00
|
|
|
if (config.contains("quests." + questKey + ".stages.ordered." + stageNum + ".custom-objectives")) {
|
2022-02-18 07:40:02 +01:00
|
|
|
final ConfigurationSection sec = config.getConfigurationSection("quests." + questKey
|
|
|
|
+ ".stages.ordered." + stageNum + ".custom-objectives");
|
2021-08-19 15:43:48 +02:00
|
|
|
if (sec != null) {
|
|
|
|
for (final String path : sec.getKeys(false)) {
|
|
|
|
final String name = sec.getString(path + ".name");
|
|
|
|
final int count = sec.getInt(path + ".count");
|
2022-01-19 03:15:49 +01:00
|
|
|
Optional<ICustomObjective> found = Optional.empty();
|
|
|
|
for (final ICustomObjective cr : customObjectives) {
|
2021-08-19 15:43:48 +02:00
|
|
|
if (cr.getName().equalsIgnoreCase(name)) {
|
|
|
|
found = Optional.of(cr);
|
|
|
|
break;
|
|
|
|
}
|
2021-07-10 01:48:00 +02:00
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
if (found.isPresent()) {
|
2022-01-13 17:02:43 +01:00
|
|
|
oStage.addCustomObjectives(found.get());
|
|
|
|
oStage.addCustomObjectiveCounts(Math.max(count, 0));
|
2021-08-19 15:43:48 +02:00
|
|
|
final ConfigurationSection sec2 = sec.getConfigurationSection(path + ".data");
|
|
|
|
for (final Entry<String,Object> prompt : found.get().getData()) {
|
|
|
|
final Entry<String, Object> data = populateCustoms(sec2, prompt);
|
2022-01-13 17:02:43 +01:00
|
|
|
oStage.addCustomObjectiveData(data);
|
2021-08-19 15:43:48 +02:00
|
|
|
}
|
2021-07-10 01:48:00 +02:00
|
|
|
} else {
|
2022-01-23 06:29:15 +01:00
|
|
|
throw new QuestFormatException(name + " custom objective not found for IStage "
|
2021-08-19 15:43:48 +02:00
|
|
|
+ stageNum, questKey);
|
2021-07-10 01:48:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-07-10 01:48:00 +02:00
|
|
|
final Rewards rews = quest.getRewards();
|
|
|
|
if (config.contains("quests." + questKey + ".rewards.custom-rewards")) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final ConfigurationSection sec = config.getConfigurationSection("quests." + questKey
|
|
|
|
+ ".rewards.custom-rewards");
|
|
|
|
final Map<String, Map<String, Object>> temp = new HashMap<>();
|
|
|
|
if (sec != null) {
|
|
|
|
for (final String path : sec.getKeys(false)) {
|
|
|
|
final String name = sec.getString(path + ".name");
|
2022-01-19 03:15:49 +01:00
|
|
|
Optional<CustomReward> found = Optional.empty();
|
2021-08-19 15:43:48 +02:00
|
|
|
for (final CustomReward cr : customRewards) {
|
|
|
|
if (cr.getName().equalsIgnoreCase(name)) {
|
2022-01-19 03:15:49 +01:00
|
|
|
found = Optional.of(cr);
|
2021-08-19 15:43:48 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (found.isPresent()) {
|
|
|
|
final ConfigurationSection sec2 = sec.getConfigurationSection(path + ".data");
|
|
|
|
final Map<String, Object> data = populateCustoms(sec2, found.get().getData());
|
|
|
|
temp.put(name, data);
|
|
|
|
} else {
|
|
|
|
throw new QuestFormatException(name + " custom reward not found", questKey);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-07-10 01:48:00 +02:00
|
|
|
rews.setCustomRewards(temp);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-07-10 01:48:00 +02:00
|
|
|
final Requirements reqs = quest.getRequirements();
|
|
|
|
if (config.contains("quests." + questKey + ".requirements.custom-requirements")) {
|
|
|
|
final ConfigurationSection sec = config.getConfigurationSection("quests." + questKey
|
|
|
|
+ ".requirements.custom-requirements");
|
2021-08-19 15:43:48 +02:00
|
|
|
final Map<String, Map<String, Object>> temp = new HashMap<>();
|
|
|
|
if (sec != null) {
|
|
|
|
for (final String path : sec.getKeys(false)) {
|
|
|
|
final String name = sec.getString(path + ".name");
|
2022-01-19 03:15:49 +01:00
|
|
|
Optional<CustomRequirement> found = Optional.empty();
|
2021-08-19 15:43:48 +02:00
|
|
|
for (final CustomRequirement cr : customRequirements) {
|
|
|
|
if (cr.getName().equalsIgnoreCase(name)) {
|
2022-01-19 03:15:49 +01:00
|
|
|
found = Optional.of(cr);
|
2021-08-19 15:43:48 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (found.isPresent()) {
|
|
|
|
final ConfigurationSection sec2 = sec.getConfigurationSection(path + ".data");
|
2022-01-19 03:15:49 +01:00
|
|
|
final Map<String, Object> data = populateCustoms(sec2, found.get().getData());
|
2021-08-19 15:43:48 +02:00
|
|
|
temp.put(name, data);
|
|
|
|
} else {
|
|
|
|
throw new QuestFormatException(name + " custom requirement not found", questKey);
|
2021-07-10 01:48:00 +02:00
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
2021-07-10 01:48:00 +02:00
|
|
|
reqs.setCustomRequirements(temp);
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Permits use of fallbacks for customs maps<p>
|
|
|
|
*
|
|
|
|
* Avoid null objects in datamap by initializing the entry value with empty string if no fallback present.
|
|
|
|
*
|
|
|
|
* @param section The section of configuration to check
|
2021-08-19 15:43:48 +02:00
|
|
|
* @param dataMap The map to process
|
2020-04-16 01:18:06 +02:00
|
|
|
* @return Populated map
|
|
|
|
*/
|
2021-08-19 15:43:48 +02:00
|
|
|
private static Map<String, Object> populateCustoms(final ConfigurationSection section,
|
|
|
|
final Map<String, Object> dataMap) {
|
|
|
|
final Map<String,Object> data = new HashMap<>();
|
2020-04-16 01:18:06 +02:00
|
|
|
if (section != null) {
|
2021-08-19 15:43:48 +02:00
|
|
|
for (final String key : dataMap.keySet()) {
|
|
|
|
data.put(key, section.contains(key) ? section.get(key) : dataMap.get(key) != null
|
|
|
|
? dataMap.get(key) : "");
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Permits use of fallbacks for customs entries<p>
|
|
|
|
*
|
|
|
|
* Avoid null objects in datamap by initializing the entry value with empty string if no fallback present.
|
|
|
|
*
|
|
|
|
* @param section The section of configuration to check
|
2021-08-19 15:43:48 +02:00
|
|
|
* @param dataMap The entry to process
|
|
|
|
* @return Populated entry, or null
|
2020-04-16 01:18:06 +02:00
|
|
|
*/
|
2021-08-19 15:43:48 +02:00
|
|
|
private static Entry<String, Object> populateCustoms(final ConfigurationSection section,
|
|
|
|
final Entry<String, Object> dataMap) {
|
|
|
|
Entry<String, Object> data = null;
|
2020-04-16 01:18:06 +02:00
|
|
|
if (section != null) {
|
2021-08-19 15:43:48 +02:00
|
|
|
final String key = dataMap.getKey();
|
|
|
|
final Object value = dataMap.getValue();
|
|
|
|
data = new AbstractMap.SimpleEntry<>(key, section.contains(key) ? section.get(key) : value != null
|
|
|
|
? value : "");
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
return data;
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Load actions from file
|
|
|
|
*/
|
|
|
|
public void loadActions() {
|
2020-08-06 11:32:43 +02:00
|
|
|
final YamlConfiguration config = new YamlConfiguration();
|
|
|
|
final File legacyFile = new File(this.getDataFolder(), "events.yml");
|
|
|
|
final File actionsFile = new File(this.getDataFolder(), "actions.yml");
|
2021-09-06 04:34:05 +02:00
|
|
|
// Using #isFile because #exists and #renameTo can return false positives
|
2020-04-16 01:18:06 +02:00
|
|
|
if (legacyFile.isFile()) {
|
|
|
|
try {
|
2021-08-19 15:43:48 +02:00
|
|
|
if (legacyFile.renameTo(actionsFile)) {
|
|
|
|
getLogger().log(Level.INFO, "Renamed legacy events.yml to actions.yml");
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
if (actionsFile.isFile()) {
|
2021-08-19 15:43:48 +02:00
|
|
|
getLogger().log(Level.INFO, "Successfully deleted legacy events.yml");
|
|
|
|
if (legacyFile.delete()) {
|
|
|
|
getLogger().log(Level.INFO, "Done!");
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2020-08-06 11:32:43 +02:00
|
|
|
} catch (final Exception e) {
|
2021-08-19 15:43:48 +02:00
|
|
|
getLogger().log(Level.WARNING, "Unable to convert events.yml to actions.yml");
|
2020-04-16 01:18:06 +02:00
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (actionsFile.length() != 0) {
|
|
|
|
try {
|
|
|
|
if (actionsFile.isFile()) {
|
|
|
|
config.load(actionsFile);
|
|
|
|
} else {
|
|
|
|
config.load(legacyFile);
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
} catch (final IOException | InvalidConfigurationException e) {
|
2020-04-16 01:18:06 +02:00
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
ConfigurationSection sec = config.getConfigurationSection("actions");
|
|
|
|
if (sec == null) {
|
|
|
|
getLogger().log(Level.INFO,
|
|
|
|
"Could not find section \"actions\" from actions.yml. Trying legacy \"events\"...");
|
|
|
|
sec = config.getConfigurationSection("events");
|
|
|
|
}
|
|
|
|
if (sec != null) {
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final String s : sec.getKeys(false)) {
|
2020-04-16 01:18:06 +02:00
|
|
|
Action action = null;
|
|
|
|
try {
|
2020-07-13 06:35:28 +02:00
|
|
|
action = loadAction(s);
|
2020-08-06 11:32:43 +02:00
|
|
|
} catch (final ActionFormatException e) {
|
2020-04-16 01:18:06 +02:00
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
if (action != null) {
|
|
|
|
actions.add(action);
|
|
|
|
} else {
|
2022-01-19 03:15:49 +01:00
|
|
|
getLogger().log(Level.SEVERE, "Failed to load IAction \"" + s + "\". Skipping.");
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
getLogger().log(Level.SEVERE, "Could not find beginning section from actions.yml. Skipping.");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
getLogger().log(Level.WARNING, "Empty file actions.yml was not loaded.");
|
|
|
|
}
|
|
|
|
}
|
2020-07-13 06:35:28 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Load conditions from file
|
|
|
|
*/
|
|
|
|
public void loadConditions() {
|
2020-08-06 11:32:43 +02:00
|
|
|
final YamlConfiguration config = new YamlConfiguration();
|
|
|
|
final File conditionsFile = new File(this.getDataFolder(), "conditions.yml");
|
2021-09-06 04:34:05 +02:00
|
|
|
// Using #isFile because #exists and #renameTo can return false positives
|
2020-07-13 06:35:28 +02:00
|
|
|
if (conditionsFile.length() != 0) {
|
|
|
|
try {
|
|
|
|
if (conditionsFile.isFile()) {
|
|
|
|
config.load(conditionsFile);
|
|
|
|
}
|
2021-08-19 15:43:48 +02:00
|
|
|
} catch (final IOException | InvalidConfigurationException e) {
|
2020-07-13 06:35:28 +02:00
|
|
|
e.printStackTrace();
|
|
|
|
}
|
2020-08-06 11:32:43 +02:00
|
|
|
final ConfigurationSection sec = config.getConfigurationSection("conditions");
|
2020-07-13 06:35:28 +02:00
|
|
|
if (sec != null) {
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final String s : sec.getKeys(false)) {
|
2020-07-13 06:35:28 +02:00
|
|
|
Condition condition = null;
|
|
|
|
try {
|
|
|
|
condition = loadCondition(s);
|
2020-08-06 11:32:43 +02:00
|
|
|
} catch (final ConditionFormatException e) {
|
2020-07-13 06:35:28 +02:00
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
if (condition != null) {
|
|
|
|
conditions.add(condition);
|
|
|
|
} else {
|
2022-01-19 03:15:49 +01:00
|
|
|
getLogger().log(Level.SEVERE, "Failed to load ICondition \"" + s + "\". Skipping.");
|
2020-07-13 06:35:28 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
getLogger().log(Level.SEVERE, "Could not find beginning section from conditions.yml. Skipping.");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
getLogger().log(Level.WARNING, "Empty file conditions.yml was not loaded.");
|
|
|
|
}
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
|
2020-08-06 11:32:43 +02:00
|
|
|
public static SkillType getMcMMOSkill(final String s) {
|
2020-04-16 01:18:06 +02:00
|
|
|
return SkillType.getSkill(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if player can use Quests
|
|
|
|
*
|
|
|
|
* @param uuid the entity UUID to be checked
|
|
|
|
* @return {@code true} if entity is a Player that has permission
|
|
|
|
*/
|
2020-08-06 11:32:43 +02:00
|
|
|
public boolean canUseQuests(final UUID uuid) {
|
|
|
|
final Player p = Bukkit.getPlayer(uuid);
|
2020-06-01 06:57:14 +02:00
|
|
|
if (p != null) {
|
2020-08-06 11:32:43 +02:00
|
|
|
for (final Permission perm : getDescription().getPermissions()) {
|
2020-06-01 06:57:14 +02:00
|
|
|
if (p.hasPermission(perm.getName())) {
|
2020-05-28 21:04:47 +02:00
|
|
|
return true;
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-05-28 21:04:47 +02:00
|
|
|
return false;
|
2020-04-16 01:18:06 +02:00
|
|
|
}
|
2021-06-21 12:08:44 +02:00
|
|
|
|
|
|
|
/**
|
2021-11-24 10:17:34 +01:00
|
|
|
* Checks if conversable is non-op, non-* player in Trial Mode
|
2021-06-21 12:08:44 +02:00
|
|
|
*
|
|
|
|
* @param conversable the editor user to be checked
|
2021-10-06 07:09:44 +02:00
|
|
|
* @return {@code true} if user is a Player with quests.mode.trial permission
|
2021-06-21 12:08:44 +02:00
|
|
|
*/
|
|
|
|
public boolean hasLimitedAccess(final Conversable conversable) {
|
|
|
|
if (!(conversable instanceof Player)) {
|
|
|
|
return false;
|
|
|
|
}
|
2021-11-11 00:03:08 +01:00
|
|
|
final Player player = ((Player)conversable);
|
2021-11-24 10:17:34 +01:00
|
|
|
if (player.isOp() || player.hasPermission("*")) {
|
2021-11-11 00:03:08 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return player.hasPermission("quests.mode.trial");
|
2021-06-21 12:08:44 +02:00
|
|
|
}
|
2022-02-04 12:41:23 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get a Quest by ID
|
|
|
|
*
|
|
|
|
* @param id ID of the quest
|
|
|
|
* @return Exact match or null if not found
|
|
|
|
* @since 3.8.6
|
|
|
|
*/
|
|
|
|
public Quest getQuestById(final String id) {
|
|
|
|
if (id == null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
for (final IQuest iq : quests) {
|
|
|
|
final Quest q = (Quest) iq;
|
|
|
|
if (q.getId().equals(id)) {
|
|
|
|
return q;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2020-04-16 01:18:06 +02:00
|
|
|
/**
|
|
|
|
* Get a Quest by ID
|
|
|
|
*
|
|
|
|
* @param id ID of the quest
|
|
|
|
* @return Exact match or null if not found
|
|
|
|
* @since 3.8.6
|
2022-02-04 12:41:23 +01:00
|
|
|
* @deprecated Do not use
|
2020-04-16 01:18:06 +02:00
|
|
|
*/
|
2022-02-04 12:41:23 +01:00
|
|
|
public IQuest getQuestByIdTemp(final String id) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (id == null) {
|
|
|
|
return null;
|
|
|
|
}
|
2022-01-19 03:15:49 +01:00
|
|
|
for (final IQuest q : quests) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (q.getId().equals(id)) {
|
|
|
|
return q;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
2022-02-04 12:41:23 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get a Quest by name
|
|
|
|
*
|
|
|
|
* @param name Name of the quest
|
|
|
|
* @return Closest match or null if not found
|
|
|
|
*/
|
|
|
|
public Quest getQuest(final String name) {
|
|
|
|
if (name == null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
for (final IQuest iq : quests) {
|
|
|
|
final Quest q = (Quest) iq;
|
|
|
|
if (q.getName().equalsIgnoreCase(ChatColor.translateAlternateColorCodes('&', name))) {
|
|
|
|
return q;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (final IQuest iq : quests) {
|
|
|
|
final Quest q = (Quest) iq;
|
|
|
|
if (q.getName().toLowerCase().startsWith(ChatColor.translateAlternateColorCodes('&', name).toLowerCase())) {
|
|
|
|
return q;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (final IQuest iq : quests) {
|
|
|
|
final Quest q = (Quest) iq;
|
|
|
|
if (q.getName().toLowerCase().contains(ChatColor.translateAlternateColorCodes('&', name).toLowerCase())) {
|
|
|
|
return q;
|
|
|
|
}
|
|
|
|
}
|
2022-03-24 06:28:51 +01:00
|
|
|
for (final IQuest iq : quests) {
|
|
|
|
// For tab completion
|
|
|
|
final Quest q = (Quest) iq;
|
|
|
|
if (ChatColor.stripColor(q.getName()).equals(ChatColor.stripColor(ChatColor
|
|
|
|
.translateAlternateColorCodes('&', name)))) {
|
|
|
|
return q;
|
|
|
|
}
|
|
|
|
}
|
2022-02-04 12:41:23 +01:00
|
|
|
return null;
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get a Quest by name
|
|
|
|
*
|
|
|
|
* @param name Name of the quest
|
|
|
|
* @return Closest match or null if not found
|
|
|
|
*/
|
2022-02-04 12:41:23 +01:00
|
|
|
public IQuest getQuestTemp(final String name) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (name == null) {
|
|
|
|
return null;
|
|
|
|
}
|
2022-01-19 03:15:49 +01:00
|
|
|
for (final IQuest q : quests) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (q.getName().equalsIgnoreCase(ChatColor.translateAlternateColorCodes('&', name))) {
|
|
|
|
return q;
|
|
|
|
}
|
|
|
|
}
|
2022-01-19 03:15:49 +01:00
|
|
|
for (final IQuest q : quests) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (q.getName().toLowerCase().startsWith(ChatColor.translateAlternateColorCodes('&', name).toLowerCase())) {
|
|
|
|
return q;
|
|
|
|
}
|
|
|
|
}
|
2022-01-19 03:15:49 +01:00
|
|
|
for (final IQuest q : quests) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (q.getName().toLowerCase().contains(ChatColor.translateAlternateColorCodes('&', name).toLowerCase())) {
|
|
|
|
return q;
|
|
|
|
}
|
|
|
|
}
|
2022-03-24 06:28:51 +01:00
|
|
|
for (final IQuest q : quests) {
|
|
|
|
// For tab completion
|
|
|
|
if (ChatColor.stripColor(q.getName()).equals(ChatColor.stripColor(ChatColor
|
|
|
|
.translateAlternateColorCodes('&', name)))) {
|
|
|
|
return q;
|
|
|
|
}
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-01-19 03:15:49 +01:00
|
|
|
* Get an IAction by name
|
2020-04-16 01:18:06 +02:00
|
|
|
*
|
|
|
|
* @param name Name of the action
|
|
|
|
* @return Closest match or null if not found
|
|
|
|
*/
|
2022-01-19 03:15:49 +01:00
|
|
|
public IAction getAction(final String name) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (name == null) {
|
|
|
|
return null;
|
|
|
|
}
|
2022-01-19 03:15:49 +01:00
|
|
|
for (final IAction a : actions) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (a.getName().equalsIgnoreCase(ChatColor.translateAlternateColorCodes('&', name))) {
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
}
|
2022-01-19 03:15:49 +01:00
|
|
|
for (final IAction a : actions) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (a.getName().toLowerCase().startsWith(ChatColor.translateAlternateColorCodes('&', name).toLowerCase())) {
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
}
|
2022-01-19 03:15:49 +01:00
|
|
|
for (final IAction a : actions) {
|
2020-04-16 01:18:06 +02:00
|
|
|
if (a.getName().toLowerCase().contains(ChatColor.translateAlternateColorCodes('&', name).toLowerCase())) {
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
}
|
2022-03-24 06:28:51 +01:00
|
|
|
for (final IAction a : actions) {
|
|
|
|
// For tab completion
|
|
|
|
if (ChatColor.stripColor(a.getName()).equals(ChatColor.stripColor(ChatColor.
|
|
|
|
translateAlternateColorCodes('&', name)))) {
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
}
|
2020-04-16 01:18:06 +02:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2020-07-13 06:35:28 +02:00
|
|
|
/**
|
2022-01-19 03:15:49 +01:00
|
|
|
* Get a ICondition by name
|
2020-07-13 06:35:28 +02:00
|
|
|
*
|
|
|
|
* @param name Name of the condition
|
|
|
|
* @return Closest match or null if not found
|
|
|
|
*/
|
2022-01-19 03:15:49 +01:00
|
|
|
public ICondition getCondition(final String name) {
|
2020-07-13 06:35:28 +02:00
|
|
|
if (name == null) {
|
|
|
|
return null;
|
|
|
|
}
|
2022-01-19 03:15:49 +01:00
|
|
|
for (final ICondition c : conditions) {
|
2020-07-13 06:35:28 +02:00
|
|
|
if (c.getName().equalsIgnoreCase(ChatColor.translateAlternateColorCodes('&', name))) {
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
}
|
2022-01-19 03:15:49 +01:00
|
|
|
for (final ICondition c : conditions) {
|
2020-07-13 06:35:28 +02:00
|
|
|
if (c.getName().toLowerCase().startsWith(ChatColor.translateAlternateColorCodes('&', name).toLowerCase())) {
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
}
|
2022-01-19 03:15:49 +01:00
|
|
|
for (final ICondition c : conditions) {
|
2020-07-13 06:35:28 +02:00
|
|
|
if (c.getName().toLowerCase().contains(ChatColor.translateAlternateColorCodes('&', name).toLowerCase())) {
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
}
|
2022-03-24 06:28:51 +01:00
|
|
|
for (final ICondition c : conditions) {
|
|
|
|
// For tab completion
|
|
|
|
if (ChatColor.stripColor(c.getName()).equals(ChatColor.stripColor(ChatColor
|
|
|
|
.translateAlternateColorCodes('&', name)))) {
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
}
|
2020-07-13 06:35:28 +02:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2020-04-16 01:18:06 +02:00
|
|
|
/**
|
|
|
|
* Checks whether a NPC has a quest that the player may accept
|
|
|
|
*
|
|
|
|
* @param npc The giver NPC to check
|
|
|
|
* @param quester The player to check
|
|
|
|
* @return true if at least one available quest has not yet been completed
|
|
|
|
*/
|
2022-01-19 03:15:49 +01:00
|
|
|
public boolean hasQuest(final NPC npc, final IQuester quester) {
|
|
|
|
for (final IQuest q : quests) {
|
2022-02-04 12:41:23 +01:00
|
|
|
if (q.getNpcStart() != null && !quester.getCompletedQuestsTemp().contains(q)) {
|
2022-06-04 09:47:44 +02:00
|
|
|
if (q.getNpcStart().equals(npc.getUniqueId())) {
|
2020-08-06 11:32:43 +02:00
|
|
|
final boolean ignoreLockedQuests = settings.canIgnoreLockedQuests();
|
2021-07-10 01:48:00 +02:00
|
|
|
if (!ignoreLockedQuests || q.testRequirements(quester)) {
|
2020-04-16 01:18:06 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Unused internally, left for external use
|
|
|
|
/**
|
|
|
|
* Checks whether a NPC has a quest that the player has already completed
|
|
|
|
*
|
|
|
|
* @param npc The giver NPC to check
|
|
|
|
* @param quester The player to check
|
|
|
|
* @return true if at least one available quest has been completed
|
|
|
|
*/
|
2022-01-19 03:15:49 +01:00
|
|
|
public boolean hasCompletedQuest(final NPC npc, final IQuester quester) {
|
|
|
|
for (final IQuest q : quests) {
|
2022-02-04 12:41:23 +01:00
|
|
|
if (q.getNpcStart() != null && quester.getCompletedQuestsTemp().contains(q)) {
|
2022-06-04 09:47:44 +02:00
|
|
|
if (q.getNpcStart().equals(npc.getUniqueId())) {
|
2020-08-06 11:32:43 +02:00
|
|
|
final boolean ignoreLockedQuests = settings.canIgnoreLockedQuests();
|
2021-07-10 01:48:00 +02:00
|
|
|
if (!ignoreLockedQuests || q.testRequirements(quester)) {
|
2020-04-16 01:18:06 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks whether a NPC has a repeatable quest that the player has already completed
|
|
|
|
*
|
|
|
|
* @param npc The giver NPC to check
|
|
|
|
* @param quester The player to check
|
|
|
|
* @return true if at least one available, redoable quest has been completed
|
|
|
|
*/
|
2022-01-19 03:15:49 +01:00
|
|
|
public boolean hasCompletedRedoableQuest(final NPC npc, final IQuester quester) {
|
|
|
|
for (final IQuest q : quests) {
|
2022-02-04 12:41:23 +01:00
|
|
|
if (q.getNpcStart() != null && quester.getCompletedQuestsTemp().contains(q)
|
2022-01-12 21:10:01 +01:00
|
|
|
&& q.getPlanner().getCooldown() > -1) {
|
2022-06-04 09:47:44 +02:00
|
|
|
if (q.getNpcStart().equals(npc.getUniqueId())) {
|
2020-08-06 11:32:43 +02:00
|
|
|
final boolean ignoreLockedQuests = settings.canIgnoreLockedQuests();
|
2021-07-10 01:48:00 +02:00
|
|
|
if (!ignoreLockedQuests || q.testRequirements(quester)) {
|
2020-04-16 01:18:06 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|