From 7c1deb9384291459b3627ac78df7928589a60a12 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sat, 16 Mar 2024 09:13:01 -0700 Subject: [PATCH] Release 1.3.0 (#331) * Init 1.2.0 version * Fixes #311 localization errors in zn-CN. Original translation author translated `[]` placeholders which broke locale * Init 1.2.0 version * Edit some unfit translation (#312) Edit some unfit translation * Fixes a regex bug that replaced every [player] char instead of whole word. * Fixes a crash that prevented STATISTICS entity and material/item challenges to be completed. * Add requirement-not-met-material and requirement-not-met-entity to display statistic required item on error. * Add locale of Chinese-Hong Kong (zh-HK) (#313) Addition of locale updated to latest version * Add ${argLine} to get jacoco coverage * Updated Jacoco POM section * Update build.yml Java 17 for Surefire * Updated pladdon annotations * Add support for gamemode-specific translations. This was a request from Floris * Update ChallengesManagerTest methods with world parameter. * Implement option that excludes undeployed challenges The new option allows to toggle if undeployed challenges should be included in level completion count. Disabling option will not include these challenges for level completion. Fixes #315 * Create plugin.yml (#316) * Create plugin.yml * Update pom.xml * Update ChallengesPladdon.java * Remove dependency to org.apache.commons Replace org.apache.commons.lang.ArrayUtils to a default Java implementation. * Fixes a crash with written/writable books. The issue was with generating description message for written books without title or author. Fixes #318 * Fixed TryToComplete test class * Fixed CompleteChallengeCommandTest * Fixed ChallengesCommandTest * Fixed ChallengesManagerTest * Update Github Action build script * Add required distribution * Fixes the admin GUI crash. Add shade plugin that was missing for dependencies. * Update Hungarian translation (#301) * Translate hu.yml via GitLocalize * Translate hu.yml via GitLocalize * Translate hu.yml via GitLocalize * Translate hu.yml via GitLocalize * Update hu.yml Fix color codes and placeholders --------- Co-authored-by: driverdakid Co-authored-by: mt-gitlocalize Co-authored-by: BONNe Co-authored-by: slimcraft Co-authored-by: tastybento * Update POM versions to use latest API * Remove duplicate plugin reference in POM * Try adding maven dependency to fix test issue * Remove offending test. Was not that useful anyway. * Update Jacoco * Update pom.xml * Update to BentoBox 2.0.0 Had to ignore some tests because PowerMockito can't mock them for some reason. * Add Ukrainian locale (#326) * Translate uk.yml via GitLocalize * Translate uk.yml via GitLocalize --------- Co-authored-by: mt-gitlocalize Co-authored-by: GIGABAIT * Translate uk.yml via GitLocalize (#325) Co-authored-by: GIGABAIT Co-authored-by: tastybento * Show money as formatted. Addresses #324 * Update README.md * Update README.md * Fixes enchanted book meta not displayed (#328) Apparently in Spigot EnchantmentStorage has a map that is not used for enchantment storing. Nice. Fixes #327 * Upgrade PanelUtils to 1.2.0 * Fixes crash when player in CREATIVE shift+clicks on INVENTORY challenge. Limit completion time to 2, if player is in creative instead of Integer.MAX_VALUE Fixes #330 * Fix tests for creative user inventory challenge completion * Update TIPPED_ARROW to latest API in panels * Update en-US.yml * Reference latest BentoBox release version --------- Co-authored-by: BONNe Co-authored-by: EpicMo <1982742309@qq.com> Co-authored-by: JamesMCL44 Co-authored-by: gitlocalize-app[bot] <55277160+gitlocalize-app[bot]@users.noreply.github.com> Co-authored-by: driverdakid Co-authored-by: mt-gitlocalize Co-authored-by: slimcraft Co-authored-by: GIGABAIT --- .github/workflows/build.yml | 9 +- README.md | 44 +- pom.xml | 83 +- .../challenges/panel/CommonPanel.java | 990 ++--- .../panel/admin/EditChallengePanel.java | 3460 ++++++++--------- .../challenges/tasks/TryToComplete.java | 2 + .../bentobox/challenges/utils/Utils.java | 18 +- src/main/resources/locales/en-US.yml | 2 +- src/main/resources/locales/hu.yml | 1102 ++++++ src/main/resources/locales/uk.yml | 1113 ++++++ src/main/resources/panels/gamemode_panel.yml | 4 +- src/main/resources/panels/main_panel.yml | 8 +- .../challenges/ChallengesManagerTest.java | 20 +- .../commands/ChallengesCommandTest.java | 44 +- .../CompleteChallengeCommandTest.java | 22 +- .../challenges/tasks/TryToCompleteTest.java | 1146 +++--- 16 files changed, 4899 insertions(+), 3168 deletions(-) create mode 100644 src/main/resources/locales/hu.yml create mode 100644 src/main/resources/locales/uk.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4b8156be..9296f262 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,21 +11,22 @@ jobs: name: Build runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - name: Set up JDK 17 - uses: actions/setup-java@v1 + uses: actions/setup-java@v3 with: + distribution: 'adopt' java-version: 17 - name: Cache SonarCloud packages - uses: actions/cache@v1 + uses: actions/cache@v3 with: path: ~/.sonar/cache key: ${{ runner.os }}-sonar restore-keys: ${{ runner.os }}-sonar - name: Cache Maven packages - uses: actions/cache@v1 + uses: actions/cache@v3 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/README.md b/README.md index 1046c96d..b8cd9ad3 100644 --- a/README.md +++ b/README.md @@ -2,24 +2,9 @@ [![Discord](https://img.shields.io/discord/272499714048524288.svg?logo=discord)](https://discord.bentobox.world) [![Build Status](https://ci.codemc.org/buildStatus/icon?job=BentoBoxWorld/Challenges)](https://ci.codemc.org/job/BentoBoxWorld/job/Challenges/) -Add-on for BentoBox to provide challenges for any BentoBox GameMode. +Add-on for BentoBox to provide challenges for any BentoBox GameMode. Challenges can be to collect items, to have items or blocks nearby, to amass an amount of money or island levels, or to have accomplished some player statistic. Each challenge can reward the player with money, experience points, blocks, items, or other things, like permissions, Pre-built challenges are available and there is also a Web Library of pre-built ones. Customize them to fit your needs! -## Where to find - -Currently Challenges Addon is in **Beta stage**, so it may or may not contain bugs... a lot of bugs. Also it means, that some features are not working or implemented. -Latest official **Beta Release is 0.8.3**, and you can download it from [Release tab](https://github.com/BentoBoxWorld/Challenges/releases) -But it will work with BentoBox 1.14. - -Latest development builds will be based on **Minecraft 1.16.1** and **BentoBox 1.14.0**. -**Nightly builds** are available in [Jenkins Server](https://ci.codemc.org/job/BentoBoxWorld/job/Challenges/lastStableBuild/). - -If you like this addon but something is missing or is not working as you want, you can always submit an [Issue request](https://github.com/BentoBoxWorld/Challenges/issues) or get a support in Discord [BentoBox ![icon](https://avatars2.githubusercontent.com/u/41555324?s=15&v=4)](https://discord.bentobox.world) - -## Translations - -As most of BentoBox projects, Challenges Addon is translatable in any language. Everyone can contribute, and translate some parts of the addon in their language via [GitLocalize](https://gitlocalize.com/repo/2896). -If your language is not in the list, please contact to developers via Discord and it will be added there. -Unfortunately, default challenges come only in English translation. But with version 0.8.0 there will be access to different challenges libraries, where everyone could share their challenges with their translations. More information will come soon. +![Challenges](https://github.com/BentoBoxWorld/Challenges/assets/4407265/9b3c5278-3a9d-45f2-9ee1-2c1fc1199a8d) ## How to use @@ -27,21 +12,32 @@ Unfortunately, default challenges come only in English translation. But with ver 2. Restart the server 3. Edit the config.yml how you want. 4. Restart the server +5. Run the Admin challenges command to set up challenges for your game mode. -#### Challenges +#### Installation -By default, challenges addon comes without any challenge or level. On first runtime only Admin GUI will be accessible. -Admins can create their own challenges or import some default challenges, which importing also are available via Admin GUI. Default challenges contains 5 levels and 57 challenges. -There exist also Web Library, where users can download public challenges. It is accessible with Admin GUI by clicking on Web icon. +By default, challenges addon comes without any challenge or level. On first run time only Admin GUI will be accessible. +Admins can create their own challenges or import some default challenges. Default challenges contains 5 levels and 57 challenges. +There also exists a Web Library, where admins can download public challenges. It is accessible from the Admin GUI by clicking on the Web icon. ## Compatibility -- [x] BentoBox - 1.14 versions +- [x] BentoBok - [x] BSkyBlock - [x] AcidIsland - [x] SkyGrid - [x] CaveBlock -## Information +## Translations + +As with most of BentoBox projects, Challenges Addon is translatable into any language. Everyone can contribute, and translate some parts of the addon in their language via [GitLocalize](https://gitlocalize.com/repo/2896). +If your language is not in the list, please contact the developers via Discord and it will be added there. +Unfortunately, default challenges come only be in English, but there are different challenges libraries where everyone can share their challenges with their translations. + +## Documentation + +More information can be found in the docs: https://docs.bentobox.world/en/latest/addons/Challenges/ + +## Bugs or feature requests +If you like this addon but something is missing or is not working as you want, you can always submit an [Issue request](https://github.com/BentoBoxWorld/Challenges/issues) or get a support in Discord [BentoBox ![icon](https://avatars2.githubusercontent.com/u/41555324?s=15&v=4)](https://discord.bentobox.world) -More information can be found in [Wiki Pages](https://docs.bentobox.world/en/latest/addons/Challenges/). diff --git a/pom.xml b/pom.xml index 481dfa55..b3e9d028 100644 --- a/pom.xml +++ b/pom.xml @@ -35,16 +35,16 @@ 17 2.0.9 - 1.17.1-R0.1-SNAPSHOT + 1.20.4-R0.1-SNAPSHOT 1.2.3-SNAPSHOT - 1.21.0 + 2.1.0 2.6.3 1.7 - 1.1.0 + 1.2.0 ${build.version}-SNAPSHOT - 1.2.0 + 1.3.0 -LOCAL BentoBoxWorld_Challenges @@ -120,6 +120,12 @@ + + + org.javassist + javassist + 3.30.2-GA + org.spigotmc @@ -187,6 +193,11 @@ 1.5.21 provided + + org.apache.commons + commons-math3 + 3.6.1 + @@ -217,6 +228,38 @@ + + org.apache.maven.plugins + maven-shade-plugin + 3.3.1-SNAPSHOT + + true + + + lv.id.bonne:panelutils:* + + + + + + MANIFEST.MF + + + + META-INF/MANIFEST.MF + src/main/resources/META-INF/MANIFEST.MF + + + + + + package + + shade + + + + org.apache.maven.plugins maven-clean-plugin @@ -325,40 +368,15 @@ org.jacoco jacoco-maven-plugin - 0.8.4 - - true - - - **/*Names* - - - - - pre-unit-test - - prepare-agent - - - - post-unit-test - - report - - - - - - org.jacoco - jacoco-maven-plugin - 0.8.7 + 0.8.10 true **/*Names* + + org/bukkit/Material* @@ -378,6 +396,7 @@ XML + diff --git a/src/main/java/world/bentobox/challenges/panel/CommonPanel.java b/src/main/java/world/bentobox/challenges/panel/CommonPanel.java index 14fb7257..6709d617 100644 --- a/src/main/java/world/bentobox/challenges/panel/CommonPanel.java +++ b/src/main/java/world/bentobox/challenges/panel/CommonPanel.java @@ -3,9 +3,14 @@ // Copyright - 2021 // - package world.bentobox.challenges.panel; +import java.time.Duration; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; import org.bukkit.Material; import org.bukkit.World; @@ -13,10 +18,6 @@ import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; -import java.time.*; -import java.util.*; -import java.util.stream.Collectors; - import world.bentobox.bentobox.api.panels.PanelItem; import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder; import world.bentobox.bentobox.api.user.User; @@ -24,26 +25,26 @@ import world.bentobox.challenges.ChallengesAddon; import world.bentobox.challenges.database.object.Challenge; import world.bentobox.challenges.database.object.ChallengeLevel; -import world.bentobox.challenges.database.object.requirements.*; +import world.bentobox.challenges.database.object.requirements.InventoryRequirements; +import world.bentobox.challenges.database.object.requirements.IslandRequirements; +import world.bentobox.challenges.database.object.requirements.OtherRequirements; +import world.bentobox.challenges.database.object.requirements.StatisticRequirements; import world.bentobox.challenges.managers.ChallengesManager; import world.bentobox.challenges.utils.Constants; import world.bentobox.challenges.utils.LevelStatus; import world.bentobox.challenges.utils.Utils; - /** * This class contains common methods for all panels. */ -public abstract class CommonPanel -{ +public abstract class CommonPanel { /** * This is default constructor for all classes that extends CommonPanel. * * @param addon ChallengesAddon instance. - * @param user User who opens panel. + * @param user User who opens panel. */ - protected CommonPanel(ChallengesAddon addon, User user, World world, String topLabel, String permissionPrefix) - { + protected CommonPanel(ChallengesAddon addon, User user, World world, String topLabel, String permissionPrefix) { this.addon = addon; this.world = world; this.manager = addon.getChallengesManager(); @@ -54,26 +55,21 @@ protected CommonPanel(ChallengesAddon addon, User user, World world, String topL this.parentPanel = null; - this.returnButton = new PanelItemBuilder(). - name(this.user.getTranslation(Constants.BUTTON + "quit.name")). - description(this.user.getTranslationOrNothing(Constants.BUTTON + "quit.description")). - description(""). - description(this.user.getTranslationOrNothing(Constants.TIPS + "click-to-quit")). - icon(Material.OAK_DOOR). - clickHandler((panel, user1, clickType, i) -> { - this.user.closeInventory(); - return true; - }).build(); + this.returnButton = new PanelItemBuilder().name(this.user.getTranslation(Constants.BUTTON + "quit.name")) + .description(this.user.getTranslationOrNothing(Constants.BUTTON + "quit.description")).description("") + .description(this.user.getTranslationOrNothing(Constants.TIPS + "click-to-quit")) + .icon(Material.OAK_DOOR).clickHandler((panel, user1, clickType, i) -> { + this.user.closeInventory(); + return true; + }).build(); } - /** * This is default constructor for all classes that extends CommonPanel. * * @param parentPanel Parent panel of current panel. */ - protected CommonPanel(@NonNull CommonPanel parentPanel) - { + protected CommonPanel(@NonNull CommonPanel parentPanel) { this.addon = parentPanel.addon; this.manager = parentPanel.manager; this.user = parentPanel.user; @@ -84,199 +80,159 @@ protected CommonPanel(@NonNull CommonPanel parentPanel) this.parentPanel = parentPanel; - this.returnButton = new PanelItemBuilder(). - name(this.user.getTranslation(Constants.BUTTON + "return.name")). - description(this.user.getTranslationOrNothing(Constants.BUTTON + "return.description")). - description(""). - description(this.user.getTranslationOrNothing(Constants.TIPS + "click-to-return")). - icon(Material.OAK_DOOR). - clickHandler((panel, user1, clickType, i) -> { - this.parentPanel.build(); - return true; - }).build(); + this.returnButton = new PanelItemBuilder().name(this.user.getTranslation(Constants.BUTTON + "return.name")) + .description(this.user.getTranslationOrNothing(Constants.BUTTON + "return.description")).description("") + .description(this.user.getTranslationOrNothing(Constants.TIPS + "click-to-return")) + .icon(Material.OAK_DOOR).clickHandler((panel, user1, clickType, i) -> { + this.parentPanel.build(); + return true; + }).build(); } - /** * This method allows building panel. */ protected abstract void build(); - /** * This method reopens given panel. + * * @param panel Panel that must be reopened. */ - public static void reopen(CommonPanel panel) - { + public static void reopen(CommonPanel panel) { panel.build(); } - -// --------------------------------------------------------------------- -// Section: Common methods -// --------------------------------------------------------------------- - + // --------------------------------------------------------------------- + // Section: Common methods + // --------------------------------------------------------------------- /** - * 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. + * 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. - * @param target target player. + * @param target target player. * @return List of strings that will be used in challenges description. */ - protected List generateChallengeDescription(Challenge challenge, @Nullable User target) - { + protected List generateChallengeDescription(Challenge challenge, @Nullable User target) { // Some values to avoid over checking. - final boolean isCompletedOnce = target != null && - this.manager.isChallengeComplete(target.getUniqueId(), this.world, challenge); + final boolean isCompletedOnce = target != null + && this.manager.isChallengeComplete(target.getUniqueId(), this.world, challenge); - final long doneTimes = target != null && challenge.isRepeatable() ? - this.manager.getChallengeTimes(target, this.world, challenge) : (isCompletedOnce ? 0 : 1); + final long doneTimes = target != null && challenge.isRepeatable() + ? this.manager.getChallengeTimes(target, this.world, challenge) + : (isCompletedOnce ? 0 : 1); - boolean isCompletedAll = isCompletedOnce && - (!challenge.isRepeatable() || - challenge.getMaxTimes() > 0 && doneTimes >= challenge.getMaxTimes()); + boolean isCompletedAll = isCompletedOnce + && (!challenge.isRepeatable() || challenge.getMaxTimes() > 0 && doneTimes >= challenge.getMaxTimes()); final String reference = Constants.DESCRIPTIONS + "challenge."; // Get description from custom translations - String description = this.user.getTranslationOrNothing( - "challenges.challenges." + challenge.getUniqueId() + ".description"); + String description = this.user + .getTranslationOrNothing("challenges.challenges." + challenge.getUniqueId() + ".description"); - if (description.isEmpty()) - { + if (description.isEmpty()) { // Get data from object in single string. description = Util.translateColorCodes(String.join("\n", challenge.getDescription())); } - // Non-memory optimal code used for easier debugging and nicer code layout for my eye :) + // Non-memory optimal code used for easier debugging and nicer code layout for + // my eye :) // Get status in single string - String status = this.generateChallengeStatus(isCompletedOnce, - isCompletedAll, - doneTimes, - challenge.getMaxTimes()); + String status = this.generateChallengeStatus(isCompletedOnce, isCompletedAll, doneTimes, + challenge.getMaxTimes()); // Get requirements in single string String requirements = isCompletedAll ? "" : this.generateRequirements(challenge, target); // Get rewards in single string String rewards = isCompletedAll ? "" : this.generateRewards(challenge, isCompletedOnce); // Get coolDown in singe string - String coolDown = isCompletedAll || challenge.getTimeout() <= 0 ? "" : - this.generateCoolDown(challenge, target); + String coolDown = isCompletedAll || challenge.getTimeout() <= 0 ? "" : this.generateCoolDown(challenge, target); - if (!description.replaceAll("(?m)^[ \\t]*\\r?\\n", "").isEmpty()) - { - String returnString = this.user.getTranslationOrNothing(reference + "lore", - "[requirements]", requirements, - "[rewards]", rewards, - "[status]", status, - "[cooldown]", coolDown); + if (!description.replaceAll("(?m)^[ \\t]*\\r?\\n", "").isEmpty()) { + String returnString = this.user.getTranslationOrNothing(reference + "lore", "[requirements]", requirements, + "[rewards]", rewards, "[status]", status, "[cooldown]", coolDown); // remove empty lines from the generated text. - List collect = - Arrays.stream(returnString.replaceAll("(?m)^[ \\t]*\\r?\\n", ""). - split("\n")). - collect(Collectors.toList()); + List collect = Arrays.stream(returnString.replaceAll("(?m)^[ \\t]*\\r?\\n", "").split("\n")) + .collect(Collectors.toList()); // find and replace description from collected blocks. - for (int i = 0; i < collect.size(); i++) - { - if (collect.get(i).contains(Constants.PARAMETER_DESCRIPTION)) - { + for (int i = 0; i < collect.size(); i++) { + if (collect.get(i).contains(Constants.PARAMETER_DESCRIPTION)) { collect.set(i, collect.get(i).replace(Constants.PARAMETER_DESCRIPTION, description)); } } return collect; - } - else - { - String returnString = this.user.getTranslationOrNothing(reference + "lore", - Constants.PARAMETER_DESCRIPTION, description, - "[requirements]", requirements, - "[rewards]", rewards, - "[status]", status, - "[cooldown]", coolDown); + } else { + String returnString = this.user.getTranslationOrNothing(reference + "lore", Constants.PARAMETER_DESCRIPTION, + description, "[requirements]", requirements, "[rewards]", rewards, "[status]", status, "[cooldown]", + coolDown); // Remove empty lines and returns as a list. - return Arrays.stream(returnString.replaceAll("(?m)^[ \\t]*\\r?\\n", ""). - split("\n")). - collect(Collectors.toList()); + return Arrays.stream(returnString.replaceAll("(?m)^[ \\t]*\\r?\\n", "").split("\n")) + .collect(Collectors.toList()); } } - /** * Generate cool down string. * * @param challenge the challenge - * @param target the target + * @param target the target * @return the string */ - private String generateCoolDown(Challenge challenge, @Nullable User target) - { + private String generateCoolDown(Challenge challenge, @Nullable User target) { final String reference = Constants.DESCRIPTIONS + "challenge.cooldown."; String coolDown; - if (target != null && this.manager.isBreachingTimeOut(target, this.world, challenge)) - { - long missing = this.manager.getLastCompletionDate(this.user, this.world, challenge) + - challenge.getTimeout() - System.currentTimeMillis(); + if (target != null && this.manager.isBreachingTimeOut(target, this.world, challenge)) { + long missing = this.manager.getLastCompletionDate(this.user, this.world, challenge) + challenge.getTimeout() + - System.currentTimeMillis(); - coolDown = this.user.getTranslation(reference + "wait-time", - "[time]", - Utils.parseDuration(Duration.ofMillis(missing), this.user)); - } - else - { + coolDown = this.user.getTranslation(reference + "wait-time", "[time]", + Utils.parseDuration(Duration.ofMillis(missing), this.user)); + } else { coolDown = ""; } - String timeout = this.user.getTranslation(reference + "timeout", - "[time]", - Utils.parseDuration(Duration.ofMillis(challenge.getTimeout()), this.user)); + String timeout = this.user.getTranslation(reference + "timeout", "[time]", + Utils.parseDuration(Duration.ofMillis(challenge.getTimeout()), this.user)); - return this.user.getTranslation(reference + "lore", - "[timeout]", timeout, - "[wait-time]", coolDown); + return this.user.getTranslation(reference + "lore", "[timeout]", timeout, "[wait-time]", coolDown); } - /** * This method generate requirements description for given challenge. + * * @param challenge Challenge which requirements must be generated. * @return Lore message with requirements. */ - private String generateRequirements(Challenge challenge, @Nullable User target) - { + private String generateRequirements(Challenge challenge, @Nullable User target) { final String reference = Constants.DESCRIPTIONS + "challenge.requirements."; String environment; - if (challenge.getEnvironment().isEmpty() || challenge.getEnvironment().size() == 3) - { + if (challenge.getEnvironment().isEmpty() || challenge.getEnvironment().size() == 3) { // If challenge can be completed everywhere, do not display requirement. environment = ""; - } - else if (challenge.getEnvironment().size() == 1) - { + } else if (challenge.getEnvironment().size() == 1) { environment = this.user.getTranslationOrNothing(reference + "environment-single", - Constants.PARAMETER_ENVIRONMENT, - Utils.prettifyObject(challenge.getEnvironment().iterator().next(), this.user)); - } - else - { + Constants.PARAMETER_ENVIRONMENT, + Utils.prettifyObject(challenge.getEnvironment().iterator().next(), this.user)); + } else { StringBuilder builder = new StringBuilder(); builder.append(this.user.getTranslationOrNothing(reference + "environment-title")); - challenge.getEnvironment().stream().sorted().forEach(en -> - { + challenge.getEnvironment().stream().sorted().forEach(en -> { builder.append("\n"); builder.append(this.user.getTranslationOrNothing(reference + "environment-single", - Constants.PARAMETER_ENVIRONMENT, - Utils.prettifyObject(en, this.user))); + Constants.PARAMETER_ENVIRONMENT, Utils.prettifyObject(en, this.user))); }); environment = builder.toString(); @@ -284,784 +240,620 @@ else if (challenge.getEnvironment().size() == 1) String permissions; - if (!challenge.getRequirements().getRequiredPermissions().isEmpty()) - { + if (!challenge.getRequirements().getRequiredPermissions().isEmpty()) { // Yes list duplication for complete menu. - List missingPermissions = challenge.getRequirements().getRequiredPermissions().stream(). - filter(permission -> target == null || !target.hasPermission(permission)). - sorted().toList(); + List missingPermissions = challenge.getRequirements().getRequiredPermissions().stream() + .filter(permission -> target == null || !target.hasPermission(permission)).sorted().toList(); StringBuilder permissionBuilder = new StringBuilder(); - if (missingPermissions.size() == 1) - { + if (missingPermissions.size() == 1) { permissionBuilder.append(this.user.getTranslationOrNothing(reference + "permission-single", - Constants.PARAMETER_PERMISSION, missingPermissions.get(0))); - } - else if (!missingPermissions.isEmpty()) - { + Constants.PARAMETER_PERMISSION, missingPermissions.get(0))); + } else if (!missingPermissions.isEmpty()) { permissionBuilder.append(this.user.getTranslationOrNothing(reference + "permissions-title")); - missingPermissions.forEach(permission -> - { + missingPermissions.forEach(permission -> { permissionBuilder.append("\n"); permissionBuilder.append(this.user.getTranslationOrNothing(reference + "permissions-list", - Constants.PARAMETER_PERMISSION, permission)); + Constants.PARAMETER_PERMISSION, permission)); }); } permissions = permissionBuilder.toString(); - } - else - { + } else { permissions = ""; } String typeRequirement = switch (challenge.getChallengeType()) { - case INVENTORY_TYPE -> this.generateInventoryChallenge(challenge.getRequirements()); - case ISLAND_TYPE -> this.generateIslandChallenge(challenge.getRequirements()); - case OTHER_TYPE -> this.generateOtherChallenge(challenge.getRequirements()); - case STATISTIC_TYPE -> this.generateStatisticChallenge(challenge.getRequirements()); + case INVENTORY_TYPE -> this.generateInventoryChallenge(challenge.getRequirements()); + case ISLAND_TYPE -> this.generateIslandChallenge(challenge.getRequirements()); + case OTHER_TYPE -> this.generateOtherChallenge(challenge.getRequirements()); + case STATISTIC_TYPE -> this.generateStatisticChallenge(challenge.getRequirements()); }; - return this.user.getTranslationOrNothing(reference + "lore", - Constants.PARAMETER_ENVIRONMENT, environment, - "[type-requirement]", typeRequirement, - "[permissions]", permissions); + return this.user.getTranslationOrNothing(reference + "lore", Constants.PARAMETER_ENVIRONMENT, environment, + "[type-requirement]", typeRequirement, "[permissions]", permissions); } - /** * This method generates lore message for island requirement. + * * @param requirement Island Requirement. * @return Requirement lore message. */ - private String generateIslandChallenge(IslandRequirements requirement) - { + private String generateIslandChallenge(IslandRequirements requirement) { final String reference = Constants.DESCRIPTIONS + "challenge.requirements.island."; String blocks; - if (!requirement.getRequiredBlocks().isEmpty()) - { + if (!requirement.getRequiredBlocks().isEmpty()) { StringBuilder builder = new StringBuilder(); builder.append(this.user.getTranslationOrNothing(reference + "blocks-title")); - requirement.getRequiredBlocks().entrySet().stream(). - sorted(Map.Entry.comparingByKey()). - forEach(entry -> - { - builder.append("\n"); - - if (entry.getValue() > 1) - { - builder.append(this.user.getTranslationOrNothing(reference + "blocks-value", - Constants.PARAMETER_NUMBER, String.valueOf(entry.getValue()), - Constants.PARAMETER_MATERIAL, Utils.prettifyObject(entry.getKey(), this.user))); - } - else - { - builder.append(this.user.getTranslationOrNothing(reference + "block-value", + requirement.getRequiredBlocks().entrySet().stream().sorted(Map.Entry.comparingByKey()).forEach(entry -> { + builder.append("\n"); + + if (entry.getValue() > 1) { + builder.append(this.user.getTranslationOrNothing(reference + "blocks-value", + Constants.PARAMETER_NUMBER, String.valueOf(entry.getValue()), Constants.PARAMETER_MATERIAL, + Utils.prettifyObject(entry.getKey(), this.user))); + } else { + builder.append(this.user.getTranslationOrNothing(reference + "block-value", Constants.PARAMETER_MATERIAL, Utils.prettifyObject(entry.getKey(), this.user))); - } - }); + } + }); blocks = builder.toString(); - } - else - { + } else { blocks = ""; } String entities; - if (!requirement.getRequiredEntities().isEmpty()) - { + if (!requirement.getRequiredEntities().isEmpty()) { StringBuilder builder = new StringBuilder(); builder.append(this.user.getTranslationOrNothing(reference + "entities-title")); - requirement.getRequiredEntities().entrySet().stream(). - sorted(Map.Entry.comparingByKey()). - forEach(entry -> - { - builder.append("\n"); - - if (entry.getValue() > 1) - { - builder.append(this.user.getTranslationOrNothing(reference + "entities-value", - Constants.PARAMETER_NUMBER, String.valueOf(entry.getValue()), - Constants.PARAMETER_ENTITY, Utils.prettifyObject(entry.getKey(), this.user))); - } - else - { - builder.append(this.user.getTranslationOrNothing(reference + "entity-value", + requirement.getRequiredEntities().entrySet().stream().sorted(Map.Entry.comparingByKey()).forEach(entry -> { + builder.append("\n"); + + if (entry.getValue() > 1) { + builder.append(this.user.getTranslationOrNothing(reference + "entities-value", + Constants.PARAMETER_NUMBER, String.valueOf(entry.getValue()), Constants.PARAMETER_ENTITY, + Utils.prettifyObject(entry.getKey(), this.user))); + } else { + builder.append(this.user.getTranslationOrNothing(reference + "entity-value", Constants.PARAMETER_ENTITY, Utils.prettifyObject(entry.getKey(), this.user))); - } - }); + } + }); entities = builder.toString(); - } - else - { + } else { entities = ""; } - String searchRadius = this.user.getTranslationOrNothing(reference + "search-radius", - Constants.PARAMETER_NUMBER, String.valueOf(requirement.getSearchRadius())); + String searchRadius = this.user.getTranslationOrNothing(reference + "search-radius", Constants.PARAMETER_NUMBER, + String.valueOf(requirement.getSearchRadius())); - String warningBlocks = requirement.isRemoveBlocks() ? - this.user.getTranslationOrNothing(reference + "warning-block") : ""; - String warningEntities = requirement.isRemoveEntities() ? - this.user.getTranslationOrNothing(reference + "warning-entity") : ""; + String warningBlocks = requirement.isRemoveBlocks() + ? this.user.getTranslationOrNothing(reference + "warning-block") + : ""; + String warningEntities = requirement.isRemoveEntities() + ? this.user.getTranslationOrNothing(reference + "warning-entity") + : ""; - return this.user.getTranslationOrNothing(reference + "lore", - "[blocks]", blocks, - "[entities]", entities, - "[warning-block]", warningBlocks, - "[warning-entity]", warningEntities, - "[search-radius]", searchRadius); + return this.user.getTranslationOrNothing(reference + "lore", "[blocks]", blocks, "[entities]", entities, + "[warning-block]", warningBlocks, "[warning-entity]", warningEntities, "[search-radius]", searchRadius); } - /** * This method generates lore message for inventory requirement. + * * @param requirement Inventory Requirement. * @return Requirement lore message. */ - private String generateInventoryChallenge(InventoryRequirements requirement) - { + private String generateInventoryChallenge(InventoryRequirements requirement) { final String reference = Constants.DESCRIPTIONS + "challenge.requirements.inventory."; String items; - if (!requirement.getRequiredItems().isEmpty()) - { + if (!requirement.getRequiredItems().isEmpty()) { StringBuilder builder = new StringBuilder(); builder.append(this.user.getTranslationOrNothing(reference + "item-title")); - Utils.groupEqualItems(requirement.getRequiredItems(), requirement.getIgnoreMetaData()).stream(). - sorted(Comparator.comparing(ItemStack::getType)). - forEach(itemStack -> - { - builder.append("\n"); - - if (itemStack.getAmount() > 1) - { - builder.append(this.user.getTranslationOrNothing(reference + "items-value", - "[number]", String.valueOf(itemStack.getAmount()), - "[item]", Utils.prettifyObject(itemStack, this.user))); - } - else - { - builder.append(this.user.getTranslationOrNothing(reference + "item-value", - "[item]", Utils.prettifyObject(itemStack, this.user))); - } - }); + Utils.groupEqualItems(requirement.getRequiredItems(), requirement.getIgnoreMetaData()).stream() + .sorted(Comparator.comparing(ItemStack::getType)).forEach(itemStack -> { + builder.append("\n"); + + if (itemStack.getAmount() > 1) { + builder.append(this.user.getTranslationOrNothing(reference + "items-value", "[number]", + String.valueOf(itemStack.getAmount()), "[item]", + Utils.prettifyObject(itemStack, this.user))); + } else { + builder.append(this.user.getTranslationOrNothing(reference + "item-value", "[item]", + Utils.prettifyObject(itemStack, this.user))); + } + }); items = builder.toString(); - } - else - { + } else { items = ""; } - String warning = requirement.isTakeItems() ? - this.user.getTranslationOrNothing(reference + "warning") : ""; + String warning = requirement.isTakeItems() ? this.user.getTranslationOrNothing(reference + "warning") : ""; - return this.user.getTranslationOrNothing(reference + "lore", - "[items]", items, - "[warning]", warning); + return this.user.getTranslationOrNothing(reference + "lore", "[items]", items, "[warning]", warning); } - /** * This method generates lore message for other requirement. + * * @param requirement Other Requirement. * @return Requirement lore message. */ - private String generateOtherChallenge(OtherRequirements requirement) - { + private String generateOtherChallenge(OtherRequirements requirement) { final String reference = Constants.DESCRIPTIONS + "challenge.requirements.other."; - String experience = requirement.getRequiredExperience() <= 0 ? "" : - this.user.getTranslationOrNothing(reference + "experience", - "[number]", String.valueOf(requirement.getRequiredExperience())); + String experience = requirement.getRequiredExperience() <= 0 ? "" + : this.user.getTranslationOrNothing(reference + "experience", "[number]", + String.valueOf(requirement.getRequiredExperience())); - String experienceWarning = requirement.getRequiredExperience() > 0 && requirement.isTakeExperience() ? - this.user.getTranslationOrNothing(reference + "experience-warning") : ""; + String experienceWarning = requirement.getRequiredExperience() > 0 && requirement.isTakeExperience() + ? this.user.getTranslationOrNothing(reference + "experience-warning") + : ""; - String money = !this.addon.isEconomyProvided() || requirement.getRequiredMoney() <= 0 ? "" : - this.user.getTranslationOrNothing(reference + "money", - "[number]", String.valueOf(requirement.getRequiredMoney())); + String money = !this.addon.isEconomyProvided() || requirement.getRequiredMoney() <= 0 ? "" + : this.user.getTranslationOrNothing(reference + "money", "[number]", + String.valueOf(requirement.getRequiredMoney())); - String moneyWarning = this.addon.isEconomyProvided() && - requirement.getRequiredMoney() > 0 && - requirement.isTakeMoney() ? - this.user.getTranslationOrNothing(reference + "money-warning") : ""; + String moneyWarning = this.addon.isEconomyProvided() && requirement.getRequiredMoney() > 0 + && requirement.isTakeMoney() ? this.user.getTranslationOrNothing(reference + "money-warning") : ""; - String level = !this.addon.isLevelProvided() || requirement.getRequiredIslandLevel() <= 0 ? "" : - this.user.getTranslationOrNothing(reference + "level", - "[number]", String.valueOf(requirement.getRequiredIslandLevel())); + String level = !this.addon.isLevelProvided() || requirement.getRequiredIslandLevel() <= 0 ? "" + : this.user.getTranslationOrNothing(reference + "level", "[number]", + String.valueOf(requirement.getRequiredIslandLevel())); - return this.user.getTranslationOrNothing(reference + "lore", - "[experience]", experience, - "[experience-warning]", experienceWarning, - "[money]", money, - "[money-warning]", moneyWarning, - "[level]", level); + return this.user.getTranslationOrNothing(reference + "lore", "[experience]", experience, "[experience-warning]", + experienceWarning, "[money]", money, "[money-warning]", moneyWarning, "[level]", level); } - /** * This method generates lore message for Statistic requirement. + * * @param requirement Statistic Requirement. * @return Requirement lore message. */ - private String generateStatisticChallenge(StatisticRequirements requirement) - { + private String generateStatisticChallenge(StatisticRequirements requirement) { final String reference = Constants.DESCRIPTIONS + "challenge.requirements.statistic."; String statistic; - if (requirement.getStatistic() == null) - { + if (requirement.getStatistic() == null) { // Challenges by default comes with empty statistic field. return ""; } - switch (requirement.getStatistic().getType()) - { - case UNTYPED -> statistic = this.user.getTranslationOrNothing(reference + "statistic", - "[statistic]", Utils.prettifyObject(requirement.getStatistic(), this.user), - "[number]", String.valueOf(requirement.getAmount())); - case ITEM, BLOCK -> { - if (requirement.getAmount() > 1) - { - statistic = this.user.getTranslationOrNothing(reference + "multiple-target", - "[statistic]", Utils.prettifyObject(requirement.getStatistic(), this.user), - "[number]", String.valueOf(requirement.getAmount()), - "[target]", Utils.prettifyObject(requirement.getMaterial(), this.user)); - } - else - { - statistic = this.user.getTranslationOrNothing(reference + "single-target", - "[statistic]", Utils.prettifyObject(requirement.getStatistic(), this.user), - "[target]", Utils.prettifyObject(requirement.getMaterial(), this.user)); - } + switch (requirement.getStatistic().getType()) { + case UNTYPED -> statistic = this.user.getTranslationOrNothing(reference + "statistic", "[statistic]", + Utils.prettifyObject(requirement.getStatistic(), this.user), "[number]", + String.valueOf(requirement.getAmount())); + case ITEM, BLOCK -> { + if (requirement.getAmount() > 1) { + statistic = this.user.getTranslationOrNothing(reference + "multiple-target", "[statistic]", + Utils.prettifyObject(requirement.getStatistic(), this.user), "[number]", + String.valueOf(requirement.getAmount()), "[target]", + Utils.prettifyObject(requirement.getMaterial(), this.user)); + } else { + statistic = this.user.getTranslationOrNothing(reference + "single-target", "[statistic]", + Utils.prettifyObject(requirement.getStatistic(), this.user), "[target]", + Utils.prettifyObject(requirement.getMaterial(), this.user)); } - case ENTITY -> { - if (requirement.getAmount() > 1) - { - statistic = this.user.getTranslationOrNothing(reference + "multiple-target", - "[statistic]", Utils.prettifyObject(requirement.getStatistic(), this.user), - "[number]", String.valueOf(requirement.getAmount()), - "[target]", Utils.prettifyObject(requirement.getEntity(), this.user)); - } - else - { - statistic = this.user.getTranslationOrNothing(reference + "single-target", - "[statistic]", Utils.prettifyObject(requirement.getStatistic(), this.user), - "[target]", Utils.prettifyObject(requirement.getEntity(), this.user)); - } + } + case ENTITY -> { + if (requirement.getAmount() > 1) { + statistic = this.user.getTranslationOrNothing(reference + "multiple-target", "[statistic]", + Utils.prettifyObject(requirement.getStatistic(), this.user), "[number]", + String.valueOf(requirement.getAmount()), "[target]", + Utils.prettifyObject(requirement.getEntity(), this.user)); + } else { + statistic = this.user.getTranslationOrNothing(reference + "single-target", "[statistic]", + Utils.prettifyObject(requirement.getStatistic(), this.user), "[target]", + Utils.prettifyObject(requirement.getEntity(), this.user)); } - default -> statistic = ""; + } + default -> statistic = ""; } - String warning = requirement.isReduceStatistic() ? - this.user.getTranslationOrNothing(reference + "warning") : ""; + String warning = requirement.isReduceStatistic() ? this.user.getTranslationOrNothing(reference + "warning") + : ""; - return this.user.getTranslationOrNothing(reference + "lore", - "[statistic]", statistic, - "[warning]", warning); + return this.user.getTranslationOrNothing(reference + "lore", "[statistic]", statistic, "[warning]", warning); } - /** * This message generates challenge status description. - * @param completedOnce Indicate that challenge is completed at least one time. - * @param completedAll Indicate that challenge is not repeatable anymore. + * + * @param completedOnce Indicate that challenge is completed at least one + * time. + * @param completedAll Indicate that challenge is not repeatable anymore. * @param completionCount Number of completion count. - * @param maxCompletions Number of max completion count. + * @param maxCompletions Number of max completion count. * @return String with a text that will be generated for status. */ - private String generateChallengeStatus(boolean completedOnce, - boolean completedAll, - long completionCount, - int maxCompletions) - { + private String generateChallengeStatus(boolean completedOnce, boolean completedAll, long completionCount, + int maxCompletions) { final String reference = Constants.DESCRIPTIONS + "challenge.status."; - if (completedAll) - { - if (maxCompletions > 1) - { - return this.user.getTranslationOrNothing(reference + "completed-times-reached", - Constants.PARAMETER_MAX, String.valueOf(maxCompletions)); - } - else - { + if (completedAll) { + if (maxCompletions > 1) { + return this.user.getTranslationOrNothing(reference + "completed-times-reached", Constants.PARAMETER_MAX, + String.valueOf(maxCompletions)); + } else { return this.user.getTranslationOrNothing(reference + "completed"); } - } - else if (completedOnce) - { - if (maxCompletions > 0) - { - return this.user.getTranslationOrNothing(reference + "completed-times-of", - Constants.PARAMETER_MAX, String.valueOf(maxCompletions), - Constants.PARAMETER_NUMBER, String.valueOf(completionCount)); - } - else - { - return this.user.getTranslationOrNothing(reference + "completed-times", - Constants.PARAMETER_NUMBER, String.valueOf(completionCount)); + } else if (completedOnce) { + if (maxCompletions > 0) { + return this.user.getTranslationOrNothing(reference + "completed-times-of", Constants.PARAMETER_MAX, + String.valueOf(maxCompletions), Constants.PARAMETER_NUMBER, String.valueOf(completionCount)); + } else { + return this.user.getTranslationOrNothing(reference + "completed-times", Constants.PARAMETER_NUMBER, + String.valueOf(completionCount)); } - } - else - { + } else { return ""; } } - /** * This method creates reward lore text. - * @param challenge Challenge which reward lore must be generated. - * @param isRepeating Boolean that indicate if it is repeating reward or first time. + * + * @param challenge Challenge which reward lore must be generated. + * @param isRepeating Boolean that indicate if it is repeating reward or first + * time. * @return Reward text. */ - private String generateRewards(Challenge challenge, boolean isRepeating) - { - if (isRepeating) - { + private String generateRewards(Challenge challenge, boolean isRepeating) { + if (isRepeating) { return this.generateRepeatReward(challenge); - } - else - { + } else { return this.generateReward(challenge); } } - /** * This method creates repeat reward lore text. + * * @param challenge Challenge which reward lore must be generated. * @return Reward text. */ - private String generateRepeatReward(Challenge challenge) - { + private String generateRepeatReward(Challenge challenge) { final String reference = Constants.DESCRIPTIONS + "challenge.rewards."; String items; - if (!challenge.getRepeatItemReward().isEmpty()) - { + if (!challenge.getRepeatItemReward().isEmpty()) { StringBuilder builder = new StringBuilder(); builder.append(this.user.getTranslationOrNothing(reference + "item-title")); - Utils.groupEqualItems(challenge.getRepeatItemReward(), challenge.getIgnoreRewardMetaData()).stream(). - sorted(Comparator.comparing(ItemStack::getType)). - forEach(itemStack -> - { - builder.append("\n"); - - if (itemStack.getAmount() > 1) - { - builder.append(this.user.getTranslationOrNothing(reference + "items-value", - "[number]", String.valueOf(itemStack.getAmount()), - "[item]", Utils.prettifyObject(itemStack, this.user))); - } - else - { - builder.append(this.user.getTranslationOrNothing(reference + "item-value", - "[item]", Utils.prettifyObject(itemStack, this.user))); - } - }); + Utils.groupEqualItems(challenge.getRepeatItemReward(), challenge.getIgnoreRewardMetaData()).stream() + .sorted(Comparator.comparing(ItemStack::getType)).forEach(itemStack -> { + builder.append("\n"); + + if (itemStack.getAmount() > 1) { + builder.append(this.user.getTranslationOrNothing(reference + "items-value", "[number]", + String.valueOf(itemStack.getAmount()), "[item]", + Utils.prettifyObject(itemStack, this.user))); + } else { + builder.append(this.user.getTranslationOrNothing(reference + "item-value", "[item]", + Utils.prettifyObject(itemStack, this.user))); + } + }); items = builder.toString(); - } - else - { + } else { items = ""; } - String experience = challenge.getRepeatExperienceReward() <= 0 ? "" : - this.user.getTranslationOrNothing(reference + "experience", - "[number]", String.valueOf(challenge.getRepeatExperienceReward())); + String experience = challenge.getRepeatExperienceReward() <= 0 ? "" + : this.user.getTranslationOrNothing(reference + "experience", "[number]", + String.valueOf(challenge.getRepeatExperienceReward())); - String money = !this.addon.isEconomyProvided() || challenge.getRepeatMoneyReward() <= 0 ? "" : - this.user.getTranslationOrNothing(reference + "money", - "[number]", String.valueOf(challenge.getRepeatMoneyReward())); + String money = !this.addon.isEconomyProvided() || challenge.getRepeatMoneyReward() <= 0 ? "" + : this.user.getTranslationOrNothing(reference + "money", "[number]", + addon.getPlugin().getVault().map(v -> v.format(challenge.getRepeatMoneyReward())) + .orElse(String.valueOf(challenge.getRepeatMoneyReward()))); String commands; - if (!challenge.getRepeatRewardCommands().isEmpty()) - { + if (!challenge.getRepeatRewardCommands().isEmpty()) { StringBuilder permissionBuilder = new StringBuilder(); - if (!challenge.getRepeatRewardCommands().isEmpty()) - { + if (!challenge.getRepeatRewardCommands().isEmpty()) { permissionBuilder.append(this.user.getTranslationOrNothing(reference + "commands-title")); - challenge.getRepeatRewardCommands().forEach(command -> - { + challenge.getRepeatRewardCommands().forEach(command -> { permissionBuilder.append("\n"); - permissionBuilder.append(this.user.getTranslationOrNothing(reference + "command", - "[command]", command)); + permissionBuilder + .append(this.user.getTranslationOrNothing(reference + "command", "[command]", command)); }); } commands = permissionBuilder.toString(); - } - else - { + } else { commands = ""; } - if (challenge.getRepeatRewardText().isEmpty() && - items.isEmpty() && - experience.isEmpty() && - money.isEmpty() && - commands.isEmpty()) - { + if (challenge.getRepeatRewardText().isEmpty() && items.isEmpty() && experience.isEmpty() && money.isEmpty() + && commands.isEmpty()) { // If everything is empty, do not return anything. return ""; } - String rewardText = this.user.getTranslationOrNothing( - "challenges.challenges." + challenge.getUniqueId() + ".repeat-reward-text"); + String rewardText = this.user + .getTranslationOrNothing("challenges.challenges." + challenge.getUniqueId() + ".repeat-reward-text"); - if (rewardText.isEmpty()) - { + if (rewardText.isEmpty()) { rewardText = Util.translateColorCodes(String.join("\n", challenge.getRepeatRewardText())); } - return this.user.getTranslationOrNothing(reference + "lore", - "[text]", rewardText, - "[items]", items, - "[experience]", experience, - "[money]", money, - "[commands]", commands); + return this.user.getTranslationOrNothing(reference + "lore", "[text]", rewardText, "[items]", items, + "[experience]", experience, "[money]", money, "[commands]", commands); } - /** * This method creates reward lore text. + * * @param challenge Challenge which reward lore must be generated. * @return Reward text. */ - private String generateReward(Challenge challenge) - { + private String generateReward(Challenge challenge) { final String reference = Constants.DESCRIPTIONS + "challenge.rewards."; String items; - if (!challenge.getRewardItems().isEmpty()) - { + if (!challenge.getRewardItems().isEmpty()) { StringBuilder builder = new StringBuilder(); builder.append(this.user.getTranslationOrNothing(reference + "item-title")); - Utils.groupEqualItems(challenge.getRewardItems(), challenge.getIgnoreRewardMetaData()).stream(). - sorted(Comparator.comparing(ItemStack::getType)). - forEach(itemStack -> - { - builder.append("\n"); - - if (itemStack.getAmount() > 1) - { - builder.append(this.user.getTranslationOrNothing(reference + "items-value", - "[number]", String.valueOf(itemStack.getAmount()), - "[item]", Utils.prettifyObject(itemStack, this.user))); - } - else - { - builder.append(this.user.getTranslationOrNothing(reference + "item-value", - "[item]", Utils.prettifyObject(itemStack, this.user))); - } - }); + Utils.groupEqualItems(challenge.getRewardItems(), challenge.getIgnoreRewardMetaData()).stream() + .sorted(Comparator.comparing(ItemStack::getType)).forEach(itemStack -> { + builder.append("\n"); + + if (itemStack.getAmount() > 1) { + builder.append(this.user.getTranslationOrNothing(reference + "items-value", "[number]", + String.valueOf(itemStack.getAmount()), "[item]", + Utils.prettifyObject(itemStack, this.user))); + } else { + builder.append(this.user.getTranslationOrNothing(reference + "item-value", "[item]", + Utils.prettifyObject(itemStack, this.user))); + } + }); items = builder.toString(); - } - else - { + } else { items = ""; } - String experience = challenge.getRewardExperience() <= 0 ? "" : - this.user.getTranslationOrNothing(reference + "experience", - "[number]", String.valueOf(challenge.getRewardExperience())); + String experience = challenge.getRewardExperience() <= 0 ? "" + : this.user.getTranslationOrNothing(reference + "experience", "[number]", + String.valueOf(challenge.getRewardExperience())); - String money = !this.addon.isEconomyProvided() || challenge.getRewardMoney() <= 0 ? "" : - this.user.getTranslationOrNothing(reference + "money", - "[number]", String.valueOf(challenge.getRewardMoney())); + String money = !this.addon.isEconomyProvided() || challenge.getRewardMoney() <= 0 ? "" + : this.user.getTranslationOrNothing(reference + "money", "[number]", + addon.getPlugin().getVault().map(v -> v.format(challenge.getRewardMoney())) + .orElse(String.valueOf(challenge.getRewardMoney()))); String commands; - if (!challenge.getRewardCommands().isEmpty()) - { + if (!challenge.getRewardCommands().isEmpty()) { StringBuilder permissionBuilder = new StringBuilder(); - if (!challenge.getRewardCommands().isEmpty()) - { + if (!challenge.getRewardCommands().isEmpty()) { permissionBuilder.append(this.user.getTranslationOrNothing(reference + "commands-title")); - challenge.getRewardCommands().forEach(command -> - { + challenge.getRewardCommands().forEach(command -> { permissionBuilder.append("\n"); - permissionBuilder.append(this.user.getTranslationOrNothing(reference + "command", - "[command]", command)); + permissionBuilder + .append(this.user.getTranslationOrNothing(reference + "command", "[command]", command)); }); } commands = permissionBuilder.toString(); - } - else - { + } else { commands = ""; } - if (challenge.getRewardText().isEmpty() && - items.isEmpty() && - experience.isEmpty() && - money.isEmpty() && - commands.isEmpty()) - { + if (challenge.getRewardText().isEmpty() && items.isEmpty() && experience.isEmpty() && money.isEmpty() + && commands.isEmpty()) { // If everything is empty, do not return anything. return ""; } - String rewardText = this.user.getTranslationOrNothing( - "challenges.challenges." + challenge.getUniqueId() + ".reward-text"); + String rewardText = this.user + .getTranslationOrNothing("challenges.challenges." + challenge.getUniqueId() + ".reward-text"); - if (rewardText.isEmpty()) - { + if (rewardText.isEmpty()) { rewardText = Util.translateColorCodes(String.join("\n", challenge.getRewardText())); } - return this.user.getTranslationOrNothing(reference + "lore", - "[text]", rewardText, - "[items]", items, - "[experience]", experience, - "[money]", money, - "[commands]", commands); + return this.user.getTranslationOrNothing(reference + "lore", "[text]", rewardText, "[items]", items, + "[experience]", experience, "[money]", money, "[commands]", commands); } - /** * This method generates level description string. + * * @param level Level which string must be generated. * @return List with generated description. */ - protected List generateLevelDescription(ChallengeLevel level) - { + protected List generateLevelDescription(ChallengeLevel level) { final String reference = Constants.DESCRIPTIONS + "level."; - // Non-memory optimal code used for easier debugging and nicer code layout for my eye :) + // Non-memory optimal code used for easier debugging and nicer code layout for + // my eye :) // Get status in single string String status = ""; // Get requirements in single string - String waiver = this.manager.isLastLevel(level, this.world) ? "" : - this.user.getTranslationOrNothing(reference + "waiver", - "[number]", String.valueOf(level.getWaiverAmount())); + String waiver = this.manager.isLastLevel(level, this.world) ? "" + : this.user.getTranslationOrNothing(reference + "waiver", "[number]", + String.valueOf(level.getWaiverAmount())); // Get rewards in single string String rewards = this.generateReward(level); - String returnString = this.user.getTranslation(reference + "lore", - "[text]", Util.translateColorCodes(level.getUnlockMessage()), - "[waiver]", waiver, - "[rewards]", rewards, - "[status]", status); + String returnString = this.user.getTranslation(reference + "lore", "[text]", + Util.translateColorCodes(level.getUnlockMessage()), "[waiver]", waiver, "[rewards]", rewards, + "[status]", status); // Remove empty lines and returns as a list. - return Arrays.stream(returnString.replaceAll("(?m)^[ \\t]*\\r?\\n", ""). - split("\n")). - collect(Collectors.toList()); + return Arrays.stream(returnString.replaceAll("(?m)^[ \\t]*\\r?\\n", "").split("\n")) + .collect(Collectors.toList()); } - /** * This method generates level description string. + * * @param levelStatus Level which string must be generated. - * @param user User who calls generation. + * @param user User who calls generation. * @return List with generated description. */ - protected List generateLevelDescription(LevelStatus levelStatus, User user) - { + protected List generateLevelDescription(LevelStatus levelStatus, User user) { ChallengeLevel level = levelStatus.getLevel(); final String reference = Constants.DESCRIPTIONS + "level."; - // Non-memory optimal code used for easier debugging and nicer code layout for my eye :) + // Non-memory optimal code used for easier debugging and nicer code layout for + // my eye :) // Get status in single string String status = this.generateLevelStatus(levelStatus); // Get requirements in single string - String waiver = this.manager.isLastLevel(level, this.world) || - !levelStatus.isUnlocked() || - levelStatus.isComplete() ? - "" : this.user.getTranslationOrNothing(reference + "waiver", - "[number]", String.valueOf(level.getWaiverAmount())); + String waiver = this.manager.isLastLevel(level, this.world) || !levelStatus.isUnlocked() + || levelStatus.isComplete() ? "" + : this.user.getTranslationOrNothing(reference + "waiver", "[number]", + String.valueOf(level.getWaiverAmount())); // Get rewards in single string String rewards = !levelStatus.isUnlocked() ? "" : this.generateReward(level); - String description = this.user.getTranslationOrNothing( - "challenges.levels." + level.getUniqueId() + ".description"); + String description = this.user + .getTranslationOrNothing("challenges.levels." + level.getUniqueId() + ".description"); - if (description.isEmpty()) - { + if (description.isEmpty()) { description = Util.translateColorCodes(String.join("\n", level.getUnlockMessage())); } - String returnString = this.user.getTranslation(reference + "lore", - "[text]", description, - "[waiver]", waiver, - "[rewards]", rewards, - "[status]", status); + String returnString = this.user.getTranslation(reference + "lore", "[text]", description, "[waiver]", waiver, + "[rewards]", rewards, "[status]", status); // Remove empty lines and returns as a list. - return Arrays.stream(returnString.replaceAll("(?m)^[ \\t]*\\r?\\n", ""). - split("\n")). - collect(Collectors.toList()); + return Arrays.stream(returnString.replaceAll("(?m)^[ \\t]*\\r?\\n", "").split("\n")) + .collect(Collectors.toList()); } - /** * This method generates level status description. + * * @param levelStatus Level status which description must be generated. * @return Level status text. */ - private String generateLevelStatus(LevelStatus levelStatus) - { + private String generateLevelStatus(LevelStatus levelStatus) { final String reference = Constants.DESCRIPTIONS + "level.status."; - if (!levelStatus.isUnlocked()) - { - return this.user.getTranslationOrNothing(reference + "locked") + "\n" + - this.user.getTranslationOrNothing(reference + "missing-challenges", - "[number]", String.valueOf(levelStatus.getNumberOfChallengesStillToDo())); - } - else if (levelStatus.isComplete()) - { + if (!levelStatus.isUnlocked()) { + return this.user.getTranslationOrNothing(reference + "locked") + "\n" + + this.user.getTranslationOrNothing(reference + "missing-challenges", "[number]", + String.valueOf(levelStatus.getNumberOfChallengesStillToDo())); + } else if (levelStatus.isComplete()) { return this.user.getTranslationOrNothing(reference + "completed"); - } - else - { + } else { ChallengeLevel level = levelStatus.getLevel(); List challengeList = this.addon.getChallengesManager().getLevelChallenges(level); // Check if unlock message should appear. - int doneChallenges = (int) challengeList. - stream(). - filter(challenge -> this.addon.getChallengesManager().isChallengeComplete(user.getUniqueId(), world, challenge)). - count(); - - return this.user.getTranslation(reference + "completed-challenges-of", - "[number]", String.valueOf(doneChallenges), - "[max]", String.valueOf(challengeList.size())); + int doneChallenges = (int) challengeList.stream().filter(challenge -> this.addon.getChallengesManager() + .isChallengeComplete(user.getUniqueId(), world, challenge)).count(); + + return this.user.getTranslation(reference + "completed-challenges-of", "[number]", + String.valueOf(doneChallenges), "[max]", String.valueOf(challengeList.size())); } } - /** * This method creates reward lore text. + * * @param level ChallengeLevel which reward lore must be generated. * @return Reward text. */ - private String generateReward(ChallengeLevel level) - { + private String generateReward(ChallengeLevel level) { final String reference = Constants.DESCRIPTIONS + "level.rewards."; String items; - if (!level.getRewardItems().isEmpty()) - { + if (!level.getRewardItems().isEmpty()) { StringBuilder builder = new StringBuilder(); builder.append(this.user.getTranslationOrNothing(reference + "item-title")); - Utils.groupEqualItems(level.getRewardItems(), level.getIgnoreRewardMetaData()).stream(). - sorted(Comparator.comparing(ItemStack::getType)). - forEach(itemStack -> - { - builder.append("\n"); - - if (itemStack.getAmount() > 1) - { - builder.append(this.user.getTranslationOrNothing(reference + "items-value", - "[number]", String.valueOf(itemStack.getAmount()), - "[item]", Utils.prettifyObject(itemStack, this.user))); - } - else - { - builder.append(this.user.getTranslationOrNothing(reference + "item-value", - "[item]", Utils.prettifyObject(itemStack, this.user))); - } - }); + Utils.groupEqualItems(level.getRewardItems(), level.getIgnoreRewardMetaData()).stream() + .sorted(Comparator.comparing(ItemStack::getType)).forEach(itemStack -> { + builder.append("\n"); + + if (itemStack.getAmount() > 1) { + builder.append(this.user.getTranslationOrNothing(reference + "items-value", "[number]", + String.valueOf(itemStack.getAmount()), "[item]", + Utils.prettifyObject(itemStack, this.user))); + } else { + builder.append(this.user.getTranslationOrNothing(reference + "item-value", "[item]", + Utils.prettifyObject(itemStack, this.user))); + } + }); items = builder.toString(); - } - else - { + } else { items = ""; } - String experience = level.getRewardExperience() <= 0 ? "" : - this.user.getTranslationOrNothing(reference + "experience", - "[number]", String.valueOf(level.getRewardExperience())); + String experience = level.getRewardExperience() <= 0 ? "" + : this.user.getTranslationOrNothing(reference + "experience", "[number]", + String.valueOf(level.getRewardExperience())); - String money = !this.addon.isEconomyProvided() || level.getRewardMoney() <= 0 ? "" : - this.user.getTranslationOrNothing(reference + "money", - "[number]", String.valueOf(level.getRewardMoney())); + String money = !this.addon.isEconomyProvided() || level.getRewardMoney() <= 0 ? "" + : this.user.getTranslationOrNothing(reference + "money", "[number]", + String.valueOf(level.getRewardMoney())); String commands; - if (!level.getRewardCommands().isEmpty()) - { + if (!level.getRewardCommands().isEmpty()) { StringBuilder permissionBuilder = new StringBuilder(); - if (!level.getRewardCommands().isEmpty()) - { + if (!level.getRewardCommands().isEmpty()) { permissionBuilder.append(this.user.getTranslationOrNothing(reference + "commands-title")); - level.getRewardCommands().forEach(command -> - { + level.getRewardCommands().forEach(command -> { permissionBuilder.append("\n"); - permissionBuilder.append(this.user.getTranslationOrNothing(reference + "command", - "[command]", command)); + permissionBuilder + .append(this.user.getTranslationOrNothing(reference + "command", "[command]", command)); }); } commands = permissionBuilder.toString(); - } - else - { + } else { commands = ""; } - if (level.getRewardText().isEmpty() && - items.isEmpty() && - experience.isEmpty() && - money.isEmpty() && - commands.isEmpty()) - { + if (level.getRewardText().isEmpty() && items.isEmpty() && experience.isEmpty() && money.isEmpty() + && commands.isEmpty()) { // If everything is empty, do not return anything. return ""; } - String rewardText = this.user.getTranslationOrNothing( - "challenges.levels." + level.getUniqueId() + ".reward-text"); + String rewardText = this.user + .getTranslationOrNothing("challenges.levels." + level.getUniqueId() + ".reward-text"); - if (rewardText.isEmpty()) - { + if (rewardText.isEmpty()) { rewardText = Util.translateColorCodes(String.join("\n", level.getRewardText())); } - return this.user.getTranslationOrNothing(reference + "lore", - "[text]", rewardText, - "[items]", items, - "[experience]", experience, - "[money]", money, - "[commands]", commands); + return this.user.getTranslationOrNothing(reference + "lore", "[text]", rewardText, "[items]", items, + "[experience]", experience, "[money]", money, "[commands]", commands); } - -// --------------------------------------------------------------------- -// Section: Variables -// --------------------------------------------------------------------- - + // --------------------------------------------------------------------- + // Section: Variables + // --------------------------------------------------------------------- /** * This variable stores parent gui. diff --git a/src/main/java/world/bentobox/challenges/panel/admin/EditChallengePanel.java b/src/main/java/world/bentobox/challenges/panel/admin/EditChallengePanel.java index 8c026e42..147f8f7b 100644 --- a/src/main/java/world/bentobox/challenges/panel/admin/EditChallengePanel.java +++ b/src/main/java/world/bentobox/challenges/panel/admin/EditChallengePanel.java @@ -1,8 +1,13 @@ package world.bentobox.challenges.panel.admin; - import java.time.Duration; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -27,2093 +32,1740 @@ import world.bentobox.challenges.database.object.requirements.StatisticRequirements; import world.bentobox.challenges.panel.CommonPanel; import world.bentobox.challenges.panel.ConversationUtils; -import world.bentobox.challenges.panel.util.*; +import world.bentobox.challenges.panel.util.EnvironmentSelector; +import world.bentobox.challenges.panel.util.ItemSelector; +import world.bentobox.challenges.panel.util.MultiBlockSelector; +import world.bentobox.challenges.panel.util.SingleBlockSelector; +import world.bentobox.challenges.panel.util.SingleEntitySelector; +import world.bentobox.challenges.panel.util.StatisticSelector; import world.bentobox.challenges.utils.Constants; import world.bentobox.challenges.utils.Utils; - /** - * This class contains all necessary methods that creates GUI and allow to edit challenges - * properties. + * This class contains all necessary methods that creates GUI and allow to edit + * challenges properties. */ -public class EditChallengePanel extends CommonPanel -{ +public class EditChallengePanel extends CommonPanel { // --------------------------------------------------------------------- // Section: Constructors // --------------------------------------------------------------------- - /** - * @param addon Addon where panel operates. - * @param world World from which panel was created. - * @param user User who created panel. - * @param topLabel Command top label which creates panel (f.e. island or ai) + * @param addon Addon where panel operates. + * @param world World from which panel was created. + * @param user User who created panel. + * @param topLabel Command top label which creates panel (f.e. island or + * ai) * @param permissionPrefix Command permission prefix (f.e. bskyblock.) - * @param challenge - challenge that needs editing + * @param challenge - challenge that needs editing */ - private EditChallengePanel(ChallengesAddon addon, - User user, - World world, - String topLabel, - String permissionPrefix, - Challenge challenge) - { - super(addon, user, world, topLabel, permissionPrefix); - this.challenge = challenge; - this.currentMenuType = MenuType.PROPERTIES; + private EditChallengePanel(ChallengesAddon addon, User user, World world, String topLabel, String permissionPrefix, + Challenge challenge) { + super(addon, user, world, topLabel, permissionPrefix); + this.challenge = challenge; + this.currentMenuType = MenuType.PROPERTIES; } - /** - * @param panel Parent panel + * @param panel Parent panel * @param challenge challenge that needs editing. */ - private EditChallengePanel(CommonPanel panel, Challenge challenge) - { - super(panel); - this.challenge = challenge; - // Default panel should be Properties. - this.currentMenuType = MenuType.PROPERTIES; + private EditChallengePanel(CommonPanel panel, Challenge challenge) { + super(panel); + this.challenge = challenge; + // Default panel should be Properties. + this.currentMenuType = MenuType.PROPERTIES; } - /** * Open the Challenges Edit GUI. * - * @param addon the addon - * @param world the world - * @param user the user - * @param topLabel the top label + * @param addon the addon + * @param world the world + * @param user the user + * @param topLabel the top label * @param permissionPrefix the permission prefix - * @param challenge - challenge that needs editing + * @param challenge - challenge that needs editing */ - public static void open(ChallengesAddon addon, - User user, - World world, - String topLabel, - String permissionPrefix, - Challenge challenge) - { - new EditChallengePanel(addon, user, world, topLabel, permissionPrefix, challenge).build(); + public static void open(ChallengesAddon addon, User user, World world, String topLabel, String permissionPrefix, + Challenge challenge) { + new EditChallengePanel(addon, user, world, topLabel, permissionPrefix, challenge).build(); } - /** * Open the Challenges Edit GUI. * - * @param panel - Parent Panel + * @param panel - Parent Panel * @param challenge - challenge that needs editing */ - public static void open(CommonPanel panel, Challenge challenge) - { - new EditChallengePanel(panel, challenge).build(); + public static void open(CommonPanel panel, Challenge challenge) { + new EditChallengePanel(panel, challenge).build(); } - // --------------------------------------------------------------------- // Section: Panel Creation related methods // --------------------------------------------------------------------- - /** * {@inheritDoc} */ @Override - protected void build() - { - PanelBuilder panelBuilder = new PanelBuilder().user(this.user).name( - this.user.getTranslation(Constants.TITLE + "edit-challenge", - "[challenge]", this.challenge.getFriendlyName())); - - PanelUtils.fillBorder(panelBuilder); - - panelBuilder.item(2, this.createMenuButton(MenuType.PROPERTIES)); - panelBuilder.item(4, this.createMenuButton(MenuType.REQUIREMENTS)); - panelBuilder.item(6, this.createMenuButton(MenuType.REWARDS)); - - if (this.currentMenuType.equals(MenuType.PROPERTIES)) - { - this.buildMainPropertiesPanel(panelBuilder); - } - else if (this.currentMenuType.equals(MenuType.REQUIREMENTS)) - { - switch (this.challenge.getChallengeType()) - { - case INVENTORY_TYPE -> this.buildInventoryRequirementsPanel(panelBuilder); - case ISLAND_TYPE -> this.buildIslandRequirementsPanel(panelBuilder); - case OTHER_TYPE -> this.buildOtherRequirementsPanel(panelBuilder); - case STATISTIC_TYPE -> this.buildStatisticRequirementsPanel(panelBuilder); - } - } - else if (this.currentMenuType.equals(MenuType.REWARDS)) - { - this.buildRewardsPanel(panelBuilder); - } - - panelBuilder.item(44, this.returnButton); - - // Every time when this GUI is build, save challenge - // This will ensure that all main things will be always stored - this.addon.getChallengesManager().saveChallenge(this.challenge); - // If for some reason challenge is not loaded, do it. - this.addon.getChallengesManager().loadChallenge(this.challenge, this.world,false, null, true); - - panelBuilder.build(); + protected void build() { + PanelBuilder panelBuilder = new PanelBuilder().user(this.user).name(this.user + .getTranslation(Constants.TITLE + "edit-challenge", "[challenge]", this.challenge.getFriendlyName())); + + PanelUtils.fillBorder(panelBuilder); + + panelBuilder.item(2, this.createMenuButton(MenuType.PROPERTIES)); + panelBuilder.item(4, this.createMenuButton(MenuType.REQUIREMENTS)); + panelBuilder.item(6, this.createMenuButton(MenuType.REWARDS)); + + if (this.currentMenuType.equals(MenuType.PROPERTIES)) { + this.buildMainPropertiesPanel(panelBuilder); + } else if (this.currentMenuType.equals(MenuType.REQUIREMENTS)) { + switch (this.challenge.getChallengeType()) { + case INVENTORY_TYPE -> this.buildInventoryRequirementsPanel(panelBuilder); + case ISLAND_TYPE -> this.buildIslandRequirementsPanel(panelBuilder); + case OTHER_TYPE -> this.buildOtherRequirementsPanel(panelBuilder); + case STATISTIC_TYPE -> this.buildStatisticRequirementsPanel(panelBuilder); + } + } else if (this.currentMenuType.equals(MenuType.REWARDS)) { + this.buildRewardsPanel(panelBuilder); + } + + panelBuilder.item(44, this.returnButton); + + // Every time when this GUI is build, save challenge + // This will ensure that all main things will be always stored + this.addon.getChallengesManager().saveChallenge(this.challenge); + // If for some reason challenge is not loaded, do it. + this.addon.getChallengesManager().loadChallenge(this.challenge, this.world, false, null, true); + + panelBuilder.build(); } - /** * This class populate ChallengesEditGUI with main challenge settings. + * * @param panelBuilder PanelBuilder where icons must be added. */ - private void buildMainPropertiesPanel(PanelBuilder panelBuilder) - { - panelBuilder.listener(new IconChanger()); + private void buildMainPropertiesPanel(PanelBuilder panelBuilder) { + panelBuilder.listener(new IconChanger()); - panelBuilder.item(10, this.createButton(Button.NAME)); - panelBuilder.item(16, this.createButton(Button.DEPLOYED)); + panelBuilder.item(10, this.createButton(Button.NAME)); + panelBuilder.item(16, this.createButton(Button.DEPLOYED)); - panelBuilder.item(19, this.createButton(Button.ICON)); - panelBuilder.item(22, this.createButton(Button.DESCRIPTION)); - panelBuilder.item(25, this.createButton(Button.ORDER)); + panelBuilder.item(19, this.createButton(Button.ICON)); + panelBuilder.item(22, this.createButton(Button.DESCRIPTION)); + panelBuilder.item(25, this.createButton(Button.ORDER)); - panelBuilder.item(28, this.createButton(Button.ENVIRONMENT)); - panelBuilder.item(31, this.createButton(Button.REMOVE_ON_COMPLETE)); + panelBuilder.item(28, this.createButton(Button.ENVIRONMENT)); + panelBuilder.item(31, this.createButton(Button.REMOVE_ON_COMPLETE)); } - /** - * This class populates ChallengesEditGUI with island challenges requirement elements. + * This class populates ChallengesEditGUI with island challenges requirement + * elements. + * * @param panelBuilder PanelBuilder where icons must be added. */ - private void buildIslandRequirementsPanel(PanelBuilder panelBuilder) - { - panelBuilder.item(19, this.createRequirementButton(RequirementButton.REQUIRED_ENTITIES)); - panelBuilder.item(28, this.createRequirementButton(RequirementButton.REMOVE_ENTITIES)); + private void buildIslandRequirementsPanel(PanelBuilder panelBuilder) { + panelBuilder.item(19, this.createRequirementButton(RequirementButton.REQUIRED_ENTITIES)); + panelBuilder.item(28, this.createRequirementButton(RequirementButton.REMOVE_ENTITIES)); - panelBuilder.item(21, this.createRequirementButton(RequirementButton.REQUIRED_BLOCKS)); - panelBuilder.item(30, this.createRequirementButton(RequirementButton.REMOVE_BLOCKS)); + panelBuilder.item(21, this.createRequirementButton(RequirementButton.REQUIRED_BLOCKS)); + panelBuilder.item(30, this.createRequirementButton(RequirementButton.REMOVE_BLOCKS)); - panelBuilder.item(23, this.createRequirementButton(RequirementButton.SEARCH_RADIUS)); - panelBuilder.item(25, this.createRequirementButton(RequirementButton.REQUIRED_PERMISSIONS)); + panelBuilder.item(23, this.createRequirementButton(RequirementButton.SEARCH_RADIUS)); + panelBuilder.item(25, this.createRequirementButton(RequirementButton.REQUIRED_PERMISSIONS)); } - /** - * This class populates ChallengesEditGUI with inventory challenges requirement elements. + * This class populates ChallengesEditGUI with inventory challenges requirement + * elements. + * * @param panelBuilder PanelBuilder where icons must be added. */ - private void buildInventoryRequirementsPanel(PanelBuilder panelBuilder) - { - panelBuilder.item(10, this.createRequirementButton(RequirementButton.REQUIRED_ITEMS)); - panelBuilder.item(19, this.createRequirementButton(RequirementButton.REMOVE_ITEMS)); - - if (!this.challenge.getRequirements().getRequiredItems().isEmpty()) - { - panelBuilder.item(12, this.createRequirementButton(RequirementButton.ADD_IGNORED_META)); - - if (!this.challenge.getRequirements().getIgnoreMetaData().isEmpty()) - { - panelBuilder.item(21, this.createRequirementButton(RequirementButton.REMOVE_IGNORED_META)); - } - } - - panelBuilder.item(25, this.createRequirementButton(RequirementButton.REQUIRED_PERMISSIONS)); - } + private void buildInventoryRequirementsPanel(PanelBuilder panelBuilder) { + panelBuilder.item(10, this.createRequirementButton(RequirementButton.REQUIRED_ITEMS)); + panelBuilder.item(19, this.createRequirementButton(RequirementButton.REMOVE_ITEMS)); + + if (!this.challenge.getRequirements().getRequiredItems().isEmpty()) { + panelBuilder.item(12, this.createRequirementButton(RequirementButton.ADD_IGNORED_META)); + if (!this.challenge.getRequirements().getIgnoreMetaData().isEmpty()) { + panelBuilder.item(21, this.createRequirementButton(RequirementButton.REMOVE_IGNORED_META)); + } + } + + panelBuilder.item(25, this.createRequirementButton(RequirementButton.REQUIRED_PERMISSIONS)); + } /** - * This class populates ChallengesEditGUI with other challenges requirement elements. + * This class populates ChallengesEditGUI with other challenges requirement + * elements. + * * @param panelBuilder PanelBuilder where icons must be added. */ - private void buildOtherRequirementsPanel(PanelBuilder panelBuilder) - { - panelBuilder.item(10, this.createRequirementButton(RequirementButton.REQUIRED_EXPERIENCE)); - panelBuilder.item(19, this.createRequirementButton(RequirementButton.REMOVE_EXPERIENCE)); + private void buildOtherRequirementsPanel(PanelBuilder panelBuilder) { + panelBuilder.item(10, this.createRequirementButton(RequirementButton.REQUIRED_EXPERIENCE)); + panelBuilder.item(19, this.createRequirementButton(RequirementButton.REMOVE_EXPERIENCE)); - panelBuilder.item(12, this.createRequirementButton(RequirementButton.REQUIRED_MONEY)); - panelBuilder.item(21, this.createRequirementButton(RequirementButton.REMOVE_MONEY)); + panelBuilder.item(12, this.createRequirementButton(RequirementButton.REQUIRED_MONEY)); + panelBuilder.item(21, this.createRequirementButton(RequirementButton.REMOVE_MONEY)); - panelBuilder.item(23, this.createRequirementButton(RequirementButton.REQUIRED_LEVEL)); + panelBuilder.item(23, this.createRequirementButton(RequirementButton.REQUIRED_LEVEL)); - panelBuilder.item(25, this.createRequirementButton(RequirementButton.REQUIRED_PERMISSIONS)); + panelBuilder.item(25, this.createRequirementButton(RequirementButton.REQUIRED_PERMISSIONS)); } - /** - * This class populates ChallengesEditGUI with other challenges requirement elements. + * This class populates ChallengesEditGUI with other challenges requirement + * elements. + * * @param panelBuilder PanelBuilder where icons must be added. */ - private void buildStatisticRequirementsPanel(PanelBuilder panelBuilder) - { - panelBuilder.item(10, this.createRequirementButton(RequirementButton.STATISTIC)); - panelBuilder.item(19, this.createRequirementButton(RequirementButton.REMOVE_STATISTIC)); - - panelBuilder.item(11, this.createRequirementButton(RequirementButton.STATISTIC_AMOUNT)); - - StatisticRequirements requirements = this.challenge.getRequirements(); - - if (requirements.getStatistic() != null) - { - switch (requirements.getStatistic().getType()) - { - case ITEM -> panelBuilder.item(13, this.createRequirementButton(RequirementButton.STATISTIC_ITEMS)); - case BLOCK -> panelBuilder.item(13, this.createRequirementButton(RequirementButton.STATISTIC_BLOCKS)); - case ENTITY -> panelBuilder.item(13, this.createRequirementButton(RequirementButton.STATISTIC_ENTITIES)); - default -> {} - } - } - - panelBuilder.item(25, this.createRequirementButton(RequirementButton.REQUIRED_PERMISSIONS)); - } + private void buildStatisticRequirementsPanel(PanelBuilder panelBuilder) { + panelBuilder.item(10, this.createRequirementButton(RequirementButton.STATISTIC)); + panelBuilder.item(19, this.createRequirementButton(RequirementButton.REMOVE_STATISTIC)); + + panelBuilder.item(11, this.createRequirementButton(RequirementButton.STATISTIC_AMOUNT)); + StatisticRequirements requirements = this.challenge.getRequirements(); + + if (requirements.getStatistic() != null) { + switch (requirements.getStatistic().getType()) { + case ITEM -> panelBuilder.item(13, this.createRequirementButton(RequirementButton.STATISTIC_ITEMS)); + case BLOCK -> panelBuilder.item(13, this.createRequirementButton(RequirementButton.STATISTIC_BLOCKS)); + case ENTITY -> panelBuilder.item(13, this.createRequirementButton(RequirementButton.STATISTIC_ENTITIES)); + default -> { + } + } + } + + panelBuilder.item(25, this.createRequirementButton(RequirementButton.REQUIRED_PERMISSIONS)); + } /** * This class populates ChallengesEditGUI with challenges reward elements. + * * @param panelBuilder PanelBuilder where icons must be added. */ - private void buildRewardsPanel(PanelBuilder panelBuilder) - { - panelBuilder.item(10, this.createRewardButton(RewardButton.REWARD_TEXT)); - panelBuilder.item(19, this.createRewardButton(RewardButton.REWARD_COMMANDS)); - - panelBuilder.item(11, this.createRewardButton(RewardButton.REWARD_ITEMS)); - panelBuilder.item(20, this.createRewardButton(RewardButton.REWARD_EXPERIENCE)); - panelBuilder.item(29, this.createRewardButton(RewardButton.REWARD_MONEY)); - - panelBuilder.item(22, this.createRewardButton(RewardButton.REPEATABLE)); - - if (!this.challenge.getRewardItems().isEmpty() || !this.challenge.getRepeatItemReward().isEmpty()) - { - panelBuilder.item(31, this.createRewardButton(RewardButton.ADD_IGNORED_META)); - } - - if (!this.challenge.getIgnoreRewardMetaData().isEmpty()) - { - panelBuilder.item(32, this.createRewardButton(RewardButton.REMOVE_IGNORED_META)); - } - - if (this.challenge.isRepeatable()) - { - panelBuilder.item(13, this.createRewardButton(RewardButton.COOL_DOWN)); - panelBuilder.item(23, this.createRewardButton(RewardButton.REPEAT_COUNT)); - - panelBuilder.item(15, this.createRewardButton(RewardButton.REPEAT_REWARD_TEXT)); - panelBuilder.item(24, this.createRewardButton(RewardButton.REPEAT_REWARD_COMMANDS)); - - panelBuilder.item(16, this.createRewardButton(RewardButton.REPEAT_REWARD_ITEMS)); - panelBuilder.item(25, this.createRewardButton(RewardButton.REPEAT_REWARD_EXPERIENCE)); - panelBuilder.item(34, this.createRewardButton(RewardButton.REPEAT_REWARD_MONEY)); - } - } + private void buildRewardsPanel(PanelBuilder panelBuilder) { + panelBuilder.item(10, this.createRewardButton(RewardButton.REWARD_TEXT)); + panelBuilder.item(19, this.createRewardButton(RewardButton.REWARD_COMMANDS)); + + panelBuilder.item(11, this.createRewardButton(RewardButton.REWARD_ITEMS)); + panelBuilder.item(20, this.createRewardButton(RewardButton.REWARD_EXPERIENCE)); + panelBuilder.item(29, this.createRewardButton(RewardButton.REWARD_MONEY)); + + panelBuilder.item(22, this.createRewardButton(RewardButton.REPEATABLE)); + if (!this.challenge.getRewardItems().isEmpty() || !this.challenge.getRepeatItemReward().isEmpty()) { + panelBuilder.item(31, this.createRewardButton(RewardButton.ADD_IGNORED_META)); + } + + if (!this.challenge.getIgnoreRewardMetaData().isEmpty()) { + panelBuilder.item(32, this.createRewardButton(RewardButton.REMOVE_IGNORED_META)); + } + + if (this.challenge.isRepeatable()) { + panelBuilder.item(13, this.createRewardButton(RewardButton.COOL_DOWN)); + panelBuilder.item(23, this.createRewardButton(RewardButton.REPEAT_COUNT)); + + panelBuilder.item(15, this.createRewardButton(RewardButton.REPEAT_REWARD_TEXT)); + panelBuilder.item(24, this.createRewardButton(RewardButton.REPEAT_REWARD_COMMANDS)); + + panelBuilder.item(16, this.createRewardButton(RewardButton.REPEAT_REWARD_ITEMS)); + panelBuilder.item(25, this.createRewardButton(RewardButton.REPEAT_REWARD_EXPERIENCE)); + panelBuilder.item(34, this.createRewardButton(RewardButton.REPEAT_REWARD_MONEY)); + } + } // --------------------------------------------------------------------- // Section: Other methods // --------------------------------------------------------------------- - /** * This method creates top menu buttons, that allows to switch "tabs". + * * @param menuType Menu Type which button must be constructed. * @return PanelItem that represents given menu type. */ - private PanelItem createMenuButton(MenuType menuType) - { - final String reference = Constants.BUTTON + menuType.name().toLowerCase() + "."; - - final String name = this.user.getTranslation(reference + "name"); - final List description = new ArrayList<>(3); - description.add(this.user.getTranslation(reference + "description")); - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-select")); - - ItemStack icon; - boolean glow; - PanelItem.ClickHandler clickHandler; - - switch (menuType) - { - case PROPERTIES -> { - icon = new ItemStack(Material.CRAFTING_TABLE); - clickHandler = (panel, user, clickType, slot) -> { - this.currentMenuType = MenuType.PROPERTIES; - this.build(); - - return true; - }; - glow = this.currentMenuType.equals(MenuType.PROPERTIES); - } - case REQUIREMENTS -> { - icon = new ItemStack(Material.HOPPER); - clickHandler = (panel, user, clickType, slot) -> { - this.currentMenuType = MenuType.REQUIREMENTS; - this.build(); - - return true; - }; - glow = this.currentMenuType.equals(MenuType.REQUIREMENTS); - } - case REWARDS -> { - icon = new ItemStack(Material.DROPPER); - clickHandler = (panel, user, clickType, slot) -> { - this.currentMenuType = MenuType.REWARDS; - this.build(); - - return true; - }; - glow = this.currentMenuType.equals(MenuType.REWARDS); - } - default -> { - icon = new ItemStack(Material.PAPER); - clickHandler = null; - glow = false; - } - } - - return new PanelItemBuilder(). - icon(icon). - name(name). - description(description). - glow(glow). - clickHandler(clickHandler). - build(); + private PanelItem createMenuButton(MenuType menuType) { + final String reference = Constants.BUTTON + menuType.name().toLowerCase() + "."; + + final String name = this.user.getTranslation(reference + "name"); + final List description = new ArrayList<>(3); + description.add(this.user.getTranslation(reference + "description")); + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-select")); + + ItemStack icon; + boolean glow; + PanelItem.ClickHandler clickHandler; + + switch (menuType) { + case PROPERTIES -> { + icon = new ItemStack(Material.CRAFTING_TABLE); + clickHandler = (panel, user, clickType, slot) -> { + this.currentMenuType = MenuType.PROPERTIES; + this.build(); + + return true; + }; + glow = this.currentMenuType.equals(MenuType.PROPERTIES); + } + case REQUIREMENTS -> { + icon = new ItemStack(Material.HOPPER); + clickHandler = (panel, user, clickType, slot) -> { + this.currentMenuType = MenuType.REQUIREMENTS; + this.build(); + + return true; + }; + glow = this.currentMenuType.equals(MenuType.REQUIREMENTS); + } + case REWARDS -> { + icon = new ItemStack(Material.DROPPER); + clickHandler = (panel, user, clickType, slot) -> { + this.currentMenuType = MenuType.REWARDS; + this.build(); + + return true; + }; + glow = this.currentMenuType.equals(MenuType.REWARDS); + } + default -> { + icon = new ItemStack(Material.PAPER); + clickHandler = null; + glow = false; + } + } + + return new PanelItemBuilder().icon(icon).name(name).description(description).glow(glow) + .clickHandler(clickHandler).build(); } - /** * This method creates buttons for default main menu. + * * @param button Button which panel item must be created. * @return PanelItem that represents given button. */ - private PanelItem createButton(Button button) - { - final String reference = Constants.BUTTON + button.name().toLowerCase() + "."; - - final String name = this.user.getTranslation(reference + "name"); - final List description = new ArrayList<>(3); - description.add(this.user.getTranslation(reference + "description")); - - ItemStack icon; - boolean glow; - PanelItem.ClickHandler clickHandler; - - switch (button) - { - case NAME -> { - description.add(this.user.getTranslation(reference + "value", - Constants.PARAMETER_NAME, this.challenge.getFriendlyName())); - - icon = new ItemStack(Material.NAME_TAG); - - clickHandler = (panel, user, clickType, i) -> - { - // Create consumer that process description change - Consumer consumer = value -> - { - if (value != null) - { - this.challenge.setFriendlyName(value); - } - - this.build(); - }; - - // start conversation - ConversationUtils.createStringInput(consumer, - user, - user.getTranslation(Constants.CONVERSATIONS + "write-name"), - user.getTranslation(Constants.CONVERSATIONS + "name-changed")); - - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - } - case DEPLOYED -> { - description.add(this.user.getTranslation(reference + - (this.challenge.isDeployed() ? "enabled" : "disabled"))); - - icon = new ItemStack(Material.LEVER); - clickHandler = (panel, user, clickType, slot) -> { - if (this.challenge.isValid()) - { - this.challenge.setDeployed(!this.challenge.isDeployed()); - } - else - { - Utils.sendMessage(this.user, - this.world, - Constants.CONVERSATIONS + "invalid-challenge", - Constants.PARAMETER_CHALLENGE, - this.challenge.getFriendlyName()); - this.challenge.setDeployed(false); - } - - this.build(); - return true; - }; - glow = this.challenge.isDeployed(); - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-toggle")); - } - case ICON -> { - icon = this.challenge.getIcon(); - clickHandler = (panel, user, clickType, i) -> - { - this.selectedButton = button; - this.build(); - return true; - }; - glow = this.selectedButton == button; - - if (this.selectedButton != button) - { - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - } - else - { - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-on-item")); - } - } - case DESCRIPTION -> { - icon = new ItemStack(Material.WRITTEN_BOOK); - - description.add(this.user.getTranslation(reference + "value")); - this.challenge.getDescription().forEach(line -> description.add(Util.translateColorCodes(line))); - - clickHandler = (panel, user, clickType, i) -> - { - // Create consumer that process description change - Consumer> consumer = value -> - { - if (value != null) - { - this.challenge.setDescription(value); - } - - this.build(); - }; - - if (!this.challenge.getDescription().isEmpty() && clickType.isShiftClick()) - { - // Reset to the empty value - consumer.accept(Collections.emptyList()); - } - else - { - // start conversation - ConversationUtils.createStringListInput(consumer, - user, - user.getTranslation(Constants.CONVERSATIONS + "write-description"), - user.getTranslation(Constants.CONVERSATIONS + "description-changed")); - } - - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - - if (!this.challenge.getDescription().isEmpty()) - { - description.add(this.user.getTranslation(Constants.TIPS + "shift-click-to-reset")); - } - } - case ORDER -> { - description.add(this.user.getTranslation(reference + "value", - Constants.PARAMETER_NUMBER, String.valueOf(this.challenge.getOrder()))); - - icon = new ItemStack(Material.HOPPER, Math.max(1, this.challenge.getOrder())); - clickHandler = (panel, user, clickType, i) -> { - Consumer numberConsumer = number -> { - if (number != null) - { - this.challenge.setOrder(number.intValue()); - } - - // reopen panel - this.build(); - }; - - ConversationUtils.createNumericInput(numberConsumer, - this.user, - this.user.getTranslation(Constants.CONVERSATIONS + "input-number"), - 0, - 2000); - - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - } - case ENVIRONMENT -> { - description.add(this.user.getTranslation(this.challenge.getEnvironment().contains(World.Environment.NORMAL) ? - reference + "enabled" : reference + "disabled") + - Utils.prettifyObject(World.Environment.NORMAL, this.user)); - description.add(this.user.getTranslation(this.challenge.getEnvironment().contains(World.Environment.NETHER) ? - reference + "enabled" : reference + "disabled") + - Utils.prettifyObject(World.Environment.NETHER, this.user)); - description.add(this.user.getTranslation(this.challenge.getEnvironment().contains(World.Environment.THE_END) ? - reference + "enabled" : reference + "disabled") + - Utils.prettifyObject(World.Environment.THE_END, this.user)); - - icon = new ItemStack(Material.DROPPER); - clickHandler = (panel, user, clickType, slot) -> { - EnvironmentSelector.open(this.user, - this.challenge.getEnvironment(), - (status, value) -> { - if (status) - { - this.challenge.setEnvironment(value); - } - - this.build(); - }); - - return true; - }; - glow = false; - } - case REMOVE_ON_COMPLETE -> { - description.add(this.user.getTranslation(reference + - (this.challenge.isRemoveWhenCompleted() ? "enabled" : "disabled"))); - - if (this.challenge.isRemoveWhenCompleted()) - { - icon = new ItemStack(Material.LAVA_BUCKET); - } - else - { - icon = new ItemStack(Material.BUCKET); - } - - clickHandler = (panel, user, clickType, slot) -> { - this.challenge.setRemoveWhenCompleted(!this.challenge.isRemoveWhenCompleted()); - this.build(); - - return true; - }; - glow = this.challenge.isRemoveWhenCompleted(); - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-toggle")); - } - default -> { - icon = new ItemStack(Material.PAPER); - clickHandler = null; - glow = false; - } - } - - return new PanelItemBuilder(). - icon(icon). - name(name). - description(description). - glow(glow). - clickHandler(clickHandler). - build(); + private PanelItem createButton(Button button) { + final String reference = Constants.BUTTON + button.name().toLowerCase() + "."; + + final String name = this.user.getTranslation(reference + "name"); + final List description = new ArrayList<>(3); + description.add(this.user.getTranslation(reference + "description")); + + ItemStack icon; + boolean glow; + PanelItem.ClickHandler clickHandler; + + switch (button) { + case NAME -> { + description.add(this.user.getTranslation(reference + "value", Constants.PARAMETER_NAME, + this.challenge.getFriendlyName())); + + icon = new ItemStack(Material.NAME_TAG); + + clickHandler = (panel, user, clickType, i) -> { + // Create consumer that process description change + Consumer consumer = value -> { + if (value != null) { + this.challenge.setFriendlyName(value); + } + + this.build(); + }; + + // start conversation + ConversationUtils.createStringInput(consumer, user, + user.getTranslation(Constants.CONVERSATIONS + "write-name"), + user.getTranslation(Constants.CONVERSATIONS + "name-changed")); + + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + } + case DEPLOYED -> { + description + .add(this.user.getTranslation(reference + (this.challenge.isDeployed() ? "enabled" : "disabled"))); + + icon = new ItemStack(Material.LEVER); + clickHandler = (panel, user, clickType, slot) -> { + if (this.challenge.isValid()) { + this.challenge.setDeployed(!this.challenge.isDeployed()); + } else { + Utils.sendMessage(this.user, this.world, Constants.CONVERSATIONS + "invalid-challenge", + Constants.PARAMETER_CHALLENGE, this.challenge.getFriendlyName()); + this.challenge.setDeployed(false); + } + + this.build(); + return true; + }; + glow = this.challenge.isDeployed(); + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-toggle")); + } + case ICON -> { + icon = this.challenge.getIcon(); + clickHandler = (panel, user, clickType, i) -> { + this.selectedButton = button; + this.build(); + return true; + }; + glow = this.selectedButton == button; + + if (this.selectedButton != button) { + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + } else { + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-on-item")); + } + } + case DESCRIPTION -> { + icon = new ItemStack(Material.WRITTEN_BOOK); + + description.add(this.user.getTranslation(reference + "value")); + this.challenge.getDescription().forEach(line -> description.add(Util.translateColorCodes(line))); + + clickHandler = (panel, user, clickType, i) -> { + // Create consumer that process description change + Consumer> consumer = value -> { + if (value != null) { + this.challenge.setDescription(value); + } + + this.build(); + }; + + if (!this.challenge.getDescription().isEmpty() && clickType.isShiftClick()) { + // Reset to the empty value + consumer.accept(Collections.emptyList()); + } else { + // start conversation + ConversationUtils.createStringListInput(consumer, user, + user.getTranslation(Constants.CONVERSATIONS + "write-description"), + user.getTranslation(Constants.CONVERSATIONS + "description-changed")); + } + + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + + if (!this.challenge.getDescription().isEmpty()) { + description.add(this.user.getTranslation(Constants.TIPS + "shift-click-to-reset")); + } + } + case ORDER -> { + description.add(this.user.getTranslation(reference + "value", Constants.PARAMETER_NUMBER, + String.valueOf(this.challenge.getOrder()))); + + icon = new ItemStack(Material.HOPPER, Math.max(1, this.challenge.getOrder())); + clickHandler = (panel, user, clickType, i) -> { + Consumer numberConsumer = number -> { + if (number != null) { + this.challenge.setOrder(number.intValue()); + } + + // reopen panel + this.build(); + }; + + ConversationUtils.createNumericInput(numberConsumer, this.user, + this.user.getTranslation(Constants.CONVERSATIONS + "input-number"), 0, 2000); + + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + } + case ENVIRONMENT -> { + description.add(this.user.getTranslation( + this.challenge.getEnvironment().contains(World.Environment.NORMAL) ? reference + "enabled" + : reference + "disabled") + + Utils.prettifyObject(World.Environment.NORMAL, this.user)); + description.add(this.user.getTranslation( + this.challenge.getEnvironment().contains(World.Environment.NETHER) ? reference + "enabled" + : reference + "disabled") + + Utils.prettifyObject(World.Environment.NETHER, this.user)); + description.add(this.user.getTranslation( + this.challenge.getEnvironment().contains(World.Environment.THE_END) ? reference + "enabled" + : reference + "disabled") + + Utils.prettifyObject(World.Environment.THE_END, this.user)); + + icon = new ItemStack(Material.DROPPER); + clickHandler = (panel, user, clickType, slot) -> { + EnvironmentSelector.open(this.user, this.challenge.getEnvironment(), (status, value) -> { + if (status) { + this.challenge.setEnvironment(value); + } + + this.build(); + }); + + return true; + }; + glow = false; + } + case REMOVE_ON_COMPLETE -> { + description.add(this.user + .getTranslation(reference + (this.challenge.isRemoveWhenCompleted() ? "enabled" : "disabled"))); + + if (this.challenge.isRemoveWhenCompleted()) { + icon = new ItemStack(Material.LAVA_BUCKET); + } else { + icon = new ItemStack(Material.BUCKET); + } + + clickHandler = (panel, user, clickType, slot) -> { + this.challenge.setRemoveWhenCompleted(!this.challenge.isRemoveWhenCompleted()); + this.build(); + + return true; + }; + glow = this.challenge.isRemoveWhenCompleted(); + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-toggle")); + } + default -> { + icon = new ItemStack(Material.PAPER); + clickHandler = null; + glow = false; + } + } + + return new PanelItemBuilder().icon(icon).name(name).description(description).glow(glow) + .clickHandler(clickHandler).build(); } - /** * This method creates buttons for requirements menu. + * * @param button Button which panel item must be created. * @return PanelItem that represents given button. */ - private PanelItem createRequirementButton(RequirementButton button) - { - switch (button) - { - case REQUIRED_PERMISSIONS -> { - String reference = Constants.BUTTON + button.name().toLowerCase() + "."; - - String name = this.user.getTranslation(reference + "name"); - final List description = new ArrayList<>(3); - description.add(this.user.getTranslation(reference + "description")); - - if (this.challenge.getRequirements().getRequiredPermissions().isEmpty()) - { - description.add(this.user.getTranslation(reference + "none")); - } - else - { - description.add(this.user.getTranslation(reference + "title")); - - this.challenge.getRequirements().getRequiredPermissions().forEach(permission -> - description.add(this.user.getTranslation(reference + "permission", - "[permission]", permission))); - } - - ItemStack icon = new ItemStack(Material.REDSTONE_LAMP); - - PanelItem.ClickHandler clickHandler = (panel, user, clickType, i) -> - { - // Create consumer that process description change - Consumer> consumer = value -> - { - if (value != null) - { - this.challenge.getRequirements().setRequiredPermissions(new HashSet<>(value)); - } - - this.build(); - }; - - if (!this.challenge.getRequirements().getRequiredPermissions().isEmpty() && - clickType.isShiftClick()) - { - // Reset to the empty value - consumer.accept(Collections.emptyList()); - } - else - { - // start conversation - ConversationUtils.createStringListInput(consumer, - user, - user.getTranslation(Constants.CONVERSATIONS + "write-permissions"), - user.getTranslation(Constants.CONVERSATIONS + "permissions-changed")); - } - - return true; - }; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - - if (!this.challenge.getRequirements().getRequiredPermissions().isEmpty()) - { - description.add(this.user.getTranslation(Constants.TIPS + "shift-click-to-reset")); - } - - return new PanelItemBuilder(). - icon(icon). - name(name). - description(description). - clickHandler(clickHandler). - build(); - } - // Buttons for Island Requirements - case REQUIRED_ENTITIES, REMOVE_ENTITIES, REQUIRED_BLOCKS, REMOVE_BLOCKS, SEARCH_RADIUS -> { - return this.createIslandRequirementButton(button); - } - // Buttons for Inventory Requirements - case REQUIRED_ITEMS, REMOVE_ITEMS, ADD_IGNORED_META, REMOVE_IGNORED_META -> { - return this.createInventoryRequirementButton(button); - } - // Buttons for Other Requirements - case REQUIRED_EXPERIENCE, REMOVE_EXPERIENCE, REQUIRED_LEVEL, REQUIRED_MONEY, REMOVE_MONEY -> { - return this.createOtherRequirementButton(button); - } - // Buttons for Statistic Requirements - case STATISTIC, STATISTIC_BLOCKS, STATISTIC_ITEMS, STATISTIC_ENTITIES, STATISTIC_AMOUNT, REMOVE_STATISTIC -> { - return this.createStatisticRequirementButton(button); - } - // Default behaviour. - default -> { - return PanelItem.empty(); - } - } + private PanelItem createRequirementButton(RequirementButton button) { + switch (button) { + case REQUIRED_PERMISSIONS -> { + String reference = Constants.BUTTON + button.name().toLowerCase() + "."; + + String name = this.user.getTranslation(reference + "name"); + final List description = new ArrayList<>(3); + description.add(this.user.getTranslation(reference + "description")); + + if (this.challenge.getRequirements().getRequiredPermissions().isEmpty()) { + description.add(this.user.getTranslation(reference + "none")); + } else { + description.add(this.user.getTranslation(reference + "title")); + + this.challenge.getRequirements().getRequiredPermissions().forEach(permission -> description + .add(this.user.getTranslation(reference + "permission", "[permission]", permission))); + } + + ItemStack icon = new ItemStack(Material.REDSTONE_LAMP); + + PanelItem.ClickHandler clickHandler = (panel, user, clickType, i) -> { + // Create consumer that process description change + Consumer> consumer = value -> { + if (value != null) { + this.challenge.getRequirements().setRequiredPermissions(new HashSet<>(value)); + } + + this.build(); + }; + + if (!this.challenge.getRequirements().getRequiredPermissions().isEmpty() && clickType.isShiftClick()) { + // Reset to the empty value + consumer.accept(Collections.emptyList()); + } else { + // start conversation + ConversationUtils.createStringListInput(consumer, user, + user.getTranslation(Constants.CONVERSATIONS + "write-permissions"), + user.getTranslation(Constants.CONVERSATIONS + "permissions-changed")); + } + + return true; + }; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + + if (!this.challenge.getRequirements().getRequiredPermissions().isEmpty()) { + description.add(this.user.getTranslation(Constants.TIPS + "shift-click-to-reset")); + } + + return new PanelItemBuilder().icon(icon).name(name).description(description).clickHandler(clickHandler) + .build(); + } + // Buttons for Island Requirements + case REQUIRED_ENTITIES, REMOVE_ENTITIES, REQUIRED_BLOCKS, REMOVE_BLOCKS, SEARCH_RADIUS -> { + return this.createIslandRequirementButton(button); + } + // Buttons for Inventory Requirements + case REQUIRED_ITEMS, REMOVE_ITEMS, ADD_IGNORED_META, REMOVE_IGNORED_META -> { + return this.createInventoryRequirementButton(button); + } + // Buttons for Other Requirements + case REQUIRED_EXPERIENCE, REMOVE_EXPERIENCE, REQUIRED_LEVEL, REQUIRED_MONEY, REMOVE_MONEY -> { + return this.createOtherRequirementButton(button); + } + // Buttons for Statistic Requirements + case STATISTIC, STATISTIC_BLOCKS, STATISTIC_ITEMS, STATISTIC_ENTITIES, STATISTIC_AMOUNT, REMOVE_STATISTIC -> { + return this.createStatisticRequirementButton(button); + } + // Default behaviour. + default -> { + return PanelItem.empty(); + } + } } - /** * This method creates buttons for island requirements menu. + * * @param button Button which panel item must be created. * @return PanelItem that represents given button. */ - private PanelItem createIslandRequirementButton(RequirementButton button) - { - final String reference = Constants.BUTTON + button.name().toLowerCase() + "."; - - final String name = this.user.getTranslation(reference + "name"); - final List description = new ArrayList<>(3); - description.add(this.user.getTranslation(reference + "description")); - - ItemStack icon; - boolean glow; - PanelItem.ClickHandler clickHandler; - - final IslandRequirements requirements = this.challenge.getRequirements(); - - switch (button) - { - case REQUIRED_ENTITIES -> { - if (requirements.getRequiredEntities().isEmpty()) - { - description.add(this.user.getTranslation(reference + "none")); - } - else - { - description.add(this.user.getTranslation(reference + "title")); - - requirements.getRequiredEntities().forEach((entity, count) -> - description.add(this.user.getTranslation(reference + "list", - "[entity]", Utils.prettifyObject(entity, this.user), - "[number]", String.valueOf(count)))); - } - - icon = new ItemStack(Material.CREEPER_HEAD); - clickHandler = (panel, user, clickType, slot) -> { - ManageEntitiesPanel.open(this, requirements.getRequiredEntities()); - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - } - case REMOVE_ENTITIES -> { - description.add(this.user.getTranslation(reference + - (requirements.isRemoveEntities() ? "enabled" : "disabled"))); - - icon = new ItemStack(Material.LEVER); - clickHandler = (panel, user, clickType, slot) -> { - requirements.setRemoveEntities(!requirements.isRemoveEntities()); - this.build(); - return true; - }; - glow = requirements.isRemoveEntities(); - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-toggle")); - } - case REQUIRED_BLOCKS -> { - if (requirements.getRequiredBlocks().isEmpty()) - { - description.add(this.user.getTranslation(reference + "none")); - } - else - { - description.add(this.user.getTranslation(reference + "title")); - - requirements.getRequiredBlocks().forEach((block, count) -> - description.add(this.user.getTranslation(reference + "list", - "[block]", Utils.prettifyObject(block, this.user), - "[number]", String.valueOf(count)))); - } - - icon = new ItemStack(Material.STONE); - clickHandler = (panel, user, clickType, slot) -> { - ManageBlocksPanel.open(this, requirements.getRequiredBlocks()); - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - } - case REMOVE_BLOCKS -> { - description.add(this.user.getTranslation(reference + - (requirements.isRemoveBlocks() ? "enabled" : "disabled"))); - - icon = new ItemStack(Material.LEVER); - clickHandler = (panel, user, clickType, slot) -> { - requirements.setRemoveBlocks(!requirements.isRemoveBlocks()); - this.build(); - return true; - }; - glow = requirements.isRemoveBlocks(); - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-toggle")); - } - case SEARCH_RADIUS -> { - description.add(this.user.getTranslation(reference + "value", - Constants.PARAMETER_NUMBER, String.valueOf(requirements.getSearchRadius()))); - icon = new ItemStack(Material.COBBLESTONE_WALL); - clickHandler = (panel, user, clickType, i) -> { - Consumer numberConsumer = number -> { - if (number != null) - { - requirements.setSearchRadius(number.intValue()); - } - - // reopen panel - this.build(); - }; - - int maxSearchDistance = - this.addon.getPlugin().getIWM().getAddon(this.world).map(gameModeAddon -> - gameModeAddon.getWorldSettings().getIslandDistance()).orElse(100); - - ConversationUtils.createNumericInput(numberConsumer, - this.user, - this.user.getTranslation(Constants.CONVERSATIONS + "input-number"), - 1, - maxSearchDistance); - - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - } - default -> { - icon = new ItemStack(Material.PAPER); - clickHandler = null; - glow = false; - } - } - - return new PanelItemBuilder(). - icon(icon). - name(name). - description(description). - glow(glow). - clickHandler(clickHandler). - build(); + private PanelItem createIslandRequirementButton(RequirementButton button) { + final String reference = Constants.BUTTON + button.name().toLowerCase() + "."; + + final String name = this.user.getTranslation(reference + "name"); + final List description = new ArrayList<>(3); + description.add(this.user.getTranslation(reference + "description")); + + ItemStack icon; + boolean glow; + PanelItem.ClickHandler clickHandler; + + final IslandRequirements requirements = this.challenge.getRequirements(); + + switch (button) { + case REQUIRED_ENTITIES -> { + if (requirements.getRequiredEntities().isEmpty()) { + description.add(this.user.getTranslation(reference + "none")); + } else { + description.add(this.user.getTranslation(reference + "title")); + + requirements.getRequiredEntities().forEach( + (entity, count) -> description.add(this.user.getTranslation(reference + "list", "[entity]", + Utils.prettifyObject(entity, this.user), "[number]", String.valueOf(count)))); + } + + icon = new ItemStack(Material.CREEPER_HEAD); + clickHandler = (panel, user, clickType, slot) -> { + ManageEntitiesPanel.open(this, requirements.getRequiredEntities()); + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + } + case REMOVE_ENTITIES -> { + description.add( + this.user.getTranslation(reference + (requirements.isRemoveEntities() ? "enabled" : "disabled"))); + + icon = new ItemStack(Material.LEVER); + clickHandler = (panel, user, clickType, slot) -> { + requirements.setRemoveEntities(!requirements.isRemoveEntities()); + this.build(); + return true; + }; + glow = requirements.isRemoveEntities(); + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-toggle")); + } + case REQUIRED_BLOCKS -> { + if (requirements.getRequiredBlocks().isEmpty()) { + description.add(this.user.getTranslation(reference + "none")); + } else { + description.add(this.user.getTranslation(reference + "title")); + + requirements.getRequiredBlocks() + .forEach((block, count) -> description.add(this.user.getTranslation(reference + "list", + "[block]", Utils.prettifyObject(block, this.user), "[number]", String.valueOf(count)))); + } + + icon = new ItemStack(Material.STONE); + clickHandler = (panel, user, clickType, slot) -> { + ManageBlocksPanel.open(this, requirements.getRequiredBlocks()); + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + } + case REMOVE_BLOCKS -> { + description.add( + this.user.getTranslation(reference + (requirements.isRemoveBlocks() ? "enabled" : "disabled"))); + + icon = new ItemStack(Material.LEVER); + clickHandler = (panel, user, clickType, slot) -> { + requirements.setRemoveBlocks(!requirements.isRemoveBlocks()); + this.build(); + return true; + }; + glow = requirements.isRemoveBlocks(); + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-toggle")); + } + case SEARCH_RADIUS -> { + description.add(this.user.getTranslation(reference + "value", Constants.PARAMETER_NUMBER, + String.valueOf(requirements.getSearchRadius()))); + icon = new ItemStack(Material.COBBLESTONE_WALL); + clickHandler = (panel, user, clickType, i) -> { + Consumer numberConsumer = number -> { + if (number != null) { + requirements.setSearchRadius(number.intValue()); + } + + // reopen panel + this.build(); + }; + + int maxSearchDistance = this.addon.getPlugin().getIWM().getAddon(this.world) + .map(gameModeAddon -> gameModeAddon.getWorldSettings().getIslandDistance()).orElse(100); + + ConversationUtils.createNumericInput(numberConsumer, this.user, + this.user.getTranslation(Constants.CONVERSATIONS + "input-number"), 1, maxSearchDistance); + + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + } + default -> { + icon = new ItemStack(Material.PAPER); + clickHandler = null; + glow = false; + } + } + + return new PanelItemBuilder().icon(icon).name(name).description(description).glow(glow) + .clickHandler(clickHandler).build(); } - /** * This method creates buttons for inventory requirements menu. + * * @param button Button which panel item must be created. * @return PanelItem that represents given button. */ - private PanelItem createInventoryRequirementButton(RequirementButton button) - { - final String reference = Constants.BUTTON + button.name().toLowerCase() + "."; - - final String name = this.user.getTranslation(reference + "name"); - final List description = new ArrayList<>(3); - description.add(this.user.getTranslation(reference + "description")); - - ItemStack icon; - boolean glow; - PanelItem.ClickHandler clickHandler; - - final InventoryRequirements requirements = this.challenge.getRequirements(); - - switch (button) - { - case REQUIRED_ITEMS -> { - if (requirements.getRequiredItems().isEmpty()) - { - description.add(this.user.getTranslation(reference + "none")); - } - else - { - description.add(this.user.getTranslation(reference + "title")); - - Utils.groupEqualItems(requirements.getRequiredItems(), requirements.getIgnoreMetaData()). - stream(). - sorted(Comparator.comparing(ItemStack::getType)). - forEach(itemStack -> - description.add(this.user.getTranslationOrNothing(reference + "list", - "[number]", String.valueOf(itemStack.getAmount()), - "[item]", Utils.prettifyObject(itemStack, this.user)))); - } - - icon = new ItemStack(Material.CHEST); - clickHandler = (panel, user, clickType, slot) -> { - ItemSelector.open(this.user, - requirements.getRequiredItems(), - (status, value) -> { - if (status) - { - requirements.setRequiredItems(value); - } - - this.build(); - }); - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - } - case REMOVE_ITEMS -> { - description.add(this.user.getTranslation(reference + - (requirements.isTakeItems() ? "enabled" : "disabled"))); - - icon = new ItemStack(Material.LEVER); - clickHandler = (panel, user, clickType, slot) -> { - requirements.setTakeItems(!requirements.isTakeItems()); - this.build(); - return true; - }; - glow = requirements.isTakeItems(); - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-toggle")); - } - case ADD_IGNORED_META -> { - if (requirements.getIgnoreMetaData().isEmpty()) - { - description.add(this.user.getTranslation(reference + "none")); - } - else - { - description.add(this.user.getTranslation(reference + "title")); - - requirements.getIgnoreMetaData().stream(). - sorted(Comparator.comparing(Material::name)). - forEach(itemStack -> - description.add(this.user.getTranslationOrNothing(reference + "list", - "[item]", Utils.prettifyObject(itemStack, this.user)))); - } - - icon = new ItemStack(Material.GREEN_SHULKER_BOX); - - clickHandler = (panel, user, clickType, slot) -> { - if (requirements.getRequiredItems().isEmpty()) - { - // Do nothing if no requirements are set. - return true; - } - - // Allow choosing only from inventory items. - Set collection = Arrays.stream(Material.values()).collect(Collectors.toSet()); - requirements.getRequiredItems().stream(). - map(ItemStack::getType). - forEach(collection::remove); - collection.addAll(requirements.getIgnoreMetaData()); - - if (Material.values().length == collection.size()) - { - // If there are no items anymore, then do not allow opening gui. - return true; - } - - MultiBlockSelector.open(this.user, - MultiBlockSelector.Mode.ANY, - collection, - (status, materials) -> - { - if (status) - { - materials.addAll(requirements.getIgnoreMetaData()); - requirements.setIgnoreMetaData(new HashSet<>(materials)); - } - - this.build(); - }); - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-add")); - } - case REMOVE_IGNORED_META -> { - icon = new ItemStack(Material.RED_SHULKER_BOX); - - clickHandler = (panel, user, clickType, slot) -> { - if (requirements.getIgnoreMetaData().isEmpty()) - { - // Do nothing if no requirements are set. - return true; - } - - // Allow choosing only from inventory items. - Set collection = Arrays.stream(Material.values()).collect(Collectors.toSet()); - collection.removeAll(requirements.getIgnoreMetaData()); - - MultiBlockSelector.open(this.user, - MultiBlockSelector.Mode.ANY, - collection, - (status, materials) -> - { - if (status) - { - requirements.getIgnoreMetaData().removeAll(materials); - } - - this.build(); - }); - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-remove")); - } - default -> { - icon = new ItemStack(Material.PAPER); - clickHandler = null; - glow = false; - } - } - - return new PanelItemBuilder(). - icon(icon). - name(name). - description(description). - glow(glow). - clickHandler(clickHandler). - build(); + private PanelItem createInventoryRequirementButton(RequirementButton button) { + final String reference = Constants.BUTTON + button.name().toLowerCase() + "."; + + final String name = this.user.getTranslation(reference + "name"); + final List description = new ArrayList<>(3); + description.add(this.user.getTranslation(reference + "description")); + + ItemStack icon; + boolean glow; + PanelItem.ClickHandler clickHandler; + + final InventoryRequirements requirements = this.challenge.getRequirements(); + + switch (button) { + case REQUIRED_ITEMS -> { + if (requirements.getRequiredItems().isEmpty()) { + description.add(this.user.getTranslation(reference + "none")); + } else { + description.add(this.user.getTranslation(reference + "title")); + + Utils.groupEqualItems(requirements.getRequiredItems(), requirements.getIgnoreMetaData()).stream() + .sorted(Comparator.comparing(ItemStack::getType)) + .forEach(itemStack -> description.add(this.user.getTranslationOrNothing(reference + "list", + "[number]", String.valueOf(itemStack.getAmount()), "[item]", + Utils.prettifyObject(itemStack, this.user)))); + } + + icon = new ItemStack(Material.CHEST); + clickHandler = (panel, user, clickType, slot) -> { + ItemSelector.open(this.user, requirements.getRequiredItems(), (status, value) -> { + if (status) { + requirements.setRequiredItems(value); + } + + this.build(); + }); + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + } + case REMOVE_ITEMS -> { + description + .add(this.user.getTranslation(reference + (requirements.isTakeItems() ? "enabled" : "disabled"))); + + icon = new ItemStack(Material.LEVER); + clickHandler = (panel, user, clickType, slot) -> { + requirements.setTakeItems(!requirements.isTakeItems()); + this.build(); + return true; + }; + glow = requirements.isTakeItems(); + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-toggle")); + } + case ADD_IGNORED_META -> { + if (requirements.getIgnoreMetaData().isEmpty()) { + description.add(this.user.getTranslation(reference + "none")); + } else { + description.add(this.user.getTranslation(reference + "title")); + + requirements.getIgnoreMetaData().stream().sorted(Comparator.comparing(Material::name)) + .forEach(itemStack -> description.add(this.user.getTranslationOrNothing(reference + "list", + "[item]", Utils.prettifyObject(itemStack, this.user)))); + } + + icon = new ItemStack(Material.GREEN_SHULKER_BOX); + + clickHandler = (panel, user, clickType, slot) -> { + if (requirements.getRequiredItems().isEmpty()) { + // Do nothing if no requirements are set. + return true; + } + + // Allow choosing only from inventory items. + Set collection = Arrays.stream(Material.values()).collect(Collectors.toSet()); + requirements.getRequiredItems().stream().map(ItemStack::getType).forEach(collection::remove); + collection.addAll(requirements.getIgnoreMetaData()); + + if (Material.values().length == collection.size()) { + // If there are no items anymore, then do not allow opening gui. + return true; + } + + MultiBlockSelector.open(this.user, MultiBlockSelector.Mode.ANY, collection, (status, materials) -> { + if (status) { + materials.addAll(requirements.getIgnoreMetaData()); + requirements.setIgnoreMetaData(new HashSet<>(materials)); + } + + this.build(); + }); + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-add")); + } + case REMOVE_IGNORED_META -> { + icon = new ItemStack(Material.RED_SHULKER_BOX); + + clickHandler = (panel, user, clickType, slot) -> { + if (requirements.getIgnoreMetaData().isEmpty()) { + // Do nothing if no requirements are set. + return true; + } + + // Allow choosing only from inventory items. + Set collection = Arrays.stream(Material.values()).collect(Collectors.toSet()); + collection.removeAll(requirements.getIgnoreMetaData()); + + MultiBlockSelector.open(this.user, MultiBlockSelector.Mode.ANY, collection, (status, materials) -> { + if (status) { + requirements.getIgnoreMetaData().removeAll(materials); + } + + this.build(); + }); + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-remove")); + } + default -> { + icon = new ItemStack(Material.PAPER); + clickHandler = null; + glow = false; + } + } + + return new PanelItemBuilder().icon(icon).name(name).description(description).glow(glow) + .clickHandler(clickHandler).build(); } - /** * This method creates buttons for other requirements menu. + * * @param button Button which panel item must be created. * @return PanelItem that represents given button. */ - private PanelItem createOtherRequirementButton(RequirementButton button) - { - final String reference = Constants.BUTTON + button.name().toLowerCase() + "."; - - final String name = this.user.getTranslation(reference + "name"); - final List description = new ArrayList<>(3); - description.add(this.user.getTranslation(reference + "description")); - - ItemStack icon; - boolean glow; - PanelItem.ClickHandler clickHandler; - - final OtherRequirements requirements = this.challenge.getRequirements(); - - switch (button) - { - case REQUIRED_EXPERIENCE -> { - description.add(this.user.getTranslation(reference + "value", - Constants.PARAMETER_NUMBER, String.valueOf(requirements.getRequiredExperience()))); - icon = new ItemStack(Material.EXPERIENCE_BOTTLE); - clickHandler = (panel, user, clickType, i) -> { - Consumer numberConsumer = number -> { - if (number != null) - { - requirements.setRequiredExperience(number.intValue()); - } - - // reopen panel - this.build(); - }; - ConversationUtils.createNumericInput(numberConsumer, - this.user, - this.user.getTranslation(Constants.CONVERSATIONS + "input-number"), - 0, - Integer.MAX_VALUE); - - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - } - case REMOVE_EXPERIENCE -> { - description.add(this.user.getTranslation(reference + - (requirements.isTakeExperience() ? "enabled" : "disabled"))); - - icon = new ItemStack(Material.LEVER); - clickHandler = (panel, user, clickType, slot) -> { - requirements.setTakeExperience(!requirements.isTakeExperience()); - this.build(); - return true; - }; - glow = requirements.isTakeExperience(); - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-toggle")); - } - case REQUIRED_LEVEL -> { - description.add(this.user.getTranslation(reference + "value", - Constants.PARAMETER_NUMBER, String.valueOf(requirements.getRequiredIslandLevel()))); - icon = new ItemStack(this.addon.isLevelProvided() ? Material.BEACON : Material.BARRIER); - clickHandler = (panel, user, clickType, i) -> { - Consumer numberConsumer = number -> { - if (number != null) - { - requirements.setRequiredIslandLevel(number.longValue()); - } - - // reopen panel - this.build(); - }; - ConversationUtils.createNumericInput(numberConsumer, - this.user, - this.user.getTranslation(Constants.CONVERSATIONS + "input-number"), - 0, - Integer.MAX_VALUE); - - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - } - case REQUIRED_MONEY -> { - description.add(this.user.getTranslation(reference + "value", - Constants.PARAMETER_NUMBER, String.valueOf(requirements.getRequiredMoney()))); - icon = new ItemStack(this.addon.isEconomyProvided() ? Material.GOLD_INGOT : Material.BARRIER); - clickHandler = (panel, user, clickType, i) -> { - Consumer numberConsumer = number -> { - if (number != null) - { - requirements.setRequiredMoney(number.doubleValue()); - } - - // reopen panel - this.build(); - }; - ConversationUtils.createNumericInput(numberConsumer, - this.user, - this.user.getTranslation(Constants.CONVERSATIONS + "input-number"), - 0, - Double.MAX_VALUE); - - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - } - case REMOVE_MONEY -> { - description.add(this.user.getTranslation(reference + - (requirements.isTakeMoney() ? "enabled" : "disabled"))); - - icon = new ItemStack(this.addon.isEconomyProvided() ? Material.LEVER : Material.BARRIER); - clickHandler = (panel, user, clickType, slot) -> { - requirements.setTakeMoney(!requirements.isTakeMoney()); - this.build(); - return true; - }; - glow = requirements.isTakeMoney(); - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-toggle")); - } - default -> { - icon = new ItemStack(Material.PAPER); - clickHandler = null; - glow = false; - } - } - - return new PanelItemBuilder(). - icon(icon). - name(name). - description(description). - glow(glow). - clickHandler(clickHandler). - build(); + private PanelItem createOtherRequirementButton(RequirementButton button) { + final String reference = Constants.BUTTON + button.name().toLowerCase() + "."; + + final String name = this.user.getTranslation(reference + "name"); + final List description = new ArrayList<>(3); + description.add(this.user.getTranslation(reference + "description")); + + ItemStack icon; + boolean glow; + PanelItem.ClickHandler clickHandler; + + final OtherRequirements requirements = this.challenge.getRequirements(); + + switch (button) { + case REQUIRED_EXPERIENCE -> { + description.add(this.user.getTranslation(reference + "value", Constants.PARAMETER_NUMBER, + String.valueOf(requirements.getRequiredExperience()))); + icon = new ItemStack(Material.EXPERIENCE_BOTTLE); + clickHandler = (panel, user, clickType, i) -> { + Consumer numberConsumer = number -> { + if (number != null) { + requirements.setRequiredExperience(number.intValue()); + } + + // reopen panel + this.build(); + }; + ConversationUtils.createNumericInput(numberConsumer, this.user, + this.user.getTranslation(Constants.CONVERSATIONS + "input-number"), 0, Integer.MAX_VALUE); + + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + } + case REMOVE_EXPERIENCE -> { + description.add( + this.user.getTranslation(reference + (requirements.isTakeExperience() ? "enabled" : "disabled"))); + + icon = new ItemStack(Material.LEVER); + clickHandler = (panel, user, clickType, slot) -> { + requirements.setTakeExperience(!requirements.isTakeExperience()); + this.build(); + return true; + }; + glow = requirements.isTakeExperience(); + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-toggle")); + } + case REQUIRED_LEVEL -> { + description.add(this.user.getTranslation(reference + "value", Constants.PARAMETER_NUMBER, + String.valueOf(requirements.getRequiredIslandLevel()))); + icon = new ItemStack(this.addon.isLevelProvided() ? Material.BEACON : Material.BARRIER); + clickHandler = (panel, user, clickType, i) -> { + Consumer numberConsumer = number -> { + if (number != null) { + requirements.setRequiredIslandLevel(number.longValue()); + } + + // reopen panel + this.build(); + }; + ConversationUtils.createNumericInput(numberConsumer, this.user, + this.user.getTranslation(Constants.CONVERSATIONS + "input-number"), 0, Integer.MAX_VALUE); + + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + } + case REQUIRED_MONEY -> { + description.add(this.user.getTranslation(reference + "value", Constants.PARAMETER_NUMBER, + String.valueOf(requirements.getRequiredMoney()))); + icon = new ItemStack(this.addon.isEconomyProvided() ? Material.GOLD_INGOT : Material.BARRIER); + clickHandler = (panel, user, clickType, i) -> { + Consumer numberConsumer = number -> { + if (number != null) { + requirements.setRequiredMoney(number.doubleValue()); + } + + // reopen panel + this.build(); + }; + ConversationUtils.createNumericInput(numberConsumer, this.user, + this.user.getTranslation(Constants.CONVERSATIONS + "input-number"), 0, Double.MAX_VALUE); + + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + } + case REMOVE_MONEY -> { + description + .add(this.user.getTranslation(reference + (requirements.isTakeMoney() ? "enabled" : "disabled"))); + + icon = new ItemStack(this.addon.isEconomyProvided() ? Material.LEVER : Material.BARRIER); + clickHandler = (panel, user, clickType, slot) -> { + requirements.setTakeMoney(!requirements.isTakeMoney()); + this.build(); + return true; + }; + glow = requirements.isTakeMoney(); + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-toggle")); + } + default -> { + icon = new ItemStack(Material.PAPER); + clickHandler = null; + glow = false; + } + } + + return new PanelItemBuilder().icon(icon).name(name).description(description).glow(glow) + .clickHandler(clickHandler).build(); } - /** * Creates a button for statistic requirements. + * * @param button Button that must be created. * @return PanelItem button. */ - private PanelItem createStatisticRequirementButton(RequirementButton button) - { - final String reference = Constants.BUTTON + button.name().toLowerCase() + "."; - - final String name = this.user.getTranslation(reference + "name"); - final List description = new ArrayList<>(3); - description.add(this.user.getTranslation(reference + "description")); - - ItemStack icon; - boolean glow; - PanelItem.ClickHandler clickHandler; - - final StatisticRequirements requirements = this.challenge.getRequirements(); - - switch (button) - { - case STATISTIC -> { - description.add(this.user.getTranslation(reference + "value", - "[statistic]", Utils.prettifyObject(requirements.getStatistic(), this.user))); - - icon = new ItemStack(requirements.getStatistic() == null ? Material.BARRIER : Material.PAPER); - clickHandler = (panel, user, clickType, slot) -> { - StatisticSelector.open(this.user, (status, statistic) -> { - if (status) - { - requirements.setStatistic(statistic); - requirements.setMaterial(null); - requirements.setEntity(null); - requirements.setAmount(0); - } - - this.build(); - }); - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - } - case STATISTIC_AMOUNT -> { - description.add(this.user.getTranslation(reference + "value", - Constants.PARAMETER_NUMBER, String.valueOf(requirements.getAmount()))); - icon = new ItemStack(Material.CHEST); - clickHandler = (panel, user, clickType, i) -> { - Consumer numberConsumer = number -> { - if (number != null) - { - requirements.setAmount(number.intValue()); - } - - // reopen panel - this.build(); - }; - ConversationUtils.createNumericInput(numberConsumer, - this.user, - this.user.getTranslation(Constants.CONVERSATIONS + "input-number"), - 0, - Integer.MAX_VALUE); - - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - } - case REMOVE_STATISTIC -> { - description.add(this.user.getTranslation(reference + - (requirements.isReduceStatistic() ? "enabled" : "disabled"))); - - icon = new ItemStack(Material.LEVER); - clickHandler = (panel, user, clickType, slot) -> { - requirements.setReduceStatistic(!requirements.isReduceStatistic()); - this.build(); - return true; - }; - glow = requirements.isReduceStatistic(); - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-toggle")); - } - case STATISTIC_BLOCKS -> { - description.add(this.user.getTranslation(reference + "value", - "[block]", Utils.prettifyObject(requirements.getMaterial(), this.user))); - - icon = requirements.getMaterial() == null ? - new ItemStack(Material.BARRIER) : - new ItemStack(requirements.getMaterial()); - clickHandler = (panel, user, clickType, slot) -> { - SingleBlockSelector.open(this.user, - SingleBlockSelector.Mode.BLOCKS, - (status, block) -> { - if (status) - { - requirements.setMaterial(block); - } - - this.build(); - }); - - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - } - case STATISTIC_ITEMS -> { - description.add(this.user.getTranslation(reference + "value", - "[item]", Utils.prettifyObject(requirements.getMaterial(), this.user))); - - icon = requirements.getMaterial() == null ? - new ItemStack(Material.BARRIER) : - new ItemStack(requirements.getMaterial()); - clickHandler = (panel, user, clickType, slot) -> { - SingleBlockSelector.open(this.user, - SingleBlockSelector.Mode.ITEMS, - (status, block) -> { - if (status) - { - requirements.setMaterial(block); - } - - this.build(); - }); - - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - } - case STATISTIC_ENTITIES -> { - description.add(this.user.getTranslation(reference + "value", - "[entity]", Utils.prettifyObject(requirements.getEntity(), this.user))); - - icon = requirements.getEntity() == null ? - new ItemStack(Material.BARRIER) : - new ItemStack(PanelUtils.getEntityEgg(requirements.getEntity())); - clickHandler = (panel, user, clickType, slot) -> { - SingleEntitySelector.open(this.user, - true, - (status, entity) -> { - if (status) - { - requirements.setEntity(entity); - } - - this.build(); - }); - - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - } - default -> { - icon = new ItemStack(Material.PAPER); - clickHandler = null; - glow = false; - } - } - - return new PanelItemBuilder(). - icon(icon). - name(name). - description(description). - glow(glow). - clickHandler(clickHandler). - build(); + private PanelItem createStatisticRequirementButton(RequirementButton button) { + final String reference = Constants.BUTTON + button.name().toLowerCase() + "."; + + final String name = this.user.getTranslation(reference + "name"); + final List description = new ArrayList<>(3); + description.add(this.user.getTranslation(reference + "description")); + + ItemStack icon; + boolean glow; + PanelItem.ClickHandler clickHandler; + + final StatisticRequirements requirements = this.challenge.getRequirements(); + + switch (button) { + case STATISTIC -> { + description.add(this.user.getTranslation(reference + "value", "[statistic]", + Utils.prettifyObject(requirements.getStatistic(), this.user))); + + icon = new ItemStack(requirements.getStatistic() == null ? Material.BARRIER : Material.PAPER); + clickHandler = (panel, user, clickType, slot) -> { + StatisticSelector.open(this.user, (status, statistic) -> { + if (status) { + requirements.setStatistic(statistic); + requirements.setMaterial(null); + requirements.setEntity(null); + requirements.setAmount(0); + } + + this.build(); + }); + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + } + case STATISTIC_AMOUNT -> { + description.add(this.user.getTranslation(reference + "value", Constants.PARAMETER_NUMBER, + String.valueOf(requirements.getAmount()))); + icon = new ItemStack(Material.CHEST); + clickHandler = (panel, user, clickType, i) -> { + Consumer numberConsumer = number -> { + if (number != null) { + requirements.setAmount(number.intValue()); + } + + // reopen panel + this.build(); + }; + ConversationUtils.createNumericInput(numberConsumer, this.user, + this.user.getTranslation(Constants.CONVERSATIONS + "input-number"), 0, Integer.MAX_VALUE); + + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + } + case REMOVE_STATISTIC -> { + description.add( + this.user.getTranslation(reference + (requirements.isReduceStatistic() ? "enabled" : "disabled"))); + + icon = new ItemStack(Material.LEVER); + clickHandler = (panel, user, clickType, slot) -> { + requirements.setReduceStatistic(!requirements.isReduceStatistic()); + this.build(); + return true; + }; + glow = requirements.isReduceStatistic(); + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-toggle")); + } + case STATISTIC_BLOCKS -> { + description.add(this.user.getTranslation(reference + "value", "[block]", + Utils.prettifyObject(requirements.getMaterial(), this.user))); + + icon = requirements.getMaterial() == null ? new ItemStack(Material.BARRIER) + : new ItemStack(requirements.getMaterial()); + clickHandler = (panel, user, clickType, slot) -> { + SingleBlockSelector.open(this.user, SingleBlockSelector.Mode.BLOCKS, (status, block) -> { + if (status) { + requirements.setMaterial(block); + } + + this.build(); + }); + + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + } + case STATISTIC_ITEMS -> { + description.add(this.user.getTranslation(reference + "value", "[item]", + Utils.prettifyObject(requirements.getMaterial(), this.user))); + + icon = requirements.getMaterial() == null ? new ItemStack(Material.BARRIER) + : new ItemStack(requirements.getMaterial()); + clickHandler = (panel, user, clickType, slot) -> { + SingleBlockSelector.open(this.user, SingleBlockSelector.Mode.ITEMS, (status, block) -> { + if (status) { + requirements.setMaterial(block); + } + + this.build(); + }); + + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + } + case STATISTIC_ENTITIES -> { + description.add(this.user.getTranslation(reference + "value", "[entity]", + Utils.prettifyObject(requirements.getEntity(), this.user))); + + icon = requirements.getEntity() == null ? new ItemStack(Material.BARRIER) + : new ItemStack(PanelUtils.getEntityEgg(requirements.getEntity())); + clickHandler = (panel, user, clickType, slot) -> { + SingleEntitySelector.open(this.user, true, (status, entity) -> { + if (status) { + requirements.setEntity(entity); + } + + this.build(); + }); + + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + } + default -> { + icon = new ItemStack(Material.PAPER); + clickHandler = null; + glow = false; + } + } + + return new PanelItemBuilder().icon(icon).name(name).description(description).glow(glow) + .clickHandler(clickHandler).build(); } - /** * This method creates buttons for rewards menu. + * * @param button Button which panel item must be created. * @return PanelItem that represents given button. */ - private PanelItem createRewardButton(RewardButton button) - { - final String reference = Constants.BUTTON + button.name().toLowerCase() + "."; - - final String name = this.user.getTranslation(reference + "name"); - final List description = new ArrayList<>(3); - description.add(this.user.getTranslation(reference + "description")); - - ItemStack icon; - boolean glow; - PanelItem.ClickHandler clickHandler; - - switch (button) - { - case REWARD_TEXT -> { - icon = new ItemStack(Material.WRITTEN_BOOK); - - description.add(this.user.getTranslation(reference + "value")); - description.add(Util.translateColorCodes(this.challenge.getRewardText())); - - clickHandler = (panel, user, clickType, i) -> - { - // Create consumer that process description change - Consumer> consumer = value -> - { - if (value != null) - { - this.challenge.setRewardText(String.join("\n", value)); - } - - this.build(); - }; - - if (!this.challenge.getRewardText().isEmpty() && clickType.isShiftClick()) - { - // Reset to the empty value - consumer.accept(Collections.emptyList()); - } - else - { - // start conversation - ConversationUtils.createStringListInput(consumer, - user, - user.getTranslation(Constants.CONVERSATIONS + "write-reward-text"), - user.getTranslation(Constants.CONVERSATIONS + "reward-text-changed")); - } - - - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - - if (!this.challenge.getRewardText().isEmpty()) - { - description.add(this.user.getTranslation(Constants.TIPS + "shift-click-to-reset")); - } - } - case REWARD_ITEMS -> { - - if (this.challenge.getRewardItems().isEmpty()) - { - description.add(this.user.getTranslation(reference + "none")); - } - else - { - description.add(this.user.getTranslation(reference + "title")); - - Utils.groupEqualItems(this.challenge.getRewardItems(), this.challenge.getIgnoreRewardMetaData()). - stream(). - sorted(Comparator.comparing(ItemStack::getType)). - forEach(itemStack -> - description.add(this.user.getTranslationOrNothing(reference + "list", - "[number]", String.valueOf(itemStack.getAmount()), - "[item]", Utils.prettifyObject(itemStack, this.user)))); - } - - icon = new ItemStack(Material.CHEST); - clickHandler = (panel, user, clickType, slot) -> { - ItemSelector.open(this.user, - this.challenge.getRewardItems(), - (status, value) -> { - if (status) - { - this.challenge.setRewardItems(value); - } - - this.build(); - }); - - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - } - case REWARD_EXPERIENCE -> { - description.add(this.user.getTranslation(reference + "value", - Constants.PARAMETER_NUMBER, String.valueOf(this.challenge.getRewardExperience()))); - icon = new ItemStack(Material.EXPERIENCE_BOTTLE); - clickHandler = (panel, user, clickType, i) -> { - Consumer numberConsumer = number -> { - if (number != null) - { - this.challenge.setRewardExperience(number.intValue()); - } - - // reopen panel - this.build(); - }; - ConversationUtils.createNumericInput(numberConsumer, - this.user, - this.user.getTranslation(Constants.CONVERSATIONS + "input-number"), - 0, - Integer.MAX_VALUE); - - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - } - case REWARD_MONEY -> { - description.add(this.user.getTranslation(reference + "value", - Constants.PARAMETER_NUMBER, String.valueOf(this.challenge.getRewardMoney()))); - icon = new ItemStack(this.addon.isEconomyProvided() ? Material.GOLD_INGOT : Material.BARRIER); - clickHandler = (panel, user, clickType, i) -> { - Consumer numberConsumer = number -> { - if (number != null) - { - this.challenge.setRewardMoney(number.doubleValue()); - } - - // reopen panel - this.build(); - }; - ConversationUtils.createNumericInput(numberConsumer, - this.user, - this.user.getTranslation(Constants.CONVERSATIONS + "input-number"), - 0, - Double.MAX_VALUE); - - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - } - case REWARD_COMMANDS -> { - icon = new ItemStack(Material.COMMAND_BLOCK); - - description.add(this.user.getTranslation(reference + "value")); - description.addAll(this.challenge.getRewardCommands()); - - clickHandler = (panel, user, clickType, i) -> - { - // Create consumer that process description change - Consumer> consumer = value -> - { - if (value != null) - { - this.challenge.setRewardCommands(value); - } - - this.build(); - }; - - if (!this.challenge.getRewardCommands().isEmpty() && clickType.isShiftClick()) - { - // Reset to the empty value - consumer.accept(Collections.emptyList()); - } - else - { - // start conversation - ConversationUtils.createStringListInput(consumer, - user, - user.getTranslation(Constants.CONVERSATIONS + "write-reward-commands"), - user.getTranslation(Constants.CONVERSATIONS + "reward-commands-changed")); - } - - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - - if (!this.challenge.getRewardCommands().isEmpty()) - { - description.add(this.user.getTranslation(Constants.TIPS + "shift-click-to-reset")); - } - } - case REPEATABLE -> { - description.add(this.user.getTranslation(reference + - (this.challenge.isRepeatable() ? "enabled" : "disabled"))); - - icon = new ItemStack(Material.LEVER); - clickHandler = (panel, user, clickType, slot) -> { - this.challenge.setRepeatable(!this.challenge.isRepeatable()); - this.build(); - return true; - }; - glow = this.challenge.isRepeatable(); - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-toggle")); - } - case REPEAT_COUNT -> { - description.add(this.user.getTranslation(reference + "value", - Constants.PARAMETER_NUMBER, String.valueOf(this.challenge.getMaxTimes()))); - icon = new ItemStack(Material.COBBLESTONE_WALL); - clickHandler = (panel, user, clickType, i) -> { - Consumer numberConsumer = number -> { - if (number != null) - { - this.challenge.setMaxTimes(number.intValue()); - } - - // reopen panel - this.build(); - }; - ConversationUtils.createNumericInput(numberConsumer, - this.user, - this.user.getTranslation(Constants.CONVERSATIONS + "input-number"), - 0, - Integer.MAX_VALUE); - - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - } - case COOL_DOWN -> { - description.add(this.user.getTranslation(reference + "value", - "[time]", - Utils.parseDuration(Duration.ofMillis(this.challenge.getTimeout()), this.user))); - icon = new ItemStack(Material.CLOCK); - clickHandler = (panel, user, clickType, i) -> { - Consumer numberConsumer = number -> { - if (number != null) - { - this.challenge.setTimeout(number.longValue() * 1000); - } - - // reopen panel - this.build(); - }; - ConversationUtils.createNumericInput(numberConsumer, - this.user, - this.user.getTranslation(Constants.CONVERSATIONS + "input-seconds"), - 0, - Integer.MAX_VALUE); - - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - } - case REPEAT_REWARD_TEXT -> { - icon = new ItemStack(Material.WRITTEN_BOOK); - - description.add(this.user.getTranslation(reference + "value")); - description.add(Util.translateColorCodes(this.challenge.getRepeatRewardText())); - - clickHandler = (panel, user, clickType, i) -> - { - // Create consumer that process description change - Consumer> consumer = value -> - { - if (value != null) - { - this.challenge.setRepeatRewardText(String.join("\n", value)); - } - - this.build(); - }; - - if (!this.challenge.getRepeatRewardText().isEmpty() && clickType.isShiftClick()) - { - // Reset to the empty value - consumer.accept(Collections.emptyList()); - } - else - { - // start conversation - ConversationUtils.createStringListInput(consumer, - user, - user.getTranslation(Constants.CONVERSATIONS + "write-repeat-reward-text"), - user.getTranslation(Constants.CONVERSATIONS + "repeat-reward-text-changed")); - } - - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - - if (!this.challenge.getRepeatRewardText().isEmpty()) - { - description.add(this.user.getTranslation(Constants.TIPS + "shift-click-to-reset")); - } - } - case REPEAT_REWARD_ITEMS -> { - - if (this.challenge.getRepeatItemReward().isEmpty()) - { - description.add(this.user.getTranslation(reference + "none")); - } - else - { - description.add(this.user.getTranslation(reference + "title")); - - Utils.groupEqualItems(this.challenge.getRepeatItemReward(), this.challenge.getIgnoreRewardMetaData()). - stream(). - sorted(Comparator.comparing(ItemStack::getType)). - forEach(itemStack -> - description.add(this.user.getTranslationOrNothing(reference + "list", - "[number]", String.valueOf(itemStack.getAmount()), - "[item]", Utils.prettifyObject(itemStack, this.user)))); - } - - icon = new ItemStack(Material.CHEST); - clickHandler = (panel, user, clickType, slot) -> { - ItemSelector.open(this.user, - this.challenge.getRewardItems(), - (status, value) -> { - if (status) - { - this.challenge.setRepeatItemReward(value); - } - - this.build(); - }); - - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - } - case REPEAT_REWARD_EXPERIENCE -> { - description.add(this.user.getTranslation(reference + "value", - Constants.PARAMETER_NUMBER, String.valueOf(this.challenge.getRepeatExperienceReward()))); - icon = new ItemStack(Material.EXPERIENCE_BOTTLE); - clickHandler = (panel, user, clickType, i) -> { - Consumer numberConsumer = number -> { - if (number != null) - { - this.challenge.setRepeatExperienceReward(number.intValue()); - } - - // reopen panel - this.build(); - }; - ConversationUtils.createNumericInput(numberConsumer, - this.user, - this.user.getTranslation(Constants.CONVERSATIONS + "input-number"), - 0, - Integer.MAX_VALUE); - - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - } - case REPEAT_REWARD_MONEY -> { - description.add(this.user.getTranslation(reference + "value", - Constants.PARAMETER_NUMBER, String.valueOf(this.challenge.getRepeatMoneyReward()))); - icon = new ItemStack(this.addon.isEconomyProvided() ? Material.GOLD_NUGGET : Material.BARRIER); - clickHandler = (panel, user, clickType, i) -> { - Consumer numberConsumer = number -> { - if (number != null) - { - this.challenge.setRepeatMoneyReward(number.doubleValue()); - } - - // reopen panel - this.build(); - }; - ConversationUtils.createNumericInput(numberConsumer, - this.user, - this.user.getTranslation(Constants.CONVERSATIONS + "input-number"), - 0, - Double.MAX_VALUE); - - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - } - case REPEAT_REWARD_COMMANDS -> { - icon = new ItemStack(Material.COMMAND_BLOCK); - - description.add(this.user.getTranslation(reference + "value")); - description.addAll(this.challenge.getRepeatRewardCommands()); - - clickHandler = (panel, user, clickType, i) -> - { - // Create consumer that process description change - Consumer> consumer = value -> - { - if (value != null) - { - this.challenge.setRepeatRewardCommands(value); - } - - this.build(); - }; - - if (!this.challenge.getRepeatRewardCommands().isEmpty() && clickType.isShiftClick()) - { - // Reset to the empty value - consumer.accept(Collections.emptyList()); - } - else - { - // start conversation - ConversationUtils.createStringListInput(consumer, - user, - user.getTranslation(Constants.CONVERSATIONS + "write-repeat-reward-commands"), - user.getTranslation(Constants.CONVERSATIONS + "repeat-reward-commands-changed")); - } - - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); - - if (!this.challenge.getRepeatRewardCommands().isEmpty()) - { - description.add(this.user.getTranslation(Constants.TIPS + "shift-click-to-reset")); - } - } - case ADD_IGNORED_META -> { - if (this.challenge.getIgnoreRewardMetaData().isEmpty()) - { - description.add(this.user.getTranslation(reference + "none")); - } - else - { - description.add(this.user.getTranslation(reference + "title")); - - this.challenge.getIgnoreRewardMetaData().stream(). - sorted(Comparator.comparing(Material::name)). - forEach(itemStack -> - description.add(this.user.getTranslationOrNothing(reference + "list", - "[item]", Utils.prettifyObject(itemStack, this.user)))); - } - - icon = new ItemStack(Material.GREEN_SHULKER_BOX); - - clickHandler = (panel, user, clickType, slot) -> { - if (this.challenge.getRewardItems().isEmpty() && - this.challenge.getRepeatItemReward().isEmpty()) - { - // Do nothing if no requirements are set. - return true; - } - - // Allow choosing only from inventory items. - Set collection = Arrays.stream(Material.values()).collect(Collectors.toSet()); - this.challenge.getRewardItems().stream(). - map(ItemStack::getType). - forEach(collection::remove); - this.challenge.getRepeatItemReward().stream(). - map(ItemStack::getType). - forEach(collection::remove); - collection.addAll(this.challenge.getIgnoreRewardMetaData()); - - if (Material.values().length == collection.size()) - { - // If there are no items anymore, then do not allow opening gui. - return true; - } - - MultiBlockSelector.open(this.user, - MultiBlockSelector.Mode.ANY, - collection, - (status, materials) -> - { - if (status) - { - materials.addAll(this.challenge.getIgnoreRewardMetaData()); - this.challenge.setIgnoreRewardMetaData(new HashSet<>(materials)); - } - - this.build(); - }); - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-add")); - } - case REMOVE_IGNORED_META -> { - icon = new ItemStack(Material.RED_SHULKER_BOX); - - clickHandler = (panel, user, clickType, slot) -> { - if (this.challenge.getIgnoreRewardMetaData().isEmpty()) - { - // Do nothing if no requirements are set. - return true; - } - - // Allow choosing only from inventory items. - Set collection = Arrays.stream(Material.values()).collect(Collectors.toSet()); - collection.removeAll(this.challenge.getIgnoreRewardMetaData()); - - MultiBlockSelector.open(this.user, - MultiBlockSelector.Mode.ANY, - collection, - (status, materials) -> - { - if (status) - { - this.challenge.getIgnoreRewardMetaData().removeAll(materials); - } - - this.build(); - }); - return true; - }; - glow = false; - - description.add(""); - description.add(this.user.getTranslation(Constants.TIPS + "click-to-remove")); - } - default -> { - icon = new ItemStack(Material.PAPER); - clickHandler = null; - glow = false; - } - } - - return new PanelItemBuilder(). - icon(icon). - name(name). - description(description). - glow(glow). - clickHandler(clickHandler). - build(); + private PanelItem createRewardButton(RewardButton button) { + final String reference = Constants.BUTTON + button.name().toLowerCase() + "."; + + final String name = this.user.getTranslation(reference + "name"); + final List description = new ArrayList<>(3); + description.add(this.user.getTranslation(reference + "description")); + + ItemStack icon; + boolean glow; + PanelItem.ClickHandler clickHandler; + + switch (button) { + case REWARD_TEXT -> { + icon = new ItemStack(Material.WRITTEN_BOOK); + + description.add(this.user.getTranslation(reference + "value")); + description.add(Util.translateColorCodes(this.challenge.getRewardText())); + + clickHandler = (panel, user, clickType, i) -> { + // Create consumer that process description change + Consumer> consumer = value -> { + if (value != null) { + this.challenge.setRewardText(String.join("\n", value)); + } + + this.build(); + }; + + if (!this.challenge.getRewardText().isEmpty() && clickType.isShiftClick()) { + // Reset to the empty value + consumer.accept(Collections.emptyList()); + } else { + // start conversation + ConversationUtils.createStringListInput(consumer, user, + user.getTranslation(Constants.CONVERSATIONS + "write-reward-text"), + user.getTranslation(Constants.CONVERSATIONS + "reward-text-changed")); + } + + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + + if (!this.challenge.getRewardText().isEmpty()) { + description.add(this.user.getTranslation(Constants.TIPS + "shift-click-to-reset")); + } + } + case REWARD_ITEMS -> { + + if (this.challenge.getRewardItems().isEmpty()) { + description.add(this.user.getTranslation(reference + "none")); + } else { + description.add(this.user.getTranslation(reference + "title")); + + Utils.groupEqualItems(this.challenge.getRewardItems(), this.challenge.getIgnoreRewardMetaData()) + .stream().sorted(Comparator.comparing(ItemStack::getType)) + .forEach(itemStack -> description.add(this.user.getTranslationOrNothing(reference + "list", + "[number]", String.valueOf(itemStack.getAmount()), "[item]", + Utils.prettifyObject(itemStack, this.user)))); + } + + icon = new ItemStack(Material.CHEST); + clickHandler = (panel, user, clickType, slot) -> { + ItemSelector.open(this.user, this.challenge.getRewardItems(), (status, value) -> { + if (status) { + this.challenge.setRewardItems(value); + } + + this.build(); + }); + + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + } + case REWARD_EXPERIENCE -> { + description.add(this.user.getTranslation(reference + "value", Constants.PARAMETER_NUMBER, + String.valueOf(this.challenge.getRewardExperience()))); + icon = new ItemStack(Material.EXPERIENCE_BOTTLE); + clickHandler = (panel, user, clickType, i) -> { + Consumer numberConsumer = number -> { + if (number != null) { + this.challenge.setRewardExperience(number.intValue()); + } + + // reopen panel + this.build(); + }; + ConversationUtils.createNumericInput(numberConsumer, this.user, + this.user.getTranslation(Constants.CONVERSATIONS + "input-number"), 0, Integer.MAX_VALUE); + + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + } + case REWARD_MONEY -> { + description.add(this.user.getTranslation(reference + "value", Constants.PARAMETER_NUMBER, + addon.getPlugin().getVault().map(v -> v.format(challenge.getRewardMoney())) + .orElse(String.valueOf(challenge.getRewardMoney())))); + icon = new ItemStack(this.addon.isEconomyProvided() ? Material.GOLD_INGOT : Material.BARRIER); + clickHandler = (panel, user, clickType, i) -> { + Consumer numberConsumer = number -> { + if (number != null) { + this.challenge.setRewardMoney(number.doubleValue()); + } + + // reopen panel + this.build(); + }; + ConversationUtils.createNumericInput(numberConsumer, this.user, + this.user.getTranslation(Constants.CONVERSATIONS + "input-number"), 0, Double.MAX_VALUE); + + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + } + case REWARD_COMMANDS -> { + icon = new ItemStack(Material.COMMAND_BLOCK); + + description.add(this.user.getTranslation(reference + "value")); + description.addAll(this.challenge.getRewardCommands()); + + clickHandler = (panel, user, clickType, i) -> { + // Create consumer that process description change + Consumer> consumer = value -> { + if (value != null) { + this.challenge.setRewardCommands(value); + } + + this.build(); + }; + + if (!this.challenge.getRewardCommands().isEmpty() && clickType.isShiftClick()) { + // Reset to the empty value + consumer.accept(Collections.emptyList()); + } else { + // start conversation + ConversationUtils.createStringListInput(consumer, user, + user.getTranslation(Constants.CONVERSATIONS + "write-reward-commands"), + user.getTranslation(Constants.CONVERSATIONS + "reward-commands-changed")); + } + + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + + if (!this.challenge.getRewardCommands().isEmpty()) { + description.add(this.user.getTranslation(Constants.TIPS + "shift-click-to-reset")); + } + } + case REPEATABLE -> { + description.add( + this.user.getTranslation(reference + (this.challenge.isRepeatable() ? "enabled" : "disabled"))); + + icon = new ItemStack(Material.LEVER); + clickHandler = (panel, user, clickType, slot) -> { + this.challenge.setRepeatable(!this.challenge.isRepeatable()); + this.build(); + return true; + }; + glow = this.challenge.isRepeatable(); + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-toggle")); + } + case REPEAT_COUNT -> { + description.add(this.user.getTranslation(reference + "value", Constants.PARAMETER_NUMBER, + String.valueOf(this.challenge.getMaxTimes()))); + icon = new ItemStack(Material.COBBLESTONE_WALL); + clickHandler = (panel, user, clickType, i) -> { + Consumer numberConsumer = number -> { + if (number != null) { + this.challenge.setMaxTimes(number.intValue()); + } + + // reopen panel + this.build(); + }; + ConversationUtils.createNumericInput(numberConsumer, this.user, + this.user.getTranslation(Constants.CONVERSATIONS + "input-number"), 0, Integer.MAX_VALUE); + + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + } + case COOL_DOWN -> { + description.add(this.user.getTranslation(reference + "value", "[time]", + Utils.parseDuration(Duration.ofMillis(this.challenge.getTimeout()), this.user))); + icon = new ItemStack(Material.CLOCK); + clickHandler = (panel, user, clickType, i) -> { + Consumer numberConsumer = number -> { + if (number != null) { + this.challenge.setTimeout(number.longValue() * 1000); + } + + // reopen panel + this.build(); + }; + ConversationUtils.createNumericInput(numberConsumer, this.user, + this.user.getTranslation(Constants.CONVERSATIONS + "input-seconds"), 0, Integer.MAX_VALUE); + + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + } + case REPEAT_REWARD_TEXT -> { + icon = new ItemStack(Material.WRITTEN_BOOK); + + description.add(this.user.getTranslation(reference + "value")); + description.add(Util.translateColorCodes(this.challenge.getRepeatRewardText())); + + clickHandler = (panel, user, clickType, i) -> { + // Create consumer that process description change + Consumer> consumer = value -> { + if (value != null) { + this.challenge.setRepeatRewardText(String.join("\n", value)); + } + + this.build(); + }; + + if (!this.challenge.getRepeatRewardText().isEmpty() && clickType.isShiftClick()) { + // Reset to the empty value + consumer.accept(Collections.emptyList()); + } else { + // start conversation + ConversationUtils.createStringListInput(consumer, user, + user.getTranslation(Constants.CONVERSATIONS + "write-repeat-reward-text"), + user.getTranslation(Constants.CONVERSATIONS + "repeat-reward-text-changed")); + } + + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + + if (!this.challenge.getRepeatRewardText().isEmpty()) { + description.add(this.user.getTranslation(Constants.TIPS + "shift-click-to-reset")); + } + } + case REPEAT_REWARD_ITEMS -> { + + if (this.challenge.getRepeatItemReward().isEmpty()) { + description.add(this.user.getTranslation(reference + "none")); + } else { + description.add(this.user.getTranslation(reference + "title")); + + Utils.groupEqualItems(this.challenge.getRepeatItemReward(), this.challenge.getIgnoreRewardMetaData()) + .stream().sorted(Comparator.comparing(ItemStack::getType)) + .forEach(itemStack -> description.add(this.user.getTranslationOrNothing(reference + "list", + "[number]", String.valueOf(itemStack.getAmount()), "[item]", + Utils.prettifyObject(itemStack, this.user)))); + } + + icon = new ItemStack(Material.CHEST); + clickHandler = (panel, user, clickType, slot) -> { + ItemSelector.open(this.user, this.challenge.getRewardItems(), (status, value) -> { + if (status) { + this.challenge.setRepeatItemReward(value); + } + + this.build(); + }); + + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + } + case REPEAT_REWARD_EXPERIENCE -> { + description.add(this.user.getTranslation(reference + "value", Constants.PARAMETER_NUMBER, + String.valueOf(this.challenge.getRepeatExperienceReward()))); + icon = new ItemStack(Material.EXPERIENCE_BOTTLE); + clickHandler = (panel, user, clickType, i) -> { + Consumer numberConsumer = number -> { + if (number != null) { + this.challenge.setRepeatExperienceReward(number.intValue()); + } + + // reopen panel + this.build(); + }; + ConversationUtils.createNumericInput(numberConsumer, this.user, + this.user.getTranslation(Constants.CONVERSATIONS + "input-number"), 0, Integer.MAX_VALUE); + + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + } + case REPEAT_REWARD_MONEY -> { + description.add(this.user.getTranslation(reference + "value", Constants.PARAMETER_NUMBER, + String.valueOf(this.challenge.getRepeatMoneyReward()))); + icon = new ItemStack(this.addon.isEconomyProvided() ? Material.GOLD_NUGGET : Material.BARRIER); + clickHandler = (panel, user, clickType, i) -> { + Consumer numberConsumer = number -> { + if (number != null) { + this.challenge.setRepeatMoneyReward(number.doubleValue()); + } + + // reopen panel + this.build(); + }; + ConversationUtils.createNumericInput(numberConsumer, this.user, + this.user.getTranslation(Constants.CONVERSATIONS + "input-number"), 0, Double.MAX_VALUE); + + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + } + case REPEAT_REWARD_COMMANDS -> { + icon = new ItemStack(Material.COMMAND_BLOCK); + + description.add(this.user.getTranslation(reference + "value")); + description.addAll(this.challenge.getRepeatRewardCommands()); + + clickHandler = (panel, user, clickType, i) -> { + // Create consumer that process description change + Consumer> consumer = value -> { + if (value != null) { + this.challenge.setRepeatRewardCommands(value); + } + + this.build(); + }; + + if (!this.challenge.getRepeatRewardCommands().isEmpty() && clickType.isShiftClick()) { + // Reset to the empty value + consumer.accept(Collections.emptyList()); + } else { + // start conversation + ConversationUtils.createStringListInput(consumer, user, + user.getTranslation(Constants.CONVERSATIONS + "write-repeat-reward-commands"), + user.getTranslation(Constants.CONVERSATIONS + "repeat-reward-commands-changed")); + } + + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-change")); + + if (!this.challenge.getRepeatRewardCommands().isEmpty()) { + description.add(this.user.getTranslation(Constants.TIPS + "shift-click-to-reset")); + } + } + case ADD_IGNORED_META -> { + if (this.challenge.getIgnoreRewardMetaData().isEmpty()) { + description.add(this.user.getTranslation(reference + "none")); + } else { + description.add(this.user.getTranslation(reference + "title")); + + this.challenge.getIgnoreRewardMetaData().stream().sorted(Comparator.comparing(Material::name)) + .forEach(itemStack -> description.add(this.user.getTranslationOrNothing(reference + "list", + "[item]", Utils.prettifyObject(itemStack, this.user)))); + } + + icon = new ItemStack(Material.GREEN_SHULKER_BOX); + + clickHandler = (panel, user, clickType, slot) -> { + if (this.challenge.getRewardItems().isEmpty() && this.challenge.getRepeatItemReward().isEmpty()) { + // Do nothing if no requirements are set. + return true; + } + + // Allow choosing only from inventory items. + Set collection = Arrays.stream(Material.values()).collect(Collectors.toSet()); + this.challenge.getRewardItems().stream().map(ItemStack::getType).forEach(collection::remove); + this.challenge.getRepeatItemReward().stream().map(ItemStack::getType).forEach(collection::remove); + collection.addAll(this.challenge.getIgnoreRewardMetaData()); + + if (Material.values().length == collection.size()) { + // If there are no items anymore, then do not allow opening gui. + return true; + } + + MultiBlockSelector.open(this.user, MultiBlockSelector.Mode.ANY, collection, (status, materials) -> { + if (status) { + materials.addAll(this.challenge.getIgnoreRewardMetaData()); + this.challenge.setIgnoreRewardMetaData(new HashSet<>(materials)); + } + + this.build(); + }); + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-add")); + } + case REMOVE_IGNORED_META -> { + icon = new ItemStack(Material.RED_SHULKER_BOX); + + clickHandler = (panel, user, clickType, slot) -> { + if (this.challenge.getIgnoreRewardMetaData().isEmpty()) { + // Do nothing if no requirements are set. + return true; + } + + // Allow choosing only from inventory items. + Set collection = Arrays.stream(Material.values()).collect(Collectors.toSet()); + collection.removeAll(this.challenge.getIgnoreRewardMetaData()); + + MultiBlockSelector.open(this.user, MultiBlockSelector.Mode.ANY, collection, (status, materials) -> { + if (status) { + this.challenge.getIgnoreRewardMetaData().removeAll(materials); + } + + this.build(); + }); + return true; + }; + glow = false; + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-remove")); + } + default -> { + icon = new ItemStack(Material.PAPER); + clickHandler = null; + glow = false; + } + } + + return new PanelItemBuilder().icon(icon).name(name).description(description).glow(glow) + .clickHandler(clickHandler).build(); } // --------------------------------------------------------------------- // Section: Classes // --------------------------------------------------------------------- - /** * This class allows changing icon for Generator Tier */ - private class IconChanger implements PanelListener - { - /** - * Process inventory click. If generator icon is selected and user clicks on item in his inventory, then change - * icon to the item from inventory. - * - * @param user the user - * @param event the event - */ - @Override - public void onInventoryClick(User user, InventoryClickEvent event) - { - // Handle icon changing - if (EditChallengePanel.this.selectedButton != null && - event.getCurrentItem() != null && - !event.getCurrentItem().getType().equals(Material.AIR) && - event.getRawSlot() > 44) - { - // set material and amount only. Other data should be removed. - - if (EditChallengePanel.this.selectedButton == Button.ICON) - { - EditChallengePanel.this.challenge.setIcon(event.getCurrentItem().clone()); - // Deselect icon - EditChallengePanel.this.selectedButton = null; - // Rebuild icon - EditChallengePanel.this.build(); - } - } - } - - - /** - * On inventory close. - * - * @param event the event - */ - @Override - public void onInventoryClose(InventoryCloseEvent event) - { - // Do nothing - } - - - /** - * Setup current listener. - */ - @Override - public void setup() - { - // Do nothing - } + private class IconChanger implements PanelListener { + /** + * Process inventory click. If generator icon is selected and user clicks on + * item in his inventory, then change icon to the item from inventory. + * + * @param user the user + * @param event the event + */ + @Override + public void onInventoryClick(User user, InventoryClickEvent event) { + // Handle icon changing + if (EditChallengePanel.this.selectedButton != null && event.getCurrentItem() != null + && !event.getCurrentItem().getType().equals(Material.AIR) && event.getRawSlot() > 44) { + // set material and amount only. Other data should be removed. + + if (EditChallengePanel.this.selectedButton == Button.ICON) { + EditChallengePanel.this.challenge.setIcon(event.getCurrentItem().clone()); + // Deselect icon + EditChallengePanel.this.selectedButton = null; + // Rebuild icon + EditChallengePanel.this.build(); + } + } + } + + /** + * On inventory close. + * + * @param event the event + */ + @Override + public void onInventoryClose(InventoryCloseEvent event) { + // Do nothing + } + + /** + * Setup current listener. + */ + @Override + public void setup() { + // Do nothing + } } - // --------------------------------------------------------------------- // Section: Enums // --------------------------------------------------------------------- - /** * Represents different types of menus */ - private enum MenuType - { - PROPERTIES, - REQUIREMENTS, - REWARDS + private enum MenuType { + PROPERTIES, REQUIREMENTS, REWARDS } - /** * Represents different buttons that could be in menus. */ - private enum Button - { - NAME, - DEPLOYED, - ICON, - DESCRIPTION, - ORDER, - ENVIRONMENT, - REMOVE_ON_COMPLETE, + private enum Button { + NAME, DEPLOYED, ICON, DESCRIPTION, ORDER, ENVIRONMENT, REMOVE_ON_COMPLETE, } - /** * Represents different rewards buttons that are used in menus. */ - private enum RewardButton - { - REWARD_TEXT, - REWARD_ITEMS, - REWARD_EXPERIENCE, - REWARD_MONEY, - REWARD_COMMANDS, - - REPEATABLE, - REPEAT_COUNT, - COOL_DOWN, - - REPEAT_REWARD_TEXT, - REPEAT_REWARD_ITEMS, - REPEAT_REWARD_EXPERIENCE, - REPEAT_REWARD_MONEY, - REPEAT_REWARD_COMMANDS, - - ADD_IGNORED_META, - REMOVE_IGNORED_META, - } + private enum RewardButton { + REWARD_TEXT, REWARD_ITEMS, REWARD_EXPERIENCE, REWARD_MONEY, REWARD_COMMANDS, + REPEATABLE, REPEAT_COUNT, COOL_DOWN, + + REPEAT_REWARD_TEXT, REPEAT_REWARD_ITEMS, REPEAT_REWARD_EXPERIENCE, REPEAT_REWARD_MONEY, REPEAT_REWARD_COMMANDS, + + ADD_IGNORED_META, REMOVE_IGNORED_META, + } /** * Represents different requirement buttons that are used in menus. */ - private enum RequirementButton - { - REQUIRED_ENTITIES, - REMOVE_ENTITIES, - REQUIRED_BLOCKS, - REMOVE_BLOCKS, - SEARCH_RADIUS, - REQUIRED_PERMISSIONS, - REQUIRED_ITEMS, - REMOVE_ITEMS, - ADD_IGNORED_META, - REMOVE_IGNORED_META, - REQUIRED_EXPERIENCE, - REMOVE_EXPERIENCE, - REQUIRED_LEVEL, - REQUIRED_MONEY, - REMOVE_MONEY, - STATISTIC, - STATISTIC_BLOCKS, - STATISTIC_ITEMS, - STATISTIC_ENTITIES, - STATISTIC_AMOUNT, - REMOVE_STATISTIC, + private enum RequirementButton { + REQUIRED_ENTITIES, REMOVE_ENTITIES, REQUIRED_BLOCKS, REMOVE_BLOCKS, SEARCH_RADIUS, REQUIRED_PERMISSIONS, + REQUIRED_ITEMS, REMOVE_ITEMS, ADD_IGNORED_META, REMOVE_IGNORED_META, REQUIRED_EXPERIENCE, REMOVE_EXPERIENCE, + REQUIRED_LEVEL, REQUIRED_MONEY, REMOVE_MONEY, STATISTIC, STATISTIC_BLOCKS, STATISTIC_ITEMS, STATISTIC_ENTITIES, + STATISTIC_AMOUNT, REMOVE_STATISTIC, } - // --------------------------------------------------------------------- // Section: Variables // --------------------------------------------------------------------- - /** * Variable holds challenge thats needs editing. */ private final Challenge challenge; - private Button selectedButton; /** diff --git a/src/main/java/world/bentobox/challenges/tasks/TryToComplete.java b/src/main/java/world/bentobox/challenges/tasks/TryToComplete.java index aaf3ff36..971923a5 100644 --- a/src/main/java/world/bentobox/challenges/tasks/TryToComplete.java +++ b/src/main/java/world/bentobox/challenges/tasks/TryToComplete.java @@ -952,6 +952,8 @@ private ChallengeResult checkInventory(int maxTimes) else { requiredItems = Collections.emptyList(); + // Set maxTime to 2, to not crash client when completing 2147483647 times. + maxTimes = 2; } // Return the result diff --git a/src/main/java/world/bentobox/challenges/utils/Utils.java b/src/main/java/world/bentobox/challenges/utils/Utils.java index 5b7e2df9..09acb619 100644 --- a/src/main/java/world/bentobox/challenges/utils/Utils.java +++ b/src/main/java/world/bentobox/challenges/utils/Utils.java @@ -7,11 +7,19 @@ import java.util.Locale; import java.util.Set; -import org.bukkit.*; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.Statistic; +import org.bukkit.World; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.EntityType; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.*; +import org.bukkit.inventory.meta.BookMeta; +import org.bukkit.inventory.meta.EnchantmentStorageMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.inventory.meta.SkullMeta; import org.bukkit.potion.PotionData; import org.bukkit.potion.PotionType; import org.eclipse.jdt.annotation.Nullable; @@ -823,7 +831,7 @@ public static String prettifyObject(ItemStack item, @Nullable EnchantmentStorage StringBuilder builder = new StringBuilder(); - enchantmentMeta.getEnchants().forEach((enchantment, level) -> { + enchantmentMeta.getStoredEnchants().forEach((enchantment, level) -> { builder.append("\n"); builder.append(user.getTranslationOrNothing(Constants.ITEM_STACKS + "meta.enchant-meta", "[type]", prettifyObject(enchantment, user), @@ -868,8 +876,8 @@ public static String prettifyObject(ItemStack item, @Nullable BookMeta bookMeta, final String metaReference = Constants.ITEM_STACKS + "meta."; String meta = user.getTranslationOrNothing(metaReference + "book-meta", - "[title]", bookMeta.getTitle(), - "[author]", bookMeta.getAuthor()); + "[title]", bookMeta.hasTitle() ? bookMeta.getTitle() : "", + "[author]", bookMeta.hasAuthor() ? bookMeta.getAuthor() : ""); return user.getTranslationOrNothing(Constants.ITEM_STACKS + "generic", "[type]", prettifyObject(itemType, user), diff --git a/src/main/resources/locales/en-US.yml b/src/main/resources/locales/en-US.yml index 8d344151..fe517be4 100755 --- a/src/main/resources/locales/en-US.yml +++ b/src/main/resources/locales/en-US.yml @@ -907,7 +907,7 @@ challenges: # Message that will be added after environment-title-multiple. environment-list: " &7 - &e [environment]" # Message that will replace [permissions] placeholder if there is just a single permission. - permission-single: "&c Requires [permissions] permission" + permission-single: "&c Requires [permission] permission" # Message that will replace [permissions] placeholder if there are multiple permissions. permissions-title: "&c Requires permissions: " # Message that will be added after permissions-title-multiple. diff --git a/src/main/resources/locales/hu.yml b/src/main/resources/locales/hu.yml new file mode 100644 index 00000000..1af7a2d9 --- /dev/null +++ b/src/main/resources/locales/hu.yml @@ -0,0 +1,1102 @@ +--- +meta: + authors: + - BONNe +challenges: + commands: + admin: + main: + description: Elsődleges admin parancs. Megnyitja a GUI-t + reload: + description: A kihívások újratöltése az adatbázisból + show: + description: Kinyomtat minden, a világban létező csevegést. + complete: + description: Teljesíts egy kihívást egy játékos számára. + parameters: " " + reset: + description: Állítsa vissza a kihívást egy játékos számára. Ha a "challenge_id" + értéke "all", akkor az összes kihívást visszaállítja. + parameters: " " + migrate: + description: A jelenlegi játékvilág migrálása 0.8.0 tárolási formátumba próbálja + ki az adatokat. + user: + main: + description: Megnyitja a küldetéseket + complete: + description: Teljes kihívás. + parameters: " [count]" + gui: + titles: + player-gui: "&0 &l Kihívások menü" + gamemode-gui: "&0 &l Válassza a GameMode lehetőséget" + multiple-gui: "&0 &l Hányszor?" + admin-gui: "&0 &l Challenges Admin menü" + edit-challenge: "&0 &l Szerkesztés [challenge]" + edit-level: "&0 &l Szerkesztés [level]" + settings: "&0 &l Beállítások" + choose-challenge: "&0 &l Válassza ki a kihívást" + choose-level: "&0 &l Válassza ki a szintet" + choose-player: "&0 &l Válassza ki a lejátszót" + library: "&0 &l Könyvtár" + manage-blocks: "&0 &l Blokkok kezelése" + manage-entities: "&0 &l Entitások kezelése" + type-selector: "&0 &l Kihívás típusválasztó" + item-selector: "&0 &l Elemválasztó" + block-selector: "&0 &l Blokkválasztó" + entity-selector: "&0 &l entitásválasztó" + challenge-selector: "&0 &l Kihívásválasztó" + statistic-selector: "&0 &l statisztikaválasztó" + environment-selector: "&0 &l Környezetválasztó" + buttons: + free-challenges: + name: "&f &l Ingyenes kihívások" + description: |- + &7 Megjeleníti a listát + &7 ingyenes kihívás + return: + name: "&f &l Vissza" + description: |- + &7 Visszatérés az előző menübe + &7 vagy lépjen ki a GUI -ból + previous: + name: "&f &l Előző oldal" + description: "&7 Váltás &e [number] és 7 oldalra" + next: + name: "&f &l Következő oldal" + description: "&7 Váltás &e [number] és 7 oldalra" + reduce: + name: "&f &l Csökkent" + description: "&7 Csökkentés &e -vel [number]" + increase: + name: "&f &l Növelés" + description: "&7 Növelés &e -vel [number]" + accept: + name: "&f &l Teljes" + description: |- + &7 Teljesítsd a kihívást és e [number] + &7 alkalom + quit: + name: "&f &l Kilépés" + description: "&7 Kilépés a GUI -ból." + complete_user_challenges: + name: "&f &l Teljes felhasználói kihívás (ok)" + description: |- + &7 Lehetővé teszi a felhasználó és a kiválasztását + &7 teljes kihívás + &7 őt + reset_user_challenges: + name: "&f &l Felhasználói kihívások visszaállítása" + description: |- + &7 Lehetővé teszi a felhasználó és a kiválasztását + &7 visszaállítja a kihívásait + add_challenge: + name: "&f &l Kihívás létrehozása" + description: |- + &7 Elindít egy folyamatot + &7 új kihívást jelent. + add_level: + name: "&f &l Szint létrehozása" + description: |- + &7 Elindít egy folyamatot + &7 új szint létrehozása. + edit_challenge: + name: "&f &l Kihívás szerkesztése" + description: |- + &7 Lehetővé teszi a választást és a szerkesztést + &7 kihívás. + edit_level: + name: "&f &l Szint szerkesztése" + description: |- + &7 Lehetővé teszi a választást és a szerkesztést + &7 szinten. + delete_challenge: + name: "&f &l Kihívás törlése" + description: |- + &7 Lehetővé teszi a választást és a törlést + &7 kihívás. + delete_level: + name: "&f &l Szint törlése" + description: |- + &7 Lehetővé teszi a választást és a törlést + &7 szinten. + edit_settings: + name: "&f &l Beállítások" + description: |- + &7 Lehetővé teszi a megtekintést és a szerkesztést + &7 és a kiegészítő beállítások. + complete_wipe: + name: "&f &l Teljes törlés" + description: |- + &7 Teljesen elhárítja a kihívásokat + &7 addon adatbázis, beleértve + &7 felhasználói adat. + challenge_wipe: + name: "&f &l Challenge Wipe" + description: |- + &7 Teljesen elhárítja a kihívásokat + &7 és szintek az adatbázisból. + user_wipe: + name: "&f &l Felhasználói törlés" + description: |- + &7 Teljesen törli a felhasználót + &7 adat az adatbázisból. + library: + name: "&f &l Könyvtár" + description: |- + &7 Nyit egy nyilvánosságot + &7 kihívások könyvtár. + import_database: + name: "&f &l Adatbázis importálása" + description: |- + &7 Lehetővé teszi az exportált importálást + &7 kihívások adatbázis. + import_template: + name: "&f &l Sablon importálása" + description: |- + &7 Lehetővé teszi sablon importálását + &7 fájl kihívásokkal. + export_challenges: + name: "&f &l Export kihívások" + description: |- + &7 Lehetővé teszi az adatbázis exportálását + &7 helyi fájlba. + properties: + name: "&f &l Tulajdonságok" + description: "&7 Az összes fő tulajdonság megtekintése." + requirements: + name: "&f &l Követelmények" + description: "&7 A követelmények tulajdonságainak megtekintése." + rewards: + name: "&f &l Jutalmak" + description: "&7 A jutalmak tulajdonságainak megtekintése." + deployed: + name: "&f &l Telepítés" + description: |- + &7 Váltás ha kihívás + &7 telepítve van, és a felhasználók is + &7 fejezze be. + enabled: "&2 Engedélyezve" + disabled: "&c Letiltva" + name: + name: "&f &l Név" + description: |- + &7 Lehetővé teszi a változtatást + &7 a megjelenített név. + value: "&7 Jelenleg: &r [name]" + remove_on_complete: + name: "&f &l Elrejtés a befejezés után" + description: |- + &7 Váltás, ha a kihívás szükséges + &7 rejtve a játékos után + &7 befejeződött. + enabled: "&2 Engedélyezve" + disabled: "&c Letiltva" + description: + name: "&f &l Leírás" + description: |- + &7 A konkrét leírás + &7 a kihíváshoz. A szín + &7 kódot kell alkalmazni rá. + value: "&7 Aktuális leírás:" + environment: + name: "&f &l Dimenzió" + description: |- + &7 Lehetővé teszi annak korlátozását + &7 dimenzió a kihívás + &7 befejezhető. + enabled: "&2" + disabled: és c + order: + name: "&f &l Rendelés" + description: |- + &7 Lehetővé teszi a sorrend megváltoztatását + &7 objektum. + &7 Egyenlő számú objektum + &7 -et ők rendelik + &7 egyedi azonosító név. + value: "&7 Jelenlegi sorrend: &e [number]" + icon: + name: "&f &l ikon" + description: |- + &7 Lehetővé teszi az ikon megváltoztatását + &7 erre a kihívásra. + locked_icon: + name: "&f &l Zárolt ikon" + description: |- + &7 Lehetővé teszi a zárolt módosítást + &7 szint ikon. + required_permissions: + name: "&f &l Szükséges engedélyek" + description: |- + &7 Lehetővé teszi a szükséges módosítást + &7 engedély erre + &7 kihívás teljesíthető. + title: "&7 engedély:" + permission: " &8 - [permission]" + none: "&7 Az engedélyek nincsenek beállítva." + remove_entities: + name: "&f &l Entitások eltávolítása" + description: |- + &7 Lehetővé teszi a váltást, ha + &7 szükséges entitás + &7 távolítsa el a világból + &7 befejezése után + &7 kihívás. + enabled: "&2 Engedélyezve" + disabled: "&c Letiltva" + required_entities: + name: "&f &l Kötelező entitások" + description: |- + &7 Lehetővé teszi a szükséges módosítást + &7 entitás ehhez + &7 kihívás teljesíthető. + title: "&7 entitás:" + list: " &8 - [number] x [block]" + none: "&7 Entitások nincsenek hozzáadva." + remove_blocks: + name: "&f &l Blokkok eltávolítása" + description: |- + &7 Lehetővé teszi a váltást, ha + &7 szükséges blokk lesz + &7 távolítsa el a világból + &7 befejezése után + &7 kihívás. + enabled: "&2 Engedélyezve" + disabled: "&c Letiltva" + required_blocks: + name: "&f &l Kötelező blokkok" + description: |- + &7 Lehetővé teszi a szükséges módosítást + &7 blokk erre + &7 kihívás teljesíthető. + title: "&7 blokk:" + list: " &8 - [number] x [block]" + none: "&7 Blokkok nincsenek hozzáadva." + search_radius: + name: "&f &l Keresési sugár" + description: |- + &7 Lehetővé teszi a sugár megváltoztatását + &7 körül játékos, ahonnan + &7 blokk és/vagy entitás + &7 észlelve. + value: "&7 Jelenlegi távolság: &e [number]" + remove_items: + name: "&f &l Elemek eltávolítása" + description: |- + &7 Lehetővé teszi a váltást, ha + &7 kötelező elem lesz + &7 eltávolításra kerül a készletből + &7 befejezése után + &7 kihívás. + enabled: "&2 Engedélyezve" + disabled: "&c Letiltva" + required_items: + name: "&f &l Kötelező elemek" + description: |- + &7 Lehetővé teszi a szükséges módosítást + &7 elem ehhez + &7 kihívás teljesíthető. + title: "&7 elem:" + list: " &8 - [item]" + none: "&7 Elemek nincsenek hozzáadva." + add_ignored_meta: + name: "&f &l Metaadatok figyelmen kívül hagyása" + description: |- + &7 Lehetővé teszi, hogy melyiket adja hozzá + &7 elemet figyelmen kívül kell hagyni + &7 minden olyan metaadat + &7 van hozzárendelve. + title: "&7 elem:" + list: " &8 - [item]" + none: "&7 Elemek nincsenek hozzáadva." + remove_ignored_meta: + name: "&f &l A metaadatok figyelmen kívül hagyásának eltávolítása" + description: |- + &7 Lehetővé teszi annak eltávolítását + &7 elemet figyelmen kívül kell hagyni + &7 minden olyan metaadat + &7 van hozzárendelve. + remove_experience: + name: "&f &l Tapasztalat eltávolítása" + description: |- + &7 Lehetővé teszi a váltást, ha + &7 szükséges tapasztalat lesz + &7 eltávolításra kerül a lejátszóból + &7 befejezése után + &7 kihívás. + enabled: "&2 Engedélyezve" + disabled: "&c Letiltva" + required_experience: + name: "&f &l Szükséges tapasztalat" + description: |- + &7 Lehetővé teszi a + &7 szükséges tapasztalat + &7 a lejátszó. + value: "&7 Jelenlegi tapasztalat: &e [number]" + required_level: + name: "&f &l Kötelező szigetszint" + description: |- + &7 Lehetővé teszi a + &7 szükséges sziget szint + &7 a kihíváshoz. + value: "&7 Jelenlegi szint: &e [number]" + remove_money: + name: "&f &l Pénz eltávolítása" + description: |- + &7 Lehetővé teszi a váltást, ha + &7 szükséges pénz lesz + &7 eltávolításra kerül a lejátszóból + &7 fiók befejezése után + &7 a kihívás. + enabled: "&2 Engedélyezve" + disabled: "&c Letiltva" + required_money: + name: "&f &l Szükséges pénz" + description: |- + &7 Lehetővé teszi a + &7 szükséges pénz a játékosra + &7 figyelembe veszi a kihívást. + value: "&7 Jelenlegi érték: &e [number]" + statistic: + name: "&f &l Statisztika" + description: |- + &7 Lehetővé teszi a + &7 statisztikai típus + &7 ellenőrizte ezt a kihívást. + value: "&7 Jelenlegi érték: &e [statistic]" + statistic_amount: + name: "&f &l Célérték" + description: |- + &7 Lehetővé teszi a + &7 statisztikai célérték + &7, amit teljesíteni kell. + value: "&7 Jelenlegi érték: &e [number]" + remove_statistic: + name: "&f &l Statisztika csökkentése" + description: |- + &7 Lehetővé teszi a váltást, ha + &7 statisztikai érték lesz + &7 befejezése után csökkenteni kell + &7 a kihívás. + enabled: "&2 Engedélyezve" + disabled: "&c Letiltva" + statistic_blocks: + name: "&f &l céltábla" + description: |- + &7 Lehetővé teszi a + &7 statisztikai célblokk. + value: "&7 Aktuális blokk: &e [block]" + statistic_items: + name: "&f &l Célpont" + description: |- + &7 Lehetővé teszi a + &7 statisztikai célpont. + value: "&7 Jelenlegi tétel: &e [item]" + statistic_entities: + name: "&f &l Cél Entitás" + description: |- + &7 Lehetővé teszi a + &7 statisztikai cél entitást. + value: "&7 Jelenlegi entitás: &e [block]" + reward_text: + name: "&f &l Jutalomszöveg" + description: |- + &7 A konkrét jutalomszöveg. + &7 A színkódoknak meg kell lenniük + &7 vonatkozik rá. + value: "&7 Jelenlegi szöveg:" + repeat_reward_text: + name: "&f &l Jutalomszöveg ismétlése" + description: |- + &7 Az adott ismétlődő jutalomszöveg + &7 a kihíváshoz. A szín + &7 kódot kell alkalmazni rá. + value: "&7 Jelenlegi szöveg:" + reward_items: + name: "&f &l Jutalom" + description: |- + &7 Lehetővé teszi a jutalom megváltoztatását + &7 elem. + title: "&7 elem:" + list: " &8 - [item]" + none: "&7 Elemek nincsenek hozzáadva." + repeat_reward_items: + name: "&f &l Ismételje meg a jutalom tételeit" + description: |- + &7 Lehetővé teszi az ismétlés megváltoztatását + &7 jutalom elemet ezért + &7 kihívás. + title: "&7 elem:" + list: " &8 - [item]" + none: "&7 Elemek nincsenek hozzáadva." + reward_experience: + name: "&f &l Jutalomélmény" + description: |- + &7 Lehetővé teszi a + &7 jutalmazási élmény + &7 a lejátszó. + value: "&7 Jutalomélmény: &e [number]" + repeat_reward_experience: + name: "&f &l Ismétlődő jutalomélmény" + description: |- + &7 Lehetővé teszi a + &7 ismétlődő jutalomélmény + &7 a játékos számára. + value: "&7 Jutalomélmény: &e [number]" + reward_money: + name: "&f &l Pénzjutalom" + description: |- + &7 Lehetővé teszi a + &7 jutalompénz. + value: "&7 Jelenlegi érték: &e [number]" + repeat_reward_money: + name: "&f &l Ismételje meg a jutalompénzt" + description: |- + &7 Lehetővé teszi a + &7 ismételt jutalompénz + &7 a kihíváshoz. + value: "&7 Jelenlegi érték: &e [number]" + reward_commands: + name: "&f &l Jutalomparancsok" + description: |- + &7 A specifikus jutalmazási parancsok. + &8 Tipp: + &8 A parancs nem követeli meg + &8 először írni "/", ahogy akarja + &8 automatikusan alkalmazásra kerül. + &8 Alapértelmezés szerint a parancsok lesznek + &8 szerver hajtja végre. azonban + &8 a "[SELF]" hozzáadása az elején + &8 lehetővé teszi a parancsok megadását + &8 végrehajtja a játékos. Az is + &8 egy helyőrzőt támogat + &8 `[player]` lesz + &8 játékos névvel helyettesítve + &8, aki teljesítette a kihívást. + value: "&7 Aktuális parancsok:" + repeat_reward_commands: + name: "&f &l Ismételje meg a jutalmazási parancsokat" + description: |- + &7 A konkrét ismétlődő jutalom + &7 parancs a kihíváshoz. + &8 Tipp: + &8 A parancs nem követeli meg + &8 először írni "/", ahogy akarja + &8 automatikusan alkalmazásra kerül. + &8 Alapértelmezés szerint a parancsok lesznek + &8 szerver hajtja végre. azonban + &8 a "[SELF]" hozzáadása az elején + &8 lehetővé teszi a parancsok megadását + &8 végrehajtja a játékos. Az is + &8 egy helyőrzőt támogat + &8 `[player]` lesz + &8 játékos névvel helyettesítve + &8, aki teljesítette a kihívást. + value: "&7 Aktuális parancsok:" + repeatable: + name: "&f &l Ismételhető" + description: |- + &7 Lehetővé teszi a váltást, ha + &7 a kihívás + &7 megismételhető. + enabled: "&2 Engedélyezve" + disabled: "&c Letiltva" + repeat_count: + name: "&f &l Ismétlés Count" + description: |- + &7 Lehetővé teszi a + &7 ismétlésszám + &7 a kihíváshoz. + value: "&7 Jelenlegi érték: &e [number]" + cool_down: + name: "&f &l Lehűlni" + description: |- + &7 Lehetővé teszi a + &7 lehűlési másodperc + &7 között várni kell + &7 megismételhető kihívás + &7 befejezés. + value: "&7 Jelenlegi érték: &e [time]" + challenges: + name: "&f &l Kihívások" + description: |- + &7 A hozzárendelt kihívások megtekintése + &7 szintre. + waiver_amount: + name: "&f &l Lemondási összeg" + description: |- + &7 Lehetővé teszi szám beállítását + &7 kihívás, amely képes + &7 befejezetlen marad + &7 a következő szint felszabadítása. + value: "&7 Jelenlegi érték: &e [number]" + add_challenges: + name: "&f &l Kihívás hozzáadása" + description: |- + &7 Lehetővé teszi a és kiválasztását + &7 további kihívásokat jelent a + &7 szint. + remove_challenges: + name: "&f &l Kihívás (ok) eltávolítása" + description: |- + &7 Lehetővé teszi a és kiválasztását + &7 távolítsa el a kihívásokat + &7 szint. + reset_on_new: + name: "&f &l Reset On New" + description: |- + &7 Lehetővé teszi a váltást, ha + &7 kihívásnak kell lennie + &7 alaphelyzetbe állítás, amikor a felhasználó távozik + &7 szigeten, vagy létrehoz egy újat + &7 sziget. + enabled: "&2 Engedélyezve" + disabled: "&c Letiltva" + broadcast: + name: "&f &l Közvetítés" + description: |- + &7 Adások kihívása és + &7 szintű első befejezés + &7 mindenkinek. + enabled: "&2 Engedélyezve" + disabled: "&c Letiltva" + remove_completed: + name: "&f &l Elrejtés befejezve" + description: |- + &7 Elrejti a befejezett kihívásokat + &7 a menüből. + enabled: "&2 Engedélyezve" + disabled: "&c Letiltva" + glow_completed: + name: "&f &l Ragyogás befejezve" + description: |- + &7 Varázslatos ragyogást kölcsönöz + &7 a befejezett kihívásokra. + enabled: "&2 Engedélyezve" + disabled: "&c Letiltva" + store_history: + name: "&f &l Store History" + description: |- + &7 Belső előzményeket tárol + &7, amikor minden kihívás + &7 elkészült. + &7 Jelenleg csak megtekinthető + &7 az adatbázisban. + enabled: "&2 Engedélyezve" + disabled: "&c Letiltva" + data_per_island: + name: "&f &l Store Per Island" + description: |- + &7 A befejezettet tárolja + &7 kihívás szigetenként. + &7 A haladás megosztásra kerül + &7 a csapat összes játékosával. + enabled: "&2 Engedélyezve" + disabled: "&c Letiltva" + show_title: + name: "&f &l Cím megjelenítése" + description: |- + &7 Megjeleníti a címet, amikor a + &7 kihívás vagy szint + &7 befejeződött. + enabled: "&2 Engedélyezve" + disabled: "&c Letiltva" + gamemode_gui: + name: "&f &l GameMode Selection GUI" + description: |- + &7 Engedélyezi az egyetlen GUI -t + &7 a /kihívásokon keresztül érhető el + &7 parancsot. + &c A szerver újraindítását igényli. + enabled: "&2 Engedélyezve" + disabled: "&c Letiltva" + locked_level_icon: + name: "&f &l Alapértelmezett zárolt szint ikon" + description: |- + &7 Az összes zárolt alapértelmezett ikonja + &7 szint. Minden szint változhat + &7 ezt az ikont. + purge_history: + name: "&f &l Történelem Élettartam" + description: |- + &7 Napok száma, mennyi ideig + &7 előzményadat tárolódik + &7 a felhasználói adatok között. + &7 0 azt jelenti, hogy az adatok fognak + &7 nem távolítható el. + value: "&7 Jelenlegi érték: &e [number]" + title_showtime: + name: "&f &l Cím Showtime" + description: |- + &7 A címkék száma + &7 jelenik meg a játékosnak. + value: "&7 Jelenlegi érték: &e [number]" + active_world_list: + name: "&f &l Csak aktív világ megjelenítése" + description: |- + &7 Ha a GameMode Selection GUI + &7 engedélyezve van, ez válthat + &7, ha a grafikus felhasználói felület megjeleníti a GameMode választást + &7 vagy kihívások a jelenlegi világ számára. + &c A szerver újraindítását igényli. + enabled: "&2 Engedélyezve" + disabled: "&c Letiltva" + visibility_mode: + name: "&f &l Láthatósági mód" + description: |- + &7 Láthatósági mód + &7 kihívás + &7 hiddend. + enabled: "&2" + disabled: és c + visible: Látható kihívások megjelenítése + hidden: Mutasd meg az összes kihívást + toggleable: Váltás engedélyezése + download: + name: "&f &l Könyvtárak letöltése" + description: |- + &7 Manuális frissítés érhető el + &7 kihívást jelent a könyvtáraknak. + enabled: "&2 A gyorsítótár üres" + disabled: "&c Gyorsítótár nélkül törölje" + player: + name: "&f &l [name]" + description: "&7 szigettulajdonos: [owner]" + members: "&7 szigettag:" + member: "&8 - [name]" + no-island: |- + &c Player nem rendelkezik + és c egy sziget. + player_list: + name: "&f &l Válassza ki a Felhasználói listát" + description: |- + &7 Válassza ki a felhasználói listát + &7 -et kell mutatni. + enabled: "&2" + disabled: és c + online: Online játékosok + with_island: Játékosok szigetekkel + in_world: Játékosok a világban + add_block: + name: "&f &l Blokk hozzáadása" + description: |- + &7 Lehetővé teszi újak hozzáadását + &7 blokk a listához. + remove_block: + name: "&f &l Blokk eltávolítása" + description: |- + &7 Lehetővé teszi az eltávolítást + &7 kiválasztott blokk + &7 a listákból. + title: "&7 kiválasztott anyag:" + material: "&8 - [material]" + material: + name: "&f &l [material]" + description: "&7 Anyag -azonosító: [id]" + selected: "&2 Kiválasztva" + add_entity: + name: "&f &l Entitás hozzáadása" + description: |- + &7 Lehetővé teszi újak hozzáadását + &7 entitás a listában. + switch_entity: + name: "&f &l Tojásváltás" + description: |- + &7 Lehetővé teszi a váltást + &7 tojás a csőcselékfejekhez. + remove_entity: + name: "&f &l Entitás eltávolítása" + description: |- + &7 Lehetővé teszi az eltávolítást + &7 kiválasztott entitás + &7 a listákból. + title: "&7 kiválasztott entitás:" + entity: "&8 - [block]" + entity: + name: "&f &l [block]" + description: "&7 Entitás azonosító: [id]" + selected: "&2 Kiválasztva" + inventory_type: + name: "&f &l Készlet típusa" + description: |- + &7 Kihívás, amely ellenőrzi + &7 elem a játékosok készletében + island_type: + name: "&f &l Sziget típusa" + description: |- + &7 Kihívás, amely ellenőrzi + &7 blokk vagy entitás körül + &7 játékos. + other_type: + name: "&f &l Egyéb típus" + description: |- + &7 Kihívás + &7 bővítmény vagy kiegészítő, + &7, mint a szint és a pénz. + statistic_type: + name: "&f &l Statisztika típusa" + description: |- + &7 Kihívás, amely ellenőrzi + &7 játékos statisztikai adatai. + save: + name: "&f &l Mentés" + description: |- + &7 Menti a változtatásokat és + &7 visszatér. + cancel: + name: "&f &l Mégse" + description: |- + &7 Elveti a módosításokat és + &7 visszatér. + accept_selected: + name: "&f &l Kiválasztott elfogadása" + description: |- + &7 Visszaadja a kijelölt elemeket + &7 és megnyitja az előző GUI -t. + title: "&7 kiválasztva:" + element: "&8 - [item]" + statistic_element: + name: "&f &l [statistic]" + description: "[description]" + environment_element: + name: "&f &l [environment]" + description: "[description]" + search: + name: "&f &l Keresés" + description: |- + &7 Lehetővé teszi a keresést egy + &7 elem bemenettel + &7 szövegérték. + search: "&b Érték: [value]" + tips: + click-to-select: "&e Kattintson a &7 gombra a kiválasztáshoz." + click-to-choose: "&e Kattintson a &7 gombra a kiválasztáshoz." + click-to-complete: "&e Kattintson a &7 gombra a befejezéshez." + right-click-multiple-open: "&e Kattintson a jobb egérgombbal és a 7 gombbal + a befejezés számának kiválasztásához." + shift-left-click-to-complete-all: "&e Shift Kattintson a &7 gombra az összes + befejezéséhez." + left-click-to-accept: "&e A bal egérgombbal &7 a befejezéshez." + right-click-to-write: "&e Íráshoz kattintson a jobb gombbal &7." + click-to-reduce: "&e Kattintson a &7 gombra a kicsinyítéshez." + click-to-increase: "&e Kattintson a &7 gombra a növeléshez." + click-to-return: "&e Kattintson a &7 gombra a visszatéréshez." + click-to-quit: "&e Kilépéshez kattintson a &7 gombra." + click-to-wipe: "&e Törléshez kattintson a &7 gombra." + left-click-to-wipe: "&e Bal kattintás &7 a törléshez." + right-click-to-switch: "&e A jobb egérgombbal &7 váltani." + click-to-open: "&e Kattintson a &7 gombra a megnyitáshoz." + click-to-export: "&e Kattintson a &7 gombra az exportáláshoz." + click-to-create: "&e Kattintson a &7 gombra a létrehozáshoz." + left-click-to-open: "&e A bal egérgombbal &7 megnyitásához." + right-click-to-reset-all: "&e Az összes törléséhez kattintson a jobb gombbal + &7." + click-to-toggle: "&e A &7 gombra kattintva válthat." + click-to-change: "&e Kattintson a &7 gombra a változtatáshoz." + shift-click-to-reset: "&e Shift Kattintson a &7 gombra a visszaállításhoz." + click-to-add: "&e Kattintson a &7 gombra a hozzáadáshoz." + click-to-remove: "&e Az eltávolításhoz kattintson a &7 gombra." + left-click-to-cycle: "&e Bal egérgombbal &7 a lefelé léptetéshez." + right-click-to-cycle: "&e A jobb egérgombbal és a 7 gombbal válthat." + click-to-edit: "&e Kattintson a &7 gombra a szerkesztéshez." + left-click-to-download: "&e Bal kattintás és 7 a letöltéshez." + right-click-to-toggle: "&e A jobb egérgombbal &7 a váltáshoz." + click-to-install: "&e Kattintson a &7 gombra a telepítéshez." + click-to-reset-all: "&e Kattintson az &7 gombra az összes visszaállításához." + right-click-to-select: "&e A jobb egérgombbal és a 7 gombbal választhat." + right-click-to-deselect: "&e Kattintson a jobb egérgombbal és a 7 gombbal a + kijelölés megszüntetéséhez." + left-click-to-choose: "&e Bal egérgombbal &7 a kiválasztáshoz." + click-to-cancel: "&e Kattintson a &7 gombra a törléshez." + click-to-save: "&e Kattintson a &7 gombra a mentéshez." + click-to-deselect: "&e Kattintson a &7 gombra a kijelölés megszüntetéséhez." + click-on-item: |- + &e Kattintson a &7 -re az elemen + &7 a készletét. + left-click-to-edit: "&e Bal kattintás &7 a szerkesztéshez." + right-click-to-clear: "&e A jobb egérgombbal és a 7 törléshez." + click-to-previous: "&e Kattintson a &7 gombra az előző oldal megtekintéséhez." + click-to-next: "&e Kattintson a &7 gombra a következő oldal megtekintéséhez." + descriptions: + challenge: + lore: |- + [description] + [status] + [cooldown] + [requirements] + [rewards] + status: + completed: "&2 &l Befejezve" + completed-times: "&2 befejezve &7 &l [number] &r &2 idő (k)" + completed-times-of: "&2 befejezve &7 &l [number] &r &2 / &7 &l [max] + &r &2 alkalommal" + completed-times-reached: "&2 &l Összes &7 [max] és 2 alkalommal befejezve" + cooldown: + lore: |- + [timeout] + [wait-time] + timeout: "&7 &l Lehűlés: &r &7 [time]" + wait-time: "&c &l Elérhető: &r&c [time]" + in-days: "[number] d" + in-hours: "[number] h" + in-minutes: "[number] perc" + in-seconds: "[number] s" + requirements: + lore: |- + [environment] + [type-requirement] + [permissions] + environment-single: "&7 Korlátozott: [environment]" + environment-title: "&7 Korlátozott:" + environment-list: " &7 - &e [environment]" + permission-single: "&c [permissions] engedély szükséges" + permissions-title: "&c Engedélyek szükségesek:" + permissions-list: " &c - [permission]" + island: + lore: |- + [blocks] + [entities] + [search-radius] + [warning-block] + [warning-entity] + blocks-title: "&7 &l Kötelező blokkok:" + block-value: " &7 - &e [material]" + blocks-value: " &7 - &e [number] x [material]" + entities-title: "&7 &l Kötelező entitások:" + entity-value: " &7 - &e [block]" + entities-value: " &7 - &e [number] x [block]" + search-radius: "&7 Legfeljebb &e [number] &7 méternél" + warning-block: "&e Blokkok &c eltávolításra kerülnek" + warning-entity: "&e Az entitások eltávolításra kerülnek" + inventory: + lore: |- + [items] + [warning] + item-title: "&7 &l Kötelező elemek:" + item-value: " &7 - &e [item]" + items-value: " &7 - &e [number] x [item]" + warning: "&e Elem (ek) eltávolításra kerülnek" + other: + lore: |- + [experience] + [experience-warning] + [money] + [money-warning] + [level] + experience: "&7 &l Szükséges tapasztalat: &r &e [number]" + experience-warning: "&e A tapasztalatok eltávolításra kerülnek" + money: "&7 &l Szükséges pénz: &r &e [number]" + money-warning: "&e A pénz eltávolításra kerül" + level: "&7 &l Kötelező szigetszint: &r &e [number]" + statistic: + lore: |- + [statistic] + [warning] + multiple-target: "&7 &l [statistic]: &r &e [number] x [target]" + single-target: "&7 &l [statistic]: &r &e [target]" + statistic: "&7 &l [statistic] &r &e [number]" + warning: "&e A statisztikai adatok csökkennek" + rewards: + lore: |- + &7 &l jutalmak: + [text] + [items] + [experience] + [money] + [commands] + item-title: "&7 elem:" + item-value: " &7 - &e [item]" + items-value: " &7 - &e [number] x [item]" + experience: "&7 Tapasztalat: &r &e [number]" + money: "&7 Pénz: &r &e [number]" + commands-title: "&7 parancs:" + command: " &7 - &e [command]" + level: + lore: |- + [text] + [status] + [waiver] + [rewards] + status: + completed: "&2 &l Befejezve" + completed-challenges-of: |- + &2 Befejezve &7 &l [number] &r &2 ki + &7 &l [max] &r &2 kihívások. + locked: "&c &l zárolva" + missing-challenges: |- + &7 [number] több kihívás kell + &7 befejeződött ennek a szintnek a feloldásához. + waiver: |- + &7 &l [number] kihívás (ok) &r &7 lehet + &7 átugrott a következő szint feloldásához. + rewards: + lore: |- + &7 &l jutalmak: + [text] + [items] + [experience] + [money] + [commands] + item-title: "&7 elem:" + item-value: " &7 - &e [item]" + items-value: " &7 - &e [number] x [item]" + experience: "&7 Tapasztalat: &r &e [number]" + money: "&7 Pénz: &r &e [number]" + commands-title: "&7 parancs:" + command: " &7 - &e [command]" + library: + author: "&7 [author]" + version: "&7 Kihívásokkal készült és e [version]" + lang: "&7 Nyelv: &e [lang]" + gamemode: "&7 Elsődleges &e [gamemode]" + conversations: + prefix: "&l &6 [BentoBox]: &r" + confirm-string: igaz, be, igen, megerősítés, y, érvényes, helyes + deny-string: hamis, ki, nem, tagad, n, érvénytelen, helytelen + cancel-string: megszünteti + exit-string: törlés, kilépés, kilépés + cancelled: "&c A beszélgetés megszakítva!" + input-number: "&e Kérjük, adjon meg egy számot a chatben." + input-seconds: "&e Kérjük, adjon meg egy másodpercet a csevegésben." + numeric-only: "&c A megadott [value] nem szám!" + not-valid-value: "&c A megadott szám [value] nem érvényes. Nagyobbnak kell lennie, + mint [min] és kisebbnek, mint [max]!" + user-data-removed: "&a A [gamemode] összes felhasználói adata törlődik az adatbázisból." + confirm-user-data-deletion: "&e Kérjük, erősítse meg, hogy törölni szeretné a + [gamemode] felhasználói adatbázisát." + challenge-data-removed: "&a [gamemode] adatai törlődnek az adatbázisból." + confirm-challenge-data-deletion: "&e Kérjük, erősítse meg, hogy törölni szeretné + a [gamemode] kihívások adatbázisát." + all-data-removed: "&a A [gamemode] összes kiegészítő adata törlődik az adatbázisból." + confirm-all-data-deletion: "&e Kérjük, erősítse meg, hogy törölni szeretné a + [gamemode] addon adatait." + write-name: "&e Kérjük, írjon nevet a chatbe." + new-object-created: "&Új objektum jön létre a [gamemode] számára." + object-already-exists: "&c Az objektum &7 [id] &c már létezik. Válasszon másik + nevet." + invalid-challenge: "&c Challenge [gamemode] érvénytelen adatokat tartalmaz. Nem + telepíthető!" + name-changed: "&a siker, a név frissült." + write-description: "&e Kérjük, írjon be egy új leírást a chat -be, és a befejezéshez + 'kilép' egy sorban." + description-changed: "&a siker, a leírás frissült." + write-permissions: "&e Kérjük, adja meg a szükséges jogosultságokat, egyet soronként + a csevegésben, és 'kilép' egy soron a befejezéshez." + permissions-changed: "&a siker, a kihívási jogosultságok frissültek." + write-reward-text: "&e Kérjük, írjon be egy új jutalomszöveget a csevegésbe, + és a befejezéshez 'kilép' egy sorban." + reward-text-changed: "&a siker, a jutalom szövege frissült." + write-repeat-reward-text: "&e Kérjük, írjon be egy új ismétlődő jutalomszöveget + a csevegésbe, és a befejezéshez 'kilép' egy sorban." + repeat-reward-text-changed: "&a siker, az ismételt jutalom szövege frissült." + write-reward-commands: "&e Kérjük, írjon be egy új jutalmazási parancsot a csevegés + minden sorába, és a befejezéshez 'kilép' egy soron." + reward-commands-changed: "&a siker, a jutalmazási parancsok frissültek." + write-repeat-reward-commands: "&e Kérjük, írjon be egy új ismétlési jutalmazási + parancsot a csevegés minden sorába, és a befejezéshez 'kilép' egy soron." + repeat-reward-commands-changed: "&a siker, az ismétlődő jutalmazási parancsok + frissültek." + challenge-removed: "&a [gamemode] a [gamemode] számára eltávolításra kerül az + adatbázisból." + confirm-challenge-deletion: "&e Kérjük, erősítse meg, hogy el szeretné távolítani + a [gamemode] [challenge] az adatbázisból." + level-removed: "&A [gamemode] szint [level] eltávolításra kerül az adatbázisból." + confirm-level-deletion: "&e Kérjük, erősítse meg, hogy el szeretné távolítani + a [gamemode] [level] szintjét az adatbázisból." + start-downloading: "&a A kihívások könyvtárának letöltése és importálása." + written-text: "&beviteli szöveg:" + confirm-data-replacement: "&e Kérjük, erősítse meg, hogy a jelenlegi kihívásokat + újakra kívánja cserélni." + new-challenges-imported: "&a siker, új kihívásokat importált a [gamemode] számára." + exported-file-name: "&e Kérjük, adja meg az exportált adatbázis fájl fájlnevét. + (a kilépéshez írja be: „Mégse”)" + database-export-completed: "&a siker, a [world] adatbázis -exportálása befejeződött. + Fájl [file] létrehozva." + file-name-exist: "&c Létezik „[id]” nevű fájl. Nem írható felül." + write-search: "&e Kérjük, írjon be egy keresési értéket. (a kilépéshez írja be: + „Mégse”)" + search-updated: "&a keresési érték frissítve." + titles: + challenge-title: Sikeresen teljesítve + challenge-subtitle: "[friendlyName]" + level-title: Sikeresen teljesítve + level-subtitle: "[friendlyName]" + messages: + completed: "&2 Befejezte a [player] kihívását [name] a [player] számára!" + already-completed: "&2 Ez a kihívás már befejeződött!" + reset: "&2 Visszaállítja a [player] kihívását [name]!" + reset-all: "&2 Minden [player] kihívás visszaállt!" + not-completed: "&2 Ez a kihívás még nem fejeződött be!" + migrate-start: "&2 Kezdje el a kihívások bővítési adatainak áttelepítését." + migrate-end: "&2 Challenges addon adatok új formátumba frissítve." + migrate-not: "&2 Minden adat érvényes." + start-downloading: "&5 A kihívások könyvtárának letöltése és importálása." + you-completed-challenge: "&2 Teljesítette a [value] &r &2 kihívást!" + you-repeated-challenge: "&2 Megismételte a [value] &r &2 kihívást!" + you-repeated-challenge-multiple: "&2 Ismételted a [value] &r &2 kihívást [count]!" + you-completed-level: "&2 Elérted az [value] &r &2 szintet!" + name-has-completed-challenge: "&5 [name] teljesítette a [value] &r &5 kihívást!" + name-has-completed-level: "&5 [name] befejezte az [value] &r &5 szintet!" + load-skipping: '"[value]" már létezik - kihagyás' + load-overwriting: A "[value]" felülírása + load-add: 'Új objektum hozzáadása: [value]' + errors: + no-name: "&c Hiányzik a kihívás neve" + unknown-challenge: "&c Ismeretlen kihívás" + not-valid-integer: |- + &c A megadott "[value]" egész szám nem érvényes! + Az értéknek [min] és [max] között kell lennie. + not-deployed: "&c Challenge nincs telepítve!" + not-on-island: "&c Ehhez a szigeten kell lennie!" + challenge-level-not-available: "&c Még nem oldotta fel a kihívás teljesítéséhez + szükséges szintet." + not-repeatable: "&c Ez a kihívás nem ismételhető!" + wrong-environment: "&c Rossz környezetben van!" + not-enough-items: "&c Nincs elég [item] a kihívás teljesítéséhez!" + not-close-enough: "&c Az összes szükséges tétel [number] mondatán belül kell állnia." + you-still-need: "&c Továbbra is szüksége van [amount] x [item]" + missing-addon: "&c Nem lehet teljesíteni a kihívást: Hiányzik a szükséges kiegészítő + vagy bővítmény." + incorrect: "&c Nem lehet teljesíteni a kihívást: A követelmények helytelenek." + not-enough-money: "&c A kihívás teljesítéséhez fiókjában [value] szükséges." + not-enough-experience: "&c A kihívás teljesítéséhez [value] EXP szükséges." + island-level: "&c A szigetnek [number] szintnek vagy magasabbnak kell lennie a + kihívás teljesítéséhez!" + no-load: "&c Hiba: Nem sikerült betölteni a fájlt. [message]" + load-error: "&c Hiba: Nem lehet betölteni az [value] értéket." + no-rank: "&c Nincs elég magas rangod ahhoz." + cannot-remove-items: "&c Néhány elem nem távolítható el a készletből!" + exist-challenges-or-levels: "&c A világban már léteznek kihívások. Nem lehet + folytatni!" + no-challenges: "&c A kihívások még nem valósultak meg ezen a világon!" + no-challenges-admin: "&c A kihívások még nem valósultak meg ezen a világon! Használja + a &5 /[command] &c billentyűket a hozzáadásukhoz!" + missing-arguments: "&c A parancsból hiányoznak az argumentumok." + no-multiple-permission: "&c Nincs engedélye arra, hogy ezt a kihívást egyszerre + többször teljesítse." + invalid-level: "&c A [level] szint érvénytelen adatokat tartalmaz. Nem töltődik + be az adatbázisból!" + invalid-challenge: "&c Challenge [gamemode] érvénytelen adatokat tartalmaz. Nem + töltődik be az adatbázisból!" + no-library-entries: "&c Nem találhatók könyvtári bejegyzések. Nincs mit mutatni." + not-hooked: "&c Challenges Az Addon nem talált GameMode módot." + timeout: "&c Ehhez a kihíváshoz várni kell [timeout] a befejezések között. Meg + kell várnia [wait-time], amíg újra befejezi." +protection: + flags: + CHALLENGES_ISLAND_PROTECTION: + description: |- + &5 &o Váltás ki teheti + &5 &o teljes kihívások + name: Kihívja a védelmet + CHALLENGES_WORLD_PROTECTION: + description: |- + &5 &o Engedélyezés/letiltás + &5 &o követelmény a játékosoknak + &5 &o legyen a szigetükön + &5 &o teljesít egy kihívást. + name: Kihívások a sziget korlátozására + hint: Nincs kihívás a szigeten kívül +version: 12 diff --git a/src/main/resources/locales/uk.yml b/src/main/resources/locales/uk.yml new file mode 100644 index 00000000..03fe8f64 --- /dev/null +++ b/src/main/resources/locales/uk.yml @@ -0,0 +1,1113 @@ +--- +meta: + authors: + - BONNe +challenges: + commands: + admin: + main: + description: Основна команда адміністратора. Відкриває GUI. + reload: + description: Перезавантажте завдання з бази даних + show: + description: Друкує всі виклики в чаті, які існують у цьому світі. + complete: + description: Виконайте завдання для гравця. + parameters: " " + reset: + description: Скинути виклик для гравця. Якщо для «challenge_id» встановлено + значення «all», усі виклики буде скинуто. + parameters: " " + migrate: + description: Перенесіть поточні дані викликів ігрового світу у формат зберігання + 0.8.0. + user: + main: + description: Графічний інтерфейс Open Challenges. + complete: + description: Повний виклик. + parameters: " [count]" + gui: + titles: + player-gui: "&0&l Меню викликів" + gamemode-gui: "&0&l Виберіть GameMode" + multiple-gui: "&0&l Скільки разів?" + admin-gui: "&0&l Меню адміністратора завдань" + edit-challenge: "&0&l Редагувати [challenge]" + edit-level: "&0&l Редагувати [level]" + settings: "&0&l Налаштування" + choose-challenge: "&0&l Виберіть завдання" + choose-level: "&0&l Виберіть рівень" + choose-player: "&0&l Виберіть програвач" + library: Бібліотека &0&l + manage-blocks: "&0&l Керувати блоками" + manage-entities: "&0&l Керувати сутностями" + type-selector: "&0&l Вибір типу завдання" + item-selector: "&0&l Вибір елементів" + block-selector: "&0&l Вибір блоку" + entity-selector: "&0&l Вибір сутності" + challenge-selector: "&0&l Вибір викликів" + statistic-selector: "&0&l Селектор статистики" + environment-selector: "&0&l Вибір середовища" + buttons: + free-challenges: + name: "&f&l Безкоштовні виклики" + description: |- + &7 Відображає список + &7 безкоштовних завдань + return: + name: "&f&l Повернути" + description: |- + &7 Повернення до попереднього меню + &7 або вийти з GUI + previous: + name: "&f&l Попередня сторінка" + description: "&7 Перейти на сторінку &e [number] &7" + next: + name: "&f&l Наступна сторінка" + description: "&7 Перейти на сторінку &e [number] &7" + reduce: + name: "&f&l Зменшити" + description: "&7 Зменшити на &e [number]" + increase: + name: "&f&l Збільшити" + description: "&7 Зменшити на &e [number]" + accept: + name: "&f&l Завершено" + description: |- + &7 Виконати завдання &e [number] + &7 раз(ів) + quit: + name: "&f&l Вийти" + description: "&7 Вийти з GUI." + complete_user_challenges: + name: "&f&l Виконайте завдання користувача(-и)" + description: |- + &7 Дозволяє вибрати користувача та + &7 завершити виклик(и) для + &7 його + reset_user_challenges: + name: "&f&l Скинути виклики користувача" + description: |- + &7 Дозволяє вибрати користувача та + &7 скинути його виклики + add_challenge: + name: "&f&l Створити виклик" + description: |- + &7 Запускає процес для + &7 створення нового виклику. + add_level: + name: "&f&l Створити рівень" + description: |- + &7 Запускає процес для + &7 створення нового рівня. + edit_challenge: + name: "&f&l Редагувати завдання" + description: |- + &7 Дозволяє вибирати та редагувати + &7 виклик. + edit_level: + name: "&f&l Редагувати рівень" + description: |- + &7 Дозволяє вибирати та редагувати + &7 рівень. + delete_challenge: + name: "&f&l Видалити завдання" + description: |- + &7 Дозволяє вибирати та видаляти + &7 виклик. + delete_level: + name: "&f&l Видалити рівень" + description: |- + &7 Дозволяє вибирати та видаляти + &7 рівень. + edit_settings: + name: "&f&l Налаштування" + description: |- + &7 Дозволяє переглядати та редагувати + &7 налаштування аддона. + complete_wipe: + name: "&f&l Повне очищення" + description: |- + &7 Повністю усуває проблеми + &7 база даних аддонів, у тому числі + &7 даних користувача. + challenge_wipe: + name: "&f&l Витирання виклику" + description: |- + &7 Повністю усуває проблеми + &7 та рівні з бази даних. + user_wipe: + name: "&f&l Стирання користувача" + description: |- + &7 Повністю очищає користувача + &7 дані з бази даних. + library: + name: "&f&l Бібліотека" + description: |- + &7 Відкриває паблік + Бібліотека &7 викликів. + import_database: + name: "&f&l Імпорт бази даних" + description: |- + &7 Дозволяє імпортувати експортовані + База даних викликів &7. + import_template: + name: "&f&l Імпортувати шаблон" + description: |- + &7 Дозволяє імпортувати шаблон + &7 файл із викликами. + export_challenges: + name: "&f&l Виклики експорту" + description: |- + &7 Дозволяє експортувати базу даних + &7 до локального файлу. + properties: + name: "&f&l властивості" + description: "&7 Переглянути всі основні властивості." + requirements: + name: "&f&l Вимоги" + description: "&7 Переглянути властивості вимог." + rewards: + name: "&f&l Нагороди" + description: "&7 Переглянути властивості нагород." + deployed: + name: "&f&l Розгортання" + description: |- + &7 Перемкнути, якщо виклик є + &7 розгорнуто, і користувачі можуть + &7 завершити його. + enabled: "&2 Увімкнено" + disabled: "&c Вимкнено" + name: + name: "&f&l Ім'я" + description: |- + &7 Дозволяє змінювати + &7 відображуване ім'я. + value: "&7 Зараз: &r [nane]" + remove_on_complete: + name: "&f&l Приховати після завершення" + description: |- + &7 Перемкнути, якщо виклик повинен + &7 прихований від гравця після + &7 це завершено. + enabled: "&2 Увімкнено" + disabled: "&c Вимкнено" + description: + name: "&f&l Опис" + description: |- + &7 Конкретний опис + &7 за виклик. Колір + До нього необхідно застосувати коди &7. + value: "&7 Поточний опис:" + environment: + name: "&f&l Розмір" + description: |- + &7 Дозволяє обмежити, у якому + &7 оцініть завдання + &7 можна завершити. + enabled: "&2" + disabled: і c + order: + name: "&f&l Порядок" + description: |- + &7 Дозволяє змінювати порядок + &7 об'єктів. + &7 Об’єкти з рівними номерами + &7 замовлять їх + &7 унікальних імен ідентифікаторів. + value: "&7 Поточне замовлення: &e [number]" + icon: + name: "&f&l Значок" + description: |- + &7 Дозволяє змінити значок + &7 за цей виклик. + locked_icon: + name: "&f&l Заблокований значок" + description: |- + &7 Дозволяє змінювати заблоковані + значок рівня &7. + required_permissions: + name: "&f&l Необхідні дозволи" + description: |- + &7 Дозволяє змінювати потрібні + &7 дозволів для цього + &7 завдання, яке потрібно виконати. + title: "&7 Дозволи:" + permission: " &8 - [permission]" + none: "&7 Дозволи не встановлено." + remove_entities: + name: "&f&l Видалити сутності" + description: |- + &7 Дозволяє перемикати якщо + &7 необхідних сутностей будуть + &7 бути видаленим зі світу + &7 після завершення + &7 завдання. + enabled: "&2 Увімкнено" + disabled: "&c Вимкнено" + required_entities: + name: "&f&l Обов'язкові сутності" + description: |- + &7 Дозволяє змінювати потрібні + &7 сутностей для цього + &7 завдання, яке потрібно виконати. + title: "&7 Сутності:" + list: " &8 - [number] x [entity]" + none: "&7 Сутності не додано." + remove_blocks: + name: "&f&l Видалити блоки" + description: |- + &7 Дозволяє перемикати якщо + &7 необхідних блоків буде + &7 буде видалено зі світу + &7 після завершення + &7 завдання. + enabled: "&2 Увімкнено" + disabled: "&c Вимкнено" + required_blocks: + name: "&f&l Необхідні блоки" + description: |- + &7 Дозволяє змінювати потрібні + &7 блоків для цього + &7 завдання, яке потрібно виконати. + title: "&7 блоків:" + list: "&8 - [number] x [entity]" + none: "&7 Блоки не додаються." + search_radius: + name: "&f&l Радіус пошуку" + description: |- + &7 Дозволяє змінювати радіус + &7 навколо гравця, з якого + &7 блоків та/або сутностей + &7 виявлено. + value: "&7 Поточна відстань: &e [number]" + remove_items: + name: "&f&l Видалити елементи" + description: |- + &7 Дозволяє перемикати якщо + &7 обов'язкових елементів будуть + &7 буде видалено з інвентарю + &7 після завершення + &7 завдання. + enabled: "&2 Увімкнено" + disabled: "&c Вимкнено" + required_items: + name: "&f&l Обов'язкові елементи" + description: |- + &7 Дозволяє змінювати потрібні + &7 елементів для цього + &7 завдання, яке потрібно виконати. + title: "&7 елементів:" + list: " &8 - [number] x [entity]" + none: "&7 Елементи не додано." + add_ignored_meta: + name: "&f&l Додати ігнорувати метадані" + description: |- + &7 Дозволяє додати which + &7 елементів слід ігнорувати + &7 будь-які метадані, які + Їм призначається &7. + title: "&7 елементів:" + list: " &8 - [number] x [entity]" + none: "&7 Елементи не додано." + remove_ignored_meta: + name: "&f&l Видалити ігнорувати метадані" + description: |- + &7 Дозволяє видалити які + &7 елементів слід ігнорувати + &7 будь-які метадані, які + Їм призначається &7. + remove_experience: + name: "&f&l Видалити досвід" + description: |- + &7 Дозволяє перемикати якщо + &7 необхідний досвід буде + &7 буде видалено з гравця + &7 після завершення + &7 завдання. + enabled: "&2 Увімкнено" + disabled: "&c Вимкнено" + required_experience: + name: "&f&l Необхідний досвід" + description: |- + &7 Дозволяє змінювати + &7 необхідний досвід для + &7 гравець. + value: "&7 Поточний досвід: &e [number]" + required_level: + name: "&f&l Необхідний рівень острова" + description: |- + &7 Дозволяє змінювати + &7 необхідний рівень острова + &7 за виклик. + value: "&7 Поточний рівень: &e [number]" + remove_money: + name: "&f&l Видалити гроші" + description: |- + &7 Дозволяє перемикати якщо + &7 потрібні гроші будуть + &7 буде видалено з гравця + &7 обліковий запис після завершення + &7 виклик. + enabled: "&2 Увімкнено" + disabled: "&c Вимкнено" + required_money: + name: "&f&l Необхідні гроші" + description: |- + &7 Дозволяє змінювати + &7 потрібні гроші для гравця + &7 рахунок для виклику. + value: "&7 Поточне значення: &e [number]" + statistic: + name: "&f&l Статистика" + description: |- + &7 Дозволяє змінювати + &7 тип статистики + &7 перевірив у цьому виклику. + value: "&7 Поточне значення: &e [statistic]" + statistic_amount: + name: "&f&l Цільове значення" + description: |- + &7 Дозволяє змінювати + &7 статистичне цільове значення + &7, які повинні бути виконані. + value: "&7 Поточне значення: &e [number]" + remove_statistic: + name: "&f&l Зменшити статистику" + description: |- + &7 Дозволяє перемикати якщо + &7 статистичне значення буде + &7 буде зменшено після завершення + &7 виклик. + enabled: "&2 Увімкнено" + disabled: "&c Вимкнено" + statistic_blocks: + name: "&f&l Цільовий блок" + description: |- + &7 Дозволяє змінювати + &7 статистичний цільовий блок. + value: "&7 Поточний блок: &e [block]" + statistic_items: + name: "&f&l Цільовий елемент" + description: |- + &7 Дозволяє змінювати + &7 статистичний цільовий елемент. + value: "&7 Поточний елемент: &e [item]" + statistic_entities: + name: "&f&l Цільова сутність" + description: |- + &7 Дозволяє змінювати + &7 статистична цільова сутність. + value: "&7 Поточна сутність: &e [entity]" + reward_text: + name: "&f&l Текст винагороди" + description: |- + &7 Конкретний текст винагороди. + &7 Кольорові коди мають бути + &7 застосовано до нього. + value: "&7 Поточний текст:" + repeat_reward_text: + name: "&f&l Повторити текст винагороди" + description: |- + &7 Конкретний повторний текст винагороди + &7 за виклик. Колір + До нього необхідно застосувати коди &7. + value: "&7 Поточний текст:" + reward_items: + name: "&f&l Нагородні предмети" + description: |- + &7 Дозволяє змінювати винагороду + &7 предметів. + title: "&7 елементів:" + list: " &8 - [number] x [item]" + none: "&7 Елементи не додано." + repeat_reward_items: + name: "&f&l Повторюйте елементи винагороди" + description: |- + &7 Дозволяє змінити повтор + &7 предметів нагороди за це + &7 завдання. + title: "&7 елементів:" + list: " &8 - [number] x [item]" + none: "&7 Елементи не додано." + reward_experience: + name: "&f&l Досвід винагороди" + description: |- + &7 Дозволяє змінювати + &7 винагорода за досвід + &7 гравець. + value: "&7 Поточний рівень: &e [number]" + repeat_reward_experience: + name: "&f&l Повторіть нагороду" + description: |- + &7 Дозволяє змінювати + &7 повторний досвід винагороди + &7 для гравця. + value: "&7 Поточний рівень: &e [number]" + reward_money: + name: "&f&l Гроші винагороди" + description: |- + &7 Дозволяє змінювати + &7 грошова винагорода. + value: "&7 Поточне значення: &e [number]" + repeat_reward_money: + name: "&f&l Повторити винагороду" + description: |- + &7 Дозволяє змінювати + &7 повторити грошову винагороду + &7 за виклик. + value: "&7 Поточне значення: &e [number]" + reward_commands: + name: "&f&l Команди винагороди" + description: |- + &7 Конкретні команди винагороди. + &8 Порада: + &8 Команда не вимагає + &8 написання першого `/` як буде + &8 буде застосовано автоматично. + &8 За замовчуванням команди будуть + &8 виконується сервером. Проте + &8 додавання `[SELF]` на початку + &8 дозволить команді бути + &8 виконується гравцем. Він також + &8 підтримує один заповнювач + &8 `[player]` це буде + &8 замінено іменем гравця + &8, який виконав завдання. + value: "&7 Поточні команди:" + repeat_reward_commands: + name: "&f&l Повторити команди винагороди" + description: |- + &7 Конкретна повторна винагорода + &7 команд для завдання. + &8 Порада: + &8 Команда не вимагає + &8 написання першого `/` як буде + &8 буде застосовано автоматично. + &8 За замовчуванням команди будуть + &8 виконується сервером. Проте + &8 додавання `[SELF]` на початку + &8 дозволить команді бути + &8 виконується гравцем. Він також + &8 підтримує один заповнювач + &8 `[player]` це буде + &8 замінено іменем гравця + &8, який виконав завдання. + value: "&7 Поточні команди:" + repeatable: + name: "&f&l Повторюється" + description: |- + &7 Дозволяє перемикати якщо + &7 виклик полягає в тому + &7 повторюється. + enabled: "&2 Увімкнено" + disabled: "&c Вимкнено" + repeat_count: + name: "&f&l Підрахунок повторів" + description: |- + &7 Дозволяє змінювати + &7 кількість повторень + &7 за виклик. + value: "&7 Поточне значення: &e [number]" + cool_down: + name: "&f&l Охолодження" + description: |- + &7 Дозволяє змінювати + &7 охолонути секунд, що + &7 потрібно почекати між + &7 повторюване завдання + &7 завершень. + value: "&7 Поточне значення: &e [time]" + challenges: + name: "&f&l Виклики" + description: |- + &7 Перегляньте призначені завдання + &7 до рівня. + waiver_amount: + name: "&f&l Сума відмови" + description: |- + &7 Дозволяє встановити число + &7 викликів, які можуть + &7 залишити незавершеним для + &7 розблокування наступного рівня. + value: "&7 Поточне значення: &e [number]" + add_challenges: + name: "&f&l Додати виклик(и)" + description: |- + &7 Дозволяє вибрати та + &7 додає виклики + &7 рівень. + remove_challenges: + name: "&f&l Видалити виклик(и)" + description: |- + &7 Дозволяє вибрати та + &7 видалити виклики для + &7 рівень. + reset_on_new: + name: "&f&l Скинути на новий" + description: |- + &7 Дозволяє перемикати якщо + &7 проблем має бути + &7 скидання, коли користувач залишає + &7 острів або створює новий + &7 острів. + enabled: "&2 Увімкнено" + disabled: "&c Вимкнено" + broadcast: + name: "&f&l Трансляція" + description: |- + &7 Трансляції виклик і + &7 рівень перше завершення + &7 кожному. + enabled: "&2 Увімкнено" + disabled: "&c Вимкнено" + remove_completed: + name: "&f&l Приховати завершено" + description: |- + &7 Приховує виконані завдання + &7 з меню. + enabled: "&2 Увімкнено" + disabled: "&c Вимкнено" + glow_completed: + name: "&f&l Світіння завершено" + description: |- + &7 Додає чарівне сяйво + &7 до виконаних завдань. + enabled: "&2 Увімкнено" + disabled: "&c Вимкнено" + store_history: + name: "&f&l Історія магазину" + description: |- + &7 Зберігає внутрішню історію + &7, коли є кожне завдання + &7 завершено. + &7 Наразі лише для перегляду + &7 у базі даних. + enabled: "&2 Увімкнено" + disabled: "&c Вимкнено" + data_per_island: + name: "&f&l Магазин для кожного острова" + description: |- + &7 Зберігає виконане + &7 викликів на острів. + &7 Буде надано спільний доступ до прогресу + &7 з усіма гравцями в команді. + enabled: "&2 Увімкнено" + disabled: "&c Вимкнено" + show_title: + name: "&f&l Показати назву" + description: |- + &7 Показує назву, коли a + &7 виклик або рівень + &7 завершено. + enabled: "&2 Увімкнено" + disabled: "&c Вимкнено" + gamemode_gui: + name: "&f&l Графічний інтерфейс вибору GameMode" + description: |- + &7 Вмикає один GUI, який + &7 доступний через /challenges + &7 команда. + &c Вимагає перезавантаження сервера. + enabled: "&2 Увімкнено" + disabled: "&c Вимкнено" + locked_level_icon: + name: "&f&l Значок заблокованого рівня за умовчанням" + description: |- + &7 Значок за умовчанням для всіх заблокованих + &7 рівнів. Кожен рівень може змінюватися + &7 цей значок. + purge_history: + name: "&f&l Історія життя" + description: |- + &7 Кількість днів як довго + &7 дані історії зберігаються + &7 у даних користувача. + &7 0 означає, що дані будуть + &7 не видаляти. + value: "&7 Поточне значення: &e [number]" + title_showtime: + name: "&f&l Час показу заголовка" + description: |- + &7 Кількість позначок цієї назви + &7 буде показано гравцеві. + value: "&7 Поточне значення: &e [number]" + active_world_list: + name: "&f&l Показати лише активний світ" + description: |- + &7 Якщо графічний інтерфейс вибору GameMode + &7 увімкнено, це можна перемикати + &7, якщо GUI показує вибір GameMode + &7 або виклики для сучасного світу. + &c Вимагає перезавантаження сервера. + enabled: "&2 Увімкнено" + disabled: "&c Вимкнено" + visibility_mode: + name: "&f&l Режим видимості" + description: |- + &7 Режим видимості для + &7 проблем, які є + &7 приховано. + enabled: "&2" + disabled: "&c" + visible: Покажіть видимі виклики + hidden: Показати всі виклики + toggleable: Дозволити перемикання + include_undeployed: + name: "&f&l Включити нерозгорнуті завдання" + description: |- + &7 Вказує, якщо не розгорнуто + &7 проблем має бути + &7 зараховується до рівня + &7 завершення. + enabled: "&2 Увімкнено" + disabled: "&c Вимкнено" + download: + name: "&f&l Бібліотеки завантажень" + description: |- + &7 Доступне оновлення вручну + &7 викликів бібліотек. + enabled: "&2 З очищенням кешу" + disabled: "&c Без очищення кешу" + player: + name: "&f&l [name]" + description: 'Власник острова &7: [owner]' + members: "&7 членів острова:" + member: "&8 - [name]" + no-island: |- + &c Гравець не має + &c острів. + player_list: + name: "&f&l Виберіть список користувачів" + description: |- + &7 Виберіть список користувачів + Має бути показано &7. + enabled: "&2" + disabled: "&c" + online: Онлайн гравці + with_island: Гравці з островами + in_world: Гравці у світі + add_block: + name: "&f&l Додати блок" + description: |- + &7 Дозволяє додати новий + &7 блок до списку. + remove_block: + name: "&f&l Видалити блок" + description: |- + &7 Дозволяє видалити + &7 вибраних блоків + &7 зі списків. + title: "&7 Вибрані матеріали:" + material: "&8 - [material]" + material: + name: "&8 - [material]" + description: "&7 Ідентифікатор матеріалу: [id]" + selected: "&2 Вибрано" + add_entity: + name: "&f&l Додати сутність" + description: |- + &7 Дозволяє додати новий + &7 сутність до списку. + switch_entity: + name: "&f&l Зміна яєць" + description: |- + &7 Дозволяє перемикатися з + &7 яєць головам натовпу. + remove_entity: + name: "&f&l Видалити сутність" + description: |- + &7 Дозволяє видалити + &7 вибраних сутностей + &7 зі списків. + title: "&7 Вибрані сутності:" + entity: "&8 - [entity]" + entity: + name: "&f&l [entity]" + description: "&7 Ідентифікатор організації: [id]" + selected: "&2 Вибрано" + inventory_type: + name: "&f&l Тип запасів" + description: |- + &7 Виклик, який перевіряє + &7 предметів в інвентарі гравця + island_type: + name: "&f&l Тип острова" + description: |- + &7 Виклик, який перевіряє + &7 блоків або сутностей навколо + &7 гравець. + other_type: + name: "&f&l Інший тип" + description: |- + &7 Виклик, який використовує + &7 плагінів або додаткових речей, + &7 як рівень і гроші. + statistic_type: + name: "&f&l Тип статистики" + description: |- + &7 Виклик, який перевіряє + &7 статистичні дані гравців. + save: + name: "&f&l Зберегти" + description: |- + &7 Зберігає зміни та + &7 повертає. + cancel: + name: "&f&l Скасувати" + description: |- + &7 Скасування змін і + &7 повертає. + accept_selected: + name: "&f&l Прийняти вибране" + description: |- + &7 Повертає вибрані елементи + &7 і відкриває попередній графічний інтерфейс. + title: "&7 Вибрано:" + element: "&8 - [element]" + statistic_element: + name: "&f&l [statistic]" + description: "[description]" + environment_element: + name: "&f&l [environment]" + description: "[description]" + search: + name: "&f&l Пошук" + description: |- + &7 Дозволяє шукати + &7 елемент із введенням + &7 текстове значення. + search: "&b Значення: [value]" + tips: + click-to-select: "&e Натисніть &7, щоб вибрати." + click-to-choose: "&e Натисніть &7, щоб вибрати." + click-to-complete: "&e Натисніть &7, щоб завершити." + right-click-multiple-open: "&e Клацніть правою кнопкою миші &7, щоб вибрати + кількість завершень." + shift-left-click-to-complete-all: "&e Shift Натисніть &7, щоб завершити все." + left-click-to-accept: "&e Клацніть лівою кнопкою миші &7, щоб завершити." + right-click-to-write: "&e Клацніть правою кнопкою миші &7, щоб написати." + click-to-reduce: "&e Натисніть &7, щоб зменшити." + click-to-increase: "&e Натисніть &7, щоб збільшити." + click-to-return: "&e Натисніть &7, щоб повернутися." + click-to-quit: "&e Натисніть &7, щоб вийти." + click-to-wipe: "&e Натисніть &7, щоб стерти." + left-click-to-wipe: "&e Клацніть лівою кнопкою миші &7, щоб стерти." + right-click-to-switch: "&e Клацніть правою кнопкою миші &7, щоб переключитися." + click-to-open: "&e Натисніть &7, щоб відкрити." + click-to-export: "&e Натисніть &7, щоб експортувати." + click-to-create: "&e Натисніть &7, щоб створити." + left-click-to-open: "&e Клацніть лівою кнопкою миші &7, щоб відкрити." + right-click-to-reset-all: "&e Клацніть правою кнопкою миші &7, щоб стерти все." + click-to-toggle: "&e Натисніть &7, щоб перемкнути." + click-to-change: "&e Натисніть &7, щоб змінити." + shift-click-to-reset: "&e Shift Натисніть &7, щоб скинути." + click-to-add: "&e Натисніть &7, щоб додати." + click-to-remove: "&e Натисніть &7, щоб видалити." + left-click-to-cycle: "&e Клацніть лівою кнопкою миші &7, щоб перейти вниз." + right-click-to-cycle: "&e Клацніть правою кнопкою миші &7, щоб перейти вгору." + click-to-edit: "&e Натисніть &7, щоб редагувати." + left-click-to-download: "&e Клацніть лівою кнопкою миші &7, щоб завантажити." + right-click-to-toggle: "&e Клацніть правою кнопкою миші &7 для перемикання." + click-to-install: "&e Натисніть &7, щоб установити." + click-to-reset-all: "&e Натисніть &7, щоб скинути все." + right-click-to-select: "&e Клацніть правою кнопкою миші &7, щоб вибрати." + right-click-to-deselect: "&e Клацніть правою кнопкою миші &7, щоб скасувати + вибір." + left-click-to-choose: "&e Клацніть лівою кнопкою миші &7, щоб вибрати." + click-to-cancel: "&e Натисніть &7, щоб скасувати." + click-to-save: "&e Натисніть &7, щоб зберегти." + click-to-deselect: "&e Натисніть &7, щоб скасувати вибір." + click-on-item: |- + &e Клацніть &7 на елементі в + &7 ваш інвентар. + left-click-to-edit: "&e Клацніть лівою кнопкою миші &7 для редагування." + right-click-to-clear: "&e Клацніть правою кнопкою миші &7, щоб очистити." + click-to-previous: "&e Натисніть &7, щоб переглянути попередню сторінку." + click-to-next: "&e Натисніть &7, щоб переглянути наступну сторінку." + descriptions: + challenge: + lore: |- + [description] + [status] + [cooldown] + [requirements] + [rewards] + status: + completed: "&2&l Завершено" + completed-times: "&2 Виконано &7&l [number] &r&2 раз(ів)" + completed-times-of: "&2 Виконано &7&l [number] &r&2 із &7&l [max] &r&2 разів" + completed-times-reached: "&2&l Виконано всі &7 [max] &2 рази" + cooldown: + lore: |- + [timeout] + [wait-time] + timeout: "&7&l Охолодження: &r&7 [time]" + wait-time: "&c&l Доступно після: &r&c [time]" + in-days: "[number] дн " + in-hours: "[number] год " + in-minutes: "[number] хв" + in-seconds: "[number] с" + requirements: + lore: |- + [environment] + [type-requirement] + [permissions] + environment-single: "&7 Обмежено [environment]" + environment-title: "&7 Обмежується:" + environment-list: " &7 - &e [environment]" + permission-single: "&c Потрібен дозвіл [permissions]." + permissions-title: "&c Потрібні дозволи:" + permissions-list: " &c - [permission]" + island: + lore: |- + [blocks] + [entities] + [search-radius] + [warning-block] + [warning-entity] + blocks-title: "&7&l Необхідні блоки:" + block-value: " &7 - &e [material]" + blocks-value: " &7 - &e [number] x [material]" + entities-title: "&7&l Необхідні сутності:" + entity-value: " &7 - &e [entity]" + entities-value: " &7 - &e [number] x [entity]" + search-radius: "&7 Не далі &e [number] &7 метрів" + warning-block: "&e Блоки будуть &c видалені" + warning-entity: "&e Сутності будуть &c видалені" + inventory: + lore: |- + [items] + [warning] + item-title: "&7&l Необхідні елементи:" + item-value: " &7 - &e [item]" + items-value: " &7 - &e [number] x [item]" + warning: "&e Елемент(и) буде &c видалено" + other: + lore: |- + [experience] + [experience-warning] + [money] + [money-warning] + [level] + experience: "&7&l Необхідний досвід: &r&e [number]" + experience-warning: "&e Досвід буде &c видалено" + money: "&7&l Необхідні гроші: &r&e [number]" + money-warning: "&e Гроші будуть &c видалені" + level: "&7&l Необхідний рівень острова: &r&e [number]" + statistic: + lore: |- + [statistic] + [warning] + multiple-target: "&7&l [статистика]: &r&e [number] x [target]" + single-target: "&7&l [statistic]: &r&e [terget]" + statistic: "&7&l [statistic] &r&e [number]" + warning: "&e Статистичні дані будуть &c зменшені" + rewards: + lore: |- + &7&l Нагороди: + [text] + [items] + [experience] + [money] + [commands] + item-title: "&7 елементів:" + item-value: " &7 - &e [item]" + items-value: " &7 - &e [number] x [item]" + experience: "&7 Досвід: &r&e [номер]" + money: "&7 Гроші: &r&e [number]" + commands-title: "&7 Команди:" + command: " &7 - &e [command]" + level: + lore: |- + [text] + [status] + [waiver] + [rewards] + status: + completed: "&2&l Завершено" + completed-challenges-of: |- + &2 Завершено &7&l [number] &r&2 з + &7&l [max] &r&2 виклики. + locked: "&c&l Заблоковано" + missing-challenges: |- + &7 [number] має бути більше викликів + &7 завершено, щоб розблокувати цей рівень. + waiver: |- + &7&l [number] завдання(-и) &r&7 може бути + &7 пропущено, щоб розблокувати наступний рівень. + rewards: + lore: |- + &7&l Нагороди: + [text] + [items] + [experience] + [money] + [commands] + item-title: "&7 елементів:" + item-value: " &7 - &e [item]" + items-value: " &7 - &e [number] x [item]" + experience: "&7 Досвід: &r&e [number]" + money: "&7 Гроші: &r&e [number]" + commands-title: "&7 Команди:" + command: " &7 - &e [command]" + library: + author: "&7 від &e [author]" + version: "&7 Made with Challenges &e [version]" + lang: "&7 Мова: &e [lang]" + gamemode: "&7 Основний для &e [gamemode]" + conversations: + prefix: "&l&6 [BentoBox]: &r" + confirm-string: true, on, yes, confirm, y, valid, correct + deny-string: false, off, no, deny, n, invalid, incorrect + cancel-string: скасувати + exit-string: скасувати, вийти, вийти + cancelled: "&c Розмова скасована!" + input-number: "&e Будь ласка, введіть номер у чаті." + input-seconds: "&e Будь ласка, введіть секунди в чаті." + numeric-only: "&c Дане [value] не є числом!" + not-valid-value: "&c Дане число [value] недійсне. Він має бути більшим за [min] + і меншим за [max]!" + user-data-removed: "&a Усі дані користувача для [gamemode] видалено з бази даних." + confirm-user-data-deletion: "&e Підтвердьте, що ви бажаєте очистити базу даних + користувачів для [gamemode]." + challenge-data-removed: "&a Усі дані викликів для [gamemode] видалено з бази даних." + confirm-challenge-data-deletion: "&e Будь ласка, підтвердьте, що ви хочете очистити + базу даних викликів для [gamemode]." + all-data-removed: "&a Усі дані аддонів для [gamemode] видалено з бази даних." + confirm-all-data-deletion: "&e Будь ласка, підтвердьте, що ви хочете очистити + дані аддонів для [gamemode]." + write-name: "&e Будь ласка, напишіть ім'я в чаті." + new-object-created: "&Створено новий об’єкт для [gamemode]." + object-already-exists: "&c Об'єкт &7 [id] &c вже існує. Виберіть інше ім'я." + invalid-challenge: "&c Завдання [challenge] містить недійсні дані. Його не можна + розгортати!" + name-changed: "&a Успіх, назву оновлено." + write-description: "&e Будь ласка, введіть новий опис у чаті та 'quit' у окремому + рядку, щоб завершити." + description-changed: "&a Успіх, опис оновлено." + write-permissions: "&e Будь ласка, введіть необхідні дозволи, по одному на рядок + у чаті, і 'quit' на окремому рядку, щоб завершити." + permissions-changed: "&a Успіх, дозволи на виклик оновлено." + write-reward-text: "&e Будь ласка, введіть новий текст винагороди в чаті та 'quit' + в окремому рядку, щоб завершити." + reward-text-changed: "&a Успіх, текст нагороди оновлено." + write-repeat-reward-text: "&e Будь ласка, введіть новий повторний текст винагороди + в чаті та 'quit' в окремому рядку, щоб завершити." + repeat-reward-text-changed: "&a Успіх, текст повторної винагороди оновлено." + write-reward-commands: "&e Будь ласка, введіть нову команду винагороди для кожного + рядка в чаті та 'quit' в окремому рядку, щоб завершити." + reward-commands-changed: "&a Успіх, команди винагород оновлено." + write-repeat-reward-commands: "&e Будь ласка, введіть нову повторну команду винагороди + для кожного рядка в чаті та 'quit' в окремому рядку, щоб завершити." + repeat-reward-commands-changed: "&a Успіх, повторні команди винагороди оновлено." + challenge-removed: "&a Challenges [challenge] для [gamemode] видалено з бази даних." + confirm-challenge-deletion: "&e Будь ласка, підтвердьте, що ви хочете видалити + [challenge] для [gamemode] з бази даних." + level-removed: "&a Рівень [level] для [gamemode] видалено з бази даних." + confirm-level-deletion: "&e Будь ласка, підтвердьте, що ви хочете видалити [level] + для [gamemode] з бази даних." + start-downloading: "&a Початок завантаження та імпорту бібліотеки завдань." + written-text: "&a Текст введення:" + confirm-data-replacement: "&e Будь ласка, підтвердьте, що ви бажаєте замінити + свої поточні завдання новими." + new-challenges-imported: "&a Успіху, нові завдання для [gamemode] імпортовано." + exported-file-name: "&e Будь ласка, введіть назву файлу для експортованого файлу + бази даних. (напишіть 'cancel', щоб вийти)" + database-export-completed: "&a Успіх, експорт бази даних для [world] завершено. + Файл [file] створено." + file-name-exist: "&c Файл із назвою '[id]' існує. Неможливо перезаписати." + write-search: "&e Введіть пошукове значення. (напишіть 'cancel', щоб вийти)" + search-updated: "&a Значення пошуку оновлено." + titles: + challenge-title: Успішно завершено + challenge-subtitle: "[friendlyName]" + level-title: Успішно завершено + level-subtitle: "[friendlyName]" + messages: + completed: "&2 Ви виконали виклик [name] для [player]!" + already-completed: "&2 Це завдання вже виконано!" + reset: "&2 Ви скинули виклик [name] для [player]!" + reset-all: "&2 Усі завдання [player] скинуто!" + not-completed: "&2 Це завдання ще не завершено!" + migrate-start: "&2 Розпочати міграцію даних аддонів викликів." + migrate-end: "&2 Дані надбудови Challenges оновлено до нового формату." + migrate-not: "&2 Усі дані дійсні." + start-downloading: "&5 Початок завантаження та імпорту бібліотеки завдань." + you-completed-challenge: "&2 Ви завершили завдання [value] &r &2!" + you-repeated-challenge: "&2 Ви повторили завдання [value] &r &2!" + you-repeated-challenge-multiple: "&2 Ви повторили завдання [value] &r &2 [count] + разів!" + you-completed-level: "&2 Ви завершили рівень [value] &r &2!" + name-has-completed-challenge: "&5 [name] виконав завдання [value] &r &5!" + name-has-completed-level: "&5 [name] завершив рівень [value] &r &5!" + load-skipping: '"[value]" вже існує - пропуск' + load-overwriting: Перезапис "[value]" + load-add: 'Додавання нового об''єкта: [value]' + errors: + no-name: "&c Відсутня назва завдання" + unknown-challenge: "&c Невідомий виклик" + not-valid-integer: |- + &c Дане ціле число "[value]" недійсне! + Значення має бути між [min] і [max]. + not-deployed: "&c Challenge не розгорнуто!" + not-on-island: "&c Для цього ви повинні бути на своєму острові!" + challenge-level-not-available: "&c Ви не розблокували необхідний рівень для виконання + цього завдання." + not-repeatable: "&c Цей виклик неможливо повторити!" + wrong-environment: "&c Ви перебуваєте в неправильному середовищі!" + not-enough-items: "&c У вас недостатньо [items], щоб виконати це завдання!" + not-close-enough: "&c Ви повинні знаходитися в межах [number] блоків від усіх + необхідних елементів." + you-still-need: "&c Вам все ще потрібно [amount] x [item]" + missing-addon: "&c Неможливо виконати завдання: відсутній необхідний аддон або + плагін." + incorrect: "&c Неможливо завершити завдання: вимоги неправильні." + not-enough-money: "&c Щоб виконати завдання, у вашому обліковому записі необхідно + мати [value]." + not-enough-experience: "&c Щоб виконати це завдання, необхідно мати [value] досвіду." + island-level: "&c Ваш острів має бути рівня [number] або вище, щоб виконати це + завдання!" + no-load: "&c Помилка: Не вдалося завантажити [file]. [message]" + load-error: "&c Помилка: неможливо завантажити [value]." + no-rank: "&c Ви не маєте достатньо високого рангу, щоб це зробити." + cannot-remove-items: "&c Деякі предмети не можна видалити з вашого інвентарю!" + exist-challenges-or-levels: "&c Проблеми вже існують у вашому світі. Неможливо + продовжити!" + no-challenges: "&c Виклики ще не реалізовані в цьому світі!" + no-challenges-admin: "&c Виклики ще не реалізовані в цьому світі! Використовуйте + &5 /[command] &c, щоб додати їх!" + missing-arguments: У команді &c відсутні аргументи. + no-multiple-permission: "&c Ви не маєте дозволу виконувати це завдання кілька + разів одночасно." + invalid-level: "&c Рівень [level] містить недійсні дані. Він не буде завантажений + з бази даних!" + invalid-challenge: "&c Завдання [challenge] містить недійсні дані. Він не буде + завантажений з бази даних!" + no-library-entries: "&c Не вдається знайти жодного запису бібліотеки. Нічого показати." + not-hooked: "&c Challenges Addon не вдалося знайти режим гри." + timeout: "&c Цей виклик вимагає очікування [timeout] між завершеннями. Ви повинні + зачекати [wait-time], поки завершите його знову." + requirement-not-met: "&c Цей виклик вимагає [statistic] мати [number]. У вас є + лише [value]." + requirement-not-met-entity: "&c Цей виклик вимагає [statistic] [entity] мати [number]. + У вас є лише [value]." + requirement-not-met-material: "&c Цей виклик вимагає, щоб [statistic] [material] + мала [number]. У вас є лише [value]." +protection: + flags: + CHALLENGES_ISLAND_PROTECTION: + description: |- + &5 &o Перемкнути, хто може + &5 &o завершення завдань + name: Захист викликів + CHALLENGES_WORLD_PROTECTION: + description: |- + &5 &o Увімкнути/вимкнути + &5 &o вимоги до гравців + &5 &o бути на своєму острові, щоб + &5 &o виконати завдання. + name: Обмеження острова викликів + hint: Жодних проблем за межами острова +version: 12 diff --git a/src/main/resources/panels/gamemode_panel.yml b/src/main/resources/panels/gamemode_panel.yml index 7634b0c2..0492b22b 100644 --- a/src/main/resources/panels/gamemode_panel.yml +++ b/src/main/resources/panels/gamemode_panel.yml @@ -15,7 +15,7 @@ gamemode_panel: content: 2: 1: - icon: TIPPED_ARROW:INSTANT_HEAL::::1 + icon: tipped_arrow{CustomPotionColor:11546150} title: challenges.gui.buttons.previous.name description: challenges.gui.buttons.previous.description data: @@ -33,7 +33,7 @@ gamemode_panel: 7: gamemode 8: gamemode 9: - icon: TIPPED_ARROW:JUMP::::1 + icon: tipped_arrow{CustomPotionColor:8439583} title: challenges.gui.buttons.next.name description: challenges.gui.buttons.next.description data: diff --git a/src/main/resources/panels/main_panel.yml b/src/main/resources/panels/main_panel.yml index 78171b61..09cf0fe2 100644 --- a/src/main/resources/panels/main_panel.yml +++ b/src/main/resources/panels/main_panel.yml @@ -23,7 +23,7 @@ main_panel: 8: challenge_button 3: 1: - icon: TIPPED_ARROW:INSTANT_HEAL::::1 + icon: tipped_arrow{CustomPotionColor:11546150} title: challenges.gui.buttons.previous.name description: challenges.gui.buttons.previous.description data: @@ -41,7 +41,7 @@ main_panel: 7: challenge_button 8: challenge_button 9: - icon: TIPPED_ARROW:JUMP::::1 + icon: tipped_arrow{CustomPotionColor:8439583} title: challenges.gui.buttons.next.name description: challenges.gui.buttons.next.description data: @@ -53,7 +53,7 @@ main_panel: tooltip: challenges.gui.tips.click-to-next 5: 1: - icon: TIPPED_ARROW:INSTANT_HEAL::::1 + icon: tipped_arrow{CustomPotionColor:11546150} title: challenges.gui.buttons.previous.name description: challenges.gui.buttons.previous.description data: @@ -71,7 +71,7 @@ main_panel: 7: level_button 8: level_button 9: - icon: TIPPED_ARROW:JUMP::::1 + icon: tipped_arrow{CustomPotionColor:8439583} title: challenges.gui.buttons.next.name description: challenges.gui.buttons.next.description data: diff --git a/src/test/java/world/bentobox/challenges/ChallengesManagerTest.java b/src/test/java/world/bentobox/challenges/ChallengesManagerTest.java index 4e8fca26..c690e348 100644 --- a/src/test/java/world/bentobox/challenges/ChallengesManagerTest.java +++ b/src/test/java/world/bentobox/challenges/ChallengesManagerTest.java @@ -82,7 +82,7 @@ public class ChallengesManagerTest { // Mocks @Mock private ChallengesAddon addon; - @Mock + private Settings settings; @Mock private IslandWorldManager iwm; @@ -134,9 +134,11 @@ public void setUp() throws Exception { when(s.getDatabaseType()).thenReturn(DatabaseType.JSON); // Addon Settings + settings = new Settings(); when(addon.getChallengesSettings()).thenReturn(settings); - when(settings.isStoreHistory()).thenReturn(true); - when(settings.getLifeSpan()).thenReturn(10); + settings.setStoreAsIslandData(false); + settings.setStoreHistory(true); + settings.setLifeSpan(10); // Database database = new File("database"); @@ -264,7 +266,7 @@ public void testLoadChallengeNoOverwriteNotSilent() { assertTrue(cm.loadChallenge(challenge, world, false, user, true)); // load twice - no overwrite, not silent assertFalse(cm.loadChallenge(challenge, world, false, user, false)); - verify(user).getTranslation("challenges.messages.load-skipping", "[value]", "name"); + verify(user).getTranslation(world, "challenges.messages.load-skipping", "[value]", "name"); } /** @@ -276,7 +278,7 @@ public void testLoadChallengeOverwriteSilent() { assertTrue(cm.loadChallenge(challenge, world, false, user, true)); // overwrite assertTrue(cm.loadChallenge(challenge, world, true, user, true)); - verify(user, never()).getTranslation(anyString(), anyString(), anyString()); + verify(user, never()).getTranslation(any(World.class), anyString(), anyString(), anyString()); } /** @@ -288,7 +290,7 @@ public void testLoadChallengeOverwriteNotSilent() { assertTrue(cm.loadChallenge(challenge, world, false, user, true)); // overwrite not silent assertTrue(cm.loadChallenge(challenge, world, true, user, false)); - verify(user).getTranslation("challenges.messages.load-overwriting", "[value]", "name"); + verify(user).getTranslation(world, "challenges.messages.load-overwriting", "[value]", "name"); } /** @@ -311,7 +313,7 @@ public void testLoadLevelNoOverwriteNotSilent() { assertTrue(cm.loadLevel(level, world, false, user, true)); // load twice - no overwrite, not silent assertFalse(cm.loadLevel(level, world, false, user, false)); - verify(user).getTranslation("challenges.messages.load-skipping", "[value]", "Novice"); + verify(user).getTranslation(world, "challenges.messages.load-skipping", "[value]", "Novice"); } /** @@ -323,7 +325,7 @@ public void testLoadLevelOverwriteSilent() { assertTrue(cm.loadLevel(level, world, false, user, true)); // overwrite assertTrue(cm.loadLevel(level, world, true, user, true)); - verify(user, never()).getTranslation(anyString(), anyString(), anyString()); + verify(user, never()).getTranslation(any(World.class), anyString(), anyString(), anyString()); } /** @@ -335,7 +337,7 @@ public void testLoadLevelOverwriteNotSilent() { assertTrue(cm.loadLevel(level, world, false, user, true)); // overwrite not silent assertTrue(cm.loadLevel(level, world, true, user, false)); - verify(user).getTranslation("challenges.messages.load-overwriting", "[value]", "Novice"); + verify(user).getTranslation(world, "challenges.messages.load-overwriting", "[value]", "Novice"); } /** diff --git a/src/test/java/world/bentobox/challenges/commands/ChallengesCommandTest.java b/src/test/java/world/bentobox/challenges/commands/ChallengesCommandTest.java index 5d12e2af..56c041c9 100644 --- a/src/test/java/world/bentobox/challenges/commands/ChallengesCommandTest.java +++ b/src/test/java/world/bentobox/challenges/commands/ChallengesCommandTest.java @@ -6,7 +6,6 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @@ -17,7 +16,6 @@ import java.util.UUID; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemFactory; @@ -38,7 +36,6 @@ import world.bentobox.bentobox.api.addons.GameModeAddon; import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.configuration.WorldSettings; -import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.managers.CommandsManager; @@ -46,16 +43,16 @@ import world.bentobox.bentobox.managers.IslandsManager; import world.bentobox.bentobox.util.Util; import world.bentobox.challenges.ChallengesAddon; -import world.bentobox.challenges.managers.ChallengesManager; import world.bentobox.challenges.config.Settings; import world.bentobox.challenges.config.SettingsUtils.VisibilityMode; +import world.bentobox.challenges.managers.ChallengesManager; /** * @author tastybento * */ @RunWith(PowerMockRunner.class) -@PrepareForTest({Bukkit.class, BentoBox.class, ChatColor.class, Util.class}) +@PrepareForTest({ Bukkit.class, BentoBox.class, Util.class }) public class ChallengesCommandTest { @Mock @@ -104,7 +101,7 @@ public void setUp() { Optional optionalAddon = Optional.of(gameModeAddon); when(iwm.getAddon(any())).thenReturn(optionalAddon); when(plugin.getIWM()).thenReturn(iwm); - + @NonNull WorldSettings ws = new TestWorldSetting(); when(iwm.getWorldSettings(any())).thenReturn(ws); @@ -143,10 +140,6 @@ public void setUp() { // Challenges exist when(chm.hasAnyChallengeData(any(World.class))).thenReturn(true); - // ChatColor - PowerMockito.mockStatic(ChatColor.class); - when(ChatColor.translateAlternateColorCodes(any(char.class), anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(1, String.class)); - // Settings Settings settings = new Settings(); when(addon.getChallengesSettings()).thenReturn(settings); @@ -161,6 +154,9 @@ public void setUp() { // Util PowerMockito.mockStatic(Util.class, Mockito.RETURNS_MOCKS); when(Util.sameWorld(any(), any())).thenReturn(true); + when(Util.translateColorCodes(anyString())) + .thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); + // Command under test cc = new ChallengesPlayerCommand(addon, ic); } @@ -172,7 +168,7 @@ public void setUp() { public void testCanExecuteWrongWorld() { when(iwm.inWorld(any(World.class))).thenReturn(false); assertFalse(cc.canExecute(user, "challenges", Collections.emptyList())); - verify(user).getTranslation("general.errors.wrong-world"); + verify(user).getTranslation(world, "general.errors.wrong-world"); } /** @@ -184,7 +180,7 @@ public void testCanExecuteNoChallenges() { when(chm.hasAnyChallengeData(any(World.class))).thenReturn(false); assertFalse(cc.canExecute(user, "challenges", Collections.emptyList())); verify(addon).logError("There are no challenges set up in world!"); - verify(user).getTranslation("challenges.errors.no-challenges"); + verify(user).getTranslation(world, "challenges.errors.no-challenges"); } /** @@ -196,8 +192,8 @@ public void testCanExecuteNoChallengesOp() { when(chm.hasAnyChallengeData(any(World.class))).thenReturn(false); assertFalse(cc.canExecute(user, "challenges", Collections.emptyList())); verify(addon).logError("There are no challenges set up in world!"); - verify(user).getTranslation("challenges.errors.no-challenges-admin", "[command]", "bsb challenges"); - verify(user, never()).getTranslation("challenges.errors.no-challenges"); + verify(user).getTranslation(world, "challenges.errors.no-challenges-admin", "[command]", "bsb challenges"); + verify(user, never()).getTranslation(world, "challenges.errors.no-challenges"); } /** @@ -209,8 +205,8 @@ public void testCanExecuteNoChallengesHasPerm() { when(chm.hasAnyChallengeData(any(World.class))).thenReturn(false); assertFalse(cc.canExecute(user, "challenges", Collections.emptyList())); verify(addon).logError("There are no challenges set up in world!"); - verify(user).getTranslation("challenges.errors.no-challenges-admin", "[command]", "bsb challenges"); - verify(user, never()).getTranslation("challenges.errors.no-challenges"); + verify(user).getTranslation(world, "challenges.errors.no-challenges-admin", "[command]", "bsb challenges"); + verify(user, never()).getTranslation(world, "challenges.errors.no-challenges"); } /** @@ -223,8 +219,8 @@ public void testCanExecuteNoAdminCommand() { when(chm.hasAnyChallengeData(any(World.class))).thenReturn(false); assertFalse(cc.canExecute(user, "challenges", Collections.emptyList())); verify(addon).logError("There are no challenges set up in world!"); - verify(user).getTranslation("challenges.errors.no-challenges-admin", "[command]", "bsb challenges"); - verify(user, never()).getTranslation("challenges.errors.no-challenges"); + verify(user).getTranslation(world, "challenges.errors.no-challenges-admin", "[command]", "bsb challenges"); + verify(user, never()).getTranslation(world, "challenges.errors.no-challenges"); } /** @@ -234,7 +230,7 @@ public void testCanExecuteNoAdminCommand() { public void testCanExecuteNoIsland() { when(im.getIsland(any(), any(User.class))).thenReturn(null); assertFalse(cc.canExecute(user, "challenges", Collections.emptyList())); - verify(user).getTranslation("general.errors.no-island"); + verify(user).getTranslation(world, "general.errors.no-island"); } /** @@ -246,16 +242,6 @@ public void testCanExecuteSuccess() { verify(user, never()).sendMessage(anyString()); } - /** - * Test method for {@link ChallengesPlayerCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. - */ - @Test - public void testExecuteUserStringListOfStringConsole() { - User console = mock(User.class); - assertFalse(cc.execute(console, "challenges", Collections.emptyList())); - verify(console).sendMessage(eq("commands.help.header"), eq(TextVariables.LABEL), eq("BSkyBlock")); - } - /** * Test method for {@link ChallengesPlayerCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ diff --git a/src/test/java/world/bentobox/challenges/commands/CompleteChallengeCommandTest.java b/src/test/java/world/bentobox/challenges/commands/CompleteChallengeCommandTest.java index 5b9e4f42..876717a2 100644 --- a/src/test/java/world/bentobox/challenges/commands/CompleteChallengeCommandTest.java +++ b/src/test/java/world/bentobox/challenges/commands/CompleteChallengeCommandTest.java @@ -19,7 +19,6 @@ import java.util.UUID; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemFactory; @@ -46,11 +45,12 @@ import world.bentobox.bentobox.managers.IslandsManager; import world.bentobox.bentobox.util.Util; import world.bentobox.challenges.ChallengesAddon; -import world.bentobox.challenges.managers.ChallengesManager; import world.bentobox.challenges.config.Settings; import world.bentobox.challenges.config.SettingsUtils.VisibilityMode; import world.bentobox.challenges.database.object.Challenge; +import world.bentobox.challenges.managers.ChallengesManager; import world.bentobox.challenges.tasks.TryToComplete; +import world.bentobox.challenges.utils.Constants; import world.bentobox.challenges.utils.Utils; /** @@ -58,7 +58,7 @@ * */ @RunWith(PowerMockRunner.class) -@PrepareForTest({Bukkit.class, BentoBox.class, ChatColor.class, Utils.class, TryToComplete.class, Util.class}) +@PrepareForTest({ Bukkit.class, BentoBox.class, Utils.class, TryToComplete.class, Util.class }) public class CompleteChallengeCommandTest { @Mock @@ -149,11 +149,6 @@ public void setUp() { List nameList = Arrays.asList("world_maker", "world_placer", "bad_challenge_name", "world_breaker"); when(chm.getAllChallengesNames(any())).thenReturn(nameList); - - // ChatColor - PowerMockito.mockStatic(ChatColor.class); - when(ChatColor.translateAlternateColorCodes(any(char.class), anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(1, String.class)); - // Settings Settings settings = new Settings(); when(addon.getChallengesSettings()).thenReturn(settings); @@ -175,6 +170,8 @@ public void setUp() { // Util PowerMockito.mockStatic(Util.class); when(Util.tabLimit(any(), any())).thenAnswer((Answer>) invocation -> (List)invocation.getArgument(0, List.class)); + when(Util.translateColorCodes(anyString())) + .thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); // Command under test cc = new CompleteChallengeCommand(addon, ic); @@ -207,7 +204,8 @@ public void testSetup() { @Test public void testExecuteUserStringListOfStringNoArgs() { assertFalse(cc.execute(user, "complete", Collections.emptyList())); - verify(user).getTranslation(eq("challenges.errors.no-name")); + PowerMockito.verifyStatic(Utils.class); + Utils.sendMessage(user, world, Constants.ERRORS + "no-name"); verify(user).sendMessage(eq("commands.help.header"), eq(TextVariables.LABEL), eq("BSkyBlock")); } @@ -218,7 +216,8 @@ public void testExecuteUserStringListOfStringNoArgs() { public void testExecuteUserStringListOfStringUnknownChallenge() { when(chm.getChallenge(anyString())).thenReturn(null); assertFalse(cc.execute(user, "complete", Collections.singletonList("mychal"))); - verify(user).getTranslation(eq("challenges.errors.unknown-challenge")); + PowerMockito.verifyStatic(Utils.class); + Utils.sendMessage(user, world, Constants.ERRORS + "unknown-challenge"); verify(user).sendMessage(eq("commands.help.header"), eq(TextVariables.LABEL), eq("BSkyBlock")); } @@ -247,7 +246,8 @@ public void testExecuteUserStringListOfStringKnownChallengeSuccess() { @Test public void testExecuteUserStringListOfStringKnownChallengeSuccessMultipleTimesNoPerm() { assertTrue(cc.execute(user, "complete", Arrays.asList("mychal", "5"))); - verify(user).getTranslation(eq("challenges.error.no-multiple-permission")); + PowerMockito.verifyStatic(Utils.class); + Utils.sendMessage(user, world, Constants.ERRORS + "no-multiple-permission"); } /** diff --git a/src/test/java/world/bentobox/challenges/tasks/TryToCompleteTest.java b/src/test/java/world/bentobox/challenges/tasks/TryToCompleteTest.java index 07d18e66..363367a2 100644 --- a/src/test/java/world/bentobox/challenges/tasks/TryToCompleteTest.java +++ b/src/test/java/world/bentobox/challenges/tasks/TryToCompleteTest.java @@ -10,6 +10,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import java.io.IOException; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -21,7 +22,6 @@ import java.util.UUID; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.Material; @@ -36,7 +36,9 @@ import org.bukkit.util.BoundingBox; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; +import org.junit.After; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -60,588 +62,644 @@ import world.bentobox.bentobox.managers.PlaceholdersManager; import world.bentobox.bentobox.util.Util; import world.bentobox.challenges.ChallengesAddon; -import world.bentobox.challenges.managers.ChallengesManager; import world.bentobox.challenges.config.Settings; import world.bentobox.challenges.database.object.Challenge; import world.bentobox.challenges.database.object.Challenge.ChallengeType; import world.bentobox.challenges.database.object.ChallengeLevel; import world.bentobox.challenges.database.object.requirements.InventoryRequirements; import world.bentobox.challenges.database.object.requirements.IslandRequirements; +import world.bentobox.challenges.managers.ChallengesManager; import world.bentobox.challenges.tasks.TryToComplete.ChallengeResult; -import world.bentobox.challenges.utils.Utils; - /** * @author tastybento * */ @RunWith(PowerMockRunner.class) -@PrepareForTest({Bukkit.class, BentoBox.class, Util.class, Utils.class, ChatColor.class}) +@PrepareForTest({ Bukkit.class, BentoBox.class, Util.class }) public class TryToCompleteTest { - // Constants - private static final String GAME_MODE_NAME = "BSkyBlock"; - private static final String[] NAMES = {"adam", "ben", "cara", "dave", "ed", "frank", "freddy", "george", "harry", "ian", "joe"}; - - private TryToComplete ttc; - private Challenge challenge; - @Mock - private ChallengesAddon addon; - @Mock - private User user; - @Mock - private World world; - private final String topLabel = "island"; - private final String permissionPrefix = "perm."; - - @Mock - private ChallengesManager cm; - @Mock - private BentoBox plugin; - @Mock - private GameModeAddon gameMode; - @Mock - private AddonsManager am; - @Mock - private IslandsManager im; - @Mock - private Island island; - @Mock - private Player player; - @Mock - private Settings settings; - @Mock - private WorldSettings mySettings; - @Mock - private @Nullable PlayerInventory inv; - private final ItemStack[] contents = {}; - @Mock - private BoundingBox bb; - - /** - */ - @Before - public void setUp() { - // Set up plugin - Whitebox.setInternalState(BentoBox.class, "instance", plugin); - when(addon.getPlugin()).thenReturn(plugin); - // World - when(user.getWorld()).thenReturn(world); - when(world.getName()).thenReturn("world"); - when(world.getEnvironment()).thenReturn(Environment.NORMAL); - - // Addons manager - when(plugin.getAddonsManager()).thenReturn(am); - // One game mode - when(am.getGameModeAddons()).thenReturn(Collections.singletonList(gameMode)); - AddonDescription desc2 = new AddonDescription.Builder("bentobox", GAME_MODE_NAME, "1.3").description("test").authors("tasty").build(); - when(gameMode.getDescription()).thenReturn(desc2); - - // Challenge Level - @NonNull ChallengeLevel level = new ChallengeLevel(); - String levelName = GAME_MODE_NAME + "_novice"; - level.setUniqueId(levelName); - level.setFriendlyName("Novice"); - // Set up challenge - String uuid = UUID.randomUUID().toString(); - challenge = new Challenge(); - challenge.setUniqueId(GAME_MODE_NAME + "_" + uuid); - challenge.setFriendlyName("name"); - challenge.setLevel(GAME_MODE_NAME + "_novice"); - challenge.setDescription(Collections.singletonList("A description")); - challenge.setChallengeType(ChallengeType.INVENTORY_TYPE); - challenge.setDeployed(true); - challenge.setIcon(new ItemStack(Material.EMERALD)); - challenge.setEnvironment(Collections.singleton(World.Environment.NORMAL)); - challenge.setLevel(levelName); - challenge.setRepeatable(true); - challenge.setMaxTimes(10); - InventoryRequirements req = new InventoryRequirements(); - - challenge.setRequirements(req); - // Util - PowerMockito.mockStatic(Util.class); - when(Util.getWorld(any())).thenReturn(world); - when(Util.prettifyText(anyString())).thenCallRealMethod(); - when(Util.stripSpaceAfterColorCodes(anyString())).thenCallRealMethod(); - - // Island World Manager - IslandWorldManager iwm = mock(IslandWorldManager.class); - when(plugin.getIWM()).thenReturn(iwm); - Optional optionalGameMode = Optional.of(gameMode); - when(iwm.getAddon(any())).thenReturn(optionalGameMode); - when(iwm.getIslandDistance(any())).thenReturn(400); - when(iwm.inWorld(any(World.class))).thenReturn(true); - - // Island Manager - when(addon.getIslands()).thenReturn(im); - Optional opIsland = Optional.of(island); - when(im.getIslandAt(any())).thenReturn(opIsland); - when(im.getIsland(any(), any(User.class))).thenReturn(island); - // Player is on island - when(im.locationIsOnIsland(any(), any())).thenReturn(true); - // Island flags - everything is allowed by default - when(island.isAllowed(any(), any())).thenReturn(true); - // Island - - @Nullable - Location loc = mock(Location.class); - when(loc.toString()).thenReturn("center"); - when(island.getCenter()).thenReturn(loc); - - // Challenges Manager - when(addon.getChallengesManager()).thenReturn(cm); - // All levels unlocked by default - when(cm.isLevelUnlocked(any(), any(), any())).thenReturn(true); - // Player has done this challenge 3 times (default max is 10) - when(cm.getChallengeTimes(any(), any(), any(Challenge.class))).thenReturn(3L); - - // User has all perms by default - when(user.hasPermission(anyString())).thenReturn(true); - when(user.getPlayer()).thenReturn(player); - UUID uniqueId = UUID.randomUUID(); - when(user.getUniqueId()).thenReturn(uniqueId); - when(user.getTranslation(anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); - when(user.getTranslation(anyString(), anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); - when(user.getTranslationOrNothing(anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); - when(user.getName()).thenReturn("tastybento"); - @Nullable - Location userLoc = mock(Location.class); - when(userLoc.toString()).thenReturn("location"); - when(user.getLocation()).thenReturn(userLoc); - when(user.getInventory()).thenReturn(inv); - when(inv.getContents()).thenReturn(contents); - when(player.getBoundingBox()).thenReturn(bb); - when(bb.clone()).thenReturn(bb); - when(bb.toString()).thenReturn("BoundingBox"); - // Locales - User.setPlugin(plugin); - LocalesManager lm = mock(LocalesManager.class); - when(plugin.getLocalesManager()).thenReturn(lm); + // Constants + private static final String GAME_MODE_NAME = "BSkyBlock"; + private static final String[] NAMES = { "adam", "ben", "cara", "dave", "ed", "frank", "freddy", "george", "harry", + "ian", "joe" }; + + private TryToComplete ttc; + private Challenge challenge; + @Mock + private ChallengesAddon addon; + @Mock + private User user; + @Mock + private World world; + private final String topLabel = "island"; + private final String permissionPrefix = "perm."; + + @Mock + private ChallengesManager cm; + @Mock + private BentoBox plugin; + @Mock + private GameModeAddon gameMode; + @Mock + private AddonsManager am; + @Mock + private IslandsManager im; + @Mock + private Island island; + @Mock + private Player player; + @Mock + private Settings settings; + @Mock + private WorldSettings mySettings; + @Mock + private @Nullable PlayerInventory inv; + private final ItemStack[] contents = {}; + @Mock + private BoundingBox bb; + private Set onlinePlayers; + + /** + */ + @Before + public void setUp() { + // Set up plugin + Whitebox.setInternalState(BentoBox.class, "instance", plugin); + when(addon.getPlugin()).thenReturn(plugin); + // World + when(user.getWorld()).thenReturn(world); + when(world.getName()).thenReturn("world"); + when(world.getEnvironment()).thenReturn(Environment.NORMAL); + + // Addons manager + when(plugin.getAddonsManager()).thenReturn(am); + // One game mode + when(am.getGameModeAddons()).thenReturn(Collections.singletonList(gameMode)); + AddonDescription desc2 = new AddonDescription.Builder("bentobox", GAME_MODE_NAME, "1.3").description("test") + .authors("tasty").build(); + when(gameMode.getDescription()).thenReturn(desc2); + + // Challenge Level + @NonNull + ChallengeLevel level = new ChallengeLevel(); + String levelName = GAME_MODE_NAME + "_novice"; + level.setUniqueId(levelName); + level.setFriendlyName("Novice"); + // Set up challenge + String uuid = UUID.randomUUID().toString(); + challenge = new Challenge(); + challenge.setUniqueId(GAME_MODE_NAME + "_" + uuid); + challenge.setFriendlyName("name"); + challenge.setLevel(GAME_MODE_NAME + "_novice"); + challenge.setDescription(Collections.singletonList("A description")); + challenge.setChallengeType(ChallengeType.INVENTORY_TYPE); + challenge.setDeployed(true); + challenge.setIcon(new ItemStack(Material.EMERALD)); + challenge.setEnvironment(Collections.singleton(World.Environment.NORMAL)); + challenge.setLevel(levelName); + challenge.setRepeatable(true); + challenge.setMaxTimes(10); + InventoryRequirements req = new InventoryRequirements(); + + challenge.setRequirements(req); + // Util + PowerMockito.mockStatic(Util.class); + when(Util.getWorld(any())).thenReturn(world); + when(Util.prettifyText(anyString())).thenCallRealMethod(); + when(Util.stripSpaceAfterColorCodes(anyString())).thenCallRealMethod(); + when(Util.translateColorCodes(anyString())) + .thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); + + // Island World Manager + IslandWorldManager iwm = mock(IslandWorldManager.class); + when(plugin.getIWM()).thenReturn(iwm); + Optional optionalGameMode = Optional.of(gameMode); + when(iwm.getAddon(any())).thenReturn(optionalGameMode); + when(iwm.getIslandDistance(any())).thenReturn(400); + when(iwm.inWorld(any(World.class))).thenReturn(true); + + // Island Manager + when(addon.getIslands()).thenReturn(im); + Optional opIsland = Optional.of(island); + when(im.getIslandAt(any())).thenReturn(opIsland); + when(im.getIsland(any(), any(User.class))).thenReturn(island); + // Player is on island + when(im.locationIsOnIsland(any(), any())).thenReturn(true); + // Island flags - everything is allowed by default + when(island.isAllowed(any(), any())).thenReturn(true); + // Island + + @Nullable + Location loc = mock(Location.class); + when(loc.toString()).thenReturn("center"); + when(island.getCenter()).thenReturn(loc); + + // Challenges Manager + when(addon.getChallengesManager()).thenReturn(cm); + // All levels unlocked by default + when(cm.isLevelUnlocked(any(), any(), any())).thenReturn(true); + // Player has done this challenge 3 times (default max is 10) + when(cm.getChallengeTimes(any(), any(), any(Challenge.class))).thenReturn(3L); + + // User has all perms by default + when(user.hasPermission(anyString())).thenReturn(true); + when(user.getPlayer()).thenReturn(player); + UUID uniqueId = UUID.randomUUID(); + when(player.getUniqueId()).thenReturn(uniqueId); + when(user.getUniqueId()).thenReturn(uniqueId); + when(user.getTranslation(anyString())) + .thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); + when(user.getTranslation(anyString(), anyString())) + .thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); + when(user.getTranslationOrNothing(anyString())) + .thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); + when(user.getName()).thenReturn("tastybento"); + User.getInstance(player); + @Nullable + Location userLoc = mock(Location.class); + when(userLoc.toString()).thenReturn("location"); + when(user.getLocation()).thenReturn(userLoc); + when(user.getInventory()).thenReturn(inv); + when(inv.getContents()).thenReturn(contents); + when(player.getBoundingBox()).thenReturn(bb); + when(bb.clone()).thenReturn(bb); + when(bb.toString()).thenReturn("BoundingBox"); + // Locales + User.setPlugin(plugin); + LocalesManager lm = mock(LocalesManager.class); + when(plugin.getLocalesManager()).thenReturn(lm); + when(lm.get(any(), any())).thenAnswer((Answer) invocation -> invocation.getArgument(1, String.class)); when(lm.get(any(), any())).thenAnswer((Answer) invocation -> invocation.getArgument(1, String.class)); - PlaceholdersManager phm = mock(PlaceholdersManager.class); - when(plugin.getPlaceholdersManager()).thenReturn(phm); - when(phm.replacePlaceholders(any(), any())).thenAnswer((Answer) invocation -> invocation.getArgument(1, String.class)); - - // Survival by default - when(player.getGameMode()).thenReturn(GameMode.SURVIVAL); - - // Addon - when(addon.getChallengesSettings()).thenReturn(settings); - when(settings.isBroadcastMessages()).thenReturn(true); - - // Bukkit - online players - Map online = new HashMap<>(); - - Set onlinePlayers = new HashSet<>(); - for (String name : NAMES) { - Player p1 = mock(Player.class); - UUID uuid2 = UUID.randomUUID(); - when(p1.getUniqueId()).thenReturn(uuid2); - when(p1.getName()).thenReturn(name); - online.put(uuid2, name); - onlinePlayers.add(p1); - } - PowerMockito.mockStatic(Bukkit.class); - when(Bukkit.getOnlinePlayers()).then((Answer>) invocation -> onlinePlayers); - - // World settings - Map map = new HashMap<>(); - when(mySettings.getWorldFlags()).thenReturn(map); - when(iwm.getWorldSettings(any())).thenReturn(mySettings); - ChallengesAddon.CHALLENGES_WORLD_PROTECTION.setSetting(world, true); - - // ItemFactory - ItemFactory itemFactory = mock(ItemFactory.class); - when(Bukkit.getItemFactory()).thenReturn(itemFactory); - - // ChatColor - PowerMockito.mockStatic(ChatColor.class, Mockito.RETURNS_MOCKS); - when(ChatColor.stripColor(anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); - } - - /** - * Test method for {@link world.bentobox.challenges.tasks.TryToComplete#TryToComplete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. - */ - @Test - public void testTryToCompleteChallengesAddonUserChallengeWorldStringString() { - ttc = new TryToComplete(addon, - user, - challenge, - world, - topLabel, - permissionPrefix); - verify(addon).getChallengesManager(); - - } - - /** - * Test method for {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. - */ - @Test - public void testCompleteChallengesAddonUserChallengeWorldStringStringNotDeployed() { - challenge.setDeployed(false); - assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); - verify(user).getTranslation("challenges.errors.not-deployed"); - } - - /** - * Test method for {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. - */ - @Test - public void testCompleteChallengesAddonUserChallengeWorldStringStringWrongWorld() { - challenge.setUniqueId("test"); - assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); - verify(user).getTranslation("general.errors.wrong-world"); - } - - /** - * Test method for {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. - */ - @Test - public void testCompleteChallengesAddonUserChallengeWorldStringStringNotOnIsland() { - ChallengesAddon.CHALLENGES_WORLD_PROTECTION.setSetting(world, true); - when(im.locationIsOnIsland(any(Player.class), any(Location.class))).thenReturn(false); - assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); - verify(user).getTranslation("challenges.errors.not-on-island"); - } - - /** - * Test method for {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. - */ - @Test - public void testCompleteChallengesAddonUserChallengeWorldStringStringNotOnIslandButOk() { - ChallengesAddon.CHALLENGES_WORLD_PROTECTION.setSetting(world, false); - when(im.locationIsOnIsland(any(Player.class), any(Location.class))).thenReturn(false); - assertTrue(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); - verify(user).getTranslation("challenges.messages.you-completed-challenge", "[value]", "name"); - } - - /** + PlaceholdersManager phm = mock(PlaceholdersManager.class); + when(plugin.getPlaceholdersManager()).thenReturn(phm); + when(phm.replacePlaceholders(any(), any())) + .thenAnswer((Answer) invocation -> invocation.getArgument(1, String.class)); + + // Survival by default + when(player.getGameMode()).thenReturn(GameMode.SURVIVAL); + + // Addon + when(addon.getChallengesSettings()).thenReturn(settings); + when(settings.isBroadcastMessages()).thenReturn(true); + + // Bukkit - online players + Map online = new HashMap<>(); + + onlinePlayers = new HashSet<>(); + for (String name : NAMES) { + Player p1 = mock(Player.class); + UUID uuid2 = UUID.randomUUID(); + when(p1.getUniqueId()).thenReturn(uuid2); + when(p1.getName()).thenReturn(name); + online.put(uuid2, name); + onlinePlayers.add(p1); + } + PowerMockito.mockStatic(Bukkit.class); + when(Bukkit.getOnlinePlayers()).then((Answer>) invocation -> Set.of(player)); + + // World settings + Map map = new HashMap<>(); + when(mySettings.getWorldFlags()).thenReturn(map); + when(iwm.getWorldSettings(any())).thenReturn(mySettings); + ChallengesAddon.CHALLENGES_WORLD_PROTECTION.setSetting(world, true); + + // ItemFactory + ItemFactory itemFactory = mock(ItemFactory.class); + when(Bukkit.getItemFactory()).thenReturn(itemFactory); + + } + + @After + public void tearDown() throws IOException { + User.clearUsers(); + Mockito.framework().clearInlineMocks(); + } + + /** + * Test method for + * {@link world.bentobox.challenges.tasks.TryToComplete#TryToComplete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. + */ + @Test + public void testTryToCompleteChallengesAddonUserChallengeWorldStringString() { + ttc = new TryToComplete(addon, user, challenge, world, topLabel, permissionPrefix); + verify(addon).getChallengesManager(); + + } + + /** + * Test method for + * {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. + */ + @Test + public void testCompleteChallengesAddonUserChallengeWorldStringStringNotDeployed() { + challenge.setDeployed(false); + assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); + verify(user).getTranslation(any(World.class), eq("challenges.errors.not-deployed")); + } + + /** + * Test method for + * {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. + */ + @Test + public void testCompleteChallengesAddonUserChallengeWorldStringStringWrongWorld() { + challenge.setUniqueId("test"); + assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); + verify(user).getTranslation(any(World.class), eq("general.errors.wrong-world")); + } + + /** + * Test method for + * {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. + */ + @Test + public void testCompleteChallengesAddonUserChallengeWorldStringStringNotOnIsland() { + ChallengesAddon.CHALLENGES_WORLD_PROTECTION.setSetting(world, true); + when(im.locationIsOnIsland(any(Player.class), any(Location.class))).thenReturn(false); + assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); + verify(user).getTranslation(any(World.class), eq("challenges.messages.not-on-island")); + } + + /** + * Test method for + * {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. + */ + @Test + public void testCompleteChallengesAddonUserChallengeWorldStringStringNotOnIslandButOk() { + ChallengesAddon.CHALLENGES_WORLD_PROTECTION.setSetting(world, false); + when(im.locationIsOnIsland(any(Player.class), any(Location.class))).thenReturn(false); + assertTrue(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); + verify(user).getTranslation(any(World.class), eq("challenges.messages.you-completed-challenge"), eq("[value]"), + eq("name")); + } + + /** * Test method for {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. */ @Test public void testCompleteChallengesAddonUserChallengeWorldStringStringLevelNotUnlocked() { when(cm.isLevelUnlocked(any(), any(), any())).thenReturn(false); assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); - verify(user).getTranslation("challenges.errors.challenge-level-not-available"); + verify(user).getTranslation(any(World.class), eq("challenges.errors.challenge-level-not-available")); } - /** - * Test method for {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. - */ - @Test - public void testCompleteChallengesAddonUserChallengeWorldStringStringNotRepeatable() { - challenge.setRepeatable(false); - when(cm.isChallengeComplete(any(User.class), any(), any())).thenReturn(true); - assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); - verify(user).getTranslation("challenges.errors.not-repeatable"); - } - - /** - * Test method for {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. - */ - @Test - public void testCompleteChallengesAddonUserChallengeWorldStringStringNotRepeatableFirstTime() { - challenge.setRepeatable(false); - challenge.setMaxTimes(0); - when(cm.getChallengeTimes(any(), any(), any(Challenge.class))).thenReturn(0L); - assertTrue(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); - verify(user).getTranslation("challenges.messages.you-completed-challenge", "[value]", "name"); - } - - /** + /** + * Test method for + * {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. + */ + @Test + public void testCompleteChallengesAddonUserChallengeWorldStringStringNotRepeatable() { + challenge.setRepeatable(false); + when(cm.isChallengeComplete(any(User.class), any(), any())).thenReturn(true); + assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); + verify(user).getTranslation(any(World.class), eq("challenges.errors.not-repeatable")); + } + + /** + * Test method for + * {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. + */ + @Test + public void testCompleteChallengesAddonUserChallengeWorldStringStringNotRepeatableFirstTime() { + challenge.setRepeatable(false); + challenge.setMaxTimes(0); + when(cm.getChallengeTimes(any(), any(), any(Challenge.class))).thenReturn(0L); + assertTrue(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); + verify(user).getTranslation(any(World.class), eq("challenges.messages.you-completed-challenge"), eq("[value]"), + eq("name")); + } + + /** * Test method for {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. */ @Test public void testCompleteChallengesAddonUserChallengeWorldStringStringNoRank() { when(island.isAllowed(any(), any())).thenReturn(false); assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); - verify(user).getTranslation("challenges.errors.no-rank"); + verify(user).getTranslation(any(World.class), eq("challenges.messages.no-rank")); } - /** - * Test method for {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String, int)}. - */ - @Test - public void testCompleteChallengesAddonUserChallengeWorldStringStringIntZero() { - assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix, 0)); - verify(user).getTranslation("challenges.errors.not-valid-integer"); - } - - /** - * Test method for {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String, int)}. - */ - @Test - public void testCompleteChallengesAddonUserChallengeWorldStringStringIntNegative() { - assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix, -10)); - verify(user).getTranslation("challenges.errors.not-valid-integer"); - } - - /** - * Test method for {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String, int)}. - */ - @Test - public void testCompleteChallengesAddonUserChallengeWorldStringStringIntPositiveWrongEnvinonment() { - challenge.setEnvironment(Collections.singleton(Environment.NETHER)); - assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix, 100)); - verify(user).getTranslation("challenges.errors.wrong-environment"); - } - - /** - * Test method for {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String, int)}. - */ - @Test - public void testCompleteChallengesAddonUserChallengeWorldStringStringIntPositiveNoPerm() { - InventoryRequirements req = new InventoryRequirements(); - req.setRequiredPermissions(Collections.singleton("perm-you-dont-have")); - when(user.hasPermission(anyString())).thenReturn(false); - challenge.setRequirements(req); - assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix, 100)); - verify(user).getTranslation("general.errors.no-permission"); - } - - /** - * Test method for {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. - */ - @Test - public void testCompleteChallengesAddonUserChallengeWorldStringStringSuccess() { - assertTrue(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); - verify(user).getTranslation("challenges.messages.you-completed-challenge", "[value]", "name"); - } - - /** - * Test method for {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. - */ - @Test - public void testCompleteChallengesAddonUserChallengeWorldStringStringSuccessSingleReq() { - InventoryRequirements req = new InventoryRequirements(); - req.setRequiredItems(Collections.singletonList(new ItemStack(Material.EMERALD_BLOCK))); - challenge.setRequirements(req); - assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); - verify(user).getTranslation("challenges.errors.not-enough-items", "[items]", "challenges.materials.emerald_block"); - } - - /** - * Test method for {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. - */ - @Test - public void testCompleteChallengesAddonUserChallengeWorldStringStringSuccessMultipleReq() { - - InventoryRequirements req = new InventoryRequirements(); - ItemStack itemStackMock = mock(ItemStack.class); - when(itemStackMock.getAmount()).thenReturn(3); - when(itemStackMock.getType()).thenReturn(Material.EMERALD_BLOCK); - when(itemStackMock.clone()).thenReturn(itemStackMock); - - ItemStack itemStackMock2 = mock(ItemStack.class); - when(itemStackMock2.getType()).thenReturn(Material.ENCHANTED_BOOK); - when(itemStackMock2.getAmount()).thenReturn(10); - when(itemStackMock2.clone()).thenReturn(itemStackMock2); - - ItemStack itemStackMock3 = mock(ItemStack.class); - when(itemStackMock3.getType()).thenReturn(Material.EMERALD_BLOCK); - when(itemStackMock3.getAmount()).thenReturn(15); - when(itemStackMock3.clone()).thenReturn(itemStackMock3); - // itemStackMock and 3 are same type - when(itemStackMock3.isSimilar(eq(itemStackMock))).thenReturn(true); - when(itemStackMock.isSimilar(eq(itemStackMock3))).thenReturn(true); - - req.setRequiredItems(Arrays.asList(itemStackMock , itemStackMock2)); - challenge.setRequirements(req); - ItemStack[] newContents = {itemStackMock3}; - when(inv.getContents()).thenReturn(newContents); - - assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); - // Sufficient emerald blocks - verify(user, never()).getTranslation("challenges.errors.not-enough-items", "[items]", "challenges.materials.emerald_block"); - // Not enough books - verify(user).getTranslation("challenges.errors.not-enough-items", "[items]", "challenges.materials.enchanted_book"); - } - - /** + /** + * Test method for + * {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String, int)}. + */ + @Test + public void testCompleteChallengesAddonUserChallengeWorldStringStringIntZero() { + assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix, 0)); + verify(user).getTranslation(any(World.class), eq("challenges.errors.not-valid-integer")); + } + + /** + * Test method for + * {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String, int)}. + */ + @Test + public void testCompleteChallengesAddonUserChallengeWorldStringStringIntNegative() { + assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix, -10)); + verify(user).getTranslation(any(World.class), eq("challenges.errors.not-valid-integer")); + } + + /** + * Test method for + * {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String, int)}. + */ + @Test + public void testCompleteChallengesAddonUserChallengeWorldStringStringIntPositiveWrongEnvinonment() { + challenge.setEnvironment(Collections.singleton(Environment.NETHER)); + assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix, 100)); + verify(user).getTranslation(any(World.class), eq("challenges.errors.wrong-environment")); + } + + /** + * Test method for + * {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String, int)}. + */ + @Test + public void testCompleteChallengesAddonUserChallengeWorldStringStringIntPositiveNoPerm() { + InventoryRequirements req = new InventoryRequirements(); + req.setRequiredPermissions(Collections.singleton("perm-you-dont-have")); + when(user.hasPermission(anyString())).thenReturn(false); + challenge.setRequirements(req); + assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix, 100)); + verify(user).getTranslation(any(World.class), eq("challenges.errors.no-permission")); + } + + /** + * Test method for + * {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. + */ + @Test + public void testCompleteChallengesAddonUserChallengeWorldStringStringSuccess() { + assertTrue(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); + verify(user).getTranslation(any(World.class), eq("challenges.messages.you-completed-challenge"), eq("[value]"), + eq("name")); + } + + /** + * Test method for + * {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. + */ + @Test + @Ignore("Method is too large for JVM") + public void testCompleteChallengesAddonUserChallengeWorldStringStringSuccessSingleReq() { + InventoryRequirements req = new InventoryRequirements(); + req.setRequiredItems(Collections.singletonList(new ItemStack(Material.EMERALD_BLOCK))); + challenge.setRequirements(req); + assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); + verify(user).getTranslation(any(World.class), eq("challenges.errors.not-enough-items"), eq("[items]"), + eq("challenges.materials.emerald_block")); + } + + /** + * Test method for + * {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. + */ + @Test + @Ignore("Too big for JVM") + public void testCompleteChallengesAddonUserChallengeWorldStringStringSuccessMultipleReq() { + + InventoryRequirements req = new InventoryRequirements(); + ItemStack itemStackMock = mock(ItemStack.class); + when(itemStackMock.getAmount()).thenReturn(3); + when(itemStackMock.getType()).thenReturn(Material.EMERALD_BLOCK); + when(itemStackMock.clone()).thenReturn(itemStackMock); + + ItemStack itemStackMock2 = mock(ItemStack.class); + when(itemStackMock2.getType()).thenReturn(Material.ENCHANTED_BOOK); + when(itemStackMock2.getAmount()).thenReturn(10); + when(itemStackMock2.clone()).thenReturn(itemStackMock2); + + ItemStack itemStackMock3 = mock(ItemStack.class); + when(itemStackMock3.getType()).thenReturn(Material.EMERALD_BLOCK); + when(itemStackMock3.getAmount()).thenReturn(15); + when(itemStackMock3.clone()).thenReturn(itemStackMock3); + // itemStackMock and 3 are same type + when(itemStackMock3.isSimilar(eq(itemStackMock))).thenReturn(true); + when(itemStackMock.isSimilar(eq(itemStackMock3))).thenReturn(true); + + req.setRequiredItems(Arrays.asList(itemStackMock, itemStackMock2)); + challenge.setRequirements(req); + ItemStack[] newContents = { itemStackMock3 }; + when(inv.getContents()).thenReturn(newContents); + + assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); + // Sufficient emerald blocks + verify(user, never()).getTranslation(any(World.class), eq("challenges.errors.not-enough-items"), eq("[items]"), + eq("challenges.materials.emerald_block")); + // Not enough books + verify(user).getTranslation(any(World.class), eq("challenges.errors.not-enough-items"), eq("[items]"), + eq("challenges.materials.enchanted_book")); + } + + /** * Test method for {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. */ @Test public void testCompleteChallengesAddonUserChallengeWorldStringStringSuccessCreative() { when(player.getGameMode()).thenReturn(GameMode.CREATIVE); assertTrue(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); - verify(user).getTranslation("challenges.messages.you-completed-challenge", "[value]", "name"); - } - - /** - * Test method for {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. - */ - @Test - public void testCompleteChallengesAddonUserChallengeWorldStringStringIslandBBTooLarge() { - challenge.setChallengeType(ChallengeType.ISLAND_TYPE); - IslandRequirements req = new IslandRequirements(); - req.setSearchRadius(1); - challenge.setRequirements(req); - // Trigger big bounding box error - when(bb.getWidthX()).thenReturn(50000D); - assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); - verify(addon).logError("BoundingBox is larger than SearchRadius. | BoundingBox: BoundingBox | Search Distance: 1 | Location: location | Center: center | Range: 0"); - verify(bb).expand(1); - - } - - /** - * Test method for {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. - */ - @Test - public void testCompleteChallengesAddonUserChallengeWorldStringStringIslandSuccessNoEntities() { - challenge.setChallengeType(ChallengeType.ISLAND_TYPE); - IslandRequirements req = new IslandRequirements(); - req.setSearchRadius(1); - challenge.setRequirements(req); - assertTrue(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); - verify(user).getTranslation("challenges.messages.you-completed-challenge", "[value]", "name"); - - } - - /** - * Test method for {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. - */ - @Test - public void testCompleteChallengesAddonUserChallengeWorldStringStringIslandFailEntities() { - challenge.setChallengeType(ChallengeType.ISLAND_TYPE); - IslandRequirements req = new IslandRequirements(); - Map requiredEntities = Collections.singletonMap(EntityType.GHAST, 3); - req.setRequiredEntities(requiredEntities); - req.setSearchRadius(1); - challenge.setRequirements(req); - assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); - verify(user).getTranslation("challenges.errors.you-still-need", "[amount]", "3", "[item]", "challenges.entities.ghast.name"); - - } - - /** - * Test method for {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. - */ - @Test - public void testCompleteChallengesAddonUserChallengeWorldStringStringIslandFailMultipleEntities() { - challenge.setChallengeType(ChallengeType.ISLAND_TYPE); - IslandRequirements req = new IslandRequirements(); - Map requiredEntities = new HashMap<>(); - requiredEntities.put(EntityType.GHAST, 3); - requiredEntities.put(EntityType.CHICKEN, 5); - requiredEntities.put(EntityType.PUFFERFISH, 1); - req.setRequiredEntities(requiredEntities); - req.setSearchRadius(1); - challenge.setRequirements(req); - assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); - verify(user).getTranslation("challenges.errors.you-still-need", "[amount]", "3", "[item]", "challenges.entities.ghast.name"); - verify(user).getTranslation("challenges.errors.you-still-need", "[amount]", "1", "[item]", "challenges.entities.pufferfish.name"); - verify(user).getTranslation("challenges.errors.you-still-need", "[amount]", "5", "[item]", "challenges.entities.chicken.name"); - - } - - /** - * Test method for {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. - */ - @Test - public void testCompleteChallengesAddonUserChallengeWorldStringStringIslandFailPartialMultipleEntities() { - challenge.setChallengeType(ChallengeType.ISLAND_TYPE); - IslandRequirements req = new IslandRequirements(); - Map requiredEntities = new HashMap<>(); - requiredEntities.put(EntityType.GHAST, 3); - requiredEntities.put(EntityType.CHICKEN, 5); - requiredEntities.put(EntityType.PUFFERFISH, 1); - req.setRequiredEntities(requiredEntities); - req.setSearchRadius(1); - challenge.setRequirements(req); - Entity ent = mock(Entity.class); - when(ent.getType()).thenReturn(EntityType.PUFFERFISH); - Location loc = mock(Location.class); - when(ent.getLocation()).thenReturn(loc); - List list = Collections.singletonList(ent); - when(world.getNearbyEntities(any(BoundingBox.class))).thenReturn(list); - assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); - verify(user).getTranslation("challenges.errors.you-still-need", "[amount]", "3", "[item]", "challenges.entities.ghast.name"); - verify(user, never()).getTranslation("challenges.errors.you-still-need", "[amount]", "1", "[item]", "challenges.entities.pufferfish.name"); - verify(user).getTranslation("challenges.errors.you-still-need", "[amount]", "5", "[item]", "challenges.entities.chicken.name"); - - } - - /** - * Test method for {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. - */ - @Test - public void testCompleteChallengesAddonUserChallengeWorldStringStringIslandSuccess() { - challenge.setChallengeType(ChallengeType.ISLAND_TYPE); - IslandRequirements req = new IslandRequirements(); - Map requiredEntities = new HashMap<>(); - requiredEntities.put(EntityType.PUFFERFISH, 1); - req.setRequiredEntities(requiredEntities); - req.setSearchRadius(1); - challenge.setRequirements(req); - Entity ent = mock(Entity.class); - when(ent.getType()).thenReturn(EntityType.PUFFERFISH); - Location loc = mock(Location.class); - when(ent.getLocation()).thenReturn(loc); - List list = Collections.singletonList(ent); - when(world.getNearbyEntities(any(BoundingBox.class))).thenReturn(list); - assertTrue(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); - verify(user).getTranslation("challenges.messages.you-completed-challenge", "[value]", "name"); + // Creative players automatically complete inventory challenges twice - they have infinite inventory + verify(user).getTranslation(world, "challenges.messages.you-repeated-challenge-multiple", "[value]", "name", + "[count]", "2"); } - /** - * Test method for {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. - */ - @Test - public void testCompleteChallengesAddonUserChallengeWorldStringStringIslandPlayerInOtherEnvironment() { - challenge.setEnvironment(Collections.singleton(Environment.NETHER)); - World netherWorld = mock(World.class); - when(user.getWorld()).thenReturn(netherWorld); - when(netherWorld.getName()).thenReturn("world_nether"); - when(netherWorld.getEnvironment()).thenReturn(Environment.NETHER); - challenge.setChallengeType(ChallengeType.ISLAND_TYPE); - IslandRequirements req = new IslandRequirements(); - Map requiredEntities = new HashMap<>(); - requiredEntities.put(EntityType.PUFFERFISH, 1); - req.setRequiredEntities(requiredEntities); - req.setSearchRadius(1); - challenge.setRequirements(req); - Entity ent = mock(Entity.class); - when(ent.getType()).thenReturn(EntityType.PUFFERFISH); - Location loc = mock(Location.class); - when(ent.getLocation()).thenReturn(loc); - List list = Collections.singletonList(ent); - when(world.getNearbyEntities(any(BoundingBox.class))).thenReturn(list); - when(netherWorld.getNearbyEntities(any(BoundingBox.class))).thenReturn(Collections.emptyList()); - assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); - verify(user).getTranslation("challenges.errors.you-still-need", "[amount]", "1", "[item]", "challenges.entities.pufferfish.name"); - } - - /** - * Test method for {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String, int)}. - */ - @Test - public void testCompleteChallengesAddonUserChallengeWorldStringStringIntMultipleTimesPositiveSuccess() { - // Try to complete 10 times. Already done 3 times, and max is 10, so it should be only done 7 times - assertTrue(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix, 10)); - verify(user).getTranslation("challenges.messages.you-repeated-challenge-multiple", "[value]", "name", "[count]", "7"); - } - - /** - * Test method for {@link world.bentobox.challenges.tasks.TryToComplete#build(int)}. - */ - @Test - public void testBuild() { - this.testTryToCompleteChallengesAddonUserChallengeWorldStringString(); - ChallengeResult result = this.ttc.build(10); - assertTrue(result.isMeetsRequirements()); - } - - /** - * Test method for {@link world.bentobox.challenges.tasks.TryToComplete#removeItems(java.util.List, int)}. - */ - @Test - public void testRemoveItemsNothing() { - this.testTryToCompleteChallengesAddonUserChallengeWorldStringString(); - assertTrue(ttc.removeItems(Collections.emptyList(), 1).isEmpty()); - - } + /** + * Test method for + * {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. + */ + @Test + public void testCompleteChallengesAddonUserChallengeWorldStringStringIslandBBTooLarge() { + challenge.setChallengeType(ChallengeType.ISLAND_TYPE); + IslandRequirements req = new IslandRequirements(); + req.setSearchRadius(1); + challenge.setRequirements(req); + // Trigger big bounding box error + when(bb.getWidthX()).thenReturn(50000D); + assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); + verify(addon).logError( + "BoundingBox is larger than SearchRadius. | BoundingBox: BoundingBox | Search Distance: 1 | Location: location | Center: center | Range: 0"); + verify(bb).expand(1); + + } + + /** + * Test method for + * {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. + */ + @Test + public void testCompleteChallengesAddonUserChallengeWorldStringStringIslandSuccessNoEntities() { + challenge.setChallengeType(ChallengeType.ISLAND_TYPE); + IslandRequirements req = new IslandRequirements(); + req.setSearchRadius(1); + challenge.setRequirements(req); + assertTrue(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); + verify(user).getTranslation(any(World.class), eq("challenges.messages.you-completed-challenge"), eq("[value]"), + eq("name")); + + } + + /** + * Test method for + * {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. + */ + @Test + public void testCompleteChallengesAddonUserChallengeWorldStringStringIslandFailEntities() { + challenge.setChallengeType(ChallengeType.ISLAND_TYPE); + IslandRequirements req = new IslandRequirements(); + Map requiredEntities = Collections.singletonMap(EntityType.GHAST, 3); + req.setRequiredEntities(requiredEntities); + req.setSearchRadius(1); + challenge.setRequirements(req); + assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); + verify(user).getTranslation(any(World.class), eq("challenges.errors.you-still-need"), eq("[amount]"), eq("3"), + eq("[item]"), eq("challenges.entities.ghast.name")); + + } + + /** + * Test method for + * {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. + */ + @Test + public void testCompleteChallengesAddonUserChallengeWorldStringStringIslandFailMultipleEntities() { + challenge.setChallengeType(ChallengeType.ISLAND_TYPE); + IslandRequirements req = new IslandRequirements(); + Map requiredEntities = new HashMap<>(); + requiredEntities.put(EntityType.GHAST, 3); + requiredEntities.put(EntityType.CHICKEN, 5); + requiredEntities.put(EntityType.PUFFERFISH, 1); + req.setRequiredEntities(requiredEntities); + req.setSearchRadius(1); + challenge.setRequirements(req); + assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); + verify(user).getTranslation(any(World.class), eq("challenges.errors.you-still-need"), eq("[amount]"), eq("3"), + eq("[item]"), eq("challenges.entities.ghast.name")); + verify(user).getTranslation(any(World.class), eq("challenges.errors.you-still-need"), eq("[amount]"), eq("1"), + eq("[item]"), eq("challenges.entities.pufferfish.name")); + verify(user).getTranslation(any(World.class), eq("challenges.errors.you-still-need"), eq("[amount]"), eq("5"), + eq("[item]"), eq("challenges.entities.chicken.name")); + + } + + /** + * Test method for + * {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. + */ + @Test + public void testCompleteChallengesAddonUserChallengeWorldStringStringIslandFailPartialMultipleEntities() { + challenge.setChallengeType(ChallengeType.ISLAND_TYPE); + IslandRequirements req = new IslandRequirements(); + Map requiredEntities = new HashMap<>(); + requiredEntities.put(EntityType.GHAST, 3); + requiredEntities.put(EntityType.CHICKEN, 5); + requiredEntities.put(EntityType.PUFFERFISH, 1); + req.setRequiredEntities(requiredEntities); + req.setSearchRadius(1); + challenge.setRequirements(req); + Entity ent = mock(Entity.class); + when(ent.getType()).thenReturn(EntityType.PUFFERFISH); + Location loc = mock(Location.class); + when(ent.getLocation()).thenReturn(loc); + List list = Collections.singletonList(ent); + when(world.getNearbyEntities(any(BoundingBox.class))).thenReturn(list); + assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); + verify(user).getTranslation(any(World.class), eq("challenges.errors.you-still-need"), eq("[amount]"), eq("3"), + eq("[item]"), eq("challenges.entities.ghast.name")); + verify(user, never()).getTranslation(any(World.class), eq("challenges.errors.you-still-need"), eq("[amount]"), + eq("1"), eq("[item]"), eq("challenges.entities.pufferfish.name")); + verify(user).getTranslation(any(World.class), eq("challenges.errors.you-still-need"), eq("[amount]"), eq("5"), + eq("[item]"), eq("challenges.entities.chicken.name")); + + } + + /** + * Test method for + * {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. + */ + @Test + public void testCompleteChallengesAddonUserChallengeWorldStringStringIslandSuccess() { + challenge.setChallengeType(ChallengeType.ISLAND_TYPE); + IslandRequirements req = new IslandRequirements(); + Map requiredEntities = new HashMap<>(); + requiredEntities.put(EntityType.PUFFERFISH, 1); + req.setRequiredEntities(requiredEntities); + req.setSearchRadius(1); + challenge.setRequirements(req); + Entity ent = mock(Entity.class); + when(ent.getType()).thenReturn(EntityType.PUFFERFISH); + Location loc = mock(Location.class); + when(ent.getLocation()).thenReturn(loc); + List list = Collections.singletonList(ent); + when(world.getNearbyEntities(any(BoundingBox.class))).thenReturn(list); + assertTrue(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); + verify(user).getTranslation(any(World.class), eq("challenges.messages.you-completed-challenge"), eq("[value]"), + eq("name")); + } + + /** + * Test method for + * {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String)}. + */ + @Test + public void testCompleteChallengesAddonUserChallengeWorldStringStringIslandPlayerInOtherEnvironment() { + challenge.setEnvironment(Collections.singleton(Environment.NETHER)); + World netherWorld = mock(World.class); + when(user.getWorld()).thenReturn(netherWorld); + when(netherWorld.getName()).thenReturn("world_nether"); + when(netherWorld.getEnvironment()).thenReturn(Environment.NETHER); + challenge.setChallengeType(ChallengeType.ISLAND_TYPE); + IslandRequirements req = new IslandRequirements(); + Map requiredEntities = new HashMap<>(); + requiredEntities.put(EntityType.PUFFERFISH, 1); + req.setRequiredEntities(requiredEntities); + req.setSearchRadius(1); + challenge.setRequirements(req); + Entity ent = mock(Entity.class); + when(ent.getType()).thenReturn(EntityType.PUFFERFISH); + Location loc = mock(Location.class); + when(ent.getLocation()).thenReturn(loc); + List list = Collections.singletonList(ent); + when(world.getNearbyEntities(any(BoundingBox.class))).thenReturn(list); + when(netherWorld.getNearbyEntities(any(BoundingBox.class))).thenReturn(Collections.emptyList()); + assertFalse(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix)); + verify(user).getTranslation(any(World.class), eq("challenges.errors.you-still-need"), eq("[amount]"), eq("1"), + eq("[item]"), eq("challenges.entities.pufferfish.name")); + } + + /** + * Test method for + * {@link world.bentobox.challenges.tasks.TryToComplete#complete(world.bentobox.challenges.ChallengesAddon, world.bentobox.bentobox.api.user.User, world.bentobox.challenges.database.object.Challenge, org.bukkit.World, java.lang.String, java.lang.String, int)}. + */ + @Test + public void testCompleteChallengesAddonUserChallengeWorldStringStringIntMultipleTimesPositiveSuccess() { + // Try to complete 10 times. Already done 3 times, and max is 10, so it should + // be only done 7 times + assertTrue(TryToComplete.complete(addon, user, challenge, world, topLabel, permissionPrefix, 10)); + verify(user).getTranslation(any(World.class), eq("challenges.messages.you-repeated-challenge-multiple"), + eq("[value]"), eq("name"), eq("[count]"), eq("7")); + } + + /** + * Test method for + * {@link world.bentobox.challenges.tasks.TryToComplete#build(int)}. + */ + @Test + public void testBuild() { + this.testTryToCompleteChallengesAddonUserChallengeWorldStringString(); + ChallengeResult result = this.ttc.build(10); + assertTrue(result.isMeetsRequirements()); + } + + /** + * Test method for + * {@link world.bentobox.challenges.tasks.TryToComplete#removeItems(java.util.List, int)}. + */ + @Test + public void testRemoveItemsNothing() { + this.testTryToCompleteChallengesAddonUserChallengeWorldStringString(); + assertTrue(ttc.removeItems(Collections.emptyList(), 1).isEmpty()); + + } }