diff --git a/src/main/java/xyz/twovb/sgm/commands/impl/GameCommand.java b/src/main/java/xyz/twovb/sgm/commands/impl/GameCommand.java index 3c560f5..6b4a099 100644 --- a/src/main/java/xyz/twovb/sgm/commands/impl/GameCommand.java +++ b/src/main/java/xyz/twovb/sgm/commands/impl/GameCommand.java @@ -43,35 +43,30 @@ public class GameCommand { @Execute(name = "init") @Permission("sgm.games.init") void init(@Context Player player, @Arg("name") Optional map) { - CustomPlayer cPlayer = new CustomPlayer(player); new InitGameGui().getGui().show(player); -// SGM.getInstance().getGameManager().initGame(new CTB(), player, name); } @Execute(name = "start") @Permission("sgm.games.start") void start(@Context Player player) { - CustomPlayer cPlayer = new CustomPlayer(player); Minigame game = SGM.getInstance().getGameManager().findGame(player); game.start(); } - @Execute(name = "team join") + @Execute(name = "team") @Permission("sgm.games.team") void teamJoin(@Context Player player, @Arg("player") Optional target) { -// String name = LevelName.orElse(UUID.randomUUID().toString()); Player targetPlayer = target.orElse(player); new TeamGui(targetPlayer).getGui().show(player); } - @Execute(name = "testjoin") - void testjoin(@Context Player player) { + @Execute(name = "join") + void join(@Context Player player) { new JoinGameGui().getGui().show(player); } - @Execute(name = "join") - void join(@Context Player player, @Arg("id") String id) { - CustomPlayer cPlayer = new CustomPlayer(player); + @Execute(name = "testjoin") + void testjoin(@Context Player player, @Arg("id") String id) { SGM.getInstance().getGameManager().addPlayerToGame(player, UUID.fromString(id)); } diff --git a/src/main/java/xyz/twovb/sgm/commands/impl/LevelCommand.java b/src/main/java/xyz/twovb/sgm/commands/impl/LevelCommand.java index be70cfc..0a8630f 100644 --- a/src/main/java/xyz/twovb/sgm/commands/impl/LevelCommand.java +++ b/src/main/java/xyz/twovb/sgm/commands/impl/LevelCommand.java @@ -68,8 +68,7 @@ public class LevelCommand { @Execute(name = "export") @Permission("sgm.levels.export") - void export(@Context Player player, @Arg("name") String name) { - CustomPlayer cPlayer = new CustomPlayer(player); + void export(@Context CommandSender sender, @Arg("name") String name) { try { SGM.getInstance().getLevelManager().exportLevel(name); } catch (IOException e) { diff --git a/src/main/java/xyz/twovb/sgm/commands/impl/SGMCommand.java b/src/main/java/xyz/twovb/sgm/commands/impl/SGMCommand.java index 9ed6c49..8ddd642 100644 --- a/src/main/java/xyz/twovb/sgm/commands/impl/SGMCommand.java +++ b/src/main/java/xyz/twovb/sgm/commands/impl/SGMCommand.java @@ -27,7 +27,4 @@ public class SGMCommand { sender.sendMessage(ChatUtils.translate(PlaceholderManager.setPlaceholders(string, sender))); } - @Execute(name = "a") - void a(@Context CommandSender sender) { - } } diff --git a/src/main/java/xyz/twovb/sgm/games/Minigame.java b/src/main/java/xyz/twovb/sgm/games/Minigame.java index f17d617..d649614 100644 --- a/src/main/java/xyz/twovb/sgm/games/Minigame.java +++ b/src/main/java/xyz/twovb/sgm/games/Minigame.java @@ -53,10 +53,11 @@ public interface Minigame extends Listener { default World createGameWorld(String name, UUID id) throws IOException { File mapDir = new File(LevelManager.mapPath + name); String tempName = name + "_" + id; - File tempDir = new File(LevelManager.gamePath + tempName); + String worldPath = LevelManager.gamePath + "/worlds/"; + File tempDir = new File(worldPath + tempName); if (tempDir.mkdirs()) { FileUtils.copyDirectory(mapDir, tempDir); - WorldCreator wc = new WorldCreator(LevelManager.gamePath + tempName, new NamespacedKey(SGM.getInstance(), tempName)); + WorldCreator wc = new WorldCreator(worldPath + tempName, new NamespacedKey(SGM.getInstance(), tempName)); return wc.createWorld(); } else { return null; diff --git a/src/main/java/xyz/twovb/sgm/games/impl/capturethebrick/CTB.java b/src/main/java/xyz/twovb/sgm/games/impl/capturethebrick/CTB.java index 47aaa8a..e8f00fc 100644 --- a/src/main/java/xyz/twovb/sgm/games/impl/capturethebrick/CTB.java +++ b/src/main/java/xyz/twovb/sgm/games/impl/capturethebrick/CTB.java @@ -6,11 +6,10 @@ package xyz.twovb.sgm.games.impl.capturethebrick; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; -import net.kyori.adventure.text.format.Style; -import net.kyori.adventure.text.format.TextDecoration; import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import net.megavex.scoreboardlibrary.api.sidebar.Sidebar; import net.megavex.scoreboardlibrary.api.sidebar.component.ComponentSidebarLayout; import net.megavex.scoreboardlibrary.api.sidebar.component.SidebarComponent; @@ -51,12 +50,12 @@ public class CTB implements Minigame { final static String name = "CaptureTheBrick"; private final UUID uuid; - private ArrayList players = new ArrayList(); private final ArrayList redBrickSpawns = new ArrayList(); private final ArrayList blueBrickSpawns = new ArrayList(); private final ArrayList redSpawnArea = new ArrayList(); private final ArrayList blueSpawnArea = new ArrayList(); private final FileConfiguration messages; + private final ArrayList players = new ArrayList(); private World gameWorld; private GameState state; private int bricks; @@ -67,7 +66,7 @@ public class CTB implements Minigame { private ScoreboardTeam redTeam; private ScoreboardTeam blueTeam; private Sidebar sb; - private SidebarAnimation titleAnimation; + private SidebarAnimation headerAnimation; private ComponentSidebarLayout layout; private CommandSender owner; @@ -94,20 +93,23 @@ public class CTB implements Minigame { setupTeamDisplay(blueTeam, "Blue Team", NamedTextColor.BLUE); this.sb = SGM.getInstance().getScoreboardLibrary().createSidebar(); - this.titleAnimation = createGradientAnimation(Component.text("Capture The Brick", Style.style(TextDecoration.BOLD))); - var title = SidebarComponent.animatedLine(titleAnimation); + this.headerAnimation = createGradientAnimation(ChatUtils.translate("Capture The Brick")); + var title = SidebarComponent.animatedLine(headerAnimation); SimpleDateFormat dtf = new SimpleDateFormat("dd/MM/yy | HH:mm:ss"); SidebarComponent gameInfo = SidebarComponent.builder() + // @formatter:off .addDynamicLine(() -> { var time = dtf.format(new Date()); - return Component.text(time, NamedTextColor.DARK_GRAY); + return Component.text(time, NamedTextColor.GRAY); }) .addBlankLine() - .addDynamicLine(() -> Component.text("Red Team: " + getBrickCount(redTeam), NamedTextColor.RED)) - .addDynamicLine(() -> Component.text("Blue Team: " + getBrickCount(blueTeam), NamedTextColor.BLUE)) + .addDynamicLine(() -> ChatUtils.translate("Red: " + getBrickCount(redTeam))) + .addDynamicLine(() -> ChatUtils.translate("Blue: " + getBrickCount(blueTeam))) + .addBlankLine() .build(); + // @formatter:on this.layout = new ComponentSidebarLayout(title, gameInfo); layout.apply(sb); @@ -122,29 +124,31 @@ public class CTB implements Minigame { } private String getBrickCount(ScoreboardTeam team) { - String icon = "\uD83E\uDDF1"; - return icon; + String icon = "\uD83D\uDDC3"; + StringBuilder builder = new StringBuilder(); + for (int i = 1; i <= this.bricks; i++) { + builder.append(icon + " "); + } + return builder.toString(); } @Override public void start() { if (checkStart()) { - state = GameState.STARTED; - sendMessageToAllPlayers("The game has started!"); for (Player player : players) { player.teleport(this.spawnLoc); sb.addPlayer(player); } - for (int i = 0; i <= bricks; i++) { - for (Location brickLoc : redBrickSpawns) { - placeBrick(brickLoc, redTeam); - } - for (Location brickLoc : blueBrickSpawns) { - placeBrick(brickLoc, blueTeam); - } + for (int i = 1; i <= this.bricks; i++) { + SGM.getInstance().getCLogger().log(i); + placeBrick(redBrickSpawns.get(i), redTeam); + placeBrick(blueBrickSpawns.get(i), blueTeam); } BukkitTask task = Bukkit.getScheduler().runTaskTimer(SGM.getInstance(), this::onTick, 0L, 1L); this.taskId = task.getTaskId(); + + state = GameState.STARTED; + sendMessageToAllPlayers("The game has started!"); } } @@ -197,7 +201,7 @@ public class CTB implements Minigame { this.stop(); } try { - titleAnimation.nextFrame(); + headerAnimation.nextFrame(); layout.apply(sb); } catch (IllegalStateException ignored) { } @@ -214,6 +218,7 @@ public class CTB implements Minigame { public void removePlayer(Player player) { players.remove(player); sb.removePlayer(player); + removePlayerFromTeams(player); sendMessageToAllPlayers(messages.getString("system.player.left").replace("%player%", player.getName())); } @@ -293,7 +298,7 @@ public class CTB implements Minigame { if (team.equals(blueTeam)) { brick.setType(Material.BLUE_WOOL); } - SGM.getInstance().getCLogger().log("Placed " + brick.getType() + " at " + location); +// SGM.getInstance().getCLogger().log("Placed " + brick.getType() + " at " + location); } private void setupTeamDisplay(ScoreboardTeam team, String displayName, NamedTextColor color) { @@ -317,6 +322,35 @@ public class CTB implements Minigame { return new CollectionSidebarAnimation<>(frames); } + private @NotNull SidebarAnimation createScrollingAnimation(@NotNull Component text, int frameDelay) { + String rawText = PlainTextComponentSerializer.plainText().serialize(text); + int textLength = rawText.length(); + int frameWidth = Math.min(20, textLength); // Use a maximum frame width of 20 or text length, whichever is smaller. + + // Determine the number of frames needed to scroll the text + int totalFrames = textLength > frameWidth ? textLength - frameWidth + 1 : 1; + List frames = new ArrayList<>(totalFrames * frameDelay); + + for (int i = 0; i < totalFrames; i++) { + int start = i; + int end = Math.min(i + frameWidth, textLength); + String frameText = rawText.substring(start, end); + + // Add padding if the frame is shorter than frameWidth + if (frameText.length() < frameWidth) { + frameText = frameText + " ".repeat(frameWidth - frameText.length()); + } + + // Add multiple identical frames to slow down the animation + Component frameComponent = Component.text(frameText, text.style()); + for (int j = 0; j < frameDelay; j++) { + frames.add(frameComponent); + } + } + + return new CollectionSidebarAnimation<>(frames); + } + private Location parseString(String string) { String[] coords = string.trim().split(","); if (coords.length == 3) { @@ -356,7 +390,7 @@ public class CTB implements Minigame { List playerSpawnArea = team.getStringList("playerSpawnArea"); // Get brick locations - if (brickSpawns.size() >= bricks) { + if (brickSpawns.size() >= this.bricks) { for (String rawBrickLoc : brickSpawns) { Location brickLoc = parseString(rawBrickLoc); if (teamName.equals("red")) {