mirror of
https://github.com/BentoBoxWorld/Level.git
synced 2024-11-27 12:38:21 +01:00
Implement customizable DetailsPanel.
Remove old DetailsGUITab due to new implementation.
This commit is contained in:
parent
43fcde5781
commit
15ff515078
39
pom.xml
39
pom.xml
@ -60,6 +60,8 @@
|
||||
<!-- More visible way how to change dependency versions -->
|
||||
<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>
|
||||
<!-- Revision variable removes warning about dynamic version -->
|
||||
<revision>${build.version}-SNAPSHOT</revision>
|
||||
<!-- Do not change unless you want different name for local builds. -->
|
||||
@ -176,6 +178,11 @@
|
||||
<version>${bentobox.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>lv.id.bonne</groupId>
|
||||
<artifactId>panelutils</artifactId>
|
||||
<version>${panelutils.version}</version>
|
||||
</dependency>
|
||||
<!-- Wild Stacker dependency -->
|
||||
<dependency>
|
||||
<groupId>com.github.OmerBenGera</groupId>
|
||||
@ -331,6 +338,38 @@
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<version>2.8.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.3.1-SNAPSHOT</version>
|
||||
<configuration>
|
||||
<minimizeJar>true</minimizeJar>
|
||||
<artifactSet>
|
||||
<includes>
|
||||
<include>lv.id.bonne:panelutils:*</include>
|
||||
</includes>
|
||||
</artifactSet>
|
||||
<transformers>
|
||||
<!-- Add a transformer to exclude any other manifest files (possibly from dependencies). -->
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.DontIncludeResourceTransformer">
|
||||
<resource>MANIFEST.MF</resource>
|
||||
</transformer>
|
||||
<!-- Add a transformer to include your custom manifest file. -->
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.IncludeResourceTransformer">
|
||||
<resource>META-INF/MANIFEST.MF</resource>
|
||||
<file>src/main/resources/META-INF/MANIFEST.MF</file>
|
||||
</transformer>
|
||||
</transformers>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
|
@ -74,15 +74,16 @@ public class Level extends Addon implements Listener {
|
||||
} else {
|
||||
configObject.saveConfigObject(settings);
|
||||
}
|
||||
|
||||
// Save existing panels.
|
||||
this.saveResource("panels/top_panel.yml", false);
|
||||
this.saveResource("panels/detail_panel.yml", false);
|
||||
}
|
||||
|
||||
private boolean loadSettings() {
|
||||
// Load settings again to get worlds
|
||||
settings = configObject.loadConfigObject();
|
||||
|
||||
// Save existing panels.
|
||||
this.saveResource("panels/top_panel.yml", false);
|
||||
|
||||
return settings == null;
|
||||
}
|
||||
|
||||
|
@ -2,11 +2,9 @@ package world.bentobox.level;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
@ -18,19 +16,12 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
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.panels.builders.TabbedPanelBuilder;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.database.Database;
|
||||
import world.bentobox.bentobox.database.objects.Island;
|
||||
import world.bentobox.level.calculators.Results;
|
||||
@ -39,8 +30,7 @@ import world.bentobox.level.events.IslandPreLevelEvent;
|
||||
import world.bentobox.level.objects.IslandLevels;
|
||||
import world.bentobox.level.objects.LevelsData;
|
||||
import world.bentobox.level.objects.TopTenData;
|
||||
import world.bentobox.level.panels.DetailsGUITab;
|
||||
import world.bentobox.level.panels.DetailsGUITab.DetailsType;
|
||||
|
||||
|
||||
public class LevelsManager {
|
||||
private static final String INTOPTEN = "intopten";
|
||||
@ -57,16 +47,12 @@ public class LevelsManager {
|
||||
}
|
||||
private Level addon;
|
||||
|
||||
|
||||
// Database handler for level data
|
||||
private final Database<IslandLevels> handler;
|
||||
// A cache of island levels.
|
||||
private final Map<String, IslandLevels> levelsCache;
|
||||
// Top ten lists
|
||||
private final Map<World,TopTenData> topTenLists;
|
||||
// Background
|
||||
private final PanelItem background;
|
||||
|
||||
|
||||
|
||||
public LevelsManager(Level addon) {
|
||||
@ -79,8 +65,6 @@ public class LevelsManager {
|
||||
levelsCache = new HashMap<>();
|
||||
// Initialize top ten lists
|
||||
topTenLists = new ConcurrentHashMap<>();
|
||||
// Background
|
||||
background = new PanelItemBuilder().icon(Material.BLACK_STAINED_GLASS_PANE).name(" ").build();
|
||||
}
|
||||
|
||||
public void migrate() {
|
||||
@ -226,102 +210,6 @@ public class LevelsManager {
|
||||
return level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the Top Ten list
|
||||
* @param world - world
|
||||
* @param user - the requesting player
|
||||
*/
|
||||
public void getGUI(World world, final User user) {
|
||||
// Check world
|
||||
Map<UUID, Long> topTen = getTopTen(world, Level.TEN);
|
||||
|
||||
PanelBuilder panel = new PanelBuilder()
|
||||
.name(user.getTranslation("island.top.gui-title"))
|
||||
.size(54)
|
||||
.user(user);
|
||||
// Background
|
||||
for (int j = 0; j < 54; panel.item(j++, background));
|
||||
|
||||
// Top Ten
|
||||
int i = 0;
|
||||
boolean inTopTen = false;
|
||||
for (Entry<UUID, Long> m : topTen.entrySet()) {
|
||||
PanelItem h = getHead((i+1), m.getValue(), m.getKey(), user, world);
|
||||
panel.item(SLOTS[i], h);
|
||||
// If this is also the asking player
|
||||
if (m.getKey().equals(user.getUniqueId())) {
|
||||
inTopTen = true;
|
||||
addSelf(world, user, panel);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
// Show remaining slots
|
||||
for (; i < SLOTS.length; i++) {
|
||||
panel.item(SLOTS[i], new PanelItemBuilder().icon(Material.GREEN_STAINED_GLASS_PANE).name(String.valueOf(i + 1)).build());
|
||||
}
|
||||
|
||||
// Add yourself if you were not already in the top ten
|
||||
if (!inTopTen) {
|
||||
addSelf(world, user, panel);
|
||||
}
|
||||
panel.build();
|
||||
}
|
||||
|
||||
private void addSelf(World world, User user, PanelBuilder panel) {
|
||||
if (addon.getIslands().hasIsland(world, user) || addon.getIslands().inTeam(world, user.getUniqueId())) {
|
||||
PanelItem head = getHead(this.getRank(world, user.getUniqueId()), this.getIslandLevel(world, user.getUniqueId()), user.getUniqueId(), user, world);
|
||||
setClickHandler(head, user, world);
|
||||
panel.item(49, head);
|
||||
}
|
||||
}
|
||||
|
||||
private void setClickHandler(PanelItem head, User user, World world) {
|
||||
head.setClickHandler((p, u, ch, s) -> {
|
||||
new TabbedPanelBuilder()
|
||||
.user(user)
|
||||
.world(world)
|
||||
.tab(1, new DetailsGUITab(addon, world, user, DetailsType.ALL_BLOCKS))
|
||||
.tab(2, new DetailsGUITab(addon, world, user, DetailsType.ABOVE_SEA_LEVEL_BLOCKS))
|
||||
.tab(3, new DetailsGUITab(addon, world, user, DetailsType.UNDERWATER_BLOCKS))
|
||||
.tab(4, new DetailsGUITab(addon, world, user, DetailsType.SPAWNERS))
|
||||
.startingSlot(1)
|
||||
.size(54)
|
||||
.build().openPanel();
|
||||
return true;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the head panel item
|
||||
* @param rank - the top ten rank of this player/team. Can be used in the name of the island for vanity.
|
||||
* @param level - the level of the island
|
||||
* @param playerUUID - the UUID of the top ten player
|
||||
* @param asker - the asker of the top ten
|
||||
* @return PanelItem
|
||||
*/
|
||||
private PanelItem getHead(int rank, long level, UUID playerUUID, User asker, World world) {
|
||||
final String name = addon.getPlayers().getName(playerUUID);
|
||||
List<String> description = new ArrayList<>();
|
||||
if (rank > 0) {
|
||||
description.add(asker.getTranslation("island.top.gui-heading", "[name]", name, "[rank]", String.valueOf(rank)));
|
||||
}
|
||||
description.add(asker.getTranslation("island.top.island-level","[level]", formatLevel(level)));
|
||||
if (addon.getIslands().inTeam(world, playerUUID)) {
|
||||
List<String> memberList = new ArrayList<>();
|
||||
for (UUID members : addon.getIslands().getMembers(world, playerUUID)) {
|
||||
memberList.add(ChatColor.AQUA + addon.getPlayers().getName(members));
|
||||
}
|
||||
description.addAll(memberList);
|
||||
}
|
||||
|
||||
PanelItemBuilder builder = new PanelItemBuilder()
|
||||
.icon(name)
|
||||
.name(name)
|
||||
.description(description);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the initial level of the island. Used to zero island levels
|
||||
* @param island - island
|
||||
|
@ -352,8 +352,7 @@ public class IslandLevelCalculator {
|
||||
/**
|
||||
* Get a chunk async
|
||||
* @param env - the environment
|
||||
* @param x - chunk x coordinate
|
||||
* @param z - chunk z coordinate
|
||||
* @param pairList - chunk coordinate
|
||||
* @return a future chunk or future null if there is no chunk to load, e.g., there is no island nether
|
||||
*/
|
||||
private CompletableFuture<List<Chunk>> getWorldChunk(Environment env, Queue<Pair<Integer, Integer>> pairList) {
|
||||
@ -481,7 +480,7 @@ public class IslandLevelCalculator {
|
||||
|
||||
/**
|
||||
* Count the blocks on the island
|
||||
* @param chunk chunk to scan
|
||||
* @param cp chunk to scan
|
||||
*/
|
||||
private void scanAsync(ChunkPair cp) {
|
||||
for (int x = 0; x< 16; x++) {
|
||||
|
@ -1,211 +0,0 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package world.bentobox.level.panels;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Tag;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import com.google.common.base.Enums;
|
||||
|
||||
import world.bentobox.bentobox.api.localization.TextVariables;
|
||||
import world.bentobox.bentobox.api.panels.Panel;
|
||||
import world.bentobox.bentobox.api.panels.PanelItem;
|
||||
import world.bentobox.bentobox.api.panels.PanelItem.ClickHandler;
|
||||
import world.bentobox.bentobox.api.panels.Tab;
|
||||
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.database.objects.Island;
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
import world.bentobox.level.Level;
|
||||
import world.bentobox.level.objects.IslandLevels;
|
||||
|
||||
/**
|
||||
* @author tastybento
|
||||
*
|
||||
*/
|
||||
public class DetailsGUITab implements Tab, ClickHandler {
|
||||
|
||||
public enum DetailsType {
|
||||
ABOVE_SEA_LEVEL_BLOCKS,
|
||||
ALL_BLOCKS,
|
||||
SPAWNERS,
|
||||
UNDERWATER_BLOCKS
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts block materials to item materials
|
||||
*/
|
||||
private static final Map<Material, Material> M2I;
|
||||
static {
|
||||
Map<Material, Material> m2i = new EnumMap<>(Material.class);
|
||||
m2i.put(Material.WATER, Material.WATER_BUCKET);
|
||||
m2i.put(Material.LAVA, Material.LAVA_BUCKET);
|
||||
m2i.put(Material.AIR, Material.BLACK_STAINED_GLASS_PANE);
|
||||
m2i.put(Material.VOID_AIR, Material.BLACK_STAINED_GLASS_PANE);
|
||||
m2i.put(Material.CAVE_AIR, Material.BLACK_STAINED_GLASS_PANE);
|
||||
m2i.put(Material.WALL_TORCH, Material.TORCH);
|
||||
m2i.put(Material.REDSTONE_WALL_TORCH, Material.REDSTONE_TORCH);
|
||||
m2i.put(Material.TALL_SEAGRASS, Material.SEAGRASS);
|
||||
m2i.put(Material.PISTON_HEAD, Material.PISTON);
|
||||
m2i.put(Material.MOVING_PISTON, Material.PISTON);
|
||||
m2i.put(Material.REDSTONE_WIRE, Material.REDSTONE);
|
||||
m2i.put(Material.NETHER_PORTAL, Material.MAGENTA_STAINED_GLASS_PANE);
|
||||
m2i.put(Material.END_PORTAL, Material.BLACK_STAINED_GLASS_PANE);
|
||||
m2i.put(Material.ATTACHED_MELON_STEM, Material.MELON_SEEDS);
|
||||
m2i.put(Material.ATTACHED_PUMPKIN_STEM, Material.PUMPKIN_SEEDS);
|
||||
m2i.put(Material.MELON_STEM, Material.MELON_SEEDS);
|
||||
m2i.put(Material.PUMPKIN_STEM, Material.PUMPKIN_SEEDS);
|
||||
m2i.put(Material.COCOA, Material.COCOA_BEANS);
|
||||
m2i.put(Material.TRIPWIRE, Material.STRING);
|
||||
m2i.put(Material.CARROTS, Material.CARROT);
|
||||
m2i.put(Material.POTATOES, Material.POTATO);
|
||||
m2i.put(Material.BEETROOTS, Material.BEETROOT);
|
||||
m2i.put(Material.END_GATEWAY, Material.BEDROCK);
|
||||
m2i.put(Material.FROSTED_ICE, Material.ICE);
|
||||
m2i.put(Material.KELP_PLANT, Material.KELP);
|
||||
m2i.put(Material.BUBBLE_COLUMN, Material.WATER_BUCKET);
|
||||
m2i.put(Material.SWEET_BERRY_BUSH, Material.SWEET_BERRIES);
|
||||
m2i.put(Material.BAMBOO_SAPLING, Material.BAMBOO);
|
||||
m2i.put(Material.FIRE, Material.FLINT_AND_STEEL);
|
||||
// 1.16.1
|
||||
if (Enums.getIfPresent(Material.class, "WEEPING_VINES_PLANT").isPresent()) {
|
||||
m2i.put(Material.WEEPING_VINES_PLANT, Material.WEEPING_VINES);
|
||||
m2i.put(Material.TWISTING_VINES_PLANT, Material.TWISTING_VINES);
|
||||
m2i.put(Material.SOUL_WALL_TORCH, Material.SOUL_TORCH);
|
||||
}
|
||||
|
||||
|
||||
M2I = Collections.unmodifiableMap(m2i);
|
||||
}
|
||||
private final Level addon;
|
||||
private final @Nullable Island island;
|
||||
private List<PanelItem> items;
|
||||
private DetailsType type;
|
||||
private final User user;
|
||||
private final World world;
|
||||
|
||||
public DetailsGUITab(Level addon, World world, User user, DetailsType type) {
|
||||
this.addon = addon;
|
||||
this.world = world;
|
||||
this.user = user;
|
||||
this.island = addon.getIslands().getIsland(world, user);
|
||||
this.type = type;
|
||||
// Generate report
|
||||
generateReport(type);
|
||||
}
|
||||
|
||||
private void createItem(Material m, Integer count) {
|
||||
if (count == null || count <= 0) return;
|
||||
// Convert walls
|
||||
m = Enums.getIfPresent(Material.class, m.name().replace("WALL_", "")).or(m);
|
||||
// Tags
|
||||
if (Enums.getIfPresent(Material.class, "SOUL_CAMPFIRE").isPresent()) {
|
||||
if (Tag.FIRE.isTagged(m)) {
|
||||
items.add(new PanelItemBuilder()
|
||||
.icon(Material.CAMPFIRE)
|
||||
.name(Util.prettifyText(m.name()) + " x " + count)
|
||||
.build());
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (Tag.FLOWER_POTS.isTagged(m)) {
|
||||
m = Enums.getIfPresent(Material.class, m.name().replace("POTTED_", "")).or(m);
|
||||
}
|
||||
items.add(new PanelItemBuilder()
|
||||
.icon(M2I.getOrDefault(m, m))
|
||||
.name(user.getTranslation("island.level-details.syntax", TextVariables.NAME,
|
||||
Util.prettifyText(m.name()), TextVariables.NUMBER, String.valueOf(count)))
|
||||
.build());
|
||||
|
||||
}
|
||||
|
||||
private void generateReport(DetailsType type) {
|
||||
items = new ArrayList<>();
|
||||
IslandLevels ld = addon.getManager().getLevelsData(island);
|
||||
// Get the items from the report
|
||||
Map<Material, Integer> sumTotal = new EnumMap<>(Material.class);
|
||||
sumTotal.putAll(ld.getMdCount());
|
||||
sumTotal.putAll(ld.getUwCount());
|
||||
switch(type) {
|
||||
case ABOVE_SEA_LEVEL_BLOCKS:
|
||||
ld.getMdCount().forEach(this::createItem);
|
||||
break;
|
||||
case SPAWNERS:
|
||||
sumTotal.entrySet().stream().filter(m -> m.getKey().equals(Material.SPAWNER)).forEach(e -> createItem(e.getKey(), e.getValue()));
|
||||
break;
|
||||
case UNDERWATER_BLOCKS:
|
||||
ld.getUwCount().forEach(this::createItem);
|
||||
break;
|
||||
default:
|
||||
sumTotal.forEach(this::createItem);
|
||||
break;
|
||||
}
|
||||
if (type.equals(DetailsType.ALL_BLOCKS) && items.isEmpty()) {
|
||||
// Nothing here - looks like they need to run level
|
||||
items.add(new PanelItemBuilder()
|
||||
.name(user.getTranslation("island.level-details.hint")).icon(Material.WRITTEN_BOOK)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PanelItem getIcon() {
|
||||
switch(type) {
|
||||
case ABOVE_SEA_LEVEL_BLOCKS:
|
||||
return new PanelItemBuilder().icon(Material.GRASS_BLOCK).name(user.getTranslation("island.level-details.above-sea-level-blocks")).build();
|
||||
case SPAWNERS:
|
||||
return new PanelItemBuilder().icon(Material.SPAWNER).name(user.getTranslation("island.level-details.spawners")).build();
|
||||
case UNDERWATER_BLOCKS:
|
||||
return new PanelItemBuilder().icon(Material.WATER_BUCKET).name(user.getTranslation("island.level-details.underwater-blocks")).build();
|
||||
default:
|
||||
return new PanelItemBuilder().icon(Material.GRASS_BLOCK).name(user.getTranslation("island.level-details.all-blocks")).build();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
String name = user.getTranslation("island.level-details.no-island");
|
||||
if (island.getOwner() != null) {
|
||||
name = island.getName() != null ? island.getName() :
|
||||
user.getTranslation("island.level-details.names-island", TextVariables.NAME, addon.getPlayers().getName(island.getOwner()));
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<@Nullable PanelItem> getPanelItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPermission() {
|
||||
String permPrefix = addon.getPlugin().getIWM().getPermissionPrefix(world);
|
||||
switch(type) {
|
||||
case ABOVE_SEA_LEVEL_BLOCKS:
|
||||
return permPrefix + "island.level.details.above-sea-level";
|
||||
case SPAWNERS:
|
||||
return permPrefix + "island.level.details.spawners";
|
||||
case UNDERWATER_BLOCKS:
|
||||
return permPrefix + "island.level.details.underwater";
|
||||
default:
|
||||
return permPrefix + "island.level.details.blocks";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onClick(Panel panel, User user, ClickType clickType, int slot) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
692
src/main/java/world/bentobox/level/panels/DetailsPanel.java
Normal file
692
src/main/java/world/bentobox/level/panels/DetailsPanel.java
Normal file
@ -0,0 +1,692 @@
|
||||
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.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.database.objects.Island;
|
||||
import world.bentobox.bentobox.hooks.LangUtilsHook;
|
||||
import world.bentobox.bentobox.util.Pair;
|
||||
import world.bentobox.level.Level;
|
||||
import world.bentobox.level.objects.IslandLevels;
|
||||
import world.bentobox.level.util.Utils;
|
||||
|
||||
|
||||
/**
|
||||
* This class opens GUI that shows generator view for user.
|
||||
*/
|
||||
public class DetailsPanel
|
||||
{
|
||||
// ---------------------------------------------------------------------
|
||||
// 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 DetailsPanel(Level addon,
|
||||
World world,
|
||||
User user)
|
||||
{
|
||||
this.addon = addon;
|
||||
this.world = world;
|
||||
this.user = user;
|
||||
|
||||
this.island = this.addon.getIslands().getIsland(world, user);
|
||||
|
||||
if (this.island != null)
|
||||
{
|
||||
this.levelsData = this.addon.getManager().getLevelsData(this.island);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.levelsData = null;
|
||||
}
|
||||
|
||||
// By default no-filters are active.
|
||||
this.activeTab = Tab.ALL_BLOCKS;
|
||||
this.materialCountList = new ArrayList<>(Material.values().length);
|
||||
|
||||
this.updateFilters();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method builds this GUI.
|
||||
*/
|
||||
private void build()
|
||||
{
|
||||
if (this.island == null || this.levelsData == null)
|
||||
{
|
||||
// Nothing to see.
|
||||
Utils.sendMessage(this.user, this.user.getTranslation("general.errors.no-island"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.levelsData.getMdCount().isEmpty() && this.levelsData.getUwCount().isEmpty())
|
||||
{
|
||||
// Nothing to see.
|
||||
Utils.sendMessage(this.user, this.user.getTranslation("level.conversations.no-data"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Start building panel.
|
||||
TemplatedPanelBuilder panelBuilder = new TemplatedPanelBuilder();
|
||||
panelBuilder.user(this.user);
|
||||
panelBuilder.world(this.user.getWorld());
|
||||
|
||||
panelBuilder.template("detail_panel", new File(this.addon.getDataFolder(), "panels"));
|
||||
|
||||
panelBuilder.parameters("[name]", this.user.getName());
|
||||
|
||||
panelBuilder.registerTypeBuilder("NEXT", this::createNextButton);
|
||||
panelBuilder.registerTypeBuilder("PREVIOUS", this::createPreviousButton);
|
||||
panelBuilder.registerTypeBuilder("BLOCK", this::createMaterialButton);
|
||||
|
||||
// Register tabs
|
||||
panelBuilder.registerTypeBuilder("TAB", this::createTabButton);
|
||||
|
||||
// Register unknown type builder.
|
||||
panelBuilder.build();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method updates filter of elements based on tabs.
|
||||
*/
|
||||
private void updateFilters()
|
||||
{
|
||||
this.materialCountList.clear();
|
||||
|
||||
switch (this.activeTab)
|
||||
{
|
||||
case ALL_BLOCKS -> {
|
||||
Map<Material, Integer> materialCountMap = new EnumMap<>(Material.class);
|
||||
|
||||
materialCountMap.putAll(this.levelsData.getMdCount());
|
||||
|
||||
// Add underwater blocks.
|
||||
this.levelsData.getUwCount().forEach((material, count) -> {
|
||||
materialCountMap.put(material,
|
||||
materialCountMap.computeIfAbsent(material, key -> 0) + count);
|
||||
});
|
||||
|
||||
materialCountMap.entrySet().stream().sorted((Map.Entry.comparingByKey())).
|
||||
forEachOrdered(entry ->
|
||||
this.materialCountList.add(new Pair<>(entry.getKey(), entry.getValue())));
|
||||
}
|
||||
case ABOVE_SEA_LEVEL -> {
|
||||
this.levelsData.getMdCount().entrySet().stream().sorted((Map.Entry.comparingByKey())).
|
||||
forEachOrdered(entry ->
|
||||
this.materialCountList.add(new Pair<>(entry.getKey(), entry.getValue())));
|
||||
}
|
||||
case UNDERWATER -> {
|
||||
this.levelsData.getUwCount().entrySet().stream().sorted((Map.Entry.comparingByKey())).
|
||||
forEachOrdered(entry ->
|
||||
this.materialCountList.add(new Pair<>(entry.getKey(), entry.getValue())));
|
||||
}
|
||||
case SPAWNER -> {
|
||||
int aboveWater = this.levelsData.getMdCount().getOrDefault(Material.SPAWNER, 0);
|
||||
int underWater = this.levelsData.getUwCount().getOrDefault(Material.SPAWNER, 0);
|
||||
|
||||
// TODO: spawners need some touch...
|
||||
this.materialCountList.add(new Pair<>(Material.SPAWNER, underWater + aboveWater));
|
||||
}
|
||||
}
|
||||
|
||||
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 createTabButton(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()));
|
||||
}
|
||||
|
||||
if (template.description() != null)
|
||||
{
|
||||
// Set description
|
||||
builder.description(this.user.getTranslation(this.world, template.description()));
|
||||
}
|
||||
|
||||
Tab tab = Enums.getIfPresent(Tab.class, String.valueOf(template.dataMap().get("tab"))).or(Tab.ALL_BLOCKS);
|
||||
|
||||
// Get only possible actions, by removing all inactive ones.
|
||||
List<ItemTemplateRecord.ActionRecords> activeActions = new ArrayList<>(template.actions());
|
||||
|
||||
activeActions.removeIf(action ->
|
||||
"VIEW".equalsIgnoreCase(action.actionType()) && this.activeTab == tab);
|
||||
|
||||
// Add Click handler
|
||||
builder.clickHandler((panel, user, clickType, i) ->
|
||||
{
|
||||
for (ItemTemplateRecord.ActionRecords action : activeActions)
|
||||
{
|
||||
if (clickType == action.clickType() || ClickType.UNKNOWN.equals(action.clickType()))
|
||||
{
|
||||
if ("VIEW".equalsIgnoreCase(action.actionType()))
|
||||
{
|
||||
this.activeTab = tab;
|
||||
|
||||
// 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.activeTab == tab);
|
||||
|
||||
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.materialCountList.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.materialCountList.isEmpty())
|
||||
{
|
||||
// Does not contain any generators.
|
||||
return null;
|
||||
}
|
||||
|
||||
int index = this.pageIndex * slot.amountMap().getOrDefault("BLOCK", 1) + slot.slot();
|
||||
|
||||
if (index >= this.materialCountList.size())
|
||||
{
|
||||
// Out of index.
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.createMaterialButton(template, this.materialCountList.get(index));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method creates button for material.
|
||||
*
|
||||
* @param template the template of the button
|
||||
* @param materialCount materialCount which button must be created.
|
||||
* @return PanelItem for generator tier.
|
||||
*/
|
||||
private PanelItem createMaterialButton(ItemTemplateRecord template,
|
||||
Pair<Material, Integer> materialCount)
|
||||
{
|
||||
PanelItemBuilder builder = new PanelItemBuilder();
|
||||
|
||||
if (template.icon() != null)
|
||||
{
|
||||
builder.icon(template.icon().clone());
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.icon(PanelUtils.getMaterialItem(materialCount.getKey()));
|
||||
}
|
||||
|
||||
if (materialCount.getValue() < 64)
|
||||
{
|
||||
builder.amount(materialCount.getValue());
|
||||
}
|
||||
|
||||
if (template.title() != null)
|
||||
{
|
||||
builder.name(this.user.getTranslation(this.world, template.title(),
|
||||
"[number]", String.valueOf(materialCount.getValue()),
|
||||
"[material]", DetailsPanel.prettifyObject(materialCount.getKey(), this.user)));
|
||||
}
|
||||
|
||||
String description = DetailsPanel.prettifyDescription(materialCount.getKey(), this.user);
|
||||
|
||||
final String reference = "level.gui.buttons.material.";
|
||||
String blockId = this.user.getTranslationOrNothing(reference + "id",
|
||||
"[id]", materialCount.getKey().name());
|
||||
|
||||
int blockValue = this.addon.getBlockConfig().getBlockValues().getOrDefault(materialCount.getKey(), 0);
|
||||
String value = blockValue > 0 ? this.user.getTranslationOrNothing(reference + "value",
|
||||
"[number]", String.valueOf(blockValue)) : "";
|
||||
|
||||
int blockLimit = this.addon.getBlockConfig().getBlockLimits().getOrDefault(materialCount.getKey(), 0);
|
||||
String limit = blockLimit > 0 ? this.user.getTranslationOrNothing(reference + "limit",
|
||||
"[number]", String.valueOf(blockLimit)) : "";
|
||||
|
||||
String count = this.user.getTranslationOrNothing(reference + "count",
|
||||
"[number]", String.valueOf(materialCount.getValue()));
|
||||
|
||||
if (template.description() != null)
|
||||
{
|
||||
builder.description(this.user.getTranslation(this.world, template.description(),
|
||||
"[description]", description,
|
||||
"[id]", blockId,
|
||||
"[value]", value,
|
||||
"[limit]", limit,
|
||||
"[count]", count).
|
||||
replaceAll("(?m)^[ \\t]*\\r?\\n", "").
|
||||
replaceAll("(?<!\\\\)\\|", "\n").
|
||||
replaceAll("\\\\\\|", "|"));
|
||||
}
|
||||
|
||||
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 DetailsPanel(addon, world, user).build();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* This enum holds possible tabs for current gui.
|
||||
*/
|
||||
private enum Tab
|
||||
{
|
||||
/**
|
||||
* All block Tab
|
||||
*/
|
||||
ALL_BLOCKS,
|
||||
/**
|
||||
* Above Sea level Tab.
|
||||
*/
|
||||
ABOVE_SEA_LEVEL,
|
||||
/**
|
||||
* Underwater Tab.
|
||||
*/
|
||||
UNDERWATER,
|
||||
/**
|
||||
* Spawner Tab.
|
||||
*/
|
||||
SPAWNER
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Variables
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* This variable holds targeted island.
|
||||
*/
|
||||
private final Island island;
|
||||
|
||||
/**
|
||||
* This variable holds targeted island level data.
|
||||
*/
|
||||
private final IslandLevels levelsData;
|
||||
|
||||
/**
|
||||
* 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<Pair<Material, Integer>> materialCountList;
|
||||
|
||||
/**
|
||||
* This variable holds current pageIndex for multi-page generator choosing.
|
||||
*/
|
||||
private int pageIndex;
|
||||
|
||||
/**
|
||||
* This variable stores which tab currently is active.
|
||||
*/
|
||||
private Tab activeTab;
|
||||
}
|
@ -66,6 +66,7 @@ level:
|
||||
gui:
|
||||
titles:
|
||||
top: "&0&l Top Islands"
|
||||
detail-panel: "&0&l [name]'s island"
|
||||
buttons:
|
||||
island:
|
||||
empty: '&f&l [name]. place'
|
||||
@ -89,5 +90,54 @@ level:
|
||||
place: "&7&o [number]. &r&7 place"
|
||||
# Section for parsing [level]
|
||||
level: "&7 Level: &o [number]"
|
||||
material:
|
||||
name: "&f&l [number] x [material]"
|
||||
description: |-
|
||||
[description]
|
||||
[count]
|
||||
[value]
|
||||
[limit]
|
||||
[id]
|
||||
id: "&7 Block id: &e [id]"
|
||||
value: "&7 Block value: &e [number]"
|
||||
limit: "&7 Block limit: &e [number]"
|
||||
count: "&7 Number of blocks: &e [number]"
|
||||
all_blocks:
|
||||
name: "&f&l All Blocks"
|
||||
description: |-
|
||||
&7 Display all blocks
|
||||
&7 on island.
|
||||
above_sea_level:
|
||||
name: "&f&l Blocks Above Sea Level"
|
||||
description: |-
|
||||
&7 Display only blocks
|
||||
&7 that are above sea
|
||||
&7 level.
|
||||
underwater:
|
||||
name: "&f&l Blocks Under Sea level"
|
||||
description: |-
|
||||
&7 Display only blocks
|
||||
&7 that are bellow sea
|
||||
&7 level.
|
||||
spawner:
|
||||
name: "&f&l Spawners"
|
||||
description: |-
|
||||
&7 Display only spawners.
|
||||
# Button that is used in multi-page GUIs which allows to return to previous page.
|
||||
previous:
|
||||
name: "&f&l Previous Page"
|
||||
description: |-
|
||||
&7 Switch to [number] page
|
||||
# Button that is used in multi-page GUIs which allows to go to next page.
|
||||
next:
|
||||
name: "&f&l Next Page"
|
||||
description: |-
|
||||
&7 Switch to [number] page
|
||||
tips:
|
||||
click-to-view: "&e Click &7 to view."
|
||||
click-to-previous: "&e Click &7 to view previous page."
|
||||
click-to-next: "&e Click &7 to view next page."
|
||||
conversations:
|
||||
# Prefix for messages that are send from server.
|
||||
prefix: "&l&6 [BentoBox]: &r"
|
||||
no-data: "&c Run level to see the block report."
|
109
src/main/resources/panels/detail_panel.yml
Normal file
109
src/main/resources/panels/detail_panel.yml
Normal file
@ -0,0 +1,109 @@
|
||||
detail_panel:
|
||||
title: level.gui.titles.detail-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:
|
||||
2:
|
||||
icon: STONE
|
||||
title: level.gui.buttons.all_blocks.name
|
||||
description: level.gui.buttons.all_blocks.description
|
||||
data:
|
||||
type: TAB
|
||||
tab: ALL_BLOCKS
|
||||
actions:
|
||||
view:
|
||||
click-type: unknwon
|
||||
tooltip: level.gui.tips.click-to-view
|
||||
3:
|
||||
icon: GRASS_BLOCK
|
||||
title: level.gui.buttons.above_sea_level.name
|
||||
description: level.gui.buttons.above_sea_level.description
|
||||
data:
|
||||
type: TAB
|
||||
tab: ABOVE_SEA_LEVEL
|
||||
actions:
|
||||
view:
|
||||
click-type: unknwon
|
||||
tooltip: level.gui.tips.click-to-view
|
||||
4:
|
||||
icon: WATER_BUCKET
|
||||
title: level.gui.buttons.underwater.name
|
||||
description: level.gui.buttons.underwater.description
|
||||
data:
|
||||
type: TAB
|
||||
tab: UNDERWATER
|
||||
actions:
|
||||
view:
|
||||
click-type: unknwon
|
||||
tooltip: level.gui.tips.click-to-view
|
||||
5:
|
||||
icon: SPAWNER
|
||||
title: level.gui.buttons.spawner.name
|
||||
description: level.gui.buttons.spawner.description
|
||||
data:
|
||||
type: TAB
|
||||
tab: SPAWNER
|
||||
actions:
|
||||
view:
|
||||
click-type: unknwon
|
||||
tooltip: level.gui.tips.click-to-view
|
||||
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.material.name
|
||||
description: level.gui.buttons.material.description
|
||||
data:
|
||||
type: BLOCK
|
@ -120,5 +120,6 @@ top_panel:
|
||||
data:
|
||||
type: VIEW
|
||||
actions:
|
||||
left:
|
||||
view:
|
||||
click-type: unknown
|
||||
tooltip: level.gui.tips.click-to-view
|
Loading…
Reference in New Issue
Block a user