From 7778426b1e728bb2eac03f35f19ab1b508b49b4f Mon Sep 17 00:00:00 2001 From: BONNe Date: Tue, 12 Feb 2019 12:24:00 +0200 Subject: [PATCH] Implement Challenge Description customization. Admins now can define Order of elements in challenge description, and remove elements, if they are not necessary. --- .../world/bentobox/challenges/Settings.java | 43 +- .../bentobox/challenges/panel/CommonGUI.java | 409 ++++++++++++++++++ .../panel/admin/ListChallengesGUI.java | 2 +- .../challenges/panel/user/ChallengesGUI.java | 188 +------- src/main/resources/config.yml | 2 + src/main/resources/locales/en-US.yml | 11 +- 6 files changed, 464 insertions(+), 191 deletions(-) diff --git a/src/main/java/world/bentobox/challenges/Settings.java b/src/main/java/world/bentobox/challenges/Settings.java index c7543a5..1bc9387 100644 --- a/src/main/java/world/bentobox/challenges/Settings.java +++ b/src/main/java/world/bentobox/challenges/Settings.java @@ -11,7 +11,7 @@ import world.bentobox.bentobox.database.objects.DataObject; @StoreAt(filename="config.yml", path="addons/Challenges") -@ConfigComment("Challenges Configuration [version]") +@ConfigComment("Challenges [version] Configuration") @ConfigComment("This config file is dynamic and saved when the server is shutdown.") @ConfigComment("You cannot edit it while the server is running because changes will") @ConfigComment("be lost! Use in-game settings GUI or edit when server is offline.") @@ -52,6 +52,25 @@ public class Settings implements DataObject @ConfigEntry(path = "lore-length") private int loreLineLength = 25; + @ConfigComment("") + @ConfigComment("This string allows to change element order in Challenge description. Each letter represents") + @ConfigComment("one object from challenge description. If letter is not used, then its represented part") + @ConfigComment("will not be in description. If use any letter that is not recognized, then it will be") + @ConfigComment("ignored. Some strings can be customized via lang file under 'challenges.gui.challenge-description'.") + @ConfigComment("List of letters and their meaning: ") + @ConfigComment(" - L - Level String: '*.level'") + @ConfigComment(" - S - Status String: '*.completed'") + @ConfigComment(" - T - Times String: '*.completed-times', '*.completed-times-of' or '*.maxed-reached'") + @ConfigComment(" - D - Description String: defined in challenge object - challenge.description") + @ConfigComment(" - W - Warning String: '*.warning-items-take', '*.objects-close-by', '*.warning-entities-kill', '*.warning-blocks-remove'") + @ConfigComment(" - E - Environment String: defined in challenge object - challenge.environment") + @ConfigComment(" - Q - Requirement String: '*.required-level', '*.required-money', '*.required-experience'") + @ConfigComment(" - R - Reward String: '*.experience-reward', '*.money-reward', '*.not-repeatable'") + @ConfigComment("By adding 'i' after Q or R (requirements and rewards) will display list of items, blocks") + @ConfigComment("and entities that are defined in challenge and can be customized under 'challenges.gui.description.*'") + @ConfigEntry(path = "challenge-lore-message") + private String challengeLoreMessage = "LSTDEQiWRi"; + @ConfigComment("") @ConfigComment("This list stores GameModes in which Challenges addon should not work.") @ConfigComment("To disable addon it is necessary to write its name in new line that starts with -. Example:") @@ -70,13 +89,23 @@ public class Settings implements DataObject * Configuration version */ @ConfigComment("") - private String configVersion = "v1.0"; + private String configVersion = "v1.1"; // --------------------------------------------------------------------- // Section: Methods // --------------------------------------------------------------------- + /** + * This method returns the challengeLoreMessage object. + * @return the challengeLoreMessage object. + */ + public String getChallengeLoreMessage() + { + return challengeLoreMessage; + } + + /** * This method returns the configVersion object. * @return the configVersion object. @@ -175,6 +204,16 @@ public class Settings implements DataObject } + /** + * This method sets the challengeLoreMessage object value. + * @param challengeLoreMessage the challengeLoreMessage object new value. + */ + public void setChallengeLoreMessage(String challengeLoreMessage) + { + this.challengeLoreMessage = challengeLoreMessage; + } + + /** * @param resetChallenges new resetChallenges value. */ diff --git a/src/main/java/world/bentobox/challenges/panel/CommonGUI.java b/src/main/java/world/bentobox/challenges/panel/CommonGUI.java index b1a9d7b..2e7dbb3 100644 --- a/src/main/java/world/bentobox/challenges/panel/CommonGUI.java +++ b/src/main/java/world/bentobox/challenges/panel/CommonGUI.java @@ -3,14 +3,20 @@ package world.bentobox.challenges.panel; import org.bukkit.Material; import org.bukkit.World; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.EntityType; import org.bukkit.inventory.ItemStack; +import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; import world.bentobox.bentobox.api.panels.PanelItem; import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder; import world.bentobox.bentobox.api.user.User; import world.bentobox.challenges.ChallengesAddon; +import world.bentobox.challenges.ChallengesManager; +import world.bentobox.challenges.database.object.Challenge; /** @@ -241,5 +247,408 @@ public abstract class CommonGUI { this.valueObject = value; } + + + /** + * This method generates and returns given challenge description. It is used here to avoid multiple + * duplicates, as it would be nice to have single place where challenge could be generated. + * @param challenge Challenge which description must be generated. + * @return List of strings that will be used in challenges description. + */ + protected List generateChallengeDescription(Challenge challenge, User user) + { + List result = new ArrayList<>(); + + // Some values to avoid overchecking. + ChallengesManager manager = this.addon.getChallengesManager(); + + final boolean isCompletedOnce = manager.isChallengeComplete(user, challenge); + final long doneTimes = challenge.isRepeatable() ? + manager.getChallengeTimes(this.user, challenge) : + isCompletedOnce ? 0 : 1; + boolean isCompletedAll = isCompletedOnce && challenge.isRepeatable() && + challenge.getMaxTimes() > 0 && doneTimes < challenge.getMaxTimes(); + + // Used to know if blocks, entities, items should be added after requirements and rewards. + char prevChar = ' '; + + for (char c : this.addon.getChallengesSettings().getChallengeLoreMessage().toLowerCase().toCharArray()) + { + switch (c) + { + case 'l': + { + result.add(this.user.getTranslation("challenges.gui.challenge-description.level", + "[level]", manager.getLevel(challenge).getFriendlyName())); + break; + } + case 's': + { + if (isCompletedOnce) + { + result.add(this.user.getTranslation("challenges.gui.challenge-description.completed")); + } + break; + } + case 't': + { + if (challenge.isRepeatable()) + { + if (challenge.getMaxTimes() > 0) + { + if (isCompletedAll) + { + result.add(this.user.getTranslation("challenges.gui.challenge-description.maxed-reached", + "[donetimes]", String.valueOf(doneTimes), + "[maxtimes]", String.valueOf(challenge.getMaxTimes()))); + } + else + { + result.add(this.user.getTranslation( + "challenges.gui.challenge-description.completed-times-of", + "[donetimes]", String.valueOf(doneTimes), + "[maxtimes]", String.valueOf(challenge.getMaxTimes()))); + } + } + else + { + result.add(this.user.getTranslation("challenges.gui.challenge-description.completed-times", + "[donetimes]", String.valueOf(doneTimes))); + } + } + break; + } + case 'd': + { + if (!isCompletedAll) + { + result.addAll(challenge.getDescription()); + } + break; + } + case 'w': + { + if (!isCompletedAll) + { + if (challenge.getChallengeType().equals(Challenge.ChallengeType.INVENTORY)) + { + if (challenge.isTakeItems()) + { + result.add(this.user.getTranslation( + "challenges.gui.challenge-description.warning-items-take")); + } + } + else if (challenge.getChallengeType().equals(Challenge.ChallengeType.ISLAND)) + { + result.add(this.user.getTranslation("challenges.gui.challenge-description.objects-close-by")); + + if (challenge.isRemoveEntities() && !challenge.getRequiredEntities().isEmpty()) + { + result.add(this.user.getTranslation( + "challenges.gui.challenge-description.warning-entities-kill")); + } + + if (challenge.isRemoveBlocks() && !challenge.getRequiredBlocks().isEmpty()) + { + result.add(this.user.getTranslation( + "challenges.gui.challenge-description.warning-blocks-remove")); + } + } + } + break; + } + case 'e': + { + // Display only if there are limited environments + + if (!isCompletedAll && + !challenge.getEnvironment().isEmpty() && + challenge.getEnvironment().size() != 3) + { + result.add(this.user.getTranslation("challenges.gui.challenge-description.environment")); + + if (challenge.getEnvironment().contains(World.Environment.NORMAL)) + { + result.add(this.user.getTranslation("challenges.gui.descriptions.normal")); + } + + if (challenge.getEnvironment().contains(World.Environment.NETHER)) + { + result.add(this.user.getTranslation("challenges.gui.descriptions.nether")); + } + + if (challenge.getEnvironment().contains(World.Environment.THE_END)) + { + result.add(this.user.getTranslation("challenges.gui.descriptions.the-end")); + } + } + break; + } + case 'q': + { + if (!isCompletedAll && challenge.getChallengeType() == Challenge.ChallengeType.OTHER) + { + result.addAll(this.getChallengeRequirements(challenge)); + } + break; + } + case 'r': + { + if (isCompletedAll) + { + result.add(this.user.getTranslation("challenges.gui.challenge-description.not-repeatable")); + } + else + { + result.addAll(this.getChallengeRewards(challenge, isCompletedOnce)); + } + break; + } + case 'i': + { + if (!isCompletedAll) + { + if (prevChar == 'q' && challenge.getChallengeType() != Challenge.ChallengeType.OTHER) + { + result.addAll(this.getChallengeRequiredItems(challenge)); + } + else if (prevChar == 'r') + { + result.addAll(this.getChallengeRewardItems(challenge, isCompletedOnce, user)); + } + } + break; + } + default: + { + break; + } + } + + prevChar = c; + } + + result.replaceAll(x -> x.replace("[label]", this.topLabel)); + + return result; + } + + + /** + * This method returns list of strings that contains basic information about challenge rewards. + * @param challenge which reward message must be created. + * @param isCompletedOnce indicate if must use repeat rewards + * @return list of strings that contains rewards message. + */ + private List getChallengeRewards(Challenge challenge, boolean isCompletedOnce) + { + String rewardText; + double rewardMoney; + int rewardExperience; + + + if (!isCompletedOnce) + { + rewardText = challenge.getRewardText(); + rewardMoney = challenge.getRewardMoney(); + rewardExperience = challenge.getRewardExperience(); + } + else + { + rewardText = challenge.getRepeatRewardText(); + rewardMoney = challenge.getRepeatMoneyReward(); + rewardExperience = challenge.getRepeatExperienceReward(); + } + + List result = new ArrayList<>(); + + // Add reward text + result.add(rewardText); + + // Add message about reward XP + if (rewardExperience > 0) + { + result.add(this.user.getTranslation("challenges.gui.challenge-description.experience-reward", + "[value]", Integer.toString(rewardExperience))); + } + + // Add message about reward money + if (this.addon.getPlugin().getSettings().isUseEconomy() && rewardMoney > 0) + { + result.add(this.user.getTranslation("challenges.gui.challenge-description.money-reward", + "[value]", Double.toString(rewardMoney))); + } + + return result; + } + + + /** + * This method returns list of strings that contains reward items and commands from given challenge. + * @param challenge Challenge which reward items and commands must be returned. + * @param isCompletedOnce Boolean that indicate if must use repeat rewards. + * @param user Target user for command string. + * @return List of strings that contains message from challenges. + */ + private List getChallengeRewardItems(Challenge challenge, boolean isCompletedOnce, User user) + { + List result = new ArrayList<>(); + + List rewardItems; + List rewardCommands; + + if (!isCompletedOnce) + { + rewardItems = challenge.getRewardItems(); + rewardCommands = challenge.getRewardCommands(); + } + else + { + rewardItems = challenge.getRepeatItemReward(); + rewardCommands = challenge.getRepeatRewardCommands(); + } + + // Add message about reward items + if (!rewardItems.isEmpty()) + { + result.add(this.user.getTranslation("challenges.gui.challenge-description.reward-items")); + + for (ItemStack itemStack : rewardItems) + { + result.add(this.user.getTranslation("challenges.gui.descriptions.item", + "[item]", itemStack.getType().name(), + "[count]", Integer.toString(itemStack.getAmount()))); + + if (itemStack.hasItemMeta() && itemStack.getEnchantments().isEmpty()) + { + result.add(this.user.getTranslation("challenges.gui.descriptions.item-meta", + "[meta]", itemStack.getItemMeta().toString())); + } + + for (Map.Entry entry : itemStack.getEnchantments().entrySet()) + { + result.add(this.user.getTranslation("challenges.gui.descriptions.item-enchant", + "[enchant]", entry.getKey().getKey().getKey(), "[level]", Integer.toString(entry.getValue()))); + } + } + } + + // Add message about reward commands + if (!rewardCommands.isEmpty()) + { + result.add(this.user.getTranslation("challenges.gui.challenge-description.reward-commands")); + + for (String command : rewardCommands) + { + result.add(this.user.getTranslation("challenges.gui.descriptions.command", + "[command]", command.replace("[player]", user.getName()).replace("[SELF]", ""))); + } + } + + return result; + } + + + /** + * This method returns list of strings that contains basic information about challenge requirements. + * @param challenge which requirements message must be created. + * @return list of strings that contains requirements message. + */ + private List getChallengeRequirements(Challenge challenge) + { + List result = new ArrayList<>(); + + // Add message about required exp + if (challenge.getRequiredExperience() > 0) + { + result.add(this.user.getTranslation("challenges.gui.challenge-description.required-experience", + "[value]", Integer.toString(challenge.getRequiredExperience()))); + } + + // Add message about required money + if (this.addon.isEconomyProvided() && challenge.getRequiredMoney() > 0) + { + result.add(this.user.getTranslation("challenges.gui.challenge-description.required-money", + "[value]", Integer.toString(challenge.getRequiredMoney()))); + } + + // Add message about required island level + if (this.addon.isLevelProvided() && challenge.getRequiredIslandLevel() > 0) + { + result.add(this.user.getTranslation("challenges.gui.challenge-description.required-island-level", + "[value]", Long.toString(challenge.getRequiredIslandLevel()))); + } + + return result; + } + + + /** + * This method returns list of strings that contains required items, entities and blocks from given challenge. + * @param challenge Challenge which requirement items, entities and blocks must be returned. + * @return List of strings that contains message from challenges. + */ + private List getChallengeRequiredItems(Challenge challenge) + { + List result = new ArrayList<>(); + + // Add message about required items + if (challenge.getChallengeType().equals(Challenge.ChallengeType.INVENTORY) && + !challenge.getRequiredItems().isEmpty()) + { + result.add(this.user.getTranslation("challenges.gui.challenge-description.required-items")); + + for (ItemStack itemStack : challenge.getRequiredItems()) + { + result.add(this.user.getTranslation("challenges.gui.descriptions.item", + "[item]", itemStack.getType().name(), + "[count]", Integer.toString(itemStack.getAmount()))); + + if (itemStack.hasItemMeta() && itemStack.getEnchantments().isEmpty()) + { + result.add(this.user.getTranslation("challenges.gui.descriptions.item-meta", + "[meta]", itemStack.getItemMeta().toString())); + } + + for (Map.Entry entry : itemStack.getEnchantments().entrySet()) + { + result.add(this.user.getTranslation("challenges.gui.descriptions.item-enchant", + "[enchant]", entry.getKey().getKey().getKey(), "[level]", Integer.toString(entry.getValue()))); + } + } + } + + if (challenge.getChallengeType().equals(Challenge.ChallengeType.ISLAND) && + (!challenge.getRequiredBlocks().isEmpty() || !challenge.getRequiredEntities().isEmpty())) + { + // Add required blocks + if (!challenge.getRequiredBlocks().isEmpty()) + { + result.add(this.user.getTranslation("challenges.gui.challenge-description.required-blocks")); + + for (Map.Entry entry : challenge.getRequiredBlocks().entrySet()) + { + result.add(this.user.getTranslation("challenges.gui.descriptions.block", + "[block]", entry.getKey().name(), + "[count]", Integer.toString(entry.getValue()))); + } + } + + // Add required entities + if (!challenge.getRequiredEntities().isEmpty()) + { + result.add(this.user.getTranslation("challenges.gui.challenge-description.required-entities")); + + for (Map.Entry entry : challenge.getRequiredEntities().entrySet()) + { + result.add(this.user.getTranslation("challenges.gui.descriptions.entity", + "[entity]", entry.getKey().name(), + "[count]", Integer.toString(entry.getValue()))); + } + } + } + + return result; + } } diff --git a/src/main/java/world/bentobox/challenges/panel/admin/ListChallengesGUI.java b/src/main/java/world/bentobox/challenges/panel/admin/ListChallengesGUI.java index 7b075c3..bb7581f 100644 --- a/src/main/java/world/bentobox/challenges/panel/admin/ListChallengesGUI.java +++ b/src/main/java/world/bentobox/challenges/panel/admin/ListChallengesGUI.java @@ -134,7 +134,7 @@ public class ListChallengesGUI extends CommonGUI { PanelItemBuilder itemBuilder = new PanelItemBuilder(). name(challenge.getFriendlyName()). - description(GuiUtils.stringSplit(challenge.getDescription(), + description(GuiUtils.stringSplit(this.generateChallengeDescription(challenge, this.user), this.addon.getChallengesSettings().getLoreLineLength())). icon(challenge.getIcon()). glow(challenge.isDeployed()); diff --git a/src/main/java/world/bentobox/challenges/panel/user/ChallengesGUI.java b/src/main/java/world/bentobox/challenges/panel/user/ChallengesGUI.java index 8cd1aaa..633d9b2 100644 --- a/src/main/java/world/bentobox/challenges/panel/user/ChallengesGUI.java +++ b/src/main/java/world/bentobox/challenges/panel/user/ChallengesGUI.java @@ -3,11 +3,9 @@ package world.bentobox.challenges.panel.user; import org.bukkit.Material; import org.bukkit.World; -import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemStack; import java.util.ArrayList; import java.util.List; -import java.util.Map; import world.bentobox.bentobox.api.panels.PanelItem; import world.bentobox.bentobox.api.panels.builders.PanelBuilder; @@ -345,7 +343,7 @@ public class ChallengesGUI extends CommonGUI return new PanelItemBuilder(). icon(challenge.getIcon()). name(challenge.getFriendlyName().isEmpty() ? challenge.getUniqueId() : challenge.getFriendlyName()). - description(GuiUtils.stringSplit(this.createChallengeDescription(challenge), + description(GuiUtils.stringSplit(this.generateChallengeDescription(challenge, this.user), this.addon.getChallengesSettings().getLoreLineLength())). clickHandler((panel, user1, clickType, slot) -> { if (TryToComplete.complete(this.addon, @@ -365,190 +363,6 @@ public class ChallengesGUI extends CommonGUI } - /** - * This method creates challenges description by adding all information that is necessary for this challenge. - * @param challenge Which information must be retrieved. - * @return List with strings that contains information about given challenge. - */ - private List createChallengeDescription(Challenge challenge) - { - List result = new ArrayList<>(); - - result.add(this.user.getTranslation("challenges.gui.challenge-description.level", - "[level]", this.challengesManager.getLevel(challenge).getFriendlyName())); - - boolean completed = this.challengesManager.isChallengeComplete(this.user, challenge); - - if (completed) - { - result.add(this.user.getTranslation("challenges.gui.challenge-description.completed")); - } - - if (challenge.isRepeatable()) - { - int maxTimes = challenge.getMaxTimes(); - long doneTimes = this.challengesManager.getChallengeTimes(this.user, challenge); - - if (maxTimes > 0) - { - if (doneTimes < maxTimes) - { - result.add(this.user.getTranslation( - "challenges.gui.challenge-description.completed-times-of", - "[donetimes]", String.valueOf(doneTimes), - "[maxtimes]", String.valueOf(maxTimes))); - - // Change value to false, as max count not reached. - completed = false; - } - else - { - result.add(this.user.getTranslation("challenges.gui.challenge-description.maxed-reached", - "[donetimes]", String.valueOf(doneTimes), - "[maxtimes]", String.valueOf(maxTimes))); - } - } - else - { - result.add(this.user.getTranslation("challenges.gui.challenge-description.completed-times", - "[donetimes]", String.valueOf(doneTimes))); - - // Change value to false, as max count not reached. - completed = false; - } - } - - if (!completed) - { - result.addAll(challenge.getDescription()); - - if (challenge.getChallengeType().equals(Challenge.ChallengeType.INVENTORY)) - { - if (challenge.isTakeItems()) - { - result.add(this.user.getTranslation( - "challenges.gui.challenge-description.warning-items-take")); - } - } - else if (challenge.getChallengeType().equals(Challenge.ChallengeType.ISLAND)) - { - result.add(this.user.getTranslation("challenges.gui.challenge-description.objects-close-by")); - - if (challenge.isRemoveEntities() && !challenge.getRequiredEntities().isEmpty()) - { - result.add(this.user.getTranslation( - "challenges.gui.challenge-description.warning-entities-kill")); - } - - if (challenge.isRemoveBlocks() && !challenge.getRequiredBlocks().isEmpty()) - { - result.add(this.user.getTranslation( - "challenges.gui.challenge-description.warning-blocks-remove")); - } - } - } - - if (completed) - { - result.add(this.user.getTranslation("challenges.gui.challenge-description.not-repeatable")); - } - else - { - result.addAll(this.challengeRewards(challenge)); - } - - result.replaceAll(x -> x.replace("[label]", this.topLabel)); - - return result; - } - - - /** - * This method returns list of strings that contains basic information about challenge rewards. - * @param challenge which reward message must be created. - * @return list of strings that contains rewards message. - */ - private List challengeRewards(Challenge challenge) - { - String rewardText; - double rewardMoney; - int rewardExperience; - List rewardItems; - List rewardCommands; - - if (!this.challengesManager.isChallengeComplete(this.user, challenge)) - { - rewardText = challenge.getRewardText(); - rewardMoney = challenge.getRewardMoney(); - rewardExperience = challenge.getRewardExperience(); - rewardItems = challenge.getRewardItems(); - rewardCommands = challenge.getRewardCommands(); - } - else - { - rewardText = challenge.getRepeatRewardText(); - rewardMoney = challenge.getRepeatMoneyReward(); - rewardExperience = challenge.getRepeatExperienceReward(); - rewardItems = challenge.getRepeatItemReward(); - rewardCommands = challenge.getRepeatRewardCommands(); - } - - List result = new ArrayList<>(); - - // Add reward text - result.add(rewardText); - - // Add message about reward XP - if (rewardExperience > 0) - { - result.add(this.user.getTranslation("challenges.gui.challenge-description.experience-reward", - "[value]", Integer.toString(rewardExperience))); - } - - // Add message about reward money - if (this.addon.getPlugin().getSettings().isUseEconomy() && rewardMoney > 0) - { - result.add(this.user.getTranslation("challenges.gui.challenge-description.money-reward", - "[value]", Double.toString(rewardMoney))); - } - - // Add message about reward items - if (!rewardItems.isEmpty()) - { - for (ItemStack itemStack : rewardItems) - { - result.add(this.user.getTranslation("challenges.gui.descriptions.item", - "[item]", itemStack.getType().name(), - "[count]", Integer.toString(itemStack.getAmount()))); - - if (itemStack.hasItemMeta() && itemStack.getEnchantments().isEmpty()) - { - result.add(this.user.getTranslation("challenges.gui.descriptions.item-meta", - "[meta]", itemStack.getItemMeta().toString())); - } - - for (Map.Entry entry : itemStack.getEnchantments().entrySet()) - { - result.add(this.user.getTranslation("challenges.gui.descriptions.item-enchant", - "[enchant]", entry.getKey().getKey().getKey(), "[level]", Integer.toString(entry.getValue()))); - } - } - } - - // Add message about reward commands - if (!rewardCommands.isEmpty()) - { - for (String command : rewardCommands) - { - result.add(this.user.getTranslation("challenges.gui.descriptions.command", - "[command]", command.replace("[player]", this.user.getName()).replace("[SELF]", ""))); - } - } - - return result; - } - - /** * This method creates button for given level. * @param level which button must be created. diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 293d255..064c2f8 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -33,3 +33,5 @@ lore-length: 25 disabled-gamemodes: [] # uniqueId: config + +challenge-lore-message: 'LSTDEQiWRi' \ No newline at end of file diff --git a/src/main/resources/locales/en-US.yml b/src/main/resources/locales/en-US.yml index 92e4577..1bc465e 100755 --- a/src/main/resources/locales/en-US.yml +++ b/src/main/resources/locales/en-US.yml @@ -244,6 +244,15 @@ challenges: not-repeatable: '&cThis challenge is not repeatable!' experience-reward: '&6Exp reward: [value]' money-reward: '&6Money reward: $[value]' + required-experience: '&6Required exp: [value]' + required-money: '&6Required money: $[value]' + required-island-level: '&6Required island level: [value]' + environment: 'Required Environments:' + reward-items: '&6Reward Items:' + reward-commands: '&6Reward Commands:' + required-items: 'Required Items:' + required-entities: 'Required Entities:' + required-blocks: 'Required Blocks:' messages: admin: hit-things: 'Hit things to add them to the list of things required. Right click when done.' @@ -284,4 +293,4 @@ challenges: import-no-file: '&cCould not find challenges.yml file to import!' no-load: '&cError: Could not load challenges.yml. [message]' load-error: '&cError: Cannot load [value].' -version: 2 \ No newline at end of file +version: 3 \ No newline at end of file