Initial commit: LoParkour v1.1.0
This commit is contained in:
commit
aecb03ccf8
120 changed files with 9668 additions and 0 deletions
76
src/main/java/dev/loki/loparkour/menu/DynamicMenu.java
Normal file
76
src/main/java/dev/loki/loparkour/menu/DynamicMenu.java
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
package dev.loki.loparkour.menu;
|
||||
|
||||
import dev.loki.loparkour.player.ParkourUser;
|
||||
import dev.efnilite.vilib.inventory.Menu;
|
||||
import dev.efnilite.vilib.inventory.item.MenuItem;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* A class for menus where items are dynamically displayed; that is, depending on provided conditions.
|
||||
* These conditions are specified by the param {@code shouldDisplay} in the method {@link #registerMainItem(int, int, BiFunction, Predicate)}.
|
||||
*/
|
||||
public abstract class DynamicMenu {
|
||||
|
||||
protected final Map<Integer, List<ItemContainer>> registeredItems = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Registers an item that will be displayed in a specific slot if the specified condition is met.
|
||||
* This will be used to create a context-aware main menu.
|
||||
*
|
||||
* @param row The row in which this item will be displayed. Starts from 0 and ends at 5.
|
||||
* @param id The id of this item. This will be used to determine the positions of each item.
|
||||
* Lower is more to the left. Can't be lower than 0.
|
||||
* @param item The item
|
||||
* @param shouldDisplay Whether this item should be displayed right now.
|
||||
*/
|
||||
public void registerMainItem(int row, int id, BiFunction<@NotNull Player, @Nullable ParkourUser, MenuItem> item, Predicate<Player> shouldDisplay) {
|
||||
if (id < 0 || row < 0 || row > 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<ItemContainer> existing = registeredItems.get(row);
|
||||
if (existing == null) {
|
||||
existing = new ArrayList<>();
|
||||
}
|
||||
existing.add(new ItemContainer(id, item, shouldDisplay));
|
||||
|
||||
registeredItems.put(row, existing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens this dynamic menu to a player
|
||||
*
|
||||
* @param player The player
|
||||
* @param menu The menu
|
||||
*/
|
||||
public void display(Player player, Menu menu) {
|
||||
ParkourUser user = ParkourUser.getUser(player);
|
||||
for (int row : registeredItems.keySet()) {
|
||||
int actualSlot = row * 9; // 0, 9, 18, etc.
|
||||
|
||||
List<ItemContainer> containers = registeredItems.get(row); // sort by id first
|
||||
containers.sort(Comparator.comparingInt(container -> container.id));
|
||||
|
||||
for (ItemContainer container : containers) {
|
||||
if (container.predicate.test(player)) { // if item in id passes predicate, display it in the menu
|
||||
menu.item(actualSlot, container.item.apply(player, user));
|
||||
actualSlot++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
menu.open(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data class for registered items
|
||||
*/
|
||||
protected record ItemContainer(int id, BiFunction<@NotNull Player, @Nullable ParkourUser, MenuItem> item,
|
||||
Predicate<Player> predicate) {}
|
||||
}
|
||||
24
src/main/java/dev/loki/loparkour/menu/MainMenu.java
Normal file
24
src/main/java/dev/loki/loparkour/menu/MainMenu.java
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
package dev.loki.loparkour.menu;
|
||||
|
||||
import dev.loki.loparkour.config.Config;
|
||||
import dev.loki.loparkour.config.Locales;
|
||||
import dev.loki.loparkour.player.ParkourPlayer;
|
||||
import dev.loki.loparkour.player.ParkourUser;
|
||||
import dev.efnilite.vilib.inventory.Menu;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class MainMenu extends DynamicMenu {
|
||||
|
||||
public MainMenu() {
|
||||
registerMainItem(1, 0, (player, user) -> Locales.getItem(player, "play.item").click(event -> Menus.PLAY.open(event.getPlayer())), player -> ParkourOption.PLAY.mayPerform(player) && Config.CONFIG.getBoolean("joining"));
|
||||
registerMainItem(1, 1, (player, user) -> Locales.getItem(player, "community.item").click(event -> Menus.COMMUNITY.open(event.getPlayer())), ParkourOption.COMMUNITY::mayPerform);
|
||||
registerMainItem(1, 2, (player, user) -> Locales.getItem(player, "settings.item").click(event -> Menus.SETTINGS.open(event.getPlayer())), player -> ParkourOption.SETTINGS.mayPerform(player) && ParkourUser.isUser(player));
|
||||
registerMainItem(1, 3, (player, user) -> Locales.getItem(player, "lobby.item").click(event -> Menus.LOBBY.open(event.getPlayer())), player -> ParkourOption.LOBBY.mayPerform(player) && ParkourUser.isUser(player));
|
||||
registerMainItem(1, 4, (player, user) -> Locales.getItem(player, "other.quit").click(event -> ParkourPlayer.leave(player)), player -> ParkourOption.QUIT.mayPerform(player) && ParkourUser.isUser(player));
|
||||
}
|
||||
|
||||
public void open(Player player) {
|
||||
display(player, new Menu(3, Locales.getString(player, "main.name"))
|
||||
.distributeRowsEvenly());
|
||||
}
|
||||
}
|
||||
39
src/main/java/dev/loki/loparkour/menu/Menus.java
Normal file
39
src/main/java/dev/loki/loparkour/menu/Menus.java
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
package dev.loki.loparkour.menu;
|
||||
|
||||
import dev.loki.loparkour.menu.community.CommunityMenu;
|
||||
import dev.loki.loparkour.menu.community.LeaderboardsMenu;
|
||||
import dev.loki.loparkour.menu.community.SingleLeaderboardMenu;
|
||||
import dev.loki.loparkour.menu.lobby.LobbyMenu;
|
||||
import dev.loki.loparkour.menu.lobby.PlayerManagementMenu;
|
||||
import dev.loki.loparkour.menu.play.PlayMenu;
|
||||
import dev.loki.loparkour.menu.play.SingleMenu;
|
||||
import dev.loki.loparkour.menu.play.SpectatorMenu;
|
||||
import dev.loki.loparkour.menu.settings.LangMenu;
|
||||
import dev.loki.loparkour.menu.settings.ParkourSettingsMenu;
|
||||
import dev.loki.loparkour.menu.settings.SettingsMenu;
|
||||
|
||||
public class Menus {
|
||||
|
||||
// main
|
||||
public static MainMenu MAIN = new MainMenu();
|
||||
|
||||
// play
|
||||
public static PlayMenu PLAY = new PlayMenu();
|
||||
public static SingleMenu SINGLE = new SingleMenu();
|
||||
public static SpectatorMenu SPECTATOR = new SpectatorMenu();
|
||||
|
||||
// community
|
||||
public static CommunityMenu COMMUNITY = new CommunityMenu();
|
||||
public static LeaderboardsMenu LEADERBOARDS = new LeaderboardsMenu();
|
||||
public static SingleLeaderboardMenu SINGLE_LEADERBOARD = new SingleLeaderboardMenu();
|
||||
|
||||
// settings
|
||||
public static SettingsMenu SETTINGS = new SettingsMenu();
|
||||
public static LangMenu LANG = new LangMenu();
|
||||
public static ParkourSettingsMenu PARKOUR_SETTINGS = new ParkourSettingsMenu();
|
||||
|
||||
// lobby
|
||||
public static LobbyMenu LOBBY = new LobbyMenu();
|
||||
public static PlayerManagementMenu PLAYER_MANAGEMENT = new PlayerManagementMenu();
|
||||
|
||||
}
|
||||
81
src/main/java/dev/loki/loparkour/menu/ParkourOption.java
Normal file
81
src/main/java/dev/loki/loparkour/menu/ParkourOption.java
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
package dev.loki.loparkour.menu;
|
||||
|
||||
import dev.loki.loparkour.config.Config;
|
||||
import dev.loki.loparkour.config.Option;
|
||||
import org.bukkit.permissions.Permissible;
|
||||
|
||||
/**
|
||||
* An enum for all Parkour Menu Options
|
||||
*/
|
||||
public enum ParkourOption {
|
||||
|
||||
// main
|
||||
MAIN("main", "LoParkour.main"),
|
||||
|
||||
// play
|
||||
PLAY("play", "LoParkour.play"),
|
||||
SINGLE("play.single", "LoParkour.play.single"),
|
||||
SPECTATOR("play.spectator", "LoParkour.play.spectator"),
|
||||
|
||||
// community
|
||||
COMMUNITY("community", "LoParkour.community"),
|
||||
LEADERBOARDS("community.leaderboards", "LoParkour.community.leaderboards"),
|
||||
|
||||
// settings
|
||||
SETTINGS("settings", "LoParkour.settings"),
|
||||
|
||||
PARKOUR_SETTINGS("settings.parkour_settings.item", "LoParkour.settings.parkour_settings"),
|
||||
STYLES("settings.parkour_settings.items.styles", "LoParkour.settings.styles"),
|
||||
LEADS("settings.parkour_settings.items.leads", "LoParkour.settings.leads"),
|
||||
TIME("settings.parkour_settings.items.time", "LoParkour.settings.time"),
|
||||
SCHEMATICS("settings.parkour_settings.items.schematics", "LoParkour.settings.schematics"),
|
||||
SCOREBOARD("settings.parkour_settings.items.scoreboard", "LoParkour.settings.show_scoreboard"),
|
||||
FALL_MESSAGE("settings.parkour_settings.items.fall_message", "LoParkour.settings.fall_message"),
|
||||
PARTICLES("settings.parkour_settings.items.particles", "LoParkour.settings.particles"),
|
||||
SOUND("settings.parkour_settings.items.sound", "LoParkour.settings.sound"),
|
||||
SPECIAL_BLOCKS("settings.parkour_settings.items.special_blocks", "LoParkour.settings.special_blocks"),
|
||||
|
||||
LANG("settings.lang", "LoParkour.settings.lang"),
|
||||
CHAT("settings.chat", "LoParkour.settings.chat"),
|
||||
|
||||
// lobby
|
||||
LOBBY("lobby", "LoParkour.lobby"),
|
||||
VISIBILITY("lobby.visibility", "LoParkour.lobby.visibility"),
|
||||
PLAYER_MANAGEMENT("lobby.player_management", "LoParkour.lobby.player_management"),
|
||||
|
||||
// other
|
||||
JOIN("join", "LoParkour.join"),
|
||||
QUIT("quit", "LoParkour.quit"),
|
||||
ADMIN("admin", "LoParkour.admin");
|
||||
|
||||
/**
|
||||
* The path in config files for this option.
|
||||
*/
|
||||
public final String path;
|
||||
|
||||
/**
|
||||
* The permission for this option.
|
||||
*/
|
||||
public final String permission;
|
||||
|
||||
ParkourOption(String path, String permission) {
|
||||
this.path = path;
|
||||
this.permission = permission;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param permissible The player
|
||||
* @return True if the player is allowed to view/perform this option, false if not.
|
||||
*/
|
||||
public boolean mayPerform(Permissible permissible) {
|
||||
boolean value = Option.OPTIONS_ENABLED.getOrDefault(this, true);
|
||||
|
||||
if (value) {
|
||||
if (Config.CONFIG.getBoolean("permissions.enabled")) {
|
||||
return permissible.hasPermission(permission);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package dev.loki.loparkour.menu.community;
|
||||
|
||||
import dev.loki.loparkour.config.Locales;
|
||||
import dev.loki.loparkour.menu.DynamicMenu;
|
||||
import dev.loki.loparkour.menu.Menus;
|
||||
import dev.loki.loparkour.menu.ParkourOption;
|
||||
import dev.efnilite.vilib.inventory.Menu;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* The menu for all community-related things
|
||||
*/
|
||||
public class CommunityMenu extends DynamicMenu {
|
||||
|
||||
public CommunityMenu() {
|
||||
registerMainItem(1, 1, (player, user) -> Locales.getItem(player, "community.leaderboards.item").click(event -> Menus.LEADERBOARDS.open(event.getPlayer())), ParkourOption.LEADERBOARDS::mayPerform);
|
||||
registerMainItem(2, 10, (player, user) -> Locales.getItem(player, "other.close").click(event -> event.getPlayer().closeInventory()), player -> true);
|
||||
}
|
||||
|
||||
public void open(Player player) {
|
||||
display(player, new Menu(3, Locales.getString(player, "community.name"))
|
||||
.distributeRowsEvenly());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
package dev.loki.loparkour.menu.community;
|
||||
|
||||
import dev.loki.loparkour.api.Registry;
|
||||
import dev.loki.loparkour.config.Locales;
|
||||
import dev.loki.loparkour.config.Option;
|
||||
import dev.loki.loparkour.leaderboard.Leaderboard;
|
||||
import dev.loki.loparkour.menu.Menus;
|
||||
import dev.loki.loparkour.menu.ParkourOption;
|
||||
import dev.loki.loparkour.mode.Mode;
|
||||
import dev.loki.loparkour.player.ParkourUser;
|
||||
import dev.efnilite.vilib.inventory.PagedMenu;
|
||||
import dev.efnilite.vilib.inventory.item.Item;
|
||||
import dev.efnilite.vilib.inventory.item.MenuItem;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Leaderboards menu
|
||||
*/
|
||||
public class LeaderboardsMenu {
|
||||
|
||||
public void open(Player player) {
|
||||
ParkourUser user = ParkourUser.getUser(player);
|
||||
String locale = user == null ? Option.OPTIONS_DEFAULTS.get(ParkourOption.LANG) : user.locale;
|
||||
|
||||
PagedMenu menu = new PagedMenu(3, Locales.getString(player, "%s.name".formatted(ParkourOption.LEADERBOARDS.path)));
|
||||
|
||||
Mode latest = null;
|
||||
List<MenuItem> items = new ArrayList<>();
|
||||
for (Mode mode : Registry.getModes()) {
|
||||
Leaderboard leaderboard = mode.getLeaderboard();
|
||||
Item item = mode.getItem(locale);
|
||||
|
||||
if (leaderboard == null || item == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
items.add(item.clone().click(event -> Menus.SINGLE_LEADERBOARD.open(player, mode, leaderboard.sort)));
|
||||
latest = mode;
|
||||
}
|
||||
|
||||
if (items.size() == 1) {
|
||||
Menus.SINGLE_LEADERBOARD.open(player, latest, Leaderboard.Sort.SCORE);
|
||||
return;
|
||||
}
|
||||
|
||||
menu.displayRows(0, 1)
|
||||
.addToDisplay(items)
|
||||
.nextPage(26, new Item(Material.LIME_DYE, "<#0DCB07><bold>»").click(event -> menu.page(1)))
|
||||
.prevPage(18, new Item(Material.RED_DYE, "<#DE1F1F><bold>«").click(event -> menu.page(-1)))
|
||||
.item(22, Locales.getItem(player, "other.close").click(event -> Menus.COMMUNITY.open(event.getPlayer())))
|
||||
.open(player);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
package dev.loki.loparkour.menu.community;
|
||||
|
||||
import dev.loki.loparkour.LoParkour;
|
||||
import dev.loki.loparkour.api.Registry;
|
||||
import dev.loki.loparkour.config.Locales;
|
||||
import dev.loki.loparkour.config.Option;
|
||||
import dev.loki.loparkour.leaderboard.Leaderboard;
|
||||
import dev.loki.loparkour.leaderboard.Score;
|
||||
import dev.loki.loparkour.menu.Menus;
|
||||
import dev.loki.loparkour.menu.ParkourOption;
|
||||
import dev.loki.loparkour.mode.Mode;
|
||||
import dev.loki.loparkour.player.ParkourUser;
|
||||
import dev.efnilite.vilib.inventory.PagedMenu;
|
||||
import dev.efnilite.vilib.inventory.item.Item;
|
||||
import dev.efnilite.vilib.inventory.item.MenuItem;
|
||||
import dev.efnilite.vilib.util.SkullSetter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Menu for a single leaderboard
|
||||
*/
|
||||
public class SingleLeaderboardMenu {
|
||||
|
||||
public void open(Player player, Mode mode, Leaderboard.Sort sort) {
|
||||
Leaderboard leaderboard = mode.getLeaderboard();
|
||||
|
||||
if (leaderboard == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// init vars
|
||||
var user = ParkourUser.getUser(player);
|
||||
var locale = user == null ? Option.OPTIONS_DEFAULTS.get(ParkourOption.LANG) : user.locale;
|
||||
var menu = new PagedMenu(3, Locales.getString(player, "%s.name".formatted(ParkourOption.LEADERBOARDS.path)));
|
||||
|
||||
var items = new ArrayList<MenuItem>();
|
||||
|
||||
var base = Locales.getItem(player, "%s.head".formatted(ParkourOption.LEADERBOARDS.path));
|
||||
|
||||
for (Map.Entry<UUID, Score> entry : leaderboard.sort(sort).entrySet()) {
|
||||
int rank = items.size() + 1;
|
||||
|
||||
var uuid = entry.getKey();
|
||||
var score = entry.getValue();
|
||||
|
||||
if (score == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Item item = base.clone().material(Material.PLAYER_HEAD)
|
||||
.modifyName(name -> name.replace("%r", Integer.toString(rank))
|
||||
.replace("%s", Integer.toString(score.score()))
|
||||
.replace("%p", score.name())
|
||||
.replace("%t", score.time())
|
||||
.replace("%d", score.difficulty()))
|
||||
.modifyLore(line -> line.replace("%r", Integer.toString(rank))
|
||||
.replace("%s", Integer.toString(score.score()))
|
||||
.replace("%p", score.name())
|
||||
.replace("%t", score.time())
|
||||
.replace("%d", score.difficulty()));
|
||||
|
||||
// Player head gathering
|
||||
ItemStack stack = item.build();
|
||||
|
||||
// if there are more than 36 players, don't show the heads to avoid server crashing
|
||||
// and bedrock has no player skull support
|
||||
if (rank <= 20 && !ParkourUser.isBedrockPlayer(player)) {
|
||||
OfflinePlayer op = Bukkit.getOfflinePlayer(uuid);
|
||||
|
||||
if (op.getName() != null && !op.getName().startsWith(".")) { // bedrock players' names with geyser start with a .
|
||||
SkullMeta meta = (SkullMeta) stack.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
SkullSetter.setPlayerHead(op, meta);
|
||||
item.meta(meta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (uuid.equals(player.getUniqueId())) {
|
||||
menu.item(21, item.clone());
|
||||
}
|
||||
|
||||
items.add(item);
|
||||
}
|
||||
|
||||
List<String> values = Locales.getStringList(locale, "%s.sort.values".formatted(ParkourOption.LEADERBOARDS.path));
|
||||
|
||||
if (values.size() != 3) {
|
||||
LoParkour.logging().stack("Error while trying to get locales for sort values: not enough sort values present",
|
||||
"check your %s locale file".formatted(locale), new IllegalArgumentException());
|
||||
}
|
||||
|
||||
String name = switch (sort) {
|
||||
case SCORE -> values.get(0);
|
||||
case TIME -> values.get(1);
|
||||
case DIFFICULTY -> values.get(2);
|
||||
};
|
||||
|
||||
// get next sorting type
|
||||
var next = switch (sort) {
|
||||
case SCORE -> Leaderboard.Sort.TIME;
|
||||
case TIME -> Leaderboard.Sort.DIFFICULTY;
|
||||
default -> Leaderboard.Sort.SCORE;
|
||||
};
|
||||
|
||||
menu.displayRows(0, 1)
|
||||
.addToDisplay(items)
|
||||
.nextPage(26, new Item(Material.LIME_DYE, "<#0DCB07><bold>»").click(event -> menu.page(1)))
|
||||
.prevPage(18, new Item(Material.RED_DYE, "<#DE1F1F><bold>«").click(event -> menu.page(-1)))
|
||||
.item(22, Locales.getItem(player, ParkourOption.LEADERBOARDS.path + ".sort", name.toLowerCase()).click(event -> open(player, mode, next)))
|
||||
.item(23, Locales.getItem(player, "other.close").click(event -> {
|
||||
List<Mode> modes = Registry.getModes()
|
||||
.stream()
|
||||
.filter(m -> m.getLeaderboard() != null && m.getItem(locale) != null)
|
||||
.toList();
|
||||
|
||||
if (modes.size() == 1) {
|
||||
Menus.COMMUNITY.open(player);
|
||||
return;
|
||||
}
|
||||
|
||||
Menus.LEADERBOARDS.open(event.getPlayer());
|
||||
}))
|
||||
.open(player);
|
||||
}
|
||||
}
|
||||
79
src/main/java/dev/loki/loparkour/menu/lobby/LobbyMenu.java
Normal file
79
src/main/java/dev/loki/loparkour/menu/lobby/LobbyMenu.java
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
package dev.loki.loparkour.menu.lobby;
|
||||
|
||||
import dev.loki.loparkour.config.Locales;
|
||||
import dev.loki.loparkour.menu.DynamicMenu;
|
||||
import dev.loki.loparkour.menu.Menus;
|
||||
import dev.loki.loparkour.menu.ParkourOption;
|
||||
import dev.loki.loparkour.player.ParkourPlayer;
|
||||
import dev.loki.loparkour.player.ParkourUser;
|
||||
import dev.loki.loparkour.session.Session;
|
||||
import dev.efnilite.vilib.inventory.Menu;
|
||||
import dev.efnilite.vilib.inventory.item.SliderItem;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class LobbyMenu extends DynamicMenu {
|
||||
|
||||
public LobbyMenu() {
|
||||
registerMainItem(1, 0, (player, user) -> Locales.getItem(player, "lobby.player_management.item").click(event -> Menus.PLAYER_MANAGEMENT.open(player)), player -> {
|
||||
ParkourUser user = ParkourUser.getUser(player);
|
||||
|
||||
return ParkourOption.PLAYER_MANAGEMENT.mayPerform(player) && user instanceof ParkourPlayer && user.session.getPlayers().get(0) == user;
|
||||
});
|
||||
|
||||
registerMainItem(1, 1, (player, user) -> {
|
||||
if (user == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<String> values = Locales.getStringList(user.locale, "lobby.visibility.values");
|
||||
|
||||
return new SliderItem().initial(switch (user.session.getVisibility()) {
|
||||
case PUBLIC -> 0;
|
||||
case ID_ONLY -> 1;
|
||||
case PRIVATE -> 2;
|
||||
}).add(0, Locales.getItem(player, "lobby.visibility").modifyLore(lore -> lore.replace("%s", values.get(2))), event -> { // public
|
||||
ParkourUser u = ParkourUser.getUser(event.getPlayer());
|
||||
|
||||
if (u != null) {
|
||||
u.session.setVisibility(Session.Visibility.PUBLIC);
|
||||
}
|
||||
|
||||
return true;
|
||||
}).add(1, Locales.getItem(player, "lobby.visibility").modifyLore(lore -> lore.replace("%s", values.get(1))), event -> { // id only
|
||||
ParkourUser u = ParkourUser.getUser(event.getPlayer());
|
||||
|
||||
if (u != null) {
|
||||
u.session.setVisibility(Session.Visibility.ID_ONLY);
|
||||
}
|
||||
|
||||
return true;
|
||||
}).add(2, Locales.getItem(player, "lobby.visibility").modifyLore(lore -> lore.replace("%s", values.get(0))), event -> { // private
|
||||
ParkourUser u = ParkourUser.getUser(event.getPlayer());
|
||||
|
||||
if (u != null) {
|
||||
u.session.setVisibility(Session.Visibility.PRIVATE);
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}, player -> {
|
||||
ParkourUser user = ParkourUser.getUser(player);
|
||||
|
||||
return ParkourOption.VISIBILITY.mayPerform(player) && user instanceof ParkourPlayer && user.session.getPlayers().get(0) == user;
|
||||
});
|
||||
|
||||
registerMainItem(2, 10, (player, user) -> Locales.getItem(player, "other.close").click(event -> event.getPlayer().closeInventory()), player -> true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the main menu.
|
||||
*
|
||||
* @param player The player to open the menu to
|
||||
*/
|
||||
public void open(Player player) {
|
||||
display(player, new Menu(3, Locales.getString(player, "lobby.name"))
|
||||
.distributeRowsEvenly());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
package dev.loki.loparkour.menu.lobby;
|
||||
|
||||
import dev.loki.loparkour.config.Locales;
|
||||
import dev.loki.loparkour.menu.Menus;
|
||||
import dev.loki.loparkour.mode.Modes;
|
||||
import dev.loki.loparkour.player.ParkourPlayer;
|
||||
import dev.loki.loparkour.player.ParkourUser;
|
||||
import dev.loki.loparkour.session.Session;
|
||||
import dev.efnilite.vilib.inventory.PagedMenu;
|
||||
import dev.efnilite.vilib.inventory.item.Item;
|
||||
import dev.efnilite.vilib.util.SkullSetter;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Menu for managing players
|
||||
*/
|
||||
public class PlayerManagementMenu {
|
||||
|
||||
public void open(Player p) {
|
||||
if (p == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ParkourPlayer viewer = ParkourPlayer.getPlayer(p);
|
||||
|
||||
if (viewer == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Session session = viewer.session;
|
||||
|
||||
PagedMenu menu = new PagedMenu(3, Locales.getString(viewer.locale, "lobby.player_management.name"));
|
||||
add(menu, viewer, session.getPlayers().stream().map(player -> (ParkourUser) player).toList());
|
||||
add(menu, viewer, session.getSpectators().stream().map(player -> (ParkourUser) player).toList());
|
||||
|
||||
menu.displayRows(0, 1)
|
||||
.prevPage(18, new Item(Material.RED_DYE, "<#DE1F1F><bold>«").click(event -> menu.page(-1)))
|
||||
.nextPage(26, new Item(Material.LIME_DYE, "<#0DCB07><bold>»").click(event -> menu.page(1)))
|
||||
.item(22, Locales.getItem(viewer.locale, "other.close").click(event -> Menus.LOBBY.open(event.getPlayer())))
|
||||
.open(p);
|
||||
}
|
||||
|
||||
private void add(PagedMenu menu, ParkourUser viewer, Collection<ParkourUser> users) {
|
||||
Session session = viewer.session;
|
||||
|
||||
for (ParkourUser other : users) {
|
||||
if (other == viewer) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Item item = Locales.getItem(viewer.locale, "lobby.player_management.head", other.getName());
|
||||
item.material(Material.PLAYER_HEAD);
|
||||
|
||||
boolean muted = session.isMuted(other);
|
||||
|
||||
List<String> lore = new ArrayList<>();
|
||||
if (muted) {
|
||||
// add top
|
||||
lore.addAll(List.of(Locales.getString(viewer.locale, "lobby.player_management.head.top").split("\\|\\|")));
|
||||
}
|
||||
|
||||
// add bottom
|
||||
lore.addAll(List.of(Locales.getString(viewer.locale, "lobby.player_management.head.bottom").split("\\|\\|")));
|
||||
|
||||
// Player head gathering
|
||||
item.material(Material.PLAYER_HEAD).lore(lore).click(event -> {
|
||||
ClickType click = event.event().getClick();
|
||||
|
||||
switch (click) {
|
||||
case LEFT -> {
|
||||
Modes.DEFAULT.create(other.player);
|
||||
|
||||
other.sendTranslated("lobby.player_management.kicked");
|
||||
|
||||
viewer.sendTranslated("lobby.player_management.advice");
|
||||
open(viewer.player);
|
||||
}
|
||||
case RIGHT -> {
|
||||
session.toggleMute(other);
|
||||
|
||||
if (!muted) {
|
||||
other.sendTranslated("lobby.player_management.muted");
|
||||
} else {
|
||||
other.sendTranslated("lobby.player_management.unmuted");
|
||||
}
|
||||
|
||||
open(viewer.player);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ItemStack stack = item.build(); // Updating meta requires building
|
||||
stack.setType(Material.PLAYER_HEAD);
|
||||
|
||||
// bedrock has no player skull support
|
||||
if (menu.getTotalToDisplay().size() <= 36 && !ParkourUser.isBedrockPlayer(other.player)) {
|
||||
if (other.getName() != null && !other.getName().startsWith(".")) { // bedrock players' names with geyser start with a .
|
||||
SkullMeta meta = (SkullMeta) stack.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
SkullSetter.setPlayerHead(other.player, meta);
|
||||
item.meta(meta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
menu.addToDisplay(List.of(item));
|
||||
}
|
||||
}
|
||||
}
|
||||
38
src/main/java/dev/loki/loparkour/menu/play/PlayMenu.java
Normal file
38
src/main/java/dev/loki/loparkour/menu/play/PlayMenu.java
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
package dev.loki.loparkour.menu.play;
|
||||
|
||||
import dev.loki.loparkour.config.Locales;
|
||||
import dev.loki.loparkour.menu.DynamicMenu;
|
||||
import dev.loki.loparkour.menu.Menus;
|
||||
import dev.loki.loparkour.menu.ParkourOption;
|
||||
import dev.efnilite.vilib.inventory.Menu;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* The menu where players can join modes
|
||||
*/
|
||||
public class PlayMenu extends DynamicMenu {
|
||||
|
||||
public PlayMenu() {
|
||||
registerMainItem(1, 0, (player, user) -> Locales.getItem(player, "play.single.item")
|
||||
.click(event -> Menus.SINGLE.open(event.getPlayer())),
|
||||
ParkourOption.SINGLE::mayPerform);
|
||||
|
||||
registerMainItem(1, 1, (player, user) -> Locales.getItem(player, "other.iep")
|
||||
.click(event -> event.getPlayer().performCommand("iep play")),
|
||||
player -> Bukkit.getPluginManager().isPluginEnabled("IEP"));
|
||||
|
||||
registerMainItem(1, 6, (player, user) -> Locales.getItem(player, "play.spectator.item")
|
||||
.click(event -> Menus.SPECTATOR.open(event.getPlayer())),
|
||||
ParkourOption.SPECTATOR::mayPerform);
|
||||
|
||||
registerMainItem(2, 0, (player, user) -> Locales.getItem(player, "other.close")
|
||||
.click(event -> event.getPlayer().closeInventory()),
|
||||
player -> true);
|
||||
}
|
||||
|
||||
public void open(Player player) {
|
||||
display(player, new Menu(3, Locales.getString(player, "play.name"))
|
||||
.distributeRowsEvenly());
|
||||
}
|
||||
}
|
||||
68
src/main/java/dev/loki/loparkour/menu/play/SingleMenu.java
Normal file
68
src/main/java/dev/loki/loparkour/menu/play/SingleMenu.java
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
package dev.loki.loparkour.menu.play;
|
||||
|
||||
import dev.loki.loparkour.api.Registry;
|
||||
import dev.loki.loparkour.config.Config;
|
||||
import dev.loki.loparkour.config.Locales;
|
||||
import dev.loki.loparkour.config.Option;
|
||||
import dev.loki.loparkour.menu.Menus;
|
||||
import dev.loki.loparkour.menu.ParkourOption;
|
||||
import dev.loki.loparkour.mode.Mode;
|
||||
import dev.loki.loparkour.mode.MultiMode;
|
||||
import dev.loki.loparkour.player.ParkourUser;
|
||||
import dev.efnilite.vilib.inventory.PagedMenu;
|
||||
import dev.efnilite.vilib.inventory.item.Item;
|
||||
import dev.efnilite.vilib.inventory.item.MenuItem;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The menu to select single player modes
|
||||
*/
|
||||
public class SingleMenu {
|
||||
|
||||
public void open(Player player) {
|
||||
ParkourUser user = ParkourUser.getUser(player);
|
||||
String locale = user == null ? Option.OPTIONS_DEFAULTS.get(ParkourOption.LANG) : user.locale;
|
||||
|
||||
List<Mode> modes = Registry.getModes();
|
||||
|
||||
List<MenuItem> items = new ArrayList<>();
|
||||
List<Mode> modeSet = new ArrayList<>();
|
||||
for (Mode mode : modes) {
|
||||
boolean permissions = Config.CONFIG.getBoolean("permissions.enabled") && !player.hasPermission("LoParkour.gamemode." + mode.getName());
|
||||
|
||||
Item item = mode.getItem(locale);
|
||||
|
||||
if (permissions || mode instanceof MultiMode || item == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
modeSet.add(mode);
|
||||
|
||||
items.add(item.clone().click(event -> {
|
||||
if (user == null || Duration.between(user.joined, Instant.now()).toSeconds() > 3) {
|
||||
mode.create(player);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
if (modeSet.size() == 1) {
|
||||
modeSet.get(0).create(player);
|
||||
return;
|
||||
}
|
||||
|
||||
PagedMenu mode = new PagedMenu(3, Locales.getString(player, "play.single.name"));
|
||||
mode.displayRows(0, 1)
|
||||
.addToDisplay(items)
|
||||
.nextPage(26, new Item(Material.LIME_DYE, "<#0DCB07><bold>»").click(event -> mode.page(1)))
|
||||
.prevPage(18, new Item(Material.RED_DYE, "<#DE1F1F><bold>«").click(event -> mode.page(-1)))
|
||||
.item(22, Locales.getItem(player, "other.close").click(event -> Menus.PLAY.open(event.getPlayer())))
|
||||
.open(player);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
package dev.loki.loparkour.menu.play;
|
||||
|
||||
import dev.loki.loparkour.config.Locales;
|
||||
import dev.loki.loparkour.config.Option;
|
||||
import dev.loki.loparkour.menu.Menus;
|
||||
import dev.loki.loparkour.menu.ParkourOption;
|
||||
import dev.loki.loparkour.mode.Modes;
|
||||
import dev.loki.loparkour.player.ParkourUser;
|
||||
import dev.loki.loparkour.session.Session;
|
||||
import dev.loki.loparkour.world.Divider;
|
||||
import dev.efnilite.vilib.inventory.PagedMenu;
|
||||
import dev.efnilite.vilib.inventory.item.Item;
|
||||
import dev.efnilite.vilib.inventory.item.MenuItem;
|
||||
import dev.efnilite.vilib.util.SkullSetter;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The menu to select other players to spectate
|
||||
*/
|
||||
public class SpectatorMenu {
|
||||
|
||||
public void open(Player player) {
|
||||
ParkourUser user = ParkourUser.getUser(player);
|
||||
String locale = user == null ? Option.OPTIONS_DEFAULTS.get(ParkourOption.LANG) : user.locale;
|
||||
|
||||
PagedMenu spectator = new PagedMenu(3, Locales.getString(player, "play.spectator.name"));
|
||||
|
||||
List<MenuItem> display = new ArrayList<>();
|
||||
|
||||
for (Session session : Divider.sections.keySet()) {
|
||||
if (!session.isAcceptingSpectators()) { // only showcase sessions with spectators enabled
|
||||
continue;
|
||||
}
|
||||
|
||||
if (user != null && session == user.session) { // don't let player join their own session
|
||||
continue;
|
||||
}
|
||||
|
||||
if (session.getPlayers().isEmpty()) { // weird but possible
|
||||
continue;
|
||||
}
|
||||
|
||||
var pp = session.getPlayers().get(0);
|
||||
|
||||
Item item = Locales.getItem(locale, "play.spectator.head", pp.getName());
|
||||
// Player head gathering
|
||||
item.material(Material.PLAYER_HEAD);
|
||||
|
||||
ItemStack stack = item.build(); // Updating meta requires building
|
||||
stack.setType(Material.PLAYER_HEAD);
|
||||
|
||||
// bedrock has no player skull support
|
||||
if (!ParkourUser.isBedrockPlayer(player)) {
|
||||
if (pp.getName() != null && !pp.getName().startsWith(".")) { // bedrock players' names with geyser start with a .
|
||||
SkullMeta meta = (SkullMeta) stack.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
SkullSetter.setPlayerHead(pp.player, meta);
|
||||
item.meta(meta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
item.click(event -> Modes.SPECTATOR.create(player, session));
|
||||
|
||||
display.add(item);
|
||||
}
|
||||
|
||||
spectator.displayRows(0, 1)
|
||||
.addToDisplay(display)
|
||||
.nextPage(26, new Item(Material.LIME_DYE, "<#0DCB07><bold>»").click(event -> spectator.page(1)))
|
||||
.prevPage(18, new Item(Material.RED_DYE, "<#DE1F1F><bold>«").click(event -> spectator.page(-1)))
|
||||
.item(22, Locales.getItem(player, "other.close").click(event -> Menus.PLAY.open(event.getPlayer())))
|
||||
.open(player);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
46
src/main/java/dev/loki/loparkour/menu/settings/LangMenu.java
Normal file
46
src/main/java/dev/loki/loparkour/menu/settings/LangMenu.java
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
package dev.loki.loparkour.menu.settings;
|
||||
|
||||
import dev.loki.loparkour.config.Locales;
|
||||
import dev.loki.loparkour.menu.Menus;
|
||||
import dev.loki.loparkour.player.ParkourPlayer;
|
||||
import dev.efnilite.vilib.inventory.PagedMenu;
|
||||
import dev.efnilite.vilib.inventory.item.Item;
|
||||
import dev.efnilite.vilib.inventory.item.MenuItem;
|
||||
import org.bukkit.Material;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class LangMenu {
|
||||
|
||||
/**
|
||||
* Opens the language menu
|
||||
*
|
||||
* @param user The ParkourPlayer instance
|
||||
*/
|
||||
public void open(ParkourPlayer user) {
|
||||
if (user == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
PagedMenu style = new PagedMenu(3, Locales.getString(user.locale, "settings.lang.name"));
|
||||
|
||||
List<MenuItem> items = new ArrayList<>();
|
||||
for (String lang : Locales.locales.keySet()) {
|
||||
Item item = new Item(Material.PAPER, "<#238681><bold>" + Locales.getString(lang, "name"));
|
||||
|
||||
items.add(item.click(event -> {
|
||||
user.locale = lang;
|
||||
user._locale = lang;
|
||||
Menus.SETTINGS.open(event.getPlayer());
|
||||
}));
|
||||
}
|
||||
|
||||
style.displayRows(0, 1).addToDisplay(items)
|
||||
.nextPage(26, new Item(Material.LIME_DYE, "<#0DCB07><bold>»").click(event -> style.page(1)))
|
||||
.prevPage(18, new Item(Material.RED_DYE, "<#DE1F1F><bold>«").click(event -> style.page(-1)))
|
||||
.item(22, Locales.getItem(user.locale, "other.close").click(event -> Menus.SETTINGS.open(event.getPlayer())))
|
||||
.open(user.player);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,344 @@
|
|||
package dev.loki.loparkour.menu.settings;
|
||||
|
||||
import dev.loki.loparkour.LoParkour;
|
||||
import dev.loki.loparkour.api.Registry;
|
||||
import dev.loki.loparkour.config.Config;
|
||||
import dev.loki.loparkour.config.Locales;
|
||||
import dev.loki.loparkour.config.Option;
|
||||
import dev.loki.loparkour.menu.DynamicMenu;
|
||||
import dev.loki.loparkour.menu.Menus;
|
||||
import dev.loki.loparkour.menu.ParkourOption;
|
||||
import dev.loki.loparkour.player.ParkourPlayer;
|
||||
import dev.loki.loparkour.player.ParkourUser;
|
||||
import dev.loki.loparkour.style.RandomStyle;
|
||||
import dev.loki.loparkour.style.Style;
|
||||
import dev.efnilite.vilib.fastboard.FastBoard;
|
||||
import dev.efnilite.vilib.inventory.Menu;
|
||||
import dev.efnilite.vilib.inventory.MenuClickEvent;
|
||||
import dev.efnilite.vilib.inventory.PagedMenu;
|
||||
import dev.efnilite.vilib.inventory.item.Item;
|
||||
import dev.efnilite.vilib.inventory.item.MenuItem;
|
||||
import dev.efnilite.vilib.inventory.item.SliderItem;
|
||||
import dev.efnilite.vilib.inventory.item.TimedItem;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Handles all menu-related activities
|
||||
*
|
||||
* @author loki
|
||||
* @since v3.0.0
|
||||
*/
|
||||
public class ParkourSettingsMenu extends DynamicMenu {
|
||||
|
||||
public ParkourSettingsMenu(ParkourOption... disabled) {
|
||||
|
||||
// ---------- top row ----------
|
||||
|
||||
// styles
|
||||
registerMainItem(1, 0, (p, user) -> Locales.getItem(p, ParkourOption.STYLES.path + ".item", user instanceof ParkourPlayer player ? player.style : null).click(event -> {
|
||||
if (!(user instanceof ParkourPlayer player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
openStyleMenu(player);
|
||||
}), player -> checkOptions(player, ParkourOption.STYLES, disabled));
|
||||
|
||||
// leads
|
||||
registerMainItem(1, 1, (p, user) -> {
|
||||
Item displayItem = Locales.getItem(p, ParkourOption.LEADS.path);
|
||||
|
||||
if (!(user instanceof ParkourPlayer player)) {
|
||||
return displayItem;
|
||||
}
|
||||
|
||||
List<Integer> leads = Option.POSSIBLE_LEADS;
|
||||
|
||||
SliderItem item = new SliderItem().initial(leads.indexOf(player.blockLead)); // initial value of the player
|
||||
|
||||
int slot = 0;
|
||||
for (int value : leads) {
|
||||
item.add(slot, displayItem.clone()
|
||||
.amount(value)
|
||||
.modifyLore(line -> line.replace("%s", Integer.toString(value))),
|
||||
event2 -> handleSettingChange(player, () -> player.blockLead = value));
|
||||
slot++;
|
||||
}
|
||||
return item;
|
||||
}, player -> checkOptions(player, ParkourOption.LEADS, disabled));
|
||||
|
||||
// schematics
|
||||
registerMainItem(1, 8, (p, user) -> {
|
||||
Item item = Locales.getItem(p, ParkourOption.SCHEMATICS.path);
|
||||
|
||||
if (!(user instanceof ParkourPlayer player)) {
|
||||
return item;
|
||||
}
|
||||
|
||||
List<Double> difficulties = List.of(0.0, 0.25, 0.5, 0.75, 1.0);
|
||||
List<String> values = Locales.getStringList(user.locale, "%s.values".formatted(ParkourOption.SCHEMATICS.path));
|
||||
|
||||
if (!difficulties.contains(player.schematicDifficulty)) {
|
||||
player.schematicDifficulty = difficulties.get(0);
|
||||
}
|
||||
|
||||
return new SliderItem()
|
||||
.initial(difficulties.indexOf(player.schematicDifficulty))
|
||||
.add(0, item.clone()
|
||||
.material(Material.RED_STAINED_GLASS_PANE)
|
||||
.modifyLore(line -> line.replace("%s", values.get(0))),
|
||||
event -> handleScoreSettingChange(player, event, () -> player.schematicDifficulty = 0.0))
|
||||
.add(1, item.clone()
|
||||
.material(Material.LIME_STAINED_GLASS_PANE)
|
||||
.modifyLore(line -> line.replace("%s", values.get(1))),
|
||||
event -> handleScoreSettingChange(player, event, () -> player.schematicDifficulty = 0.25))
|
||||
.add(2, item.clone()
|
||||
.material(Material.YELLOW_STAINED_GLASS_PANE)
|
||||
.modifyLore(line -> line.replace("%s", values.get(2))),
|
||||
event -> handleScoreSettingChange(player, event, () -> player.schematicDifficulty = 0.5))
|
||||
.add(3, item.clone()
|
||||
.material(Material.ORANGE_STAINED_GLASS_PANE)
|
||||
.modifyLore(line -> line.replace("%s", values.get(3))),
|
||||
event -> handleScoreSettingChange(player, event, () -> player.schematicDifficulty = 0.75))
|
||||
.add(4, item.clone()
|
||||
.material(Material.SKELETON_SKULL)
|
||||
.modifyLore(line -> line.replace("%s", values.get(4))),
|
||||
event -> handleScoreSettingChange(player, event, () -> player.schematicDifficulty = 1.0));
|
||||
}, player -> checkOptions(player, ParkourOption.SCHEMATICS, disabled));
|
||||
|
||||
// time
|
||||
registerMainItem(1, 9, (p, user) -> {
|
||||
Item item = Locales.getItem(p, ParkourOption.TIME.path);
|
||||
|
||||
if (!(user instanceof ParkourPlayer player)) {
|
||||
return item;
|
||||
}
|
||||
|
||||
// Tick times start at 6:00 and total is 24.000.
|
||||
// Source: https://minecraft.fandom.com/wiki/Daylight_cycle?file=Day_Night_Clock_24h.png
|
||||
List<Integer> times = Arrays.asList(0, 6000, 12000, 18000); // 00:00 -> 6:00 -> 12:00 -> 18:00
|
||||
|
||||
var format = Config.CONFIG.getInt("options.time.format");
|
||||
|
||||
return new SliderItem()
|
||||
.initial(times.indexOf(player.selectedTime))
|
||||
.add(0, item.clone()
|
||||
.modifyLore(line -> line.replace("%s", format == 12 ? "12:00 AM" : "00:00")),
|
||||
event -> handleSettingChange(player, () -> player.selectedTime = 0))
|
||||
.add(1, item.clone()
|
||||
.modifyLore(line -> line.replace("%s", format == 12 ? "6:00 AM" : "6:00")),
|
||||
event -> handleSettingChange(player, () -> player.selectedTime = 6000))
|
||||
.add(2, item.clone()
|
||||
.modifyLore(line -> line.replace("%s", format == 12 ? "12:00 PM" : "12:00")),
|
||||
event -> handleSettingChange(player, () -> player.selectedTime = 12000))
|
||||
.add(3, item.clone()
|
||||
.modifyLore(line -> line.replace("%s", format == 12 ? "6:00 PM" : "18:00")),
|
||||
event -> handleSettingChange(player, () -> player.selectedTime = 18000));
|
||||
}, player -> checkOptions(player, ParkourOption.TIME, disabled));
|
||||
|
||||
// ---------- bottom row ----------
|
||||
|
||||
// show scoreboard
|
||||
registerMainItem(2, 0, (p, user) -> {
|
||||
Item item = Locales.getItem(p, ParkourOption.SCOREBOARD.path);
|
||||
|
||||
if (!(user instanceof ParkourPlayer player)) {
|
||||
return item;
|
||||
}
|
||||
|
||||
return new SliderItem()
|
||||
.initial(player.showScoreboard ? 0 : 1)
|
||||
.add(0, item.clone()
|
||||
.material(Material.LIME_STAINED_GLASS_PANE)
|
||||
.modifyName(name -> "<#0DCB07><bold>" + ChatColor.stripColor(name))
|
||||
.modifyLore(line -> line.replace("%s", getBooleanSymbol(user, true))),
|
||||
event -> handleSettingChange(player, () -> {
|
||||
player.showScoreboard = true;
|
||||
player.board = new FastBoard(p);
|
||||
}))
|
||||
.add(1, item.clone()
|
||||
.material(Material.RED_STAINED_GLASS_PANE)
|
||||
.modifyName(name -> "<red><bold>" + ChatColor.stripColor(name))
|
||||
.modifyLore(line -> line.replace("%s", getBooleanSymbol(user, false))),
|
||||
event -> handleSettingChange(player, () -> {
|
||||
player.showScoreboard = false;
|
||||
if (player.board != null && !player.board.isDeleted()) {
|
||||
player.board.delete();
|
||||
}
|
||||
}));
|
||||
}, player -> checkOptions(player, ParkourOption.SCOREBOARD, disabled) && Boolean.parseBoolean(Option.OPTIONS_DEFAULTS.get(ParkourOption.SCOREBOARD)));
|
||||
|
||||
// show fall message
|
||||
registerMainItem(2, 1, (p, user) -> {
|
||||
Item item = Locales.getItem(p, ParkourOption.FALL_MESSAGE.path + ".item");
|
||||
|
||||
if (!(user instanceof ParkourPlayer player)) {
|
||||
return item;
|
||||
}
|
||||
|
||||
return new SliderItem()
|
||||
.initial(player.showFallMessage ? 0 : 1)
|
||||
.add(0, item.clone()
|
||||
.material(Material.LIME_STAINED_GLASS_PANE)
|
||||
.modifyName(name -> "<#0DCB07><bold>" + ChatColor.stripColor(name))
|
||||
.modifyLore(line -> line.replace("%s", getBooleanSymbol(user, true))),
|
||||
event -> handleSettingChange(player, () -> player.showFallMessage = true))
|
||||
.add(1, item.clone()
|
||||
.material(Material.RED_STAINED_GLASS_PANE)
|
||||
.modifyName(name -> "<red><bold>" + ChatColor.stripColor(name))
|
||||
.modifyLore(line -> line.replace("%s", getBooleanSymbol(user, false))),
|
||||
event -> handleSettingChange(player, () -> player.showFallMessage = false));
|
||||
}, player -> checkOptions(player, ParkourOption.FALL_MESSAGE, disabled));
|
||||
|
||||
// show sound
|
||||
registerMainItem(2, 2, (p, user) -> {
|
||||
Item item = Locales.getItem(p, ParkourOption.PARTICLES.path);
|
||||
|
||||
if (!(user instanceof ParkourPlayer player)) {
|
||||
return item;
|
||||
}
|
||||
|
||||
return new SliderItem()
|
||||
.initial(player.particles ? 0 : 1)
|
||||
.add(0, item.clone().material(Material.LIME_STAINED_GLASS_PANE)
|
||||
.modifyName(name -> "<#0DCB07><bold>" + ChatColor.stripColor(name))
|
||||
.modifyLore(line -> line.replace("%s", getBooleanSymbol(user, true))),
|
||||
event -> handleSettingChange(player, () -> player.particles = true))
|
||||
.add(1, item.clone()
|
||||
.material(Material.RED_STAINED_GLASS_PANE)
|
||||
.modifyName(name -> "<red><bold>" + ChatColor.stripColor(name))
|
||||
.modifyLore(line -> line.replace("%s", getBooleanSymbol(user, false))),
|
||||
event -> handleSettingChange(player, () -> player.particles = false));
|
||||
}, player -> checkOptions(player, ParkourOption.PARTICLES, disabled));
|
||||
|
||||
// show sound
|
||||
registerMainItem(2, 3, (p, user) -> {
|
||||
Item item = Locales.getItem(p, ParkourOption.SOUND.path);
|
||||
|
||||
if (!(user instanceof ParkourPlayer player)) {
|
||||
return item;
|
||||
}
|
||||
|
||||
return new SliderItem()
|
||||
.initial(player.sound ? 0 : 1)
|
||||
.add(0, item.clone()
|
||||
.material(Material.LIME_STAINED_GLASS_PANE)
|
||||
.modifyName(name -> "<#0DCB07><bold>" + ChatColor.stripColor(name))
|
||||
.modifyLore(line -> line.replace("%s", getBooleanSymbol(user, true))),
|
||||
event -> handleSettingChange(player, () -> player.sound = true))
|
||||
.add(1, item.clone()
|
||||
.material(Material.RED_STAINED_GLASS_PANE)
|
||||
.modifyName(name -> "<red><bold>" + ChatColor.stripColor(name))
|
||||
.modifyLore(line -> line.replace("%s", getBooleanSymbol(user, false))),
|
||||
event -> handleSettingChange(player, () -> player.sound = false));
|
||||
}, player -> checkOptions(player, ParkourOption.SOUND, disabled));
|
||||
|
||||
// show special blocks
|
||||
registerMainItem(2, 4, (p, user) -> {
|
||||
Item item = Locales.getItem(p, ParkourOption.SPECIAL_BLOCKS.path);
|
||||
|
||||
if (!(user instanceof ParkourPlayer player)) {
|
||||
return item;
|
||||
}
|
||||
|
||||
return new SliderItem()
|
||||
.initial(player.useSpecialBlocks ? 0 : 1)
|
||||
.add(0, item.clone()
|
||||
.material(Material.LIME_STAINED_GLASS_PANE)
|
||||
.modifyName(name -> "<#0DCB07><bold>" + ChatColor.stripColor(name))
|
||||
.modifyLore(line -> line.replace("%s", getBooleanSymbol(user, true))),
|
||||
event -> handleScoreSettingChange(player, event, () -> player.useSpecialBlocks = true))
|
||||
.add(1, item.clone()
|
||||
.material(Material.RED_STAINED_GLASS_PANE)
|
||||
.modifyName(name -> "<red><bold>" + ChatColor.stripColor(name))
|
||||
.modifyLore(line -> line.replace("%s", getBooleanSymbol(user, false))),
|
||||
event -> handleScoreSettingChange(player, event, () -> player.useSpecialBlocks = false));
|
||||
}, player -> checkOptions(player, ParkourOption.SPECIAL_BLOCKS, disabled));
|
||||
|
||||
// Always allow closing of the menu
|
||||
registerMainItem(3, 10,
|
||||
(player, user) -> Locales.getItem(player, "other.close")
|
||||
.click(event -> Menus.SETTINGS.open(event.getPlayer())),
|
||||
player -> true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the main menu to a valid ParkourPlayer instance
|
||||
*
|
||||
* @param user The ParkourPlayer
|
||||
*/
|
||||
public void open(ParkourPlayer user) {
|
||||
display(user.player, new Menu(4, Locales.getString(user.locale, "settings.name"))
|
||||
.distributeRowEvenly(0, 1, 2, 3)
|
||||
.item(27, Locales.getItem(user.locale, "other.close").click(event -> Menus.SETTINGS.open(event.getPlayer()))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the style menu
|
||||
*
|
||||
* @param player The ParkourPlayer instance
|
||||
*/
|
||||
public void openStyleMenu(ParkourPlayer player) {
|
||||
// init menu
|
||||
PagedMenu menu = new PagedMenu(3, Locales.getString(player.locale, ParkourOption.STYLES.path + ".name"));
|
||||
|
||||
List<MenuItem> items = new ArrayList<>();
|
||||
for (Style style : Registry.getStyles()) {
|
||||
var name = style.getName();
|
||||
|
||||
var perm = "%s.%s".formatted(ParkourOption.STYLES.permission, name.toLowerCase());
|
||||
if (Config.CONFIG.getBoolean("permissions.per-style") && !player.player.hasPermission(perm.replace(" ", "."))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var category = style instanceof RandomStyle ? "random" : "incremental";
|
||||
|
||||
items.add(Locales.getItem(player.player, ParkourOption.STYLES.path + ".style_item", name, category)
|
||||
.material(style.getNext())
|
||||
.click(event -> {
|
||||
player.style = name;
|
||||
player.updateGeneratorSettings(player.session.generator);
|
||||
open(player);
|
||||
}));
|
||||
}
|
||||
|
||||
menu.displayRows(0, 1)
|
||||
.addToDisplay(items)
|
||||
.nextPage(26, new Item(Material.LIME_DYE, "<#0DCB07><bold>»").click(event -> menu.page(1)))
|
||||
.prevPage(18, new Item(Material.RED_DYE, "<#DE1F1F><bold>«").click(event -> menu.page(-1)))
|
||||
.item(22, Locales.getItem(player.locale, "other.close").click(event -> open(player)))
|
||||
.open(player.player);
|
||||
}
|
||||
|
||||
private boolean handleSettingChange(ParkourPlayer player, Runnable onAllowed) {
|
||||
onAllowed.run();
|
||||
player.updateGeneratorSettings(player.session.generator);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean handleScoreSettingChange(ParkourPlayer player, MenuClickEvent event, Runnable onAllowed) {
|
||||
if (player.session.generator.score == 0) {
|
||||
return handleSettingChange(player, onAllowed);
|
||||
}
|
||||
|
||||
event.menu().item(event.slot(), new TimedItem(Locales.getItem(player.locale, "settings.parkour_settings.items.no_change").click((event1) -> {}), event, LoParkour.getPlugin()).stay(5 * 20));
|
||||
event.menu().updateItem(event.slot());
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
// replaces true/false with a checkmark and cross
|
||||
private String getBooleanSymbol(ParkourUser user, boolean value) {
|
||||
return value ? Locales.getString(user.player, "settings.parkour_settings.enabled") : Locales.getString(user.player, "settings.parkour_settings.disabled");
|
||||
}
|
||||
|
||||
// check if option is allowed to be displayed
|
||||
private boolean checkOptions(Player player, ParkourOption option, ParkourOption[] disabled) {
|
||||
return !Arrays.asList(disabled).contains(option) && option.mayPerform(player);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
package dev.loki.loparkour.menu.settings;
|
||||
|
||||
import dev.loki.loparkour.config.Locales;
|
||||
import dev.loki.loparkour.menu.DynamicMenu;
|
||||
import dev.loki.loparkour.menu.Menus;
|
||||
import dev.loki.loparkour.menu.ParkourOption;
|
||||
import dev.loki.loparkour.player.ParkourPlayer;
|
||||
import dev.loki.loparkour.player.ParkourUser;
|
||||
import dev.loki.loparkour.session.Session;
|
||||
import dev.efnilite.vilib.inventory.Menu;
|
||||
import dev.efnilite.vilib.inventory.item.SliderItem;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The menu for settings
|
||||
*/
|
||||
public class SettingsMenu extends DynamicMenu {
|
||||
|
||||
public SettingsMenu() {
|
||||
registerMainItem(1, 0, (player, user) -> Locales.getItem(player, "settings.parkour_settings.item").click(event -> {
|
||||
ParkourPlayer pp = ParkourPlayer.getPlayer(event.getPlayer());
|
||||
|
||||
if (pp != null) {
|
||||
pp.session.generator.menu(pp);
|
||||
}
|
||||
}), player -> ParkourOption.PARKOUR_SETTINGS.mayPerform(player) && ParkourPlayer.isPlayer(player));
|
||||
|
||||
registerMainItem(1, 1, (player, user) -> Locales.getItem(player, "settings.lang.item", user != null ? Locales.getString(user.locale, "name") : "?").click(event -> Menus.LANG.open(ParkourPlayer.getPlayer(event.getPlayer()))), player -> ParkourOption.LANG.mayPerform(player) && ParkourUser.isUser(player));
|
||||
|
||||
registerMainItem(1, 2, (player, user) -> {
|
||||
// user has to be not-null to see this item
|
||||
assert user != null;
|
||||
|
||||
List<String> values = Locales.getStringList(user.locale, "settings.chat.values");
|
||||
|
||||
return new SliderItem().initial(switch (user.chatType) {
|
||||
case LOBBY_ONLY -> 0;
|
||||
case PLAYERS_ONLY -> 1;
|
||||
case PUBLIC -> 2;
|
||||
}).add(0, Locales.getItem(player, "settings.chat").modifyLore(lore -> lore.replace("%s", values.get(0))), event -> { // lobby only
|
||||
ParkourUser u = ParkourUser.getUser(event.getPlayer());
|
||||
|
||||
if (u != null) {
|
||||
u.chatType = Session.ChatType.LOBBY_ONLY;
|
||||
}
|
||||
|
||||
return true;
|
||||
}).add(1, Locales.getItem(player, "settings.chat").modifyLore(lore -> lore.replace("%s", values.get(1))), event -> { // players only
|
||||
ParkourUser u = ParkourUser.getUser(event.getPlayer());
|
||||
|
||||
if (u != null) {
|
||||
u.chatType = Session.ChatType.PLAYERS_ONLY;
|
||||
}
|
||||
|
||||
return true;
|
||||
}).add(2, Locales.getItem(player, "settings.chat").modifyLore(lore -> lore.replace("%s", values.get(2))), event -> { // public
|
||||
ParkourUser u = ParkourUser.getUser(event.getPlayer());
|
||||
|
||||
if (u != null) {
|
||||
u.chatType = Session.ChatType.PUBLIC;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}, player -> ParkourOption.CHAT.mayPerform(player) && ParkourUser.isUser(player));
|
||||
|
||||
registerMainItem(2, 0, (player, user) -> Locales.getItem(player, "other.close").click(event -> event.getPlayer().closeInventory()), player -> true);
|
||||
}
|
||||
|
||||
public void open(Player player) {
|
||||
display(player, new Menu(3, Locales.getString(player, "settings.name")).distributeRowsEvenly());
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue