mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2024-11-01 00:10:40 +01:00
Adds an island home panel. #2531
Also enhances the customizable panel API by making templates load dynamically when requested.
This commit is contained in:
parent
58690f203b
commit
e0a3f48aed
@ -1,7 +1,5 @@
|
||||
package world.bentobox.bentobox;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@ -466,16 +464,6 @@ public class BentoBox extends JavaPlugin implements Listener {
|
||||
return false;
|
||||
}
|
||||
|
||||
log("Saving default panels...");
|
||||
if (!Files.exists(Path.of(this.getDataFolder().getPath(), "panels", "island_creation_panel.yml"))) {
|
||||
log("Saving default island_creation_panel...");
|
||||
this.saveResource("panels/island_creation_panel.yml", false);
|
||||
}
|
||||
|
||||
if (!Files.exists(Path.of(this.getDataFolder().getPath(), "panels", "language_panel.yml"))) {
|
||||
log("Saving default language_panel...");
|
||||
this.saveResource("panels/language_panel.yml", false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -346,7 +346,7 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi
|
||||
*
|
||||
* @return IslandsManager
|
||||
*/
|
||||
protected IslandsManager getIslands() {
|
||||
public IslandsManager getIslands() {
|
||||
return plugin.getIslands();
|
||||
}
|
||||
|
||||
|
@ -61,9 +61,9 @@ public class IslandGoCommand extends DelayedTeleportCommand {
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
Map<String, IslandInfo> names = getNameIslandMap(user);
|
||||
// Check if the home is known
|
||||
if (!args.isEmpty()) {
|
||||
Map<String, IslandInfo> names = getNameIslandMap(user);
|
||||
final String name = String.join(" ", args);
|
||||
if (!names.containsKey(name)) {
|
||||
// Failed home name check
|
||||
@ -113,7 +113,11 @@ public class IslandGoCommand extends DelayedTeleportCommand {
|
||||
|
||||
}
|
||||
|
||||
private record IslandInfo(Island island, boolean islandName) {}
|
||||
/**
|
||||
* Record of islands and the name to type
|
||||
*/
|
||||
private record IslandInfo(Island island, boolean islandName) {
|
||||
}
|
||||
|
||||
private Map<String, IslandInfo> getNameIslandMap(User user) {
|
||||
Map<String, IslandInfo> islandMap = new HashMap<>();
|
||||
@ -129,7 +133,8 @@ public class IslandGoCommand extends DelayedTeleportCommand {
|
||||
islandMap.put(text, new IslandInfo(island, true));
|
||||
}
|
||||
// Add homes. Homes do not need an island specified
|
||||
island.getHomes().keySet().forEach(n -> islandMap.put(n, new IslandInfo(island, false)));
|
||||
island.getHomes().keySet().stream().filter(n -> !n.isBlank())
|
||||
.forEach(n -> islandMap.put(n, new IslandInfo(island, false)));
|
||||
}
|
||||
|
||||
return islandMap;
|
||||
|
@ -1,19 +1,12 @@
|
||||
package world.bentobox.bentobox.api.commands.island;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.commands.ConfirmableCommand;
|
||||
import world.bentobox.bentobox.api.localization.TextVariables;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.database.objects.Island;
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
import world.bentobox.bentobox.panels.customizable.IslandHomesPanel;
|
||||
|
||||
public class IslandHomesCommand extends ConfirmableCommand {
|
||||
|
||||
private List<Island> islands;
|
||||
public class IslandHomesCommand extends CompositeCommand {
|
||||
|
||||
public IslandHomesCommand(CompositeCommand islandCommand) {
|
||||
super(islandCommand, "homes");
|
||||
@ -28,9 +21,8 @@ public class IslandHomesCommand extends ConfirmableCommand {
|
||||
|
||||
@Override
|
||||
public boolean canExecute(User user, String label, List<String> args) {
|
||||
islands = getIslands().getIslands(getWorld(), user);
|
||||
// Check island
|
||||
if (islands.isEmpty()) {
|
||||
if (getIslands().getIslands(getWorld(), user).isEmpty()) {
|
||||
user.sendMessage("general.errors.no-island");
|
||||
return false;
|
||||
}
|
||||
@ -39,22 +31,8 @@ public class IslandHomesCommand extends ConfirmableCommand {
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
user.sendMessage("commands.island.sethome.homes-are");
|
||||
islands.forEach(island ->
|
||||
island.getHomes().keySet().stream().filter(s -> !s.isEmpty())
|
||||
.forEach(s -> user.sendMessage("commands.island.sethome.home-list-syntax", TextVariables.NAME, s)));
|
||||
IslandHomesPanel.openPanel(this, user);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<List<String>> tabComplete(User user, String alias, List<String> args) {
|
||||
String lastArg = !args.isEmpty() ? args.get(args.size()-1) : "";
|
||||
List<String> result = new ArrayList<>();
|
||||
for (Island island : getIslands().getIslands(getWorld(), user.getUniqueId())) {
|
||||
result.addAll(island.getHomes().keySet());
|
||||
}
|
||||
return Optional.of(Util.tabLimit(result, lastArg));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -90,15 +90,29 @@ public class TemplateReader
|
||||
}
|
||||
|
||||
File file = new File(panelLocation, templateName.endsWith(YML) ? templateName : templateName + YML);
|
||||
|
||||
String absolutePath = file.getAbsolutePath();
|
||||
if (!file.exists())
|
||||
{
|
||||
// Try to get it from the JAR
|
||||
|
||||
String keyword = "panels/";
|
||||
|
||||
// Find the index of the keyword "panels/"
|
||||
int index = absolutePath.indexOf(keyword);
|
||||
|
||||
// If the keyword is found, extract the substring starting from that index
|
||||
if (index != -1) {
|
||||
BentoBox.getInstance().saveResource(absolutePath.substring(index), false);
|
||||
file = new File(panelLocation, templateName.endsWith(YML) ? templateName : templateName + YML);
|
||||
} else {
|
||||
BentoBox.getInstance().logError(file.getAbsolutePath() + " does not exist for panel template");
|
||||
// Return as file does not exist.
|
||||
return null;
|
||||
}
|
||||
|
||||
final String panelKey = file.getAbsolutePath() + ":" + panelName;
|
||||
}
|
||||
|
||||
final String panelKey = absolutePath + ":" + panelName;
|
||||
|
||||
// Check if panel is already crafted.
|
||||
if (TemplateReader.loadedPanels.containsKey(panelKey))
|
||||
|
@ -0,0 +1,419 @@
|
||||
package world.bentobox.bentobox.panels.customizable;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.commands.island.IslandGoCommand;
|
||||
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.database.objects.Island;
|
||||
|
||||
|
||||
/**
|
||||
* Panel for island homes command
|
||||
*/
|
||||
public class IslandHomesPanel extends AbstractPanel
|
||||
{
|
||||
|
||||
private static final String ISLAND = "ISLAND";
|
||||
|
||||
|
||||
/**
|
||||
* This variable stores filtered elements.
|
||||
*/
|
||||
private final Map<String, IslandInfo> islandMap;
|
||||
private final Map<Integer, String> order = new HashMap<>();
|
||||
|
||||
|
||||
/**
|
||||
* The world that this command applies to
|
||||
*/
|
||||
private final World world;
|
||||
|
||||
private final IslandGoCommand goCommand;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Constructor
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* This is internal constructor. It is used internally in current class to avoid creating objects everywhere.
|
||||
*
|
||||
* @param command CompositeCommand
|
||||
* @param user User who opens panel
|
||||
* @param islandMap map of island names and IslandInfo
|
||||
*/
|
||||
private IslandHomesPanel(@NonNull CompositeCommand command, @NonNull User user)
|
||||
{
|
||||
super(command, user);
|
||||
this.world = command.getWorld();
|
||||
this.islandMap = this.getNameIslandMap(user);
|
||||
int index = 0;
|
||||
for (String name : islandMap.keySet()) {
|
||||
order.put(index++, name);
|
||||
}
|
||||
goCommand = (IslandGoCommand) command.getParent().getSubCommand("go").orElse(null);
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Methods
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* Build method manages current panel opening. It uses BentoBox PanelAPI that is easy to use and users can get nice
|
||||
* panels.
|
||||
*/
|
||||
@Override
|
||||
protected void build()
|
||||
{
|
||||
// Do not open gui if there are no islands
|
||||
if (this.islandMap.isEmpty())
|
||||
{
|
||||
user.sendMessage("general.errors.no-island");
|
||||
return;
|
||||
}
|
||||
|
||||
// Start building panel.
|
||||
TemplatedPanelBuilder panelBuilder = new TemplatedPanelBuilder();
|
||||
|
||||
// Set main template.
|
||||
if (this.doesCustomPanelExists(this.command.getAddon(), "island_homes_panel"))
|
||||
{
|
||||
// Addon has its own island homes panel. Use it.
|
||||
panelBuilder.template("island_homes_panel", new File(this.command.getAddon().getDataFolder(), "panels"));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use default island creation panel.
|
||||
panelBuilder.template("island_homes_panel", new File(this.plugin.getDataFolder(), "panels"));
|
||||
}
|
||||
|
||||
panelBuilder.user(this.user);
|
||||
panelBuilder.world(world);
|
||||
|
||||
// Register button builders
|
||||
panelBuilder.registerTypeBuilder(ISLAND, this::createIslandButton);
|
||||
|
||||
// Register next and previous builders
|
||||
panelBuilder.registerTypeBuilder(NEXT, this::createNextButton);
|
||||
panelBuilder.registerTypeBuilder(PREVIOUS, this::createPreviousButton);
|
||||
|
||||
// Register unknown type builder.
|
||||
panelBuilder.build();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Buttons
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* Create next button panel item.
|
||||
*
|
||||
* @param template the template
|
||||
* @param slot the slot
|
||||
* @return the panel item
|
||||
*/
|
||||
@Override
|
||||
@Nullable
|
||||
protected PanelItem createNextButton(@NonNull ItemTemplateRecord template, TemplatedPanel.ItemSlot slot)
|
||||
{
|
||||
int size = this.islandMap.size();
|
||||
|
||||
if (size <= slot.amountMap().getOrDefault(ISLAND, 1)
|
||||
|| 1.0 * size / slot.amountMap().getOrDefault(ISLAND, 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.command.getWorld(), template.title()));
|
||||
}
|
||||
|
||||
if (template.description() != null)
|
||||
{
|
||||
builder.description(this.user.getTranslation(this.command.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.command.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
|
||||
@Override
|
||||
protected 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.command.getWorld(), template.title()));
|
||||
}
|
||||
|
||||
if (template.description() != null)
|
||||
{
|
||||
builder.description(this.user.getTranslation(this.command.getWorld(), template.description(),
|
||||
TextVariables.NUMBER, String.valueOf(previousPageIndex)));
|
||||
}
|
||||
|
||||
// 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.command.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 island button.
|
||||
*
|
||||
* @return PanelItem that represents island button.
|
||||
*/
|
||||
@Nullable
|
||||
private PanelItem createIslandButton(ItemTemplateRecord template, TemplatedPanel.ItemSlot slot)
|
||||
{
|
||||
if (this.islandMap.isEmpty())
|
||||
{
|
||||
// Does not contain any islands.
|
||||
return null;
|
||||
}
|
||||
|
||||
int index = this.pageIndex * slot.amountMap().getOrDefault(ISLAND, 1) + slot.slot();
|
||||
if (index >= this.islandMap.size())
|
||||
{
|
||||
// Out of index.
|
||||
return null;
|
||||
}
|
||||
return this.createIslandButtonDetail(template, slot);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method creates bundle button.
|
||||
*
|
||||
* @return PanelItem that allows to select bundle button
|
||||
*/
|
||||
private PanelItem createIslandButtonDetail(ItemTemplateRecord template, TemplatedPanel.ItemSlot slot)
|
||||
{
|
||||
// Get settings for island.
|
||||
PanelItemBuilder builder = new PanelItemBuilder();
|
||||
|
||||
if (template.icon() != null)
|
||||
{
|
||||
builder.icon(template.icon().clone());
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.icon(Material.GRASS_BLOCK);
|
||||
}
|
||||
|
||||
if (template.title() != null)
|
||||
{
|
||||
builder.name(this.user.getTranslation(this.command.getWorld(), template.title(),
|
||||
TextVariables.NAME, order.get(slot.slot())));
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.name(this.user.getTranslation("panels.island_homes.buttons.name", TextVariables.NAME,
|
||||
order.get(slot.slot())));
|
||||
}
|
||||
|
||||
// Add ClickHandler
|
||||
builder.clickHandler((panel, user, clickType, i) -> {
|
||||
template.actions().forEach(action -> {
|
||||
if (goCommand != null) {
|
||||
String name = order.get(slot.slot());
|
||||
user.closeInventory();
|
||||
if (goCommand.canExecute(user, "", List.of(name))) {
|
||||
goCommand.execute(user, "", List.of(name));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Always return true.
|
||||
return true;
|
||||
});
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Record of islands and the name to type
|
||||
*/
|
||||
private record IslandInfo(Island island, boolean islandName) {
|
||||
}
|
||||
|
||||
/**
|
||||
* This is duplicate code from the Go command.
|
||||
* @param user user
|
||||
* @return name and island info
|
||||
*/
|
||||
private Map<String, IslandInfo> getNameIslandMap(User user) {
|
||||
Map<String, IslandInfo> islandMap = new HashMap<>();
|
||||
int index = 0;
|
||||
for (Island island : command.getIslands().getIslands(command.getWorld(), user.getUniqueId())) {
|
||||
index++;
|
||||
if (island.getName() != null && !island.getName().isBlank()) {
|
||||
// Name has been set
|
||||
islandMap.put(island.getName(), new IslandInfo(island, true));
|
||||
} else {
|
||||
// Name has not been set
|
||||
String text = user.getTranslation("protection.flags.ENTER_EXIT_MESSAGES.island", TextVariables.NAME,
|
||||
user.getName(), TextVariables.DISPLAY_NAME, user.getDisplayName()) + " " + index;
|
||||
islandMap.put(text, new IslandInfo(island, true));
|
||||
}
|
||||
// Add homes. Homes do not need an island specified
|
||||
island.getHomes().keySet().stream().filter(n -> !n.isBlank())
|
||||
.forEach(n -> islandMap.put(n, new IslandInfo(island, false)));
|
||||
}
|
||||
|
||||
return islandMap;
|
||||
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// 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 user User who opens panel
|
||||
*/
|
||||
public static void openPanel(@NonNull CompositeCommand command, @NonNull User user) {
|
||||
new IslandHomesPanel(command, user).build();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1906,6 +1906,12 @@ panel:
|
||||
|
||||
# This section contains values for BentoBox panels.
|
||||
panels:
|
||||
# The section of translations used in Island Homes Panel
|
||||
island_homes:
|
||||
title: "&2&l Your island homes"
|
||||
buttons:
|
||||
# This button is used for displaying islands to teleport to
|
||||
name: "&l [name]"
|
||||
# The section of translations used in Island Creation Panel
|
||||
island_creation:
|
||||
title: "&2&l Pick an island"
|
||||
|
69
src/main/resources/panels/island_homes_panel.yml
Normal file
69
src/main/resources/panels/island_homes_panel.yml
Normal file
@ -0,0 +1,69 @@
|
||||
# This is default island homes panel. It is used in all situations when gamemode addon does not have specified their
|
||||
# of panel.
|
||||
island_homes_panel:
|
||||
title: panels.island_go.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: island_button # String values are expected to be `reusables` that are defined at the end of this file.
|
||||
3: island_button
|
||||
4: island_button
|
||||
5: island_button
|
||||
6: island_button
|
||||
7: island_button
|
||||
8: island_button
|
||||
3:
|
||||
1:
|
||||
icon: tipped_arrow{CustomPotionColor:11546150} # 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: island_button
|
||||
3: island_button
|
||||
4: island_button
|
||||
5: island_button
|
||||
6: island_button
|
||||
7: island_button
|
||||
8: island_button
|
||||
9:
|
||||
icon: tipped_arrow{CustomPotionColor:8439583}
|
||||
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: island_button
|
||||
3: island_button
|
||||
4: island_button
|
||||
5: island_button
|
||||
6: island_button
|
||||
7: island_button
|
||||
8: island_button
|
||||
reusable: # List of reoccurring buttons in the panels.
|
||||
island_button: # The ID of the button
|
||||
# icon: GRASS_BLOCK
|
||||
title: panels.island_homes.buttons.name
|
||||
data:
|
||||
type: ISLAND
|
||||
actions:
|
||||
select:
|
||||
click-type: UNKNOWN
|
||||
tooltip: panels.tips.click-to-choose
|
Loading…
Reference in New Issue
Block a user