Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Api] Hologram Service Update #4255

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ public enum MinecraftVersion {
*/
MINECRAFT_1_19(19, "1.19.x"),

/**
* This constant represents Minecraft (Java Edition) Version 1.19.4
* This minor update added display entities
*/
MINECRAFT_1_19_4(19, 4, "1.19.4"),

/**
* This constant represents Minecraft (Java Edition) Version 1.20
* ("The Trails & Tales Update")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,52 +14,73 @@
/**
* This {@link ItemAttribute} manages holograms.
*
* @author TheBusyBiscuit
* @author TheBusyBiscuit, JustAHuman
*
* @see HologramProjector
* @see HologramsService
*
*/
public interface HologramOwner extends ItemAttribute {
/**
* This returns the offset of the hologram as a {@link Vector}.
* This offset is applied to {@link Block#getLocation()} when spawning
* the hologram.
*
* @param block
* The {@link Block} which serves as the origin point
*
* @return The hologram offset
*/
@Nonnull
default Vector getHologramOffset(@Nonnull Block block) {
return Slimefun.getHologramsService().getDefaultOffset();
}

/**
* This will update the hologram text for the given {@link Block}.
*
* @param b
* @param block
* The {@link Block} to which the hologram belongs
*
* @param text
* The nametag for the hologram
* The text for the hologram
*/
default void updateHologram(@Nonnull Block b, @Nonnull String text) {
Location loc = b.getLocation().add(getHologramOffset(b));
Slimefun.getHologramsService().setHologramLabel(loc, ChatColors.color(text));
default void updateHologram(@Nonnull Block block, @Nonnull String text) {
Location location = block.getLocation();
if (Slimefun.getTickerTask().isDeletedSoon(location)) {
return;
}

Slimefun.getHologramsService().setHologramLabel(location.add(getHologramOffset(block)), ChatColors.color(text));
}

/**
* This will remove the hologram for the given {@link Block}.
*
* @param b
* The {@link Block} to which the hologram blocks
* This will update the hologram text for the given {@link Block}.
*
* @param block
* The {@link Block} to which the hologram belongs
*
* @param offset
* The new offset for the hologram
*/
default void removeHologram(@Nonnull Block b) {
Location loc = b.getLocation().add(getHologramOffset(b));
Slimefun.getHologramsService().removeHologram(loc);
default void setOffset(@Nonnull Block block, @Nonnull Vector offset) {
Location location = block.getLocation();
if (Slimefun.getTickerTask().isDeletedSoon(location)) {
return;
}

Location hologramLocation = location.clone().add(getHologramOffset(block));
Location newHologramLocation = location.clone().add(offset);
Slimefun.getHologramsService().teleportHologram(hologramLocation, newHologramLocation);
}

/**
* This returns the offset of the hologram as a {@link Vector}.
* This offset is applied to {@link Block#getLocation()} when spawning
* the hologram.
* This will remove the hologram for the given {@link Block}.
*
* @param block
* The {@link Block} which serves as the origin point
*
* @return The hologram offset
* The {@link Block} to which the hologram blocks
*/
@Nonnull
default Vector getHologramOffset(@Nonnull Block block) {
return Slimefun.getHologramsService().getDefaultOffset();
default void removeHologram(@Nonnull Block block) {
Location location = block.getLocation().add(getHologramOffset(block));
Slimefun.getHologramsService().removeHologram(location);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package io.github.thebusybiscuit.slimefun4.core.services.holograms;

import io.github.bakedlibs.dough.blocks.BlockPosition;
import io.github.bakedlibs.dough.data.persistent.PersistentDataAPI;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.utils.ArmorStandUtils;
import org.bukkit.Location;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Entity;

import java.util.Objects;

public class ArmorStandHologram extends Hologram {
private ArmorStandHologram(ArmorStand entity) {
super(entity.getUniqueId());
}

@Override
public void setText(String text) {
this.lastAccess = System.currentTimeMillis();
if (Objects.equals(this.text, text)) {
return;
}

Entity entity = getEntity();
if (entity != null) {
entity.setCustomName(text);
entity.setCustomNameVisible(text != null);
}
}

@Override
public Class<ArmorStand> getEntityType() {
return ArmorStand.class;
}

static ArmorStandHologram of(Entity entity, BlockPosition position) {
if (!(entity instanceof ArmorStand armorStand)) {
return null;
}

armorStand.setAI(false);
armorStand.setInvulnerable(true);
ArmorStandUtils.setupArmorStand(armorStand);
PersistentDataAPI.setLong(entity, Slimefun.getHologramsService().getKey(), position.getPosition());
return new ArmorStandHologram(armorStand);
}

static ArmorStandHologram create(Location location, BlockPosition position) {
ArmorStand armorStand = location.getWorld().spawn(location, ArmorStand.class);
return of(armorStand, position);
}
}
Original file line number Diff line number Diff line change
@@ -1,135 +1,95 @@
package io.github.thebusybiscuit.slimefun4.core.services.holograms;

import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import org.bukkit.Bukkit;
import org.bukkit.entity.ArmorStand;
import org.bukkit.Location;
import org.bukkit.entity.Entity;

/**
* This represents an {@link ArmorStand} that can expire and be renamed.
* A {@link Hologram} is a wrapper around an {@link Entity}
* for displaying text as "holograms".
*
* @author TheBusyBiscuit
*
* @author TheBusyBiscuit, JustAHuman
*/
class Hologram {

/**
* This is the minimum duration after which the {@link Hologram} will expire.
*/
abstract class Hologram {
private static final long EXPIRES_AFTER = TimeUnit.MINUTES.toMillis(10);

/**
* The {@link UUID} of the {@link ArmorStand}.
*/
private final UUID uniqueId;

/**
* The timestamp of when the {@link ArmorStand} was last accessed.
*/
private long lastAccess;

/**
* The label of this {@link Hologram}.
*/
private String label;
protected final UUID uniqueId;
protected long lastAccess;
protected String text;

/**
* This creates a new {@link Hologram} for the given {@link UUID}.
*
* @param uniqueId
* The {@link UUID} of the corresponding {@link ArmorStand}
* The {@link UUID} of the corresponding {@link Entity}
*/
Hologram(@Nonnull UUID uniqueId) {
protected Hologram(@Nonnull UUID uniqueId) {
this.uniqueId = uniqueId;
this.lastAccess = System.currentTimeMillis();
}

/**
* This returns the corresponding {@link ArmorStand}
* and also updates the "lastAccess" timestamp.
* <p>
* If the {@link ArmorStand} was removed, it will return null.
*
* @return The {@link ArmorStand} or null.
*/
@Nullable
ArmorStand getArmorStand() {
Entity n = Bukkit.getEntity(uniqueId);

if (n instanceof ArmorStand armorStand && n.isValid()) {
this.lastAccess = System.currentTimeMillis();
return armorStand;
} else {
this.lastAccess = 0;
return null;
}
}
public abstract void setText(@Nullable String text);
public abstract Class<? extends Entity> getEntityType();

/**
* This checks if the associated {@link ArmorStand} has despawned.
*
* @return Whether the {@link ArmorStand} despawned
* @return Whether the associated {@link Entity} has despawned.
*/
boolean hasDespawned() {
return getArmorStand() == null;
public boolean hasDespawned() {
return getEntity() == null;
}

/**
* This returns whether this {@link Hologram} has expired.
* The armorstand will expire if the last access has been more than 10
* minutes ago.
*
* The {@link Hologram} has expired if the last access was
* more than 10 minutes ago.
*
* @return Whether this {@link Hologram} has expired
*/
boolean hasExpired() {
public boolean hasExpired() {
return System.currentTimeMillis() - lastAccess > EXPIRES_AFTER;
}

/**
* This method sets the label of this {@link Hologram}.
* This returns the corresponding {@link Entity}
* and also updates the "lastAccess" timestamp.
* <p>
* If the entity was removed, it will return null.
*
* @param label
* The label to set
* @return The {@link Entity} or null.
*/
void setLabel(@Nullable String label) {
if (Objects.equals(this.label, label)) {
/*
* Label is already set, no need to cause an entity
* update. But we can update the lastAccess flag.
*/
@Nullable
public Entity getEntity() {
Entity entity = Bukkit.getEntity(uniqueId);
if (getEntityType().isInstance(entity) && entity.isValid()) {
this.lastAccess = System.currentTimeMillis();
return getEntityType().cast(entity);
} else {
this.label = label;
ArmorStand entity = getArmorStand();
this.lastAccess = 0;
return null;
}
}

if (entity != null) {
if (label != null) {
entity.setCustomNameVisible(true);
entity.setCustomName(label);
} else {
entity.setCustomNameVisible(false);
entity.setCustomName(null);
}
}
public void teleport(Location location) {
Entity getEntity = getEntity();
if (getEntity != null) {
getEntity.teleport(location);
}
}

/**
* This will remove the {@link ArmorStand} and expire this {@link Hologram}.
* This will remove the {@link Entity} and expire this {@link Hologram}.
*/
void remove() {
ArmorStand armorstand = getArmorStand();

if (armorstand != null) {
public void remove() {
Entity entity = getEntity();
if (entity != null) {
lastAccess = 0;
armorstand.remove();
entity.remove();
}
}

}
Loading