Skip to content

Instantly share code, notes, and snippets.

@mtbarr
Created November 6, 2020 10:12
Show Gist options
  • Save mtbarr/ee99a46e20d39e260e2ed1649a54ceb2 to your computer and use it in GitHub Desktop.
Save mtbarr/ee99a46e20d39e260e2ed1649a54ceb2 to your computer and use it in GitHub Desktop.
package io.github.ninjaservices.factions.util.hologram;
import lombok.AccessLevel;
import lombok.Getter;
import net.minecraft.server.v1_8_R3.*;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.entity.Player;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
@Getter
public class Hologram {
private static final int DEFAULT_RANGE = 128;
private String hologramId;
private Location originLocation;
@Getter(AccessLevel.NONE)
private List<EntityArmorStand> lines;
private Set<String> viewers;
private long expireTime;
public Hologram(Location originLocation) {
this.hologramId = Long.toHexString(System.nanoTime());
this.originLocation = originLocation;
this.lines = new ArrayList<>();
this.expireTime = System.currentTimeMillis() + (1_500);
}
public void expireIn(double seconds){
this.expireTime = (long) (System.currentTimeMillis() + (seconds + 1000L));
}
public boolean isExpired(){
return System.currentTimeMillis() >= expireTime;
}
public String getLine(int index) {
EntityArmorStand stand = this.getStand(index);
if (stand == null) {
return null;
}
return stand.getCustomName();
}
public void addLine(String line) {
int distanceMultiplier = lines.size();
spawn(originLocation.clone().subtract(0, -0.2 * distanceMultiplier, 0) , line);
}
public void setLine(int index, String text) {
EntityArmorStand stand = this.getStand(index);
if (stand == null) {
return;
}
stand.setCustomName(text);
sendPacketToViewers(new PacketPlayOutEntityMetadata(stand.getId(), stand.getDataWatcher(), false));
}
public void teleport(Location location) {
this.originLocation = location;
double y = 0;
for (int i = 0, linesSize = lines.size(); i < linesSize; i++) {
EntityArmorStand line = lines.get(i);
line.locX = location.getX();
line.locY = location.getY() - y;
line.locZ = location.getZ();
y += 0.2;
sendPacketToViewers(new PacketPlayOutEntityTeleport(line));
}
}
public void destroy() {
for (EntityArmorStand line : lines) {
sendPacketToViewers(new PacketPlayOutEntityDestroy(line.getId()));
}
}
EntityArmorStand spawn(Location location , String text) {
WorldServer handle = ((CraftWorld) location.getWorld()).getHandle();
EntityArmorStand entityArmorStand = new EntityArmorStand(handle);
entityArmorStand.setCustomName(text);
entityArmorStand.setCustomNameVisible(true);
entityArmorStand.setInvisible(true);
entityArmorStand.setSmall(true);
entityArmorStand.locX = location.getX();
entityArmorStand.locY = location.getY();
entityArmorStand.locZ = location.getZ();
sendPacketToViewers(new PacketPlayOutSpawnEntityLiving(entityArmorStand));
lines.add(entityArmorStand);
return entityArmorStand;
}
private void sendPacketToViewers(Packet<?> packet) {
Collection<? extends Player> onlinePlayers = Bukkit.getOnlinePlayers();
for (Player player : onlinePlayers) {
if(distance(originLocation,player.getLocation()) <= DEFAULT_RANGE){
sendPacket(player, packet);
}
}
}
private void sendPacket(Player player, Packet<?> packet) {
((CraftPlayer) player).getHandle()
.playerConnection
.sendPacket(packet);
}
@Nullable
EntityArmorStand getStand(int index) {
try {
return lines.get(index);
} catch (Exception e) {
return null;
}
}
public double distance(Location a, Location b){
return Math.sqrt(
square(a.getX() - b.getX())
+ square(a.getY() - b.getY())
+ square(a.getZ() - b.getZ())
);
}
private double square(double x){
return x * x;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment