diff --git a/pom.xml b/pom.xml index ff48b54..921eb99 100644 --- a/pom.xml +++ b/pom.xml @@ -32,7 +32,7 @@ UTF-8 UTF-8 - 16 + 17 2.0.9 1.17.1-R0.1-SNAPSHOT diff --git a/src/main/java/world/bentobox/challenges/ChallengesAddon.java b/src/main/java/world/bentobox/challenges/ChallengesAddon.java index 1882d57..ee9340b 100644 --- a/src/main/java/world/bentobox/challenges/ChallengesAddon.java +++ b/src/main/java/world/bentobox/challenges/ChallengesAddon.java @@ -408,8 +408,18 @@ public class ChallengesAddon extends Addon { addonName + "_latest_level_uncompleted_count", user -> { ChallengeLevel level = this.challengesManager.getLatestUnlockedLevel(user, world); - return String.valueOf(level != null ? - level.getChallenges().size() - this.challengesManager.getLevelCompletedChallengeCount(user, world, level) : 0); + + if (level == null) + { + return "0"; + } + + int challengeCount = this.getChallengesSettings().isIncludeUndeployed() ? + level.getChallenges().size() : + this.challengesManager.getLevelChallenges(level, false).size(); + + return String.valueOf(challengeCount - + this.challengesManager.getLevelCompletedChallengeCount(user, world, level)); }); } diff --git a/src/main/java/world/bentobox/challenges/config/Settings.java b/src/main/java/world/bentobox/challenges/config/Settings.java index 237fe12..a859403 100644 --- a/src/main/java/world/bentobox/challenges/config/Settings.java +++ b/src/main/java/world/bentobox/challenges/config/Settings.java @@ -106,11 +106,10 @@ public class Settings implements ConfigObject @ConfigComment("Valid values are:") @ConfigComment(" 'VISIBLE' - there will be no hidden challenges. All challenges will be viewable in GUI.") @ConfigComment(" 'HIDDEN' - shows only deployed challenges.") - @ConfigComment(" 'TOGGLEABLE' - there will be button in GUI that allows users to switch from ALL modes.") - @ConfigComment("TOGGLEABLE - Currently not implemented.") @ConfigEntry(path = "gui-settings.undeployed-view-mode") private VisibilityMode visibilityMode = VisibilityMode.VISIBLE; + @ConfigComment("") @ConfigComment("This allows to change default locked level icon. This option may be") @ConfigComment("overwritten by each challenge level. If challenge level has specified") @@ -130,6 +129,13 @@ public class Settings implements ConfigObject @ConfigEntry(path = "reset-challenges") private boolean resetChallenges = true; + @ConfigComment("") + @ConfigComment("This option indicates if undepolyed challenges should be counted to level completion.") + @ConfigComment("Disabling this option will make it so that only deployed challenges will be counted.") + @ConfigComment("Default: true") + @ConfigEntry(path = "include-undeployed") + private boolean includeUndeployed = true; + @ConfigComment("") @ConfigComment("Broadcast 1st time challenge completion messages to all players.") @ConfigComment("Change to false if the spam becomes too much.") @@ -165,7 +171,7 @@ public class Settings implements ConfigObject * Configuration version */ @ConfigComment("") - private String configVersion = "v3"; + private String configVersion = "v4"; // --------------------------------------------------------------------- @@ -597,4 +603,26 @@ public class Settings implements ConfigObject { this.visibilityMode = visibilityMode; } + + + /** + * Is count undeployed to completion boolean. + * + * @return the boolean + */ + public boolean isIncludeUndeployed() + { + return includeUndeployed; + } + + + /** + * Sets count undeployed to completion. + * + * @param includeUndeployed the count undeployed to completion + */ + public void setIncludeUndeployed(boolean includeUndeployed) + { + this.includeUndeployed = includeUndeployed; + } } diff --git a/src/main/java/world/bentobox/challenges/managers/ChallengesManager.java b/src/main/java/world/bentobox/challenges/managers/ChallengesManager.java index 9a83176..39d6889 100644 --- a/src/main/java/world/bentobox/challenges/managers/ChallengesManager.java +++ b/src/main/java/world/bentobox/challenges/managers/ChallengesManager.java @@ -1126,11 +1126,20 @@ public class ChallengesManager // know how many challenges there were and how many has been done. Then // remove waiver amount to get count of challenges that still necessary to do. + List previousChallengeList = previousLevel == null ? + Collections.emptyList() : + this.getLevelChallenges(previousLevel); + int challengesToDo = previousLevel == null ? 0 : - (previousLevel.getChallenges().size() - doneChallengeCount - previousLevel.getWaiverAmount()); + (previousChallengeList.size() - doneChallengeCount - previousLevel.getWaiverAmount()); + + List challengeList = this.getLevelChallenges(level); // As level already contains unique ids of challenges, just iterate through them. - doneChallengeCount = (int) level.getChallenges().stream().filter(playerData::isChallengeDone).count(); + doneChallengeCount = (int) challengeList.stream(). + map(Challenge::getUniqueId). + filter(playerData::isChallengeDone). + count(); // Mark if level is unlocked boolean unlocked = previousUnlocked && challengesToDo <= 0; @@ -1139,7 +1148,7 @@ public class ChallengesManager level, previousLevel, challengesToDo, - level.getChallenges().size() == doneChallengeCount, + challengeList.size() == doneChallengeCount, unlocked)); previousLevel = level; @@ -1175,18 +1184,27 @@ public class ChallengesManager { ChallengeLevel previousLevel = levelIndex < 1 ? null : challengeLevelList.get(levelIndex - 1); + List previousChallengeList = previousLevel == null ? Collections.emptyList() : + this.getLevelChallenges(previousLevel); + int challengesToDo = previousLevel == null ? 0 : - (previousLevel.getChallenges().size() - previousLevel.getWaiverAmount()) - - (int) previousLevel.getChallenges().stream().filter(playerData::isChallengeDone).count(); + (previousChallengeList.size() - previousLevel.getWaiverAmount()) - + (int) previousChallengeList.stream().map(Challenge::getUniqueId). + filter(playerData::isChallengeDone).count(); + + List challengeList = this.getLevelChallenges(level); // As level already contains unique ids of challenges, just iterate through them. - int doneChallengeCount = (int) level.getChallenges().stream().filter(playerData::isChallengeDone).count(); + int doneChallengeCount = (int) challengeList.stream(). + map(Challenge::getUniqueId). + filter(playerData::isChallengeDone). + count(); return new LevelStatus( level, previousLevel, challengesToDo, - level.getChallenges().size() == doneChallengeCount, + challengeList.size() == doneChallengeCount, challengesToDo <= 0); } } @@ -1214,9 +1232,15 @@ public class ChallengesManager { this.addPlayerData(storageDataID); ChallengesPlayerData playerData = this.playerCacheData.get(storageDataID); - long doneChallengeCount = level.getChallenges().stream().filter(playerData::isChallengeDone).count(); - return level.getChallenges().size() == doneChallengeCount; + List challengeList = this.getLevelChallenges(level); + + long doneChallengeCount = challengeList.stream(). + map(Challenge::getUniqueId). + filter(playerData::isChallengeDone). + count(); + + return challengeList.size() == doneChallengeCount; } @@ -1775,11 +1799,11 @@ public class ChallengesManager { // Free Challenges hides under FREE level. return this.islandWorldManager.getAddon(world).map(gameMode -> - this.challengeCacheData.values().stream(). - filter(challenge -> challenge.getLevel().equals(FREE) && - challenge.matchGameMode(gameMode.getDescription().getName())). - sorted(Comparator.comparing(Challenge::getOrder)). - collect(Collectors.toList())). + this.challengeCacheData.values().stream(). + filter(challenge -> challenge.getLevel().equals(FREE) && + challenge.matchGameMode(gameMode.getDescription().getName())). + sorted(Comparator.comparing(Challenge::getOrder)). + collect(Collectors.toList())). orElse(Collections.emptyList()); } @@ -1790,10 +1814,24 @@ public class ChallengesManager * @return List with challenges in given level. */ public List getLevelChallenges(ChallengeLevel level) + { + return this.getLevelChallenges(level, + this.addon.getChallengesSettings().isIncludeUndeployed()); + } + + + /** + * Level which challenges must be received + * @param level Challenge level. + * @param includeUndeployed if true, then include challenges that are not deployed. + * @return List with challenges in given level. + */ + public List getLevelChallenges(ChallengeLevel level, boolean includeUndeployed) { return level.getChallenges().stream(). map(this::getChallenge). filter(Objects::nonNull). + filter(challenge -> includeUndeployed || challenge.isDeployed()). sorted(Comparator.comparing(Challenge::getOrder)). collect(Collectors.toList()); } @@ -1912,7 +1950,9 @@ public class ChallengesManager */ public int getChallengeCount(World world) { - return this.getAllChallenges(world).size(); + return (int) this.getAllChallenges(world).stream(). + filter(challenge -> this.settings.isIncludeUndeployed() || challenge.isDeployed()). + count(); } diff --git a/src/main/java/world/bentobox/challenges/panel/CommonPanel.java b/src/main/java/world/bentobox/challenges/panel/CommonPanel.java index 60426a3..14fb725 100644 --- a/src/main/java/world/bentobox/challenges/panel/CommonPanel.java +++ b/src/main/java/world/bentobox/challenges/panel/CommonPanel.java @@ -942,14 +942,17 @@ public abstract class CommonPanel else { ChallengeLevel level = levelStatus.getLevel(); + List challengeList = this.addon.getChallengesManager().getLevelChallenges(level); + // Check if unlock message should appear. - int doneChallenges = (int) level.getChallenges().stream(). + 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(level.getChallenges().size())); + "[max]", String.valueOf(challengeList.size())); } } diff --git a/src/main/java/world/bentobox/challenges/panel/admin/EditLevelPanel.java b/src/main/java/world/bentobox/challenges/panel/admin/EditLevelPanel.java index 826e4c8..07af626 100644 --- a/src/main/java/world/bentobox/challenges/panel/admin/EditLevelPanel.java +++ b/src/main/java/world/bentobox/challenges/panel/admin/EditLevelPanel.java @@ -212,7 +212,7 @@ public class EditLevelPanel extends CommonPagedPanel private void buildChallengesPanel(PanelBuilder panelBuilder) { List challengeList = this.addon.getChallengesManager(). - getLevelChallenges(this.challengeLevel).stream(). + getLevelChallenges(this.challengeLevel, true).stream(). filter(challenge -> this.searchString.isBlank() || challenge.getFriendlyName().toLowerCase().contains(this.searchString.toLowerCase()) || challenge.getUniqueId().toLowerCase().contains(this.searchString.toLowerCase()) || @@ -784,7 +784,7 @@ public class EditLevelPanel extends CommonPagedPanel // Get all challenge that is not in current level. List challengeList = manager.getAllChallenges(this.world); - challengeList.removeAll(manager.getLevelChallenges(this.challengeLevel)); + challengeList.removeAll(manager.getLevelChallenges(this.challengeLevel, true)); // Generate descriptions for these challenges Map> challengeDescriptionMap = challengeList.stream(). @@ -820,7 +820,7 @@ public class EditLevelPanel extends CommonPagedPanel ChallengesManager manager = this.addon.getChallengesManager(); // Get all challenge that is in current level. - List challengeList = manager.getLevelChallenges(this.challengeLevel); + List challengeList = manager.getLevelChallenges(this.challengeLevel, true); // Generate descriptions for these challenges Map> challengeDescriptionMap = challengeList.stream(). diff --git a/src/main/java/world/bentobox/challenges/panel/admin/EditSettingsPanel.java b/src/main/java/world/bentobox/challenges/panel/admin/EditSettingsPanel.java index 3d0eed9..840a876 100644 --- a/src/main/java/world/bentobox/challenges/panel/admin/EditSettingsPanel.java +++ b/src/main/java/world/bentobox/challenges/panel/admin/EditSettingsPanel.java @@ -119,6 +119,7 @@ public class EditSettingsPanel extends CommonPanel panelBuilder.item(11, this.getSettingsButton(Button.GLOW_COMPLETED)); panelBuilder.item(20, this.getSettingsButton(Button.REMOVE_COMPLETED)); panelBuilder.item(29, this.getSettingsButton(Button.VISIBILITY_MODE)); + panelBuilder.item(30, this.getSettingsButton(Button.INCLUDE_UNDEPLOYED)); panelBuilder.item(21, this.getSettingsButton(Button.LOCKED_LEVEL_ICON)); @@ -414,9 +415,6 @@ public class EditSettingsPanel extends CommonPanel description.add(this.user.getTranslation(reference + (this.settings.getVisibilityMode().equals(VisibilityMode.HIDDEN) ? "enabled" : "disabled")) + this.user.getTranslation(reference + "hidden")); - description.add(this.user.getTranslation(reference + - (this.settings.getVisibilityMode().equals(VisibilityMode.TOGGLEABLE) ? "enabled" : "disabled")) + - this.user.getTranslation(reference + "toggleable")); if (this.settings.getVisibilityMode().equals(VisibilityMode.VISIBLE)) { @@ -454,6 +452,22 @@ public class EditSettingsPanel extends CommonPanel description.add(this.user.getTranslation(Constants.TIPS + "left-click-to-cycle")); description.add(this.user.getTranslation(Constants.TIPS + "right-click-to-cycle")); } + case INCLUDE_UNDEPLOYED -> { + description.add(this.user.getTranslation(reference + + (this.settings.isIncludeUndeployed() ? "enabled" : "disabled"))); + + icon = new ItemStack(Material.BARREL); + clickHandler = (panel, user1, clickType, i) -> { + this.settings.setIncludeUndeployed(!this.settings.isIncludeUndeployed()); + panel.getInventory().setItem(i, this.getSettingsButton(button).getItem()); + this.addon.saveSettings(); + return true; + }; + glow = this.settings.isIncludeUndeployed(); + + description.add(""); + description.add(this.user.getTranslation(Constants.TIPS + "click-to-toggle")); + } default -> { icon = new ItemStack(Material.PAPER); clickHandler = null; @@ -557,6 +571,10 @@ public class EditSettingsPanel extends CommonPanel LOCKED_LEVEL_ICON, SHOW_TITLE, TITLE_SHOWTIME, + /** + * This allows to switch between counting/not couting undeployed challenges. + */ + INCLUDE_UNDEPLOYED, /** * This allows to switch between different challenges visibility modes. */ diff --git a/src/main/java/world/bentobox/challenges/panel/user/ChallengesPanel.java b/src/main/java/world/bentobox/challenges/panel/user/ChallengesPanel.java index 5c1abf5..4095dc5 100644 --- a/src/main/java/world/bentobox/challenges/panel/user/ChallengesPanel.java +++ b/src/main/java/world/bentobox/challenges/panel/user/ChallengesPanel.java @@ -130,7 +130,7 @@ public class ChallengesPanel extends CommonPanel { if (this.lastSelectedLevel != null) { - this.challengeList = this.manager.getLevelChallenges(this.lastSelectedLevel.getLevel()); + this.challengeList = this.manager.getLevelChallenges(this.lastSelectedLevel.getLevel(), true); if (this.addon.getChallengesSettings().isRemoveCompleteOneTimeChallenges()) { diff --git a/src/main/resources/locales/en-US.yml b/src/main/resources/locales/en-US.yml index 1b8b67b..8d34415 100755 --- a/src/main/resources/locales/en-US.yml +++ b/src/main/resources/locales/en-US.yml @@ -683,6 +683,15 @@ challenges: visible: "Show visible challenges" hidden: "Show all challenges" toggleable: "Allow toggling" + include_undeployed: + name: "&f&l Include Undeployed Challenges" + description: |- + &7 Indicates if undeployed + &7 challenges should be + &7 counted towards level + &7 completion. + enabled: "&2 Enabled" + disabled: "&c Disabled" download: name: "&f&l Download Libraries" description: |-