fancyholograms v3: Add traits command

This commit is contained in:
Oliver
2025-07-30 19:47:36 +02:00
parent 4c43d20718
commit 87f0183e4f
4 changed files with 136 additions and 3 deletions

View File

@@ -107,7 +107,7 @@ public abstract class HologramTrait {
throw new IllegalArgumentException("Trait class " + getClass() + " is not annotated with HologramTraitClass");
}
protected final boolean isTraitAttached(Class<? extends HologramTrait> trait) {
public final boolean isTraitAttached(Class<? extends HologramTrait> trait) {
for (HologramTrait hologramTrait : hologram.getData().getTraitTrait().getTraits()) {
if (hologramTrait.getClass().equals(trait)) {
return true;
@@ -117,7 +117,7 @@ public abstract class HologramTrait {
return false;
}
protected final <T extends HologramTrait> T getTrait(Class<T> trait) {
public final <T extends HologramTrait> T getTrait(Class<T> trait) {
for (HologramTrait hologramTrait : hologram.getData().getTraitTrait().getTraits()) {
if (hologramTrait.getClass().equals(trait)) {
return (T) hologramTrait;

View File

@@ -28,6 +28,38 @@ public class HologramTraitTrait extends HologramTrait {
}
}
public void addTrait(Class<? extends HologramTrait> trait) {
try {
HologramTrait newTrait = trait.getConstructor().newInstance();
addTrait(newTrait);
} catch (Exception e) {
logger.error("Failed to instantiate trait " + trait.getSimpleName());
logger.error(e);
}
}
public void removeTrait(HologramTrait trait) {
if (this.traits.remove(trait)) {
// Detach the trait from the hologram if it was successfully removed
if (hologram != null) {
trait.onUnregister();
logger.debug("Detached trait " + trait.getClass().getSimpleName() + " from hologram " + hologram.getData().getName());
}
} else {
logger.warn("Trait " + trait.getClass().getSimpleName() + " not found in hologram " + hologram.getData().getName());
}
}
public void removeTrait(Class<? extends HologramTrait> trait) {
for (HologramTrait t : this.traits) {
if (t.getClass().equals(trait)) {
removeTrait(t);
return;
}
}
logger.warn("Trait " + trait.getSimpleName() + " not found in hologram " + hologram.getData().getName());
}
@Override
public void onAttach() {
// Attach all default traits to the hologram

View File

@@ -191,7 +191,7 @@ public final class HologramCMD extends Command {
final var usingNpcs = PluginUtils.isFancyNpcsEnabled();
List<String> suggestions = new ArrayList<>(Arrays.asList("position", "moveHere", "center", "moveTo", "rotate", "rotatepitch", "billboard", "scale", "translate", "visibilityDistance", "visibility", "shadowRadius", "shadowStrength", "brightness", usingNpcs ? "linkWithNpc" : "", usingNpcs ? "unlinkWithNpc" : ""));
List<String> suggestions = new ArrayList<>(Arrays.asList("traits", "position", "moveHere", "center", "moveTo", "rotate", "rotatepitch", "billboard", "scale", "translate", "visibilityDistance", "visibility", "shadowRadius", "shadowStrength", "brightness", usingNpcs ? "linkWithNpc" : "", usingNpcs ? "unlinkWithNpc" : ""));
suggestions.addAll(type.getCommands());
return suggestions.stream().filter(input -> input.toLowerCase().startsWith(args[2].toLowerCase(Locale.ROOT))).toList();
@@ -201,6 +201,10 @@ public final class HologramCMD extends Command {
return Collections.emptyList();
}
if (args[2].equalsIgnoreCase("traits")) {
return new TraitsCMD().tabcompletion(sender, hologram, args);
}
// /holo edit [hologram] [option] {tab:contextual}
if (args.length == 4) {
final var suggestions = switch (args[2].toLowerCase(Locale.ROOT)) {
@@ -349,6 +353,9 @@ public final class HologramCMD extends Command {
}
return switch (action) {
// hologram data
case "traits" -> new TraitsCMD().run(player, hologram, args);
// display data
case "moveto" -> new MoveToCMD().run(player, hologram, args);
case "rotate" -> new RotateCMD().run(player, hologram, args);

View File

@@ -0,0 +1,94 @@
package com.fancyinnovations.fancyholograms.commands.hologram;
import com.fancyinnovations.fancyholograms.api.FancyHolograms;
import com.fancyinnovations.fancyholograms.api.hologram.Hologram;
import com.fancyinnovations.fancyholograms.api.trait.HologramTraitRegistry;
import com.fancyinnovations.fancyholograms.commands.Subcommand;
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 TraitsCMD implements Subcommand {
@Override
public List<String> tabcompletion(@NotNull CommandSender player, @Nullable Hologram hologram, @NotNull String[] args) {
if (args.length == 4) {
return List.of("add", "remove");
} else if (args.length == 5) {
return FancyHolograms.get().getTraitRegistry().getTraits()
.stream()
.filter(ti -> !ti.isDefault())
.filter(ti -> {
if (args[3].equalsIgnoreCase("add")) {
return !hologram.getData().getTraitTrait().isTraitAttached(ti.clazz());
} else if (args[3].equalsIgnoreCase("remove")) {
return hologram.getData().getTraitTrait().isTraitAttached(ti.clazz());
}
return true;
})
.map(HologramTraitRegistry.TraitInfo::name)
.toList();
}
return List.of();
}
@Override
public boolean run(@NotNull CommandSender player, @Nullable Hologram hologram, @NotNull String[] args) {
if (!(player.hasPermission("fancyholograms.hologram.edit.traits"))) {
MessageHelper.error(player, "You don't have the required permission to change traits of a hologram.");
return false;
}
// /hologram edit <name> traits <add|remove> <trait name>
if (args.length < 5) {
MessageHelper.error(player, "Usage: /hologram edit <name> traits <add|remove> <trait name>");
return false;
}
String action = args[3];
String traitName = args[4];
if (traitName == null || traitName.isEmpty()) {
MessageHelper.error(player, "You must specify a trait name.");
return false;
}
HologramTraitRegistry.TraitInfo traitInfo = FancyHolograms.get().getTraitRegistry().getTrait(traitName);
if (traitInfo == null) {
MessageHelper.error(player, "Trait '" + traitName + "' does not exist.");
return false;
}
switch (action.toLowerCase()) {
case "add": {
if (hologram.getData().getTraitTrait().isTraitAttached(traitInfo.clazz())) {
MessageHelper.error(player, "Trait '" + traitName + "' is already attached to hologram '" + hologram.getData().getName() + "'.");
return false;
}
hologram.getData().getTraitTrait().addTrait(traitInfo.clazz());
MessageHelper.success(player, "Trait '" + traitName + "' has been added to hologram '" + hologram.getData().getName() + "'.");
return true;
}
case "remove": {
if (!hologram.getData().getTraitTrait().isTraitAttached(traitInfo.clazz())) {
MessageHelper.error(player, "Trait '" + traitName + "' is not attached to hologram '" + hologram.getData().getName() + "'.");
return false;
}
hologram.getData().getTraitTrait().removeTrait(traitInfo.clazz());
MessageHelper.success(player, "Trait '" + traitName + "' has been removed from hologram '" + hologram.getData().getName() + "'.");
return true;
}
default: {
MessageHelper.error(player, "Invalid action. Use 'add' or 'remove'.");
return false;
}
}
}
}