mirror of
https://github.com/BentoBoxWorld/Level.git
synced 2024-12-25 10:38:20 +01:00
Implement customizable Values GUI. (#262)
This GUI shows value to all items in game. It also shows max limit of blocks, if it is set. Fixes of #192
This commit is contained in:
parent
cc90579f51
commit
47053fde31
2
pom.xml
2
pom.xml
@ -61,7 +61,7 @@
|
||||
<spigot.version>1.16.5-R0.1-SNAPSHOT</spigot.version>
|
||||
<bentobox.version>1.20.0</bentobox.version>
|
||||
<!-- Panel Utils version -->
|
||||
<panelutils.version>1.0.0</panelutils.version>
|
||||
<panelutils.version>1.1.0</panelutils.version>
|
||||
<!-- Revision variable removes warning about dynamic version -->
|
||||
<revision>${build.version}-SNAPSHOT</revision>
|
||||
<!-- Do not change unless you want different name for local builds. -->
|
||||
|
@ -78,6 +78,7 @@ public class Level extends Addon implements Listener {
|
||||
// Save existing panels.
|
||||
this.saveResource("panels/top_panel.yml", false);
|
||||
this.saveResource("panels/detail_panel.yml", false);
|
||||
this.saveResource("panels/value_panel.yml", false);
|
||||
}
|
||||
|
||||
private boolean loadSettings() {
|
||||
|
@ -1,6 +1,9 @@
|
||||
package world.bentobox.level.commands;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -8,43 +11,132 @@ import org.bukkit.inventory.PlayerInventory;
|
||||
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
import world.bentobox.level.Level;
|
||||
import world.bentobox.level.panels.ValuePanel;
|
||||
import world.bentobox.level.util.Utils;
|
||||
|
||||
public class IslandValueCommand extends CompositeCommand {
|
||||
|
||||
public class IslandValueCommand extends CompositeCommand
|
||||
{
|
||||
private final Level addon;
|
||||
|
||||
public IslandValueCommand(Level addon, CompositeCommand parent) {
|
||||
|
||||
public IslandValueCommand(Level addon, CompositeCommand parent)
|
||||
{
|
||||
super(parent, "value");
|
||||
this.addon = addon;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
public void setup()
|
||||
{
|
||||
this.setPermission("island.value");
|
||||
this.setDescription("island.value.description");
|
||||
this.setParametersHelp("level.commands.value.parameters");
|
||||
this.setDescription("level.commands.value.description");
|
||||
this.setOnlyPlayer(true);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
Player player = user.getPlayer();
|
||||
PlayerInventory inventory = player.getInventory();
|
||||
if (!inventory.getItemInMainHand().getType().equals(Material.AIR)) {
|
||||
Material material = inventory.getItemInMainHand().getType();
|
||||
Integer value = addon.getBlockConfig().getValue(getWorld(), material);
|
||||
if (value != null) {
|
||||
user.sendMessage("island.value.success", "[value]", String.valueOf(value));
|
||||
double underWater = addon.getSettings().getUnderWaterMultiplier();
|
||||
if (underWater > 1.0) {
|
||||
user.sendMessage("island.value.success-underwater", "[value]", (underWater * value) + "");
|
||||
}
|
||||
} else {
|
||||
user.sendMessage("island.value.no-value");
|
||||
}
|
||||
} else {
|
||||
user.sendMessage("island.value.empty-hand");
|
||||
public boolean execute(User user, String label, List<String> args)
|
||||
{
|
||||
if (args.size() > 1)
|
||||
{
|
||||
this.showHelp(this, user);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.isEmpty())
|
||||
{
|
||||
ValuePanel.openPanel(this.addon, this.getWorld(), user);
|
||||
}
|
||||
else if (args.get(0).equalsIgnoreCase("HAND"))
|
||||
{
|
||||
Player player = user.getPlayer();
|
||||
PlayerInventory inventory = player.getInventory();
|
||||
|
||||
if (!inventory.getItemInMainHand().getType().equals(Material.AIR))
|
||||
{
|
||||
this.printValue(user, inventory.getItemInMainHand().getType());
|
||||
}
|
||||
else
|
||||
{
|
||||
Utils.sendMessage(user, user.getTranslation("level.conversations.empty-hand"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Material material = Material.matchMaterial(args.get(0));
|
||||
|
||||
if (material == null)
|
||||
{
|
||||
Utils.sendMessage(user,
|
||||
user.getTranslation(this.getWorld(), "level.conversations.unknown-item",
|
||||
"[material]", args.get(0)));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.printValue(user, material);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method prints value of the given material in chat.
|
||||
* @param user User who receives the message.
|
||||
* @param material Material value.
|
||||
*/
|
||||
private void printValue(User user, Material material)
|
||||
{
|
||||
Integer value = this.addon.getBlockConfig().getValue(getWorld(), material);
|
||||
|
||||
if (value != null)
|
||||
{
|
||||
Utils.sendMessage(user,
|
||||
user.getTranslation(this.getWorld(), "level.conversations.value",
|
||||
"[value]", String.valueOf(value),
|
||||
"[material]", Utils.prettifyObject(material, user)));
|
||||
|
||||
double underWater = this.addon.getSettings().getUnderWaterMultiplier();
|
||||
|
||||
if (underWater > 1.0)
|
||||
{
|
||||
Utils.sendMessage(user,
|
||||
user.getTranslation(this.getWorld(),"level.conversations.success-underwater",
|
||||
"[value]", (underWater * value) + ""),
|
||||
"[material]", Utils.prettifyObject(material, user));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Utils.sendMessage(user,
|
||||
user.getTranslation(this.getWorld(),"level.conversations.no-value"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Optional<List<String>> tabComplete(User user, String alias, List<String> args)
|
||||
{
|
||||
String lastArg = !args.isEmpty() ? args.get(args.size() - 1) : "";
|
||||
|
||||
if (args.isEmpty())
|
||||
{
|
||||
// Don't show every player on the server. Require at least the first letter
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
List<String> options = new ArrayList<>(Arrays.stream(Material.values()).
|
||||
filter(Material::isBlock).
|
||||
map(Material::name).toList());
|
||||
|
||||
options.add("HAND");
|
||||
|
||||
return Optional.of(Util.tabLimit(options, lastArg));
|
||||
}
|
||||
}
|
@ -165,8 +165,8 @@ public class DetailsPanel
|
||||
{
|
||||
if (o1.getValue().equals(o2.getValue()))
|
||||
{
|
||||
String o1Name = DetailsPanel.prettifyObject(o1.getKey(), this.user);
|
||||
String o2Name = DetailsPanel.prettifyObject(o2.getKey(), this.user);
|
||||
String o1Name = Utils.prettifyObject(o1.getKey(), this.user);
|
||||
String o2Name = Utils.prettifyObject(o2.getKey(), this.user);
|
||||
|
||||
return String.CASE_INSENSITIVE_ORDER.compare(o1Name, o2Name);
|
||||
}
|
||||
@ -193,8 +193,8 @@ public class DetailsPanel
|
||||
|
||||
if (o1Value == o2Value)
|
||||
{
|
||||
String o1Name = DetailsPanel.prettifyObject(o1.getKey(), this.user);
|
||||
String o2Name = DetailsPanel.prettifyObject(o2.getKey(), this.user);
|
||||
String o1Name = Utils.prettifyObject(o1.getKey(), this.user);
|
||||
String o2Name = Utils.prettifyObject(o2.getKey(), this.user);
|
||||
|
||||
return String.CASE_INSENSITIVE_ORDER.compare(o1Name, o2Name);
|
||||
}
|
||||
@ -208,8 +208,8 @@ public class DetailsPanel
|
||||
{
|
||||
sorter = (o1, o2) ->
|
||||
{
|
||||
String o1Name = DetailsPanel.prettifyObject(o1.getKey(), this.user);
|
||||
String o2Name = DetailsPanel.prettifyObject(o2.getKey(), this.user);
|
||||
String o1Name = Utils.prettifyObject(o1.getKey(), this.user);
|
||||
String o2Name = Utils.prettifyObject(o2.getKey(), this.user);
|
||||
|
||||
return String.CASE_INSENSITIVE_ORDER.compare(o1Name, o2Name);
|
||||
};
|
||||
@ -647,10 +647,10 @@ public class DetailsPanel
|
||||
{
|
||||
builder.name(this.user.getTranslation(this.world, template.title(),
|
||||
"[number]", String.valueOf(materialCount.getValue()),
|
||||
"[material]", DetailsPanel.prettifyObject(materialCount.getKey(), this.user)));
|
||||
"[material]", Utils.prettifyObject(materialCount.getKey(), this.user)));
|
||||
}
|
||||
|
||||
String description = DetailsPanel.prettifyDescription(materialCount.getKey(), this.user);
|
||||
String description = Utils.prettifyDescription(materialCount.getKey(), this.user);
|
||||
|
||||
final String reference = "level.gui.buttons.material.";
|
||||
String blockId = this.user.getTranslationOrNothing(reference + "id",
|
||||
@ -710,95 +710,6 @@ public class DetailsPanel
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prettify Material object for user.
|
||||
* @param object Object that must be pretty.
|
||||
* @param user User who will see the object.
|
||||
* @return Prettified string for Material.
|
||||
*/
|
||||
private static String prettifyObject(Material object, User user)
|
||||
{
|
||||
// Nothing to translate
|
||||
if (object == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
// Find addon structure with:
|
||||
// [addon]:
|
||||
// materials:
|
||||
// [material]:
|
||||
// name: [name]
|
||||
String translation = user.getTranslationOrNothing("level.materials." + object.name().toLowerCase() + ".name");
|
||||
|
||||
if (!translation.isEmpty())
|
||||
{
|
||||
// We found our translation.
|
||||
return translation;
|
||||
}
|
||||
|
||||
// Find addon structure with:
|
||||
// [addon]:
|
||||
// materials:
|
||||
// [material]: [name]
|
||||
|
||||
translation = user.getTranslationOrNothing("level.materials." + object.name().toLowerCase());
|
||||
|
||||
if (!translation.isEmpty())
|
||||
{
|
||||
// We found our translation.
|
||||
return translation;
|
||||
}
|
||||
|
||||
// Find general structure with:
|
||||
// materials:
|
||||
// [material]: [name]
|
||||
|
||||
translation = user.getTranslationOrNothing("materials." + object.name().toLowerCase());
|
||||
|
||||
if (!translation.isEmpty())
|
||||
{
|
||||
// We found our translation.
|
||||
return translation;
|
||||
}
|
||||
|
||||
// Use Lang Utils Hook to translate material
|
||||
return LangUtilsHook.getMaterialName(object, user);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prettify Material object description for user.
|
||||
* @param object Object that must be pretty.
|
||||
* @param user User who will see the object.
|
||||
* @return Prettified description string for Material.
|
||||
*/
|
||||
public static String prettifyDescription(Material object, User user)
|
||||
{
|
||||
// Nothing to translate
|
||||
if (object == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
// Find addon structure with:
|
||||
// [addon]:
|
||||
// materials:
|
||||
// [material]:
|
||||
// description: [text]
|
||||
String translation = user.getTranslationOrNothing("level.materials." + object.name().toLowerCase() + ".description");
|
||||
|
||||
if (!translation.isEmpty())
|
||||
{
|
||||
// We found our translation.
|
||||
return translation;
|
||||
}
|
||||
|
||||
// No text to return.
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Enums
|
||||
// ---------------------------------------------------------------------
|
||||
|
773
src/main/java/world/bentobox/level/panels/ValuePanel.java
Normal file
773
src/main/java/world/bentobox/level/panels/ValuePanel.java
Normal file
@ -0,0 +1,773 @@
|
||||
package world.bentobox.level.panels;
|
||||
|
||||
|
||||
import com.google.common.base.Enums;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import lv.id.bonne.panelutils.PanelUtils;
|
||||
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.hooks.LangUtilsHook;
|
||||
import world.bentobox.bentobox.util.Pair;
|
||||
import world.bentobox.level.Level;
|
||||
import world.bentobox.level.util.ConversationUtils;
|
||||
import world.bentobox.level.util.Utils;
|
||||
|
||||
|
||||
/**
|
||||
* This class opens GUI that shows generator view for user.
|
||||
*/
|
||||
public class ValuePanel
|
||||
{
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Internal Constructor
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* This is internal constructor. It is used internally in current class to avoid creating objects everywhere.
|
||||
*
|
||||
* @param addon Level object
|
||||
* @param world World where user is operating
|
||||
* @param user User who opens panel
|
||||
*/
|
||||
private ValuePanel(Level addon,
|
||||
World world,
|
||||
User user)
|
||||
{
|
||||
this.addon = addon;
|
||||
this.world = world;
|
||||
this.user = user;
|
||||
|
||||
this.activeFilter = Filter.NAME_ASC;
|
||||
this.materialRecordList = Arrays.stream(Material.values()).
|
||||
filter(Material::isBlock).
|
||||
filter(m -> !m.name().startsWith("LEGACY_")).
|
||||
map(material ->
|
||||
{
|
||||
Integer value = this.addon.getBlockConfig().getValue(this.world, material);
|
||||
Integer limit = this.addon.getBlockConfig().getBlockLimits().get(material);
|
||||
|
||||
return new MaterialRecord(material,
|
||||
value != null ? value : 0,
|
||||
limit != null ? limit : 0);
|
||||
}).
|
||||
collect(Collectors.toList());
|
||||
|
||||
this.elementList = new ArrayList<>(Material.values().length);
|
||||
this.searchText = "";
|
||||
|
||||
this.updateFilters();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method builds this GUI.
|
||||
*/
|
||||
private void build()
|
||||
{
|
||||
// Start building panel.
|
||||
TemplatedPanelBuilder panelBuilder = new TemplatedPanelBuilder();
|
||||
panelBuilder.user(this.user);
|
||||
panelBuilder.world(this.user.getWorld());
|
||||
|
||||
panelBuilder.template("value_panel", new File(this.addon.getDataFolder(), "panels"));
|
||||
|
||||
panelBuilder.registerTypeBuilder("NEXT", this::createNextButton);
|
||||
panelBuilder.registerTypeBuilder("PREVIOUS", this::createPreviousButton);
|
||||
panelBuilder.registerTypeBuilder("BLOCK", this::createMaterialButton);
|
||||
|
||||
panelBuilder.registerTypeBuilder("FILTER", this::createFilterButton);
|
||||
panelBuilder.registerTypeBuilder("SEARCH", this::createSearchButton);
|
||||
|
||||
// Register unknown type builder.
|
||||
panelBuilder.build();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method updates filter of elements based on tabs.
|
||||
*/
|
||||
private void updateFilters()
|
||||
{
|
||||
Comparator<MaterialRecord> sorter;
|
||||
|
||||
switch (this.activeFilter)
|
||||
{
|
||||
case VALUE_ASC ->
|
||||
{
|
||||
sorter = (o1, o2) ->
|
||||
{
|
||||
if (o1.value().equals(o2.value()))
|
||||
{
|
||||
String o1Name = Utils.prettifyObject(o1.material(), this.user);
|
||||
String o2Name = Utils.prettifyObject(o2.material(), this.user);
|
||||
|
||||
return String.CASE_INSENSITIVE_ORDER.compare(o1Name, o2Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Integer.compare(o1.value(), o2.value());
|
||||
}
|
||||
};
|
||||
}
|
||||
case VALUE_DESC ->
|
||||
{
|
||||
sorter = (o1, o2) ->
|
||||
{
|
||||
if (o1.value().equals(o2.value()))
|
||||
{
|
||||
String o1Name = Utils.prettifyObject(o1.material(), this.user);
|
||||
String o2Name = Utils.prettifyObject(o2.material(), this.user);
|
||||
|
||||
return String.CASE_INSENSITIVE_ORDER.compare(o1Name, o2Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Integer.compare(o2.value(), o1.value());
|
||||
}
|
||||
};
|
||||
}
|
||||
case NAME_DESC ->
|
||||
{
|
||||
sorter = (o1, o2) ->
|
||||
{
|
||||
String o1Name = Utils.prettifyObject(o1.material(), this.user);
|
||||
String o2Name = Utils.prettifyObject(o2.material(), this.user);
|
||||
|
||||
return String.CASE_INSENSITIVE_ORDER.compare(o2Name, o1Name);
|
||||
};
|
||||
}
|
||||
default ->
|
||||
{
|
||||
sorter = (o1, o2) ->
|
||||
{
|
||||
String o1Name = Utils.prettifyObject(o1.material(), this.user);
|
||||
String o2Name = Utils.prettifyObject(o2.material(), this.user);
|
||||
|
||||
return String.CASE_INSENSITIVE_ORDER.compare(o1Name, o2Name);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
this.materialRecordList.sort(sorter);
|
||||
|
||||
if (!this.searchText.isBlank())
|
||||
{
|
||||
this.elementList = new ArrayList<>(this.materialRecordList.size());
|
||||
final String text = this.searchText.toLowerCase();
|
||||
|
||||
this.materialRecordList.forEach(record ->
|
||||
{
|
||||
if (record.material.name().toLowerCase().contains(text) ||
|
||||
Utils.prettifyObject(record.material(), this.user).toLowerCase().contains(text))
|
||||
{
|
||||
this.elementList.add(record);
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
this.elementList = this.materialRecordList;
|
||||
}
|
||||
|
||||
this.pageIndex = 0;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Tab Button Type
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* Create tab button panel item.
|
||||
*
|
||||
* @param template the template
|
||||
* @param slot the slot
|
||||
* @return the panel item
|
||||
*/
|
||||
private PanelItem createSearchButton(ItemTemplateRecord template, TemplatedPanel.ItemSlot slot)
|
||||
{
|
||||
PanelItemBuilder builder = new PanelItemBuilder();
|
||||
|
||||
if (template.icon() != null)
|
||||
{
|
||||
// Set icon
|
||||
builder.icon(template.icon().clone());
|
||||
}
|
||||
|
||||
if (template.title() != null)
|
||||
{
|
||||
// Set title
|
||||
builder.name(this.user.getTranslation(this.world, template.title(), "[text]", this.searchText));
|
||||
}
|
||||
|
||||
if (template.description() != null)
|
||||
{
|
||||
// Set description
|
||||
builder.description(this.user.getTranslation(this.world, template.description(), "[text]", this.searchText));
|
||||
}
|
||||
|
||||
// Get only possible actions, by removing all inactive ones.
|
||||
List<ItemTemplateRecord.ActionRecords> activeActions = new ArrayList<>(template.actions());
|
||||
|
||||
activeActions.removeIf(action ->
|
||||
"CLEAR".equalsIgnoreCase(action.actionType()) && this.searchText.isBlank());
|
||||
|
||||
// Add Click handler
|
||||
builder.clickHandler((panel, user, clickType, i) ->
|
||||
{
|
||||
for (ItemTemplateRecord.ActionRecords action : activeActions)
|
||||
{
|
||||
if (clickType == action.clickType() || ClickType.UNKNOWN.equals(action.clickType()))
|
||||
{
|
||||
if ("CLEAR".equalsIgnoreCase(action.actionType()))
|
||||
{
|
||||
this.searchText = "";
|
||||
|
||||
// Update filters.
|
||||
this.updateFilters();
|
||||
this.build();
|
||||
}
|
||||
else if ("INPUT".equalsIgnoreCase(action.actionType()))
|
||||
{
|
||||
// Create consumer that process description change
|
||||
Consumer<String> consumer = value ->
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
this.searchText = value;
|
||||
this.updateFilters();
|
||||
}
|
||||
|
||||
this.build();
|
||||
};
|
||||
|
||||
// start conversation
|
||||
ConversationUtils.createStringInput(consumer,
|
||||
user,
|
||||
user.getTranslation("level.conversations.write-search"),
|
||||
user.getTranslation("level.conversations.search-updated"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
// Collect tooltips.
|
||||
List<String> tooltips = activeActions.stream().
|
||||
filter(action -> action.tooltip() != null).
|
||||
map(action -> this.user.getTranslation(this.world, 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);
|
||||
}
|
||||
|
||||
builder.glow(!this.searchText.isBlank());
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create next button panel item.
|
||||
*
|
||||
* @param template the template
|
||||
* @param slot the slot
|
||||
* @return the panel item
|
||||
*/
|
||||
private PanelItem createFilterButton(ItemTemplateRecord template, TemplatedPanel.ItemSlot slot)
|
||||
{
|
||||
PanelItemBuilder builder = new PanelItemBuilder();
|
||||
|
||||
if (template.icon() != null)
|
||||
{
|
||||
// Set icon
|
||||
builder.icon(template.icon().clone());
|
||||
}
|
||||
|
||||
String filterName = String.valueOf(template.dataMap().get("filter"));
|
||||
|
||||
final String reference = "level.gui.buttons.filters.";
|
||||
|
||||
if (template.title() != null)
|
||||
{
|
||||
// Set title
|
||||
builder.name(this.user.getTranslation(this.world, template.title()));
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.name(this.user.getTranslation(this.world, reference + filterName.toLowerCase() + ".name"));
|
||||
}
|
||||
|
||||
if (template.description() != null)
|
||||
{
|
||||
// Set description
|
||||
builder.description(this.user.getTranslation(this.world, template.description()));
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.name(this.user.getTranslation(this.world, reference + filterName.toLowerCase() + ".description"));
|
||||
}
|
||||
|
||||
// Get only possible actions, by removing all inactive ones.
|
||||
List<ItemTemplateRecord.ActionRecords> activeActions = new ArrayList<>(template.actions());
|
||||
|
||||
activeActions.removeIf(action -> {
|
||||
if (this.activeFilter.name().startsWith(filterName))
|
||||
{
|
||||
return this.activeFilter.name().endsWith("ASC") && "ASC".equalsIgnoreCase(action.actionType()) ||
|
||||
this.activeFilter.name().endsWith("DESC") && "DESC".equalsIgnoreCase(action.actionType());
|
||||
}
|
||||
else
|
||||
{
|
||||
return "DESC".equalsIgnoreCase(action.actionType());
|
||||
}
|
||||
});
|
||||
|
||||
// Add Click handler
|
||||
builder.clickHandler((panel, user, clickType, i) ->
|
||||
{
|
||||
for (ItemTemplateRecord.ActionRecords action : activeActions)
|
||||
{
|
||||
if (clickType == action.clickType() || ClickType.UNKNOWN.equals(action.clickType()))
|
||||
{
|
||||
if ("ASC".equalsIgnoreCase(action.actionType()))
|
||||
{
|
||||
this.activeFilter = Enums.getIfPresent(Filter.class, filterName + "_ASC").or(Filter.NAME_ASC);
|
||||
|
||||
// Update filters.
|
||||
this.updateFilters();
|
||||
this.build();
|
||||
}
|
||||
else if ("DESC".equalsIgnoreCase(action.actionType()))
|
||||
{
|
||||
this.activeFilter = Enums.getIfPresent(Filter.class, filterName + "_DESC").or(Filter.NAME_DESC);
|
||||
|
||||
// Update filters.
|
||||
this.updateFilters();
|
||||
this.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
// Collect tooltips.
|
||||
List<String> tooltips = activeActions.stream().
|
||||
filter(action -> action.tooltip() != null).
|
||||
map(action -> this.user.getTranslation(this.world, 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);
|
||||
}
|
||||
|
||||
builder.glow(this.activeFilter.name().startsWith(filterName.toUpperCase()));
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Create common buttons
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* Create next button panel item.
|
||||
*
|
||||
* @param template the template
|
||||
* @param slot the slot
|
||||
* @return the panel item
|
||||
*/
|
||||
private PanelItem createNextButton(ItemTemplateRecord template, TemplatedPanel.ItemSlot slot)
|
||||
{
|
||||
long size = this.elementList.size();
|
||||
|
||||
if (size <= slot.amountMap().getOrDefault("BLOCK", 1) ||
|
||||
1.0 * size / slot.amountMap().getOrDefault("BLOCK", 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.world, template.title()));
|
||||
}
|
||||
|
||||
if (template.description() != null)
|
||||
{
|
||||
builder.description(this.user.getTranslation(this.world, template.description(),
|
||||
"[number]", String.valueOf(nextPageIndex)));
|
||||
}
|
||||
|
||||
// Add ClickHandler
|
||||
builder.clickHandler((panel, user, clickType, i) ->
|
||||
{
|
||||
for (ItemTemplateRecord.ActionRecords action : template.actions())
|
||||
{
|
||||
if (clickType == action.clickType() || ClickType.UNKNOWN.equals(action.clickType()))
|
||||
{
|
||||
if ("NEXT".equalsIgnoreCase(action.actionType()))
|
||||
{
|
||||
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.world, 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
|
||||
*/
|
||||
private PanelItem createPreviousButton(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.world, template.title()));
|
||||
}
|
||||
|
||||
if (template.description() != null)
|
||||
{
|
||||
builder.description(this.user.getTranslation(this.world, template.description(),
|
||||
"[number]", String.valueOf(previousPageIndex)));
|
||||
}
|
||||
|
||||
// Add ClickHandler
|
||||
builder.clickHandler((panel, user, clickType, i) ->
|
||||
{
|
||||
for (ItemTemplateRecord.ActionRecords action : template.actions())
|
||||
{
|
||||
if (clickType == action.clickType() || ClickType.UNKNOWN.equals(action.clickType()))
|
||||
{
|
||||
if ("PREVIOUS".equalsIgnoreCase(action.actionType()))
|
||||
{
|
||||
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.world, 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();
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Create Material Button
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* Create material button panel item.
|
||||
*
|
||||
* @param template the template
|
||||
* @param slot the slot
|
||||
* @return the panel item
|
||||
*/
|
||||
private PanelItem createMaterialButton(ItemTemplateRecord template, TemplatedPanel.ItemSlot slot)
|
||||
{
|
||||
if (this.elementList.isEmpty())
|
||||
{
|
||||
// Does not contain any generators.
|
||||
return null;
|
||||
}
|
||||
|
||||
int index = this.pageIndex * slot.amountMap().getOrDefault("BLOCK", 1) + slot.slot();
|
||||
|
||||
if (index >= this.elementList.size())
|
||||
{
|
||||
// Out of index.
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.createMaterialButton(template, this.elementList.get(index));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method creates button for material.
|
||||
*
|
||||
* @param template the template of the button
|
||||
* @param materialRecord materialRecord which button must be created.
|
||||
* @return PanelItem for generator tier.
|
||||
*/
|
||||
private PanelItem createMaterialButton(ItemTemplateRecord template,
|
||||
MaterialRecord materialRecord)
|
||||
{
|
||||
PanelItemBuilder builder = new PanelItemBuilder();
|
||||
|
||||
if (template.icon() != null)
|
||||
{
|
||||
builder.icon(template.icon().clone());
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.icon(PanelUtils.getMaterialItem(materialRecord.material()));
|
||||
}
|
||||
|
||||
if (materialRecord.value() <= 64 && materialRecord.value() > 0)
|
||||
{
|
||||
builder.amount(materialRecord.value());
|
||||
}
|
||||
|
||||
if (template.title() != null)
|
||||
{
|
||||
builder.name(this.user.getTranslation(this.world, template.title(),
|
||||
"[material]", Utils.prettifyObject(materialRecord.material(), this.user)));
|
||||
}
|
||||
|
||||
String description = Utils.prettifyDescription(materialRecord.material(), this.user);
|
||||
|
||||
final String reference = "level.gui.buttons.material.";
|
||||
String blockId = this.user.getTranslationOrNothing(reference + "id",
|
||||
"[id]", materialRecord.material().name());
|
||||
|
||||
String value = this.user.getTranslationOrNothing(reference + "value",
|
||||
"[number]", String.valueOf(materialRecord.value()));
|
||||
|
||||
String underWater;
|
||||
|
||||
if (this.addon.getSettings().getUnderWaterMultiplier() > 1.0)
|
||||
{
|
||||
underWater = this.user.getTranslationOrNothing(reference + "underwater",
|
||||
"[number]", String.valueOf(materialRecord.value() * this.addon.getSettings().getUnderWaterMultiplier()));
|
||||
}
|
||||
else
|
||||
{
|
||||
underWater = "";
|
||||
}
|
||||
|
||||
String limit = materialRecord.limit() > 0 ? this.user.getTranslationOrNothing(reference + "limit",
|
||||
"[number]", String.valueOf(materialRecord.limit())) : "";
|
||||
|
||||
if (template.description() != null)
|
||||
{
|
||||
builder.description(this.user.getTranslation(this.world, template.description(),
|
||||
"[description]", description,
|
||||
"[id]", blockId,
|
||||
"[value]", value,
|
||||
"[underwater]", underWater,
|
||||
"[limit]", limit).
|
||||
replaceAll("(?m)^[ \\t]*\\r?\\n", "").
|
||||
replaceAll("(?<!\\\\)\\|", "\n").
|
||||
replaceAll("\\\\\\|", "|"));
|
||||
}
|
||||
|
||||
builder.clickHandler((panel, user1, clickType, i) -> {
|
||||
System.out.println("Material: " + materialRecord.material());
|
||||
return true;
|
||||
});
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Other Methods
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* This method is used to open UserPanel outside this class. It will be much easier to open panel with single method
|
||||
* call then initializing new object.
|
||||
*
|
||||
* @param addon Level object
|
||||
* @param world World where user is operating
|
||||
* @param user User who opens panel
|
||||
*/
|
||||
public static void openPanel(Level addon,
|
||||
World world,
|
||||
User user)
|
||||
{
|
||||
new ValuePanel(addon, world, user).build();
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Enums
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* Sorting order of blocks.
|
||||
*/
|
||||
private enum Filter
|
||||
{
|
||||
/**
|
||||
* By name asc
|
||||
*/
|
||||
NAME_ASC,
|
||||
/**
|
||||
* By name desc
|
||||
*/
|
||||
NAME_DESC,
|
||||
/**
|
||||
* By value asc
|
||||
*/
|
||||
VALUE_ASC,
|
||||
/**
|
||||
* By value desc
|
||||
*/
|
||||
VALUE_DESC,
|
||||
}
|
||||
|
||||
|
||||
private record MaterialRecord(Material material, Integer value, Integer limit)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Variables
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* This variable allows to access addon object.
|
||||
*/
|
||||
private final Level addon;
|
||||
|
||||
/**
|
||||
* This variable holds user who opens panel. Without it panel cannot be opened.
|
||||
*/
|
||||
private final User user;
|
||||
|
||||
/**
|
||||
* This variable holds a world to which gui referee.
|
||||
*/
|
||||
private final World world;
|
||||
|
||||
/**
|
||||
* This variable stores the list of elements to display.
|
||||
*/
|
||||
private final List<MaterialRecord> materialRecordList;
|
||||
|
||||
/**
|
||||
* This variable stores the list of elements to display.
|
||||
*/
|
||||
private List<MaterialRecord> elementList;
|
||||
|
||||
/**
|
||||
* This variable holds current pageIndex for multi-page generator choosing.
|
||||
*/
|
||||
private int pageIndex;
|
||||
|
||||
/**
|
||||
* This variable stores which tab currently is active.
|
||||
*/
|
||||
private String searchText;
|
||||
|
||||
/**
|
||||
* This variable stores active filter for items.
|
||||
*/
|
||||
private Filter activeFilter;
|
||||
}
|
119
src/main/java/world/bentobox/level/util/ConversationUtils.java
Normal file
119
src/main/java/world/bentobox/level/util/ConversationUtils.java
Normal file
@ -0,0 +1,119 @@
|
||||
//
|
||||
// Created by BONNe
|
||||
// Copyright - 2021
|
||||
//
|
||||
|
||||
|
||||
package world.bentobox.level.util;
|
||||
|
||||
|
||||
import org.bukkit.conversations.*;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
|
||||
|
||||
public class ConversationUtils
|
||||
{
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Conversation API implementation
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* This method will close opened gui and writes question in chat. After players answers on question in chat, message
|
||||
* will trigger consumer and gui will reopen.
|
||||
*
|
||||
* @param consumer Consumer that accepts player output text.
|
||||
* @param question Message that will be displayed in chat when player triggers conversion.
|
||||
* @param user User who is targeted with current confirmation.
|
||||
*/
|
||||
public static void createStringInput(Consumer<String> consumer,
|
||||
User user,
|
||||
@NonNull String question,
|
||||
@Nullable String successMessage)
|
||||
{
|
||||
// Text input message.
|
||||
StringPrompt stringPrompt = new StringPrompt()
|
||||
{
|
||||
@Override
|
||||
public @NonNull String getPromptText(@NonNull ConversationContext context)
|
||||
{
|
||||
user.closeInventory();
|
||||
return question;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NonNull Prompt acceptInput(@NonNull ConversationContext context, @Nullable String input)
|
||||
{
|
||||
consumer.accept(input);
|
||||
return ConversationUtils.endMessagePrompt(successMessage);
|
||||
}
|
||||
};
|
||||
|
||||
new ConversationFactory(BentoBox.getInstance()).
|
||||
withPrefix(context -> user.getTranslation("level.conversations.prefix")).
|
||||
withFirstPrompt(stringPrompt).
|
||||
// On cancel conversation will be closed.
|
||||
withLocalEcho(false).
|
||||
withTimeout(90).
|
||||
withEscapeSequence(user.getTranslation("level.conversations.cancel-string")).
|
||||
// Use null value in consumer to detect if user has abandoned conversation.
|
||||
addConversationAbandonedListener(ConversationUtils.getAbandonListener(consumer, user)).
|
||||
buildConversation(user.getPlayer()).
|
||||
begin();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is just a simple end message prompt that displays requested message.
|
||||
*
|
||||
* @param message Message that will be displayed.
|
||||
* @return MessagePrompt that displays given message and exists from conversation.
|
||||
*/
|
||||
private static MessagePrompt endMessagePrompt(@Nullable String message)
|
||||
{
|
||||
return new MessagePrompt()
|
||||
{
|
||||
@Override
|
||||
public @NonNull String getPromptText(@NonNull ConversationContext context)
|
||||
{
|
||||
return message == null ? "" : message;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected @Nullable Prompt getNextPrompt(@NonNull ConversationContext context)
|
||||
{
|
||||
return Prompt.END_OF_CONVERSATION;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method creates and returns abandon listener for every conversation.
|
||||
*
|
||||
* @param consumer Consumer which must return null value.
|
||||
* @param user User who was using conversation.
|
||||
* @return ConversationAbandonedListener instance.
|
||||
*/
|
||||
private static ConversationAbandonedListener getAbandonListener(Consumer<?> consumer, User user)
|
||||
{
|
||||
return abandonedEvent ->
|
||||
{
|
||||
if (!abandonedEvent.gracefulExit())
|
||||
{
|
||||
consumer.accept(null);
|
||||
// send cancell message
|
||||
abandonedEvent.getContext().getForWhom().sendRawMessage(
|
||||
user.getTranslation("level.conversations.prefix") +
|
||||
user.getTranslation("level.conversations.cancelled"));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -7,11 +7,13 @@
|
||||
package world.bentobox.level.util;
|
||||
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.hooks.LangUtilsHook;
|
||||
|
||||
|
||||
public class Utils
|
||||
@ -131,4 +133,93 @@ public class Utils
|
||||
|
||||
return currentValue;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prettify Material object for user.
|
||||
* @param object Object that must be pretty.
|
||||
* @param user User who will see the object.
|
||||
* @return Prettified string for Material.
|
||||
*/
|
||||
public static String prettifyObject(Material object, User user)
|
||||
{
|
||||
// Nothing to translate
|
||||
if (object == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
// Find addon structure with:
|
||||
// [addon]:
|
||||
// materials:
|
||||
// [material]:
|
||||
// name: [name]
|
||||
String translation = user.getTranslationOrNothing("level.materials." + object.name().toLowerCase() + ".name");
|
||||
|
||||
if (!translation.isEmpty())
|
||||
{
|
||||
// We found our translation.
|
||||
return translation;
|
||||
}
|
||||
|
||||
// Find addon structure with:
|
||||
// [addon]:
|
||||
// materials:
|
||||
// [material]: [name]
|
||||
|
||||
translation = user.getTranslationOrNothing("level.materials." + object.name().toLowerCase());
|
||||
|
||||
if (!translation.isEmpty())
|
||||
{
|
||||
// We found our translation.
|
||||
return translation;
|
||||
}
|
||||
|
||||
// Find general structure with:
|
||||
// materials:
|
||||
// [material]: [name]
|
||||
|
||||
translation = user.getTranslationOrNothing("materials." + object.name().toLowerCase());
|
||||
|
||||
if (!translation.isEmpty())
|
||||
{
|
||||
// We found our translation.
|
||||
return translation;
|
||||
}
|
||||
|
||||
// Use Lang Utils Hook to translate material
|
||||
return LangUtilsHook.getMaterialName(object, user);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prettify Material object description for user.
|
||||
* @param object Object that must be pretty.
|
||||
* @param user User who will see the object.
|
||||
* @return Prettified description string for Material.
|
||||
*/
|
||||
public static String prettifyDescription(Material object, User user)
|
||||
{
|
||||
// Nothing to translate
|
||||
if (object == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
// Find addon structure with:
|
||||
// [addon]:
|
||||
// materials:
|
||||
// [material]:
|
||||
// description: [text]
|
||||
String translation = user.getTranslationOrNothing("level.materials." + object.name().toLowerCase() + ".description");
|
||||
|
||||
if (!translation.isEmpty())
|
||||
{
|
||||
// We found our translation.
|
||||
return translation;
|
||||
}
|
||||
|
||||
// No text to return.
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
@ -55,18 +55,16 @@ island:
|
||||
syntax: "[name] x [number]"
|
||||
hint: "&c Run level to see the block report"
|
||||
|
||||
value:
|
||||
description: "shows the value of any block"
|
||||
success: "&7 The value of this block is: &e[value]"
|
||||
success-underwater: "&7 The value of this block below sea-level: &e[value]"
|
||||
empty-hand: "&c There are no blocks in your hand"
|
||||
no-value: "&c That item has no value."
|
||||
|
||||
level:
|
||||
commands:
|
||||
value:
|
||||
parameters: "[hand|<material>]"
|
||||
description: "shows the value of blocks. Add 'hand' at the end to display value for item in hand."
|
||||
gui:
|
||||
titles:
|
||||
top: "&0&l Top Islands"
|
||||
detail-panel: "&0&l [name]'s island"
|
||||
value-panel: "&0&l Block Values"
|
||||
buttons:
|
||||
island:
|
||||
empty: '&f&l [name]. place'
|
||||
@ -138,6 +136,18 @@ level:
|
||||
name: "&f&l Sort by Count"
|
||||
description: |-
|
||||
&7 Sort all blocks by their amount.
|
||||
value:
|
||||
name: "&f&l [material]"
|
||||
description: |-
|
||||
[description]
|
||||
[value]
|
||||
[underwater]
|
||||
[limit]
|
||||
[id]
|
||||
id: "&7 Block id: &e [id]"
|
||||
value: "&7 Block value: &e [number]"
|
||||
underwater: "&7 Bellow sea level: &e [number]"
|
||||
limit: "&7 Block limit: &e [number]"
|
||||
# Button that is used in multi-page GUIs which allows to return to previous page.
|
||||
previous:
|
||||
name: "&f&l Previous Page"
|
||||
@ -148,6 +158,12 @@ level:
|
||||
name: "&f&l Next Page"
|
||||
description: |-
|
||||
&7 Switch to [number] page
|
||||
search:
|
||||
name: "&f&l Search"
|
||||
description: |-
|
||||
&7 Search for a specific
|
||||
&7 value.
|
||||
search: "&b Value: [value]"
|
||||
tips:
|
||||
click-to-view: "&e Click &7 to view."
|
||||
click-to-previous: "&e Click &7 to view previous page."
|
||||
@ -155,7 +171,30 @@ level:
|
||||
click-to-select: "&e Click &7 to select."
|
||||
left-click-to-cycle-up: "&e Left Click &7 to cycle up."
|
||||
right-click-to-cycle-down: "&e Right Click &7 to cycle down."
|
||||
left-click-to-change: "&e Left Click &7 to edit."
|
||||
right-click-to-clear: "&e Right Click &7 to clear."
|
||||
click-to-asc: "&e Click &7 to sort in increasing order."
|
||||
click-to-desc: "&e Click &7 to sort in decreasing order."
|
||||
conversations:
|
||||
# Prefix for messages that are send from server.
|
||||
prefix: "&l&6 [BentoBox]: &r"
|
||||
no-data: "&c Run level to see the block report."
|
||||
no-data: "&c Run level to see the block report."
|
||||
# String that allows to cancel conversation. (can be only one)
|
||||
cancel-string: "cancel"
|
||||
# List of strings that allows to exit conversation. (separated with ,)
|
||||
exit-string: "cancel, exit, quit"
|
||||
# Message that asks for search value input.
|
||||
write-search: "&e Please enter a search value. (Write 'cancel' to exit)"
|
||||
# Message that appears after updating search value.
|
||||
search-updated: "&a Search value updated."
|
||||
# Message that is sent to user when conversation is cancelled.
|
||||
cancelled: "&c Conversation cancelled!"
|
||||
# Message that is sent to user when given material does not have any value.
|
||||
no-value: "&c That item has no value."
|
||||
# Message that is sent to user when requested material does not exist.
|
||||
unknown-item: "&c The '[material]' does not exist in game."
|
||||
# Messages that is sent to user when requesting value for a specific material.
|
||||
value: "&7 The value of '[material]' is: &e[value]"
|
||||
value-underwater: "&7 The value of '[material]' below sea-level: &e[value]"
|
||||
# Message that is sent to user when he does not hold any items in hand.
|
||||
empty-hand: "&c There are no blocks in your hand"
|
||||
|
109
src/main/resources/panels/value_panel.yml
Normal file
109
src/main/resources/panels/value_panel.yml
Normal file
@ -0,0 +1,109 @@
|
||||
value_panel:
|
||||
title: level.gui.titles.value-panel
|
||||
type: INVENTORY
|
||||
background:
|
||||
icon: BLACK_STAINED_GLASS_PANE
|
||||
title: "&b&r" # Empty text
|
||||
border:
|
||||
icon: BLACK_STAINED_GLASS_PANE
|
||||
title: "&b&r" # Empty text
|
||||
force-shown: []
|
||||
content:
|
||||
1:
|
||||
4:
|
||||
icon: PAPER
|
||||
title: level.gui.buttons.filters.name.name
|
||||
description: level.gui.buttons.filters.name.description
|
||||
data:
|
||||
type: FILTER
|
||||
# the value of filter button. Suggestion is to leave fist value to name if you use single button.
|
||||
filter: NAME
|
||||
actions:
|
||||
asc:
|
||||
click-type: unknown
|
||||
tooltip: level.gui.tips.click-to-asc
|
||||
desc:
|
||||
click-type: unknown
|
||||
tooltip: level.gui.tips.click-to-desc
|
||||
5:
|
||||
# You can create multiple buttons. By default it is one.
|
||||
icon: MAP
|
||||
title: level.gui.buttons.search.name
|
||||
description: level.gui.buttons.search.description
|
||||
data:
|
||||
type: SEARCH
|
||||
actions:
|
||||
input:
|
||||
click-type: left
|
||||
tooltip: level.gui.tips.left-click-to-change
|
||||
clear:
|
||||
click-type: right
|
||||
tooltip: level.gui.tips.right-click-to-clear
|
||||
6:
|
||||
icon: DIAMOND
|
||||
title: level.gui.buttons.filters.value.name
|
||||
description: level.gui.buttons.filters.value.description
|
||||
data:
|
||||
type: FILTER
|
||||
# the value of filter button. Suggestion is to leave fist value to name if you use single button.
|
||||
filter: VALUE
|
||||
actions:
|
||||
asc:
|
||||
click-type: unknown
|
||||
tooltip: level.gui.tips.click-to-asc
|
||||
desc:
|
||||
click-type: unknown
|
||||
tooltip: level.gui.tips.click-to-desc
|
||||
2:
|
||||
2: material_button
|
||||
3: material_button
|
||||
4: material_button
|
||||
5: material_button
|
||||
6: material_button
|
||||
7: material_button
|
||||
8: material_button
|
||||
3:
|
||||
1:
|
||||
icon: TIPPED_ARROW:INSTANT_HEAL::::1
|
||||
title: level.gui.buttons.previous.name
|
||||
description: level.gui.buttons.previous.description
|
||||
data:
|
||||
type: PREVIOUS
|
||||
indexing: true
|
||||
actions:
|
||||
previous:
|
||||
click-type: unknown
|
||||
tooltip: level.gui.tips.click-to-previous
|
||||
2: material_button
|
||||
3: material_button
|
||||
4: material_button
|
||||
5: material_button
|
||||
6: material_button
|
||||
7: material_button
|
||||
8: material_button
|
||||
9:
|
||||
icon: TIPPED_ARROW:JUMP::::1
|
||||
title: level.gui.buttons.next.name
|
||||
description: level.gui.buttons.next.description
|
||||
data:
|
||||
type: NEXT
|
||||
indexing: true
|
||||
actions:
|
||||
next:
|
||||
click-type: unknown
|
||||
tooltip: level.gui.tips.click-to-next
|
||||
4:
|
||||
2: material_button
|
||||
3: material_button
|
||||
4: material_button
|
||||
5: material_button
|
||||
6: material_button
|
||||
7: material_button
|
||||
8: material_button
|
||||
reusable:
|
||||
material_button:
|
||||
#icon: STONE
|
||||
title: level.gui.buttons.value.name
|
||||
description: level.gui.buttons.value.description
|
||||
data:
|
||||
type: BLOCK
|
Loading…
Reference in New Issue
Block a user