From 7573ca71c51b26be3812a61260a289edc82ecc4c Mon Sep 17 00:00:00 2001 From: Teriuihi Date: Mon, 25 Sep 2023 03:35:48 +0200 Subject: [PATCH] Implemented scoreboard --- .../fishingevent/commands/FishCommand.java | 4 +- .../fish_subcommands/Leaderboard.java | 61 +++++++++++++++ .../commands/fish_subcommands/Points.java | 2 +- .../com/alttd/fishingevent/fish/Fish.java | 2 +- .../com/alttd/fishingevent/fish/LavaFish.java | 2 +- .../alttd/fishingevent/fish/WaterFish.java | 2 +- .../fishingevent/listeners/CatchFish.java | 4 +- .../fishingevent/objects/PlayerScore.java | 7 ++ .../scoreboard/ScoreboardManager.java | 74 +++++++++++++++++++ 9 files changed, 152 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/alttd/fishingevent/commands/fish_subcommands/Leaderboard.java create mode 100644 src/main/java/com/alttd/fishingevent/objects/PlayerScore.java create mode 100644 src/main/java/com/alttd/fishingevent/scoreboard/ScoreboardManager.java diff --git a/src/main/java/com/alttd/fishingevent/commands/FishCommand.java b/src/main/java/com/alttd/fishingevent/commands/FishCommand.java index 240ee4b..d1d3452 100644 --- a/src/main/java/com/alttd/fishingevent/commands/FishCommand.java +++ b/src/main/java/com/alttd/fishingevent/commands/FishCommand.java @@ -1,6 +1,7 @@ package com.alttd.fishingevent.commands; import com.alttd.fishingevent.FishingEvent; +import com.alttd.fishingevent.commands.fish_subcommands.Leaderboard; import com.alttd.fishingevent.commands.fish_subcommands.Points; import com.alttd.fishingevent.config.Messages; import com.alttd.fishingevent.util.Logger; @@ -28,7 +29,8 @@ public class FishCommand implements CommandExecutor, TabExecutor { command.setTabCompleter(this); subCommands = Arrays.asList( - new Points() + new Points(), + new Leaderboard() ); } diff --git a/src/main/java/com/alttd/fishingevent/commands/fish_subcommands/Leaderboard.java b/src/main/java/com/alttd/fishingevent/commands/fish_subcommands/Leaderboard.java new file mode 100644 index 0000000..ab0d84a --- /dev/null +++ b/src/main/java/com/alttd/fishingevent/commands/fish_subcommands/Leaderboard.java @@ -0,0 +1,61 @@ +package com.alttd.fishingevent.commands.fish_subcommands; + +import com.alttd.fishingevent.commands.SubCommand; +import com.alttd.fishingevent.objects.PlayerScore; +import com.alttd.fishingevent.scoreboard.ScoreboardManager; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.List; +import java.util.UUID; + +public class Leaderboard extends SubCommand { + @Override + public boolean onCommand(CommandSender commandSender, String[] args) { + List top10 = ScoreboardManager.getInstance().getTop10(); + Component component = MiniMessage.miniMessage().deserialize("Scoreboard:\n"); + boolean displayPlayerScore = true; + UUID uuid = null; + if (commandSender instanceof Player player) + uuid = player.getUniqueId(); + for (PlayerScore playerScore : top10) { + component = component.append(Component.newline()).append(MiniMessage.miniMessage().deserialize("'s biggest fish was the at cm", + Placeholder.component("player", playerScore.player().displayName()), + Placeholder.parsed("length", String.format("%.2f", playerScore.biggestFish())), + Placeholder.parsed("rarity", playerScore.fish().getRarity().displayName()), + Placeholder.component("fish", playerScore.fish().fishName()))); + if (playerScore.player().getUniqueId().equals(uuid)) + displayPlayerScore = false; + } + if (displayPlayerScore && uuid != null) { + PlayerScore playerScore = ScoreboardManager.getInstance().getScore(uuid); + if (playerScore != null) + component = component.append(Component.newline()).append(MiniMessage.miniMessage().deserialize("Your biggest fish was the at cm", + Placeholder.component("player", playerScore.player().displayName()), + Placeholder.parsed("length", String.format("%.2f", playerScore.biggestFish())), + Placeholder.parsed("rarity", playerScore.fish().getRarity().displayName()), + Placeholder.component("fish", playerScore.fish().fishName()))); + } + + commandSender.sendMessage(component); + return true; + } + + @Override + public String getName() { + return "leaderboard"; + } + + @Override + public List getTabComplete(CommandSender commandSender, String[] args) { + return List.of(); + } + + @Override + public String getHelpMessage() { + return ""; //TODO implement + } +} diff --git a/src/main/java/com/alttd/fishingevent/commands/fish_subcommands/Points.java b/src/main/java/com/alttd/fishingevent/commands/fish_subcommands/Points.java index f8d0a59..ee1be2d 100644 --- a/src/main/java/com/alttd/fishingevent/commands/fish_subcommands/Points.java +++ b/src/main/java/com/alttd/fishingevent/commands/fish_subcommands/Points.java @@ -70,6 +70,6 @@ public class Points extends SubCommand { @Override public String getHelpMessage() { - return null; + return ""; //TODO implement } } diff --git a/src/main/java/com/alttd/fishingevent/fish/Fish.java b/src/main/java/com/alttd/fishingevent/fish/Fish.java index 368063e..d9a6eed 100644 --- a/src/main/java/com/alttd/fishingevent/fish/Fish.java +++ b/src/main/java/com/alttd/fishingevent/fish/Fish.java @@ -39,7 +39,7 @@ public abstract class Fish { * Gives back a different result each call, it generates a length based on the min and max length values for a fish * @return a random length for this fish */ - public abstract float getLength(); + public abstract float generateLength(); public abstract Component fishName(); diff --git a/src/main/java/com/alttd/fishingevent/fish/LavaFish.java b/src/main/java/com/alttd/fishingevent/fish/LavaFish.java index 5b4fb25..7193133 100644 --- a/src/main/java/com/alttd/fishingevent/fish/LavaFish.java +++ b/src/main/java/com/alttd/fishingevent/fish/LavaFish.java @@ -27,7 +27,7 @@ public class LavaFish extends Fish { } @Override - public float getLength() { + public float generateLength() { return 0; } diff --git a/src/main/java/com/alttd/fishingevent/fish/WaterFish.java b/src/main/java/com/alttd/fishingevent/fish/WaterFish.java index 66c0316..6921bbe 100644 --- a/src/main/java/com/alttd/fishingevent/fish/WaterFish.java +++ b/src/main/java/com/alttd/fishingevent/fish/WaterFish.java @@ -35,7 +35,7 @@ public class WaterFish extends Fish { } @Override - public float getLength() { + public float generateLength() { return new Random().nextFloat(minLength, maxLength); } diff --git a/src/main/java/com/alttd/fishingevent/listeners/CatchFish.java b/src/main/java/com/alttd/fishingevent/listeners/CatchFish.java index fe95032..0887a35 100644 --- a/src/main/java/com/alttd/fishingevent/listeners/CatchFish.java +++ b/src/main/java/com/alttd/fishingevent/listeners/CatchFish.java @@ -5,6 +5,7 @@ import com.alttd.fishingevent.fish.Fish; import com.alttd.fishingevent.fish_generator.FishGenerator; import com.alttd.fishingevent.objects.FishType; import com.alttd.fishingevent.points.PointsManagement; +import com.alttd.fishingevent.scoreboard.ScoreboardManager; import com.alttd.fishingevent.util.Logger; import org.bukkit.Location; import org.bukkit.Material; @@ -85,7 +86,7 @@ public class CatchFish implements Listener { } Fish fish = optionalFish.get(); - float length = fish.getLength(); + float length = fish.generateLength(); int pointsValue = pointsManagement.calculatePoints(fish.getRarity(), length); Optional fishItem = fish.createItem(player, length, pointsValue); if (fishItem.isEmpty()) { @@ -99,5 +100,6 @@ public class CatchFish implements Listener { logger.debug("[%] caught a [%] with length [%] and rarity [%] for [%] points", player.getName(), fish.normalFishName(), String.format("%.2f", length), fish.getRarity().displayName(), String.valueOf(pointsValue)); + ScoreboardManager.getInstance().updateScoreboard(player, length, fish); } } diff --git a/src/main/java/com/alttd/fishingevent/objects/PlayerScore.java b/src/main/java/com/alttd/fishingevent/objects/PlayerScore.java new file mode 100644 index 0000000..03a5ceb --- /dev/null +++ b/src/main/java/com/alttd/fishingevent/objects/PlayerScore.java @@ -0,0 +1,7 @@ +package com.alttd.fishingevent.objects; + +import com.alttd.fishingevent.fish.Fish; +import org.bukkit.entity.Player; + +public record PlayerScore(Player player, double biggestFish, Fish fish){ +} diff --git a/src/main/java/com/alttd/fishingevent/scoreboard/ScoreboardManager.java b/src/main/java/com/alttd/fishingevent/scoreboard/ScoreboardManager.java new file mode 100644 index 0000000..7f6ef83 --- /dev/null +++ b/src/main/java/com/alttd/fishingevent/scoreboard/ScoreboardManager.java @@ -0,0 +1,74 @@ +package com.alttd.fishingevent.scoreboard; + +import com.alttd.fishingevent.fish.Fish; +import com.alttd.fishingevent.objects.PlayerScore; +import net.kyori.adventure.text.minimessage.MiniMessage; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.scoreboard.*; + +import java.util.*; +import java.util.stream.Collectors; + +public class ScoreboardManager { + + private static ScoreboardManager instance; + private final Scoreboard scoreboard; + private Objective objective; + private final String scoreName = "Fish Leaderboard"; + private double tenthLength = 0; + private final HashMap playerScores = new HashMap<>(); //TODO save and load this along with the points data + + private ScoreboardManager() { + scoreboard = Bukkit.getScoreboardManager().getNewScoreboard(); + objective = scoreboard.getObjective(scoreName); + if (objective == null) { + objective = scoreboard.registerNewObjective(scoreName, "fishing-event", MiniMessage.miniMessage().deserialize(scoreName), RenderType.INTEGER); + objective.setDisplaySlot(DisplaySlot.SIDEBAR); + } + } + + public static ScoreboardManager getInstance() { + if (instance == null) { + instance = new ScoreboardManager(); + } + return instance; + } + + public List getTop10() { + return playerScores.values().stream().sorted(Comparator.comparingDouble(PlayerScore::biggestFish)).limit(10).collect(Collectors.toList()); + } + + public void updateScoreboard(Player player, double fishLength, Fish fish) { + UUID uuid = player.getUniqueId(); + PlayerScore playerScore = playerScores.get(uuid); + + if (playerScore != null && !(playerScore.biggestFish() < fishLength)) { + return; + } + + playerScores.put(uuid, new PlayerScore(player, fishLength, fish)); + if (fishLength <= tenthLength) + return; + updateScoreBoard(); + } + + private void updateScoreBoard() { + resetScoreBoard(); + List sortedScores = getTop10(); + for (PlayerScore sortedScore : sortedScores) { + objective.getScore(sortedScore.player()).setScore((int) sortedScore.biggestFish()); + } + if (!sortedScores.isEmpty()) + tenthLength = sortedScores.get(sortedScores.size() - 1).biggestFish(); + Bukkit.getOnlinePlayers().forEach(player -> player.setScoreboard(scoreboard)); + } + + private void resetScoreBoard() { + playerScores.values().forEach(playerScore -> scoreboard.resetScores(playerScore.player())); + } + + public PlayerScore getScore(UUID uuid) { + return playerScores.get(uuid); + } +}