mirror of
https://github.com/CitizensDev/Citizens2.git
synced 2024-11-26 04:35:50 +01:00
Rework HologramTrait implementation
This commit is contained in:
parent
dee442e935
commit
2b19473832
@ -4,6 +4,7 @@ import java.util.Collection;
|
|||||||
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;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@ -13,7 +14,6 @@ import org.bukkit.entity.EntityType;
|
|||||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import com.google.common.collect.Collections2;
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import net.citizensnpcs.Settings.Setting;
|
import net.citizensnpcs.Settings.Setting;
|
||||||
@ -26,10 +26,10 @@ 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.DataKey;
|
||||||
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;
|
||||||
import net.citizensnpcs.util.NMS;
|
import net.citizensnpcs.util.NMS;
|
||||||
|
import net.citizensnpcs.util.Util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Persists a hologram attached to the NPC.
|
* Persists a hologram attached to the NPC.
|
||||||
@ -43,7 +43,6 @@ public class HologramTrait extends Trait {
|
|||||||
private boolean lastNameplateVisible;
|
private boolean lastNameplateVisible;
|
||||||
@Persist
|
@Persist
|
||||||
private double lineHeight = -1;
|
private double lineHeight = -1;
|
||||||
private final List<NPC> lineHolograms = Lists.newArrayList();
|
|
||||||
private final List<HologramLine> lines = Lists.newArrayList();
|
private final List<HologramLine> 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());
|
||||||
@ -74,14 +73,17 @@ public class HologramTrait extends Trait {
|
|||||||
*/
|
*/
|
||||||
public void addTemporaryLine(String text, int ticks) {
|
public void addTemporaryLine(String text, int ticks) {
|
||||||
lines.add(new HologramLine(text, false, ticks));
|
lines.add(new HologramLine(text, false, ticks));
|
||||||
|
reloadLineHolograms();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears all hologram lines
|
* Clears all hologram lines
|
||||||
*/
|
*/
|
||||||
public void clear() {
|
public void clear() {
|
||||||
|
for (HologramLine line : lines) {
|
||||||
|
line.removeNPC();
|
||||||
|
}
|
||||||
lines.clear();
|
lines.clear();
|
||||||
reloadLineHolograms();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private NPC createHologram(String line, double heightOffset) {
|
private NPC createHologram(String line, double heightOffset) {
|
||||||
@ -96,6 +98,10 @@ public class HologramTrait extends Trait {
|
|||||||
Material item = SpigotUtil.isUsing1_13API() ? Material.matchMaterial(itemMatcher.group(1), false)
|
Material item = SpigotUtil.isUsing1_13API() ? Material.matchMaterial(itemMatcher.group(1), false)
|
||||||
: Material.matchMaterial(itemMatcher.group(1));
|
: Material.matchMaterial(itemMatcher.group(1));
|
||||||
NPC itemNPC = registry.createNPCUsingItem(EntityType.DROPPED_ITEM, "", new ItemStack(item, 1));
|
NPC itemNPC = registry.createNPCUsingItem(EntityType.DROPPED_ITEM, "", new ItemStack(item, 1));
|
||||||
|
if (itemMatcher.groupCount() > 1) {
|
||||||
|
itemNPC.getOrAddTrait(ScoreboardTrait.class)
|
||||||
|
.setColor(Util.matchEnum(ChatColor.values(), itemMatcher.group(2)));
|
||||||
|
}
|
||||||
itemNPC.spawn(currentLoc);
|
itemNPC.spawn(currentLoc);
|
||||||
((ArmorStand) hologramNPC.getEntity()).addPassenger(itemNPC.getEntity());
|
((ArmorStand) hologramNPC.getEntity()).addPassenger(itemNPC.getEntity());
|
||||||
itemNPC.addRunnable(new Runnable() {
|
itemNPC.addRunnable(new Runnable() {
|
||||||
@ -130,7 +136,8 @@ public class HologramTrait extends Trait {
|
|||||||
* Note: this is implementation-specific and may be removed at a later date.
|
* Note: this is implementation-specific and may be removed at a later date.
|
||||||
*/
|
*/
|
||||||
public Collection<ArmorStand> getHologramEntities() {
|
public Collection<ArmorStand> getHologramEntities() {
|
||||||
return Collections2.transform(lineHolograms, (n) -> (ArmorStand) n.getEntity());
|
return lines.stream().filter(l -> l.hologram != null && l.hologram.getEntity() != null)
|
||||||
|
.map(l -> (ArmorStand) l.hologram.getEntity()).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -160,7 +167,7 @@ public class HologramTrait extends Trait {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load(DataKey root) {
|
public void load(DataKey root) {
|
||||||
lines.clear();
|
clear();
|
||||||
for (DataKey key : root.getRelative("lines").getIntegerSubKeys()) {
|
for (DataKey key : root.getRelative("lines").getIntegerSubKeys()) {
|
||||||
lines.add(new HologramLine(key.getString(""), true));
|
lines.add(new HologramLine(key.getString(""), true));
|
||||||
}
|
}
|
||||||
@ -172,10 +179,10 @@ public class HologramTrait extends Trait {
|
|||||||
nameNPC.destroy();
|
nameNPC.destroy();
|
||||||
nameNPC = null;
|
nameNPC = null;
|
||||||
}
|
}
|
||||||
for (NPC npc : lineHolograms) {
|
|
||||||
npc.destroy();
|
for (HologramLine line : lines) {
|
||||||
|
line.removeNPC();
|
||||||
}
|
}
|
||||||
lineHolograms.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -187,6 +194,7 @@ public class HologramTrait extends Trait {
|
|||||||
public void onSpawn() {
|
public void onSpawn() {
|
||||||
if (!npc.isSpawned())
|
if (!npc.isSpawned())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lastNameplateVisible = Boolean
|
lastNameplateVisible = Boolean
|
||||||
.parseBoolean(npc.data().<Object> get(NPC.Metadata.NAMEPLATE_VISIBLE, true).toString());
|
.parseBoolean(npc.data().<Object> get(NPC.Metadata.NAMEPLATE_VISIBLE, true).toString());
|
||||||
currentLoc = npc.getStoredLocation();
|
currentLoc = npc.getStoredLocation();
|
||||||
@ -195,21 +203,20 @@ public class HologramTrait extends Trait {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < lines.size(); i++) {
|
for (int i = 0; i < lines.size(); i++) {
|
||||||
lineHolograms.add(createHologram(Placeholders.replace(lines.get(i).text, null, npc), getHeight(i)));
|
lines.get(i).spawnNPC(getHeight(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reloadLineHolograms() {
|
private void reloadLineHolograms() {
|
||||||
for (NPC npc : lineHolograms) {
|
for (HologramLine line : lines) {
|
||||||
npc.destroy();
|
line.removeNPC();
|
||||||
}
|
}
|
||||||
lineHolograms.clear();
|
|
||||||
|
|
||||||
if (!npc.isSpawned())
|
if (!npc.isSpawned())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (int i = 0; i < lines.size(); i++) {
|
for (int i = 0; i < lines.size(); i++) {
|
||||||
lineHolograms.add(createHologram(Placeholders.replace(lines.get(i).text, null, npc), getHeight(i)));
|
lines.get(i).spawnNPC(getHeight(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,7 +229,7 @@ public class HologramTrait extends Trait {
|
|||||||
if (idx < 0 || idx >= lines.size())
|
if (idx < 0 || idx >= lines.size())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lines.remove(idx);
|
lines.remove(idx).removeNPC();
|
||||||
|
|
||||||
reloadLineHolograms();
|
reloadLineHolograms();
|
||||||
}
|
}
|
||||||
@ -249,44 +256,41 @@ public class HologramTrait extends Trait {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean update = currentLoc.getWorld() != npc.getStoredLocation().getWorld()
|
boolean updatePosition = currentLoc.getWorld() != npc.getStoredLocation().getWorld()
|
||||||
|| currentLoc.distance(npc.getStoredLocation()) >= 0.001 || lastNameplateVisible != nameplateVisible
|
|| currentLoc.distance(npc.getStoredLocation()) >= 0.001 || lastNameplateVisible != nameplateVisible
|
||||||
|| Math.abs(lastEntityHeight - getEntityHeight()) >= 0.05;
|
|| Math.abs(lastEntityHeight - getEntityHeight()) >= 0.05;
|
||||||
lastNameplateVisible = nameplateVisible;
|
lastNameplateVisible = nameplateVisible;
|
||||||
|
|
||||||
if (update) {
|
if (updatePosition) {
|
||||||
currentLoc = npc.getStoredLocation();
|
currentLoc = npc.getStoredLocation();
|
||||||
lastEntityHeight = getEntityHeight();
|
lastEntityHeight = getEntityHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nameNPC != null && nameNPC.isSpawned()) {
|
if (nameNPC != null && nameNPC.isSpawned()) {
|
||||||
if (update) {
|
if (updatePosition) {
|
||||||
nameNPC.teleport(currentLoc.clone().add(0, getEntityHeight(), 0), TeleportCause.PLUGIN);
|
nameNPC.teleport(currentLoc.clone().add(0, getEntityHeight(), 0), TeleportCause.PLUGIN);
|
||||||
}
|
}
|
||||||
nameNPC.setName(npc.getFullName());
|
nameNPC.setName(npc.getFullName());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < lineHolograms.size(); i++) {
|
for (int i = 0; i < lines.size(); i++) {
|
||||||
NPC hologramNPC = lineHolograms.get(i);
|
HologramLine line = lines.get(i);
|
||||||
if (!hologramNPC.isSpawned())
|
NPC hologramNPC = line.hologram;
|
||||||
|
if (hologramNPC == null || !hologramNPC.isSpawned())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (update) {
|
if (updatePosition) {
|
||||||
hologramNPC.teleport(currentLoc.clone().add(0, lastEntityHeight
|
hologramNPC.teleport(currentLoc.clone().add(0, lastEntityHeight
|
||||||
+ (direction == HologramDirection.BOTTOM_UP ? getHeight(i) : getMaxHeight() - getHeight(i)), 0),
|
+ (direction == HologramDirection.BOTTOM_UP ? getHeight(i) : getMaxHeight() - getHeight(i)), 0),
|
||||||
TeleportCause.PLUGIN);
|
TeleportCause.PLUGIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i >= lines.size()) {
|
|
||||||
Messaging.severe("More hologram NPCs than lines for ID", npc.getId(), "lines", lines);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
HologramLine line = lines.get(i);
|
|
||||||
if (line.ticks > 0 && --line.ticks == 0) {
|
if (line.ticks > 0 && --line.ticks == 0) {
|
||||||
|
line.removeNPC();
|
||||||
lines.remove(i--);
|
lines.remove(i--);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
String text = line.text;
|
String text = line.text;
|
||||||
if (ITEM_MATCHER.matcher(text).matches()) {
|
if (ITEM_MATCHER.matcher(text).matches()) {
|
||||||
text = null;
|
text = null;
|
||||||
@ -339,13 +343,11 @@ public class HologramTrait extends Trait {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
lines.get(idx).text = text;
|
HologramLine line = lines.get(idx);
|
||||||
if (idx < lineHolograms.size()) {
|
line.setText(text);
|
||||||
lineHolograms.get(idx).setName(Placeholders.replace(text, null, npc));
|
if (line.hologram == null) {
|
||||||
return;
|
reloadLineHolograms();
|
||||||
}
|
}
|
||||||
|
|
||||||
reloadLineHolograms();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -367,9 +369,10 @@ public class HologramTrait extends Trait {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class HologramLine {
|
private class HologramLine {
|
||||||
|
NPC hologram;
|
||||||
boolean persist;
|
boolean persist;
|
||||||
String text;
|
String text;
|
||||||
public int ticks;
|
int ticks;
|
||||||
|
|
||||||
public HologramLine(String text, boolean persist) {
|
public HologramLine(String text, boolean persist) {
|
||||||
this(text, persist, -1);
|
this(text, persist, -1);
|
||||||
@ -380,7 +383,27 @@ public class HologramTrait extends Trait {
|
|||||||
this.persist = persist;
|
this.persist = persist;
|
||||||
this.ticks = ticks;
|
this.ticks = ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void removeNPC() {
|
||||||
|
if (hologram == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
hologram.destroy();
|
||||||
|
hologram = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(String text) {
|
||||||
|
this.text = text;
|
||||||
|
|
||||||
|
if (hologram != null) {
|
||||||
|
hologram.setName(Placeholders.replace(text, null, npc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void spawnNPC(double height) {
|
||||||
|
this.hologram = createHologram(Placeholders.replace(text, null, npc), height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Pattern ITEM_MATCHER = Pattern.compile("<item:(.*?)>");
|
private static final Pattern ITEM_MATCHER = Pattern.compile("<item:(.*?)>|<item:(.*?):(.*?)>");
|
||||||
}
|
}
|
||||||
|
@ -233,8 +233,8 @@ public class Text extends Trait implements Runnable, Listener, ConversationAband
|
|||||||
boolean sendPage(CommandSender player, int page) {
|
boolean sendPage(CommandSender player, int page) {
|
||||||
Paginator paginator = new Paginator().header("Current Texts").enablePageSwitcher();
|
Paginator paginator = new Paginator().header("Current Texts").enablePageSwitcher();
|
||||||
for (int i = 0; i < text.size(); i++) {
|
for (int i = 0; i < text.size(); i++) {
|
||||||
paginator.addLine("<yellow>" + text.get(i) + " <green>(<click:suggest_command:edit " + i
|
paginator.addLine(text.get(i) + " <green>(<click:suggest_command:edit " + i
|
||||||
+ "><yellow>edit</click>) (<click:run_command:remove " + i
|
+ " ><yellow>edit</click>) (<click:run_command:remove " + i
|
||||||
+ "><hover:show_text:Remove this text><red>-</hover></click>)");
|
+ "><hover:show_text:Remove this text><red>-</hover></click>)");
|
||||||
}
|
}
|
||||||
return paginator.sendPage(player, page);
|
return paginator.sendPage(player, page);
|
||||||
|
@ -340,7 +340,7 @@ citizens.editors.text.range-set=[[Range]] set to [[{0}]].
|
|||||||
citizens.editors.text.delay-set=[[Delay]] set to [[{0}]] seconds.
|
citizens.editors.text.delay-set=[[Delay]] set to [[{0}]] seconds.
|
||||||
citizens.editors.text.realistic-looking-set=[[Realistic looking]] set to [[{0}]].
|
citizens.editors.text.realistic-looking-set=[[Realistic looking]] set to [[{0}]].
|
||||||
citizens.editors.text.speech-bubbles-set=[[Speech bubbles]] set to [[{0}]].
|
citizens.editors.text.speech-bubbles-set=[[Speech bubbles]] set to [[{0}]].
|
||||||
citizens.editors.text.start-prompt=<click:suggest_command:add ><yellow>Add text</click> | <click:suggest_command:item ><hover:show_text:'Set the talk item in hand pattern (set to <yellow>default</yellow> to clear)'><yellow>item</hover></click> | <click:suggest_command:range ><hover:show_text:Set the talking range in blocks><yellow>range</hover></click> | <click:suggest_command:delay ><hover:show_text:Set the talking delay in seconds><yellow>delay</hover></click><br><click:run_command:/npc text close><hover:show_text:Toggle sending messages when players get close>{0}talk close</hover></click> | <click:run_command:/npc text random><hover:show_text:Toggle random talking>{1}random</hover></click> | <click:run_command:/npc text speech bubbles><hover:show_text:Toggle showing text as holograms instead of chat messages>{2}speech bubbles</hover></click> | <click:run_command:/npc text realistic looking><hover:show_text:Toggle requiring line of sight before speaking>{3}realistic</hover></click>
|
citizens.editors.text.start-prompt=<click:suggest_command:add ><yellow>Add text</click> | <click:suggest_command:item ><hover:show_text:"Set the talk item in hand pattern (set to <yellow>default</yellow> to clear)"><yellow>item</hover></click> | <click:suggest_command:range ><hover:show_text:Set the talking range in blocks><yellow>range</hover></click> | <click:suggest_command:delay ><hover:show_text:Set the talking delay in seconds><yellow>delay</hover></click><br><click:run_command:/npc text close><hover:show_text:Toggle sending messages when players get close>{0}talk close</hover></click> | <click:run_command:/npc text random><hover:show_text:Toggle random talking>{1}random</hover></click> | <click:run_command:/npc text speech bubbles><hover:show_text:Toggle showing text as holograms instead of chat messages>{2}speech bubbles</hover></click> | <click:run_command:/npc text realistic looking><hover:show_text:Toggle requiring line of sight before speaking>{3}realistic</hover></click>
|
||||||
citizens.editors.text.talk-item-set=[[Talk item pattern]] set to [[{0}]].
|
citizens.editors.text.talk-item-set=[[Talk item pattern]] set to [[{0}]].
|
||||||
citizens.editors.text.text-list-header=Current text:
|
citizens.editors.text.text-list-header=Current text:
|
||||||
citizens.editors.waypoints.wander.editing-regions-stop=Exited the region editor.
|
citizens.editors.waypoints.wander.editing-regions-stop=Exited the region editor.
|
||||||
|
Loading…
Reference in New Issue
Block a user