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>
<relocation>
<pattern>gnu.trove</pattern>
<shadedPattern>lib.trove</shadedPattern>
<shadedPattern>clib.trove</shadedPattern>
</relocation>
<relocation>
<pattern>org.bstats</pattern>

View File

@ -1,7 +1,6 @@
package net.citizensnpcs.trait;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
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.TraitName;
import net.citizensnpcs.api.util.Colorizer;
import net.citizensnpcs.api.util.DataKey;
import net.citizensnpcs.api.util.Messaging;
import net.citizensnpcs.api.util.Placeholders;
import net.citizensnpcs.api.util.SpigotUtil;
@ -44,8 +44,7 @@ public class HologramTrait extends Trait {
@Persist
private double lineHeight = -1;
private final List<NPC> lineHolograms = Lists.newArrayList();
@Persist
private final List<String> lines = Lists.newArrayList();
private final List<HologramLine> lines = Lists.newArrayList();
private NPC nameNPC;
private final NPCRegistry registry = CitizensAPI.createCitizensBackedNPCRegistry(new MemoryNPCDataStore());
@ -60,10 +59,23 @@ public class HologramTrait extends Trait {
* The new line to add
*/
public void addLine(String text) {
lines.add(text);
lines.add(new HologramLine(text, true));
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
*/
@ -133,7 +145,7 @@ public class HologramTrait extends Trait {
* @return the hologram lines, in bottom-up order
*/
public List<String> getLines() {
return Collections.unmodifiableList(lines);
return Lists.transform(lines, (l) -> l.text);
}
private double getMaxHeight() {
@ -147,6 +159,14 @@ public class HologramTrait extends Trait {
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
public void onDespawn() {
if (nameNPC != null) {
@ -176,8 +196,7 @@ public class HologramTrait extends Trait {
}
for (int i = 0; i < lines.size(); i++) {
String line = lines.get(i);
lineHolograms.add(createHologram(Placeholders.replace(line, null, npc), getHeight(i)));
lineHolograms.add(createHologram(Placeholders.replace(lines.get(i).text, null, npc), getHeight(i)));
}
}
@ -189,9 +208,9 @@ public class HologramTrait extends Trait {
if (!npc.isSpawned())
return;
for (int i = 0; i < lines.size(); i++) {
String line = lines.get(i);
lineHolograms.add(createHologram(Placeholders.replace(line, null, npc), getHeight(i)));
lineHolograms.add(createHologram(Placeholders.replace(lines.get(i).text, null, npc), getHeight(i)));
}
}
@ -264,7 +283,12 @@ public class HologramTrait extends Trait {
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()) {
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()
* @param direction
@ -304,7 +340,7 @@ public class HologramTrait extends Trait {
return;
}
lines.set(idx, text);
lines.get(idx).text = text;
if (idx < lineHolograms.size()) {
lineHolograms.get(idx).setName(Placeholders.replace(text, null, npc));
return;
@ -331,5 +367,18 @@ public class HologramTrait extends Trait {
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:(.*?)>");
}

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 boolean realisticLooker = Setting.DEFAULT_REALISTIC_LOOKING.asBoolean();
private boolean speechBubbles;
private int speechIndex = -1;
private final int speechIndex = -1;
private boolean talkClose = Setting.DEFAULT_TALK_CLOSE.asBoolean();
private final List<String> text = new ArrayList<String>();
@ -71,14 +71,6 @@ public class Text extends Trait implements Runnable, Listener, ConversationAband
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
public void conversationAbandoned(ConversationAbandonedEvent event) {
}
@ -193,12 +185,9 @@ public class Text extends Trait implements Runnable, Listener, ConversationAband
if (!npc.isSpawned())
return;
if (bubbleTicks > 0 && --bubbleTicks == 0) {
clearBubble();
}
if (!talkClose)
return;
List<Entity> nearby = npc.getEntity().getNearbyEntities(range, range, range);
for (Entity search : nearby) {
if (!(search instanceof Player) || ((Player) search).getGameMode() == GameMode.SPECTATOR)
@ -264,13 +253,8 @@ public class Text extends Trait implements Runnable, Listener, ConversationAband
if (speechBubbles) {
HologramTrait trait = npc.getOrAddTrait(HologramTrait.class);
if (speechIndex == -1) {
speechIndex = trait.getLines().size();
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));
}
trait.addTemporaryLine(Placeholders.replace(text.get(index), player),
Setting.DEFAULT_TEXT_SPEECH_BUBBLE_TICKS.asInt());
} else {
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.
*/
public boolean toggleSpeechBubbles() {
if (speechBubbles) {
clearBubble();
}
return (speechBubbles = !speechBubbles);
}