2020-06-30 12:17:14 +02:00
|
|
|
package net.citizensnpcs.trait;
|
|
|
|
|
2021-06-03 14:36:45 +02:00
|
|
|
import java.util.Collection;
|
2020-07-03 09:14:55 +02:00
|
|
|
import java.util.List;
|
2021-12-27 16:59:21 +01:00
|
|
|
import java.util.regex.Matcher;
|
|
|
|
import java.util.regex.Pattern;
|
2020-07-03 09:14:55 +02:00
|
|
|
|
2020-11-17 04:39:24 +01:00
|
|
|
import org.bukkit.ChatColor;
|
2020-07-03 09:14:55 +02:00
|
|
|
import org.bukkit.Location;
|
2021-12-27 16:59:21 +01:00
|
|
|
import org.bukkit.Material;
|
2021-06-03 14:36:45 +02:00
|
|
|
import org.bukkit.entity.ArmorStand;
|
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;
|
2021-12-27 16:59:21 +01:00
|
|
|
import org.bukkit.inventory.ItemStack;
|
2020-07-03 09:14:55 +02:00
|
|
|
|
2021-06-03 14:36:45 +02:00
|
|
|
import com.google.common.collect.Collections2;
|
2020-07-03 09:14:55 +02:00
|
|
|
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;
|
2020-11-17 04:39:24 +01:00
|
|
|
import net.citizensnpcs.api.util.Colorizer;
|
2022-09-03 18:22:20 +02:00
|
|
|
import net.citizensnpcs.api.util.DataKey;
|
2021-07-04 07:07:15 +02:00
|
|
|
import net.citizensnpcs.api.util.Messaging;
|
2020-06-30 12:17:14 +02:00
|
|
|
import net.citizensnpcs.api.util.Placeholders;
|
2022-08-12 07:48:54 +02:00
|
|
|
import net.citizensnpcs.api.util.SpigotUtil;
|
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;
|
2022-04-21 09:25:57 +02:00
|
|
|
private double lastEntityHeight = 0;
|
2021-09-21 10:12:15 +02:00
|
|
|
private boolean lastNameplateVisible;
|
2020-06-30 12:17:14 +02:00
|
|
|
@Persist
|
2020-07-03 09:14:55 +02:00
|
|
|
private double lineHeight = -1;
|
2021-09-05 08:59:19 +02:00
|
|
|
private final List<NPC> lineHolograms = Lists.newArrayList();
|
2022-09-03 18:22:20 +02:00
|
|
|
private final List<HologramLine> lines = Lists.newArrayList();
|
2020-07-06 10:37:34 +02:00
|
|
|
private NPC nameNPC;
|
2021-02-04 03:10:48 +01:00
|
|
|
private final NPCRegistry registry = CitizensAPI.createCitizensBackedNPCRegistry(new MemoryNPCDataStore());
|
2020-06-30 12:17:14 +02:00
|
|
|
|
|
|
|
public HologramTrait() {
|
|
|
|
super("hologramtrait");
|
|
|
|
}
|
|
|
|
|
2021-06-03 14:36:45 +02:00
|
|
|
/**
|
|
|
|
* Adds a new hologram line which will displayed over an NPC's head.
|
|
|
|
*
|
|
|
|
* @param text
|
|
|
|
* The new line to add
|
|
|
|
*/
|
2020-07-03 09:14:55 +02:00
|
|
|
public void addLine(String text) {
|
2022-09-03 18:22:20 +02:00
|
|
|
lines.add(new HologramLine(text, true));
|
2022-04-24 20:22:39 +02:00
|
|
|
reloadLineHolograms();
|
2020-07-03 09:14:55 +02:00
|
|
|
}
|
|
|
|
|
2022-09-03 18:22:20 +02:00
|
|
|
/**
|
|
|
|
* Adds a new hologram line which will displayed over an NPC's head. It will not persist to disk and will last for
|
|
|
|
* the specified amount of ticks.
|
|
|
|
*
|
|
|
|
* @param text
|
|
|
|
* The new line to add
|
|
|
|
* @param ticks
|
|
|
|
* The number of ticks to last for
|
|
|
|
*/
|
|
|
|
public void addTemporaryLine(String text, int ticks) {
|
|
|
|
lines.add(new HologramLine(text, false, ticks));
|
|
|
|
}
|
|
|
|
|
2021-06-03 14:36:45 +02:00
|
|
|
/**
|
|
|
|
* Clears all hologram lines
|
|
|
|
*/
|
2020-07-06 19:07:01 +02:00
|
|
|
public void clear() {
|
|
|
|
lines.clear();
|
2022-04-24 20:22:39 +02:00
|
|
|
reloadLineHolograms();
|
2020-07-06 19:07:01 +02:00
|
|
|
}
|
|
|
|
|
2020-07-06 10:37:34 +02:00
|
|
|
private NPC createHologram(String line, double heightOffset) {
|
|
|
|
NPC hologramNPC = registry.createNPC(EntityType.ARMOR_STAND, line);
|
2022-10-04 16:18:05 +02:00
|
|
|
hologramNPC.getOrAddTrait(ArmorStandTrait.class).setAsHelperEntityWithName(npc);
|
2020-07-27 11:34:07 +02:00
|
|
|
hologramNPC.spawn(currentLoc.clone().add(0,
|
|
|
|
getEntityHeight()
|
|
|
|
+ (direction == HologramDirection.BOTTOM_UP ? heightOffset : getMaxHeight() - heightOffset),
|
|
|
|
0));
|
2021-12-27 16:59:21 +01:00
|
|
|
Matcher itemMatcher = ITEM_MATCHER.matcher(line);
|
|
|
|
if (itemMatcher.matches()) {
|
2022-08-12 07:48:54 +02:00
|
|
|
Material item = SpigotUtil.isUsing1_13API() ? Material.matchMaterial(itemMatcher.group(1), false)
|
|
|
|
: Material.matchMaterial(itemMatcher.group(1));
|
2021-12-27 16:59:21 +01:00
|
|
|
NPC itemNPC = registry.createNPCUsingItem(EntityType.DROPPED_ITEM, "", new ItemStack(item, 1));
|
|
|
|
itemNPC.spawn(currentLoc);
|
|
|
|
((ArmorStand) hologramNPC.getEntity()).addPassenger(itemNPC.getEntity());
|
|
|
|
itemNPC.addRunnable(new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
if (!itemNPC.isSpawned() || !itemNPC.getEntity().isInsideVehicle()) {
|
|
|
|
itemNPC.destroy();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2022-04-21 09:25:57 +02:00
|
|
|
lastEntityHeight = getEntityHeight();
|
2020-07-06 10:37:34 +02:00
|
|
|
return hologramNPC;
|
|
|
|
}
|
|
|
|
|
2021-06-03 14:36:45 +02:00
|
|
|
/**
|
|
|
|
* @return The direction that hologram lines are displayed in
|
|
|
|
*/
|
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) {
|
2022-08-12 07:48:54 +02:00
|
|
|
return getLineHeight() * (lastNameplateVisible ? lineNumber + 1 : lineNumber);
|
2020-07-03 09:14:55 +02:00
|
|
|
}
|
|
|
|
|
2021-06-03 14:36:45 +02:00
|
|
|
/**
|
|
|
|
* Note: this is implementation-specific and may be removed at a later date.
|
|
|
|
*/
|
|
|
|
public Collection<ArmorStand> getHologramEntities() {
|
2021-09-05 08:59:19 +02:00
|
|
|
return Collections2.transform(lineHolograms, (n) -> (ArmorStand) n.getEntity());
|
2021-06-03 14:36:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return The line height between each hologram line, in blocks
|
|
|
|
*/
|
2020-10-07 13:16:41 +02:00
|
|
|
public double getLineHeight() {
|
2022-08-12 07:48:54 +02:00
|
|
|
return lineHeight == -1 ? Setting.DEFAULT_NPC_HOLOGRAM_LINE_HEIGHT.asDouble() : lineHeight;
|
2020-10-07 13:16:41 +02:00
|
|
|
}
|
|
|
|
|
2021-06-03 14:36:45 +02:00
|
|
|
/**
|
|
|
|
* @return the hologram lines, in bottom-up order
|
|
|
|
*/
|
2020-07-03 09:14:55 +02:00
|
|
|
public List<String> getLines() {
|
2022-09-03 18:22:20 +02:00
|
|
|
return Lists.transform(lines, (l) -> l.text);
|
2020-07-03 09:14:55 +02:00
|
|
|
}
|
|
|
|
|
2020-07-27 11:34:07 +02:00
|
|
|
private double getMaxHeight() {
|
2022-08-12 07:48:54 +02:00
|
|
|
return getLineHeight() * (lines.size() + (lastNameplateVisible ? 1 : -1));
|
2020-07-27 11:34:07 +02:00
|
|
|
}
|
|
|
|
|
2021-06-03 14:36:45 +02:00
|
|
|
/**
|
|
|
|
* Note: this is implementation-specific and may be removed at a later date.
|
|
|
|
*/
|
|
|
|
public ArmorStand getNameEntity() {
|
2021-09-17 13:04:52 +02:00
|
|
|
return nameNPC != null && nameNPC.isSpawned() ? ((ArmorStand) nameNPC.getEntity()) : null;
|
2021-06-03 14:36:45 +02:00
|
|
|
}
|
|
|
|
|
2022-09-03 18:22:20 +02:00
|
|
|
@Override
|
|
|
|
public void load(DataKey root) {
|
|
|
|
lines.clear();
|
|
|
|
for (DataKey key : root.getRelative("lines").getIntegerSubKeys()) {
|
|
|
|
lines.add(new HologramLine(key.getString(""), true));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-30 12:17:14 +02:00
|
|
|
@Override
|
|
|
|
public void onDespawn() {
|
2021-07-04 07:07:15 +02:00
|
|
|
if (nameNPC != null) {
|
|
|
|
nameNPC.destroy();
|
|
|
|
nameNPC = null;
|
|
|
|
}
|
2021-09-05 08:59:19 +02:00
|
|
|
for (NPC npc : lineHolograms) {
|
2021-07-04 07:07:15 +02:00
|
|
|
npc.destroy();
|
|
|
|
}
|
2021-09-05 08:59:19 +02:00
|
|
|
lineHolograms.clear();
|
2020-06-30 12:17:14 +02:00
|
|
|
}
|
|
|
|
|
2020-07-03 16:59:18 +02:00
|
|
|
@Override
|
|
|
|
public void onRemove() {
|
2021-07-04 07:07:15 +02:00
|
|
|
onDespawn();
|
2020-07-03 16:59:18 +02:00
|
|
|
}
|
|
|
|
|
2020-06-30 12:17:14 +02:00
|
|
|
@Override
|
|
|
|
public void onSpawn() {
|
2021-08-27 11:30:27 +02:00
|
|
|
if (!npc.isSpawned())
|
|
|
|
return;
|
2021-09-21 10:12:15 +02:00
|
|
|
lastNameplateVisible = Boolean
|
2022-03-23 13:57:18 +01:00
|
|
|
.parseBoolean(npc.data().<Object> get(NPC.Metadata.NAMEPLATE_VISIBLE, true).toString());
|
2021-07-04 07:07:15 +02:00
|
|
|
currentLoc = npc.getStoredLocation();
|
2021-09-21 10:12:15 +02:00
|
|
|
if (npc.requiresNameHologram() && lastNameplateVisible) {
|
2021-07-04 07:07:15 +02:00
|
|
|
nameNPC = createHologram(npc.getFullName(), 0);
|
|
|
|
}
|
2022-04-24 20:22:39 +02:00
|
|
|
|
|
|
|
for (int i = 0; i < lines.size(); i++) {
|
2022-09-03 18:22:20 +02:00
|
|
|
lineHolograms.add(createHologram(Placeholders.replace(lines.get(i).text, null, npc), getHeight(i)));
|
2022-04-24 20:22:39 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void reloadLineHolograms() {
|
|
|
|
for (NPC npc : lineHolograms) {
|
|
|
|
npc.destroy();
|
|
|
|
}
|
|
|
|
lineHolograms.clear();
|
|
|
|
|
|
|
|
if (!npc.isSpawned())
|
|
|
|
return;
|
2022-09-03 18:22:20 +02:00
|
|
|
|
2021-07-04 07:07:15 +02:00
|
|
|
for (int i = 0; i < lines.size(); i++) {
|
2022-09-03 18:22:20 +02:00
|
|
|
lineHolograms.add(createHologram(Placeholders.replace(lines.get(i).text, null, npc), getHeight(i)));
|
2021-07-04 07:07:15 +02:00
|
|
|
}
|
2020-07-03 09:14:55 +02:00
|
|
|
}
|
|
|
|
|
2021-06-03 14:36:45 +02:00
|
|
|
/**
|
|
|
|
* Removes the line at the specified index
|
|
|
|
*
|
|
|
|
* @param idx
|
|
|
|
*/
|
2020-07-03 09:14:55 +02:00
|
|
|
public void removeLine(int idx) {
|
2022-04-24 20:22:39 +02:00
|
|
|
if (idx < 0 || idx >= lines.size())
|
|
|
|
return;
|
|
|
|
|
2020-07-03 09:14:55 +02:00
|
|
|
lines.remove(idx);
|
2022-04-24 20:22:39 +02:00
|
|
|
|
|
|
|
reloadLineHolograms();
|
2020-06-30 12:17:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void run() {
|
2020-07-03 09:14:55 +02:00
|
|
|
if (!npc.isSpawned()) {
|
2021-07-04 07:07:15 +02:00
|
|
|
onDespawn();
|
2020-06-30 12:17:14 +02:00
|
|
|
return;
|
|
|
|
}
|
2022-04-23 07:42:48 +02:00
|
|
|
|
2021-09-05 08:59:19 +02:00
|
|
|
if (currentLoc == null) {
|
|
|
|
currentLoc = npc.getStoredLocation();
|
|
|
|
}
|
2022-04-23 07:42:48 +02:00
|
|
|
|
2021-09-21 10:12:15 +02:00
|
|
|
boolean nameplateVisible = Boolean
|
2022-03-23 13:57:18 +01:00
|
|
|
.parseBoolean(npc.data().<Object> get(NPC.Metadata.NAMEPLATE_VISIBLE, true).toString());
|
2020-07-10 06:19:29 +02:00
|
|
|
if (npc.requiresNameHologram()) {
|
2021-09-21 10:12:15 +02:00
|
|
|
if (nameNPC != null && !nameplateVisible) {
|
2020-07-10 06:19:29 +02:00
|
|
|
nameNPC.destroy();
|
|
|
|
nameNPC = null;
|
2021-09-21 10:12:15 +02:00
|
|
|
} else if (nameNPC == null && nameplateVisible) {
|
2020-07-10 06:19:29 +02:00
|
|
|
nameNPC = createHologram(npc.getFullName(), 0);
|
|
|
|
}
|
|
|
|
}
|
2022-04-23 07:42:48 +02:00
|
|
|
|
2020-11-03 07:36:44 +01:00
|
|
|
boolean update = currentLoc.getWorld() != npc.getStoredLocation().getWorld()
|
2022-04-21 09:25:57 +02:00
|
|
|
|| currentLoc.distance(npc.getStoredLocation()) >= 0.001 || lastNameplateVisible != nameplateVisible
|
2022-04-21 09:27:46 +02:00
|
|
|
|| Math.abs(lastEntityHeight - getEntityHeight()) >= 0.05;
|
2021-09-21 10:12:15 +02:00
|
|
|
lastNameplateVisible = nameplateVisible;
|
|
|
|
|
2020-07-03 09:14:55 +02:00
|
|
|
if (update) {
|
|
|
|
currentLoc = npc.getStoredLocation();
|
2022-04-21 09:25:57 +02:00
|
|
|
lastEntityHeight = getEntityHeight();
|
2020-07-03 09:14:55 +02:00
|
|
|
}
|
2022-04-23 07:42:48 +02:00
|
|
|
|
2020-07-06 10:37:34 +02:00
|
|
|
if (nameNPC != null && nameNPC.isSpawned()) {
|
|
|
|
if (update) {
|
|
|
|
nameNPC.teleport(currentLoc.clone().add(0, getEntityHeight(), 0), TeleportCause.PLUGIN);
|
|
|
|
}
|
|
|
|
nameNPC.setName(npc.getFullName());
|
|
|
|
}
|
2022-04-23 07:42:48 +02:00
|
|
|
|
2021-09-05 08:59:19 +02:00
|
|
|
for (int i = 0; i < lineHolograms.size(); i++) {
|
|
|
|
NPC hologramNPC = lineHolograms.get(i);
|
2020-07-06 10:37:34 +02:00
|
|
|
if (!hologramNPC.isSpawned())
|
2020-07-03 09:14:55 +02:00
|
|
|
continue;
|
2022-04-23 07:42:48 +02:00
|
|
|
|
2020-07-03 09:14:55 +02:00
|
|
|
if (update) {
|
2022-08-12 07:48:54 +02:00
|
|
|
hologramNPC.teleport(currentLoc.clone().add(0, lastEntityHeight
|
|
|
|
+ (direction == HologramDirection.BOTTOM_UP ? getHeight(i) : getMaxHeight() - getHeight(i)), 0),
|
2020-07-03 09:14:55 +02:00
|
|
|
TeleportCause.PLUGIN);
|
|
|
|
}
|
2022-04-23 07:42:48 +02:00
|
|
|
|
2021-07-04 07:07:15 +02:00
|
|
|
if (i >= lines.size()) {
|
2021-07-16 11:23:36 +02:00
|
|
|
Messaging.severe("More hologram NPCs than lines for ID", npc.getId(), "lines", lines);
|
2021-07-04 07:07:15 +02:00
|
|
|
break;
|
|
|
|
}
|
2022-04-23 07:42:48 +02:00
|
|
|
|
2022-09-03 18:22:20 +02:00
|
|
|
HologramLine line = lines.get(i);
|
|
|
|
if (line.ticks > 0 && --line.ticks == 0) {
|
|
|
|
lines.remove(i--);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
String text = line.text;
|
2021-12-27 16:59:21 +01:00
|
|
|
if (ITEM_MATCHER.matcher(text).matches()) {
|
|
|
|
text = null;
|
|
|
|
}
|
2022-04-23 07:42:48 +02:00
|
|
|
|
2020-11-17 04:39:24 +01:00
|
|
|
if (text != null && !ChatColor.stripColor(Colorizer.parseColors(text)).isEmpty()) {
|
2020-07-03 09:14:55 +02:00
|
|
|
hologramNPC.setName(Placeholders.replace(text, null, npc));
|
2022-03-23 13:57:18 +01:00
|
|
|
hologramNPC.data().set(NPC.Metadata.NAMEPLATE_VISIBLE, true);
|
2020-07-03 09:14:55 +02:00
|
|
|
} else {
|
2020-11-07 08:10:49 +01:00
|
|
|
hologramNPC.setName("");
|
2022-03-23 13:57:18 +01:00
|
|
|
hologramNPC.data().set(NPC.Metadata.NAMEPLATE_VISIBLE, "hover");
|
2020-07-03 09:14:55 +02:00
|
|
|
}
|
2020-06-30 12:17:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-03 18:22:20 +02:00
|
|
|
@Override
|
|
|
|
public void save(DataKey root) {
|
|
|
|
root.removeKey("lines");
|
|
|
|
int i = 0;
|
|
|
|
for (HologramLine line : lines) {
|
|
|
|
if (!line.persist)
|
|
|
|
continue;
|
|
|
|
root.setString("lines." + i, line.text);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-03 14:36:45 +02:00
|
|
|
/**
|
|
|
|
* @see #getDirection()
|
|
|
|
* @param direction
|
|
|
|
* The new direction
|
|
|
|
*/
|
2020-07-27 11:34:07 +02:00
|
|
|
public void setDirection(HologramDirection direction) {
|
|
|
|
this.direction = direction;
|
2022-04-24 20:22:39 +02:00
|
|
|
|
|
|
|
reloadLineHolograms();
|
2020-07-27 11:34:07 +02:00
|
|
|
}
|
|
|
|
|
2021-06-03 14:36:45 +02:00
|
|
|
/**
|
|
|
|
* Sets the hologram line at a specific index
|
|
|
|
*
|
|
|
|
* @param idx
|
|
|
|
* The index
|
|
|
|
* @param text
|
|
|
|
* The new line
|
|
|
|
*/
|
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()) {
|
2022-04-24 20:22:39 +02:00
|
|
|
addLine(text);
|
|
|
|
return;
|
2020-08-11 16:57:32 +02:00
|
|
|
}
|
2022-04-23 07:42:48 +02:00
|
|
|
|
2022-09-03 18:22:20 +02:00
|
|
|
lines.get(idx).text = text;
|
2022-04-24 20:22:39 +02:00
|
|
|
if (idx < lineHolograms.size()) {
|
|
|
|
lineHolograms.get(idx).setName(Placeholders.replace(text, null, npc));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
reloadLineHolograms();
|
2020-07-03 09:14:55 +02:00
|
|
|
}
|
|
|
|
|
2021-06-03 14:36:45 +02:00
|
|
|
/**
|
|
|
|
* Sets the line height
|
|
|
|
*
|
|
|
|
* @see #getLineHeight()
|
|
|
|
* @param height
|
|
|
|
* The line height in blocks
|
|
|
|
*/
|
2020-07-03 09:14:55 +02:00
|
|
|
public void setLineHeight(double height) {
|
|
|
|
lineHeight = height;
|
2022-04-24 20:22:39 +02:00
|
|
|
|
|
|
|
reloadLineHolograms();
|
2020-07-03 09:14:55 +02:00
|
|
|
}
|
2020-07-27 11:34:07 +02:00
|
|
|
|
|
|
|
public enum HologramDirection {
|
|
|
|
BOTTOM_UP,
|
|
|
|
TOP_DOWN;
|
|
|
|
}
|
2021-12-27 16:59:21 +01:00
|
|
|
|
2022-09-03 18:22:20 +02:00
|
|
|
private class HologramLine {
|
|
|
|
boolean persist;
|
|
|
|
String text;
|
|
|
|
public int ticks;
|
|
|
|
|
|
|
|
public HologramLine(String text, boolean persist) {
|
|
|
|
this(text, persist, -1);
|
|
|
|
}
|
|
|
|
|
|
|
|
public HologramLine(String text, boolean persist, int ticks) {
|
2022-09-06 20:11:07 +02:00
|
|
|
this.text = text;
|
|
|
|
this.persist = persist;
|
|
|
|
this.ticks = ticks;
|
2022-09-03 18:22:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-27 16:59:21 +01:00
|
|
|
private static final Pattern ITEM_MATCHER = Pattern.compile("<item:(.*?)>");
|
2020-06-30 12:17:14 +02:00
|
|
|
}
|