mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2024-11-10 21:11:04 +01:00
Customizable Island Creation Panel (#2255)
* Customizable Island Creation Panel This implements customizable Island Creation Panel. By default, panel is generated in `/plugins/bentobox/panels` folder, however, if GameModeAddon has a specific panel defined in their folder, then that panel is taken. * Create UnitTests for new panels * Add island creation panel saving on loading * Remove old IslandCreationPanel and move to the new one. * Fixes some issues with locale and panel --------- Co-authored-by: tastybento <tastybento@users.noreply.github.com>
This commit is contained in:
parent
3be034bfa9
commit
bfb487342a
@ -465,8 +465,7 @@ public class BentoBox extends JavaPlugin implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log("Saving default panels...");
|
log("Saving default panels...");
|
||||||
this.saveResource("panels/language_panel.yml", false);
|
this.saveResource("panels/island_creation_panel.yml", false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ import world.bentobox.bentobox.api.user.User;
|
|||||||
import world.bentobox.bentobox.database.objects.Island;
|
import world.bentobox.bentobox.database.objects.Island;
|
||||||
import world.bentobox.bentobox.managers.BlueprintsManager;
|
import world.bentobox.bentobox.managers.BlueprintsManager;
|
||||||
import world.bentobox.bentobox.managers.island.NewIsland;
|
import world.bentobox.bentobox.managers.island.NewIsland;
|
||||||
import world.bentobox.bentobox.panels.IslandCreationPanel;
|
import world.bentobox.bentobox.panels.customizable.IslandCreationPanel;
|
||||||
import world.bentobox.bentobox.util.Util;
|
import world.bentobox.bentobox.util.Util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,7 +16,7 @@ import world.bentobox.bentobox.database.objects.Island;
|
|||||||
import world.bentobox.bentobox.managers.BlueprintsManager;
|
import world.bentobox.bentobox.managers.BlueprintsManager;
|
||||||
import world.bentobox.bentobox.managers.island.NewIsland;
|
import world.bentobox.bentobox.managers.island.NewIsland;
|
||||||
import world.bentobox.bentobox.managers.island.NewIsland.Builder;
|
import world.bentobox.bentobox.managers.island.NewIsland.Builder;
|
||||||
import world.bentobox.bentobox.panels.IslandCreationPanel;
|
import world.bentobox.bentobox.panels.customizable.IslandCreationPanel;
|
||||||
import world.bentobox.bentobox.util.Util;
|
import world.bentobox.bentobox.util.Util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,91 +0,0 @@
|
|||||||
package world.bentobox.bentobox.panels;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNull;
|
|
||||||
|
|
||||||
import world.bentobox.bentobox.BentoBox;
|
|
||||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
|
||||||
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.bentobox.blueprints.dataobjects.BlueprintBundle;
|
|
||||||
import world.bentobox.bentobox.managers.BlueprintsManager;
|
|
||||||
import world.bentobox.bentobox.util.Util;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Displays the available BlueprintBundles to pick up as the island.
|
|
||||||
* @author tastybento
|
|
||||||
* @since 1.5.0
|
|
||||||
*/
|
|
||||||
public class IslandCreationPanel {
|
|
||||||
|
|
||||||
private IslandCreationPanel() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shows a player a panel of selectable blueprint bundles. Checks user's permission
|
|
||||||
* @param command - the command requesting the panel, e.g., create or reset
|
|
||||||
* @param user - the user
|
|
||||||
* @param label - label
|
|
||||||
*/
|
|
||||||
public static void openPanel(@NonNull CompositeCommand command, @NonNull User user, @NonNull String label) {
|
|
||||||
BentoBox plugin = BentoBox.getInstance();
|
|
||||||
// Create the panel
|
|
||||||
PanelBuilder pb = new PanelBuilder().name(user.getTranslation("commands.island.create.pick")).user(user);
|
|
||||||
// Get the bundles
|
|
||||||
Comparator<BlueprintBundle> sortByDisplayName = (p, o) -> p.getDisplayName().compareToIgnoreCase(o.getDisplayName());
|
|
||||||
List<BlueprintBundle> bbs = plugin.getBlueprintsManager().getBlueprintBundles(command.getAddon()).values()
|
|
||||||
.stream().sorted(sortByDisplayName).toList();
|
|
||||||
// Loop through them and create items in the panel
|
|
||||||
for (BlueprintBundle bb : bbs) {
|
|
||||||
String perm = command.getPermissionPrefix() + "island.create." + bb.getUniqueId();
|
|
||||||
if (bb.getUniqueId().equals(BlueprintsManager.DEFAULT_BUNDLE_NAME)
|
|
||||||
|| !bb.isRequirePermission()
|
|
||||||
|| user.hasPermission(perm)) {
|
|
||||||
// Add an item
|
|
||||||
PanelItem item = new PanelItemBuilder()
|
|
||||||
.name(bb.getDisplayName())
|
|
||||||
.description(bb.getDescription().stream().map(Util::translateColorCodes).toList())
|
|
||||||
.icon(bb.getIcon()).clickHandler((panel, user1, clickType, slot1) -> {
|
|
||||||
user1.closeInventory();
|
|
||||||
command.execute(user1, label, Collections.singletonList(bb.getUniqueId()));
|
|
||||||
return true;
|
|
||||||
}).build();
|
|
||||||
// Determine slot
|
|
||||||
if (bb.getSlot() < 0 || bb.getSlot() > BlueprintManagementPanel.MAX_BP_SLOT) {
|
|
||||||
bb.setSlot(0);
|
|
||||||
}
|
|
||||||
if (pb.slotOccupied(bb.getSlot())) {
|
|
||||||
int slot = getFirstAvailableSlot(pb);
|
|
||||||
if (slot == -1) {
|
|
||||||
// TODO add paging
|
|
||||||
plugin.logError("Too many blueprint bundles to show!");
|
|
||||||
pb.item(item);
|
|
||||||
} else {
|
|
||||||
pb.item(slot, item);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pb.item(bb.getSlot(), item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pb.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param pb - panel builder
|
|
||||||
* @return first available slot, or -1 if none
|
|
||||||
*/
|
|
||||||
private static int getFirstAvailableSlot(PanelBuilder pb) {
|
|
||||||
for (int i = 0; i < BlueprintManagementPanel.MAX_BP_SLOT; i++) {
|
|
||||||
if (!pb.slotOccupied(i)) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,544 @@
|
|||||||
|
//
|
||||||
|
// Created by BONNe
|
||||||
|
// Copyright - 2023
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
package world.bentobox.bentobox.panels.customizable;
|
||||||
|
|
||||||
|
|
||||||
|
import org.bukkit.event.inventory.ClickType;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.eclipse.jdt.annotation.NonNull;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import world.bentobox.bentobox.BentoBox;
|
||||||
|
import world.bentobox.bentobox.api.addons.GameModeAddon;
|
||||||
|
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||||
|
import world.bentobox.bentobox.api.localization.TextVariables;
|
||||||
|
import world.bentobox.bentobox.api.panels.PanelItem;
|
||||||
|
import world.bentobox.bentobox.api.panels.TemplatedPanel;
|
||||||
|
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
|
||||||
|
import world.bentobox.bentobox.api.panels.builders.TemplatedPanelBuilder;
|
||||||
|
import world.bentobox.bentobox.api.panels.reader.ItemTemplateRecord;
|
||||||
|
import world.bentobox.bentobox.api.user.User;
|
||||||
|
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBundle;
|
||||||
|
import world.bentobox.bentobox.util.Util;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class generates Island Creation Panel based on user specified file with name: "island_creation_panel.yml".
|
||||||
|
* If file with such name is located at gamemode panels directory, then that file will be used.
|
||||||
|
* Otherwise, file in BentoBox/panels is used.
|
||||||
|
*/
|
||||||
|
public class IslandCreationPanel
|
||||||
|
{
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// Section: Constructor
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is internal constructor. It is used internally in current class to avoid creating objects everywhere.
|
||||||
|
*
|
||||||
|
* @param command CompositeCommand object
|
||||||
|
* @param label The main command label
|
||||||
|
* @param user User who opens panel
|
||||||
|
*/
|
||||||
|
private IslandCreationPanel(@NonNull CompositeCommand command,
|
||||||
|
@NonNull User user,
|
||||||
|
@NonNull String label)
|
||||||
|
{
|
||||||
|
this.plugin = BentoBox.getInstance();
|
||||||
|
this.user = user;
|
||||||
|
this.mainLabel = label;
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
this.mainCommand = command;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// Section: Methods
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build method manages current panel opening. It uses BentoBox PanelAPI that is easy to use and users can get nice
|
||||||
|
* panels.
|
||||||
|
*/
|
||||||
|
private void build()
|
||||||
|
{
|
||||||
|
// Do not open gui if there is no magic sticks.
|
||||||
|
if (this.elementList.isEmpty())
|
||||||
|
{
|
||||||
|
this.plugin.logError("There are no available phases for selection!");
|
||||||
|
this.user.sendMessage("no-phases",
|
||||||
|
TextVariables.GAMEMODE, this.plugin.getDescription().getName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start building panel.
|
||||||
|
TemplatedPanelBuilder panelBuilder = new TemplatedPanelBuilder();
|
||||||
|
|
||||||
|
// Set main template.
|
||||||
|
if (this.doesCustomPanelExists(this.mainCommand.getAddon(), "island_creation_panel"))
|
||||||
|
{
|
||||||
|
// Addon has its own island creation panel. Use it.
|
||||||
|
panelBuilder.template("island_creation_panel", new File(this.mainCommand.getAddon().getDataFolder(), "panels"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Use default island creation panel.
|
||||||
|
panelBuilder.template("island_creation_panel", new File(this.plugin.getDataFolder(), "panels"));
|
||||||
|
}
|
||||||
|
|
||||||
|
panelBuilder.user(this.user);
|
||||||
|
panelBuilder.world(this.user.getWorld());
|
||||||
|
|
||||||
|
// Register button builders
|
||||||
|
panelBuilder.registerTypeBuilder(BUNDLES, this::createBundleButton);
|
||||||
|
|
||||||
|
// Register next and previous builders
|
||||||
|
panelBuilder.registerTypeBuilder(NEXT, this::createNextButton);
|
||||||
|
panelBuilder.registerTypeBuilder(PREVIOUS, this::createPreviousButton);
|
||||||
|
|
||||||
|
// Register unknown type builder.
|
||||||
|
panelBuilder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns if panel with the requested name is located in GameModeAddon folder.
|
||||||
|
* @param addon GameModeAddon that need to be checked.
|
||||||
|
* @param name Name of the panel.
|
||||||
|
* @return {@code true} if panel exists, {@code false} otherwise.
|
||||||
|
*/
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// Section: Buttons
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create next button panel item.
|
||||||
|
*
|
||||||
|
* @param template the template
|
||||||
|
* @param slot the slot
|
||||||
|
* @return the panel item
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private PanelItem createNextButton(@NonNull ItemTemplateRecord template, TemplatedPanel.ItemSlot slot)
|
||||||
|
{
|
||||||
|
int size = this.elementList.size();
|
||||||
|
|
||||||
|
if (size <= slot.amountMap().getOrDefault(BUNDLES, 1) ||
|
||||||
|
1.0 * size / slot.amountMap().getOrDefault(BUNDLES, 1) <= this.pageIndex + 1)
|
||||||
|
{
|
||||||
|
// There are no next elements
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nextPageIndex = this.pageIndex + 2;
|
||||||
|
|
||||||
|
PanelItemBuilder builder = new PanelItemBuilder();
|
||||||
|
|
||||||
|
if (template.icon() != null)
|
||||||
|
{
|
||||||
|
ItemStack clone = template.icon().clone();
|
||||||
|
|
||||||
|
if ((boolean) template.dataMap().getOrDefault(INDEXING, false))
|
||||||
|
{
|
||||||
|
clone.setAmount(nextPageIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.icon(clone);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (template.title() != null)
|
||||||
|
{
|
||||||
|
builder.name(this.user.getTranslation(this.mainCommand.getWorld(), template.title()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (template.description() != null)
|
||||||
|
{
|
||||||
|
builder.description(this.user.getTranslation(this.mainCommand.getWorld(), template.description(),
|
||||||
|
TextVariables.NUMBER, String.valueOf(nextPageIndex)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add ClickHandler
|
||||||
|
builder.clickHandler((panel, user, clickType, i) ->
|
||||||
|
{
|
||||||
|
template.actions().forEach(action -> {
|
||||||
|
if ((clickType == action.clickType() ||
|
||||||
|
action.clickType() == ClickType.UNKNOWN) && NEXT.equalsIgnoreCase(action.actionType()))
|
||||||
|
{
|
||||||
|
// Next button ignores click type currently.
|
||||||
|
this.pageIndex++;
|
||||||
|
this.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// Always return true.
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Collect tooltips.
|
||||||
|
List<String> 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())));
|
||||||
|
|
||||||
|
// Add tooltips.
|
||||||
|
if (!tooltips.isEmpty())
|
||||||
|
{
|
||||||
|
// Empty line and tooltips.
|
||||||
|
builder.description("");
|
||||||
|
builder.description(tooltips);
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create previous button panel item.
|
||||||
|
*
|
||||||
|
* @param template the template
|
||||||
|
* @param slot the slot
|
||||||
|
* @return the panel item
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private PanelItem createPreviousButton(@NonNull ItemTemplateRecord template, TemplatedPanel.ItemSlot slot)
|
||||||
|
{
|
||||||
|
if (this.pageIndex == 0)
|
||||||
|
{
|
||||||
|
// There are no next elements
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int previousPageIndex = this.pageIndex;
|
||||||
|
|
||||||
|
PanelItemBuilder builder = new PanelItemBuilder();
|
||||||
|
|
||||||
|
if (template.icon() != null)
|
||||||
|
{
|
||||||
|
ItemStack clone = template.icon().clone();
|
||||||
|
|
||||||
|
if ((boolean) template.dataMap().getOrDefault(INDEXING, false))
|
||||||
|
{
|
||||||
|
clone.setAmount(previousPageIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.icon(clone);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (template.title() != null)
|
||||||
|
{
|
||||||
|
builder.name(this.user.getTranslation(this.mainCommand.getWorld(), template.title()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (template.description() != null)
|
||||||
|
{
|
||||||
|
builder.description(this.user.getTranslation(this.mainCommand.getWorld(), template.description(),
|
||||||
|
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()))
|
||||||
|
{
|
||||||
|
// Next button ignores click type currently.
|
||||||
|
this.pageIndex--;
|
||||||
|
this.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// Always return true.
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Collect tooltips.
|
||||||
|
List<String> 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())));
|
||||||
|
|
||||||
|
// Add tooltips.
|
||||||
|
if (!tooltips.isEmpty())
|
||||||
|
{
|
||||||
|
// Empty line and tooltips.
|
||||||
|
builder.description("");
|
||||||
|
builder.description(tooltips);
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method creates and returns bundle button.
|
||||||
|
*
|
||||||
|
* @return PanelItem that represents bundle button.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private PanelItem createBundleButton(ItemTemplateRecord template, TemplatedPanel.ItemSlot slot)
|
||||||
|
{
|
||||||
|
if (this.elementList.isEmpty())
|
||||||
|
{
|
||||||
|
// Does not contain any sticks.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = this.pageIndex * slot.amountMap().getOrDefault(BUNDLES, 1) + slot.slot();
|
||||||
|
|
||||||
|
BlueprintBundle blueprintBundle;
|
||||||
|
|
||||||
|
if (index >= this.elementList.size())
|
||||||
|
{
|
||||||
|
// Out of index.
|
||||||
|
blueprintBundle = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
blueprintBundle = this.elementList.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (template.dataMap().containsKey("unique_id"))
|
||||||
|
{
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.createBundleButton(template, blueprintBundle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// Section: Other methods
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method creates bundle button.
|
||||||
|
*
|
||||||
|
* @return PanelItem that allows to select bundle button
|
||||||
|
*/
|
||||||
|
private PanelItem createBundleButton(ItemTemplateRecord template, BlueprintBundle bundle)
|
||||||
|
{
|
||||||
|
if (bundle == null)
|
||||||
|
{
|
||||||
|
// return as bundle is null. Empty button will be created.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String reference = "panels.island_creation.buttons.bundle.";
|
||||||
|
|
||||||
|
// Get settings for island.
|
||||||
|
PanelItemBuilder builder = new PanelItemBuilder();
|
||||||
|
|
||||||
|
if (template.icon() != null)
|
||||||
|
{
|
||||||
|
builder.icon(template.icon().clone());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
builder.icon(bundle.getIcon());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (template.title() != null)
|
||||||
|
{
|
||||||
|
builder.name(this.user.getTranslation(this.mainCommand.getWorld(), template.title(),
|
||||||
|
TextVariables.NAME, bundle.getDisplayName()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
builder.name(this.user.getTranslation(reference + "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())));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
builder.description(this.user.getTranslation(reference + "description",
|
||||||
|
TextVariables.DESCRIPTION, String.join("\n", bundle.getDescription())));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ItemTemplateRecord.ActionRecords> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Always return true.
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Collect tooltips.
|
||||||
|
List<String> 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// Section: Static methods
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is used to open Panel outside this class. It will be much easier to open panel with single method
|
||||||
|
* call then initializing new object.
|
||||||
|
*
|
||||||
|
* @param command CompositeCommand object
|
||||||
|
* @param label The main command label
|
||||||
|
* @param user User who opens panel
|
||||||
|
*/
|
||||||
|
public static void openPanel(@NonNull CompositeCommand command,
|
||||||
|
@NonNull User user,
|
||||||
|
@NonNull String label)
|
||||||
|
{
|
||||||
|
new IslandCreationPanel(command, user, label).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<BlueprintBundle> elementList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This variable holds current pageIndex for multi-page island choosing.
|
||||||
|
*/
|
||||||
|
private int pageIndex;
|
||||||
|
}
|
@ -1736,19 +1736,15 @@ panel:
|
|||||||
|
|
||||||
# This section contains values for BentoBox panels.
|
# This section contains values for BentoBox panels.
|
||||||
panels:
|
panels:
|
||||||
# The section of translations used in Language Panel
|
# The section of translations used in Island Creation Panel
|
||||||
language:
|
island_creation:
|
||||||
title: "&2&l Select your language"
|
title: "&2&l Pick an island"
|
||||||
buttons:
|
buttons:
|
||||||
# This button is used for displaying different locales that are available in language selection panel.
|
# This button is used for displaying blueprint bundle in the island creation panel.
|
||||||
language:
|
bundle:
|
||||||
name: "&f&l [name]"
|
name: "&l [name]"
|
||||||
description: |-
|
description: |-
|
||||||
[authors]
|
[description]
|
||||||
|[selected]
|
|
||||||
authors: "&7 Authors: "
|
|
||||||
author: "&7 - &b [name]"
|
|
||||||
selected: "&a Currently selected."
|
|
||||||
# The set of common buttons used in multiple panels.
|
# The set of common buttons used in multiple panels.
|
||||||
buttons:
|
buttons:
|
||||||
# Button that is used in multi-page GUIs which allows to return to previous page.
|
# Button that is used in multi-page GUIs which allows to return to previous page.
|
||||||
|
71
src/main/resources/panels/island_creation_panel.yml
Normal file
71
src/main/resources/panels/island_creation_panel.yml
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
# This is default island creation panel. It is used in all situations when gamemode addon does not have specified their
|
||||||
|
# of panel.
|
||||||
|
island_creation_panel:
|
||||||
|
title: panels.island_creation.title # The title of panel or link to the localization location.
|
||||||
|
type: INVENTORY # The type of inventory: INVENTORY, DROPPER, HOPPER
|
||||||
|
background: # The item that will be displayed in empty spots. This section can be removed.
|
||||||
|
icon: BLACK_STAINED_GLASS_PANE # The icon of background item
|
||||||
|
title: "&b&r" # Empty text # The text of background item
|
||||||
|
border: # The item that will be displayed around the inventory. This section can be removed.
|
||||||
|
icon: BLACK_STAINED_GLASS_PANE # The icon of background item
|
||||||
|
title: "&b&r" # Empty text # The text of background item
|
||||||
|
force-shown: [] # Allow to specify (1-6, 1-3, 1) which rows must be showed regardless of empty elements.
|
||||||
|
content: # Allow to define buttons in your panel.
|
||||||
|
2:
|
||||||
|
2: blueprint_bundle_button # String values are expected to be `reusables` that are defined at the end of this file.
|
||||||
|
3: blueprint_bundle_button
|
||||||
|
4: blueprint_bundle_button
|
||||||
|
5: blueprint_bundle_button
|
||||||
|
6: blueprint_bundle_button
|
||||||
|
7: blueprint_bundle_button
|
||||||
|
8: blueprint_bundle_button
|
||||||
|
3:
|
||||||
|
1:
|
||||||
|
icon: TIPPED_ARROW:INSTANT_HEAL::::1 # The icon for button
|
||||||
|
title: panels.buttons.previous.name # The name of button, or link to the localization.
|
||||||
|
description: panels.buttons.previous.description # The description of button, or link to the localization.
|
||||||
|
data:
|
||||||
|
type: PREVIOUS # Indicates what button is doing. Available values depends on panel
|
||||||
|
indexing: true # Parameter for button.
|
||||||
|
actions: # List of actions that button can do. Available values depends on button
|
||||||
|
previous:
|
||||||
|
click-type: UNKNOWN # UNKNOWN means that any click type is respected.
|
||||||
|
tooltip: panels.tips.click-to-previous # Tooltips are always generated an empty line bellow description/title. Not required.
|
||||||
|
2: blueprint_bundle_button
|
||||||
|
3: blueprint_bundle_button
|
||||||
|
4: blueprint_bundle_button
|
||||||
|
5: blueprint_bundle_button
|
||||||
|
6: blueprint_bundle_button
|
||||||
|
7: blueprint_bundle_button
|
||||||
|
8: blueprint_bundle_button
|
||||||
|
9:
|
||||||
|
icon: TIPPED_ARROW:JUMP::::1
|
||||||
|
title: panels.buttons.next.name
|
||||||
|
description: panels.buttons.next.description
|
||||||
|
data:
|
||||||
|
type: NEXT
|
||||||
|
indexing: true
|
||||||
|
actions:
|
||||||
|
next:
|
||||||
|
click-type: UNKNOWN
|
||||||
|
tooltip: panels.tips.click-to-next
|
||||||
|
4:
|
||||||
|
2: blueprint_bundle_button
|
||||||
|
3: blueprint_bundle_button
|
||||||
|
4: blueprint_bundle_button
|
||||||
|
5: blueprint_bundle_button
|
||||||
|
6: blueprint_bundle_button
|
||||||
|
7: blueprint_bundle_button
|
||||||
|
8: blueprint_bundle_button
|
||||||
|
reusable: # List of reoccurring buttons in the panels.
|
||||||
|
blueprint_bundle_button: # The ID of the button
|
||||||
|
# icon: GRASS_BLOCK
|
||||||
|
title: panels.island_creation.buttons.bundle.name
|
||||||
|
description: panels.island_creation.buttons.bundle.description
|
||||||
|
data:
|
||||||
|
type: BUNDLE
|
||||||
|
# unique_id: default # Specifying unique_id will force to show the requested bundle if it is available.
|
||||||
|
actions:
|
||||||
|
select:
|
||||||
|
click-type: UNKNOWN
|
||||||
|
tooltip: panels.tips.click-to-choose
|
@ -54,7 +54,7 @@ import world.bentobox.bentobox.managers.IslandsManager;
|
|||||||
import world.bentobox.bentobox.managers.PlayersManager;
|
import world.bentobox.bentobox.managers.PlayersManager;
|
||||||
import world.bentobox.bentobox.managers.island.NewIsland;
|
import world.bentobox.bentobox.managers.island.NewIsland;
|
||||||
import world.bentobox.bentobox.managers.island.NewIsland.Builder;
|
import world.bentobox.bentobox.managers.island.NewIsland.Builder;
|
||||||
import world.bentobox.bentobox.panels.IslandCreationPanel;
|
import world.bentobox.bentobox.panels.customizable.IslandCreationPanel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author tastybento
|
* @author tastybento
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package world.bentobox.bentobox.panels;
|
package world.bentobox.bentobox.panels.customizable;
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
@ -7,18 +7,18 @@ import static org.mockito.Mockito.mock;
|
|||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.nio.file.Path;
|
||||||
import java.util.HashMap;
|
import java.nio.file.Paths;
|
||||||
import java.util.Map;
|
import java.util.*;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.World;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.Inventory;
|
import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.inventory.ItemFactory;
|
import org.bukkit.inventory.ItemFactory;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.bukkit.plugin.PluginDescriptionFile;
|
||||||
import org.bukkit.scheduler.BukkitScheduler;
|
import org.bukkit.scheduler.BukkitScheduler;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@ -43,7 +43,6 @@ import world.bentobox.bentobox.managers.CommandsManager;
|
|||||||
import world.bentobox.bentobox.managers.IslandWorldManager;
|
import world.bentobox.bentobox.managers.IslandWorldManager;
|
||||||
import world.bentobox.bentobox.managers.IslandsManager;
|
import world.bentobox.bentobox.managers.IslandsManager;
|
||||||
import world.bentobox.bentobox.managers.PlayersManager;
|
import world.bentobox.bentobox.managers.PlayersManager;
|
||||||
import world.bentobox.bentobox.managers.island.NewIsland.Builder;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author tastybento
|
* @author tastybento
|
||||||
@ -60,8 +59,6 @@ public class IslandCreationPanelTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private IslandWorldManager iwm;
|
private IslandWorldManager iwm;
|
||||||
@Mock
|
@Mock
|
||||||
private Builder builder;
|
|
||||||
@Mock
|
|
||||||
private BentoBox plugin;
|
private BentoBox plugin;
|
||||||
@Mock
|
@Mock
|
||||||
private Settings settings;
|
private Settings settings;
|
||||||
@ -78,6 +75,11 @@ public class IslandCreationPanelTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private BlueprintBundle bb3;
|
private BlueprintBundle bb3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of the resources folder
|
||||||
|
*/
|
||||||
|
private final Path resourcePath = Paths.get("src","test","resources");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
@Before
|
@Before
|
||||||
@ -100,14 +102,25 @@ public class IslandCreationPanelTest {
|
|||||||
when(user.getUniqueId()).thenReturn(uuid);
|
when(user.getUniqueId()).thenReturn(uuid);
|
||||||
when(user.getPlayer()).thenReturn(player);
|
when(user.getPlayer()).thenReturn(player);
|
||||||
when(user.hasPermission(anyString())).thenReturn(true);
|
when(user.hasPermission(anyString())).thenReturn(true);
|
||||||
when(user.getTranslation(any()))
|
|
||||||
.thenAnswer((Answer<String>) invocation -> invocation.getArgument(0, String.class));
|
|
||||||
User.setPlugin(plugin);
|
User.setPlugin(plugin);
|
||||||
// Set up user already
|
// Set up user already
|
||||||
User.getInstance(player);
|
User.getInstance(player);
|
||||||
|
|
||||||
// Addon
|
// Addon
|
||||||
GameModeAddon addon = mock(GameModeAddon.class);
|
GameModeAddon addon = mock(GameModeAddon.class);
|
||||||
|
when(addon.getDataFolder()).thenReturn(resourcePath.toFile());
|
||||||
|
|
||||||
|
when(user.getTranslation(any())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(0, String.class));
|
||||||
|
when(user.getTranslation(any(World.class), any(), any())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(1, String.class));
|
||||||
|
when(user.getTranslation(any(String.class), any())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(0, String.class));
|
||||||
|
when(user.getTranslationOrNothing(any(), any())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(0, String.class));
|
||||||
|
|
||||||
|
when(user.getTranslation(any(World.class), eq("panels.island_creation.buttons.bundle.name"), any())).
|
||||||
|
thenAnswer((Answer<String>) invocation -> invocation.getArgument(3, String.class));
|
||||||
|
when(user.getTranslation(any(World.class), eq("panels.island_creation.buttons.bundle.description"), any())).
|
||||||
|
thenAnswer((Answer<String>) invocation -> invocation.getArgument(3, String.class));
|
||||||
|
when(plugin.getDescription()).thenAnswer((Answer<PluginDescriptionFile>) invocation ->
|
||||||
|
new PluginDescriptionFile("BentoBox", "1.0", "world.bentobox.bentobox"));
|
||||||
|
|
||||||
// Parent command has no aliases
|
// Parent command has no aliases
|
||||||
when(ic.getSubCommandAliases()).thenReturn(new HashMap<>());
|
when(ic.getSubCommandAliases()).thenReturn(new HashMap<>());
|
||||||
@ -117,6 +130,8 @@ public class IslandCreationPanelTest {
|
|||||||
when(ic.getUsage()).thenReturn("");
|
when(ic.getUsage()).thenReturn("");
|
||||||
when(ic.getSubCommand(Mockito.anyString())).thenReturn(Optional.empty());
|
when(ic.getSubCommand(Mockito.anyString())).thenReturn(Optional.empty());
|
||||||
when(ic.getAddon()).thenReturn(addon);
|
when(ic.getAddon()).thenReturn(addon);
|
||||||
|
World world = mock(World.class);
|
||||||
|
when(ic.getWorld()).thenReturn(world);
|
||||||
|
|
||||||
// No island for player to begin with (set it later in the tests)
|
// No island for player to begin with (set it later in the tests)
|
||||||
when(im.hasIsland(any(), eq(uuid))).thenReturn(false);
|
when(im.hasIsland(any(), eq(uuid))).thenReturn(false);
|
||||||
@ -184,42 +199,41 @@ public class IslandCreationPanelTest {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for
|
* Test method for
|
||||||
* {@link world.bentobox.bentobox.panels.IslandCreationPanel#openPanel(world.bentobox.bentobox.api.commands.CompositeCommand, world.bentobox.bentobox.api.user.User, java.lang.String)}.
|
* {@link world.bentobox.bentobox.panels.customizable.IslandCreationPanel#openPanel(world.bentobox.bentobox.api.commands.CompositeCommand, world.bentobox.bentobox.api.user.User, java.lang.String)}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testOpenPanel() {
|
public void testOpenPanel() {
|
||||||
IslandCreationPanel.openPanel(ic, user, "");
|
IslandCreationPanel.openPanel(ic, user, "");
|
||||||
// Check for slot being set to 0
|
|
||||||
verify(bb2).setSlot(eq(0));
|
|
||||||
verify(bb3).setSlot(eq(0));
|
|
||||||
// Set correctly
|
// Set correctly
|
||||||
verify(inv).setItem(eq(5), any());
|
verify(inv).setItem(eq(0), any());
|
||||||
|
verify(inv).setItem(eq(1), any());
|
||||||
verify(meta).setDisplayName(eq("test"));
|
verify(meta).setDisplayName(eq("test"));
|
||||||
verify(meta).setLocalizedName(eq("test"));
|
verify(meta).setLocalizedName(eq("test"));
|
||||||
verify(meta).setLore(eq(Collections.singletonList("A description")));
|
verify(meta).setLore(eq(List.of("A description", "", "panels.tips.click-to-choose")));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.bentobox.panels.IslandCreationPanel#openPanel(world.bentobox.bentobox.api.commands.CompositeCommand, world.bentobox.bentobox.api.user.User, java.lang.String)}.
|
* Test method for {@link world.bentobox.bentobox.panels.customizable.IslandCreationPanel#openPanel(world.bentobox.bentobox.api.commands.CompositeCommand, world.bentobox.bentobox.api.user.User, java.lang.String)}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testOpenPanelSameSlot() {
|
public void testOpenPanelSameSlot() {
|
||||||
when(bb2.getSlot()).thenReturn(5);
|
when(bb2.getSlot()).thenReturn(5);
|
||||||
when(bb3.getSlot()).thenReturn(5);
|
when(bb3.getSlot()).thenReturn(5);
|
||||||
IslandCreationPanel.openPanel(ic, user, "");
|
IslandCreationPanel.openPanel(ic, user, "");
|
||||||
verify(inv).setItem(eq(5), any());
|
verify(inv).setItem(eq(0), any());
|
||||||
|
verify(inv).setItem(eq(1), any());
|
||||||
verify(meta).setDisplayName(eq("test"));
|
verify(meta).setDisplayName(eq("test"));
|
||||||
verify(meta).setLocalizedName(eq("test"));
|
verify(meta).setLocalizedName(eq("test"));
|
||||||
verify(meta).setLore(eq(Collections.singletonList("A description")));
|
verify(meta).setLore(eq(List.of("A description", "", "panels.tips.click-to-choose")));
|
||||||
verify(inv).setItem(eq(0), any());
|
verify(inv).setItem(eq(0), any());
|
||||||
verify(meta).setDisplayName(eq("test2"));
|
verify(meta).setDisplayName(eq("test2"));
|
||||||
verify(meta).setLocalizedName(eq("test2"));
|
verify(meta).setLocalizedName(eq("test2"));
|
||||||
verify(meta).setLore(eq(Collections.singletonList("A description 2")));
|
verify(meta).setLore(eq(List.of("A description 2", "", "panels.tips.click-to-choose")));
|
||||||
verify(inv).setItem(eq(1), any());
|
verify(inv).setItem(eq(1), any());
|
||||||
verify(meta).setDisplayName(eq("test3"));
|
verify(meta).setDisplayName(eq("test3"));
|
||||||
verify(meta).setLocalizedName(eq("test3"));
|
verify(meta).setLocalizedName(eq("test3"));
|
||||||
verify(meta).setLore(eq(Collections.singletonList("A description 3")));
|
verify(meta).setLore(eq(List.of("A description 3", "", "panels.tips.click-to-choose")));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
29
src/test/resources/panels/island_creation_panel.yml
Normal file
29
src/test/resources/panels/island_creation_panel.yml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# This is default island creation panel. It is used in all situations when gamemode addon does not have specified their
|
||||||
|
# of panel.
|
||||||
|
island_creation_panel:
|
||||||
|
title: panels.island_creation.title # The title of panel or link to the localization location.
|
||||||
|
type: INVENTORY # The type of inventory: INVENTORY, DROPPER, HOPPER
|
||||||
|
force-shown: [] # Allow to specify (1-6, 1-3, 1) which rows must be showed regardless of empty elements.
|
||||||
|
content: # Allow to define buttons in your panel.
|
||||||
|
1:
|
||||||
|
1: blueprint_bundle_button # String values are expected to be `reusables` that are defined at the end of this file.
|
||||||
|
2: blueprint_bundle_button
|
||||||
|
3: blueprint_bundle_button
|
||||||
|
4: blueprint_bundle_button
|
||||||
|
5: blueprint_bundle_button
|
||||||
|
6: blueprint_bundle_button
|
||||||
|
7: blueprint_bundle_button
|
||||||
|
8: blueprint_bundle_button
|
||||||
|
9: blueprint_bundle_button
|
||||||
|
reusable: # List of reoccurring buttons in the panels.
|
||||||
|
blueprint_bundle_button: # The ID of the button
|
||||||
|
# icon: GRASS_BLOCK
|
||||||
|
title: panels.island_creation.buttons.bundle.name
|
||||||
|
description: panels.island_creation.buttons.bundle.description
|
||||||
|
data:
|
||||||
|
type: BUNDLE
|
||||||
|
# unique_id: default # Specifying unique_id will force to show the requested bundle if it is available.
|
||||||
|
actions:
|
||||||
|
select:
|
||||||
|
click-type: UNKNOWN
|
||||||
|
tooltip: panels.tips.click-to-choose
|
Loading…
Reference in New Issue
Block a user