diff --git a/build.gradle b/build.gradle index 57768d0..c2b372f 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { } group = 'com.maximde' -version = '1.4.7' +version = '1.4.8' repositories { diff --git a/src/main/java/com/maximde/hologramapi/hologram/HologramManager.java b/src/main/java/com/maximde/hologramapi/hologram/HologramManager.java index 795d6e8..8b429ae 100644 --- a/src/main/java/com/maximde/hologramapi/hologram/HologramManager.java +++ b/src/main/java/com/maximde/hologramapi/hologram/HologramManager.java @@ -123,7 +123,7 @@ public void updateLeaderboard(TextHologram hologram, Map leader hologram.update(); } - public void spawn(TextHologram textHologram, Location location) { + public TextHologram spawn(TextHologram textHologram, Location location) { textHologram.getInternalAccess().setLocation(location); textHologram.getInternalAccess().setEntityId(ThreadLocalRandom.current().nextInt(4000, Integer.MAX_VALUE)); WrapperPlayServerSpawnEntity packet = new WrapperPlayServerSpawnEntity( @@ -137,6 +137,7 @@ public void spawn(TextHologram textHologram, Location location) { }); textHologram.update(); register(textHologram); + return textHologram; } public void attach(TextHologram textHologram, int entityID) { @@ -144,11 +145,18 @@ public void attach(TextHologram textHologram, int entityID) { } public boolean register(TextHologram textHologram) { - if (textHologram == null) return false; + if (textHologram == null) { + return false; + } + if (hologramsMap.containsKey(textHologram.getId())) { + Bukkit.getLogger().severe("Error: Hologram with ID " + textHologram.getId() + " is already registered."); + return false; + } hologramsMap.put(textHologram.getId(), textHologram); return true; } + public boolean remove(TextHologram textHologram) { return textHologram != null && remove(textHologram.getId()); } @@ -203,4 +211,23 @@ public boolean updateHologramIfExists(String id, Consumer updateAc } return false; } + + /** + * Creates a copy of an existing hologram at a new location + * @param source The hologram to copy from + * @param id The ID for the new hologram + * @return The newly created hologram copy + */ + public TextHologram copyHologram(TextHologram source, String id) { + return this.spawn(source.getInternalAccess().copy(id), source.getLocation()); + } + + /** + * Creates a copy of an existing hologram at a new location + * @param source The hologram to copy from + * @return The newly created hologram copy + */ + public TextHologram copyHologram(TextHologram source) { + return this.spawn(source.getInternalAccess().copy(), source.getLocation()); + } } \ No newline at end of file diff --git a/src/main/java/com/maximde/hologramapi/hologram/TextHologram.java b/src/main/java/com/maximde/hologramapi/hologram/TextHologram.java index a47771c..03c9e8b 100644 --- a/src/main/java/com/maximde/hologramapi/hologram/TextHologram.java +++ b/src/main/java/com/maximde/hologramapi/hologram/TextHologram.java @@ -31,6 +31,7 @@ import java.util.*; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.ThreadLocalRandom; public class TextHologram { @@ -100,11 +101,13 @@ public interface Internal { * Use TextHologram#telport(Location) if you want to move the hologram instead! * @param location */ - void setLocation(Location location); - void setDead(boolean dead); - void setEntityId(int entityId); - void sendPacket(PacketWrapper packet); - void updateAffectedPlayers(); + TextHologram setLocation(Location location); + TextHologram setDead(boolean dead); + TextHologram setEntityId(int entityId); + TextHologram sendPacket(PacketWrapper packet); + TextHologram updateAffectedPlayers(); + TextHologram copy(String id); + TextHologram copy(); } @@ -134,34 +137,84 @@ public TextHologram(String id) { this.internalAccess = new InternalSetters(); } + /** + * Creates a copy of this hologram with a new ID. + * The new ID will be the original ID with '_copy_' appended. + * @return A new TextHologram instance with copied properties + */ + private TextHologram copy() { + int randomNumber = ThreadLocalRandom.current().nextInt(100000); + return this.copy(this.id + "_copy_" + randomNumber); + } + + /** + * Creates a copy of this hologram with a new ID. + * + * @return A new TextHologram instance with copied properties + */ + private TextHologram copy(String id) { + TextHologram copy = new TextHologram(id, this.renderMode); + copy.text = this.text; + copy.scale = new Vector3f(this.scale); + copy.translation = new Vector3f(this.translation); + copy.rightRotation = new Quaternion4f(this.rightRotation.getX(), this.rightRotation.getY(), + this.rightRotation.getZ(), this.rightRotation.getW()); + copy.leftRotation = new Quaternion4f(this.leftRotation.getX(), this.leftRotation.getY(), + this.leftRotation.getZ(), this.leftRotation.getW()); + copy.billboard = this.billboard; + copy.interpolationDurationRotation = this.interpolationDurationRotation; + copy.interpolationDurationTransformation = this.interpolationDurationTransformation; + copy.viewRange = this.viewRange; + copy.shadow = this.shadow; + copy.maxLineWidth = this.maxLineWidth; + copy.backgroundColor = this.backgroundColor; + copy.seeThroughBlocks = this.seeThroughBlocks; + copy.alignment = this.alignment; + copy.textOpacity = this.textOpacity; + copy.updateTaskPeriod = this.updateTaskPeriod; + copy.nearbyEntityScanningDistance = this.nearbyEntityScanningDistance; + return copy; + } + private class InternalSetters implements Internal { @Override - public void setLocation(Location location) { + public TextHologram setLocation(Location location) { if (location == null) { throw new IllegalArgumentException("Location cannot be null"); } TextHologram.this.location = location; + return TextHologram.this; } @Override - public void setDead(boolean dead) { + public TextHologram setDead(boolean dead) { TextHologram.this.dead = dead; + return TextHologram.this; } @Override - public void setEntityId(int entityId) { + public TextHologram setEntityId(int entityId) { TextHologram.this.entityID = entityId; + return TextHologram.this; } @Override - public void sendPacket(PacketWrapper packet) { + public TextHologram sendPacket(PacketWrapper packet) { TextHologram.this.sendPacket(packet); + return TextHologram.this; } @Override - public void updateAffectedPlayers() { + public TextHologram updateAffectedPlayers() { TextHologram.this.updateAffectedPlayers(); + return TextHologram.this; } + + @Override + public TextHologram copy(String id) { TextHologram.this.copy(id); return TextHologram.this;} + + @Override + public TextHologram copy() { TextHologram.this.copy(); return TextHologram.this;} } private void validateId(String id) {