diff --git a/patches/api/0002-Player-GUI-API.patch b/patches/api/0002-Player-GUI-API.patch index 2872b7b..203029a 100644 --- a/patches/api/0002-Player-GUI-API.patch +++ b/patches/api/0002-Player-GUI-API.patch @@ -21,10 +21,10 @@ index 0000000000000000000000000000000000000000..cc0645aa27e6e96922f26242e71fef5d +public record ItemIcon(Function itemUpdate, Consumer onClick, int slot) {} diff --git a/src/main/java/me/samsuik/sakura/player/gui/PlayerGUI.java b/src/main/java/me/samsuik/sakura/player/gui/PlayerGUI.java new file mode 100644 -index 0000000000000000000000000000000000000000..1619a55dcdb8da143c82489419650f12dfbdf0a3 +index 0000000000000000000000000000000000000000..8eec1182c82ea9f1ca88998494280ad1d7b7d653 --- /dev/null +++ b/src/main/java/me/samsuik/sakura/player/gui/PlayerGUI.java -@@ -0,0 +1,114 @@ +@@ -0,0 +1,122 @@ +package me.samsuik.sakura.player.gui; + +import org.bukkit.entity.Player; @@ -70,6 +70,14 @@ index 0000000000000000000000000000000000000000..1619a55dcdb8da143c82489419650f12 + } + } + ++ protected void refreshSlot(Player player, int slot) { ++ Inventory inventory = player.getOpenInventory().getTopInventory(); ++ ++ if (inventory.getHolder() instanceof Holder && iconMap.containsKey(slot)) { ++ updateIcon(player, iconMap.get(slot), inventory); ++ } ++ } ++ + public void unregister() { + REGISTERED_GUIS.remove(this); + registered = false; @@ -95,7 +103,7 @@ index 0000000000000000000000000000000000000000..1619a55dcdb8da143c82489419650f12 + + if (icon != null) { + icon.onClick() -+ .andThen((p) -> updateIcon(player, icon, inventory)) ++ .andThen(p -> updateIcon(player, icon, inventory)) + .accept(player); + } + } diff --git a/patches/api/0003-Visibility-API.patch b/patches/api/0003-Visibility-API.patch index ad73f2f..b80c3aa 100644 --- a/patches/api/0003-Visibility-API.patch +++ b/patches/api/0003-Visibility-API.patch @@ -6,12 +6,16 @@ Subject: [PATCH] Visibility API diff --git a/src/main/java/me/samsuik/sakura/player/visibility/Visibility.java b/src/main/java/me/samsuik/sakura/player/visibility/Visibility.java new file mode 100644 -index 0000000000000000000000000000000000000000..01525d386e39709084344c5325793dacf41650fb +index 0000000000000000000000000000000000000000..3df11f07ce533b8b911ec423be850374fcc8a7c1 --- /dev/null +++ b/src/main/java/me/samsuik/sakura/player/visibility/Visibility.java -@@ -0,0 +1,141 @@ +@@ -0,0 +1,198 @@ +package me.samsuik.sakura.player.visibility; + ++import net.kyori.adventure.text.format.NamedTextColor; ++import net.kyori.adventure.text.format.TextColor; ++import org.bukkit.Material; ++ +import java.util.EnumSet; +import java.util.Locale; + @@ -57,9 +61,7 @@ index 0000000000000000000000000000000000000000..01525d386e39709084344c5325793dac + * @param setting provided + */ + public void toggle(Setting setting) { -+ if (settings.contains(setting)) { -+ settings.remove(setting); -+ } else { ++ if (!settings.remove(setting)) { + settings.add(setting); + } + } @@ -119,34 +121,89 @@ index 0000000000000000000000000000000000000000..01525d386e39709084344c5325793dac + return !settings.isEmpty(); + } + ++ /** ++ * Current visibility settings state. ++ * ++ * @return state ++ */ ++ public State getState() { ++ if (this.settings.isEmpty()) { ++ return State.ENABLED; ++ } else if (this.settings.size() != Setting.values().length) { ++ return State.MODIFIED; ++ } else { ++ return State.DISABLED; ++ } ++ } ++ + public enum Setting { -+ TNT_VISIBILITY("TNT Visibility", true), -+ SAND_VISIBILITY("Sand Visibility", true), -+ MINIMAL("Minimal TNT/Sand", false), -+ EXPLOSIONS("Explosion Particles", true), -+ ENCHANTMENT_GLINT("Enchantment Glint", true), -+ SPAWNERS("Spawner Visibility", true), -+ REDSTONE("Redstone Animations", true), -+ PISTONS("Piston Animations", true); ++ TNT_VISIBILITY("TNT Visibility", Material.TNT, NamedTextColor.RED, true), ++ SAND_VISIBILITY("Sand Visibility", Material.SAND, NamedTextColor.YELLOW, true), ++ MINIMAL("Minimal TNT/Sand", Material.NETHER_BRICK_SLAB, NamedTextColor.GOLD, false), ++ EXPLOSIONS("Explosion Particles", Material.COBWEB, NamedTextColor.WHITE, true), ++ ENCHANTMENT_GLINT("Enchantment Glint", Material.ENCHANTED_BOOK, NamedTextColor.DARK_PURPLE, true), ++ SPAWNERS("Spawner Visibility", Material.SPAWNER, NamedTextColor.DARK_GRAY, true), ++ REDSTONE("Redstone Animations", Material.REDSTONE, NamedTextColor.DARK_RED, true), ++ PISTONS("Piston Animations", Material.PISTON, NamedTextColor.GOLD, true); + + private final String friendlyName; ++ private final Material material; ++ private final TextColor colour; + private final boolean defaultValue; + -+ Setting(String friendlyName, boolean defaultValue) { ++ Setting(String friendlyName, Material material, TextColor color, boolean defaultValue) { + this.friendlyName = friendlyName; ++ this.material = material; ++ this.colour = color; + this.defaultValue = defaultValue; + } + + public boolean getDefault() { -+ return defaultValue; ++ return this.defaultValue; + } + + public String friendlyName() { -+ return friendlyName; ++ return this.friendlyName; ++ } ++ ++ public Material material() { ++ return this.material; ++ } ++ ++ public TextColor colour() { ++ return this.colour; + } + + public String basicName() { -+ return name().replace("_", "").toLowerCase(Locale.ROOT); ++ return this.name().replace("_", "").toLowerCase(Locale.ROOT); ++ } ++ } ++ ++ public enum State { ++ ENABLED("Enabled", Material.GREEN_STAINED_GLASS_PANE, NamedTextColor.GREEN), ++ MODIFIED("Modified", Material.MAGENTA_STAINED_GLASS_PANE, NamedTextColor.LIGHT_PURPLE), ++ DISABLED("Disabled", Material.RED_STAINED_GLASS_PANE, NamedTextColor.RED); ++ ++ private final String title; ++ private final Material material; ++ private final TextColor colour; ++ ++ State(String name, Material material, TextColor colour) { ++ this.title = name; ++ this.material = material; ++ this.colour = colour; ++ } ++ ++ public String title() { ++ return this.title; ++ } ++ ++ public Material material() { ++ return material; ++ } ++ ++ public TextColor colour() { ++ return colour; + } + } + diff --git a/patches/server/0005-Visibility-API-and-Command.patch b/patches/server/0005-Visibility-API-and-Command.patch index c4def9c..bf0310c 100644 --- a/patches/server/0005-Visibility-API-and-Command.patch +++ b/patches/server/0005-Visibility-API-and-Command.patch @@ -114,10 +114,10 @@ index 0000000000000000000000000000000000000000..148a583279333eeb3e5db16652623082 +} diff --git a/src/main/java/me/samsuik/sakura/player/visibility/VisibilityGUI.java b/src/main/java/me/samsuik/sakura/player/visibility/VisibilityGUI.java new file mode 100644 -index 0000000000000000000000000000000000000000..d61d47f9a473d072a160bc6b1cff8a8daf8929b6 +index 0000000000000000000000000000000000000000..6f74429456e78f17fa3e4426d9d9b5f008d8df42 --- /dev/null +++ b/src/main/java/me/samsuik/sakura/player/visibility/VisibilityGUI.java -@@ -0,0 +1,117 @@ +@@ -0,0 +1,123 @@ +package me.samsuik.sakura.player.visibility; + +import me.samsuik.sakura.configuration.GlobalConfiguration; @@ -125,7 +125,6 @@ index 0000000000000000000000000000000000000000..d61d47f9a473d072a160bc6b1cff8a8d +import me.samsuik.sakura.player.gui.PlayerGUI; +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.format.TextDecoration; +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; +import org.bukkit.Bukkit; @@ -168,45 +167,49 @@ index 0000000000000000000000000000000000000000..d61d47f9a473d072a160bc6b1cff8a8d + + @Override + protected void register() { -+ registerFPSIcon(Visibility.Setting.TNT_VISIBILITY, Material.TNT, NamedTextColor.RED, 12); -+ registerFPSIcon(Visibility.Setting.SAND_VISIBILITY, Material.SAND, NamedTextColor.YELLOW, 14); -+ registerFPSIcon(Visibility.Setting.MINIMAL, Material.NETHER_BRICK_SLAB, NamedTextColor.GOLD, 13); -+ registerFPSIcon(Visibility.Setting.SPAWNERS, Material.SPAWNER, NamedTextColor.DARK_GRAY, 20); -+ //registerFPSIcon(Visibility.Setting.FLASHING_TNT, Material.REDSTONE_LAMP, NamedTextColor.RED, 22); -+ registerFPSIcon(Visibility.Setting.EXPLOSIONS, Material.COBWEB, NamedTextColor.WHITE, 24); -+ registerFPSIcon(Visibility.Setting.PISTONS, Material.PISTON, NamedTextColor.GOLD, 30); -+ registerFPSIcon(Visibility.Setting.REDSTONE, Material.REDSTONE, NamedTextColor.DARK_RED, 31); -+ registerFPSIcon(Visibility.Setting.ENCHANTMENT_GLINT, Material.ENCHANTED_BOOK, NamedTextColor.DARK_PURPLE, 32); ++ registerFPSIcon(Visibility.Setting.TNT_VISIBILITY, 12); ++ registerFPSIcon(Visibility.Setting.SAND_VISIBILITY, 14); ++ registerFPSIcon(Visibility.Setting.MINIMAL, 13); ++ registerFPSIcon(Visibility.Setting.SPAWNERS, 20); ++ // ...22 ++ registerFPSIcon(Visibility.Setting.EXPLOSIONS, 24); ++ registerFPSIcon(Visibility.Setting.PISTONS, 30); ++ registerFPSIcon(Visibility.Setting.REDSTONE, 31); ++ registerFPSIcon(Visibility.Setting.ENCHANTMENT_GLINT, 32); + -+ registerIcon(new ItemIcon( -+ player -> { -+ ItemStack itemstack = new ItemStack(Material.GREEN_STAINED_GLASS_PANE); -+ Component title = Component.text("Toggle all", NamedTextColor.GREEN); -+ -+ itemstack.editMeta(meta -> meta.displayName(title.decoration(TextDecoration.ITALIC, false))); -+ return itemstack; -+ }, -+ player -> { -+ player.getVisibility().toggleAll(); ++ registerIcon(new ItemIcon(player -> { ++ Visibility.State state = player.getVisibility().getState(); ++ ItemStack itemstack = new ItemStack(state.material()); + -+ // refresh icons after toggling -+ this.refresh(player); -+ }, -+ 26 -+ )); ++ itemstack.editMeta(meta -> { ++ Component title = Component.text("Toggle all", state.colour()); ++ ++ // italic is default ++ title = title.decoration(TextDecoration.ITALIC, false); ++ ++ meta.displayName(title.append(Component.space()) ++ .append(Component.text(state.title(), NamedTextColor.GRAY))); ++ }); ++ ++ return itemstack; ++ }, player -> { ++ player.getVisibility().toggleAll(); ++ // refresh icons after toggling ++ this.refresh(player); ++ }, 26)); + } + -+ private void registerFPSIcon(Visibility.Setting setting, Material material, TextColor colour, int slot) { ++ private void registerFPSIcon(Visibility.Setting setting, int slot) { + registerIcon(new ItemIcon(player -> { + Visibility visibility = player.getVisibility(); -+ ItemStack itemstack = new ItemStack(material); ++ ItemStack itemstack = new ItemStack(setting.material()); + + itemstack.editMeta(meta -> { + // Get the current state as a string + String state = visibility.isEnabled(setting) ? "Enabled" : "Disabled"; + + // Friendly name as a component -+ Component title = Component.text(setting.friendlyName(), colour); ++ Component title = Component.text(setting.friendlyName(), setting.colour()); + + // Display names are italic by default + title = title.decoration(TextDecoration.ITALIC, false); @@ -231,6 +234,9 @@ index 0000000000000000000000000000000000000000..d61d47f9a473d072a160bc6b1cff8a8d + Placeholder.unparsed("name", setting.friendlyName()), + Placeholder.unparsed("state", state) + ); ++ ++ // Update toggle all icon ++ this.refreshSlot(player, 26); + }, slot)); + } +