Citizens2/main/src/main/java/net/citizensnpcs/trait/HologramTrait.java

209 lines
6.1 KiB
Java
Raw Normal View History

2020-06-30 12:17:14 +02:00
package net.citizensnpcs.trait;
2020-07-03 09:14:55 +02:00
import java.util.List;
import org.bukkit.Location;
2020-06-30 12:17:14 +02:00
import org.bukkit.entity.EntityType;
2020-07-03 09:14:55 +02:00
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import com.google.common.collect.Lists;
2020-06-30 12:17:14 +02:00
2020-07-03 09:14:55 +02:00
import net.citizensnpcs.Settings.Setting;
2020-06-30 12:17:14 +02:00
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.npc.MemoryNPCDataStore;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.npc.NPCRegistry;
import net.citizensnpcs.api.persistence.Persist;
import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.trait.TraitName;
import net.citizensnpcs.api.util.Placeholders;
2020-07-06 02:42:46 +02:00
import net.citizensnpcs.util.NMS;
2020-06-30 12:17:14 +02:00
/**
* Persists a hologram attached to the NPC.
*/
@TraitName("hologramtrait")
public class HologramTrait extends Trait {
2020-07-03 09:14:55 +02:00
private Location currentLoc;
2020-07-27 11:34:07 +02:00
@Persist
private HologramDirection direction = HologramDirection.BOTTOM_UP;
2020-07-03 09:14:55 +02:00
private final List<NPC> hologramNPCs = Lists.newArrayList();
2020-06-30 12:17:14 +02:00
@Persist
2020-07-03 09:14:55 +02:00
private double lineHeight = -1;
@Persist
private final List<String> lines = Lists.newArrayList();
private NPC nameNPC;
2020-07-03 09:14:55 +02:00
private final NPCRegistry registry = CitizensAPI.createAnonymousNPCRegistry(new MemoryNPCDataStore());
2020-06-30 12:17:14 +02:00
public HologramTrait() {
super("hologramtrait");
}
2020-07-03 09:14:55 +02:00
public void addLine(String text) {
lines.add(text);
unload();
load();
}
2020-07-06 19:07:01 +02:00
public void clear() {
unload();
lines.clear();
}
private NPC createHologram(String line, double heightOffset) {
NPC hologramNPC = registry.createNPC(EntityType.ARMOR_STAND, line);
hologramNPC.addTrait(new ClickRedirectTrait(npc));
2020-09-14 11:57:58 +02:00
ArmorStandTrait trait = hologramNPC.getOrAddTrait(ArmorStandTrait.class);
trait.setVisible(false);
trait.setSmall(true);
trait.setMarker(true);
trait.setGravity(false);
trait.setHasArms(false);
trait.setHasBaseplate(false);
2020-07-27 11:34:07 +02:00
hologramNPC.spawn(currentLoc.clone().add(0,
getEntityHeight()
+ (direction == HologramDirection.BOTTOM_UP ? heightOffset : getMaxHeight() - heightOffset),
0));
return hologramNPC;
}
2020-10-07 13:16:41 +02:00
public HologramDirection getDirection() {
return direction;
}
2020-07-06 02:42:46 +02:00
private double getEntityHeight() {
return NMS.getHeight(npc.getEntity());
}
2020-07-03 09:14:55 +02:00
private double getHeight(int lineNumber) {
return (lineHeight == -1 ? Setting.DEFAULT_NPC_HOLOGRAM_LINE_HEIGHT.asDouble() : lineHeight) * (lineNumber + 1);
2020-07-03 09:14:55 +02:00
}
2020-10-07 13:16:41 +02:00
public double getLineHeight() {
return lineHeight;
}
2020-07-03 09:14:55 +02:00
public List<String> getLines() {
return lines;
}
2020-07-27 11:34:07 +02:00
private double getMaxHeight() {
return (lineHeight == -1 ? Setting.DEFAULT_NPC_HOLOGRAM_LINE_HEIGHT.asDouble() : lineHeight)
2020-08-11 16:47:45 +02:00
* (lines.size() + (npc.requiresNameHologram() ? 0 : 1));
2020-07-27 11:34:07 +02:00
}
2020-07-03 09:14:55 +02:00
private void load() {
currentLoc = npc.getStoredLocation();
int i = 0;
2020-07-10 06:28:39 +02:00
if (npc.requiresNameHologram()
&& Boolean.parseBoolean(npc.data().<Object> get(NPC.NAMEPLATE_VISIBLE_METADATA, true).toString())) {
nameNPC = createHologram(npc.getFullName(), 0);
}
2020-07-03 09:14:55 +02:00
for (String line : lines) {
hologramNPCs.add(createHologram(Placeholders.replace(line, null, npc), getHeight(i)));
2020-07-03 09:14:55 +02:00
i++;
}
}
2020-06-30 12:17:14 +02:00
@Override
public void onDespawn() {
2020-07-03 09:14:55 +02:00
unload();
2020-06-30 12:17:14 +02:00
}
@Override
public void onRemove() {
unload();
}
2020-06-30 12:17:14 +02:00
@Override
public void onSpawn() {
2020-07-03 09:14:55 +02:00
load();
}
public void removeLine(int idx) {
lines.remove(idx);
unload();
load();
2020-06-30 12:17:14 +02:00
}
@Override
public void run() {
2020-07-03 09:14:55 +02:00
if (!npc.isSpawned()) {
unload();
2020-06-30 12:17:14 +02:00
return;
}
2020-07-10 06:19:29 +02:00
if (npc.requiresNameHologram()) {
2020-07-10 06:28:39 +02:00
boolean visible = Boolean
.parseBoolean(npc.data().<Object> get(NPC.NAMEPLATE_VISIBLE_METADATA, true).toString());
2020-07-10 06:19:29 +02:00
if (nameNPC != null && !visible) {
nameNPC.destroy();
nameNPC = null;
} else if (nameNPC == null && visible) {
nameNPC = createHologram(npc.getFullName(), 0);
}
}
2020-11-03 07:36:44 +01:00
boolean update = currentLoc.getWorld() != npc.getStoredLocation().getWorld()
|| currentLoc.distanceSquared(npc.getStoredLocation()) >= 0.01;
2020-07-03 09:14:55 +02:00
if (update) {
currentLoc = npc.getStoredLocation();
}
if (nameNPC != null && nameNPC.isSpawned()) {
if (update) {
nameNPC.teleport(currentLoc.clone().add(0, getEntityHeight(), 0), TeleportCause.PLUGIN);
}
nameNPC.setName(npc.getFullName());
}
2020-07-03 09:14:55 +02:00
for (int i = 0; i < hologramNPCs.size(); i++) {
NPC hologramNPC = hologramNPCs.get(i);
if (!hologramNPC.isSpawned())
2020-07-03 09:14:55 +02:00
continue;
if (update) {
2020-07-06 02:42:46 +02:00
hologramNPC.teleport(currentLoc.clone().add(0, getEntityHeight() + getHeight(i), 0),
2020-07-03 09:14:55 +02:00
TeleportCause.PLUGIN);
}
String text = lines.get(i);
if (text != null && !text.isEmpty()) {
hologramNPC.setName(Placeholders.replace(text, null, npc));
hologramNPC.data().set(NPC.NAMEPLATE_VISIBLE_METADATA, true);
2020-07-03 09:14:55 +02:00
} else {
2020-11-07 08:10:49 +01:00
hologramNPC.setName("");
hologramNPC.data().set(NPC.NAMEPLATE_VISIBLE_METADATA, false);
2020-07-03 09:14:55 +02:00
}
2020-06-30 12:17:14 +02:00
}
}
2020-07-27 11:34:07 +02:00
public void setDirection(HologramDirection direction) {
this.direction = direction;
unload();
load();
}
2020-07-03 09:14:55 +02:00
public void setLine(int idx, String text) {
2020-08-11 16:57:32 +02:00
if (idx == lines.size()) {
lines.add(idx, text);
} else {
lines.set(idx, text);
}
2020-07-03 09:14:55 +02:00
}
public void setLineHeight(double height) {
lineHeight = height;
2020-06-30 12:17:14 +02:00
}
2020-07-03 09:14:55 +02:00
private void unload() {
if (nameNPC != null) {
nameNPC.destroy();
nameNPC = null;
}
2020-07-03 09:14:55 +02:00
for (NPC npc : hologramNPCs) {
npc.destroy();
}
hologramNPCs.clear();
}
2020-07-27 11:34:07 +02:00
public enum HologramDirection {
BOTTOM_UP,
TOP_DOWN;
}
2020-06-30 12:17:14 +02:00
}