From ac05767bad088bb798e68c09fa03fbbade01b958 Mon Sep 17 00:00:00 2001 From: TSERATO Date: Thu, 6 Nov 2025 21:46:04 +0100 Subject: [PATCH 1/7] Implemented feature from here: https://github.com/FancyInnovations/FancyPlugins/issues/86 --- .../fancynpcs/api/actions/types/NeedPermissionAction.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plugins/fancynpcs/fn-api/src/main/java/de/oliver/fancynpcs/api/actions/types/NeedPermissionAction.java b/plugins/fancynpcs/fn-api/src/main/java/de/oliver/fancynpcs/api/actions/types/NeedPermissionAction.java index 1f57ffcb..0c3eaadb 100644 --- a/plugins/fancynpcs/fn-api/src/main/java/de/oliver/fancynpcs/api/actions/types/NeedPermissionAction.java +++ b/plugins/fancynpcs/fn-api/src/main/java/de/oliver/fancynpcs/api/actions/types/NeedPermissionAction.java @@ -20,7 +20,13 @@ public void execute(ActionExecutionContext context, String value) { return; } - if (!context.getPlayer().hasPermission(value)) { + boolean invertCheck = value.startsWith("!"); + String permission = invertCheck ? value.substring(1) : value; + + boolean hasPermission = context.getPlayer().hasPermission(permission); + boolean passesCheck = invertCheck ? !hasPermission : hasPermission; + + if (!passesCheck) { FancyNpcsPlugin.get().getTranslator().translate("action_missing_permissions").send(context.getPlayer()); context.terminate(); } From 6c8661988e2dd2b607b8580a9ae1cedb0320baef Mon Sep 17 00:00:00 2001 From: TSERATO Date: Thu, 6 Nov 2025 22:11:04 +0100 Subject: [PATCH 2/7] Implemented feature from here: https://github.com/FancyInnovations/FancyPlugins/issues/50 --- .../fancynpcs/api/events/NpcModifyEvent.java | 1 + .../commands/CloudCommandManager.java | 1 + .../fancynpcs/commands/npc/RotateCMD.java | 43 +++++++++++++++++++ .../src/main/resources/languages/default.yml | 5 +++ 4 files changed, 50 insertions(+) create mode 100644 plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/commands/npc/RotateCMD.java diff --git a/plugins/fancynpcs/fn-api/src/main/java/de/oliver/fancynpcs/api/events/NpcModifyEvent.java b/plugins/fancynpcs/fn-api/src/main/java/de/oliver/fancynpcs/api/events/NpcModifyEvent.java index 202916d3..2e94499c 100644 --- a/plugins/fancynpcs/fn-api/src/main/java/de/oliver/fancynpcs/api/events/NpcModifyEvent.java +++ b/plugins/fancynpcs/fn-api/src/main/java/de/oliver/fancynpcs/api/events/NpcModifyEvent.java @@ -90,6 +90,7 @@ public enum NpcModification { LOCATION, MIRROR_SKIN, PLAYER_COMMAND, + ROTATION, SERVER_COMMAND, SHOW_IN_TAB, SKIN, diff --git a/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/commands/CloudCommandManager.java b/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/commands/CloudCommandManager.java index 15fcfde9..9a98ca8d 100644 --- a/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/commands/CloudCommandManager.java +++ b/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/commands/CloudCommandManager.java @@ -184,6 +184,7 @@ else if (exceptionContext.exception().enumClass() == GlowingColor.class) annotationParser.parse(NearbyCMD.INSTANCE); annotationParser.parse(HelpCMD.INSTANCE); annotationParser.parse(RemoveCMD.INSTANCE); + annotationParser.parse(RotateCMD.INSTANCE); annotationParser.parse(ShowInTabCMD.INSTANCE); annotationParser.parse(SkinCMD.INSTANCE); annotationParser.parse(TeleportCMD.INSTANCE); diff --git a/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/commands/npc/RotateCMD.java b/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/commands/npc/RotateCMD.java new file mode 100644 index 00000000..31a804d5 --- /dev/null +++ b/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/commands/npc/RotateCMD.java @@ -0,0 +1,43 @@ +package de.oliver.fancynpcs.commands.npc; + +import de.oliver.fancylib.translations.Translator; +import de.oliver.fancynpcs.FancyNpcs; +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.events.NpcModifyEvent; +import org.bukkit.Location; +import org.bukkit.command.CommandSender; +import org.incendo.cloud.annotations.Command; +import org.incendo.cloud.annotations.Permission; +import org.jetbrains.annotations.NotNull; + +public enum RotateCMD { + INSTANCE; + + private final Translator translator = FancyNpcs.getInstance().getTranslator(); + + @Command("npc rotate ") + @Permission("fancynpcs.command.npc.rotate") + public void onRotate( + final @NotNull CommandSender sender, + final @NotNull Npc npc, + final float yaw, + final float pitch + ) { + final Location currentLocation = npc.getData().getLocation(); + final Location newLocation = currentLocation.clone(); + newLocation.setYaw(yaw); + newLocation.setPitch(pitch); + + if (new NpcModifyEvent(npc, NpcModifyEvent.NpcModification.ROTATION, new float[]{yaw, pitch}, sender).callEvent()) { + npc.getData().setLocation(newLocation); + npc.updateForAll(); + translator.translate("npc_rotate_set_success") + .replace("npc", npc.getData().getName()) + .replace("yaw", String.valueOf(yaw)) + .replace("pitch", String.valueOf(pitch)) + .send(sender); + } else { + translator.translate("command_npc_modification_cancelled").send(sender); + } + } +} \ No newline at end of file diff --git a/plugins/fancynpcs/src/main/resources/languages/default.yml b/plugins/fancynpcs/src/main/resources/languages/default.yml index 2563765d..d3e217e1 100644 --- a/plugins/fancynpcs/src/main/resources/languages/default.yml +++ b/plugins/fancynpcs/src/main/resources/languages/default.yml @@ -123,6 +123,7 @@ messages: npc_move_to: "Syntax: {primaryColor}/npc move_to {secondaryColor}(npc) (x) (y) (z) [world]" npc_nearby: "Syntax: {primaryColor}/npc nearby {secondaryColor}[filters...]" npc_remove: "Syntax: {primaryColor}/npc remove {secondaryColor}(npc)" + npc_rotate: "Syntax: {primaryColor}/npc rotate {secondaryColor}(npc) (yaw) (pitch)" npc_show_in_tab: "Syntax: {primaryColor}/npc show_in_tab {secondaryColor}(npc) (state)" npc_skin: "Syntax: {primaryColor}/npc skin {secondaryColor}(npc) (@none | @mirror | name | uuid | placeholder | url | file name) [--slim]" npc_teleport: "Syntax: {primaryColor}/npc teleport {secondaryColor}(npc)" @@ -176,6 +177,7 @@ messages: - "Teleports NPC to specified location.'>{primaryColor}/npc move_to {secondaryColor}(npc) (x) (y) (z) [world]" - "Lists all NPCs in your world. Can be filtered and sorted.'>{primaryColor}/npc nearby {secondaryColor}[--radius] [--type] [--sort]" - "Removes (deletes) specified NPC.'>{primaryColor}/npc remove {secondaryColor}(npc)" + - "Changes the rotation (yaw and pitch) of the NPC.'>{primaryColor}/npc rotate {secondaryColor}(npc) (yaw) (pitch)" - "Changes the scale of the size of the NPC.'>{primaryColor}/npc scale {secondaryColor}(npc) (factor)" - "Changes whether the NPC is shown in the player-list. This works only on NPCs of PLAYER type.{errorColor}Re-connecting to the server might be required for changes to take effect.'>{primaryColor}/npc show_in_tab {secondaryColor}(npc) (state)" - "Changes skin of the NPC.Supports PlaceholderAPI and MiniPlaceholders.{warningColor}@none - removes the skin{warningColor}@mirror - mirrors player skin{warningColor}(name) - name of any player{warningColor}(url) - url of the skin texture'>{primaryColor}/npc skin {secondaryColor}(npc) (@none | @mirror | name | url) [--slim]" @@ -302,6 +304,9 @@ messages: # Commands (npc remove) npc_remove_success: "NPC {warningColor}{npc} has been removed." + # Commands (npc rotate) + npc_rotate_set_success: "NPC {warningColor}{npc} has been rotated to yaw {warningColor}{yaw} and pitch {warningColor}{pitch}." + # Commands (scale) npc_scale_set_success: "NPC {warningColor}{npc} has been scaled to {warningColor}{scale}." From 9a5b6a69144a0011c202a552cbc3a974aefc64e6 Mon Sep 17 00:00:00 2001 From: TSERATO Date: Fri, 7 Nov 2025 14:59:17 +0100 Subject: [PATCH 3/7] Add glowing feature from here: https://github.com/FancyInnovations/FancyPlugins/issues/48 --- .../api/data/DisplayHologramData.java | 45 +++++- .../api/events/HologramUpdateEvent.java | 4 +- .../fancyholograms/commands/HologramCMD.java | 4 +- .../commands/hologram/GlowingCMD.java | 130 ++++++++++++++++++ .../fancyholograms/hologram/HologramImpl.java | 24 ++++ .../storage/json/JsonAdapter.java | 16 ++- .../json/model/JsonDisplayHologramData.java | 4 +- .../fancyholograms/utils/GlowingColor.java | 50 +++++++ 8 files changed, 269 insertions(+), 8 deletions(-) create mode 100644 plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/hologram/GlowingCMD.java create mode 100644 plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/utils/GlowingColor.java diff --git a/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/data/DisplayHologramData.java b/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/data/DisplayHologramData.java index 8302d7d3..f83adb91 100644 --- a/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/data/DisplayHologramData.java +++ b/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/data/DisplayHologramData.java @@ -1,6 +1,7 @@ package com.fancyinnovations.fancyholograms.api.data; import com.fancyinnovations.fancyholograms.api.hologram.HologramType; +import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Location; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.Display; @@ -26,6 +27,8 @@ public class DisplayHologramData extends HologramData { private float shadowRadius = DEFAULT_SHADOW_RADIUS; private float shadowStrength = DEFAULT_SHADOW_STRENGTH; private int interpolationDuration = DEFAULT_INTERPOLATION_DURATION; + private boolean glowing = false; + private NamedTextColor glowingColor = NamedTextColor.WHITE; /** * @param name Name of hologram @@ -130,6 +133,32 @@ public DisplayHologramData setInterpolationDuration(int interpolationDuration) { return this; } + public boolean isGlowing() { + return glowing; + } + + public DisplayHologramData setGlowing(boolean glowing) { + if (this.glowing != glowing) { + this.glowing = glowing; + setHasChanges(true); + } + + return this; + } + + public NamedTextColor getGlowingColor() { + return glowingColor; + } + + public DisplayHologramData setGlowingColor(NamedTextColor glowingColor) { + if (!Objects.equals(this.glowingColor, glowingColor)) { + this.glowingColor = glowingColor; + setHasChanges(true); + } + + return this; + } + @Override @ApiStatus.Internal public boolean read(ConfigurationSection section, String name) { @@ -167,6 +196,9 @@ public boolean read(ConfigurationSection section, String name) { ); } + glowing = section.getBoolean("glowing", false); + glowingColor = NamedTextColor.NAMES.value(section.getString("glowing_color", "white")); + return true; } @@ -189,6 +221,8 @@ public boolean write(ConfigurationSection section, String name) { } section.set("billboard", billboard != Display.Billboard.CENTER ? billboard.name().toLowerCase(Locale.ROOT) : null); + section.set("glowing", glowing); + section.set("glowing_color", glowingColor.toString()); return true; } @@ -203,10 +237,13 @@ public DisplayHologramData copy(String name) { .setBillboard(this.getBillboard()) .setTranslation(this.getTranslation()) .setBrightness(this.getBrightness()) - .setVisibilityDistance(this.getVisibilityDistance()) - .setVisibility(this.getVisibility()) - .setPersistent(this.isPersistent()) - .setLinkedNpcName(this.getLinkedNpcName()); + .setGlowing(this.isGlowing()) + .setGlowingColor(this.getGlowingColor()); + + displayHologramData.setVisibilityDistance(this.getVisibilityDistance()); + displayHologramData.setVisibility(this.getVisibility()); + displayHologramData.setPersistent(this.isPersistent()); + displayHologramData.setLinkedNpcName(this.getLinkedNpcName()); return displayHologramData; } diff --git a/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/events/HologramUpdateEvent.java b/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/events/HologramUpdateEvent.java index 8799fc4a..94303d49 100644 --- a/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/events/HologramUpdateEvent.java +++ b/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/events/HologramUpdateEvent.java @@ -82,7 +82,9 @@ public enum HologramModification { SHADOW_RADIUS, SHADOW_STRENGTH, UPDATE_TEXT_INTERVAL, - UPDATE_VISIBILITY_DISTANCE; + UPDATE_VISIBILITY_DISTANCE, + GLOWING, + GLOWING_COLOR; } } diff --git a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/HologramCMD.java b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/HologramCMD.java index 88922c2f..b34d623f 100644 --- a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/HologramCMD.java +++ b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/HologramCMD.java @@ -192,7 +192,7 @@ public boolean execute(@NotNull CommandSender sender, @NotNull String label, @No final var usingNpcs = PluginUtils.isFancyNpcsEnabled(); - List suggestions = new ArrayList<>(Arrays.asList("traits", "position", "moveHere", "center", "moveTo", "rotate", "rotatepitch", "billboard", "scale", "translate", "visibilityDistance", "visibility", "shadowRadius", "shadowStrength", "brightness", usingNpcs ? "linkWithNpc" : "", usingNpcs ? "unlinkWithNpc" : "")); + List suggestions = new ArrayList<>(Arrays.asList("traits", "position", "moveHere", "center", "moveTo", "rotate", "rotatepitch", "billboard", "scale", "translate", "visibilityDistance", "visibility", "shadowRadius", "shadowStrength", "brightness", "glowing", usingNpcs ? "linkWithNpc" : "", usingNpcs ? "unlinkWithNpc" : "")); suggestions.addAll(type.getCommands()); return suggestions.stream().filter(input -> input.toLowerCase().startsWith(args[2].toLowerCase(Locale.ROOT))).toList(); @@ -256,6 +256,7 @@ public boolean execute(@NotNull CommandSender sender, @NotNull String label, @No case "block" -> Arrays.stream(Material.values()).filter(Material::isBlock).map(Enum::name); case "seethrough" -> Stream.of("true", "false"); case "visibility" -> new VisibilityCMD().tabcompletion(sender, hologram, args).stream(); + case "glowing" -> new GlowingCMD().tabcompletion(sender, hologram, args).stream(); default -> null; }; @@ -364,6 +365,7 @@ private boolean edit(@NotNull final CommandSender player, @NotNull final Hologra case "shadowradius" -> new ShadowRadiusCMD().run(player, hologram, args); case "shadowstrength" -> new ShadowStrengthCMD().run(player, hologram, args); case "brightness" -> new BrightnessCMD().run(player, hologram, args); + case "glowing" -> new GlowingCMD().run(player, hologram, args); // text data case "background" -> new BackgroundCMD().run(player, hologram, args); diff --git a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/hologram/GlowingCMD.java b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/hologram/GlowingCMD.java new file mode 100644 index 00000000..44170896 --- /dev/null +++ b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/hologram/GlowingCMD.java @@ -0,0 +1,130 @@ +package com.fancyinnovations.fancyholograms.commands.hologram; + +import com.fancyinnovations.fancyholograms.api.data.DisplayHologramData; +import com.fancyinnovations.fancyholograms.api.events.HologramUpdateEvent; +import com.fancyinnovations.fancyholograms.api.hologram.Hologram; +import com.fancyinnovations.fancyholograms.commands.HologramCMD; +import com.fancyinnovations.fancyholograms.commands.Subcommand; +import com.fancyinnovations.fancyholograms.main.FancyHologramsPlugin; +import com.fancyinnovations.fancyholograms.utils.GlowingColor; +import de.oliver.fancylib.MessageHelper; +import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; +import java.util.List; +import java.util.Locale; +import java.util.Objects; +import java.util.stream.Collectors; + +public class GlowingCMD implements Subcommand { + + @Override + public List tabcompletion(@NotNull CommandSender player, @Nullable Hologram hologram, @NotNull String[] args) { + if (args.length == 4) { + return Arrays.stream(GlowingColor.values()) + .map(color -> color.name().toLowerCase(Locale.ROOT)) + .collect(Collectors.toList()); + } + return null; + } + + @Override + public boolean run(@NotNull CommandSender player, @Nullable Hologram hologram, @NotNull String[] args) { + if (!(player.hasPermission("fancyholograms.hologram.edit.glowing"))) { + MessageHelper.error(player, "You don't have the required permission to change the glowing of a hologram"); + return false; + } + + if (!(hologram.getData() instanceof DisplayHologramData displayData)) { + MessageHelper.error(player, "This command can only be used on display holograms"); + return false; + } + + if (hologram.getData().getType() == com.fancyinnovations.fancyholograms.api.hologram.HologramType.TEXT) { + MessageHelper.error(player, "You can only make item and block holograms glow"); + return false; + } + + if (args.length == 3) { + final var copied = displayData.copy(displayData.getName()); + copied.setGlowing(!displayData.isGlowing()); + + if (!HologramCMD.callModificationEvent(hologram, player, copied, HologramUpdateEvent.HologramModification.GLOWING)) { + return false; + } + + displayData.setGlowing(copied.isGlowing()); + + if (FancyHologramsPlugin.get().getHologramConfiguration().isSaveOnChangedEnabled()) { + FancyHologramsPlugin.get().getStorage().save(hologram.getData()); + } + + MessageHelper.success(player, "Toggled glowing " + (displayData.isGlowing() ? "on" : "off")); + return true; + } + + final var colorArg = args[3].toLowerCase(Locale.ROOT); + + if (colorArg.equals("disabled")) { + final var copied = displayData.copy(displayData.getName()); + copied.setGlowing(false); + + if (!HologramCMD.callModificationEvent(hologram, player, copied, HologramUpdateEvent.HologramModification.GLOWING)) { + return false; + } + + displayData.setGlowing(false); + + if (FancyHologramsPlugin.get().getHologramConfiguration().isSaveOnChangedEnabled()) { + FancyHologramsPlugin.get().getStorage().save(hologram.getData()); + } + + MessageHelper.success(player, "Disabled glowing"); + return true; + } + + NamedTextColor color; + try { + GlowingColor glowingColor = GlowingColor.valueOf(colorArg.toUpperCase(Locale.ROOT)); + color = glowingColor.getColor(); + if (color == null) { + MessageHelper.error(player, "Could not parse glowing color"); + return false; + } + } catch (IllegalArgumentException e) { + MessageHelper.error(player, "Could not parse glowing color"); + return false; + } + + if (Objects.equals(color, displayData.getGlowingColor()) && displayData.isGlowing()) { + MessageHelper.warning(player, "This hologram already has this glowing color"); + return false; + } + + final var copied = displayData.copy(displayData.getName()); + copied.setGlowingColor(color); + copied.setGlowing(true); + + if (!HologramCMD.callModificationEvent(hologram, player, copied, HologramUpdateEvent.HologramModification.GLOWING_COLOR)) { + return false; + } + + if (Objects.equals(copied.getGlowingColor(), displayData.getGlowingColor()) && displayData.isGlowing()) { + MessageHelper.warning(player, "This hologram already has this glowing color"); + return false; + } + + displayData.setGlowingColor(copied.getGlowingColor()); + displayData.setGlowing(true); + + if (FancyHologramsPlugin.get().getHologramConfiguration().isSaveOnChangedEnabled()) { + FancyHologramsPlugin.get().getStorage().save(hologram.getData()); + } + + MessageHelper.success(player, "Changed glowing color"); + return true; + } +} \ No newline at end of file diff --git a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/hologram/HologramImpl.java b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/hologram/HologramImpl.java index 2774f722..8f33252e 100644 --- a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/hologram/HologramImpl.java +++ b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/hologram/HologramImpl.java @@ -194,6 +194,30 @@ private void syncWithData() { fsDisplay.setShadowStrength(displayData.getShadowStrength()); fsDisplay.setViewRange(displayData.getVisibilityDistance()); + + if (displayData.isGlowing()) { + int rgb = displayData.getGlowingColor().value() & 0xFFFFFF; + int argb = 0xFF000000 | rgb; + fsDisplay.setGlowColorOverride(argb); + + byte flags = 0x40; + try { + byte currentFlags = fsDisplay.getSharedFlags(); + flags = (byte) (currentFlags | 0x40); + } catch (NullPointerException ignored) { + } + fsDisplay.setSharedFlags(flags); + } else { + fsDisplay.setGlowColorOverride(-1); + + byte flags = 0; + try { + byte currentFlags = fsDisplay.getSharedFlags(); + flags = (byte) (currentFlags & ~0x40); + } catch (NullPointerException ignored) { + } + fsDisplay.setSharedFlags(flags); + } } } diff --git a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/storage/json/JsonAdapter.java b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/storage/json/JsonAdapter.java index 06b11474..59bf54d3 100644 --- a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/storage/json/JsonAdapter.java +++ b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/storage/json/JsonAdapter.java @@ -6,6 +6,7 @@ import com.fancyinnovations.fancyholograms.api.trait.HologramTraitRegistry; import com.fancyinnovations.fancyholograms.storage.json.model.*; import de.oliver.fancyanalytics.logger.properties.ThrowableProperty; +import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; @@ -57,7 +58,9 @@ public static JsonDisplayHologramData displayHologramDataToJson(com.fancyinnovat data.getBrightness().getBlockLight(), data.getBrightness().getSkyLight() ), - data.getBillboard() + data.getBillboard(), + data.isGlowing(), + data.getGlowingColor().toString() ); } @@ -158,6 +161,11 @@ public static com.fancyinnovations.fancyholograms.api.data.HologramData fromJson ); } + boolean glowing = data.display_data().glowing() != null && data.display_data().glowing(); + NamedTextColor glowingColor = data.display_data().glowing_color() != null + ? NamedTextColor.NAMES.value(data.display_data().glowing_color()) + : NamedTextColor.WHITE; + HologramData hologramData = switch (data.hologram_data().type()) { case TEXT -> new com.fancyinnovations.fancyholograms.api.data.TextHologramData(data.hologram_data().name(), loc) @@ -173,6 +181,8 @@ public static com.fancyinnovations.fancyholograms.api.data.HologramData fromJson .setBrightness(brightness) .setShadowRadius(data.display_data().shadow_radius()) .setShadowStrength(data.display_data().shadow_strength()) + .setGlowing(glowing) + .setGlowingColor(glowingColor) .setWorldName(data.hologram_data().worldName())// hologram data .setVisibilityDistance(data.hologram_data().visibilityDistance()) .setVisibility(data.hologram_data().visibility()) @@ -187,6 +197,8 @@ public static com.fancyinnovations.fancyholograms.api.data.HologramData fromJson .setBrightness(brightness) .setShadowRadius(data.display_data().shadow_radius()) .setShadowStrength(data.display_data().shadow_strength()) + .setGlowing(glowing) + .setGlowingColor(glowingColor) .setWorldName(data.hologram_data().worldName())// hologram data .setVisibilityDistance(data.hologram_data().visibilityDistance()) .setVisibility(data.hologram_data().visibility()) @@ -200,6 +212,8 @@ public static com.fancyinnovations.fancyholograms.api.data.HologramData fromJson .setBrightness(brightness) .setShadowRadius(data.display_data().shadow_radius()) .setShadowStrength(data.display_data().shadow_strength()) + .setGlowing(glowing) + .setGlowingColor(glowingColor) .setWorldName(data.hologram_data().worldName())// hologram data .setVisibilityDistance(data.hologram_data().visibilityDistance()) .setVisibility(data.hologram_data().visibility()) diff --git a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/storage/json/model/JsonDisplayHologramData.java b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/storage/json/model/JsonDisplayHologramData.java index cc6db4a7..23afa620 100644 --- a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/storage/json/model/JsonDisplayHologramData.java +++ b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/storage/json/model/JsonDisplayHologramData.java @@ -8,7 +8,9 @@ public record JsonDisplayHologramData( Float shadow_radius, Float shadow_strength, JsonBrightness brightness, - Display.Billboard billboard + Display.Billboard billboard, + Boolean glowing, + String glowing_color ) { } diff --git a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/utils/GlowingColor.java b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/utils/GlowingColor.java new file mode 100644 index 00000000..7f5d4d72 --- /dev/null +++ b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/utils/GlowingColor.java @@ -0,0 +1,50 @@ +package com.fancyinnovations.fancyholograms.utils; + +import net.kyori.adventure.text.format.NamedTextColor; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public enum GlowingColor { + DISABLED(null, ""), + BLACK(NamedTextColor.BLACK, "color_black"), + DARK_BLUE(NamedTextColor.DARK_BLUE, "color_dark_blue"), + DARK_GREEN(NamedTextColor.DARK_GREEN, "color_dark_green"), + DARK_AQUA(NamedTextColor.DARK_AQUA, "color_dark_aqua"), + DARK_RED(NamedTextColor.DARK_RED, "color_dark_red"), + DARK_PURPLE(NamedTextColor.DARK_PURPLE, "color_dark_purple"), + GOLD(NamedTextColor.GOLD, "color_gold"), + GRAY(NamedTextColor.GRAY, "color_gray"), + DARK_GRAY(NamedTextColor.DARK_GRAY, "color_dark_gray"), + BLUE(NamedTextColor.BLUE, "color_blue"), + GREEN(NamedTextColor.GREEN, "color_green"), + AQUA(NamedTextColor.AQUA, "color_aqua"), + RED(NamedTextColor.RED, "color_red"), + LIGHT_PURPLE(NamedTextColor.LIGHT_PURPLE, "color_light_purple"), + YELLOW(NamedTextColor.YELLOW, "color_yellow"), + WHITE(NamedTextColor.WHITE, "color_white"); + + private final @Nullable NamedTextColor color; + private final @NotNull String translationKey; + + GlowingColor(final @Nullable NamedTextColor color, final @NotNull String translationKey) { + this.color = color; + this.translationKey = translationKey; + } + + public @Nullable NamedTextColor getColor() { + return color; + } + + public @NotNull String getTranslationKey() { + return translationKey; + } + + public static @NotNull GlowingColor fromAdventure(final @NotNull NamedTextColor color) { + for (final GlowingColor glowingColor : GlowingColor.values()) + if (glowingColor.color != null && glowingColor.color.value() == color.value()) + return glowingColor; + throw new IllegalArgumentException("UNSUPPORTED COLOR"); + } + +} \ No newline at end of file From db64f230ac4863a0e58d54493ee1f39c5af53dde Mon Sep 17 00:00:00 2001 From: TSERATO Date: Fri, 7 Nov 2025 15:50:30 +0100 Subject: [PATCH 4/7] Implemented feature from here: https://github.com/FancyInnovations/FancyPlugins/issues/46 --- .../api/data/TextHologramData.java | 18 +++++ .../api/events/HologramUpdateEvent.java | 1 + .../api/hologram/HologramType.java | 2 +- .../fancyholograms/commands/HologramCMD.java | 2 + .../commands/hologram/OpacityCMD.java | 80 +++++++++++++++++++ .../fancyholograms/hologram/HologramImpl.java | 1 + 6 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/hologram/OpacityCMD.java diff --git a/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/data/TextHologramData.java b/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/data/TextHologramData.java index 06150ff4..12e6cd00 100644 --- a/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/data/TextHologramData.java +++ b/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/data/TextHologramData.java @@ -21,6 +21,7 @@ public class TextHologramData extends DisplayHologramData { public static final boolean DEFAULT_TEXT_SHADOW_STATE = false; public static final boolean DEFAULT_SEE_THROUGH = false; public static final int DEFAULT_TEXT_UPDATE_INTERVAL = -1; + public static final byte DEFAULT_TEXT_OPACITY = (byte) 255; private List text = new ArrayList<>(DEFAULT_TEXT); private Color background = null; @@ -28,6 +29,7 @@ public class TextHologramData extends DisplayHologramData { private boolean textShadow = DEFAULT_TEXT_SHADOW_STATE; private boolean seeThrough = DEFAULT_SEE_THROUGH; private int textUpdateInterval = DEFAULT_TEXT_UPDATE_INTERVAL; + private byte textOpacity = DEFAULT_TEXT_OPACITY; /** * @param name Name of hologram @@ -150,6 +152,19 @@ public TextHologramData setTextUpdateInterval(int textUpdateInterval) { return this; } + public byte getTextOpacity() { + return textOpacity; + } + + public TextHologramData setTextOpacity(byte textOpacity) { + if (this.textOpacity != textOpacity) { + this.textOpacity = textOpacity; + setHasChanges(true); + } + + return this; + } + @Override @ApiStatus.Internal public boolean read(ConfigurationSection section, String name) { @@ -163,6 +178,7 @@ public boolean read(ConfigurationSection section, String name) { textShadow = section.getBoolean("text_shadow", DEFAULT_TEXT_SHADOW_STATE); seeThrough = section.getBoolean("see_through", DEFAULT_SEE_THROUGH); textUpdateInterval = section.getInt("update_text_interval", DEFAULT_TEXT_UPDATE_INTERVAL); + textOpacity = (byte) section.getInt("text_opacity", DEFAULT_TEXT_OPACITY); String textAlignmentStr = section.getString("text_alignment", DEFAULT_TEXT_ALIGNMENT.name().toLowerCase()); textAlignment = switch (textAlignmentStr.toLowerCase(Locale.ROOT)) { @@ -197,6 +213,7 @@ public boolean write(ConfigurationSection section, String name) { section.set("see_through", seeThrough); section.set("text_alignment", textAlignment.name().toLowerCase(Locale.ROOT)); section.set("update_text_interval", textUpdateInterval); + section.set("text_opacity", textOpacity); final String color; if (background == null) { @@ -223,6 +240,7 @@ public TextHologramData copy(String name) { .setTextShadow(this.hasTextShadow()) .setSeeThrough(this.isSeeThrough()) .setTextUpdateInterval(this.getTextUpdateInterval()) + .setTextOpacity(this.getTextOpacity()) .setScale(this.getScale()) .setShadowRadius(this.getShadowRadius()) .setShadowStrength(this.getShadowStrength()) diff --git a/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/events/HologramUpdateEvent.java b/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/events/HologramUpdateEvent.java index 94303d49..4ed86a8a 100644 --- a/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/events/HologramUpdateEvent.java +++ b/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/events/HologramUpdateEvent.java @@ -78,6 +78,7 @@ public enum HologramModification { BACKGROUND, TEXT_SHADOW, TEXT_ALIGNMENT, + TEXT_OPACITY, SEE_THROUGH, SHADOW_RADIUS, SHADOW_STRENGTH, diff --git a/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/hologram/HologramType.java b/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/hologram/HologramType.java index a004de3c..a21aa8b7 100644 --- a/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/hologram/HologramType.java +++ b/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/hologram/HologramType.java @@ -4,7 +4,7 @@ import java.util.List; public enum HologramType { - TEXT(Arrays.asList("background", "textshadow", "textalignment", "seethrough", "setline", "removeline", "addline", "insertbefore", "insertafter", "updatetextinterval")), + TEXT(Arrays.asList("background", "textshadow", "textalignment", "opacity", "seethrough", "setline", "removeline", "addline", "insertbefore", "insertafter", "updatetextinterval")), ITEM(List.of("item")), BLOCK(List.of("block")); diff --git a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/HologramCMD.java b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/HologramCMD.java index b34d623f..71474a04 100644 --- a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/HologramCMD.java +++ b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/HologramCMD.java @@ -49,6 +49,7 @@ public final class HologramCMD extends Command { <%primary_color%>- /hologram edit background - Changes the background of the hologram <%primary_color%>- /hologram edit textShadow - Enables/disables the text shadow <%primary_color%>- /hologram edit textAlignment - Sets the text alignment + <%primary_color%>- /hologram edit opacity <0-100> - Changes the opacity of the text hologram <%primary_color%>- /hologram edit seeThrough - Enables/disables whether the text can be seen through blocks <%primary_color%>- /hologram edit shadowRadius - Changes the shadow radius of the hologram <%primary_color%>- /hologram edit shadowStrength - Changes the shadow strength of the hologram @@ -376,6 +377,7 @@ private boolean edit(@NotNull final CommandSender player, @NotNull final Hologra case "insertafter" -> new InsertAfterCMD().run(player, hologram, args); case "textshadow" -> new TextShadowCMD().run(player, hologram, args); case "textalignment" -> new TextAlignmentCMD().run(player, hologram, args); + case "opacity" -> new OpacityCMD().run(player, hologram, args); case "seethrough" -> new SeeThroughCMD().run(player, hologram, args); // block data diff --git a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/hologram/OpacityCMD.java b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/hologram/OpacityCMD.java new file mode 100644 index 00000000..f09fdcd2 --- /dev/null +++ b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/hologram/OpacityCMD.java @@ -0,0 +1,80 @@ +package com.fancyinnovations.fancyholograms.commands.hologram; + +import com.fancyinnovations.fancyholograms.api.data.TextHologramData; +import com.fancyinnovations.fancyholograms.api.events.HologramUpdateEvent; +import com.fancyinnovations.fancyholograms.api.hologram.Hologram; +import com.fancyinnovations.fancyholograms.commands.HologramCMD; +import com.fancyinnovations.fancyholograms.commands.Subcommand; +import com.fancyinnovations.fancyholograms.main.FancyHologramsPlugin; +import com.fancyinnovations.fancyholograms.util.NumberHelper; +import de.oliver.fancylib.MessageHelper; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class OpacityCMD implements Subcommand { + + @Override + public List tabcompletion(@NotNull CommandSender player, @Nullable Hologram hologram, @NotNull String[] args) { + return null; + } + + @Override + public boolean run(@NotNull CommandSender player, @Nullable Hologram hologram, @NotNull String[] args) { + + if (!(player.hasPermission("fancyholograms.hologram.edit.opacity"))) { + MessageHelper.error(player, "You don't have the required permission to edit a hologram"); + return false; + } + + if (!(hologram.getData() instanceof TextHologramData textData)) { + MessageHelper.error(player, "This command can only be used on text holograms"); + return false; + } + + final var parsedNumber = NumberHelper.parseInt(args[3]); + + if (parsedNumber.isEmpty()) { + MessageHelper.error(player, "Invalid opacity value."); + return false; + } + + final int opacityPercentage = parsedNumber.get(); + + if (opacityPercentage < 0 || opacityPercentage > 100) { + MessageHelper.error(player, "Invalid opacity value, must be between 0 and 100"); + return false; + } + + // Convert percentage (0-100) to byte value (0-255) + final byte opacity = (byte) Math.round(opacityPercentage * 255.0 / 100.0); + + if (opacity == textData.getTextOpacity()) { + MessageHelper.warning(player, "This hologram already has opacity set to " + opacityPercentage + "%"); + return false; + } + + final var copied = textData.copy(textData.getName()); + copied.setTextOpacity(opacity); + + if (!HologramCMD.callModificationEvent(hologram, player, copied, HologramUpdateEvent.HologramModification.TEXT_OPACITY)) { + return false; + } + + if (opacity == textData.getTextOpacity()) { + MessageHelper.warning(player, "This hologram already has opacity set to " + opacityPercentage + "%"); + return false; + } + + textData.setTextOpacity(copied.getTextOpacity()); + + if (FancyHologramsPlugin.get().getHologramConfiguration().isSaveOnChangedEnabled()) { + FancyHologramsPlugin.get().getStorage().save(hologram.getData()); + } + + MessageHelper.success(player, "Changed text opacity to " + opacityPercentage + "%"); + return true; + } +} diff --git a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/hologram/HologramImpl.java b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/hologram/HologramImpl.java index 8f33252e..1c00df78 100644 --- a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/hologram/HologramImpl.java +++ b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/hologram/HologramImpl.java @@ -151,6 +151,7 @@ private void syncWithData() { textDisplay.setStyleFlags((byte) 0); textDisplay.setShadow(textData.hasTextShadow()); textDisplay.setSeeThrough(textData.isSeeThrough()); + textDisplay.setTextOpacity(textData.getTextOpacity()); switch (textData.getTextAlignment()) { case LEFT -> textDisplay.setAlignLeft(true); From 5bc0239393dfed3ef296a75ce5f7519b876f3d7c Mon Sep 17 00:00:00 2001 From: TSERATO Date: Fri, 7 Nov 2025 19:29:48 +0100 Subject: [PATCH 5/7] Added missing json storage for opacity value --- .../fancyholograms/storage/json/JsonAdapter.java | 7 +++++++ .../storage/json/model/JsonTextHologramData.java | 1 + 2 files changed, 8 insertions(+) diff --git a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/storage/json/JsonAdapter.java b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/storage/json/JsonAdapter.java index 59bf54d3..46473817 100644 --- a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/storage/json/JsonAdapter.java +++ b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/storage/json/JsonAdapter.java @@ -65,12 +65,16 @@ public static JsonDisplayHologramData displayHologramDataToJson(com.fancyinnovat } public static JsonTextHologramData textHologramDataToJson(com.fancyinnovations.fancyholograms.api.data.TextHologramData data) { + // Convert byte (0-255) to percentage (0-100) + int opacityPercentage = Math.round(((int) data.getTextOpacity() & 0xFF) * 100.0f / 255.0f); + return new JsonTextHologramData( data.getText(), data.hasTextShadow(), data.isSeeThrough(), data.getTextAlignment(), data.getTextUpdateInterval(), + opacityPercentage, data.getBackground() == null ? "" : "#" + Integer.toHexString(data.getBackground().asARGB()) ); } @@ -175,6 +179,9 @@ public static com.fancyinnovations.fancyholograms.api.data.HologramData fromJson .setTextShadow(data.text_data().text_shadow()) .setSeeThrough(data.text_data().see_through()) .setTextUpdateInterval(data.text_data().text_update_interval()) + .setTextOpacity(data.text_data().text_opacity() != null + ? (byte) Math.round(data.text_data().text_opacity() * 255.0 / 100.0) + : (byte) 255) .setBillboard(data.display_data().billboard()) // display data .setScale(scale) .setTranslation(translation) diff --git a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/storage/json/model/JsonTextHologramData.java b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/storage/json/model/JsonTextHologramData.java index 0fcb6a52..7fec3728 100644 --- a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/storage/json/model/JsonTextHologramData.java +++ b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/storage/json/model/JsonTextHologramData.java @@ -10,6 +10,7 @@ public record JsonTextHologramData( Boolean see_through, TextDisplay.TextAlignment text_alignment, Integer text_update_interval, + Integer text_opacity, String background_color ) { } From 969618ddc382d47e60649159baa396ed5de0901b Mon Sep 17 00:00:00 2001 From: TSERATO Date: Fri, 7 Nov 2025 20:04:37 +0100 Subject: [PATCH 6/7] Added blockstate command suggested here: https://github.com/FancyInnovations/FancyPlugins/issues/43 --- .../api/data/BlockHologramData.java | 17 ++ .../api/events/HologramUpdateEvent.java | 4 +- .../api/hologram/HologramType.java | 2 +- .../fancyholograms/commands/HologramCMD.java | 2 + .../commands/hologram/BlockStateCMD.java | 180 ++++++++++++++++++ .../fancyholograms/hologram/HologramImpl.java | 17 +- .../storage/json/JsonAdapter.java | 4 +- .../json/model/JsonBlockHologramData.java | 3 +- 8 files changed, 222 insertions(+), 7 deletions(-) create mode 100644 plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/hologram/BlockStateCMD.java diff --git a/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/data/BlockHologramData.java b/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/data/BlockHologramData.java index 5cce7520..81bf776d 100644 --- a/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/data/BlockHologramData.java +++ b/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/data/BlockHologramData.java @@ -13,6 +13,7 @@ public class BlockHologramData extends DisplayHologramData { public static Material DEFAULT_BLOCK = Material.GRASS_BLOCK; private Material block = DEFAULT_BLOCK; + private String blockState = null; /** * @param name Name of hologram @@ -36,11 +37,25 @@ public BlockHologramData setBlock(Material block) { return this; } + public String getBlockState() { + return blockState; + } + + public BlockHologramData setBlockState(String blockState) { + if (!Objects.equals(this.blockState, blockState)) { + this.blockState = blockState; + setHasChanges(true); + } + + return this; + } + @Override @ApiStatus.Internal public boolean read(ConfigurationSection section, String name) { super.read(section, name); block = Material.getMaterial(section.getString("block", "GRASS_BLOCK").toUpperCase()); + blockState = section.getString("block_state", null); return true; } @@ -50,6 +65,7 @@ public boolean read(ConfigurationSection section, String name) { public boolean write(ConfigurationSection section, String name) { super.write(section, name); section.set("block", block.name()); + section.set("block_state", blockState); return true; } @@ -59,6 +75,7 @@ public BlockHologramData copy(String name) { BlockHologramData blockHologramData = new BlockHologramData(name, getLocation()); blockHologramData .setBlock(this.getBlock()) + .setBlockState(this.getBlockState()) .setScale(this.getScale()) .setShadowRadius(this.getShadowRadius()) .setShadowStrength(this.getShadowStrength()) diff --git a/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/events/HologramUpdateEvent.java b/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/events/HologramUpdateEvent.java index 4ed86a8a..c18a112e 100644 --- a/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/events/HologramUpdateEvent.java +++ b/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/events/HologramUpdateEvent.java @@ -85,7 +85,9 @@ public enum HologramModification { UPDATE_TEXT_INTERVAL, UPDATE_VISIBILITY_DISTANCE, GLOWING, - GLOWING_COLOR; + GLOWING_COLOR, + BLOCK, + BLOCK_STATE; } } diff --git a/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/hologram/HologramType.java b/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/hologram/HologramType.java index a21aa8b7..8fb3eb70 100644 --- a/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/hologram/HologramType.java +++ b/plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/hologram/HologramType.java @@ -6,7 +6,7 @@ public enum HologramType { TEXT(Arrays.asList("background", "textshadow", "textalignment", "opacity", "seethrough", "setline", "removeline", "addline", "insertbefore", "insertafter", "updatetextinterval")), ITEM(List.of("item")), - BLOCK(List.of("block")); + BLOCK(Arrays.asList("block", "blockstate")); private final List commands; diff --git a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/HologramCMD.java b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/HologramCMD.java index 71474a04..def14b49 100644 --- a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/HologramCMD.java +++ b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/HologramCMD.java @@ -55,6 +55,7 @@ public final class HologramCMD extends Command { <%primary_color%>- /hologram edit shadowStrength - Changes the shadow strength of the hologram <%primary_color%>- /hologram edit brightness <0-15> - Changes the brightness of the hologram <%primary_color%>- /hologram edit updateTextInterval - Sets the interval for updating the text + <%primary_color%>- /hologram edit blockState - Changes the block state (e.g., "facing north" for block holograms) <%primary_color%>- /hologram edit traits - Adds or removes a trait to the hologram """.replace("%primary_color%", MessageHelper.getPrimaryColor()); @@ -382,6 +383,7 @@ private boolean edit(@NotNull final CommandSender player, @NotNull final Hologra // block data case "block" -> new BlockCMD().run(player, hologram, args); + case "blockstate" -> new BlockStateCMD().run(player, hologram, args); default -> false; }; diff --git a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/hologram/BlockStateCMD.java b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/hologram/BlockStateCMD.java new file mode 100644 index 00000000..4b418b36 --- /dev/null +++ b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/hologram/BlockStateCMD.java @@ -0,0 +1,180 @@ +package com.fancyinnovations.fancyholograms.commands.hologram; + +import com.fancyinnovations.fancyholograms.api.data.BlockHologramData; +import com.fancyinnovations.fancyholograms.api.events.HologramUpdateEvent; +import com.fancyinnovations.fancyholograms.api.hologram.Hologram; +import com.fancyinnovations.fancyholograms.commands.HologramCMD; +import com.fancyinnovations.fancyholograms.commands.Subcommand; +import com.fancyinnovations.fancyholograms.main.FancyHologramsPlugin; +import de.oliver.fancylib.MessageHelper; +import org.bukkit.Bukkit; +import org.bukkit.block.data.BlockData; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; +import java.util.stream.Collectors; + +public class BlockStateCMD implements Subcommand { + + @Override + public List tabcompletion(@NotNull CommandSender player, @Nullable Hologram hologram, @NotNull String[] args) { + if (hologram == null || !(hologram.getData() instanceof BlockHologramData blockData)) { + return Collections.emptyList(); + } + + try { + BlockData defaultBlockData = blockData.getBlock().createBlockData(); + + if (args.length == 4) { + return Arrays.stream(defaultBlockData.getAsString(true) + .replaceAll("^[^\\[]*\\[", "") + .replaceAll("\\]$", "") + .split(",")) + .map(s -> s.split("=")[0]) + .filter(prop -> prop.toLowerCase().startsWith(args[3].toLowerCase())) + .collect(Collectors.toList()); + } else if (args.length == 5) { + String propertyName = args[3]; + String currentState = defaultBlockData.getAsString(true); + + for (String prop : currentState.replaceAll("^[^\\[]*\\[", "").replaceAll("\\]$", "").split(",")) { + String[] parts = prop.split("="); + if (parts[0].equals(propertyName)) { + List possibleValues = new ArrayList<>(); + + possibleValues.add("true"); + possibleValues.add("false"); + + possibleValues.addAll(Arrays.asList("north", "south", "east", "west", "up", "down")); + + for (int i = 0; i <= 15; i++) { + possibleValues.add(String.valueOf(i)); + } + + return possibleValues.stream() + .filter(val -> { + try { + Bukkit.createBlockData(blockData.getBlock(), propertyName + "=" + val); + return true; + } catch (IllegalArgumentException e) { + return false; + } + }) + .filter(val -> val.toLowerCase().startsWith(args[4].toLowerCase())) + .collect(Collectors.toList()); + } + } + } + } catch (Exception e) { + return Collections.emptyList(); + } + + return Collections.emptyList(); + } + + @Override + public boolean run(@NotNull CommandSender player, @Nullable Hologram hologram, @NotNull String[] args) { + + if (!(player.hasPermission("fancyholograms.hologram.edit.block_state"))) { + MessageHelper.error(player, "You don't have the required permission to change the block state of this hologram"); + return false; + } + + if (!(hologram.getData() instanceof BlockHologramData blockData)) { + MessageHelper.error(player, "This command can only be used on block holograms"); + return false; + } + + // If no additional args, clear the block state + if (args.length < 4) { + final var copied = blockData.copy(blockData.getName()); + copied.setBlockState(null); + + if (!HologramCMD.callModificationEvent(hologram, player, copied, HologramUpdateEvent.HologramModification.BLOCK_STATE)) { + return false; + } + + blockData.setBlockState(null); + + if (FancyHologramsPlugin.get().getHologramConfiguration().isSaveOnChangedEnabled()) { + FancyHologramsPlugin.get().getStorage().save(hologram.getData()); + } + + MessageHelper.success(player, "Cleared block state (using default)"); + return true; + } + + // Parse property=value pairs from args + // Format: /hologram edit blockstate [property] [value] ... + + // Start with existing properties or create default + Map existingProperties = new HashMap<>(); + + // Parse existing block state if present + if (blockData.getBlockState() != null && !blockData.getBlockState().isEmpty()) { + String[] props = blockData.getBlockState().split(","); + for (String prop : props) { + String[] parts = prop.split("=", 2); + if (parts.length == 2) { + existingProperties.put(parts[0].trim(), parts[1].trim()); + } + } + } + + // Apply the new properties (overwriting existing ones) + for (int i = 3; i < args.length; i += 2) { + if (i + 1 >= args.length) { + MessageHelper.error(player, "Missing value for property: " + args[i]); + return false; + } + + String property = args[i]; + String value = args[i + 1]; + existingProperties.put(property, value); + } + + // Build the block state string with brackets format + String blockStateString = existingProperties.entrySet().stream() + .sorted(Map.Entry.comparingByKey()) // Sort for consistency + .map(e -> e.getKey() + "=" + e.getValue()) + .collect(Collectors.joining(",")); + + // Validate the block state by creating block data with full string format + try { + String fullBlockString = blockData.getBlock().getKey().toString() + "[" + blockStateString + "]"; + Bukkit.createBlockData(fullBlockString); + } catch (IllegalArgumentException e) { + MessageHelper.error(player, "Invalid block state: " + e.getMessage()); + return false; + } + + if (java.util.Objects.equals(blockStateString, blockData.getBlockState())) { + MessageHelper.warning(player, "This block state is already set"); + return false; + } + + final var copied = blockData.copy(blockData.getName()); + copied.setBlockState(blockStateString); + + if (!HologramCMD.callModificationEvent(hologram, player, copied, HologramUpdateEvent.HologramModification.BLOCK_STATE)) { + return false; + } + + if (java.util.Objects.equals(blockStateString, blockData.getBlockState())) { + MessageHelper.warning(player, "This block state is already set"); + return false; + } + + blockData.setBlockState(blockStateString); + + if (FancyHologramsPlugin.get().getHologramConfiguration().isSaveOnChangedEnabled()) { + FancyHologramsPlugin.get().getStorage().save(hologram.getData()); + } + + MessageHelper.success(player, "Set block state: " + blockStateString); + + return true; + } +} diff --git a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/hologram/HologramImpl.java b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/hologram/HologramImpl.java index 1c00df78..4770c5de 100644 --- a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/hologram/HologramImpl.java +++ b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/hologram/HologramImpl.java @@ -166,9 +166,20 @@ private void syncWithData() { itemDisplay.setItem(itemData.getItemStack()); } else if (fsDisplay instanceof FS_BlockDisplay blockDisplay && data instanceof com.fancyinnovations.fancyholograms.api.data.BlockHologramData blockData) { // block - -// BlockType blockType = RegistryAccess.registryAccess().getRegistry(RegistryKey.BLOCK).get(blockData.getBlock().getKey()); - blockDisplay.setBlock(blockData.getBlock().createBlockData().createBlockState()); + try { + // If blockState is set, use it; otherwise use default + if (blockData.getBlockState() != null && !blockData.getBlockState().isEmpty()) { + // Create block data using full format: namespace:block[properties] + String fullBlockString = blockData.getBlock().getKey().toString() + "[" + blockData.getBlockState() + "]"; + blockDisplay.setBlock(org.bukkit.Bukkit.createBlockData(fullBlockString).createBlockState()); + } else { + blockDisplay.setBlock(blockData.getBlock().createBlockData().createBlockState()); + } + } catch (IllegalArgumentException e) { + // If block state is invalid, fall back to default + FancyHolograms.get().getFancyLogger().warn("Invalid block state for hologram " + blockData.getName() + ": " + e.getMessage()); + blockDisplay.setBlock(blockData.getBlock().createBlockData().createBlockState()); + } } if (data instanceof com.fancyinnovations.fancyholograms.api.data.DisplayHologramData displayData) { diff --git a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/storage/json/JsonAdapter.java b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/storage/json/JsonAdapter.java index 46473817..663d78f7 100644 --- a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/storage/json/JsonAdapter.java +++ b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/storage/json/JsonAdapter.java @@ -81,7 +81,8 @@ public static JsonTextHologramData textHologramDataToJson(com.fancyinnovations.f public static JsonBlockHologramData blockHologramDataToJson(com.fancyinnovations.fancyholograms.api.data.BlockHologramData data) { return new JsonBlockHologramData( - data.getBlock().name() + data.getBlock().name(), + data.getBlockState() ); } @@ -213,6 +214,7 @@ public static com.fancyinnovations.fancyholograms.api.data.HologramData fromJson case BLOCK -> new com.fancyinnovations.fancyholograms.api.data.BlockHologramData(data.hologram_data().name(), loc) .setBlock(Material.getMaterial(data.block_data().block_material())) // block data + .setBlockState(data.block_data().block_state()) .setBillboard(data.display_data().billboard()) // display data .setScale(scale) .setTranslation(translation) diff --git a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/storage/json/model/JsonBlockHologramData.java b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/storage/json/model/JsonBlockHologramData.java index f793ae21..a013684b 100644 --- a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/storage/json/model/JsonBlockHologramData.java +++ b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/storage/json/model/JsonBlockHologramData.java @@ -1,6 +1,7 @@ package com.fancyinnovations.fancyholograms.storage.json.model; public record JsonBlockHologramData( - String block_material + String block_material, + String block_state ) { } From 83faebc2c1316dcb16de52ec372f93126a3b7485 Mon Sep 17 00:00:00 2001 From: TSERATO Date: Fri, 21 Nov 2025 18:15:08 +0100 Subject: [PATCH 7/7] Converted blockstate command to lamp framework --- .../fancyholograms/commands/HologramCMD.java | 1 - .../commands/hologram/BlockStateCMD.java | 180 ------------------ .../lampCommands/hologram/BlockStateCMD.java | 121 ++++++++++++ .../main/FancyHologramsPlugin.java | 2 + 4 files changed, 123 insertions(+), 181 deletions(-) delete mode 100644 plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/hologram/BlockStateCMD.java create mode 100644 plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/lampCommands/hologram/BlockStateCMD.java diff --git a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/HologramCMD.java b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/HologramCMD.java index def14b49..f720488d 100644 --- a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/HologramCMD.java +++ b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/HologramCMD.java @@ -383,7 +383,6 @@ private boolean edit(@NotNull final CommandSender player, @NotNull final Hologra // block data case "block" -> new BlockCMD().run(player, hologram, args); - case "blockstate" -> new BlockStateCMD().run(player, hologram, args); default -> false; }; diff --git a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/hologram/BlockStateCMD.java b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/hologram/BlockStateCMD.java deleted file mode 100644 index 4b418b36..00000000 --- a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/hologram/BlockStateCMD.java +++ /dev/null @@ -1,180 +0,0 @@ -package com.fancyinnovations.fancyholograms.commands.hologram; - -import com.fancyinnovations.fancyholograms.api.data.BlockHologramData; -import com.fancyinnovations.fancyholograms.api.events.HologramUpdateEvent; -import com.fancyinnovations.fancyholograms.api.hologram.Hologram; -import com.fancyinnovations.fancyholograms.commands.HologramCMD; -import com.fancyinnovations.fancyholograms.commands.Subcommand; -import com.fancyinnovations.fancyholograms.main.FancyHologramsPlugin; -import de.oliver.fancylib.MessageHelper; -import org.bukkit.Bukkit; -import org.bukkit.block.data.BlockData; -import org.bukkit.command.CommandSender; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.*; -import java.util.stream.Collectors; - -public class BlockStateCMD implements Subcommand { - - @Override - public List tabcompletion(@NotNull CommandSender player, @Nullable Hologram hologram, @NotNull String[] args) { - if (hologram == null || !(hologram.getData() instanceof BlockHologramData blockData)) { - return Collections.emptyList(); - } - - try { - BlockData defaultBlockData = blockData.getBlock().createBlockData(); - - if (args.length == 4) { - return Arrays.stream(defaultBlockData.getAsString(true) - .replaceAll("^[^\\[]*\\[", "") - .replaceAll("\\]$", "") - .split(",")) - .map(s -> s.split("=")[0]) - .filter(prop -> prop.toLowerCase().startsWith(args[3].toLowerCase())) - .collect(Collectors.toList()); - } else if (args.length == 5) { - String propertyName = args[3]; - String currentState = defaultBlockData.getAsString(true); - - for (String prop : currentState.replaceAll("^[^\\[]*\\[", "").replaceAll("\\]$", "").split(",")) { - String[] parts = prop.split("="); - if (parts[0].equals(propertyName)) { - List possibleValues = new ArrayList<>(); - - possibleValues.add("true"); - possibleValues.add("false"); - - possibleValues.addAll(Arrays.asList("north", "south", "east", "west", "up", "down")); - - for (int i = 0; i <= 15; i++) { - possibleValues.add(String.valueOf(i)); - } - - return possibleValues.stream() - .filter(val -> { - try { - Bukkit.createBlockData(blockData.getBlock(), propertyName + "=" + val); - return true; - } catch (IllegalArgumentException e) { - return false; - } - }) - .filter(val -> val.toLowerCase().startsWith(args[4].toLowerCase())) - .collect(Collectors.toList()); - } - } - } - } catch (Exception e) { - return Collections.emptyList(); - } - - return Collections.emptyList(); - } - - @Override - public boolean run(@NotNull CommandSender player, @Nullable Hologram hologram, @NotNull String[] args) { - - if (!(player.hasPermission("fancyholograms.hologram.edit.block_state"))) { - MessageHelper.error(player, "You don't have the required permission to change the block state of this hologram"); - return false; - } - - if (!(hologram.getData() instanceof BlockHologramData blockData)) { - MessageHelper.error(player, "This command can only be used on block holograms"); - return false; - } - - // If no additional args, clear the block state - if (args.length < 4) { - final var copied = blockData.copy(blockData.getName()); - copied.setBlockState(null); - - if (!HologramCMD.callModificationEvent(hologram, player, copied, HologramUpdateEvent.HologramModification.BLOCK_STATE)) { - return false; - } - - blockData.setBlockState(null); - - if (FancyHologramsPlugin.get().getHologramConfiguration().isSaveOnChangedEnabled()) { - FancyHologramsPlugin.get().getStorage().save(hologram.getData()); - } - - MessageHelper.success(player, "Cleared block state (using default)"); - return true; - } - - // Parse property=value pairs from args - // Format: /hologram edit blockstate [property] [value] ... - - // Start with existing properties or create default - Map existingProperties = new HashMap<>(); - - // Parse existing block state if present - if (blockData.getBlockState() != null && !blockData.getBlockState().isEmpty()) { - String[] props = blockData.getBlockState().split(","); - for (String prop : props) { - String[] parts = prop.split("=", 2); - if (parts.length == 2) { - existingProperties.put(parts[0].trim(), parts[1].trim()); - } - } - } - - // Apply the new properties (overwriting existing ones) - for (int i = 3; i < args.length; i += 2) { - if (i + 1 >= args.length) { - MessageHelper.error(player, "Missing value for property: " + args[i]); - return false; - } - - String property = args[i]; - String value = args[i + 1]; - existingProperties.put(property, value); - } - - // Build the block state string with brackets format - String blockStateString = existingProperties.entrySet().stream() - .sorted(Map.Entry.comparingByKey()) // Sort for consistency - .map(e -> e.getKey() + "=" + e.getValue()) - .collect(Collectors.joining(",")); - - // Validate the block state by creating block data with full string format - try { - String fullBlockString = blockData.getBlock().getKey().toString() + "[" + blockStateString + "]"; - Bukkit.createBlockData(fullBlockString); - } catch (IllegalArgumentException e) { - MessageHelper.error(player, "Invalid block state: " + e.getMessage()); - return false; - } - - if (java.util.Objects.equals(blockStateString, blockData.getBlockState())) { - MessageHelper.warning(player, "This block state is already set"); - return false; - } - - final var copied = blockData.copy(blockData.getName()); - copied.setBlockState(blockStateString); - - if (!HologramCMD.callModificationEvent(hologram, player, copied, HologramUpdateEvent.HologramModification.BLOCK_STATE)) { - return false; - } - - if (java.util.Objects.equals(blockStateString, blockData.getBlockState())) { - MessageHelper.warning(player, "This block state is already set"); - return false; - } - - blockData.setBlockState(blockStateString); - - if (FancyHologramsPlugin.get().getHologramConfiguration().isSaveOnChangedEnabled()) { - FancyHologramsPlugin.get().getStorage().save(hologram.getData()); - } - - MessageHelper.success(player, "Set block state: " + blockStateString); - - return true; - } -} diff --git a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/lampCommands/hologram/BlockStateCMD.java b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/lampCommands/hologram/BlockStateCMD.java new file mode 100644 index 00000000..4a05c775 --- /dev/null +++ b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/lampCommands/hologram/BlockStateCMD.java @@ -0,0 +1,121 @@ +package com.fancyinnovations.fancyholograms.commands.lampCommands.hologram; + +import com.fancyinnovations.fancyholograms.api.data.BlockHologramData; +import com.fancyinnovations.fancyholograms.api.events.HologramUpdateEvent; +import com.fancyinnovations.fancyholograms.api.hologram.Hologram; +import com.fancyinnovations.fancyholograms.commands.HologramCMD; +import com.fancyinnovations.fancyholograms.main.FancyHologramsPlugin; +import de.oliver.fancylib.MessageHelper; +import org.bukkit.Bukkit; +import org.jetbrains.annotations.NotNull; +import revxrsal.commands.annotation.Command; +import revxrsal.commands.annotation.Default; +import revxrsal.commands.annotation.Description; +import revxrsal.commands.bukkit.actor.BukkitCommandActor; +import revxrsal.commands.bukkit.annotation.CommandPermission; + +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; + +public final class BlockStateCMD { + + public static final BlockStateCMD INSTANCE = new BlockStateCMD(); + + private BlockStateCMD() { + } + + @Command("hologram-new edit blockstate ") + @Description("Sets or clears block state properties") + @CommandPermission("fancyholograms.hologram.edit.block_state") + public void blockState( + final @NotNull BukkitCommandActor actor, + final @NotNull Hologram hologram, + final @Default("") String args + ) { + if (!(hologram.getData() instanceof BlockHologramData blockData)) { + MessageHelper.error(actor.sender(), "This command can only be used on block holograms"); + return; + } + + // Split args by spaces + String[] argArray = args.trim().isEmpty() ? new String[0] : args.split("\\s+"); + + // If no args, clear the block state + if (argArray.length == 0) { + final var copied = blockData.copy(blockData.getName()); + copied.setBlockState(null); + + if (!HologramCMD.callModificationEvent(hologram, actor.sender(), copied, HologramUpdateEvent.HologramModification.BLOCK_STATE)) { + return; + } + + blockData.setBlockState(null); + + if (FancyHologramsPlugin.get().getHologramConfiguration().isSaveOnChangedEnabled()) { + FancyHologramsPlugin.get().getStorage().save(hologram.getData()); + } + + MessageHelper.success(actor.sender(), "Cleared block state (using default)"); + return; + } + + // Start with existing properties + Map existingProperties = new HashMap<>(); + + // Parse existing block state if present + if (blockData.getBlockState() != null && !blockData.getBlockState().isEmpty()) { + String[] props = blockData.getBlockState().split(","); + for (String prop : props) { + String[] parts = prop.split("=", 2); + if (parts.length == 2) { + existingProperties.put(parts[0].trim(), parts[1].trim()); + } + } + } + + // Parse property-value pairs from args + for (int i = 0; i < argArray.length; i += 2) { + if (i + 1 >= argArray.length) { + MessageHelper.error(actor.sender(), "Missing value for property: " + argArray[i]); + return; + } + existingProperties.put(argArray[i], argArray[i + 1]); + } + + // Build the block state string + String blockStateString = existingProperties.entrySet().stream() + .sorted(Map.Entry.comparingByKey()) + .map(e -> e.getKey() + "=" + e.getValue()) + .collect(Collectors.joining(",")); + + // Validate the block state + try { + String fullBlockString = blockData.getBlock().getKey().toString() + "[" + blockStateString + "]"; + Bukkit.createBlockData(fullBlockString); + } catch (IllegalArgumentException e) { + MessageHelper.error(actor.sender(), "Invalid block state: " + e.getMessage()); + return; + } + + if (java.util.Objects.equals(blockStateString, blockData.getBlockState())) { + MessageHelper.warning(actor.sender(), "This block state is already set"); + return; + } + + final var copied = blockData.copy(blockData.getName()); + copied.setBlockState(blockStateString); + + if (!HologramCMD.callModificationEvent(hologram, actor.sender(), copied, HologramUpdateEvent.HologramModification.BLOCK_STATE)) { + return; + } + + blockData.setBlockState(blockStateString); + + if (FancyHologramsPlugin.get().getHologramConfiguration().isSaveOnChangedEnabled()) { + FancyHologramsPlugin.get().getStorage().save(hologram.getData()); + } + + MessageHelper.success(actor.sender(), "Set block state: " + blockStateString); + } +} diff --git a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/main/FancyHologramsPlugin.java b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/main/FancyHologramsPlugin.java index 776d7678..e6b7165f 100644 --- a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/main/FancyHologramsPlugin.java +++ b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/main/FancyHologramsPlugin.java @@ -11,6 +11,7 @@ import com.fancyinnovations.fancyholograms.commands.FancyHologramsTestCMD; import com.fancyinnovations.fancyholograms.commands.HologramCMD; import com.fancyinnovations.fancyholograms.commands.lampCommands.fancyholograms.ConfigCMD; +import com.fancyinnovations.fancyholograms.commands.lampCommands.hologram.BlockStateCMD; import com.fancyinnovations.fancyholograms.commands.lampCommands.hologram.TraitCMD; import com.fancyinnovations.fancyholograms.commands.lampCommands.types.HologramCommandType; import com.fancyinnovations.fancyholograms.commands.lampCommands.types.TraitCommandType; @@ -305,6 +306,7 @@ private void registerLampCommands() { // hologram commands lamp.register(TraitCMD.INSTANCE); + lamp.register(BlockStateCMD.INSTANCE); } private void registerListeners() {