From ac80a7e7e4d47a91e49b1aaa7d36a9e8d4ab5ad3 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 18 Nov 2018 19:39:14 -0800 Subject: [PATCH] Fix for taking items even if challenge incomplete https://github.com/BentoBoxWorld/addon-challenges/issues/27 Also added admin challenge reset command. --- pom.xml | 2 +- .../addon/challenges/ChallengesManager.java | 14 +++ .../challenges/commands/admin/Challenges.java | 1 + .../commands/admin/ResetChallenge.java | 77 ++++++++++++ .../database/object/ChallengesPlayerData.java | 16 ++- .../challenges/panel/ChallengesPanels.java | 4 +- .../addon/challenges/panel/TryToComplete.java | 117 ++++++++++++++---- src/main/resources/locales/en-US.yml | 5 +- 8 files changed, 209 insertions(+), 27 deletions(-) create mode 100644 src/main/java/bentobox/addon/challenges/commands/admin/ResetChallenge.java diff --git a/pom.xml b/pom.xml index 4f1aa67..9629a35 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ us.tastybento Challenges - 0.2.1-SNAPSHOT + 0.2.2-SNAPSHOT Challenges Challenges is an add-on for BentoBox, an expandable Minecraft Bukkit plugin for island-type games like ASkyBlock or AcidIsland. diff --git a/src/main/java/bentobox/addon/challenges/ChallengesManager.java b/src/main/java/bentobox/addon/challenges/ChallengesManager.java index 439bb64..72884f6 100644 --- a/src/main/java/bentobox/addon/challenges/ChallengesManager.java +++ b/src/main/java/bentobox/addon/challenges/ChallengesManager.java @@ -398,6 +398,18 @@ public class ChallengesManager { playerData.get(user.getUniqueId()).setChallengeDone(world, challengeUniqueId); } + /** + * Reset the challenge to zero time / not done + * @param user - user + * @param challengeUniqueId - unique challenge id + * @param world - world to set + */ + public void setResetChallenge(User user, String challengeUniqueId, World world) { + addPlayer(user); + playerData.get(user.getUniqueId()).setChallengeTimes(world, challengeUniqueId, 0); + + } + /** * @param challengeList the challengeList to set */ @@ -485,4 +497,6 @@ public class ChallengesManager { Arrays.asList(string.split("\\|")).forEach(line -> result.addAll(Arrays.asList(WordUtils.wrap(line,25).split("\\n")))); return result; } + + } diff --git a/src/main/java/bentobox/addon/challenges/commands/admin/Challenges.java b/src/main/java/bentobox/addon/challenges/commands/admin/Challenges.java index 5137e71..bba1c56 100644 --- a/src/main/java/bentobox/addon/challenges/commands/admin/Challenges.java +++ b/src/main/java/bentobox/addon/challenges/commands/admin/Challenges.java @@ -27,6 +27,7 @@ public class Challenges extends CompositeCommand { new ImportCommand(getAddon(), this); new CompleteChallenge(getAddon(), this); new ReloadChallenges(getAddon(), this); + new ResetChallenge(getAddon(), this); //new ShowChallenges(getAddon(), this); //new CreateChallenge(getAddon(), this); diff --git a/src/main/java/bentobox/addon/challenges/commands/admin/ResetChallenge.java b/src/main/java/bentobox/addon/challenges/commands/admin/ResetChallenge.java new file mode 100644 index 0000000..66a2f44 --- /dev/null +++ b/src/main/java/bentobox/addon/challenges/commands/admin/ResetChallenge.java @@ -0,0 +1,77 @@ +package bentobox.addon.challenges.commands.admin; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import bentobox.addon.challenges.ChallengesAddon; +import bentobox.addon.challenges.ChallengesManager; +import world.bentobox.bentobox.api.addons.Addon; +import world.bentobox.bentobox.api.commands.CompositeCommand; +import world.bentobox.bentobox.api.localization.TextVariables; +import world.bentobox.bentobox.api.user.User; +import world.bentobox.bentobox.util.Util; + +public class ResetChallenge extends CompositeCommand { + + private ChallengesManager manager; + + /** + * Admin command to complete user challenges + * @param parent + */ + public ResetChallenge(Addon addon, CompositeCommand parent) { + super(addon, parent, "reset"); + } + + @Override + public void setup() { + this.setPermission("admin.challenges"); + this.setParametersHelp("challenges.admin.reset.parameters"); + this.setDescription("challenges.admin.reset.description"); + manager = ((ChallengesAddon)getAddon()).getChallengesManager(); + } + + @Override + public boolean execute(User user, String label, List args) { + if (args.size() != 2) { + // Show help + showHelp(this, user); + return false; + } + // Get target player + UUID targetUUID = getPlayers().getUUID(args.get(0)); + if (targetUUID == null) { + user.sendMessage("general.errors.unknown-player", TextVariables.NAME, args.get(0)); + return false; + } + if (!getPlugin().getIslands().hasIsland(getWorld(), targetUUID)) { + user.sendMessage("general.errors.player-has-no-island"); + return false; + } + // Check for valid challenge name + if (!manager.isChallenge(getWorld(), args.get(1))) { + user.sendMessage("challenges.admin.complete.unknown-challenge"); + return false; + } + // Complete challenge + User target = User.getInstance(targetUUID); + manager.setResetChallenge(target, args.get(1), getWorld()); + user.sendMessage("general.success"); + return true; + } + + @Override + public Optional> tabComplete(User user, String alias, List args) { + String lastArg = !args.isEmpty() ? args.get(args.size()-1) : ""; + if (args.size() == 3) { + // Online players + return Optional.of(Util.tabLimit(new ArrayList<>(Util.getOnlinePlayerList(user)), lastArg)); + } else if (args.size() == 4) { + // Challenges in this world + return Optional.of(Util.tabLimit(manager.getAllChallengesList(getWorld()), lastArg)); + } + return Optional.empty(); + } +} diff --git a/src/main/java/bentobox/addon/challenges/database/object/ChallengesPlayerData.java b/src/main/java/bentobox/addon/challenges/database/object/ChallengesPlayerData.java index 828ae57..dd23802 100644 --- a/src/main/java/bentobox/addon/challenges/database/object/ChallengesPlayerData.java +++ b/src/main/java/bentobox/addon/challenges/database/object/ChallengesPlayerData.java @@ -21,7 +21,7 @@ import world.bentobox.bentobox.util.Util; * */ public class ChallengesPlayerData implements DataObject { - + @Expose private String uniqueId = ""; /** @@ -39,6 +39,7 @@ public class ChallengesPlayerData implements DataObject { /** * Mark a challenge as having been completed. Will increment the number of times and timestamp + * @param world - world of challenge * @param challengeName - unique challenge name */ public void setChallengeDone(World world, String challengeName) { @@ -48,6 +49,19 @@ public class ChallengesPlayerData implements DataObject { challengesTimestamp.put(name, System.currentTimeMillis()); } + /** + * Set the number of times a challenge has been done + * @param world - world of challenge + * @param challengeName - unique challenge name + * @param times - the number of times to set + * + */ + public void setChallengeTimes(World world, String challengeName, int times) { + String name = Util.getWorld(world).getName() + challengeName; + challengeStatus.put(name, times); + challengesTimestamp.put(name, System.currentTimeMillis()); + } + /** * Check if a challenge has been done * @param challengeName - unique challenge name diff --git a/src/main/java/bentobox/addon/challenges/panel/ChallengesPanels.java b/src/main/java/bentobox/addon/challenges/panel/ChallengesPanels.java index 1e80a10..e84711f 100644 --- a/src/main/java/bentobox/addon/challenges/panel/ChallengesPanels.java +++ b/src/main/java/bentobox/addon/challenges/panel/ChallengesPanels.java @@ -97,7 +97,9 @@ public class ChallengesPanels { .glow(completed) .clickHandler((panel, player, c, s) -> { if (!challenge.getChallengeType().equals(ChallengeType.ICON)) { - new TryToComplete(addon, player, manager, challenge, world, permPrefix, label); + new TryToComplete(addon).user(player).manager(manager).challenge(challenge) + .world(world).permPrefix(permPrefix).label(label).build(); + //new TryToComplete(addon, player, manager, challenge, world, permPrefix, label); } return true; }) diff --git a/src/main/java/bentobox/addon/challenges/panel/TryToComplete.java b/src/main/java/bentobox/addon/challenges/panel/TryToComplete.java index a80e416..944c763 100644 --- a/src/main/java/bentobox/addon/challenges/panel/TryToComplete.java +++ b/src/main/java/bentobox/addon/challenges/panel/TryToComplete.java @@ -42,6 +42,85 @@ public class TryToComplete { private User user; private ChallengesManager manager; private Challenges challenge; + private String label; + + public TryToComplete label(String label) { + this.label = label; + return this; + } + + public TryToComplete user(User user) { + this.user = user; + return this; + } + + public TryToComplete manager(ChallengesManager manager) { + this.manager = manager; + return this; + } + + public TryToComplete challenge(Challenges challenge) { + this.challenge = challenge; + return this; + } + + public TryToComplete world(World world) { + this.world = world; + return this; + } + + public TryToComplete permPrefix(String prefix) { + this.permPrefix = prefix; + return this; + } + + public TryToComplete(ChallengesAddon addon) { + this.addon = addon; + } + + public ChallengeResult build() { + // Check if can complete challenge + ChallengeResult result = checkIfCanCompleteChallenge(); + if (!result.meetsRequirements) { + return result; + } + if (!result.repeat) { + // Give rewards + for (ItemStack reward : challenge.getRewardItems()) { + user.getInventory().addItem(reward).forEach((k,v) -> user.getWorld().dropItem(user.getLocation(), v)); + } + // Give money + challenge.getRewardMoney(); + // Give exp + user.getPlayer().giveExp(challenge.getRewardExp()); + // Run commands + runCommands(challenge.getRewardCommands()); + user.sendMessage("challenges.you-completed", "[challenge]", challenge.getFriendlyName()); + if (addon.getConfig().getBoolean("broadcastmessages", false)) { + for (Player p : addon.getServer().getOnlinePlayers()) { + User.getInstance(p).sendMessage("challenges.name-has-completed", + "[name]", user.getName(), "[challenge]", challenge.getFriendlyName()); + } + } + } else { + // Give rewards + for (ItemStack reward : challenge.getRepeatItemReward()) { + user.getInventory().addItem(reward).forEach((k,v) -> user.getWorld().dropItem(user.getLocation(), v)); + } + // Give money + challenge.getRepeatMoneyReward(); + // Give exp + user.getPlayer().giveExp(challenge.getRepeatExpReward()); + // Run commands + runCommands(challenge.getRepeatRewardCommands()); + user.sendMessage("challenges.you-repeated", "[challenge]", challenge.getFriendlyName()); + } + // Mark as complete + manager.setChallengeComplete(user, challenge.getUniqueId(), world); + user.closeInventory(); + user.getPlayer().performCommand(label + " " + ChallengesCommand.CHALLENGE_COMMAND + " " + challenge.getLevel()); + return result; + } /** * @param addon @@ -150,23 +229,6 @@ public class TryToComplete { user.sendMessage("challenges.error.not-enough-items", "[items]", Util.prettifyText(req.getType().toString())); return new ChallengeResult(); } - // If remove items, then remove them - if (challenge.isTakeItems()) { - int amountToBeRemoved = req.getAmount(); - List itemsInInv = Arrays.stream(user.getInventory().getContents()).filter(Objects::nonNull).filter(i -> i.getType().equals(req.getType())).collect(Collectors.toList()); - for (ItemStack i : itemsInInv) { - if (amountToBeRemoved > 0) { - // Remove all of this item - HashMap remaining = user.getInventory().removeItem(i); - if (!remaining.isEmpty()) { - remaining.forEach((k,v) -> addon.logError("Could not remove items: " + v)); - } else { - amountToBeRemoved -= i.getAmount(); - } - } - } - - } break; default: // General checking @@ -174,19 +236,28 @@ public class TryToComplete { user.sendMessage("challenges.error.not-enough-items", "[items]", Util.prettifyText(req.getType().toString())); return new ChallengeResult(); } - // If remove items, then remove them - if (challenge.isTakeItems()) { - for (ItemStack items : required) { - HashMap remaining = user.getInventory().removeItem(items); + } + + } + // If remove items, then remove them + if (challenge.isTakeItems()) { + for (ItemStack req : required) { + int amountToBeRemoved = req.getAmount(); + List itemsInInv = Arrays.stream(user.getInventory().getContents()).filter(Objects::nonNull).filter(i -> i.getType().equals(req.getType())).collect(Collectors.toList()); + for (ItemStack i : itemsInInv) { + if (amountToBeRemoved > 0) { + // Remove all of this item + HashMap remaining = user.getInventory().removeItem(i); if (!remaining.isEmpty()) { remaining.forEach((k,v) -> addon.logError("Could not remove items: " + v)); + } else { + amountToBeRemoved -= i.getAmount(); } } } } - } - + // Return the result return new ChallengeResult().setMeetsRequirements().setRepeat(manager.isChallengeComplete(user, challenge.getUniqueId(), world)); } diff --git a/src/main/resources/locales/en-US.yml b/src/main/resources/locales/en-US.yml index 69c98fd..ca97f86 100755 --- a/src/main/resources/locales/en-US.yml +++ b/src/main/resources/locales/en-US.yml @@ -74,9 +74,12 @@ challenges: overwriting: "Overwriting '[challenge]'" imported: "Imported '[challenge]'" complete: - description: "Marks challenge complete" + description: "Mark challenge complete" parameters: " " unknown-challenge: "&cUnknown challenge" + reset: + description: "Reset challenge to 0 times / incomplete" + parameters: " " create: description: "&6Collect:" description-item-color: "&B"