diff --git a/src/main/java/world/bentobox/challenges/commands/CompleteChallengeCommand.java b/src/main/java/world/bentobox/challenges/commands/CompleteChallengeCommand.java index 22e0c99..306348a 100644 --- a/src/main/java/world/bentobox/challenges/commands/CompleteChallengeCommand.java +++ b/src/main/java/world/bentobox/challenges/commands/CompleteChallengeCommand.java @@ -62,10 +62,19 @@ public class CompleteChallengeCommand extends CompositeCommand String challengeName = Utils.getGameMode(this.getWorld()) + "_" + args.get(0); Challenge challenge = this.addon.getChallengesManager().getChallenge(challengeName); - int count = args.size() == 2 ? Integer.valueOf(args.get(1)) : 1; - if (challenge != null) { + int count = args.size() == 2 ? Integer.valueOf(args.get(1)) : 1; + + boolean canMultipleTimes = + user.hasPermission(this.getPermission() + ".multiple"); + + if (!canMultipleTimes && count > 1) + { + user.sendMessage("challenges.error.no-multiple-permission"); + count = 1; + } + return TryToComplete.complete(this.addon, user, challenge, diff --git a/src/main/java/world/bentobox/challenges/panel/user/ChallengesGUI.java b/src/main/java/world/bentobox/challenges/panel/user/ChallengesGUI.java index 103e73d..43219c9 100644 --- a/src/main/java/world/bentobox/challenges/panel/user/ChallengesGUI.java +++ b/src/main/java/world/bentobox/challenges/panel/user/ChallengesGUI.java @@ -358,35 +358,26 @@ public class ChallengesGUI extends CommonGUI // Add ability to input how many repeats player should do. // Do not open if challenge is not repeatable. - // TODO: AnvilGUI is removed. Need to use different input mode. -// if (clickType.isRightClick() && challenge.isRepeatable()) -// { -// new AnvilGUI(this.addon.getPlugin(), -// this.user.getPlayer(), -// "1", -// (player, reply) -> { -// try -// { -// if (TryToComplete.complete(this.addon, -// this.user, -// challenge, -// this.world, -// this.topLabel, -// this.permissionPrefix, -// Integer.parseInt(reply))) -// { -// panel.getInventory().setItem(slot, this.getChallengeButton(challenge).getItem()); -// } -// } -// catch (Exception e) -// { -// this.user.sendMessage("challenges.errors.not-a-integer", "[value]", reply); -// } -// -// return reply; -// }); -// } -// else + + if (clickType.isRightClick() && + challenge.isRepeatable() && + this.user.hasPermission(this.permissionPrefix + "complete.multiple")) + { + new MultipleGUI(this.user, + this.addon.getChallengesSettings().getLoreLineLength(), + value -> { + TryToComplete.complete(this.addon, + this.user, + challenge, + this.world, + this.topLabel, + this.permissionPrefix, + value); + + this.build(); + }); + } + else { if (TryToComplete.complete(this.addon, this.user, diff --git a/src/main/java/world/bentobox/challenges/panel/user/MultipleGUI.java b/src/main/java/world/bentobox/challenges/panel/user/MultipleGUI.java new file mode 100644 index 0000000..509f29c --- /dev/null +++ b/src/main/java/world/bentobox/challenges/panel/user/MultipleGUI.java @@ -0,0 +1,215 @@ + +package world.bentobox.challenges.panel.user; + +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import java.util.function.Consumer; + + +import world.bentobox.bentobox.api.panels.Panel; +import world.bentobox.bentobox.api.panels.PanelItem; +import world.bentobox.bentobox.api.panels.builders.PanelBuilder; +import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder; +import world.bentobox.bentobox.api.user.User; +import world.bentobox.challenges.utils.GuiUtils; + + +/** + * This GUI will pop out when user uses right click on challenge. It is meant to choose + * how many times player will complete challenges. + */ +public class MultipleGUI +{ + /** + * Default constructor. + * @param user User who opens gui. + * @param lineLength Length of lore message. + * @param action Action that will be performed on value clicking. + */ + public MultipleGUI(User user, int lineLength, Consumer action) + { + this.user = user; + this.lineLength = lineLength; + this.action = action; + + this.build(); + } + + /** + * This method builds panel that allows to change given number value. + */ + private void build() + { + PanelBuilder panelBuilder = new PanelBuilder(). + user(this.user). + type(Panel.Type.HOPPER). + name(this.user.getTranslation("challenges.gui.title.multiple-complete")); + + panelBuilder.item(2, this.getButton(Button.VALUE)); + + // Reduce + panelBuilder.item(0, this.getButton(Button.REDUCE_LOT)); + panelBuilder.item(1, this.getButton(Button.REDUCE)); + + // Increase + panelBuilder.item(3, this.getButton(Button.INCREASE)); + panelBuilder.item(4, this.getButton(Button.INCREASE_LOT)); + + panelBuilder.build(); + } + + + /** + * This method creates PanelItem with required functionality. + * @param button Functionality requirement. + * @return PanelItem with functionality. + */ + private PanelItem getButton(Button button) + { + ItemStack icon; + String name; + String description; + PanelItem.ClickHandler clickHandler; + boolean glow; + + switch (button) + { + case VALUE: + { + name = this.user.getTranslation("challenges.gui.buttons.value"); + description = this.user.getTranslation("challenges.gui.descriptions.current-value", "[value]", Integer.toString(this.value)); + icon = new ItemStack(Material.GREEN_STAINED_GLASS_PANE); + clickHandler = (panel, user, clickType, slot) -> { + this.action.accept(this.value); + return true; + }; + glow = false; + break; + } + case INCREASE: + { + name = this.user.getTranslation("challenges.gui.buttons.increase"); + description = this.user.getTranslation("challenges.gui.descriptions.increase-by", "[value]", "1"); + icon = new ItemStack(Material.BLUE_STAINED_GLASS_PANE); + clickHandler = (panel, user, clickType, slot) -> { + this.value++; + // Necessary just to update second item + panel.getInventory().setItem(2, this.getButton(Button.VALUE).getItem()); + return true; + }; + glow = false; + break; + } + case INCREASE_LOT: + { + name = this.user.getTranslation("challenges.gui.buttons.increase"); + description = this.user.getTranslation("challenges.gui.descriptions.increase-by", "[value]", "5"); + icon = new ItemStack(Material.MAGENTA_STAINED_GLASS_PANE); + clickHandler = (panel, user, clickType, slot) -> { + this.value += 5; + // Necessary just to update second item + panel.getInventory().setItem(2, this.getButton(Button.VALUE).getItem()); + return true; + }; + glow = false; + break; + } + case REDUCE: + { + name = this.user.getTranslation("challenges.gui.buttons.reduce"); + description = this.user.getTranslation("challenges.gui.descriptions.reduce-by", "[value]", "1"); + icon = new ItemStack(Material.ORANGE_STAINED_GLASS_PANE); + clickHandler = (panel, user, clickType, slot) -> { + this.value--; + + if (this.value < 1) + { + this.value = 1; + } + + // Necessary just to update second item + panel.getInventory().setItem(2, this.getButton(Button.VALUE).getItem()); + + return true; + }; + glow = false; + break; + } + case REDUCE_LOT: + { + name = this.user.getTranslation("challenges.gui.buttons.reduce"); + description = this.user.getTranslation("challenges.gui.descriptions.reduce-by", "[value]", "5"); + icon = new ItemStack(Material.RED_STAINED_GLASS_PANE); + clickHandler = (panel, user, clickType, slot) -> { + this.value -= 5; + + if (this.value < 1) + { + this.value = 1; + } + + // Necessary just to update second item + panel.getInventory().setItem(2, this.getButton(Button.VALUE).getItem()); + + return true; + }; + glow = false; + break; + } + default: + return null; + } + + return new PanelItemBuilder(). + icon(icon). + name(name). + description(GuiUtils.stringSplit(description, this.lineLength)). + glow(glow). + clickHandler(clickHandler). + build(); + } + + +// --------------------------------------------------------------------- +// Section: Enums +// --------------------------------------------------------------------- + + + /** + * This enum allows to easier define available buttons. + */ + enum Button + { + VALUE, + REDUCE, + REDUCE_LOT, + INCREASE, + INCREASE_LOT + } + + +// --------------------------------------------------------------------- +// Section: Instance variables +// --------------------------------------------------------------------- + + + /** + * This variable allows to access to user object. + */ + private User user; + + /** + * This variable holds action that will be performed on accept. + */ + private Consumer action; + + /** + * This variable holds a number of characters in single line for lore message. + */ + private int lineLength; + + /** + * This integer holds current value of completion count. + */ + private int value = 1; +} diff --git a/src/main/resources/addon.yml b/src/main/resources/addon.yml index efe56d8..53633f5 100755 --- a/src/main/resources/addon.yml +++ b/src/main/resources/addon.yml @@ -17,27 +17,43 @@ permissions: addon.challenges: description: Let the player use the '/challenges' command default: true + bskyblock.challenges: description: Let the player use the '/island challenges' command default: true + bskyblock.challenges.multiple: + description: Let the player complete challenge multiple times + default: true bskyblock.admin.challenges: description: Access challenge admin commands default: op + acidisland.challenges: description: Let the player use the '/ai challenges' command default: true + acidisland.challenges.multiple: + description: Let the player complete challenge multiple times + default: true acidisland.admin.challenges: description: Access challenge admin commands default: op + caveblock.challenges: description: Let the player use the '/cave challenges' command default: true + caveblock.challenges.multiple: + description: Let the player complete challenge multiple times + default: true caveblock.admin.challenges: description: Access challenge admin commands default: op + skygrid.challenges: description: Let the player use the '/skygrid challenges' command default: true + skygrid.challenges.multiple: + description: Let the player complete challenge multiple times + default: true skygrid.admin.challenges: description: Access challenge admin commands default: op diff --git a/src/main/resources/locales/en-US.yml b/src/main/resources/locales/en-US.yml index e4c0117..10b8dec 100755 --- a/src/main/resources/locales/en-US.yml +++ b/src/main/resources/locales/en-US.yml @@ -67,8 +67,10 @@ challenges: select-entity: '&aSelect Entity' toggle-environment: '&aToggle Environment' edit-text-fields: '&aEdit Text Fields' - challenges: '&aChallenges' - game-modes: '&aChoose GameMode' + challenges: '&6Challenges' + game-modes: '&6Choose GameMode' + + multiple-complete: '&6How many times?' buttons: admin: complete: 'Complete user challenge' @@ -162,6 +164,10 @@ challenges: next: 'Next' previous: 'Previous' return: 'Return' + + value: "Complete" + increase: "Increase" + reduce: "Reduce" descriptions: admin: save: 'Save and return to previous GUI.' @@ -274,6 +280,9 @@ challenges: command: '- [command]' level-unlocked: 'Click to see [level] challenges!' level-locked: 'Complete [count] more [level] challenges to unlock this level!' + + increase-by: "&aIncrease completion count by [value]" + reduce-by: "&cReduce completion count by [value]" challenge-description: level: '&FLevel: [level]' completed: '&BCompleted' @@ -406,6 +415,7 @@ challenges: no-challenges-admin: '&cChallenges are not implemented in current world! You should use &5/[command] &cto adding them!' missing-level: '&cChallenge Level [level] is not defined in database. It may case some errors!' missing-arguments: '&cCommand is missing arguments.' + no-multiple-permission: "&cYou do not have permission to complete challenge multiple times at once." protection: flags: CHALLENGES_ISLAND_PROTECTION: