diff --git a/src/main/java/net/fameless/forcebattle/ForceBattle.java b/src/main/java/net/fameless/forcebattle/ForceBattle.java index 7c03d35..9dc84ee 100644 --- a/src/main/java/net/fameless/forcebattle/ForceBattle.java +++ b/src/main/java/net/fameless/forcebattle/ForceBattle.java @@ -16,6 +16,7 @@ import net.fameless.forcebattle.gui.LanguageGUI; import net.fameless.forcebattle.gui.ResultGUI; import net.fameless.forcebattle.gui.SettingsGUI; +import net.fameless.forcebattle.tablist.TablistManager; import net.fameless.forcebattle.util.BukkitUtil; import net.fameless.forcebattle.util.ResourceUtil; import net.kyori.adventure.text.Component; @@ -105,6 +106,7 @@ private void initCore() { Command.createInstances(); BossbarManager.runTask(); + TablistManager.startUpdating(); PluginUpdater.checkForUpdate(); } diff --git a/src/main/java/net/fameless/forcebattle/command/BackpackCommand.java b/src/main/java/net/fameless/forcebattle/command/BackpackCommand.java index fd5214e..2e8532a 100644 --- a/src/main/java/net/fameless/forcebattle/command/BackpackCommand.java +++ b/src/main/java/net/fameless/forcebattle/command/BackpackCommand.java @@ -1,6 +1,5 @@ package net.fameless.forcebattle.command; -import net.fameless.forcebattle.ForceBattle; import net.fameless.forcebattle.caption.Caption; import net.fameless.forcebattle.command.framework.CallerType; import net.fameless.forcebattle.command.framework.Command; @@ -34,10 +33,6 @@ public void executeCommand(CommandCaller caller, String[] args) { caller.sendMessage(Caption.of("error.backpacks_disabled")); return; } - if (!ForceBattle.getTimer().isRunning()) { - caller.sendMessage(Caption.of("error.game_not_started")); - return; - } Optional senderOpt = BattlePlayer.adapt(caller.getName()); diff --git a/src/main/java/net/fameless/forcebattle/command/DisplayResultsCommand.java b/src/main/java/net/fameless/forcebattle/command/DisplayResultsCommand.java index 4454ba3..5b894e1 100644 --- a/src/main/java/net/fameless/forcebattle/command/DisplayResultsCommand.java +++ b/src/main/java/net/fameless/forcebattle/command/DisplayResultsCommand.java @@ -13,10 +13,7 @@ import java.util.ArrayList; import java.util.Comparator; -import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -42,76 +39,60 @@ protected void executeCommand(CommandCaller caller, String[] args) { return; } - final HashMap PLAYER_POINTS_MAP = new HashMap<>(); - final HashMap TEAM_POINTS_MAP = new HashMap<>(); - - for (BattlePlayer battlePlayer : BattlePlayer.BATTLE_PLAYERS) { - PLAYER_POINTS_MAP.put(battlePlayer, battlePlayer.getPoints()); - } - - LinkedHashMap sortedPlayerPointsMap = PLAYER_POINTS_MAP.entrySet() - .stream() - .sorted(Map.Entry.comparingByValue()) - .collect(Collectors.toMap( - HashMap.Entry::getKey, - HashMap.Entry::getValue, - (e1, e2) -> e1, - LinkedHashMap::new - )); - - for (Team team : Team.teams) { - TEAM_POINTS_MAP.put(team, team.getPoints()); + if (args.length == 0) { + sendUsage(caller); + return; } - LinkedHashMap sortedTeamPointsMap = TEAM_POINTS_MAP.entrySet() - .stream() - .sorted(Map.Entry.comparingByValue()) - .collect(Collectors.toMap( - HashMap.Entry::getKey, - HashMap.Entry::getValue, - (e1, e2) -> e1, - LinkedHashMap::new - )); - - ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); final long delay = 750; final long[] counter = {0}; - switch (args[0]) { + switch (args[0].toLowerCase()) { case "player" -> { - sortedPlayerPointsMap.forEach((battlePlayer, points) -> { - long place = sortedPlayerPointsMap.size() - counter[0]; - scheduler.schedule( - () -> ForceBattle.broadcast( - MiniMessage.miniMessage().deserialize("" + place + ". " + battlePlayer.getName() + ": " + points) - ), counter[0] * delay, TimeUnit.MILLISECONDS - ); + List sortedPlayers = new ArrayList<>(BattlePlayer.BATTLE_PLAYERS); + sortedPlayers.sort(Comparator.comparingInt(BattlePlayer::getPoints).reversed()); + + for (BattlePlayer player : sortedPlayers) { + int place = BattlePlayer.getPlace(player); + int points = player.getPoints(); + + scheduler.schedule(() -> ForceBattle.broadcast( + MiniMessage.miniMessage().deserialize( + "" + place + ". " + player.getName() + ": " + points + ) + ), counter[0] * delay, TimeUnit.MILLISECONDS); counter[0]++; - }); - - scheduler.shutdown(); + } } + case "team" -> { - sortedTeamPointsMap.forEach((team, points) -> { - long place = sortedTeamPointsMap.size() - counter[0]; + List sortedTeams = new ArrayList<>(Team.teams); + sortedTeams.sort(Comparator.comparingInt(Team::getPoints).reversed()); + + for (Team team : sortedTeams) { + int place = Team.getPlace(team); + int points = team.getPoints(); String players = team.getPlayers().stream() .sorted(Comparator.comparingInt(BattlePlayer::getPoints).reversed()) .map(p -> p.getName() + " (" + p.getPoints() + ")") .collect(Collectors.joining(", ")); - scheduler.schedule( - () -> ForceBattle.broadcast( - MiniMessage.miniMessage().deserialize("" + place + ". " + team.getId() + " (" + players + ")" + ": " + points) - ), counter[0] * delay, TimeUnit.MILLISECONDS - ); + scheduler.schedule(() -> ForceBattle.broadcast( + MiniMessage.miniMessage().deserialize( + "" + place + ". " + team.getId() + + " (" + players + "): " + points + ) + ), counter[0] * delay, TimeUnit.MILLISECONDS); counter[0]++; - }); - - scheduler.shutdown(); + } } + + default -> sendUsage(caller); } + + scheduler.shutdown(); } @Override diff --git a/src/main/java/net/fameless/forcebattle/command/SkipCommand.java b/src/main/java/net/fameless/forcebattle/command/SkipCommand.java index 33f8c30..27aeaa0 100644 --- a/src/main/java/net/fameless/forcebattle/command/SkipCommand.java +++ b/src/main/java/net/fameless/forcebattle/command/SkipCommand.java @@ -51,17 +51,21 @@ public void executeCommand(CommandCaller caller, String[] args) { ); } case "team" -> { - @NotNull Optional teamOpt = Team.ofId(Integer.parseInt(args[1])); - teamOpt.ifPresentOrElse( - team -> { - team.updateObjective(null, false, false); - team.getPlayers().forEach(player -> player.sendMessage(Caption.of("notification.skip_by_admin_target"))); - caller.sendMessage(Caption.of( - "notification.skip_by_admin_player", - TagResolver.resolver("player", Tag.inserting(Component.text(team.getId()))) - )); - }, () -> caller.sendMessage(Caption.of("command.no_such_team")) - ); + try { + @NotNull Optional teamOpt = Team.ofId(Integer.parseInt(args[3])); + teamOpt.ifPresentOrElse( + team -> { + team.updateObjective(null, false, false); + team.getPlayers().forEach(player -> player.sendMessage(Caption.of("notification.skip_by_admin_target"))); + caller.sendMessage(Caption.of( + "notification.skip_by_admin_player", + TagResolver.resolver("player", Tag.inserting(Component.text(team.getId()))) + )); + }, () -> caller.sendMessage(Caption.of("command.no_such_team")) + ); + } catch (NumberFormatException e) { + caller.sendMessage(Caption.of("command.not_a_number")); + } } } } else { diff --git a/src/main/java/net/fameless/forcebattle/game/GameListener.java b/src/main/java/net/fameless/forcebattle/game/GameListener.java index 99cae02..e972b69 100644 --- a/src/main/java/net/fameless/forcebattle/game/GameListener.java +++ b/src/main/java/net/fameless/forcebattle/game/GameListener.java @@ -55,7 +55,8 @@ public class GameListener implements Listener { - private final List skipCooldown = new ArrayList<>(); + private final List playerSkipCooldown = new ArrayList<>(); + private final List teamSkipCooldown = new ArrayList<>(); private final List swapCooldown = new ArrayList<>(); private boolean sentUpdateMessage = false; private boolean startPhase = true; @@ -73,10 +74,6 @@ public GameListener() { TaskManager.startAll(); } - //TODO bp nach dem battle aufmachen - //TODO prüfen ob ruined portals gehen - //TODO /displayresults auf gleiche Plätze setzen wenn Punkte gleich => nächstes team dementsprechend abstufen - //TODO evtl dupe obj fix for both player/team idk //TODO better tablist //TODO scoreboard which shows teammate obj @@ -285,7 +282,7 @@ public void onPlayerSkip(@NotNull PlayerInteractEvent event) { BattlePlayer battlePlayer = BattlePlayer.adapt(event.getPlayer()); if (battlePlayer.isExcluded()) return; - if (skipCooldown.contains(battlePlayer)) return; + if (playerSkipCooldown.contains(battlePlayer)) return; event.setCancelled(true); @@ -312,8 +309,8 @@ public void onPlayerSkip(@NotNull PlayerInteractEvent event) { ItemStack itemStack = new ItemStack(Material.valueOf(oldObjective.getObjectiveString())); battlePlayer.getPlayer().getWorld().dropItemNaturally(battlePlayer.getPlayer().getLocation(), itemStack); } - skipCooldown.add(battlePlayer); - Bukkit.getScheduler().runTaskLater(ForceBattle.get(), () -> skipCooldown.remove(battlePlayer), 20); + playerSkipCooldown.add(battlePlayer); + Bukkit.getScheduler().runTaskLater(ForceBattle.get(), () -> playerSkipCooldown.remove(battlePlayer), 20); } @EventHandler @@ -325,7 +322,7 @@ public void onTeamSkip(@NotNull PlayerInteractEvent event) { BattlePlayer battlePlayer = BattlePlayer.adapt(event.getPlayer()); Team team = battlePlayer.getTeam(); if (battlePlayer.isExcluded()) return; - if (skipCooldown.contains(battlePlayer)) return; + if (teamSkipCooldown.contains(battlePlayer)) return; event.setCancelled(true); @@ -363,8 +360,8 @@ public void onTeamSkip(@NotNull PlayerInteractEvent event) { ItemStack itemStack = new ItemStack(Material.valueOf(oldObjective.getObjectiveString())); battlePlayer.getPlayer().getWorld().dropItemNaturally(battlePlayer.getPlayer().getLocation(), itemStack); } - skipCooldown.add(battlePlayer); - Bukkit.getScheduler().runTaskLater(ForceBattle.get(), () -> skipCooldown.remove(battlePlayer), 20); + teamSkipCooldown.add(battlePlayer); + Bukkit.getScheduler().runTaskLater(ForceBattle.get(), () -> teamSkipCooldown.remove(battlePlayer), 20); } @EventHandler diff --git a/src/main/java/net/fameless/forcebattle/game/ObjectiveManager.java b/src/main/java/net/fameless/forcebattle/game/ObjectiveManager.java index 631cb2a..7ba2846 100644 --- a/src/main/java/net/fameless/forcebattle/game/ObjectiveManager.java +++ b/src/main/java/net/fameless/forcebattle/game/ObjectiveManager.java @@ -1,6 +1,7 @@ package net.fameless.forcebattle.game; import net.fameless.forcebattle.ForceBattle; +import net.fameless.forcebattle.caption.Caption; import net.fameless.forcebattle.configuration.SettingsManager; import net.fameless.forcebattle.game.data.BiomeSimplified; import net.fameless.forcebattle.game.data.StructureSimplified; @@ -9,6 +10,9 @@ import net.fameless.forcebattle.util.BattleType; import net.fameless.forcebattle.util.BukkitUtil; import net.fameless.forcebattle.game.data.Structure; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.tag.Tag; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; @@ -22,7 +26,6 @@ import java.util.HashSet; import java.util.List; import java.util.Locale; -import java.util.Objects; import java.util.Random; import java.util.Set; import java.util.concurrent.ThreadLocalRandom; @@ -96,7 +99,16 @@ private Objective generateObjective(BattleType battleType, BattlePlayer battlePl allPossible.removeIf(finished::contains); } - if (allPossible.isEmpty()) return null; + if (allPossible.isEmpty()) { + battlePlayer.sendMessage(Caption.of( + "error.no_objective_available", TagResolver.resolver("type", Tag.inserting(Component.text(battleType.name()))) + )); + if (team != null) { + return getNewObjective(team); + } else { + return getNewObjective(battlePlayer); + } + } String objectiveString = allPossible.get(random.nextInt(allPossible.size())); return new Objective(battleType, objectiveString); diff --git a/src/main/java/net/fameless/forcebattle/game/Team.java b/src/main/java/net/fameless/forcebattle/game/Team.java index cc7fbbc..50722b6 100644 --- a/src/main/java/net/fameless/forcebattle/game/Team.java +++ b/src/main/java/net/fameless/forcebattle/game/Team.java @@ -17,6 +17,7 @@ import org.slf4j.LoggerFactory; import java.util.ArrayList; +import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -174,27 +175,30 @@ public static Map getPlaces() { } public static int getPlace(Team team) { - return getPlaces().entrySet() - .stream() - .filter(entry -> entry.getValue().equals(team)) - .map(Map.Entry::getKey) - .findFirst() - .orElse(-1); - } + List sortedTeams = new ArrayList<>(Team.teams); + sortedTeams.sort(Comparator.comparingInt(Team::getPoints).reversed()); - public void updateObjective(BattlePlayer finisher, boolean finishLast, boolean hasBeenSkipped) { - Objective newObjective = ForceBattle.getObjectiveManager().getNewObjective(this); - ObjectiveUpdateEvent updateEvent = new ObjectiveUpdateEvent(this, newObjective); - Bukkit.getPluginManager().callEvent(updateEvent); - if (updateEvent.isCancelled()) { - logger.info("ObjectiveUpdateEvent has been denied by an external plugin."); - return; + int place = 1; + int previousPoints = -1; + + for (int i = 0; i < sortedTeams.size(); i++) { + Team current = sortedTeams.get(i); + + if (current.getPoints() != previousPoints) { + place = i + 1; + previousPoints = current.getPoints(); + } + + if (current.equals(team)) { + return place; + } } - setCurrentObjective(updateEvent.getNewObjective(), finisher, finishLast, hasBeenSkipped); + return -1; } - public void setCurrentObjective(Objective newObjective, BattlePlayer finisher, boolean finishLast, boolean hasBeenSkipped) { + + public void updateObjective(BattlePlayer finisher, boolean finishLast, boolean hasBeenSkipped) { if (finishLast && this.objective != null) { this.objective.setFinished(finisher); this.objective.setHasBeenSkipped(hasBeenSkipped); @@ -202,6 +206,14 @@ public void setCurrentObjective(Objective newObjective, BattlePlayer finisher, b finisher.setPoints(finisher.getPoints() + 1); } + Objective newObjective = ForceBattle.getObjectiveManager().getNewObjective(this); + if (newObjective == null) return; + + ObjectiveUpdateEvent updateEvent = new ObjectiveUpdateEvent(this, newObjective); + Bukkit.getPluginManager().callEvent(updateEvent); + if (updateEvent.isCancelled()) return; + + this.objective = updateEvent.getNewObjective(); if (ForceBattle.getTimer().isRunning()) { for (BattlePlayer member : players) { member.sendMessage(Caption.of( @@ -211,8 +223,6 @@ public void setCurrentObjective(Objective newObjective, BattlePlayer finisher, b )); } } - - this.objective = newObjective; } @Getter diff --git a/src/main/java/net/fameless/forcebattle/game/data/StructureSimplified.java b/src/main/java/net/fameless/forcebattle/game/data/StructureSimplified.java index 8a7845a..51e6a3e 100644 --- a/src/main/java/net/fameless/forcebattle/game/data/StructureSimplified.java +++ b/src/main/java/net/fameless/forcebattle/game/data/StructureSimplified.java @@ -7,8 +7,8 @@ public enum StructureSimplified { VILLAGE("Village", List.of(Structure.VILLAGE_PLAINS, Structure.VILLAGE_SAVANNA, Structure.VILLAGE_SNOWY, Structure.VILLAGE_TAIGA, Structure.VILLAGE_DESERT)), PILLAGER_OUTPOST("Pillager Outpost", List.of(Structure.PILLAGER_OUTPOST)), - //RUINED_PORTAL("Ruined Portal", List.of(Structure.RUINED_PORTAL_MOUNTAIN, Structure.RUINED_PORTAL_DESERT, Structure.RUINED_PORTAL_JUNGLE, - // Structure.RUINED_PORTAL_OCEAN, Structure.RUINED_PORTAL_SWAMP, Structure.RUINED_PORTAL_NETHER)), + RUINED_PORTAL("Ruined Portal", List.of(Structure.RUINED_PORTAL_MOUNTAIN, Structure.RUINED_PORTAL_DESERT, Structure.RUINED_PORTAL_JUNGLE, + Structure.RUINED_PORTAL_OCEAN, Structure.RUINED_PORTAL_SWAMP, Structure.RUINED_PORTAL_NETHER)), OCEAN_RUIN("Ocean Ruin", List.of(Structure.OCEAN_RUIN_COLD, Structure.OCEAN_RUIN_WARM)), TRIAL_CHAMBERS("Trial Chambers", List.of(Structure.TRIAL_CHAMBERS)), SHIPWRECK("Shipwreck", List.of(Structure.SHIPWRECK, Structure.SHIPWRECK_BEACHED)), diff --git a/src/main/java/net/fameless/forcebattle/game/tasks/StructureTask.java b/src/main/java/net/fameless/forcebattle/game/tasks/StructureTask.java index fe4ba80..0925977 100644 --- a/src/main/java/net/fameless/forcebattle/game/tasks/StructureTask.java +++ b/src/main/java/net/fameless/forcebattle/game/tasks/StructureTask.java @@ -6,7 +6,10 @@ import net.fameless.forcebattle.game.data.Structure; import net.fameless.forcebattle.game.data.StructureSimplified; import net.fameless.forcebattle.player.BattlePlayer; -import net.fameless.forcebattle.util.*; +import net.fameless.forcebattle.util.BattleType; +import net.fameless.forcebattle.util.BukkitUtil; +import net.fameless.forcebattle.util.Format; +import net.fameless.forcebattle.util.Toast; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; @@ -15,12 +18,14 @@ import org.bukkit.generator.structure.GeneratedStructure; import org.bukkit.generator.structure.StructurePiece; import org.bukkit.util.BoundingBox; -import org.bukkit.util.StructureSearchResult; -import java.util.Optional; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; public class StructureTask implements ForceTask { + private static final Map> STRUCTURE_CACHE = new ConcurrentHashMap<>(); + @Override public void runTick() { if (!SettingsManager.isEnabled(SettingsManager.Setting.FORCE_STRUCTURE)) return; @@ -82,17 +87,45 @@ private boolean isInsideStructure(Player player, String objectiveString, Registr } private boolean checkPlayerLocationInStructure(Player player, org.bukkit.generator.structure.Structure bukkitStruct) { - StructureSearchResult result = player.getWorld().locateNearestStructure(player.getLocation(), bukkitStruct, 10, false); - if (result == null) return false; - - Location loc = result.getLocation(); - Optional generated = loc.getChunk().getStructures(bukkitStruct).stream().findFirst(); - if (generated.isEmpty()) return false; - + String worldName = player.getWorld().getName(); + String cacheKey = worldName + ":" + bukkitStruct.getKey().getKey(); + Set cachedBoxes = STRUCTURE_CACHE.get(cacheKey); Location playerLoc = player.getLocation(); - for (StructurePiece piece : generated.get().getPieces()) { - if (isInsideBoundingBox(playerLoc, piece.getBoundingBox())) return true; + + if (cachedBoxes != null) { + for (BoundingBox box : cachedBoxes) { + if (isInsideBoundingBox(playerLoc, box)) return true; + } } + + Bukkit.getScheduler().runTaskAsynchronously(ForceBattle.get(), () -> { + try { + World world = player.getWorld(); + Chunk center = playerLoc.getChunk(); + int radius = 6; + + Set newBoxes = new HashSet<>(); + for (int dx = -radius; dx <= radius; dx++) { + for (int dz = -radius; dz <= radius; dz++) { + Chunk chunk = world.getChunkAt(center.getX() + dx, center.getZ() + dz); + for (GeneratedStructure generated : chunk.getStructures(bukkitStruct)) { + for (StructurePiece piece : generated.getPieces()) { + newBoxes.add(piece.getBoundingBox()); + } + } + } + } + + if (!newBoxes.isEmpty()) { + STRUCTURE_CACHE.compute(cacheKey, (key, oldSet) -> { + if (oldSet == null) return newBoxes; + oldSet.addAll(newBoxes); + return oldSet; + }); + } + } catch (Exception ignored) {} + }); + return false; } diff --git a/src/main/java/net/fameless/forcebattle/player/BattlePlayer.java b/src/main/java/net/fameless/forcebattle/player/BattlePlayer.java index 79abb3a..0f74f82 100644 --- a/src/main/java/net/fameless/forcebattle/player/BattlePlayer.java +++ b/src/main/java/net/fameless/forcebattle/player/BattlePlayer.java @@ -37,6 +37,7 @@ import org.slf4j.LoggerFactory; import java.util.ArrayList; +import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -143,14 +144,29 @@ public static Map getPlaces() { } public static int getPlace(BattlePlayer player) { - return getPlaces().entrySet() - .stream() - .filter(entry -> entry.getValue().equals(player)) - .map(Map.Entry::getKey) - .findFirst() - .orElse(-1); + List sortedPlayers = new ArrayList<>(BattlePlayer.BATTLE_PLAYERS); + sortedPlayers.sort(Comparator.comparingInt(BattlePlayer::getPoints).reversed()); + + int place = 1; + int previousPoints = -1; + + for (int i = 0; i < sortedPlayers.size(); i++) { + BattlePlayer current = sortedPlayers.get(i); + + if (current.getPoints() != previousPoints) { + place = i + 1; + previousPoints = current.getPoints(); + } + + if (current.equals(player)) { + return place; + } + } + + return -1; } + @Override public CallerType callerType() { return CallerType.PLAYER; @@ -187,14 +203,39 @@ public boolean isInTeam() { return getTeam() != null; } + public void updateObjective(boolean finishLast, boolean hasBeenSkipped) { + if (finishLast && this.objective != null) { + this.objective.setFinished(this); + this.objective.setHasBeenSkipped(hasBeenSkipped); + + this.points++; + } + + Objective newObjective = ForceBattle.getObjectiveManager().getNewObjective(this); + if (newObjective == null) return; + + ObjectiveUpdateEvent updateEvent = new ObjectiveUpdateEvent(this, newObjective); + Bukkit.getPluginManager().callEvent(updateEvent); + if (updateEvent.isCancelled()) { + logger.info("ObjectiveUpdateEvent has been denied by an external plugin."); + return; + } + + setCurrentObjective(updateEvent.getNewObjective(), false, false); + + if (SettingsManager.isEnabled(SettingsManager.Setting.CHAIN_MODE)) { + increaseChainProgress(); + } + } + public void setCurrentObjective(Objective newObjective, boolean finishLast, boolean hasBeenSkipped) { - if (finishLast) { + if (finishLast && this.objective != null) { this.objective.setFinished(this); this.objective.setHasBeenSkipped(hasBeenSkipped); this.points++; } - if (ForceBattle.getTimer().isRunning()) { + if (ForceBattle.getTimer().isRunning() && newObjective != null) { sendMessage(Caption.of( "notification.next_objective", TagResolver.resolver("objective", Tag.inserting(Component.text(Format.formatName(newObjective.getObjectiveString())))), @@ -270,20 +311,6 @@ public void openBackpack(BattlePlayer viewer) { viewer.openInventory(getBackpack()); } - public void updateObjective(boolean finishLast, boolean hasBeenSkipped) { - Objective newObjective = ForceBattle.getObjectiveManager().getNewObjective(this); - ObjectiveUpdateEvent updateEvent = new ObjectiveUpdateEvent(this, newObjective); - Bukkit.getPluginManager().callEvent(updateEvent); - if (updateEvent.isCancelled()) { - logger.info("ObjectiveUpdateEvent has been denied by an external plugin."); - return; - } - setCurrentObjective(updateEvent.getNewObjective(), finishLast, hasBeenSkipped); - if (SettingsManager.isEnabled(SettingsManager.Setting.CHAIN_MODE)) { - increaseChainProgress(); - } - } - public void playSound(Sound sound) { getAudience().playSound(sound); } diff --git a/src/main/java/net/fameless/forcebattle/tablist/TablistManager.java b/src/main/java/net/fameless/forcebattle/tablist/TablistManager.java new file mode 100644 index 0000000..fb9f4b6 --- /dev/null +++ b/src/main/java/net/fameless/forcebattle/tablist/TablistManager.java @@ -0,0 +1,88 @@ +package net.fameless.forcebattle.tablist; + +import net.fameless.forcebattle.ForceBattle; +import net.fameless.forcebattle.player.BattlePlayer; +import net.fameless.forcebattle.util.BattleType; +import net.fameless.forcebattle.util.Format; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +public class TablistManager { + + private static final ForceBattle plugin = ForceBattle.get(); + + public static void startUpdating() { + new BukkitRunnable() { + @Override + public void run() { + updateAllTablists(); + } + }.runTaskTimer(plugin, 0, 20); + } + + public static void updateAllTablists() { + BattlePlayer.getOnlinePlayers().forEach(player -> { + if (player.isInTeam()) { + player.getPlayer().setPlayerListOrder(player.getTeam().getId()); + } else { + player.getPlayer().setPlayerListOrder(999); + } + + updateTablist(player.getPlayer()); + }); + } + + public static void updateTablist(Player player) { + /* + MiniMessage miniMessage = MiniMessage.miniMessage(); + + String header = miniMessage.serialize( + Component.text("⏳ Time Left: " + Format.formatTime(ForceBattle.getTimer().getTime())) + ); + + StringBuilder footerBuilder = new StringBuilder(); + + // Show all teams first + List teams = Team.teams; + for (Team team : teams) { + footerBuilder.append("Team ").append(team.getId()).append(":\n"); + for (BattlePlayer battlePlayer : team.getPlayers()) { + footerBuilder.append(formatPlayerLineString(battlePlayer)).append("\n"); + } + } + + // Show any players not in a team + for (Player p : Bukkit.getOnlinePlayers()) { + BattlePlayer bp = BattlePlayer.adapt(p); + if (!bp.isInTeam()) { + footerBuilder.append("Solo:\n"); + footerBuilder.append(formatPlayerLineString(bp)).append("\n"); + } + } + + player.setPlayerListHeaderFooter(header, footerBuilder.toString()); + */ + } + + private static String formatPlayerLineString(BattlePlayer player) { + String name = player.getName(); + String objective = player.getObjective() != null + ? Format.formatName(player.getObjective().getObjectiveString()) + : "None"; + + String color = "§f"; // white by default + if (player.getObjective() != null) { + BattleType type = player.getObjective().getBattleType(); + color = switch (type) { + case FORCE_ITEM -> "§a"; // green + case FORCE_MOB -> "§c"; // red + case FORCE_BIOME -> "§e"; // yellow + case FORCE_ADVANCEMENT -> "§d"; // light purple + case FORCE_HEIGHT, FORCE_COORDS -> "§7"; // gray + case FORCE_STRUCTURE -> "§b"; // aqua + }; + } + + return color + " - " + name + " | " + objective; + } +} diff --git a/src/main/resources/languages/en_US.json b/src/main/resources/languages/en_US.json index 9382b1f..74ccfd9 100644 --- a/src/main/resources/languages/en_US.json +++ b/src/main/resources/languages/en_US.json @@ -105,6 +105,7 @@ "error.game_already_started" : "The game has already started.", "error.no_equal_teams" : "No equal teams can be created.", "error.no_battletype_selected" : "No battletype is selected, game can not be started!", + "error.no_objective_available" : "No objective available for BattleType . Possible all completed already?", "permission.no_permission" : "Insufficient permission: .", "item.player_skip_item_name" : "Skip", "item.player_skip_item_lore" : "Click to skip your current objective.",