feat: elytra firework boost, obstacle mode, duels menu, tests
- ElytraBoost: one-shot firework boost (v*0.7+dir*0.6, FIREWORKS_SPARK,
rocket sounds) on entering ascending section + sustained thrust; Particle.
FIREWORK doesn't exist in spigot-api 1.20.4 -> FIREWORKS_SPARK
- ObstacleGenerator (client-side obstacles: PILLARS/LINES/HOLE_IN_WALL/
CIRCLE/DIAMOND via ClientBlockChanger.sendNow) + ObstacleMode + locales
- DuelsMenu (lists open duels sessions, click to join) + /parkour duels
command + tab completion + locales play.multi.duels.{name,menu_empty}
- Tests: ElytraSection/PointType/KnotDirector/SingleDuelsGenerator (15 new)
- checkstyle 0/0 (main+test), PMD 0, 41 tests pass
This commit is contained in:
parent
5707cf2d24
commit
3b5d3d97d5
19 changed files with 804 additions and 28 deletions
|
|
@ -3,6 +3,7 @@ package dev.loki.loparkour.menu.core;
|
|||
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.DuelsMenu;
|
||||
import dev.loki.loparkour.menu.lobby.LobbyMenu;
|
||||
import dev.loki.loparkour.menu.lobby.PlayerManagementMenu;
|
||||
import dev.loki.loparkour.menu.play.PlayMenu;
|
||||
|
|
@ -37,6 +38,7 @@ public final class Menus {
|
|||
public static ParkourSettingsMenu PARKOUR_SETTINGS = new ParkourSettingsMenu();
|
||||
|
||||
// lobby
|
||||
public static DuelsMenu DUELS = new DuelsMenu();
|
||||
public static LobbyMenu LOBBY = new LobbyMenu();
|
||||
public static PlayerManagementMenu PLAYER_MANAGEMENT = new PlayerManagementMenu();
|
||||
|
||||
|
|
|
|||
123
src/main/java/dev/loki/loparkour/menu/lobby/DuelsMenu.java
Normal file
123
src/main/java/dev/loki/loparkour/menu/lobby/DuelsMenu.java
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
package dev.loki.loparkour.menu.lobby;
|
||||
|
||||
import dev.loki.loparkour.config.locale.Locales;
|
||||
import dev.loki.loparkour.duels.DuelsGenerator;
|
||||
import dev.loki.loparkour.menu.core.LPMenu;
|
||||
import dev.loki.loparkour.mode.base.Modes;
|
||||
import dev.loki.loparkour.player.core.ParkourUser;
|
||||
import dev.loki.loparkour.session.core.Session;
|
||||
import dev.loki.loparkour.util.text.ColorUtil;
|
||||
import dev.loki.loparkour.world.core.Divider;
|
||||
import dev.lolib.gui.InventoryGUI;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Lists open duels sessions and lets the player join one.
|
||||
*/
|
||||
public class DuelsMenu extends LPMenu {
|
||||
|
||||
private static final int ROWS = 3;
|
||||
private static final int ITEMS_PER_PAGE = 7;
|
||||
private static final int FIRST_SLOT = 10;
|
||||
private static final int PREV_SLOT = 0;
|
||||
private static final int NEXT_SLOT = 8;
|
||||
private static final int SLOT_EMPTY = 13;
|
||||
private static final int SLOT_CLOSE = 22;
|
||||
|
||||
private int currentPage = 0;
|
||||
|
||||
@Override
|
||||
public void open(@NotNull Player player) {
|
||||
open(player, 0);
|
||||
}
|
||||
|
||||
public void open(@NotNull Player player, int page) {
|
||||
this.currentPage = page;
|
||||
final String locale = locale(player);
|
||||
final String title = Locales.getString(locale, "play.multi.duels.name");
|
||||
|
||||
final List<Session> sessions = collectOpenSessions();
|
||||
|
||||
final int totalPages = (int) Math.ceil((double) sessions.size() / ITEMS_PER_PAGE);
|
||||
final int startIndex = currentPage * ITEMS_PER_PAGE;
|
||||
final int endIndex = Math.min(startIndex + ITEMS_PER_PAGE, sessions.size());
|
||||
|
||||
InventoryGUI gui = baseGui(title, ROWS);
|
||||
|
||||
if (sessions.isEmpty()) {
|
||||
gui = gui.setItem(SLOT_EMPTY, localeItem(player, "play.multi.duels.menu_empty"));
|
||||
} else {
|
||||
for (int i = startIndex; i < endIndex; i++) {
|
||||
final Session session = sessions.get(i);
|
||||
final int slot = FIRST_SLOT + (i - startIndex);
|
||||
gui = gui.setItem(slot, sessionItem(player, session), e -> {
|
||||
Modes.DUELS.join(player, session);
|
||||
player.closeInventory();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (currentPage > 0) {
|
||||
gui = gui.setItem(PREV_SLOT, backItem(player), e -> open(player, currentPage - 1));
|
||||
}
|
||||
|
||||
if (currentPage < totalPages - 1) {
|
||||
gui = gui.setItem(NEXT_SLOT, nextItem(player), e -> open(player, currentPage + 1));
|
||||
}
|
||||
|
||||
gui.setItem(SLOT_CLOSE, closeButton(player), e -> player.closeInventory())
|
||||
.open(player);
|
||||
}
|
||||
|
||||
private List<Session> collectOpenSessions() {
|
||||
final int maxPlayers = Modes.DUELS.getMaxPlayers();
|
||||
final List<Session> sessions = new ArrayList<>();
|
||||
for (final Session session : Divider.SECTIONS.keySet()) {
|
||||
if (isOpenForJoining(session, maxPlayers)) {
|
||||
sessions.add(session);
|
||||
}
|
||||
}
|
||||
return sessions;
|
||||
}
|
||||
|
||||
private boolean isOpenForJoining(Session session, int maxPlayers) {
|
||||
return session.generator instanceof DuelsGenerator generator
|
||||
&& generator.allowJoining
|
||||
&& session.getPlayers().size() < maxPlayers;
|
||||
}
|
||||
|
||||
private ItemStack sessionItem(@NotNull Player player, @NotNull Session session) {
|
||||
final DuelsGenerator generator = (DuelsGenerator) session.generator;
|
||||
final ItemStack item = new ItemStack(Material.PLAYER_HEAD);
|
||||
applySkullOwner(player, item, generator.owner);
|
||||
|
||||
final ItemMeta meta = item.getItemMeta();
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(ColorUtil.color(generator.owner.getName()));
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
private void applySkullOwner(@NotNull Player player, @NotNull ItemStack skull, @NotNull ParkourUser owner) {
|
||||
if (ParkourUser.isBedrockPlayer(player)) {
|
||||
return;
|
||||
}
|
||||
if (owner.getName() == null || owner.getName().startsWith(".")) {
|
||||
return;
|
||||
}
|
||||
final SkullMeta meta = (SkullMeta) skull.getItemMeta();
|
||||
if (meta != null) {
|
||||
meta.setOwningPlayer(owner.player);
|
||||
skull.setItemMeta(meta);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue