diff --git a/src/main/java/de/fanta/challenges/challenges/AllAdvancementsChallenge.java b/src/main/java/de/fanta/challenges/challenges/AllAdvancementsChallenge.java index e2a6bbf..89e383f 100644 --- a/src/main/java/de/fanta/challenges/challenges/AllAdvancementsChallenge.java +++ b/src/main/java/de/fanta/challenges/challenges/AllAdvancementsChallenge.java @@ -1,31 +1,175 @@ package de.fanta.challenges.challenges; +import com.destroystokyo.paper.event.player.PlayerAdvancementCriterionGrantEvent; import de.fanta.challenges.Challenges; +import de.fanta.challenges.events.TimerChangedEvent; import de.fanta.challenges.utils.ChatUtil; import org.bukkit.Bukkit; +import org.bukkit.NamespacedKey; import org.bukkit.advancement.Advancement; import org.bukkit.advancement.AdvancementProgress; +import org.bukkit.boss.BarColor; +import org.bukkit.boss.BarStyle; +import org.bukkit.boss.BossBar; +import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerAdvancementDoneEvent; +import org.bukkit.event.player.PlayerJoinEvent; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; public class AllAdvancementsChallenge implements Listener { - Challenges plugin = Challenges.getPlugin(); + public static BossBar bossBar; + private static boolean running; + private static final Challenges plugin = Challenges.getPlugin(); + + @EventHandler + public void onActivation(TimerChangedEvent event) { + if (plugin.getConfig().getBoolean("alladvancements")) { + if (event.isRunning()) { + start(); + } else { + stop(); + } + } + } + @EventHandler public void onAdvancementDone(PlayerAdvancementDoneEvent e) { - if (plugin.getConfig().getBoolean("alladvancements")) { - Advancement advancement = e.getAdvancement(); - if (plugin.getAdvancements().contains(advancement)) { - ChatUtil.sendDebugMessage(e.getPlayer(), e.message()); + if (isRunning()) { + createAdvancementString(e.getPlayer()); + } + } - for (Player pp: Bukkit.getOnlinePlayers()) { - AdvancementProgress ap = pp.getAdvancementProgress(advancement); - ap.awardCriteria(advancement.getCriteria().toString()); + @EventHandler + public void onAdvancementCriteria(PlayerAdvancementCriterionGrantEvent e) { + if (isRunning()) { + createAdvancementString(e.getPlayer()); + } + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent e) { + if (!isRunning()) { + return; + } + bossBar.addPlayer(e.getPlayer()); + setAdvancementsToPlayer(); + } + + public static boolean isRunning() { + return running; + } + + public static void setRunning(boolean run) { + running = run; + } + + private static void updateBossbar() { + int done = countDone(); + String bossBarTitle = ChatUtil.GREEN + "(" + done + "/" + plugin.getAdvancements().size() + ") Advancements"; + if (bossBar == null) { + bossBar = Bukkit.createBossBar(bossBarTitle, BarColor.GREEN, BarStyle.SOLID); + } else { + bossBar.setTitle(bossBarTitle); + } + double progress = done * 100.0 / plugin.getAdvancements().size() / 100.0; + bossBar.setProgress(progress); + bossBar.setVisible(true); + } + + private void createAdvancementString(Player player) { + ConfigurationSection advancements = plugin.getConfig().createSection("advancements"); + ArrayList advancementsDone = new ArrayList<>(); + ConfigurationSection progress = advancements.createSection("progress"); + Iterator it = Bukkit.advancementIterator(); + while (it.hasNext()) { + Advancement a = it.next(); + NamespacedKey key = a.getKey(); + if (key.getNamespace().equals(NamespacedKey.MINECRAFT) && !key.getKey().startsWith("recipes/")) { + AdvancementProgress ap = player.getAdvancementProgress(a); + if (ap.isDone()) { + advancementsDone.add(key.getKey()); + } else { + Collection ac = ap.getAwardedCriteria(); + if (!ac.isEmpty()) { + progress.set(key.getKey(), new ArrayList<>(ac)); + } } } } + advancements.set("done", advancementsDone); + plugin.saveConfig(); + + setAdvancementsToPlayer(); + } + + private static void setAdvancementsToPlayer() { + if (plugin.getConfig().contains("advancements")) { + ConfigurationSection advancements = plugin.getConfig().getConfigurationSection("advancements"); + if (advancements != null) { + HashSet done = new HashSet<>(advancements.getStringList("done")); + ConfigurationSection progress = advancements.getConfigurationSection("progress"); + Iterator it = Bukkit.advancementIterator(); + while (it.hasNext()) { + Advancement a = it.next(); + NamespacedKey key = a.getKey(); + if (key.getNamespace().equals(NamespacedKey.MINECRAFT) && !key.getKey().startsWith("recipes/")) { + for (Player pp : plugin.getVanish().getPlayerListWithoutVanishPlayers()) { + AdvancementProgress ap = pp.getAdvancementProgress(a); + if (done.contains(key.getKey())) { + if (!ap.isDone()) { + for (String crit : ap.getRemainingCriteria()) { + ap.awardCriteria(crit); + } + } + } else if (progress.contains(key.getKey())) { + List parts = progress.getStringList(key.getKey()); + for (String part : parts) { + ap.awardCriteria(part); + } + } + } + } + } + } + } + updateBossbar(); + } + + private static int countDone() { + int i = 0; + ConfigurationSection advancements = plugin.getConfig().getConfigurationSection("advancements"); + if (advancements != null) { + HashSet done = new HashSet<>(advancements.getStringList("done")); + for (String ignored : done) { + i++; + } + } + return i; + } + + public static void start() { + setAdvancementsToPlayer(); + updateBossbar(); + for (Player pp : Bukkit.getOnlinePlayers()) { + bossBar.addPlayer(pp); + } + setRunning(true); + } + + public static void stop() { + if (bossBar != null) { + bossBar.removeAll(); + } + setRunning(false); } } diff --git a/src/main/java/de/fanta/challenges/guis/settingsgui/ChallengesGui.java b/src/main/java/de/fanta/challenges/guis/settingsgui/ChallengesGui.java index 03b586b..c1e8236 100644 --- a/src/main/java/de/fanta/challenges/guis/settingsgui/ChallengesGui.java +++ b/src/main/java/de/fanta/challenges/guis/settingsgui/ChallengesGui.java @@ -1,6 +1,7 @@ package de.fanta.challenges.guis.settingsgui; import de.fanta.challenges.Challenges; +import de.fanta.challenges.challenges.AllAdvancementsChallenge; import de.fanta.challenges.challenges.AllItemsChallenge; import de.fanta.challenges.challenges.WorldBorderLevelChallenge; import de.fanta.challenges.utils.ChatUtil; @@ -47,6 +48,7 @@ private static final int DAMAGE_ON_SNEAK_INDEX = 38; private static final int TIED_TOGETHER_INDEX = 39; private static final int MOB_REMOVE_WORLD_INDEX = 40; + private static final int ALL_ADVANCEMENT_INDEX = 41; public ChallengesGui(Player player) { super(player, Bukkit.createInventory(player, WINDOW_SIZE, plugin.getGUIPREFIX() + " >> Challenges")); @@ -266,6 +268,17 @@ GUIUtils.sendTitleToAll("Challenge", "Mobs entfernen Welt aktiviert", ChatUtil.GREEN); } } + case ALL_ADVANCEMENT_INDEX -> { + if (plugin.getConfig().getBoolean("alladvancements")) { + AllAdvancementsChallenge.start(); + GUIUtils.setConfig("alladvancements", false); + GUIUtils.sendTitleToAll("Challenge", "All Advancement deaktiviert", ChatUtil.RED); + } else { + AllAdvancementsChallenge.stop(); + GUIUtils.setConfig("alladvancements", true); + GUIUtils.sendTitleToAll("Challenge", "All Advancement aktiviert", ChatUtil.GREEN); + } + } default -> { } } @@ -439,6 +452,13 @@ item = GUIUtils.createGuiItem(Material.BLACK_CONCRETE, ChatUtil.RED + "Mobs entfernen Welt deaktiviert", ChatUtil.GREEN + "Monster und Tiere löschen hinter sich die Welt."); } } + case ALL_ADVANCEMENT_INDEX -> { + if (plugin.getConfig().getBoolean("alladvancements")) { + item = GUIUtils.createGuiItem(Material.KNOWLEDGE_BOOK, ChatUtil.GREEN + "All Advancement aktiviert", true); + } else { + item = GUIUtils.createGuiItem(Material.KNOWLEDGE_BOOK, ChatUtil.RED + "All Advancement deaktiviert"); + } + } default -> item = GUIUtils.EMPTY_ICON; } this.getInventory().setItem(i, item);