diff --git a/plugins/fancyholograms/src/main/java/de/oliver/fancyholograms/main/FancyHologramsPlugin.java b/plugins/fancyholograms/src/main/java/de/oliver/fancyholograms/main/FancyHologramsPlugin.java index 13e25c3a..78f3a35c 100644 --- a/plugins/fancyholograms/src/main/java/de/oliver/fancyholograms/main/FancyHologramsPlugin.java +++ b/plugins/fancyholograms/src/main/java/de/oliver/fancyholograms/main/FancyHologramsPlugin.java @@ -30,6 +30,7 @@ import de.oliver.fancyholograms.storage.StorageMigrator; import de.oliver.fancyholograms.storage.json.JsonStorage; import de.oliver.fancyholograms.trait.HologramTraitRegistryImpl; import de.oliver.fancyholograms.trait.builtin.FileContentTrait; +import de.oliver.fancyholograms.trait.builtin.InteractionTrait; import de.oliver.fancyholograms.trait.builtin.MultiplePagesTrait; import de.oliver.fancyholograms.util.PluginUtils; import de.oliver.fancylib.FancyLib; @@ -192,6 +193,7 @@ public final class FancyHologramsPlugin extends JavaPlugin implements FancyHolog traitRegistry.register(MultiplePagesTrait.class); traitRegistry.register(FileContentTrait.class); + traitRegistry.register(InteractionTrait.class); new StorageMigrator().migrate(); diff --git a/plugins/fancyholograms/src/main/java/de/oliver/fancyholograms/trait/builtin/InteractionTrait.java b/plugins/fancyholograms/src/main/java/de/oliver/fancyholograms/trait/builtin/InteractionTrait.java new file mode 100644 index 00000000..5999e983 --- /dev/null +++ b/plugins/fancyholograms/src/main/java/de/oliver/fancyholograms/trait/builtin/InteractionTrait.java @@ -0,0 +1,164 @@ +package de.oliver.fancyholograms.trait.builtin; + +import de.oliver.fancyholograms.api.data.TextHologramData; +import de.oliver.fancyholograms.api.trait.HologramTrait; +import de.oliver.fancyholograms.api.trait.HologramTraitClass; +import de.oliver.fancyholograms.util.PluginUtils; +import de.oliver.fancynpcs.api.FancyNpcsPlugin; +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.api.NpcData; +import de.oliver.fancynpcs.api.actions.ActionTrigger; +import de.oliver.fancynpcs.api.actions.NpcAction; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.ApiStatus; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +@ApiStatus.Experimental +@HologramTraitClass(traitName = "interaction_trait", defaultTrait = true) +public class InteractionTrait extends HologramTrait { + + private static final FancyNpcsPlugin FN = FancyNpcsPlugin.get(); + private Configuration config; + private Npc hitbox; + + public InteractionTrait() { + if (!PluginUtils.isFancyNpcsEnabled()) { + throw new IllegalStateException("FancyNpcs is not enabled. Please enable it to use InteractionTrait."); + } + } + + @Override + public void onAttach() { + this.load(); + this.updateHitbox(); + } + + @Override + public void onSpawn(Player player) { + this.updateHitbox(); + } + + @Override + public void onDespawn(Player player) { + this.updateHitbox(); + } + + @Override + public void onModify() { + this.updateHitbox(); + } + + @Override + public void onUnregister() { + if (this.hitbox != null) { + this.hitbox.removeForAll(); + FN.getNpcManager().removeNpc(this.hitbox); + this.hitbox = null; + } + } + + @Override + public void save() { + try { + storage.set(hologram.getData().getName(), config); + } catch (Exception e) { + logger.error("Failed to save configuration for InteractionTrait"); + logger.error(e); + } + } + + @Override + public void load() { + try { + config = storage.get(hologram.getData().getName(), Configuration.class); + } catch (Exception e) { + logger.error("Failed to load configuration for InteractionTrait"); + logger.error(e); + } + if (config == null) { + config = new Configuration(List.of( + new ActionConfig("message", "Hi, you just clicked a hologram!") + )); + save(); + } + } + + private void updateHitbox() { + if (FN.getNpcManager().getNpc("hologram_hitbox_for_" + hologram.getData().getName()) == null) { + this.hitbox = FN.getNpcAdapter().apply(new NpcData( + "hologram_hitbox_for_" + hologram.getData().getName(), + UUID.randomUUID(), + hologram.getData().getLocation() + )); + this.hitbox.setSaveToFile(false); + this.hitbox.getData().setType(EntityType.INTERACTION); + this.hitbox.getData().setDisplayName(""); + + List actions = new ArrayList<>(); + for (ActionConfig acfg : this.config.actions()) { + NpcAction action = FN.getActionManager().getActionByName(acfg.action()); + if (action == null) { + logger.warn("Action " + acfg.action() + " is not registered"); + continue; + } + + actions.add(new NpcAction.NpcActionData(actions.size(), action, acfg.value())); + } + + this.hitbox.getData().getActions().put(ActionTrigger.ANY_CLICK, actions); + + this.hitbox.create(); + this.hitbox.spawnForAll(); + FN.getNpcManager().registerNpc(this.hitbox); + } + + this.hitbox.getData().setLocation(hologram.getData().getLocation()); + + NpcAttribute widthAttr = FN.getAttributeManager().getAttributeByName(EntityType.INTERACTION, "width"); + this.hitbox.getData().addAttribute(widthAttr, String.valueOf(calcWidth())); + + NpcAttribute heightAttr = FN.getAttributeManager().getAttributeByName(EntityType.INTERACTION, "height"); + this.hitbox.getData().addAttribute(heightAttr, String.valueOf(calcHeight())); + + this.hitbox.updateForAll(); + } + + private double calcHeight() { + int lines = ((TextHologramData) hologram.getData()).getText().size(); + double heightPerLine = 0.25; + double scale = ((TextHologramData) hologram.getData()).getScale().y; + return lines * heightPerLine * scale; + } + + private double calcWidth() { + List lines = ((TextHologramData) hologram.getData()).getText(); + double maxCharacters = 0; + for (String line : lines) { + if (line.length() > maxCharacters) { + maxCharacters = line.length(); + } + } + + double widthPerCharacter = 0.12; + double scale = ((TextHologramData) hologram.getData()).getScale().x; + return maxCharacters * widthPerCharacter * scale; + } + + public record ActionConfig( + String action, + String value + ) { + + } + + public record Configuration( + List actions + ) { + + } +}