From 6b27df9259fca1bbca4cf6e3fc48d585bf434153 Mon Sep 17 00:00:00 2001 From: iambibi_ <89582596+iambibi@users.noreply.github.com> Date: Thu, 19 Feb 2026 13:36:18 +0100 Subject: [PATCH 1/4] fix: content is null --- .../features/leaderboards/LeaderboardManager.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/java/fr/openmc/core/features/leaderboards/LeaderboardManager.java b/src/main/java/fr/openmc/core/features/leaderboards/LeaderboardManager.java index fd7da9e8d..6a053cc30 100644 --- a/src/main/java/fr/openmc/core/features/leaderboards/LeaderboardManager.java +++ b/src/main/java/fr/openmc/core/features/leaderboards/LeaderboardManager.java @@ -91,6 +91,9 @@ public static Component createContributorsTextLeaderboard() { int rank = entry.getKey(); String contributorName = entry.getValue().getKey(); ContributorStats stats = entry.getValue().getValue(); + + if (contributorName == null && stats == null) continue; + int addLines = stats.added(); int removeLines = stats.removed(); Component line = Component.text("\n#") @@ -126,6 +129,9 @@ public static Component createMoneyTextLeaderboard() { int rank = entry.getKey(); String playerName = entry.getValue().getKey(); String money = entry.getValue().getValue(); + + if (playerName == null && money == null) continue; + Component line = Component.text("\n#") .color(getRankColor(rank)) .append(Component.text(rank).color(getRankColor(rank))) @@ -157,6 +163,9 @@ public static Component createCityMoneyTextLeaderboard() { int rank = entry.getKey(); String cityName = entry.getValue().getKey(); String money = entry.getValue().getValue(); + + if (cityName == null && money == null) continue; + Component line = Component.text("\n#") .color(getRankColor(rank)) .append(Component.text(rank).color(getRankColor(rank))) @@ -188,6 +197,9 @@ public static Component createPlayTimeTextLeaderboard() { int rank = entry.getKey(); String playerName = entry.getValue().getKey(); String time = entry.getValue().getValue(); + + if (playerName == null && time == null) continue; + Component line = Component.text("\n#") .color(getRankColor(rank)) .append(Component.text(rank).color(getRankColor(rank))) @@ -214,6 +226,9 @@ public static Component createPumpkinCountTextLeaderboard() { int rank = entry.getKey(); String playerName = entry.getValue().getKey(); String pumpkinCount = entry.getValue().getValue(); + + if (playerName == null && pumpkinCount == null) continue; + Component line = Component.text("\n#") .color(getRankColor(rank)) .append(Component.text(rank).color(getRankColor(rank))) From 301b2d00518364c89d0fcb5f40be8787c64682db Mon Sep 17 00:00:00 2001 From: iambibi_ <89582596+iambibi@users.noreply.github.com> Date: Thu, 19 Feb 2026 13:37:27 +0100 Subject: [PATCH 2/4] fix: fancy nps plugins not found --- .../scoreboards/sb/MainScoreboard.java | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/main/java/fr/openmc/core/features/displays/scoreboards/sb/MainScoreboard.java b/src/main/java/fr/openmc/core/features/displays/scoreboards/sb/MainScoreboard.java index 89e7b63db..33ba1ebc2 100644 --- a/src/main/java/fr/openmc/core/features/displays/scoreboards/sb/MainScoreboard.java +++ b/src/main/java/fr/openmc/core/features/displays/scoreboards/sb/MainScoreboard.java @@ -3,6 +3,7 @@ import de.oliver.fancynpcs.api.FancyNpcsPlugin; import de.oliver.fancynpcs.api.Npc; import de.oliver.fancynpcs.api.NpcManager; +import fr.openmc.api.hooks.FancyNpcsHook; import fr.openmc.api.hooks.LuckPermsHook; import fr.openmc.api.hooks.WorldGuardHook; import fr.openmc.api.scoreboard.SternalBoard; @@ -61,9 +62,6 @@ public void update(Player player, SternalBoard board) { } public static List getDefaultLines(Player player) { - NpcManager npcManager = FancyNpcsPlugin.get().getNpcManager(); - Npc halloweenNPC = npcManager.getNpc("halloween_pumpkin_deposit_npc"); - Component rank = LuckPermsHook.isHasLuckPerms() ? Component.text(LuckPermsHook.getFormattedPAPIPrefix(player)) : Component.text(textToSmall("aucun")).color(TextColor.color(0xFF1FCC)); @@ -102,13 +100,18 @@ public static List getDefaultLines(Player player) { .appendSpace() .append(text(textToSmall(location)).color(TextColor.color(0xFF06DC))) ); - if (halloweenNPC != null) { - String pumpkinCount = EconomyManager.getFormattedSimplifiedNumber(HalloweenManager.getPumpkinCount(player.getUniqueId())); - lines.add(text(" • ", NamedTextColor.DARK_GRAY) - .append(text(textToSmall("citrouilles:"), NamedTextColor.GRAY)) - .appendSpace() - .append(text(textToSmall(pumpkinCount)).color(TextColor.color(0xFF7518))) - ); + + if (FancyNpcsHook.isHasFancyNpc()) { + NpcManager npcManager = FancyNpcsPlugin.get().getNpcManager(); + Npc halloweenNPC = npcManager.getNpc("halloween_pumpkin_deposit_npc"); + if (halloweenNPC != null) { + String pumpkinCount = EconomyManager.getFormattedSimplifiedNumber(HalloweenManager.getPumpkinCount(player.getUniqueId())); + lines.add(text(" • ", NamedTextColor.DARK_GRAY) + .append(text(textToSmall("citrouilles:"), NamedTextColor.GRAY)) + .appendSpace() + .append(text(textToSmall(pumpkinCount)).color(TextColor.color(0xFF7518))) + ); + } } lines.add(newline()); From f1be6f20cf4074169818915a883795534fb8c211 Mon Sep 17 00:00:00 2001 From: iambibi_ <89582596+iambibi@users.noreply.github.com> Date: Thu, 19 Feb 2026 13:46:54 +0100 Subject: [PATCH 3/4] fix: fix cannot invoke "String.isEmpty()" because "content" is null --- .../core/features/leaderboards/LeaderboardManager.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/fr/openmc/core/features/leaderboards/LeaderboardManager.java b/src/main/java/fr/openmc/core/features/leaderboards/LeaderboardManager.java index 6a053cc30..fa688a272 100644 --- a/src/main/java/fr/openmc/core/features/leaderboards/LeaderboardManager.java +++ b/src/main/java/fr/openmc/core/features/leaderboards/LeaderboardManager.java @@ -92,7 +92,7 @@ public static Component createContributorsTextLeaderboard() { String contributorName = entry.getValue().getKey(); ContributorStats stats = entry.getValue().getValue(); - if (contributorName == null && stats == null) continue; + if (contributorName == null || stats == null) continue; int addLines = stats.added(); int removeLines = stats.removed(); @@ -130,7 +130,7 @@ public static Component createMoneyTextLeaderboard() { String playerName = entry.getValue().getKey(); String money = entry.getValue().getValue(); - if (playerName == null && money == null) continue; + if (playerName == null || money == null) continue; Component line = Component.text("\n#") .color(getRankColor(rank)) @@ -164,7 +164,7 @@ public static Component createCityMoneyTextLeaderboard() { String cityName = entry.getValue().getKey(); String money = entry.getValue().getValue(); - if (cityName == null && money == null) continue; + if (cityName == null || money == null) continue; Component line = Component.text("\n#") .color(getRankColor(rank)) @@ -198,7 +198,7 @@ public static Component createPlayTimeTextLeaderboard() { String playerName = entry.getValue().getKey(); String time = entry.getValue().getValue(); - if (playerName == null && time == null) continue; + if (playerName == null || time == null) continue; Component line = Component.text("\n#") .color(getRankColor(rank)) @@ -227,7 +227,7 @@ public static Component createPumpkinCountTextLeaderboard() { String playerName = entry.getValue().getKey(); String pumpkinCount = entry.getValue().getValue(); - if (playerName == null && pumpkinCount == null) continue; + if (playerName == null || pumpkinCount == null) continue; Component line = Component.text("\n#") .color(getRankColor(rank)) From c88eaedb1ee57106f67bd1ba62b1602f38c47102 Mon Sep 17 00:00:00 2001 From: iambibi_ <89582596+iambibi@users.noreply.github.com> Date: Thu, 19 Feb 2026 14:39:16 +0100 Subject: [PATCH 4/4] chore: BossbarManager.java + impl: bossbar in milestone --- .../java/fr/openmc/core/ListenersManager.java | 2 - src/main/java/fr/openmc/core/OMCPlugin.java | 2 + .../displays/bossbar/BaseBossbar.java | 57 +++ .../displays/bossbar/BossbarManager.java | 345 +++++++----------- .../bossbar/commands/BossBarCommand.java | 138 +------ .../bossbar/contents/HelpConfigManager.java | 67 ++++ .../bossbar/contents/MainBossbar.java | 51 +++ .../bossbar/listeners/BossbarListener.java | 23 -- .../features/dream/displays/DreamBossBar.java | 76 ++-- .../dream/PlayerChangeWorldListener.java | 14 - .../listeners/dream/PlayerJoinListener.java | 8 - .../features/dream/models/db/DreamPlayer.java | 3 - .../core/features/milestones/Milestone.java | 46 ++- .../features/milestones/MilestoneQuest.java | 6 +- .../features/milestones/MilestoneStep.java | 6 + .../features/milestones/MilestoneType.java | 9 +- .../features/milestones/MilestoneUtils.java | 48 +-- .../milestones/MilestonesManager.java | 34 +- .../milestones/bossbar/MilestoneBossBar.java | 85 +++++ .../bossbar/MilestoneBossBarOptions.java | 5 + .../milestones/tutorial/TutorialBossBar.java | 54 --- .../tutorial/TutorialMilestone.java | 26 +- .../milestones/tutorial/TutorialStep.java | 3 +- .../listeners/TutorialBossBarEvent.java | 25 -- .../tutorial/quests/BreakAyweniteQuest.java | 17 +- 25 files changed, 536 insertions(+), 614 deletions(-) create mode 100644 src/main/java/fr/openmc/core/features/displays/bossbar/BaseBossbar.java create mode 100644 src/main/java/fr/openmc/core/features/displays/bossbar/contents/HelpConfigManager.java create mode 100644 src/main/java/fr/openmc/core/features/displays/bossbar/contents/MainBossbar.java delete mode 100644 src/main/java/fr/openmc/core/features/displays/bossbar/listeners/BossbarListener.java create mode 100644 src/main/java/fr/openmc/core/features/milestones/MilestoneStep.java create mode 100644 src/main/java/fr/openmc/core/features/milestones/bossbar/MilestoneBossBar.java create mode 100644 src/main/java/fr/openmc/core/features/milestones/bossbar/MilestoneBossBarOptions.java delete mode 100644 src/main/java/fr/openmc/core/features/milestones/tutorial/TutorialBossBar.java delete mode 100644 src/main/java/fr/openmc/core/features/milestones/tutorial/listeners/TutorialBossBarEvent.java diff --git a/src/main/java/fr/openmc/core/ListenersManager.java b/src/main/java/fr/openmc/core/ListenersManager.java index dbed68ddb..7d2cad511 100644 --- a/src/main/java/fr/openmc/core/ListenersManager.java +++ b/src/main/java/fr/openmc/core/ListenersManager.java @@ -5,7 +5,6 @@ import fr.openmc.core.features.cube.listeners.CubeListener; import fr.openmc.core.features.cube.listeners.RepulseEffectListener; import fr.openmc.core.features.cube.multiblocks.MultiBlocksListeners; -import fr.openmc.core.features.displays.bossbar.listeners.BossbarListener; import fr.openmc.core.features.itemsadder.SpawnerExtractorListener; import fr.openmc.core.features.settings.PlayerSettingsManager; import fr.openmc.core.features.tickets.TicketListener; @@ -34,7 +33,6 @@ public static void init() { new SleepListener(), new PlayerDeathListener(), new AsyncChatListener(OMCPlugin.getInstance()), - new BossbarListener(), new PlayerSettingsManager(), new InteractListener(), new AywenCapListener(), diff --git a/src/main/java/fr/openmc/core/OMCPlugin.java b/src/main/java/fr/openmc/core/OMCPlugin.java index 851264b9f..04aa4d5ab 100644 --- a/src/main/java/fr/openmc/core/OMCPlugin.java +++ b/src/main/java/fr/openmc/core/OMCPlugin.java @@ -19,6 +19,7 @@ import fr.openmc.core.features.cube.multiblocks.MultiBlockManager; import fr.openmc.core.features.displays.TabList; import fr.openmc.core.features.displays.bossbar.BossbarManager; +import fr.openmc.core.features.displays.bossbar.contents.HelpConfigManager; import fr.openmc.core.features.displays.holograms.HologramLoader; import fr.openmc.core.features.displays.scoreboards.ScoreboardManager; import fr.openmc.core.features.dream.DreamManager; @@ -133,6 +134,7 @@ public void onEnable() { QuestProgressSaveManager.init(); TabList.init(); AdminShopManager.init(); + HelpConfigManager.init(); BossbarManager.init(); AnimationsManager.init(); HalloweenManager.init(); diff --git a/src/main/java/fr/openmc/core/features/displays/bossbar/BaseBossbar.java b/src/main/java/fr/openmc/core/features/displays/bossbar/BaseBossbar.java new file mode 100644 index 000000000..8f4ef79d3 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/displays/bossbar/BaseBossbar.java @@ -0,0 +1,57 @@ +package fr.openmc.core.features.displays.bossbar; + +import net.kyori.adventure.bossbar.BossBar; +import org.bukkit.boss.BarColor; +import org.bukkit.entity.Player; + +public abstract class BaseBossbar { + /** + * Initialise la boss bar pour un joueur + * + * @param player Le joueur + */ + public void init(Player player, BossBar bar) { + update(player, bar); + } + + protected abstract String id(); + + /** + * Met à jour la boss bar + * + * @param player Le joueur + */ + protected abstract void update(Player player, BossBar bar); + + /** + * Détermine la couleur de la boss bar + * @param player Le joueur + * @return La couleur de la boss bar + */ + protected abstract BossBar.Color color(Player player); + + /** + * Détermine le style de la boss bar + * @param player Le joueur + * @return Le style de la boss bar + */ + protected abstract BossBar.Overlay style(Player player); + + /** + * Détermine si le boss bar doit être affiché pour un joueur + * + * @param player Le joueur à vérifier + * @return true si la boss bar doit être affiché, false sinon + */ + protected abstract boolean shouldDisplay(Player player); + + /** + * @return Le poids de la boss bar (plus la valeur est haute, plus la position de la boss bar sera haute). + */ + protected abstract int weight(); + + /** + * @return L'intervalle de mise à jour en secondes + */ + protected abstract Integer updateInterval(); +} diff --git a/src/main/java/fr/openmc/core/features/displays/bossbar/BossbarManager.java b/src/main/java/fr/openmc/core/features/displays/bossbar/BossbarManager.java index 1c1b003fd..1eb10cdad 100644 --- a/src/main/java/fr/openmc/core/features/displays/bossbar/BossbarManager.java +++ b/src/main/java/fr/openmc/core/features/displays/bossbar/BossbarManager.java @@ -3,10 +3,9 @@ import fr.openmc.core.CommandsManager; import fr.openmc.core.OMCPlugin; import fr.openmc.core.features.displays.bossbar.commands.BossBarCommand; -import fr.openmc.core.features.milestones.MilestoneUtils; -import fr.openmc.core.utils.messages.MessageType; -import fr.openmc.core.utils.messages.MessagesManager; -import fr.openmc.core.utils.messages.Prefix; +import fr.openmc.core.features.displays.bossbar.contents.MainBossbar; +import fr.openmc.core.features.displays.scoreboards.BaseScoreboard; +import fr.openmc.core.features.dream.displays.DreamBossBar; import lombok.Getter; import net.kyori.adventure.bossbar.BossBar; import net.kyori.adventure.text.Component; @@ -20,267 +19,175 @@ import java.util.*; public class BossbarManager { - @Getter - private static final List helpMessages = new ArrayList<>(); - private static final HashMap> activeBossBars = new HashMap<>(); - private static final Map playerPreferences = new HashMap<>(); - @Getter - private static boolean bossBarEnabled = true; - @Getter - private static File configFile; - private static int currentMessageIndex = 0; - - public static BossBar bossBarHelp; - - /** - * Initializes the BossbarManager - */ + private static final List registeredBossbar = new ArrayList<>(); + + private static final Map> activeBossbars = new HashMap<>(); + private static final Map> lastUpdate = new HashMap<>(); + private static final Map> offBossbars = new HashMap<>(); + public static void init() { - configFile = new File(OMCPlugin.getInstance().getDataFolder() + "/data", "bossbars.yml"); - loadConfig(); - loadDefaultMessages(); - startRotationTask(); CommandsManager.getHandler().register(new BossBarCommand()); - bossBarHelp = BossBar.bossBar( - helpMessages.getFirst(), - 0f, - BossBar.Color.RED, - BossBar.Overlay.PROGRESS + registerBossbars( + new MainBossbar(), + new DreamBossBar() ); - } - /** - * Loads configuration from bossbars.yml file - * Creates the file if it doesn't exist - */ - private static void loadConfig() { - if (!configFile.exists()) { - configFile.getParentFile().mkdirs(); - OMCPlugin.getInstance().saveResource("data/bossbars.yml", false); - } - reloadMessages(); + start(); } - /** - * Loads messages from the configuration file - */ - private static void loadDefaultMessages() { - YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile); - helpMessages.clear(); - - for (String rawMessage : config.getStringList("messages")) { - helpMessages.add(MiniMessage.miniMessage().deserialize(rawMessage)); - } - - if (helpMessages.isEmpty()) { - OMCPlugin.getInstance().getSLF4JLogger().warn("No messages found in bossbars.yml."); - } + public static void registerBossbars(BaseBossbar... bossbar) { + registeredBossbar.addAll(Arrays.asList(bossbar)); + registeredBossbar.sort(Comparator.comparingInt(BaseBossbar::weight).reversed()); } - /** - * Starts the message rotation task for bossbars - * Messages change every 10 seconds (200 ticks) - */ - private static void startRotationTask() { + private static void start() { new BukkitRunnable() { @Override public void run() { - if (helpMessages.isEmpty()) return; + for (Player player : Bukkit.getOnlinePlayers()) { + updatePlayer(player); + } + } + }.runTaskTimer(OMCPlugin.getInstance(), 0L, 20L); + } + - currentMessageIndex = (currentMessageIndex + 1) % helpMessages.size(); - Component message = helpMessages.get(currentMessageIndex); + private static void updatePlayer(Player player) { - activeBossBars.forEach((type, bossBarData) -> { - if (!type.equals(BossbarsType.HELP)) return; + UUID uuid = player.getUniqueId(); + + activeBossbars.putIfAbsent(uuid, new HashMap<>()); + offBossbars.putIfAbsent(uuid, new HashSet<>()); + lastUpdate.putIfAbsent(uuid, new HashMap<>()); + + Map playerBars = activeBossbars.get(uuid); + Set toggled = offBossbars.get(uuid); + Map playerLastUpdate = lastUpdate.get(uuid); + + long now = System.currentTimeMillis(); + + for (BaseBossbar base : registeredBossbar) { + + String id = base.id(); - bossBarData.forEach((uuid, bossBar) -> { - if (bossBar != null) { - bossBar.name(message); - } - }); - }); + if (toggled.contains(id)) { + removeBossBar(player, id); + continue; } - }.runTaskTimer(OMCPlugin.getInstance(), 0, 200); - } - /** - * Adds a bossbar to the specified player - * @param type The type of bossbar to add - * @param bossbar The bossbar to add - * @param player The player to add the bossbar to - */ - public static void addBossBar(BossbarsType type, BossBar bossbar, Player player) { - if (!bossBarEnabled) return; - - Map bars = activeBossBars.get(type); - if (bars != null && bars.containsKey(player.getUniqueId())) return; - - Boolean preference = playerPreferences.get(player.getUniqueId()); - if (preference != null && !preference) { - return; - } - removeBossBar(type, player); + boolean shouldDisplay = base.shouldDisplay(player); + BossBar existing = playerBars.get(id); - player.showBossBar(bossbar); - activeBossBars.computeIfAbsent(type, k -> new HashMap<>()).put(player.getUniqueId(), bossbar); - } + if (shouldDisplay) { - /** - * Removes the bossbar from the specified player - * @param type The type of bossbar to remove - * @param player The player to remove the bossbar from - */ - public static void removeBossBar(BossbarsType type, Player player) { - Map map = activeBossBars.get(type); - if (map == null) return; - - BossBar bossBar = map.remove(player.getUniqueId()); - if (bossBar != null) { - player.hideBossBar(bossBar); - } - } + if (existing == null) { + existing = BossBar.bossBar( + Component.text(), + 1f, + base.color(player), + base.style(player) + ); + + player.showBossBar(existing); + playerBars.put(id, existing); - /** - * Gets the bossbar for a specific player - * - * @param type The type of bossbar to get - * @param player The player to get the bossbar for - * @return The bossbar for the specified player, or null if not found - */ - public static BossBar getBossBar(BossbarsType type, Player player) { - if (activeBossBars.get(type) == null) return null; + base.update(player, existing); + playerLastUpdate.put(id, now); + continue; + } - return activeBossBars.get(type).get(player.getUniqueId()); + long last = playerLastUpdate.getOrDefault(id, 0L); + long intervalMillis = base.updateInterval() * 1000L; - } + if (now - last >= intervalMillis) { + base.update(player, existing); + playerLastUpdate.put(id, now); + } - /** - * Toggles the bossbar for a specific player - * @param player The player to toggle the bossbar for - */ - public static void toggleBossBar(Player player) { - UUID uuid = player.getUniqueId(); - boolean enabled = false; - - for (Map.Entry> activeBossBar : activeBossBars.entrySet()) { - BossbarsType type = activeBossBar.getKey(); - Map bossBarData = activeBossBar.getValue(); - if (bossBarData.containsKey(uuid)) { - removeBossBar(type, player); - enabled = false; - playerPreferences.put(uuid, false); } else { - switch (type) { - case HELP -> { - addBossBar(type, bossBarHelp, player); - enabled = true; - playerPreferences.put(uuid, true); - } - - case TUTORIAL -> { - MilestoneUtils.setBossBar(player); - enabled = true; - playerPreferences.put(uuid, true); - } - } + removeBossBar(player, id); + playerLastUpdate.remove(id); } } - - if (enabled) { - MessagesManager.sendMessage(player, Component.text("Bossbar activée"), Prefix.OPENMC, MessageType.SUCCESS, true); - } else { - MessagesManager.sendMessage(player, Component.text("Bossbar désactivée"), Prefix.OPENMC, MessageType.WARNING, true); - } } - /** - * Reloads messages from the configuration file - */ - public static void reloadMessages() { - helpMessages.clear(); - loadDefaultMessages(); - } + public static void addBossBar(Player player, String id) { + BaseBossbar base = getRegistered(id); + if (base == null) return; - /** - * Checks if bossbars are globally enabled - * @return true if bossbars are enabled, false otherwise - */ - public static boolean hasBossBar() { - return bossBarEnabled; - } + activeBossbars.putIfAbsent(player.getUniqueId(), new HashMap<>()); + + Map playerBars = activeBossbars.get(player.getUniqueId()); + + if (playerBars.containsKey(id)) return; - /** - * Sets the list of messages to display in bossbars - * @param messages The list of new messages - */ - public static void setHelpMessages(List messages) { - helpMessages.clear(); - helpMessages.addAll(messages); - saveMessagesToConfig(); + BossBar bar = BossBar.bossBar( + Component.text(), + 1L, + base.color(player), + base.style(player) + ); + + player.showBossBar(bar); + playerBars.put(id, bar); } - /** - * Saves messages to the configuration file - */ - private static void saveMessagesToConfig() { - try { - YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile); - List serializedMessages = new ArrayList<>(); + public static void removeBossBar(Player player, String id) { + Map bars = activeBossbars.get(player.getUniqueId()); + if (bars == null) return; - for (Component message : helpMessages) { - serializedMessages.add(MiniMessage.miniMessage().serialize(message)); - } + BossBar bar = bars.remove(id); - config.set("messages", serializedMessages); - config.save(configFile); - } catch (Exception e) { - OMCPlugin.getInstance().getSLF4JLogger().warn("Failed to save bossbar messages to config: {}", e.getMessage(), e); + if (bar != null) { + player.hideBossBar(bar); } } - /** - * Adds a message to the message list - * @param message The message to add - */ - public static void addMessage(Component message) { - helpMessages.add(message); - saveMessagesToConfig(); + public static BossBar getBossBar(Player player, String id) { + Map bars = activeBossbars.get(player.getUniqueId()); + if (bars == null) return null; + return bars.get(id); } - /** - * Removes a message from the message list - * @param index The index of the message to remove - */ - public static void removeMessage(int index) { - if (index >= 0 && index < helpMessages.size()) { - helpMessages.remove(index); - saveMessagesToConfig(); + public static void toggleBossBar(Player player, String id) { + offBossbars.putIfAbsent(player.getUniqueId(), new HashSet<>()); + + Set toggled = offBossbars.get(player.getUniqueId()); + + if (toggled.contains(id)) { + toggled.remove(id); + } else { + toggled.add(id); + removeBossBar(player, id); } } - /** - * Updates an existing message - * @param index The index of the message to update - * @param newMessage The new message content - */ - public static void updateMessage(int index, Component newMessage) { - if (index >= 0 && index < helpMessages.size()) { - helpMessages.set(index, newMessage); - saveMessagesToConfig(); + public static void toggleAllBossBar(Player player) { + for (BaseBossbar baseBossbar : registeredBossbar) { + toggleBossBar(player, baseBossbar.id()); } } - /** - * Toggles bossbars globally for all players - */ - public static void toggleGlobalBossBar() { - bossBarEnabled = !bossBarEnabled; + public static boolean isToggled(Player player, String id) { + return offBossbars.getOrDefault(player.getUniqueId(), Set.of()).contains(id); + } - if (bossBarEnabled) { - Bukkit.getOnlinePlayers().forEach(player -> addBossBar(BossbarsType.HELP, bossBarHelp, player)); - } else { - Bukkit.getOnlinePlayers().forEach(player -> removeBossBar(BossbarsType.HELP, player)); + public static void removePlayer(Player player) { + Map bars = activeBossbars.remove(player.getUniqueId()); + if (bars != null) { + for (BossBar bar : bars.values()) { + player.hideBossBar(bar); + } } + + offBossbars.remove(player.getUniqueId()); + } + + private static BaseBossbar getRegistered(String id) { + return registeredBossbar.stream() + .filter(b -> b.id().equalsIgnoreCase(id)) + .findFirst() + .orElse(null); } } diff --git a/src/main/java/fr/openmc/core/features/displays/bossbar/commands/BossBarCommand.java b/src/main/java/fr/openmc/core/features/displays/bossbar/commands/BossBarCommand.java index 7d81d9960..efb045e33 100644 --- a/src/main/java/fr/openmc/core/features/displays/bossbar/commands/BossBarCommand.java +++ b/src/main/java/fr/openmc/core/features/displays/bossbar/commands/BossBarCommand.java @@ -25,141 +25,7 @@ public class BossBarCommand { @CommandPlaceholder() - public void mainCommand(CommandSender sender) { - if (!(sender instanceof Player player)) { - MessagesManager.sendMessage(sender, MessagesManager.Message.NO_PERMISSION.getMessage(), Prefix.OPENMC, MessageType.ERROR, true); - return; - } - - BossbarManager.toggleBossBar(player); - } - - @CommandPermission("omc.admin.commands.bossbar.reload") - @Subcommand("reload") - public void reloadCommand(CommandSender sender) { - BossbarManager.reloadMessages(); - MessagesManager.sendMessage(sender, Component.text("§aBossbar rechargée avec succès !"), Prefix.OPENMC, MessageType.SUCCESS, true); - } - - @CommandPermission("omc.admin.commands.bossbar.toggle") - @Subcommand("toggle") - public void toggleCommand(CommandSender sender) { - BossbarManager.toggleGlobalBossBar(); - if (sender instanceof Player player) { - MessagesManager.sendMessage(player, Component.text("§aBossbar " + (BossbarManager.hasBossBar() ? "activée" : "désactivée") + " pour vous."), Prefix.OPENMC, MessageType.SUCCESS, true); - } - } - - @CommandPermission("omc.admin.commands.bossbar.manage") - @Subcommand("manage") - public void manageCommand(BukkitCommandActor actor) { - if (!(actor.sender() instanceof Player player)) { - return; - } - - List messages = BossbarManager.getHelpMessages(); - - Component header = Component.text("\n§6§lGestion des messages de la bossbar\n") - .color(NamedTextColor.GOLD) - .decorate(TextDecoration.BOLD); - - MessagesManager.sendMessage(player, header, Prefix.OPENMC, MessageType.NONE, false); - - Component addButton = Component.text("[Ajouter un message]") - .color(NamedTextColor.GREEN) - .clickEvent(ClickEvent.suggestCommand("/omcbossbar add ")) - .hoverEvent(HoverEvent.showText(Component.text("Cliquez pour ajouter un message"))); - - MessagesManager.sendMessage(player, addButton, Prefix.OPENMC, MessageType.NONE, false); - - for (int i = 0; i < messages.size(); i++) { - Component messageLine = Component.text((i + 1) + ". ", NamedTextColor.GRAY) - .append(messages.get(i)) - .append(Component.space()) - .append(createActionButton("✎ Éditer", "/omcbossbar edit " + i + " " + messages.get(i), NamedTextColor.YELLOW)) - .append(Component.space()) - .append(createActionButton("✖ Supprimer", "/omcbossbar confirm " + i, NamedTextColor.RED)); - - MessagesManager.sendMessage(player, messageLine, Prefix.OPENMC, MessageType.NONE, false); - } - - Component refreshButton = Component.text("\n[Rafraîchir]") - .color(NamedTextColor.BLUE) - .clickEvent(ClickEvent.runCommand("/omcbossbar manage")) - .hoverEvent(HoverEvent.showText(Component.text("Actualiser la liste"))); - - MessagesManager.sendMessage(player, refreshButton, Prefix.OPENMC, MessageType.NONE, false); - } - - private Component createActionButton(String text, String command, NamedTextColor color) { - return Component.text(text) - .color(color) - .clickEvent(ClickEvent.suggestCommand(command)) - .hoverEvent(HoverEvent.showText(Component.text("Exécuter : " + command))); - } - - @CommandPermission("omc.admin.commands.bossbar.manage") - @Subcommand("add") - public void addMessage( - BukkitCommandActor actor, - @Named("message") String message - ) { - try { - Component component = MiniMessage.miniMessage().deserialize(message); - BossbarManager.addMessage(component); - BossbarManager.reloadMessages(); - - MessagesManager.sendMessage(actor.sender(), Component.text("§aMessage ajouté avec succès !"), Prefix.OPENMC, MessageType.SUCCESS, true); - manageCommand(actor); - } catch (Exception e) { - MessagesManager.sendMessage(actor.sender(), Component.text("§cErreur lors de l'ajout du message ! Assurez-vous que le format est correct."), Prefix.OPENMC, MessageType.ERROR, true); - } - } - - @CommandPermission("omc.admin.commands.bossbar.manage") - @Subcommand("edit") - public void editMessage( - BukkitCommandActor actor, - @Named("index") int index, - @Named("message edité") String newMessage - ) { - try { - Component component = MiniMessage.miniMessage().deserialize(newMessage); - BossbarManager.updateMessage(index, component); - BossbarManager.reloadMessages(); - MessagesManager.sendMessage(actor.sender(), Component.text("§aMessage mis à jour avec succès !"), Prefix.OPENMC, MessageType.SUCCESS, true); - manageCommand(actor); - } catch (Exception e) { - MessagesManager.sendMessage(actor.sender(), Component.text("§cFormat de message ou index invalide !"), Prefix.OPENMC, MessageType.ERROR, true); - } - } - - @CommandPermission("omc.admin.commands.bossbar.manage") - @Subcommand("confirm") - public void confirmDelete( - BukkitCommandActor actor, - @Named("index") int index - ) { - Component confirmation = Component.text() - .append(Component.text("§eÊtes-vous sûr de vouloir supprimer ce message ?")) - .append(Component.text("[OUI]") - .color(NamedTextColor.RED) - .clickEvent(ClickEvent.runCommand("/omcbossbar delete " + index)) - .hoverEvent(HoverEvent.showText(Component.text("Confirmer la suppression")))) - .build(); - - actor.reply(confirmation); - } - - @CommandPermission("omc.admin.commands.bossbar.manage") - @Subcommand("delete") - public void deleteMessage( - BukkitCommandActor actor, - @Named("index") int index - ) { - BossbarManager.removeMessage(index); - BossbarManager.reloadMessages(); - MessagesManager.sendMessage(actor.sender(), Component.text("Message supprimé avec succès."), Prefix.OPENMC, MessageType.SUCCESS, true); - manageCommand(actor); + public void mainCommand(Player player) { + BossbarManager.toggleBossBar(player, "omc:help"); } } diff --git a/src/main/java/fr/openmc/core/features/displays/bossbar/contents/HelpConfigManager.java b/src/main/java/fr/openmc/core/features/displays/bossbar/contents/HelpConfigManager.java new file mode 100644 index 000000000..b4ea4d6b0 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/displays/bossbar/contents/HelpConfigManager.java @@ -0,0 +1,67 @@ +package fr.openmc.core.features.displays.bossbar.contents; + +import fr.openmc.core.CommandsManager; +import fr.openmc.core.OMCPlugin; +import fr.openmc.core.features.displays.bossbar.commands.BossBarCommand; +import lombok.Getter; +import net.kyori.adventure.bossbar.BossBar; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +public class HelpConfigManager { + + @Getter + private static final List helpMessages = new ArrayList<>(); + @Getter + private static File configFile; + + /** + * Initializes the HelpConfigManager by loading the configuration and default messages + */ + public static void init() { + configFile = new File(OMCPlugin.getInstance().getDataFolder() + "/data", "bossbars.yml"); + loadConfig(); + loadDefaultMessages(); + } + + /** + * Loads configuration from bossbars.yml file + * Creates the file if it doesn't exist + */ + private static void loadConfig() { + if (!configFile.exists()) { + configFile.getParentFile().mkdirs(); + OMCPlugin.getInstance().saveResource("data/bossbars.yml", false); + } + reloadMessages(); + } + + /** + * Loads messages from the configuration file + */ + private static void loadDefaultMessages() { + YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile); + helpMessages.clear(); + + for (String rawMessage : config.getStringList("messages")) { + helpMessages.add(MiniMessage.miniMessage().deserialize(rawMessage)); + } + + if (helpMessages.isEmpty()) { + OMCPlugin.getInstance().getSLF4JLogger().warn("No messages found in bossbars.yml."); + } + } + + /** + * Reloads messages from the configuration file + */ + public static void reloadMessages() { + helpMessages.clear(); + loadDefaultMessages(); + } +} diff --git a/src/main/java/fr/openmc/core/features/displays/bossbar/contents/MainBossbar.java b/src/main/java/fr/openmc/core/features/displays/bossbar/contents/MainBossbar.java new file mode 100644 index 000000000..f146dd2d7 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/displays/bossbar/contents/MainBossbar.java @@ -0,0 +1,51 @@ +package fr.openmc.core.features.displays.bossbar.contents; + +import fr.openmc.core.features.displays.bossbar.BaseBossbar; +import fr.openmc.core.features.dream.DreamUtils; +import net.kyori.adventure.bossbar.BossBar; +import net.kyori.adventure.text.minimessage.MiniMessage; +import org.bukkit.entity.Player; + +import java.util.List; + +public class MainBossbar extends BaseBossbar { + + private static int indexMessage = 0; + + @Override + protected String id() { + return "omc:help"; + } + + @Override + protected void update(Player player, BossBar bar) { + indexMessage = (indexMessage + 1) % HelpConfigManager.getHelpMessages().size(); + + bar.name(HelpConfigManager.getHelpMessages().get(indexMessage)); + } + + @Override + protected BossBar.Color color(Player player) { + return BossBar.Color.RED; + } + + @Override + protected BossBar.Overlay style(Player player) { + return BossBar.Overlay.PROGRESS; + } + + @Override + protected boolean shouldDisplay(Player player) { + return !DreamUtils.isInDreamWorld(player); + } + + @Override + protected int weight() { + return 10; + } + + @Override + protected Integer updateInterval() { + return 20; + } +} diff --git a/src/main/java/fr/openmc/core/features/displays/bossbar/listeners/BossbarListener.java b/src/main/java/fr/openmc/core/features/displays/bossbar/listeners/BossbarListener.java deleted file mode 100644 index 45379736d..000000000 --- a/src/main/java/fr/openmc/core/features/displays/bossbar/listeners/BossbarListener.java +++ /dev/null @@ -1,23 +0,0 @@ -package fr.openmc.core.features.displays.bossbar.listeners; - -import fr.openmc.core.features.displays.bossbar.BossbarManager; -import fr.openmc.core.features.displays.bossbar.BossbarsType; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerQuitEvent; - -import static fr.openmc.core.features.displays.bossbar.BossbarManager.bossBarHelp; - -public class BossbarListener implements Listener { - - @EventHandler - public void onPlayerJoin(PlayerJoinEvent event) { - BossbarManager.addBossBar(BossbarsType.HELP, bossBarHelp, event.getPlayer()); - } - - @EventHandler - public void onPlayerQuit(PlayerQuitEvent event) { - BossbarManager.removeBossBar(BossbarsType.HELP, event.getPlayer()); - } -} diff --git a/src/main/java/fr/openmc/core/features/dream/displays/DreamBossBar.java b/src/main/java/fr/openmc/core/features/dream/displays/DreamBossBar.java index cf3efd507..246591489 100644 --- a/src/main/java/fr/openmc/core/features/dream/displays/DreamBossBar.java +++ b/src/main/java/fr/openmc/core/features/dream/displays/DreamBossBar.java @@ -1,7 +1,11 @@ package fr.openmc.core.features.dream.displays; +import fr.openmc.core.features.displays.bossbar.BaseBossbar; import fr.openmc.core.features.displays.bossbar.BossbarManager; import fr.openmc.core.features.displays.bossbar.BossbarsType; +import fr.openmc.core.features.dream.DreamManager; +import fr.openmc.core.features.dream.DreamUtils; +import fr.openmc.core.features.dream.models.db.DreamPlayer; import net.kyori.adventure.bossbar.BossBar; import net.kyori.adventure.text.Component; import org.bukkit.entity.Player; @@ -11,45 +15,45 @@ * *

Cette classe permet d'ajouter, mettre à jour et cacher la BossBar associée à un joueur.

*/ -public class DreamBossBar { - - private static final Component TEXTURE_BOSSBAR = Component.text(""); - - /** - * Ajoute une BossBar pour le joueur spécifié dans la Dimension des Rêves. - * - * @param player le joueur auquel ajouter la BossBar - * @param progress la progression de la BossBar - */ - public static void addDreamBossBarForPlayer(Player player, float progress) { - BossBar bar = BossBar.bossBar( - TEXTURE_BOSSBAR, - progress, - BossBar.Color.BLUE, - BossBar.Overlay.PROGRESS - ); - BossbarManager.addBossBar(BossbarsType.DREAM, bar, player); +public class DreamBossBar extends BaseBossbar { + @Override + protected String id() { + return "omc:dream"; } - /** - * Met à jour la progression de la BossBar pour le joueur spécifié. - * - * @param player le joueur dont la BossBar doit être mise à jour - * @param progress la nouvelle progression de la BossBar - */ - public static void update(Player player, float progress) { - BossBar bar = BossbarManager.getBossBar(BossbarsType.DREAM, player); - if (bar != null) { - bar.progress(progress); - } + @Override + protected void update(Player player, BossBar bar) { + DreamPlayer dreamPlayer = DreamManager.getDreamPlayer(player); + + if (dreamPlayer == null) return; + + float progress = Math.min(1, (float) dreamPlayer.getDreamTime() / dreamPlayer.getMaxDreamTime()); + + bar.progress(progress); + } + + @Override + protected BossBar.Color color(Player player) { + return BossBar.Color.BLUE; + } + + @Override + protected BossBar.Overlay style(Player player) { + return BossBar.Overlay.PROGRESS; + } + + @Override + protected boolean shouldDisplay(Player player) { + return DreamUtils.isInDreamWorld(player); + } + + @Override + protected int weight() { + return 10; } - /** - * Cache (supprime) la BossBar du joueur spécifié. - * - * @param player le joueur dont la BossBar doit être supprimée - */ - public static void hide(Player player) { - BossbarManager.removeBossBar(BossbarsType.DREAM, player); + @Override + protected Integer updateInterval() { + return 1; } } diff --git a/src/main/java/fr/openmc/core/features/dream/listeners/dream/PlayerChangeWorldListener.java b/src/main/java/fr/openmc/core/features/dream/listeners/dream/PlayerChangeWorldListener.java index 84ba003f7..dd7393748 100644 --- a/src/main/java/fr/openmc/core/features/dream/listeners/dream/PlayerChangeWorldListener.java +++ b/src/main/java/fr/openmc/core/features/dream/listeners/dream/PlayerChangeWorldListener.java @@ -24,10 +24,6 @@ public void onDreamEntrered(PlayerTeleportEvent event) { if (!DreamUtils.isDreamWorld(event.getTo())) return; if (DreamUtils.isDreamWorld(event.getFrom())) return; - for (BossbarsType type : BossbarsType.values()) { - BossbarManager.removeBossBar(type, player); - } - try { DreamManager.addDreamPlayer(player, event.getFrom()); } catch (IOException e) { @@ -37,8 +33,6 @@ public void onDreamEntrered(PlayerTeleportEvent event) { DreamPlayer dreamPlayer = DreamManager.getDreamPlayer(player); if (dreamPlayer == null) return; - DreamBossBar.addDreamBossBarForPlayer(player, Math.min(1, (float) dreamPlayer.getDreamTime() / dreamPlayer.getMaxDreamTime())); - player.setFoodLevel(20); player.setSaturation(10.0f); AttributeInstance inst = player.getAttribute(Attribute.MAX_HEALTH); @@ -53,14 +47,6 @@ public void onDreamLeave(PlayerTeleportEvent event) { if (!DreamUtils.isDreamWorld(event.getFrom())) return; if (DreamUtils.isDreamWorld(event.getTo())) return; - for (BossbarsType type : BossbarsType.values()) { - if (type.equals(BossbarsType.DREAM)) continue; - - BossbarManager.addBossBar(type, BossbarManager.bossBarHelp, player); - } - - BossbarManager.removeBossBar(BossbarsType.DREAM, player); - DreamManager.removeDreamPlayer(player, event.getFrom()); } } diff --git a/src/main/java/fr/openmc/core/features/dream/listeners/dream/PlayerJoinListener.java b/src/main/java/fr/openmc/core/features/dream/listeners/dream/PlayerJoinListener.java index f507cec39..80ada5d61 100644 --- a/src/main/java/fr/openmc/core/features/dream/listeners/dream/PlayerJoinListener.java +++ b/src/main/java/fr/openmc/core/features/dream/listeners/dream/PlayerJoinListener.java @@ -23,14 +23,6 @@ public void onPlayerJoinInDream(PlayerJoinEvent event) { if (!DreamUtils.isInDreamWorld(player)) return; - for (BossbarsType type : BossbarsType.values()) { - if (type.equals(BossbarsType.DREAM)) continue; - - BossbarManager.addBossBar(type, BossbarManager.bossBarHelp, player); - } - - BossbarManager.removeBossBar(BossbarsType.DREAM, player); - try { DreamManager.preloadSavePlayer(player, player.getLocation()); } catch (IOException e) { diff --git a/src/main/java/fr/openmc/core/features/dream/models/db/DreamPlayer.java b/src/main/java/fr/openmc/core/features/dream/models/db/DreamPlayer.java index 530c48d22..65fe90834 100644 --- a/src/main/java/fr/openmc/core/features/dream/models/db/DreamPlayer.java +++ b/src/main/java/fr/openmc/core/features/dream/models/db/DreamPlayer.java @@ -98,10 +98,7 @@ public void scheduleTimeTask() { Bukkit.getServer().getPluginManager().callEvent(new DreamEndEvent(this.player)) ); this.cancelTimeTask(); - return; } - - DreamBossBar.update(player, Math.min(1, (float) this.getDreamTime() / this.getMaxDreamTime())); }, 0L, 20L); } diff --git a/src/main/java/fr/openmc/core/features/milestones/Milestone.java b/src/main/java/fr/openmc/core/features/milestones/Milestone.java index 8358b023b..6052e510c 100644 --- a/src/main/java/fr/openmc/core/features/milestones/Milestone.java +++ b/src/main/java/fr/openmc/core/features/milestones/Milestone.java @@ -1,15 +1,18 @@ package fr.openmc.core.features.milestones; import fr.openmc.api.menulib.Menu; +import fr.openmc.core.features.milestones.bossbar.MilestoneBossBarOptions; +import fr.openmc.core.features.milestones.tutorial.TutorialStep; import net.kyori.adventure.text.Component; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.UUID; -public interface Milestone { +public interface Milestone & MilestoneStep> { HashMap playerData = new HashMap<>(); /** @@ -42,13 +45,18 @@ default HashMap getPlayerData() { * @return The icon of the milestone. */ ItemStack getIcon(); - + /** - * Returns the steps of the milestone. - * - * @return A step list of the milestone. + * @return The class of the steps for the milestone. + */ + Class getStepClass(); + + /** + * @return The enum constants of the step class for the milestone. */ - List getSteps(); + default T[] getStepEnum() { + return this.getStepClass().getEnumConstants(); + } /** * Returns the Type of the Milestone @@ -64,4 +72,30 @@ default HashMap getPlayerData() { * @return The menu for the milestone. */ Menu getMenu(Player player); + + /** + * Returns the boss bar options for the milestone. + * If set to null, no boss bar will be displayed for the milestone. + * + * @return The boss bar options for the milestone. + */ + MilestoneBossBarOptions getBossBarOptions(); + + /** + * Determines whether the boss bar should be displayed for the given player. + * + * @param player The player for whom to check if the boss bar should be displayed. + * @return true if the boss bar should be displayed for the player, false otherwise. + */ + boolean shouldDisplayBossBar(Player player); + /** + * Returns the steps of the milestone. + * + * @return A step list of the milestone. + */ + default List getSteps() { + T[] enumStep = this.getStepEnum(); + return Arrays.stream(enumStep).map(MilestoneStep::getQuest).toList(); + } + } diff --git a/src/main/java/fr/openmc/core/features/milestones/MilestoneQuest.java b/src/main/java/fr/openmc/core/features/milestones/MilestoneQuest.java index fed40f108..f72576d79 100644 --- a/src/main/java/fr/openmc/core/features/milestones/MilestoneQuest.java +++ b/src/main/java/fr/openmc/core/features/milestones/MilestoneQuest.java @@ -13,9 +13,9 @@ public class MilestoneQuest extends Quest { protected final MilestoneType type; - protected final Enum step; + protected final Enum step; - public MilestoneQuest(String name, List baseDescription, Material icon, MilestoneType type, Enum step, QuestTier quest) { + public MilestoneQuest(String name, List baseDescription, Material icon, MilestoneType type, Enum step, QuestTier quest) { super(name, baseDescription, icon); this.type = type; this.step = step; @@ -24,7 +24,7 @@ public MilestoneQuest(String name, List baseDescription, Material icon, )); } - public MilestoneQuest(String name, List baseDescription, ItemStack icon, MilestoneType type, Enum step, QuestTier quest) { + public MilestoneQuest(String name, List baseDescription, ItemStack icon, MilestoneType type, Enum step, QuestTier quest) { this(name, baseDescription, icon.getType(), type, step, quest); } } diff --git a/src/main/java/fr/openmc/core/features/milestones/MilestoneStep.java b/src/main/java/fr/openmc/core/features/milestones/MilestoneStep.java new file mode 100644 index 000000000..1478ad3b9 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/milestones/MilestoneStep.java @@ -0,0 +1,6 @@ +package fr.openmc.core.features.milestones; + +public interface MilestoneStep { + MilestoneQuest getQuest(); + +} diff --git a/src/main/java/fr/openmc/core/features/milestones/MilestoneType.java b/src/main/java/fr/openmc/core/features/milestones/MilestoneType.java index 6979f390f..eb837a6f9 100644 --- a/src/main/java/fr/openmc/core/features/milestones/MilestoneType.java +++ b/src/main/java/fr/openmc/core/features/milestones/MilestoneType.java @@ -6,15 +6,12 @@ @Getter public enum MilestoneType { TUTORIAL( - new TutorialMilestone(), - true + new TutorialMilestone() ); - private final Milestone milestone; - private final boolean boosBar; + private final Milestone milestone; - MilestoneType(Milestone milestone, boolean bossBar) { + MilestoneType(Milestone milestone) { this.milestone = milestone; - this.boosBar = bossBar; } } diff --git a/src/main/java/fr/openmc/core/features/milestones/MilestoneUtils.java b/src/main/java/fr/openmc/core/features/milestones/MilestoneUtils.java index e1e185e18..1ddd72c5f 100644 --- a/src/main/java/fr/openmc/core/features/milestones/MilestoneUtils.java +++ b/src/main/java/fr/openmc/core/features/milestones/MilestoneUtils.java @@ -1,60 +1,18 @@ package fr.openmc.core.features.milestones; -import fr.openmc.core.features.displays.bossbar.BossbarManager; -import fr.openmc.core.features.displays.bossbar.BossbarsType; -import fr.openmc.core.features.milestones.tutorial.TutorialBossBar; -import fr.openmc.core.features.milestones.tutorial.TutorialMilestone; -import fr.openmc.core.features.milestones.tutorial.TutorialStep; -import net.kyori.adventure.text.Component; import org.bukkit.entity.Player; public class MilestoneUtils { - public static void completeStep(MilestoneType type, Player player, Enum step) { + public static void completeStep(MilestoneType type, Player player, Enum step) { int stepInt = step.ordinal() + 1; if (MilestonesManager.getPlayerStep(type, player) >= stepInt) return; MilestonesManager.setPlayerStep(type, player, stepInt); - MilestonesManager.getMilestoneData(type).get(player.getUniqueId()).setProgress(0); - - if (type != MilestoneType.TUTORIAL) return; //TODO Refaire les bossbars - - int maxStep = TutorialStep.values().length; - - if (stepInt >= maxStep) { - TutorialBossBar.hide(player); - BossbarManager.removeBossBar(BossbarsType.TUTORIAL, player); - return; - } - - TutorialBossBar.update( - player, - Component.text(TutorialBossBar.PLACEHOLDER_TUTORIAL_BOSSBAR.formatted( - (stepInt + 1), - TutorialStep.values()[stepInt].getQuest().getName(player.getUniqueId()) - )), - (float) (stepInt + 1) / maxStep - ); } - public static void setBossBar(Player player) { - int maxStep = TutorialStep.values().length; - int step = MilestonesManager.getPlayerStep(MilestoneType.TUTORIAL, player); - - if (step >= maxStep) return; - String progressStr = ""; - if (step == 0) { - progressStr = " (" + TutorialMilestone.playerData.get(player.getUniqueId()).getProgress() + " / 30)"; - } - - TutorialBossBar.addTutorialBossBarForPlayer( - player, - Component.text(TutorialBossBar.PLACEHOLDER_TUTORIAL_BOSSBAR.formatted( - step + 1, - TutorialStep.values()[step].getQuest().getName(player.getUniqueId()) + progressStr - )), - step == 0 ? (float) TutorialStep.BREAK_AYWENITE.getQuest().getProgress(player.getUniqueId()) / 30 : (float) (step + 1) / maxStep - ); + public static boolean hasFinishedMilestone(MilestoneType type, Player player) { + return MilestonesManager.getPlayerStep(type, player) >= type.getMilestone().getSteps().size(); } } diff --git a/src/main/java/fr/openmc/core/features/milestones/MilestonesManager.java b/src/main/java/fr/openmc/core/features/milestones/MilestonesManager.java index 61f0c0ecc..b15be65a7 100644 --- a/src/main/java/fr/openmc/core/features/milestones/MilestonesManager.java +++ b/src/main/java/fr/openmc/core/features/milestones/MilestonesManager.java @@ -6,8 +6,9 @@ import com.j256.ormlite.table.TableUtils; import fr.openmc.core.CommandsManager; import fr.openmc.core.OMCPlugin; +import fr.openmc.core.features.displays.bossbar.BossbarManager; +import fr.openmc.core.features.milestones.bossbar.MilestoneBossBar; import fr.openmc.core.features.milestones.listeners.PlayerJoin; -import fr.openmc.core.features.milestones.tutorial.listeners.TutorialBossBarEvent; import fr.openmc.core.features.quests.objects.Quest; import org.bukkit.entity.Player; import org.bukkit.event.Listener; @@ -16,7 +17,7 @@ import java.util.*; public class MilestonesManager { - private static final Set milestones = new HashSet<>(); + private static final Set> milestones = new HashSet<>(); private static Dao millestoneDao; @@ -29,8 +30,7 @@ public static void init() { registerMilestoneCommand(); OMCPlugin.registerEvents( - new PlayerJoin(), - new TutorialBossBarEvent() + new PlayerJoin() ); } @@ -54,7 +54,7 @@ public static void loadMilestonesData() { for (MilestoneModel data : milestoneData) { MilestoneType type = MilestoneType.valueOf(data.getType()); - Milestone milestone = type.getMilestone(); + Milestone milestone = type.getMilestone(); milestone.getPlayerData().put(data.getUUID(), data); } } catch (SQLException e) { @@ -68,7 +68,7 @@ public static void loadMilestonesData() { */ public static void saveMilestonesData() { try { - for (Milestone milestone : milestones) { + for (Milestone milestone : milestones) { for (Map.Entry entry : milestone.getPlayerData().entrySet()) { MilestoneModel model = entry.getValue(); millestoneDao.createOrUpdate(model); @@ -83,7 +83,7 @@ public static void saveMilestonesData() { * Load the quest progress for each player of each milestone */ public static void loadMilestonesProgress() { - for (Milestone milestone : milestones) { + for (Milestone milestone : milestones) { // Pour tous les joueurs du milestone, la progression est chargée à l'étape actuelle for (Map.Entry playerData : milestone.getPlayerData().entrySet()) { milestone.getSteps().get(playerData.getValue().getStep()).setProgress(playerData.getKey(), playerData.getValue().getProgress()); @@ -96,7 +96,7 @@ public static void loadMilestonesProgress() { * @param milestone the milestone to get data for * @return a map of player UUIDs to their MilestoneModel */ - public static Map getMilestoneData(Milestone milestone) { + public static Map getMilestoneData(Milestone milestone) { return milestone.getPlayerData(); } @@ -154,7 +154,7 @@ public static void setPlayerStep(MilestoneType type, Player player, int step) { * Get all registered milestones. * @return a set of all registered milestones */ - public static Set getRegisteredMilestones() { + public static Set> getRegisteredMilestones() { return milestones; } @@ -163,12 +163,12 @@ public static Set getRegisteredMilestones() { * This method adds the provided milestone to the internal set and registers it quests. * @param milestone the milestone to register */ - public static void registerMilestone(Milestone milestone) { + public static void registerMilestone(Milestone milestone) { if (milestone == null) return; milestones.add(milestone); registerQuestMilestone(milestone); - + registerMilestoneBossBar(milestone); } /** @@ -184,11 +184,19 @@ public static void registerMilestoneCommand() { * This method iterates through the steps of the milestone and registers any Listener instances. * @param milestone the milestone whose quests are to be registered */ - public static void registerQuestMilestone(Milestone milestone) { - for (Quest quest : milestone.getSteps()) { + public static void registerQuestMilestone(Milestone milestone) { + for (MilestoneQuest quest : milestone.getSteps()) { if (quest instanceof Listener listener) { OMCPlugin.registerEvents(listener); } } } + + public static void registerMilestoneBossBar(Milestone milestone) { + if (milestone.getBossBarOptions() == null) return; + + BossbarManager.registerBossbars( + new MilestoneBossBar(milestone) + ); + } } diff --git a/src/main/java/fr/openmc/core/features/milestones/bossbar/MilestoneBossBar.java b/src/main/java/fr/openmc/core/features/milestones/bossbar/MilestoneBossBar.java new file mode 100644 index 000000000..c0feddfb5 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/milestones/bossbar/MilestoneBossBar.java @@ -0,0 +1,85 @@ +package fr.openmc.core.features.milestones.bossbar; + +import fr.openmc.core.features.displays.bossbar.BaseBossbar; +import fr.openmc.core.features.milestones.*; +import net.kyori.adventure.bossbar.BossBar; +import net.kyori.adventure.text.Component; +import org.bukkit.entity.Player; + +public class MilestoneBossBar extends BaseBossbar { + + private final Milestone milestone; + + public MilestoneBossBar(Milestone milestone) { + this.milestone = milestone; + } + public static final String PLACEHOLDER_MILESTONE_BOSSBAR = "§6Étape %s : %s"; + public static final String PLACEHOLDER_MILESTONE_BOSSBAR_PROGRESS = "§6Étape %s : %s (%s/%s)"; + + @Override + protected String id() { + return "omc:" + milestone.getType().toString() + "_milestone"; + } + + @Override + protected void update(Player player, BossBar bar) { + int currentStep = MilestonesManager.getPlayerStep(milestone.getType(), player); + + MilestoneStep[] steps = milestone.getStepEnum(); + + if (currentStep >= steps.length) return; // pas affiché par défaut (shouldDisplay()) + + int maxStep = steps.length; + MilestoneStep step = steps[currentStep]; + MilestoneQuest quest = step.getQuest(); + + int progress = quest.getProgress(player.getUniqueId()); + int goal = quest.getCurrentTarget(player.getUniqueId()); + + String questName = quest.getName(player.getUniqueId()); + + if (goal <= 1) { + bar.name(Component.text( + PLACEHOLDER_MILESTONE_BOSSBAR.formatted(currentStep + 1, questName) + )); + + bar.progress((float) currentStep / maxStep); + } else { + bar.name(Component.text( + PLACEHOLDER_MILESTONE_BOSSBAR_PROGRESS.formatted( + currentStep + 1, + quest.getName(player.getUniqueId()), + progress, + goal + ) + )); + + bar.progress((float) progress / goal); + } + } + + @Override + protected BossBar.Color color(Player player) { + return milestone.getBossBarOptions().color(); + } + + @Override + protected BossBar.Overlay style(Player player) { + return milestone.getBossBarOptions().style(); + } + + @Override + protected boolean shouldDisplay(Player player) { + return milestone.shouldDisplayBossBar(player); + } + + @Override + protected int weight() { + return 5; + } + + @Override + protected Integer updateInterval() { + return 2; + } +} diff --git a/src/main/java/fr/openmc/core/features/milestones/bossbar/MilestoneBossBarOptions.java b/src/main/java/fr/openmc/core/features/milestones/bossbar/MilestoneBossBarOptions.java new file mode 100644 index 000000000..23a3d240a --- /dev/null +++ b/src/main/java/fr/openmc/core/features/milestones/bossbar/MilestoneBossBarOptions.java @@ -0,0 +1,5 @@ +package fr.openmc.core.features.milestones.bossbar; + +import net.kyori.adventure.bossbar.BossBar; + +public record MilestoneBossBarOptions(BossBar.Color color, BossBar.Overlay style) { } diff --git a/src/main/java/fr/openmc/core/features/milestones/tutorial/TutorialBossBar.java b/src/main/java/fr/openmc/core/features/milestones/tutorial/TutorialBossBar.java deleted file mode 100644 index 5607cb084..000000000 --- a/src/main/java/fr/openmc/core/features/milestones/tutorial/TutorialBossBar.java +++ /dev/null @@ -1,54 +0,0 @@ -package fr.openmc.core.features.milestones.tutorial; - -import fr.openmc.core.features.displays.bossbar.BossbarManager; -import fr.openmc.core.features.displays.bossbar.BossbarsType; -import net.kyori.adventure.bossbar.BossBar; -import net.kyori.adventure.text.Component; -import org.bukkit.entity.Player; - -public class TutorialBossBar { - - public static final String PLACEHOLDER_TUTORIAL_BOSSBAR = "§6Étape %s : %s"; - - /** - * Adds a tutorial boss bar for the player with the given message and progress. - * - * @param player The player to add the boss bar for. - * @param message The message to display on the boss bar. - * @param progress The progress of the tutorial step (0.0 to 1.0). - */ - public static void addTutorialBossBarForPlayer(Player player, Component message, float progress) { - BossBar bar = BossBar.bossBar( - message, - progress, - BossBar.Color.YELLOW, - BossBar.Overlay.PROGRESS - ); - BossbarManager.addBossBar(BossbarsType.TUTORIAL, bar, player); - } - - /** - * Updates the tutorial boss bar for the player with the given message and progress. - * - * @param player The player to update the boss bar for. - * @param message The new message to display on the boss bar. - * @param progress The new progress of the tutorial step (0.0 to 1.0). - */ - public static void update(Player player, Component message, float progress) { - BossBar bar = BossbarManager.getBossBar(BossbarsType.TUTORIAL, player); - - if (bar != null) { - bar.name(message); - bar.progress(progress); - } - } - - /** - * Hides the tutorial boss bar for the player. - * - * @param player The player to hide the boss bar for. - */ - public static void hide(Player player) { - BossbarManager.removeBossBar(BossbarsType.TUTORIAL, player); - } -} diff --git a/src/main/java/fr/openmc/core/features/milestones/tutorial/TutorialMilestone.java b/src/main/java/fr/openmc/core/features/milestones/tutorial/TutorialMilestone.java index eb927ae9f..eb7156448 100644 --- a/src/main/java/fr/openmc/core/features/milestones/tutorial/TutorialMilestone.java +++ b/src/main/java/fr/openmc/core/features/milestones/tutorial/TutorialMilestone.java @@ -1,10 +1,11 @@ package fr.openmc.core.features.milestones.tutorial; import fr.openmc.api.menulib.Menu; -import fr.openmc.core.features.milestones.Milestone; -import fr.openmc.core.features.milestones.MilestoneQuest; -import fr.openmc.core.features.milestones.MilestoneType; +import fr.openmc.core.features.dream.DreamUtils; +import fr.openmc.core.features.milestones.*; +import fr.openmc.core.features.milestones.bossbar.MilestoneBossBarOptions; import fr.openmc.core.features.milestones.menus.MilestoneMenu; +import net.kyori.adventure.bossbar.BossBar; import net.kyori.adventure.text.Component; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -13,7 +14,7 @@ import java.util.Arrays; import java.util.List; -public class TutorialMilestone implements Milestone { +public class TutorialMilestone implements Milestone { @Override public String getName() { return "§7Tutoriel d'OpenMC"; @@ -35,8 +36,8 @@ public ItemStack getIcon() { } @Override - public List getSteps() { - return Arrays.stream(TutorialStep.values()).map(TutorialStep::getQuest).toList(); + public Class getStepClass() { + return TutorialStep.class; } @Override @@ -48,4 +49,17 @@ public MilestoneType getType() { public Menu getMenu(Player player) { return new MilestoneMenu(player, this); } + + @Override + public MilestoneBossBarOptions getBossBarOptions() { + return new MilestoneBossBarOptions( + BossBar.Color.YELLOW, + BossBar.Overlay.PROGRESS + ); + } + + @Override + public boolean shouldDisplayBossBar(Player player) { + return !DreamUtils.isInDreamWorld(player) && !MilestoneUtils.hasFinishedMilestone(this.getType(), player); + } } diff --git a/src/main/java/fr/openmc/core/features/milestones/tutorial/TutorialStep.java b/src/main/java/fr/openmc/core/features/milestones/tutorial/TutorialStep.java index ffb679a54..a6801e1ee 100644 --- a/src/main/java/fr/openmc/core/features/milestones/tutorial/TutorialStep.java +++ b/src/main/java/fr/openmc/core/features/milestones/tutorial/TutorialStep.java @@ -1,11 +1,12 @@ package fr.openmc.core.features.milestones.tutorial; import fr.openmc.core.features.milestones.MilestoneQuest; +import fr.openmc.core.features.milestones.MilestoneStep; import fr.openmc.core.features.milestones.tutorial.quests.*; import lombok.Getter; @Getter -public enum TutorialStep { +public enum TutorialStep implements MilestoneStep { BREAK_AYWENITE(null), CITY_CREATE(null), CITY_LEVEL_2(null), diff --git a/src/main/java/fr/openmc/core/features/milestones/tutorial/listeners/TutorialBossBarEvent.java b/src/main/java/fr/openmc/core/features/milestones/tutorial/listeners/TutorialBossBarEvent.java deleted file mode 100644 index 85db1ea27..000000000 --- a/src/main/java/fr/openmc/core/features/milestones/tutorial/listeners/TutorialBossBarEvent.java +++ /dev/null @@ -1,25 +0,0 @@ -package fr.openmc.core.features.milestones.tutorial.listeners; - -import fr.openmc.core.features.displays.bossbar.BossbarManager; -import fr.openmc.core.features.displays.bossbar.BossbarsType; -import fr.openmc.core.features.milestones.MilestoneUtils; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerQuitEvent; - -public class TutorialBossBarEvent implements Listener { - - @EventHandler - void onPlayerJoin(PlayerJoinEvent event) { - Player player = event.getPlayer(); - - MilestoneUtils.setBossBar(player); - } - - @EventHandler - public void onPlayerQuit(PlayerQuitEvent event) { - BossbarManager.removeBossBar(BossbarsType.TUTORIAL, event.getPlayer()); - } -} diff --git a/src/main/java/fr/openmc/core/features/milestones/tutorial/quests/BreakAyweniteQuest.java b/src/main/java/fr/openmc/core/features/milestones/tutorial/quests/BreakAyweniteQuest.java index afdf2199a..9a64beec7 100644 --- a/src/main/java/fr/openmc/core/features/milestones/tutorial/quests/BreakAyweniteQuest.java +++ b/src/main/java/fr/openmc/core/features/milestones/tutorial/quests/BreakAyweniteQuest.java @@ -3,10 +3,10 @@ import dev.lone.itemsadder.api.CustomBlock; import fr.openmc.api.hooks.ItemsAdderHook; import fr.openmc.core.features.city.CityManager; +import fr.openmc.core.features.displays.bossbar.BossbarManager; import fr.openmc.core.features.milestones.MilestoneQuest; import fr.openmc.core.features.milestones.MilestoneType; import fr.openmc.core.features.milestones.MilestonesManager; -import fr.openmc.core.features.milestones.tutorial.TutorialBossBar; import fr.openmc.core.features.milestones.tutorial.TutorialStep; import fr.openmc.core.features.quests.objects.QuestTier; import fr.openmc.core.features.quests.rewards.QuestMethodsReward; @@ -15,6 +15,7 @@ import fr.openmc.core.items.CustomItemRegistry; import fr.openmc.core.utils.messages.MessageType; import fr.openmc.core.utils.messages.Prefix; +import net.kyori.adventure.bossbar.BossBar; import net.kyori.adventure.text.Component; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -64,19 +65,7 @@ public void onPlayerBreakBlock(BlockBreakEvent event) { ) { Player player = event.getPlayer(); this.incrementProgress(player.getUniqueId()); - getType().getMilestone().getPlayerData().get(player.getUniqueId()).incrementProgress(); - - int progress = this.getProgress(player.getUniqueId()); - - if (progress >= 30) return; - TutorialBossBar.update( - player, - Component.text(TutorialBossBar.PLACEHOLDER_TUTORIAL_BOSSBAR.formatted( - (step.ordinal() + 1), - TutorialStep.values()[step.ordinal()].getQuest().getName(player.getUniqueId()) + " (" + progress + " / 30)" - )), - (float) this.getProgress(player.getUniqueId()) / 30 - ); + this.getType().getMilestone().getPlayerData().get(player.getUniqueId()).incrementProgress(); } } }