From 68da91fed316b9fe271085b409c2ad472f1c957d Mon Sep 17 00:00:00 2001 From: Maxim Date: Thu, 3 Aug 2023 11:52:52 +0200 Subject: [PATCH] Added animation & updated TextHologram.java --- build.gradle | 4 +- .../maximfiedler/hologramapi/HologramAPI.java | 68 +---- .../hologramapi/TextHologram.java | 238 ------------------ .../hologramapi/hologram/HologramManager.java | 105 ++++++++ .../hologramapi/hologram/TextAnimation.java | 62 +++++ .../hologramapi/hologram/TextHologram.java | 115 +++++++++ 6 files changed, 290 insertions(+), 302 deletions(-) delete mode 100644 src/main/java/com/maximfiedler/hologramapi/TextHologram.java create mode 100644 src/main/java/com/maximfiedler/hologramapi/hologram/HologramManager.java create mode 100644 src/main/java/com/maximfiedler/hologramapi/hologram/TextAnimation.java create mode 100644 src/main/java/com/maximfiedler/hologramapi/hologram/TextHologram.java diff --git a/build.gradle b/build.gradle index 5d4c6c9..464100c 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ plugins { } group = 'com.maximfiedler' -version = '1.0.5' +version = '1.1' repositories { mavenCentral() @@ -19,6 +19,8 @@ repositories { dependencies { compileOnly "org.spigotmc:spigot-api:1.19.4-R0.1-SNAPSHOT" + compileOnly 'org.projectlombok:lombok:1.18.28' + annotationProcessor 'org.projectlombok:lombok:1.18.28' } def targetJavaVersion = 17 diff --git a/src/main/java/com/maximfiedler/hologramapi/HologramAPI.java b/src/main/java/com/maximfiedler/hologramapi/HologramAPI.java index e3ad35a..d50efde 100644 --- a/src/main/java/com/maximfiedler/hologramapi/HologramAPI.java +++ b/src/main/java/com/maximfiedler/hologramapi/HologramAPI.java @@ -1,75 +1,17 @@ package com.maximfiedler.hologramapi; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.entity.Entity; -import org.bukkit.entity.TextDisplay; -import org.bukkit.plugin.PluginDescriptionFile; +import com.maximfiedler.hologramapi.hologram.HologramManager; +import lombok.AccessLevel; +import lombok.Getter; import org.bukkit.plugin.java.JavaPlugin; -import org.joml.Vector3f; - -import java.util.ArrayList; -import java.util.List; -import java.util.logging.Level; public final class HologramAPI extends JavaPlugin { - private static HologramAPI hologramAPI; + private static @Getter(AccessLevel.PUBLIC) HologramManager hologramManager; @Override public void onEnable() { - hologramAPI = this; - getServer().getLogger().log(Level.INFO, ChatColor.GREEN + "Enabled HologramAPI v" + this.getDescription().getVersion()); - } - - public static HologramAPI getHologramAPI() { - return hologramAPI; - } - - public void removeAllHologramsByID(String id) { - for(World world : Bukkit.getWorlds()) { - for(Entity entity : world.getEntities()) { - if(!(entity instanceof TextDisplay textDisplay)) continue; - if(!textDisplay.getScoreboardTags().contains(id + "_hologram_api")) continue; - textDisplay.remove(); - } - } - } - - public List getHologramsByID(String id) { - List displays = new ArrayList<>(); - List holograms = new ArrayList<>(); - for(World world : Bukkit.getWorlds()) { - for(Entity entity : world.getEntities()) { - if(!(entity instanceof TextDisplay textDisplay)) continue; - if(!textDisplay.getScoreboardTags().contains(id + "_hologram_api")) continue; - displays.add(textDisplay); - } - } - for(TextDisplay textDisplay : displays) { - TextHologram hologram = new TextHologram("id"); - hologram.setDisplay(textDisplay); - hologram.setText(textDisplay.getText()); - hologram.setBillboard(textDisplay.getBillboard()); - hologram.setBackgroundColor(textDisplay.getBackgroundColor()); - hologram.setAlignment(textDisplay.getAlignment()); - hologram.setViewRange(textDisplay.getViewRange()); - hologram.setSeeThrough(textDisplay.isSeeThrough()); - hologram.setTextShadow(textDisplay.isShadowed()); - hologram.setLineWidth(textDisplay.getLineWidth()); - hologram.setTextOpacity(textDisplay.getTextOpacity()); - hologram.setBrightness(textDisplay.getBrightness()); - var transformation = textDisplay.getTransformation(); - hologram.setSize(transformation.getScale()); - hologram.setLeftRotation(transformation.getLeftRotation()); - hologram.setRightRotation(transformation.getRightRotation()); - hologram.setTranslation(transformation.getTranslation()); - holograms.add(hologram); - } - displays.clear(); - return holograms; + hologramManager = new HologramManager(this); } } diff --git a/src/main/java/com/maximfiedler/hologramapi/TextHologram.java b/src/main/java/com/maximfiedler/hologramapi/TextHologram.java deleted file mode 100644 index 20bb83a..0000000 --- a/src/main/java/com/maximfiedler/hologramapi/TextHologram.java +++ /dev/null @@ -1,238 +0,0 @@ -package com.maximfiedler.hologramapi; - -import org.bukkit.Color; -import org.bukkit.Location; -import org.bukkit.entity.Display; -import org.bukkit.entity.TextDisplay; -import org.bukkit.util.Transformation; -import org.joml.Quaternionf; -import org.joml.Vector3f; - - -public class TextHologram { - private TextDisplay display; - private final String id; - private Vector3f size = new Vector3f(1.5F,1.5F,1.5F); - private Vector3f translation = new Vector3f(0,0,0); - private Quaternionf rightRotation = new Quaternionf(0,0,0,1); - private Quaternionf leftRotation = new Quaternionf(0,0,0,1); - private String text = "Hologram API"; - private Display.Billboard billboard = Display.Billboard.CENTER; - private Color backgroundColor = Color.fromARGB(100, 222, 222, 222); - private byte textOpacity; - private Display.Brightness brightness; - private TextDisplay.TextAlignment alignment = TextDisplay.TextAlignment.CENTER; - private float viewRange = 1; - private boolean seeThrough = false; - private boolean textShadow = true; - private int lineWidth = 200; - - public TextHologram(String id) { - if(id.contains(" ")) throw new IllegalArgumentException("The ID cannot contain spaces!"); - this.id = id + "_hologram_api"; - } - - /** - * Applies all properties from this class to the display entity - */ - public void update() { - if(this.display == null) return; - this.display.setText(this.text); - this.display.setBillboard(this.billboard); - this.display.setBackgroundColor(this.backgroundColor); - this.display.setAlignment(alignment); - this.display.setViewRange(viewRange); - this.display.setSeeThrough(seeThrough); - this.display.setShadowed(textShadow); - this.display.setLineWidth(lineWidth); - if(this.textOpacity != 0) this.display.setTextOpacity(this.textOpacity); - if(this.brightness != null) this.display.setBrightness(brightness); - var transformation = new Transformation( - this.translation, - this.leftRotation, - this.size, - this.rightRotation - ); - this.display.setInterpolationDelay(-1); - this.display.setInterpolationDuration(0); - this.display.setTransformation(transformation); - } - - /** - * Spawns the display and applies all specified properties to it - * @param location - */ - public TextHologram spawn(Location location) { - location.getWorld().spawn(location, TextDisplay.class, textDisplay -> { - this.display = textDisplay; - textDisplay.addScoreboardTag(this.id); - update(); - }); - return this; - } - - public TextHologram kill() { - this.display.remove(); - this.display = null; - return this; - } - - public TextHologram teleport(Location location) { - display.teleport(location); - return this; - } - - /* - * ======================= SETTERS ======================= - */ - - public TextHologram setSize(Vector3f size) { - this.size = size; - return this; - } - - public TextHologram setTranslation(Vector3f translation) { - this.translation = translation; - return this; - } - - public TextHologram setRightRotation(Quaternionf rightRotation) { - this.rightRotation = rightRotation; - return this; - } - - public TextHologram setLeftRotation(Quaternionf leftRotation) { - this.leftRotation = leftRotation; - return this; - } - - public TextHologram setText(String text) { - this.text = text; - return this; - } - - public TextHologram setBillboard(Display.Billboard billboard) { - this.billboard = billboard; - return this; - } - - public TextHologram setBackgroundColor(Color backgroundColor) { - this.backgroundColor = backgroundColor; - return this; - } - - public TextHologram setTextOpacity(byte textOpacity) { - this.textOpacity = textOpacity; - return this; - } - - public TextHologram setBrightness(Display.Brightness brightness) { - this.brightness = brightness; - return this; - } - - public TextHologram setAlignment(TextDisplay.TextAlignment alignment) { - this.alignment = alignment; - return this; - } - - public TextHologram setViewRange(float viewRange) { - this.viewRange = viewRange; - return this; - } - - public TextHologram setSeeThrough(boolean seeThrough) { - this.seeThrough = seeThrough; - return this; - } - - public TextHologram setTextShadow(boolean textShadow) { - this.textShadow = textShadow; - return this; - } - - public TextHologram setLineWidth(int lineWidth) { - this.lineWidth = lineWidth; - return this; - } - - public void setDisplay(TextDisplay display) { - this.display = display; - } - - /* - * ======================= SETTERS ======================= - */ - - /* - * ======================= GETTERS ======================= - */ - - public TextDisplay getDisplay() { - return display; - } - - public String getId() { - return id; - } - - public Vector3f getSize() { - return size; - } - - public Vector3f getTranslation() { - return translation; - } - - public Quaternionf getRightRotation() { - return rightRotation; - } - - public Quaternionf getLeftRotation() { - return leftRotation; - } - - public String getText() { - return text; - } - - public Display.Billboard getBillboard() { - return billboard; - } - - public Color getBackgroundColor() { - return backgroundColor; - } - - public byte getTextOpacity() { - return textOpacity; - } - - public Display.Brightness getBrightness() { - return brightness; - } - - public TextDisplay.TextAlignment getAlignment() { - return alignment; - } - - public float getViewRange() { - return viewRange; - } - - public boolean isSeeThrough() { - return seeThrough; - } - - public boolean isTextShadow() { - return textShadow; - } - - public int getLineWidth() { - return lineWidth; - } - - /* - * ======================= GETTERS ======================= - */ -} diff --git a/src/main/java/com/maximfiedler/hologramapi/hologram/HologramManager.java b/src/main/java/com/maximfiedler/hologramapi/hologram/HologramManager.java new file mode 100644 index 0000000..b52a7b4 --- /dev/null +++ b/src/main/java/com/maximfiedler/hologramapi/hologram/HologramManager.java @@ -0,0 +1,105 @@ +package com.maximfiedler.hologramapi.hologram; + +import com.maximfiedler.hologramapi.HologramAPI; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.entity.TextDisplay; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class HologramManager { + + private final HologramAPI hologramAPI; + + private HashMap hologramAnimations = new HashMap<>(); + + public HologramManager(HologramAPI hologramAPI) { + this.hologramAPI = hologramAPI; + } + + public void applyAnimation(TextHologram hologram, TextAnimation textAnimation) { + cancelAnimation(hologram); + hologramAnimations.put(hologram, animateHologram(hologram, textAnimation)); + } + + public void cancelAnimation(TextHologram hologram) { + if(hologramAnimations.containsKey(hologram)) { + hologramAnimations.get(hologram).cancel(); + hologramAnimations.remove(hologram); + } + } + + private BukkitRunnable animateHologram(TextHologram hologram, TextAnimation textAnimation) { + final BukkitRunnable animation = new BukkitRunnable() { + int currentFrame = 0; + public void run() { + if(textAnimation.getTextFrames().isEmpty()) return; + hologram.setText(textAnimation.getTextFrames().get(0)); + hologram.update(); + currentFrame++; + if(currentFrame >= textAnimation.getTextFrames().size()) currentFrame = 0; + } + }; + + animation.runTaskTimerAsynchronously(this.hologramAPI, textAnimation.getDelay(), textAnimation.getSpeed()); + return animation; + } + + /** + * Removes all text-displays if it has a scoreboard tag with the given ID + * @param id Hologram ID / scoreboard tag + */ + public void removeAll(String id) { + for(World world : Bukkit.getWorlds()) { + for(Entity entity : world.getEntities()) { + if(!(entity instanceof TextDisplay textDisplay)) continue; + if(!textDisplay.getScoreboardTags().contains(id + "_hologram_api")) continue; + textDisplay.remove(); + } + } + } + + /** + * Get all holograms with a specific id in the form of TextHologram objects in a list + * @param id the hologram id which is saved as a scoreboard tag + * @return TextHologram list + */ + public List getHologramsByID(String id) { + List displays = new ArrayList<>(); + List holograms = new ArrayList<>(); + for(World world : Bukkit.getWorlds()) { + for(Entity entity : world.getEntities()) { + if(!(entity instanceof TextDisplay textDisplay)) continue; + if(!textDisplay.getScoreboardTags().contains(id + "_hologram_api")) continue; + displays.add(textDisplay); + } + } + for(TextDisplay textDisplay : displays) { + TextHologram hologram = new TextHologram("id"); + hologram.setDisplay(textDisplay); + hologram.setText(textDisplay.getText()); + hologram.setBillboard(textDisplay.getBillboard()); + hologram.setBackgroundColor(textDisplay.getBackgroundColor()); + hologram.setAlignment(textDisplay.getAlignment()); + hologram.setViewRange(textDisplay.getViewRange()); + hologram.setSeeThrough(textDisplay.isSeeThrough()); + hologram.setTextShadow(textDisplay.isShadowed()); + hologram.setLineWidth(textDisplay.getLineWidth()); + hologram.setTextOpacity(textDisplay.getTextOpacity()); + hologram.setBrightness(textDisplay.getBrightness()); + var transformation = textDisplay.getTransformation(); + hologram.setSize(transformation.getScale()); + hologram.setLeftRotation(transformation.getLeftRotation()); + hologram.setRightRotation(transformation.getRightRotation()); + hologram.setTranslation(transformation.getTranslation()); + holograms.add(hologram); + } + displays.clear(); + return holograms; + } + +} diff --git a/src/main/java/com/maximfiedler/hologramapi/hologram/TextAnimation.java b/src/main/java/com/maximfiedler/hologramapi/hologram/TextAnimation.java new file mode 100644 index 0000000..45d6a57 --- /dev/null +++ b/src/main/java/com/maximfiedler/hologramapi/hologram/TextAnimation.java @@ -0,0 +1,62 @@ +package com.maximfiedler.hologramapi.hologram; + +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.Accessors; + +import java.util.ArrayList; +import java.util.List; + +public class TextAnimation { + + private @Getter List textFrames = new ArrayList<>(); + + /** + * The display will be updated every x ticks + * 20 ticks = 1 second + */ + private @Getter @Setter @Accessors(chain = true) long speed = 20; + + /** + * Delay in ticks when the animation should start + * 20 ticks = 1 second + */ + private @Getter @Setter @Accessors(chain = true) long delay = 20; + + + public TextAnimation() {} + public TextAnimation(int speed) { + this.speed = speed; + } + + public TextAnimation(int speed, int delay) { + this.speed = speed; + this.delay = delay; + } + + public TextAnimation addFrame(String text) { + this.textFrames.add(text); + return this; + } + + public TextAnimation removeFrame(int number) { + this.textFrames.remove(number); + return this; + } + + public TextAnimation removeLastFrame() { + removeFrame(this.textFrames.size() - 1); + return this; + } + + public TextAnimation removeFirstFrame() { + removeFrame(0); + return this; + } + + public TextAnimation clearFrames() { + this.textFrames.clear(); + return this; + } + +} diff --git a/src/main/java/com/maximfiedler/hologramapi/hologram/TextHologram.java b/src/main/java/com/maximfiedler/hologramapi/hologram/TextHologram.java new file mode 100644 index 0000000..4d373b7 --- /dev/null +++ b/src/main/java/com/maximfiedler/hologramapi/hologram/TextHologram.java @@ -0,0 +1,115 @@ +package com.maximfiedler.hologramapi.hologram; + +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.Accessors; +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.entity.Display; +import org.bukkit.entity.TextDisplay; +import org.bukkit.util.Transformation; +import org.joml.Quaternionf; +import org.joml.Vector3f; + +//TODO remove line method (count lines then remove the line given in the argument) +//TODO also add a remove last and remove first line method + +public class TextHologram { + private @Getter @Setter TextDisplay display; + private @Getter final String id; + private @Getter @Setter @Accessors(chain = true) Vector3f size = new Vector3f(1.5F,1.5F,1.5F); + private @Getter @Setter @Accessors(chain = true) Vector3f translation = new Vector3f(0,0,0); + private @Getter @Setter @Accessors(chain = true) Quaternionf rightRotation = new Quaternionf(0,0,0,1); + private @Getter @Setter @Accessors(chain = true) Quaternionf leftRotation = new Quaternionf(0,0,0,1); + private @Getter @Setter @Accessors(chain = true) String text = "Hologram API"; + private @Getter @Setter @Accessors(chain = true) Display.Billboard billboard = Display.Billboard.CENTER; + private @Getter @Setter @Accessors(chain = true) Color backgroundColor = Color.fromARGB(100, 222, 222, 222); + private @Getter @Setter @Accessors(chain = true) byte textOpacity; + private @Getter @Setter @Accessors(chain = true) Display.Brightness brightness; + private @Getter @Setter @Accessors(chain = true) TextDisplay.TextAlignment alignment = TextDisplay.TextAlignment.CENTER; + private @Getter @Setter @Accessors(chain = true) float viewRange = 1; + private @Getter @Setter @Accessors(chain = true) boolean seeThrough = false; + private @Getter @Setter @Accessors(chain = true) boolean textShadow = true; + private @Getter @Setter @Accessors(chain = true) int lineWidth = 200; + + public TextHologram(String id) { + if(id.contains(" ")) throw new IllegalArgumentException("The ID cannot contain spaces!"); + this.id = id + "_hologram_api"; + } + + /** + * Applies all properties from this class to the display entity + */ + public void update() { + if(this.display == null) return; + this.display.setText(this.text); + this.display.setBillboard(this.billboard); + this.display.setBackgroundColor(this.backgroundColor); + this.display.setAlignment(alignment); + this.display.setViewRange(viewRange); + this.display.setSeeThrough(seeThrough); + this.display.setShadowed(textShadow); + this.display.setLineWidth(lineWidth); + if(this.textOpacity != 0) this.display.setTextOpacity(this.textOpacity); + if(this.brightness != null) this.display.setBrightness(brightness); + var transformation = new Transformation( + this.translation, + this.leftRotation, + this.size, + this.rightRotation + ); + this.display.setInterpolationDelay(-1); + this.display.setInterpolationDuration(0); + this.display.setTransformation(transformation); + } + + /** + * Spawns the display and applies all specified properties to it + * @param location + */ + public TextHologram spawn(Location location) { + location.getWorld().spawn(location, TextDisplay.class, textDisplay -> { + this.display = textDisplay; + textDisplay.addScoreboardTag(this.id); + update(); + }); + return this; + } + + public TextHologram kill() { + this.display.remove(); + this.display = null; + return this; + } + + public TextHologram teleport(Location location) { + display.teleport(location); + return this; + } + + public TextHologram addLine(String text) { + this.text += "\n" + text; + return this; + } + + public TextHologram setSize(float x, float y, float z) { + setSize(new Vector3f(x, y, z)); + return this; + } + + public TextHologram setTranslation(float x, float y, float z) { + setTranslation(new Vector3f(x, y, z)); + return this; + } + + public TextHologram setRightRotation(float x, float y, float z, float w) { + setRightRotation(new Quaternionf(x, y, z, w)); + return this; + } + + public TextHologram setLeftRotation(float x, float y, float z, float w) { + setLeftRotation(new Quaternionf(x, y, z, w)); + return this; + } + +}