diff --git a/pom.xml b/pom.xml index 181e7cc25..8aa65b84f 100644 --- a/pom.xml +++ b/pom.xml @@ -88,7 +88,7 @@ -LOCAL - 2.2.1 + 2.3.0 bentobox-world https://sonarcloud.io ${project.basedir}/lib diff --git a/src/main/java/world/bentobox/bentobox/Settings.java b/src/main/java/world/bentobox/bentobox/Settings.java index 2f2b85e2d..c149907b2 100644 --- a/src/main/java/world/bentobox/bentobox/Settings.java +++ b/src/main/java/world/bentobox/bentobox/Settings.java @@ -195,6 +195,12 @@ public class Settings implements ConfigObject { @ConfigEntry(path = "island.concurrent-islands") private int islandNumber = 1; + @ConfigComment("Hide used blueprints.") + @ConfigComment("Blueprints can have a maximum use when players have concurrent islands.") + @ConfigComment("If this is true, then ones that are used up will not be shown in the island create menu.") + @ConfigEntry(path = "island.hide-used-blueprints", since = "2.3.0") + private boolean hideUsedBlueprints = false; + // Cooldowns @ConfigComment("How long a player must wait until they can rejoin a team island after being kicked in minutes.") @ConfigComment("This slows the effectiveness of players repeating challenges") @@ -1014,4 +1020,18 @@ public class Settings implements ConfigObject { this.islandNumber = islandNumber; } + /** + * @return the hideUsedBlueprints + */ + public boolean isHideUsedBlueprints() { + return hideUsedBlueprints; + } + + /** + * @param hideUsedBlueprints the hideUsedBlueprints to set + */ + public void setHideUsedBlueprints(boolean hideUsedBlueprints) { + this.hideUsedBlueprints = hideUsedBlueprints; + } + } diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandCreateCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandCreateCommand.java index 54d3c7a12..1d4bbaf84 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandCreateCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandCreateCommand.java @@ -86,22 +86,51 @@ public class IslandCreateCommand extends CompositeCommand { user.sendMessage("commands.island.create.unknown-blueprint"); return false; } + // Check perm if (!getPlugin().getBlueprintsManager().checkPerm(getAddon(), user, Util.sanitizeInput(args.get(0)))) { return false; } + // Check maximum uses + if (checkMaxUses(user, name)) { + return false; + } // Make island return makeIsland(user, name); } else { + if (getPlugin().getSettings().getIslandNumber() > 1 + && checkMaxUses(user, BlueprintsManager.DEFAULT_BUNDLE_NAME)) { + return false; + } // Show panel only if there are multiple bundles available if (getPlugin().getBlueprintsManager().getBlueprintBundles(getAddon()).size() > 1) { // Show panel - IslandCreationPanel.openPanel(this, user, label); + IslandCreationPanel.openPanel(this, user, label, false); return true; } return makeIsland(user, BlueprintsManager.DEFAULT_BUNDLE_NAME); } } + private boolean checkMaxUses(User user, String name) { + if (getPlugin().getBlueprintsManager().getBlueprintBundles(getAddon()).containsKey(name)) { + int maxTimes = getPlugin().getBlueprintsManager().getBlueprintBundles(getAddon()).get(name).getTimes(); + if (maxTimes > 0) { + // Check how many times this player has used this bundle + if (getBundleUses(user, name) >= maxTimes) { + user.sendMessage("commands.island.create.max-uses"); + return true; + } + } + } + return false; + } + + private long getBundleUses(User user, String name) { + return getIslands().getIslands(getWorld(), user).stream() + .filter(is -> is.getMetaData("bundle").map(mdv -> name.equalsIgnoreCase(mdv.asString())).orElse(false)) + .count(); + } + private boolean makeIsland(User user, String name) { user.sendMessage("commands.island.create.creating-island"); try { diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandResetCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandResetCommand.java index feb7fb78b..8096f7a20 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandResetCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandResetCommand.java @@ -111,7 +111,7 @@ public class IslandResetCommand extends ConfirmableCommand { // Show panel only if there are multiple bundles available if (getPlugin().getBlueprintsManager().getBlueprintBundles(getAddon()).size() > 1) { // Show panel - once the player selected a bundle, this will re-run this command - IslandCreationPanel.openPanel(this, user, label); + IslandCreationPanel.openPanel(this, user, label, true); } else { resetIsland(user, BlueprintsManager.DEFAULT_BUNDLE_NAME); } diff --git a/src/main/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintBundle.java b/src/main/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintBundle.java index ce7474653..f5be3b417 100644 --- a/src/main/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintBundle.java +++ b/src/main/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintBundle.java @@ -61,6 +61,11 @@ public class BlueprintBundle implements DataObject { @Expose private int slot = 0; + /** + * Number of times this bundle can be used by a single player. 0 = unlimited + */ + @Expose + private int times = 0; /** @@ -188,4 +193,18 @@ public class BlueprintBundle implements DataObject { this.slot = slot; } + /** + * @return the times + */ + public int getTimes() { + return times; + } + + /** + * @param times the times to set + */ + public void setTimes(int times) { + this.times = times; + } + } diff --git a/src/main/java/world/bentobox/bentobox/managers/BlueprintsManager.java b/src/main/java/world/bentobox/bentobox/managers/BlueprintsManager.java index 8fec85175..d13332ed5 100644 --- a/src/main/java/world/bentobox/bentobox/managers/BlueprintsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/BlueprintsManager.java @@ -40,6 +40,7 @@ import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.addons.Addon; import world.bentobox.bentobox.api.addons.GameModeAddon; import world.bentobox.bentobox.api.localization.TextVariables; +import world.bentobox.bentobox.api.metadata.MetaDataValue; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.blueprints.Blueprint; import world.bentobox.bentobox.blueprints.BlueprintPaster; @@ -484,6 +485,8 @@ public class BlueprintsManager { b2 -> pasteEnd(addon, bb, island).thenAccept(message -> sendMessage(island)).thenAccept(b3 -> Bukkit.getScheduler().runTask(plugin, task)))); } + // Set the bundle name + island.putMetaData("bundle", new MetaDataValue(name)); return true; } diff --git a/src/main/java/world/bentobox/bentobox/panels/BlueprintManagementPanel.java b/src/main/java/world/bentobox/bentobox/panels/BlueprintManagementPanel.java index e0556413f..05b505fd8 100644 --- a/src/main/java/world/bentobox/bentobox/panels/BlueprintManagementPanel.java +++ b/src/main/java/world/bentobox/bentobox/panels/BlueprintManagementPanel.java @@ -77,10 +77,21 @@ public class BlueprintManagementPanel { environmentToBlueprint = Map.of(World.Environment.NORMAL, normalBlueprint, World.Environment.NETHER, netherBlueprint, World.Environment.THE_END, endBlueprint); } + /** + * Translate "commands.admin.blueprint.management." + t reference + * @param t - end of reference + * @return translation + */ private String t(String t) { return user.getTranslation("commands.admin.blueprint.management." + t); } + /** + * Translate "commands.admin.blueprint.management." + t + vars reference + * @param t end of reference + * @param vars any other parameters + * @return transmation + */ private String t(String t, String... vars) { return user.getTranslation("commands.admin.blueprint.management." + t, vars); } @@ -186,6 +197,10 @@ public class BlueprintManagementPanel { // Toggle permission - default is always allowed pb.item(39, getPermissionIcon(addon, bb)); } + if (plugin.getSettings().getIslandNumber() > 1) { + // Number of times allowed + pb.item(42, getTimesIcon(addon, bb)); + } // Preferred slot pb.item(40, getSlotIcon(addon, bb)); // Panel has a Back icon. @@ -198,6 +213,25 @@ public class BlueprintManagementPanel { } + private PanelItem getTimesIcon(GameModeAddon addon2, BlueprintBundle bb) { + return new PanelItemBuilder().icon(Material.CLOCK).name(t("times")) + .description(bb.getTimes() == 0 ? t("unlimited-times") + : t("maximum-times", TextVariables.NUMBER, String.valueOf(bb.getTimes()))) + .clickHandler((panel, u, clickType, slot) -> { + // Left click up, right click down + u.getPlayer().playSound(u.getLocation(), Sound.UI_BUTTON_CLICK, 1F, 1F); + if (clickType == ClickType.LEFT) { + bb.setTimes(bb.getTimes() + 1); + } else if (clickType == ClickType.RIGHT && bb.getTimes() > 0) { + bb.setTimes(bb.getTimes() - 1); + } + // Save + plugin.getBlueprintsManager().saveBlueprintBundle(addon, bb); + panel.getInventory().setItem(42, getTimesIcon(addon, bb).getItem()); + return true; + }).build(); + } + /** * Gets the preferred slot icon * @param addon - addon diff --git a/src/main/java/world/bentobox/bentobox/panels/customizable/IslandCreationPanel.java b/src/main/java/world/bentobox/bentobox/panels/customizable/IslandCreationPanel.java index 6824e7eac..681c3cd36 100644 --- a/src/main/java/world/bentobox/bentobox/panels/customizable/IslandCreationPanel.java +++ b/src/main/java/world/bentobox/bentobox/panels/customizable/IslandCreationPanel.java @@ -7,6 +7,7 @@ package world.bentobox.bentobox.panels.customizable; +import org.bukkit.World; import org.bukkit.event.inventory.ClickType; import org.bukkit.inventory.ItemStack; import org.eclipse.jdt.annotation.NonNull; @@ -37,6 +38,94 @@ import world.bentobox.bentobox.util.Util; */ public class IslandCreationPanel { + // --------------------------------------------------------------------- + // Section: Constants + // --------------------------------------------------------------------- + + /** + * This constant is used for button to indicate that it is Blueprint Bundle type. + */ + private static final String BUNDLES = "BUNDLE"; + + /** + * This constant is used for button to indicate that it is previous page type. + */ + private static final String PREVIOUS = "PREVIOUS"; + + /** + * This constant is used for button to indicate that it is next page type. + */ + private static final String NEXT = "NEXT"; + + /** + * This constant is used for indicating that pages should contain numbering. + */ + private static final String INDEXING = "indexing"; + + /** + * This constant stores value for SELECT action that is used in panels. + */ + private static final String SELECT_ACTION = "SELECT"; + + /** + * This constant stores value for COMMAND action that is used in panels. + */ + private static final String COMMANDS_ACTION = "COMMANDS"; + + /** + * This constant stores value for ERROR message that will be displayed upon failing to run creation commands. + */ + private static final String ISLAND_CREATION_COMMANDS = "ISLAND_CREATION_COMMANDS"; + + /** + * Button reference + */ + private static final String BUNDLE_BUTTON_REF = "panels.island_creation.buttons.bundle."; + + // --------------------------------------------------------------------- + // Section: Variables + // --------------------------------------------------------------------- + + /** + * This variable allows to access plugin object. + */ + private final BentoBox plugin; + + /** + * This variable stores main command that was triggered. + */ + private final CompositeCommand mainCommand; + + /** + * This variable holds user who opens panel. Without it panel cannot be opened. + */ + private final User user; + + /** + * This variable holds world where panel is opened. Without it panel cannot be opened. + */ + private final String mainLabel; + + /** + * This variable stores filtered elements. + */ + private final List elementList; + + /** + * This variable holds current pageIndex for multi-page island choosing. + */ + private int pageIndex; + + /** + * The world that this command applies to + */ + private final World world; + + /** + * true if this panel has been called by a reset command. Changes how the count of used islands is done. + */ + private final boolean reset; + // --------------------------------------------------------------------- // Section: Constructor // --------------------------------------------------------------------- @@ -48,20 +137,22 @@ public class IslandCreationPanel * @param command CompositeCommand object * @param label The main command label * @param user User who opens panel + * @param reset */ private IslandCreationPanel(@NonNull CompositeCommand command, - @NonNull User user, - @NonNull String label) + @NonNull User user, @NonNull String label, boolean reset) { this.plugin = BentoBox.getInstance(); this.user = user; this.mainLabel = label; + this.world = command.getWorld(); + this.reset = reset; this.elementList = this.plugin.getBlueprintsManager().getBlueprintBundles(command.getAddon()).values().stream(). - sorted(Comparator.comparingInt(BlueprintBundle::getSlot).thenComparing(BlueprintBundle::getUniqueId)). - filter(bundle -> !bundle.isRequirePermission() || - this.user.hasPermission(command.getPermissionPrefix() + "island.create." + bundle.getUniqueId())). - toList(); + sorted(Comparator.comparingInt(BlueprintBundle::getSlot).thenComparing(BlueprintBundle::getUniqueId)) + .filter(bundle -> !bundle.isRequirePermission() || this.user + .hasPermission(command.getPermissionPrefix() + "island.create." + bundle.getUniqueId())) + .toList(); this.mainCommand = command; } @@ -83,7 +174,7 @@ public class IslandCreationPanel { this.plugin.logError("There are no available phases for selection!"); this.user.sendMessage("no-phases", - TextVariables.GAMEMODE, this.plugin.getDescription().getName()); + TextVariables.GAMEMODE, this.plugin.getDescription().getName()); return; } @@ -126,8 +217,8 @@ public class IslandCreationPanel private boolean doesCustomPanelExists(GameModeAddon addon, String name) { return addon.getDataFolder().exists() && - new File(addon.getDataFolder(), "panels").exists() && - new File(addon.getDataFolder(), "panels" + File.separator + name + ".yml").exists(); + new File(addon.getDataFolder(), "panels").exists() + && new File(addon.getDataFolder(), "panels" + File.separator + name + ".yml").exists(); } @@ -149,7 +240,7 @@ public class IslandCreationPanel int size = this.elementList.size(); if (size <= slot.amountMap().getOrDefault(BUNDLES, 1) || - 1.0 * size / slot.amountMap().getOrDefault(BUNDLES, 1) <= this.pageIndex + 1) + 1.0 * size / slot.amountMap().getOrDefault(BUNDLES, 1) <= this.pageIndex + 1) { // There are no next elements return null; @@ -179,7 +270,7 @@ public class IslandCreationPanel if (template.description() != null) { builder.description(this.user.getTranslation(this.mainCommand.getWorld(), template.description(), - TextVariables.NUMBER, String.valueOf(nextPageIndex))); + TextVariables.NUMBER, String.valueOf(nextPageIndex))); } // Add ClickHandler @@ -187,7 +278,7 @@ public class IslandCreationPanel { template.actions().forEach(action -> { if ((clickType == action.clickType() || - action.clickType() == ClickType.UNKNOWN) && NEXT.equalsIgnoreCase(action.actionType())) + action.clickType() == ClickType.UNKNOWN) && NEXT.equalsIgnoreCase(action.actionType())) { // Next button ignores click type currently. this.pageIndex++; @@ -202,10 +293,10 @@ public class IslandCreationPanel // Collect tooltips. List tooltips = template.actions().stream(). - filter(action -> action.tooltip() != null). - map(action -> this.user.getTranslation(this.mainCommand.getWorld(), action.tooltip())). - filter(text -> !text.isBlank()). - collect(Collectors.toCollection(() -> new ArrayList<>(template.actions().size()))); + filter(action -> action.tooltip() != null) + .map(action -> this.user.getTranslation(this.mainCommand.getWorld(), action.tooltip())) + .filter(text -> !text.isBlank()) + .collect(Collectors.toCollection(() -> new ArrayList<>(template.actions().size()))); // Add tooltips. if (!tooltips.isEmpty()) @@ -259,16 +350,15 @@ public class IslandCreationPanel if (template.description() != null) { builder.description(this.user.getTranslation(this.mainCommand.getWorld(), template.description(), - TextVariables.NUMBER, String.valueOf(previousPageIndex))); + TextVariables.NUMBER, String.valueOf(previousPageIndex))); } - // Add ClickHandler // Add ClickHandler builder.clickHandler((panel, user, clickType, i) -> { template.actions().forEach(action -> { if ((clickType == action.clickType() || - action.clickType() == ClickType.UNKNOWN) && PREVIOUS.equalsIgnoreCase(action.actionType())) + action.clickType() == ClickType.UNKNOWN) && PREVIOUS.equalsIgnoreCase(action.actionType())) { // Next button ignores click type currently. this.pageIndex--; @@ -283,10 +373,10 @@ public class IslandCreationPanel // Collect tooltips. List tooltips = template.actions().stream(). - filter(action -> action.tooltip() != null). - map(action -> this.user.getTranslation(this.mainCommand.getWorld(), action.tooltip())). - filter(text -> !text.isBlank()). - collect(Collectors.toCollection(() -> new ArrayList<>(template.actions().size()))); + filter(action -> action.tooltip() != null) + .map(action -> this.user.getTranslation(this.mainCommand.getWorld(), action.tooltip())) + .filter(text -> !text.isBlank()) + .collect(Collectors.toCollection(() -> new ArrayList<>(template.actions().size()))); // Add tooltips. if (!tooltips.isEmpty()) @@ -310,7 +400,7 @@ public class IslandCreationPanel { if (this.elementList.isEmpty()) { - // Does not contain any sticks. + // Does not contain any blueprints. return null; } @@ -332,9 +422,8 @@ public class IslandCreationPanel { // Try to find bundle with requested ID. if not found, use already collected bundle. blueprintBundle = this.elementList.stream(). - filter(bundle -> bundle.getUniqueId().equals(template.dataMap().get("unique_id"))). - findFirst(). - orElse(blueprintBundle); + filter(bundle -> bundle.getUniqueId().equals(template.dataMap().get("unique_id"))).findFirst() + .orElse(blueprintBundle); } return this.createBundleButton(template, blueprintBundle); @@ -359,8 +448,6 @@ public class IslandCreationPanel return null; } - final String reference = "panels.island_creation.buttons.bundle."; - // Get settings for island. PanelItemBuilder builder = new PanelItemBuilder(); @@ -376,72 +463,92 @@ public class IslandCreationPanel if (template.title() != null) { builder.name(this.user.getTranslation(this.mainCommand.getWorld(), template.title(), - TextVariables.NAME, bundle.getDisplayName())); + TextVariables.NAME, bundle.getDisplayName())); } else { - builder.name(this.user.getTranslation(reference + "name", - TextVariables.NAME, bundle.getDisplayName())); + builder.name(this.user.getTranslation(BUNDLE_BUTTON_REF + "name", + TextVariables.NAME, bundle.getDisplayName())); } if (template.description() != null) { builder.description(this.user.getTranslation(this.mainCommand.getWorld(), template.description(), - TextVariables.DESCRIPTION, String.join("\n", bundle.getDescription()))); + TextVariables.DESCRIPTION, String.join("\n", bundle.getDescription()))); } else { - builder.description(this.user.getTranslation(reference + "description", - TextVariables.DESCRIPTION, String.join("\n", bundle.getDescription()))); + builder.description(this.user.getTranslation(BUNDLE_BUTTON_REF + "description", + TextVariables.DESCRIPTION, String.join("\n", bundle.getDescription()))); + } + boolean usedUp = false; + if (plugin.getSettings().getIslandNumber() > 1) { + // Show how many times this bundle can be used + int maxTimes = bundle.getTimes(); + if (maxTimes > 0) { + long uses = plugin.getIslands().getIslands(world, user).stream() + .filter(is -> is.getMetaData("bundle") + .map(mdv -> bundle.getDisplayName().equalsIgnoreCase(mdv.asString()) + && !(reset && is.isPrimary())) // If this is a reset, then ignore the use of the island being reset + .orElse(false)) + .count(); + builder.description(this.user.getTranslation(BUNDLE_BUTTON_REF + "uses", TextVariables.NUMBER, + String.valueOf(uses), "[max]", String.valueOf(maxTimes))); + if (uses >= maxTimes) { + usedUp = true; + } + } else { + builder.description(this.user.getTranslation(BUNDLE_BUTTON_REF + "unlimited")); + } } - List actions = template.actions().stream(). - filter(action -> SELECT_ACTION.equalsIgnoreCase(action.actionType()) || - COMMANDS_ACTION.equalsIgnoreCase(action.actionType())). - toList(); + if (usedUp) { + if (plugin.getSettings().isHideUsedBlueprints()) { + // Do not show used up blueprints + return null; + } + } else { + List actions = template.actions().stream() + .filter(action -> SELECT_ACTION.equalsIgnoreCase(action.actionType()) + || COMMANDS_ACTION.equalsIgnoreCase(action.actionType())) + .toList(); + // Add ClickHandler + builder.clickHandler((panel, user, clickType, i) -> { + actions.forEach(action -> { + if (clickType == action.clickType() || action.clickType() == ClickType.UNKNOWN) + { + if (SELECT_ACTION.equalsIgnoreCase(action.actionType())) { + user.closeInventory(); + this.mainCommand.execute(user, this.mainLabel, + Collections.singletonList(bundle.getUniqueId())); + } else if (COMMANDS_ACTION.equalsIgnoreCase(action.actionType())) { + Util.runCommands(user, + Arrays.stream(action.content() + .replaceAll(Pattern.quote(TextVariables.LABEL), + this.mainCommand.getTopLabel()) + .split("\n")).toList(), + ISLAND_CREATION_COMMANDS); + } + } + }); - // Add ClickHandler - builder.clickHandler((panel, user, clickType, i) -> - { - actions.forEach(action -> { - if (clickType == action.clickType() || action.clickType() == ClickType.UNKNOWN) - { - if (SELECT_ACTION.equalsIgnoreCase(action.actionType())) - { - user.closeInventory(); - this.mainCommand.execute(user, this.mainLabel, Collections.singletonList(bundle.getUniqueId())); - } - else if (COMMANDS_ACTION.equalsIgnoreCase(action.actionType())) - { - Util.runCommands(user, - Arrays.stream(action.content(). - replaceAll(Pattern.quote(TextVariables.LABEL), this.mainCommand.getTopLabel()). - split("\n")). - toList(), - ISLAND_CREATION_COMMANDS); - } - } + // Always return true. + return true; }); - // Always return true. - return true; - }); + // Collect tooltips. + List tooltips = actions.stream().filter(action -> action.tooltip() != null) + .map(action -> this.user.getTranslation(this.mainCommand.getWorld(), action.tooltip())) + .filter(text -> !text.isBlank()) + .collect(Collectors.toCollection(() -> new ArrayList<>(actions.size()))); - // Collect tooltips. - List tooltips = actions.stream(). - filter(action -> action.tooltip() != null). - map(action -> this.user.getTranslation(this.mainCommand.getWorld(), action.tooltip())). - filter(text -> !text.isBlank()). - collect(Collectors.toCollection(() -> new ArrayList<>(actions.size()))); - - // Add tooltips. - if (!tooltips.isEmpty()) - { - // Empty line and tooltips. - builder.description(""); - builder.description(tooltips); + // Add tooltips. + if (!tooltips.isEmpty()) { + // Empty line and tooltips. + builder.description(""); + builder.description(tooltips); + } } - return builder.build(); } @@ -458,87 +565,13 @@ public class IslandCreationPanel * @param command CompositeCommand object * @param label The main command label * @param user User who opens panel + * @param reset true if this is an island reset */ public static void openPanel(@NonNull CompositeCommand command, - @NonNull User user, - @NonNull String label) + @NonNull User user, @NonNull String label, boolean reset) { - new IslandCreationPanel(command, user, label).build(); + new IslandCreationPanel(command, user, label, reset).build(); } -// --------------------------------------------------------------------- -// Section: Constants -// --------------------------------------------------------------------- - - - /** - * This constant is used for button to indicate that it is Blueprint Bundle type. - */ - private static final String BUNDLES = "BUNDLE"; - - /** - * This constant is used for button to indicate that it is previous page type. - */ - private static final String PREVIOUS = "PREVIOUS"; - - /** - * This constant is used for button to indicate that it is next page type. - */ - private static final String NEXT = "NEXT"; - - /** - * This constant is used for indicating that pages should contain numbering. - */ - private static final String INDEXING = "indexing"; - - /** - * This constant stores value for SELECT action that is used in panels. - */ - private static final String SELECT_ACTION = "SELECT"; - - /** - * This constant stores value for COMMAND action that is used in panels. - */ - private static final String COMMANDS_ACTION = "COMMANDS"; - - /** - * This constant stores value for ERROR message that will be displayed upon failing to run creation commands. - */ - private static final String ISLAND_CREATION_COMMANDS = "ISLAND_CREATION_COMMANDS"; - -// --------------------------------------------------------------------- -// Section: Variables -// --------------------------------------------------------------------- - - - /** - * This variable allows to access plugin object. - */ - private final BentoBox plugin; - - /** - * This variable stores main command that was triggered. - */ - private final CompositeCommand mainCommand; - - /** - * This variable holds user who opens panel. Without it panel cannot be opened. - */ - private final User user; - - /** - * This variable holds world where panel is opened. Without it panel cannot be opened. - */ - private final String mainLabel; - - /** - * This variable stores filtered elements. - */ - private final List elementList; - - /** - * This variable holds current pageIndex for multi-page island choosing. - */ - private int pageIndex; } diff --git a/src/main/resources/locales/en-US.yml b/src/main/resources/locales/en-US.yml index 9c0838c47..6161572fd 100644 --- a/src/main/resources/locales/en-US.yml +++ b/src/main/resources/locales/en-US.yml @@ -414,6 +414,12 @@ commands: slot-instructions: | &a Left click to increment &a Right click to decrement + times: | + &a Max concurrent uses by player + &a Left click to increment + &a Right click to decrement + unlimited-times: &a Unlimited + maximum-times: &a Max [number] times resetflags: parameters: '[flag]' description: Reset all islands to default flag settings in config.yml @@ -547,6 +553,7 @@ commands: an administrator.' creating-island: '&a Finding a spot for your island...' you-cannot-make: '&c You cannot make any more islands!' + max-uses: "&c You cannot make any more of that type of island!" you-cannot-make-team: '&c Team members cannot make islands in the same world as their team island.' pasting: estimated-time: '&a Estimated time: &b [number] &a seconds.' @@ -1811,6 +1818,8 @@ panels: name: "&l [name]" description: |- [description] + uses: "&a Used [number]/[max]" + unlimited: "&a Unlimited uses allowed" # The section of translations used in Language Panel language: title: "&2&l Select your language" diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandCreateCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandCreateCommandTest.java index 5d35d71a7..d1f44e7fb 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandCreateCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandCreateCommandTest.java @@ -167,6 +167,10 @@ public class IslandCreateCommandTest { when(builder.build()).thenReturn(mock(Island.class)); // Bundles manager + + @NonNull + Map map = new HashMap<>(); + when(bpm.getBlueprintBundles(addon)).thenReturn(map); when(plugin.getBlueprintsManager()).thenReturn(bpm); // IslandCreationPanel diff --git a/src/test/java/world/bentobox/bentobox/panels/BlueprintManagementPanelTest.java b/src/test/java/world/bentobox/bentobox/panels/BlueprintManagementPanelTest.java index 4ff22b87e..59516412e 100644 --- a/src/test/java/world/bentobox/bentobox/panels/BlueprintManagementPanelTest.java +++ b/src/test/java/world/bentobox/bentobox/panels/BlueprintManagementPanelTest.java @@ -32,6 +32,7 @@ import org.powermock.modules.junit4.PowerMockRunner; import org.powermock.reflect.Whitebox; import world.bentobox.bentobox.BentoBox; +import world.bentobox.bentobox.Settings; import world.bentobox.bentobox.api.addons.GameModeAddon; import world.bentobox.bentobox.api.panels.PanelItem; import world.bentobox.bentobox.api.user.User; @@ -123,6 +124,9 @@ public class BlueprintManagementPanelTest { // Blueprint when(blueprint.getName()).thenReturn("blueprint name"); + // Settings + Settings settings = new Settings(); + when(plugin.getSettings()).thenReturn(settings); // Set up bmp = new BlueprintManagementPanel(plugin, user, addon); diff --git a/src/test/java/world/bentobox/bentobox/panels/customizable/IslandCreationPanelTest.java b/src/test/java/world/bentobox/bentobox/panels/customizable/IslandCreationPanelTest.java index 19f5ca654..12b982e36 100644 --- a/src/test/java/world/bentobox/bentobox/panels/customizable/IslandCreationPanelTest.java +++ b/src/test/java/world/bentobox/bentobox/panels/customizable/IslandCreationPanelTest.java @@ -203,7 +203,7 @@ public class IslandCreationPanelTest { */ @Test public void testOpenPanel() { - IslandCreationPanel.openPanel(ic, user, ""); + IslandCreationPanel.openPanel(ic, user, "", false); // Set correctly verify(inv).setItem(eq(0), any()); @@ -220,7 +220,7 @@ public class IslandCreationPanelTest { public void testOpenPanelSameSlot() { when(bb2.getSlot()).thenReturn(5); when(bb3.getSlot()).thenReturn(5); - IslandCreationPanel.openPanel(ic, user, ""); + IslandCreationPanel.openPanel(ic, user, "", false); verify(inv).setItem(eq(0), any()); verify(inv).setItem(eq(1), any()); verify(meta).setDisplayName(eq("test"));