Add temporary hologram lines

This commit is contained in:
fullwall 2022-09-04 00:22:20 +08:00
parent 6270985989
commit 61b71cb2d2
3 changed files with 65 additions and 35 deletions

View File

@ -164,7 +164,7 @@
<relocations> <relocations>
<relocation> <relocation>
<pattern>gnu.trove</pattern> <pattern>gnu.trove</pattern>
<shadedPattern>lib.trove</shadedPattern> <shadedPattern>clib.trove</shadedPattern>
</relocation> </relocation>
<relocation> <relocation>
<pattern>org.bstats</pattern> <pattern>org.bstats</pattern>

View File

@ -1,7 +1,6 @@
package net.citizensnpcs.trait; package net.citizensnpcs.trait;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -26,6 +25,7 @@ import net.citizensnpcs.api.persistence.Persist;
import net.citizensnpcs.api.trait.Trait; import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.trait.TraitName; import net.citizensnpcs.api.trait.TraitName;
import net.citizensnpcs.api.util.Colorizer; import net.citizensnpcs.api.util.Colorizer;
import net.citizensnpcs.api.util.DataKey;
import net.citizensnpcs.api.util.Messaging; import net.citizensnpcs.api.util.Messaging;
import net.citizensnpcs.api.util.Placeholders; import net.citizensnpcs.api.util.Placeholders;
import net.citizensnpcs.api.util.SpigotUtil; import net.citizensnpcs.api.util.SpigotUtil;
@ -44,8 +44,7 @@ public class HologramTrait extends Trait {
@Persist @Persist
private double lineHeight = -1; private double lineHeight = -1;
private final List<NPC> lineHolograms = Lists.newArrayList(); private final List<NPC> lineHolograms = Lists.newArrayList();
@Persist private final List<HologramLine> lines = Lists.newArrayList();
private final List<String> lines = Lists.newArrayList();
private NPC nameNPC; private NPC nameNPC;
private final NPCRegistry registry = CitizensAPI.createCitizensBackedNPCRegistry(new MemoryNPCDataStore()); private final NPCRegistry registry = CitizensAPI.createCitizensBackedNPCRegistry(new MemoryNPCDataStore());
@ -60,10 +59,23 @@ public class HologramTrait extends Trait {
* The new line to add * The new line to add
*/ */
public void addLine(String text) { public void addLine(String text) {
lines.add(text); lines.add(new HologramLine(text, true));
reloadLineHolograms(); reloadLineHolograms();
} }
/**
* 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));
}
/** /**
* Clears all hologram lines * Clears all hologram lines
*/ */
@ -133,7 +145,7 @@ public class HologramTrait extends Trait {
* @return the hologram lines, in bottom-up order * @return the hologram lines, in bottom-up order
*/ */
public List<String> getLines() { public List<String> getLines() {
return Collections.unmodifiableList(lines); return Lists.transform(lines, (l) -> l.text);
} }
private double getMaxHeight() { private double getMaxHeight() {
@ -147,6 +159,14 @@ public class HologramTrait extends Trait {
return nameNPC != null && nameNPC.isSpawned() ? ((ArmorStand) nameNPC.getEntity()) : null; return nameNPC != null && nameNPC.isSpawned() ? ((ArmorStand) nameNPC.getEntity()) : null;
} }
@Override
public void load(DataKey root) {
lines.clear();
for (DataKey key : root.getRelative("lines").getIntegerSubKeys()) {
lines.add(new HologramLine(key.getString(""), true));
}
}
@Override @Override
public void onDespawn() { public void onDespawn() {
if (nameNPC != null) { if (nameNPC != null) {
@ -176,8 +196,7 @@ public class HologramTrait extends Trait {
} }
for (int i = 0; i < lines.size(); i++) { for (int i = 0; i < lines.size(); i++) {
String line = lines.get(i); lineHolograms.add(createHologram(Placeholders.replace(lines.get(i).text, null, npc), getHeight(i)));
lineHolograms.add(createHologram(Placeholders.replace(line, null, npc), getHeight(i)));
} }
} }
@ -189,9 +208,9 @@ public class HologramTrait extends Trait {
if (!npc.isSpawned()) if (!npc.isSpawned())
return; return;
for (int i = 0; i < lines.size(); i++) { for (int i = 0; i < lines.size(); i++) {
String line = lines.get(i); lineHolograms.add(createHologram(Placeholders.replace(lines.get(i).text, null, npc), getHeight(i)));
lineHolograms.add(createHologram(Placeholders.replace(line, null, npc), getHeight(i)));
} }
} }
@ -264,7 +283,12 @@ public class HologramTrait extends Trait {
break; break;
} }
String text = lines.get(i); HologramLine line = lines.get(i);
if (line.ticks > 0 && --line.ticks == 0) {
lines.remove(i--);
continue;
}
String text = line.text;
if (ITEM_MATCHER.matcher(text).matches()) { if (ITEM_MATCHER.matcher(text).matches()) {
text = null; text = null;
} }
@ -279,6 +303,18 @@ public class HologramTrait extends Trait {
} }
} }
@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++;
}
}
/** /**
* @see #getDirection() * @see #getDirection()
* @param direction * @param direction
@ -304,7 +340,7 @@ public class HologramTrait extends Trait {
return; return;
} }
lines.set(idx, text); lines.get(idx).text = text;
if (idx < lineHolograms.size()) { if (idx < lineHolograms.size()) {
lineHolograms.get(idx).setName(Placeholders.replace(text, null, npc)); lineHolograms.get(idx).setName(Placeholders.replace(text, null, npc));
return; return;
@ -331,5 +367,18 @@ public class HologramTrait extends Trait {
TOP_DOWN; TOP_DOWN;
} }
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) {
}
}
private static final Pattern ITEM_MATCHER = Pattern.compile("<item:(.*?)>"); private static final Pattern ITEM_MATCHER = Pattern.compile("<item:(.*?)>");
} }

View File

@ -52,7 +52,7 @@ public class Text extends Trait implements Runnable, Listener, ConversationAband
private double range = Setting.DEFAULT_TALK_CLOSE_RANGE.asDouble(); private double range = Setting.DEFAULT_TALK_CLOSE_RANGE.asDouble();
private boolean realisticLooker = Setting.DEFAULT_REALISTIC_LOOKING.asBoolean(); private boolean realisticLooker = Setting.DEFAULT_REALISTIC_LOOKING.asBoolean();
private boolean speechBubbles; private boolean speechBubbles;
private int speechIndex = -1; private final int speechIndex = -1;
private boolean talkClose = Setting.DEFAULT_TALK_CLOSE.asBoolean(); private boolean talkClose = Setting.DEFAULT_TALK_CLOSE.asBoolean();
private final List<String> text = new ArrayList<String>(); private final List<String> text = new ArrayList<String>();
@ -71,14 +71,6 @@ public class Text extends Trait implements Runnable, Listener, ConversationAband
text.add(string); text.add(string);
} }
private void clearBubble() {
if (speechIndex < npc.getOrAddTrait(HologramTrait.class).getLines().size()) {
npc.getOrAddTrait(HologramTrait.class).removeLine(speechIndex);
speechIndex = -1;
}
bubbleTicks = 0;
}
@Override @Override
public void conversationAbandoned(ConversationAbandonedEvent event) { public void conversationAbandoned(ConversationAbandonedEvent event) {
} }
@ -193,12 +185,9 @@ public class Text extends Trait implements Runnable, Listener, ConversationAband
if (!npc.isSpawned()) if (!npc.isSpawned())
return; return;
if (bubbleTicks > 0 && --bubbleTicks == 0) {
clearBubble();
}
if (!talkClose) if (!talkClose)
return; return;
List<Entity> nearby = npc.getEntity().getNearbyEntities(range, range, range); List<Entity> nearby = npc.getEntity().getNearbyEntities(range, range, range);
for (Entity search : nearby) { for (Entity search : nearby) {
if (!(search instanceof Player) || ((Player) search).getGameMode() == GameMode.SPECTATOR) if (!(search instanceof Player) || ((Player) search).getGameMode() == GameMode.SPECTATOR)
@ -264,13 +253,8 @@ public class Text extends Trait implements Runnable, Listener, ConversationAband
if (speechBubbles) { if (speechBubbles) {
HologramTrait trait = npc.getOrAddTrait(HologramTrait.class); HologramTrait trait = npc.getOrAddTrait(HologramTrait.class);
if (speechIndex == -1) { trait.addTemporaryLine(Placeholders.replace(text.get(index), player),
speechIndex = trait.getLines().size(); Setting.DEFAULT_TEXT_SPEECH_BUBBLE_TICKS.asInt());
trait.addLine(Placeholders.replace(text.get(index), player));
bubbleTicks = Setting.DEFAULT_TEXT_SPEECH_BUBBLE_TICKS.asInt();
} else if (speechIndex < trait.getLines().size()) {
trait.setLine(speechIndex, Placeholders.replace(text.get(index), player));
}
} else { } else {
npc.getDefaultSpeechController().speak(new SpeechContext(text.get(index), player)); npc.getDefaultSpeechController().speak(new SpeechContext(text.get(index), player));
} }
@ -336,9 +320,6 @@ public class Text extends Trait implements Runnable, Listener, ConversationAband
* Toggles using speech bubbles instead of messages. * Toggles using speech bubbles instead of messages.
*/ */
public boolean toggleSpeechBubbles() { public boolean toggleSpeechBubbles() {
if (speechBubbles) {
clearBubble();
}
return (speechBubbles = !speechBubbles); return (speechBubbles = !speechBubbles);
} }