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"));