From 400032a94cdb39d24b37c98b65f30d42424ba1d1 Mon Sep 17 00:00:00 2001 From: Teriuihi Date: Sat, 15 Feb 2025 03:53:35 +0100 Subject: [PATCH] Switch from UUID to Player & add scoreboard for teams Replaced UUID-based logic with Player objects across all game systems. Added team scorebaord sfor colors in tab and clarity for players as to who is in the laed --- .../ctf/commands/subcommands/ChangeTeam.java | 2 +- .../ctf/commands/subcommands/CreateTeam.java | 3 +- .../ctf/commands/subcommands/SelectClass.java | 2 +- .../com/alttd/ctf/events/OnPlayerDeath.java | 2 +- .../ctf/events/OnPlayerOnlineStatus.java | 4 +- .../com/alttd/ctf/events/SnowballEvent.java | 6 +- src/main/java/com/alttd/ctf/flag/Flag.java | 10 +-- .../alttd/ctf/flag/FlagTryCaptureEvent.java | 2 +- .../java/com/alttd/ctf/game/GameManager.java | 12 ++-- .../ctf/game/phases/ClassSelectionPhase.java | 6 +- src/main/java/com/alttd/ctf/team/Team.java | 66 +++++++++++++++++-- version.properties | 4 +- 12 files changed, 88 insertions(+), 31 deletions(-) diff --git a/src/main/java/com/alttd/ctf/commands/subcommands/ChangeTeam.java b/src/main/java/com/alttd/ctf/commands/subcommands/ChangeTeam.java index e0f93a3..e969359 100644 --- a/src/main/java/com/alttd/ctf/commands/subcommands/ChangeTeam.java +++ b/src/main/java/com/alttd/ctf/commands/subcommands/ChangeTeam.java @@ -58,7 +58,7 @@ public class ChangeTeam extends SubCommand { } private void changeTeam(CommandSender commandSender, Player player, Team team) { - Optional optionalOldTeam = gameManager.getTeam(player.getUniqueId()); + Optional optionalOldTeam = gameManager.getTeam(player); if (optionalOldTeam.isPresent()) { moveBetweenTeams(commandSender, player, team, optionalOldTeam.get()); return; diff --git a/src/main/java/com/alttd/ctf/commands/subcommands/CreateTeam.java b/src/main/java/com/alttd/ctf/commands/subcommands/CreateTeam.java index 2cf4543..2a54947 100644 --- a/src/main/java/com/alttd/ctf/commands/subcommands/CreateTeam.java +++ b/src/main/java/com/alttd/ctf/commands/subcommands/CreateTeam.java @@ -76,7 +76,8 @@ public class CreateTeam extends SubCommand { int highestId = gameManager.getMaxTeamId(); Team team = new Team(MiniMessage.miniMessage().deserialize(String.format("%s", color, name)), - highestId + 1, player.getLocation(), player.getLocation(), player.getLocation(), teamColor, Material.RED_BANNER); + highestId + 1, player.getLocation(), player.getLocation(), player.getLocation(), teamColor, + Material.RED_BANNER, "§c"); return consumer.apply(team); } diff --git a/src/main/java/com/alttd/ctf/commands/subcommands/SelectClass.java b/src/main/java/com/alttd/ctf/commands/subcommands/SelectClass.java index 37abacd..aa59999 100644 --- a/src/main/java/com/alttd/ctf/commands/subcommands/SelectClass.java +++ b/src/main/java/com/alttd/ctf/commands/subcommands/SelectClass.java @@ -40,7 +40,7 @@ public class SelectClass extends SubCommand { return 0; } GamePhase gamePhase = optionalGamePhase.get(); - Optional optionalTeamPlayer = gameManager.getTeamPlayer(player.getUniqueId()); + Optional optionalTeamPlayer = gameManager.getTeamPlayer(player); if (optionalTeamPlayer.isEmpty()) { commandSender.sendRichMessage("You have to be in a CTF team to select a class."); return 0; diff --git a/src/main/java/com/alttd/ctf/events/OnPlayerDeath.java b/src/main/java/com/alttd/ctf/events/OnPlayerDeath.java index fd60197..8bc8693 100644 --- a/src/main/java/com/alttd/ctf/events/OnPlayerDeath.java +++ b/src/main/java/com/alttd/ctf/events/OnPlayerDeath.java @@ -55,7 +55,7 @@ public class OnPlayerDeath implements Listener { log.warn("Player {} died while the game wasn't running", player.getName()); return; } - Optional optionalTeamPlayer = gameManager.getTeamPlayer(player.getUniqueId()); + Optional optionalTeamPlayer = gameManager.getTeamPlayer(player); if (optionalTeamPlayer.isEmpty()) { return; } diff --git a/src/main/java/com/alttd/ctf/events/OnPlayerOnlineStatus.java b/src/main/java/com/alttd/ctf/events/OnPlayerOnlineStatus.java index d9e7e59..ae827cf 100644 --- a/src/main/java/com/alttd/ctf/events/OnPlayerOnlineStatus.java +++ b/src/main/java/com/alttd/ctf/events/OnPlayerOnlineStatus.java @@ -51,7 +51,7 @@ public class OnPlayerOnlineStatus implements Listener { if (gamePhase.equals(GamePhase.ENDED)) { return; } - Optional optionalTeamPlayer = gameManager.getTeamPlayer(player.getUniqueId()); + Optional optionalTeamPlayer = gameManager.getTeamPlayer(player); TeamPlayer teamPlayer; if (optionalTeamPlayer.isEmpty()) { Optional min = gameManager.getTeams().stream().min(Comparator.comparingInt(team -> team.getPlayers().size())); @@ -59,7 +59,7 @@ public class OnPlayerOnlineStatus implements Listener { log.error("No team found when attempting to add freshly joined player to a team"); return; } - teamPlayer = min.get().addPlayer(player.getUniqueId()); + teamPlayer = min.get().addPlayer(player); } else { teamPlayer = optionalTeamPlayer.get(); } diff --git a/src/main/java/com/alttd/ctf/events/SnowballEvent.java b/src/main/java/com/alttd/ctf/events/SnowballEvent.java index a437d53..11a85d7 100644 --- a/src/main/java/com/alttd/ctf/events/SnowballEvent.java +++ b/src/main/java/com/alttd/ctf/events/SnowballEvent.java @@ -89,7 +89,7 @@ public class SnowballEvent implements Listener { return; } - Optional teamPlayer = gameManager.getTeamPlayer(shooter.getUniqueId()); + Optional teamPlayer = gameManager.getTeamPlayer(shooter); if (teamPlayer.isEmpty()) { log.debug("The shooter that threw a snowball was not a team player"); return; @@ -127,13 +127,13 @@ public class SnowballEvent implements Listener { return; } - Optional teamPlayerShooter = gameManager.getTeamPlayer(shooter.getUniqueId()); + Optional teamPlayerShooter = gameManager.getTeamPlayer(shooter); if (teamPlayerShooter.isEmpty()) { log.debug("The shooter that hit a player with a snowball was not a team player"); return; } - Optional teamPlayerHit = gameManager.getTeamPlayer(hitPlayer.getUniqueId()); + Optional teamPlayerHit = gameManager.getTeamPlayer(hitPlayer); if (teamPlayerHit.isEmpty()) { log.debug("The shooter that hit a player with a snowball was not a team player"); return; diff --git a/src/main/java/com/alttd/ctf/flag/Flag.java b/src/main/java/com/alttd/ctf/flag/Flag.java index 873281e..a881d57 100644 --- a/src/main/java/com/alttd/ctf/flag/Flag.java +++ b/src/main/java/com/alttd/ctf/flag/Flag.java @@ -52,6 +52,7 @@ public class Flag implements Runnable { throw new IllegalStateException(String.format("Tried to spawn flag in world [%s] that doesn't exist", GameConfig.FLAG.world)); } this.flagLocation = new Location(world, GameConfig.FLAG.x, GameConfig.FLAG.y, GameConfig.FLAG.z); + gameManager.getTeams().forEach(team -> team.setScore(0)); } private BossBar createBossBar() { @@ -158,7 +159,7 @@ public class Flag implements Runnable { miniMessage.deserialize("kill before they bring it to their base.", Placeholder.component("player", flagCarrier.displayName()))); Bukkit.getOnlinePlayers().forEach(player -> - gameManager.getTeam(player.getUniqueId()).ifPresent(team -> + gameManager.getTeam(player).ifPresent(team -> player.showTitle(team.getId() == winningTeam.getId() ? capturingTeamTitle : huntingTeamTitle))); } @@ -211,9 +212,10 @@ public class Flag implements Runnable { spawnFlag(GameConfig.FLAG.MATERIAL); wins.merge(winningTeam.getId(), 1, Integer::sum); + wins.forEach((id, score) -> gameManager.getTeam(id).ifPresent(team -> team.setScore(score))); flagCarrier.getInventory().setItem(EquipmentSlot.HEAD, null); - gameManager.getTeamPlayer(flagCarrier.getUniqueId()) + gameManager.getTeamPlayer(flagCarrier) .ifPresent(teamPlayer -> teamPlayer.getGameClass().setArmor(flagCarrier, teamPlayer)); resetFlagCarrier(); @@ -274,7 +276,7 @@ public class Flag implements Runnable { */ private boolean updateScoreBasedOnNearbyPlayers(Collection players) { List nearbyPlayers = players.stream() - .map(player -> gameManager.getTeamPlayer(player.getUniqueId())) + .map(gameManager::getTeamPlayer) .filter(Optional::isPresent) .map(Optional::get) .toList(); @@ -376,7 +378,7 @@ public class Flag implements Runnable { } resetFlagCarrier(); spawnFlag(GameConfig.FLAG.MATERIAL); - gameManager.getTeam(player.getUniqueId()) + gameManager.getTeam(player) .ifPresentOrElse(team -> Bukkit.broadcast(MiniMessage.miniMessage() .deserialize("'s flag carrier died! The flag has respawned", Placeholder.component("team", team.getName()))), diff --git a/src/main/java/com/alttd/ctf/flag/FlagTryCaptureEvent.java b/src/main/java/com/alttd/ctf/flag/FlagTryCaptureEvent.java index f89da71..5ec7490 100644 --- a/src/main/java/com/alttd/ctf/flag/FlagTryCaptureEvent.java +++ b/src/main/java/com/alttd/ctf/flag/FlagTryCaptureEvent.java @@ -37,7 +37,7 @@ public class FlagTryCaptureEvent implements Listener { return; } Player player = event.getPlayer(); - Optional teamPlayer = winningTeam.getPlayer(player.getUniqueId()); + Optional teamPlayer = winningTeam.getPlayer(player); if (teamPlayer.isEmpty()) { return; } diff --git a/src/main/java/com/alttd/ctf/game/GameManager.java b/src/main/java/com/alttd/ctf/game/GameManager.java index 842d94e..d889bab 100644 --- a/src/main/java/com/alttd/ctf/game/GameManager.java +++ b/src/main/java/com/alttd/ctf/game/GameManager.java @@ -39,11 +39,11 @@ public class GameManager { public void registerPlayer(Team team, Player player) { unregisterPlayer(player); - teams.get(team.getId()).addPlayer(player.getUniqueId()); + teams.get(team.getId()).addPlayer(player); } public void unregisterPlayer(Player player) { - teams.values().forEach(team -> team.removePlayer(player.getUniqueId())); + teams.values().forEach(team -> team.removePlayer(player)); } public void registerTeam(Team team) { @@ -54,17 +54,17 @@ public class GameManager { return teams.values(); } - public Optional getTeam(@NotNull UUID uuid) { - return getTeams().stream().filter(filterTeam -> filterTeam.getPlayer(uuid).isPresent()).findAny(); + public Optional getTeam(@NotNull Player player) { + return getTeams().stream().filter(filterTeam -> filterTeam.getPlayer(player).isPresent()).findAny(); } public Optional getTeam(int teamId) { return getTeams().stream().filter(filterTeam -> filterTeam.getId() == teamId).findAny(); } - public Optional getTeamPlayer(@NotNull UUID uuid) { + public Optional getTeamPlayer(@NotNull Player player) { return getTeams().stream() - .map(team -> team.getPlayer(uuid)) + .map(team -> team.getPlayer(player)) .filter(Optional::isPresent) .findFirst() .orElseGet(Optional::empty); diff --git a/src/main/java/com/alttd/ctf/game/phases/ClassSelectionPhase.java b/src/main/java/com/alttd/ctf/game/phases/ClassSelectionPhase.java index dbec683..87b4719 100644 --- a/src/main/java/com/alttd/ctf/game/phases/ClassSelectionPhase.java +++ b/src/main/java/com/alttd/ctf/game/phases/ClassSelectionPhase.java @@ -59,10 +59,10 @@ public class ClassSelectionPhase implements GamePhaseExecutor { Collections.shuffle(players); players.stream() .filter(player -> !player.hasPermission("ctf.bypass")) - .filter(player -> gameManager.getTeamPlayer(player.getUniqueId()).isEmpty()) + .filter(player -> gameManager.getTeamPlayer(player).isEmpty()) .forEach(player -> { Team team = teamCircularIterator.next(); - team.addPlayer(player.getUniqueId()); + team.addPlayer(player); player.sendRichMessage("You joined !", Placeholder.component("team", team.getName())); }); } else { @@ -73,7 +73,7 @@ public class ClassSelectionPhase implements GamePhaseExecutor { private void teleportPlayersToStartingZone() { Bukkit.getOnlinePlayers().forEach(player -> { - Optional teamPlayer = gameManager.getTeamPlayer(player.getUniqueId()); + Optional teamPlayer = gameManager.getTeamPlayer(player); if (teamPlayer.isEmpty()) { log.warn("{} is not a team player when teleporting to starting zone", player.getName()); return; diff --git a/src/main/java/com/alttd/ctf/team/Team.java b/src/main/java/com/alttd/ctf/team/Team.java index d15890f..3f8f5df 100644 --- a/src/main/java/com/alttd/ctf/team/Team.java +++ b/src/main/java/com/alttd/ctf/team/Team.java @@ -7,8 +7,16 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextColor; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.scoreboard.*; import org.jetbrains.annotations.NotNull; import java.util.*; @@ -18,6 +26,8 @@ import java.util.*; @AllArgsConstructor public class Team { + @JsonIgnore + private final static Scoreboard scoreboard = Bukkit.getScoreboardManager().getNewScoreboard(); @JsonIgnore private final HashMap players = new HashMap<>(); @JsonProperty("name") @@ -47,15 +57,23 @@ public class Team { @NotNull @Getter private Material flagMaterial; + @JsonProperty("legacyTeamColor") + @NotNull + @Getter + private String legacyTeamColor; - public TeamPlayer addPlayer(UUID uuid) { + public TeamPlayer addPlayer(Player player) { + removeFromScoreBoard(player); + UUID uuid = player.getUniqueId(); TeamPlayer teamPlayer = new TeamPlayer(uuid, this); players.put(uuid, teamPlayer); - log.debug("Added player with uuid {} to team with id {}", uuid, id); + addToScoreboard(player); + log.debug("Added player {} to team with id {}", player.getName(), id); return teamPlayer; } - public Optional getPlayer(@NotNull UUID uuid) { + public Optional getPlayer(@NotNull Player player) { + UUID uuid = player.getUniqueId(); if (!players.containsKey(uuid)) return Optional.empty(); return Optional.of(players.get(uuid)); @@ -65,13 +83,49 @@ public class Team { return players.values(); } - public void removePlayer(@NotNull UUID uuid) { - TeamPlayer remove = players.remove(uuid); + public void removePlayer(@NotNull Player player) { + removeFromScoreBoard(player); + TeamPlayer remove = players.remove(player.getUniqueId()); if (remove != null) { - log.debug("Removed player with uuid {} from team with id {}", uuid, id); + log.debug("Removed player {} from team with id {}", player.getName(), id); } } + private void addToScoreboard(Player player) { + org.bukkit.scoreboard.Team team = scoreboard.getTeam("ctf_" + id); + if (team == null) { + team = scoreboard.registerNewTeam("ctf_" + id); + team.displayName(name); + NamedTextColor namedTextColor = NamedTextColor.nearestTo(TextColor.color(color.r(), color.g(), color.b())); + team.color(namedTextColor); + } + team.addPlayer(player); + player.setScoreboard(scoreboard); + } + + private void removeFromScoreBoard(Player player) { + scoreboard.getTeams().stream() + .filter(team -> team.getName().startsWith("ctf_")) + .filter(team -> team.hasPlayer(player)) + .forEach(team -> team.removePlayer(player)); + } + + public void setScore(int newScore) { + Objective objective = getOrCreateObjective(); + Score score = objective.getScore(legacyTeamColor + PlainTextComponentSerializer.plainText().serialize(name)); + score.setScore(newScore); + } + + private Objective getOrCreateObjective() { + Objective objective = scoreboard.getObjective("teamScores"); + if (objective == null) { + objective = scoreboard.registerNewObjective("teamScores", Criteria.DUMMY, + MiniMessage.miniMessage().deserialize("CTF score")); + objective.setDisplaySlot(DisplaySlot.SIDEBAR); + } + return objective; + } + @Override public boolean equals(Object obj) { if (this == obj) { diff --git a/version.properties b/version.properties index e0fff57..cf87afd 100644 --- a/version.properties +++ b/version.properties @@ -1,3 +1,3 @@ -#Tue Feb 11 22:21:13 CET 2025 -buildNumber=45 +#Sat Feb 15 03:47:20 CET 2025 +buildNumber=50 version=0.1