Don't use text displays for holograms

This commit is contained in:
fullwall 2023-03-19 16:14:53 +08:00
parent 904d83de43
commit f269019d56
4 changed files with 43 additions and 26 deletions

View File

@ -46,6 +46,7 @@ public class HologramTrait extends Trait {
private NPC nameNPC;
private final NPCRegistry registry = CitizensAPI.createCitizensBackedNPCRegistry(new MemoryNPCDataStore());
private int t;
private boolean useTextDisplay = false;
public HologramTrait() {
super("hologramtrait");
@ -88,12 +89,13 @@ public class HologramTrait extends Trait {
private NPC createHologram(String line, double heightOffset) {
NPC hologramNPC = null;
if (SUPPORTS_TEXT_DISPLAY) {
if (useTextDisplay) {
hologramNPC = registry.createNPC(EntityType.TEXT_DISPLAY, line);
} else {
hologramNPC = registry.createNPC(EntityType.ARMOR_STAND, line);
hologramNPC.getOrAddTrait(ArmorStandTrait.class).setAsHelperEntityWithName(npc);
}
if (Setting.PACKET_HOLOGRAMS.asBoolean()) {
hologramNPC.addTrait(PacketNPC.class);
}
@ -101,27 +103,26 @@ public class HologramTrait extends Trait {
getEntityHeight()
+ (direction == HologramDirection.BOTTOM_UP ? heightOffset : getMaxHeight() - heightOffset),
0));
Matcher itemMatcher = ITEM_MATCHER.matcher(line);
if (itemMatcher.matches()) {
Material item = SpigotUtil.isUsing1_13API() ? Material.matchMaterial(itemMatcher.group(1), false)
: Material.matchMaterial(itemMatcher.group(1));
NPC itemNPC = registry.createNPCUsingItem(EntityType.DROPPED_ITEM, "", new ItemStack(item, 1));
final NPC itemNPC = registry.createNPCUsingItem(EntityType.DROPPED_ITEM, "", new ItemStack(item, 1));
itemNPC.data().setPersistent(NPC.Metadata.NAMEPLATE_VISIBLE, false);
if (itemMatcher.group(2) != null) {
itemNPC.getOrAddTrait(ScoreboardTrait.class)
.setColor(Util.matchEnum(ChatColor.values(), itemMatcher.group(2).substring(1)));
}
itemNPC.getOrAddTrait(MountTrait.class).setMountedOn(hologramNPC.getUniqueId());
itemNPC.spawn(currentLoc);
hologramNPC.getEntity().addPassenger(itemNPC.getEntity());
itemNPC.addRunnable(new Runnable() {
@Override
public void run() {
if (!itemNPC.isSpawned() || !itemNPC.getEntity().isInsideVehicle()) {
itemNPC.destroy();
}
itemNPC.addRunnable(() -> {
if (!itemNPC.isSpawned() || !itemNPC.getEntity().isInsideVehicle()) {
itemNPC.destroy();
}
});
}
lastEntityHeight = getEntityHeight();
return hologramNPC;
}
@ -139,6 +140,9 @@ public class HologramTrait extends Trait {
private double getHeight(int lineNumber) {
double base = (lastNameplateVisible ? 0 : -getLineHeight());
if (useTextDisplay) {
base += 0.15;
}
for (int i = 0; i <= lineNumber; i++) {
HologramLine line = lines.get(i);
base += line.mb + getLineHeight();
@ -182,6 +186,11 @@ public class HologramTrait extends Trait {
return nameNPC != null && nameNPC.isSpawned() ? nameNPC.getEntity() : null;
}
private double getRotationDistance(Location loc) {
return Math.abs(loc.getYaw() - npc.getStoredLocation().getYaw())
+ Math.abs(loc.getPitch() - npc.getStoredLocation().getPitch());
}
@Override
public void load(DataKey root) {
clear();
@ -275,7 +284,8 @@ public class HologramTrait extends Trait {
boolean updatePosition = currentLoc.getWorld() != npc.getStoredLocation().getWorld()
|| currentLoc.distance(npc.getStoredLocation()) >= 0.001 || lastNameplateVisible != nameplateVisible
|| Math.abs(lastEntityHeight - getEntityHeight()) >= 0.05;
|| Math.abs(lastEntityHeight - getEntityHeight()) >= 0.05
|| (useTextDisplay && getRotationDistance(currentLoc) >= 0.001);
boolean updateName = false;
if (t++ >= Setting.HOLOGRAM_UPDATE_RATE.asTicks() + Util.getFastRandom().nextInt(3) /* add some jitter */) {
t = 0;
@ -304,9 +314,9 @@ public class HologramTrait extends Trait {
continue;
if (updatePosition) {
hologramNPC.teleport(currentLoc.clone().add(0, lastEntityHeight
+ (direction == HologramDirection.BOTTOM_UP ? getHeight(i) : getMaxHeight() - getHeight(i)), 0),
TeleportCause.PLUGIN);
Location tp = currentLoc.clone().add(0, lastEntityHeight
+ (direction == HologramDirection.BOTTOM_UP ? getHeight(i) : getMaxHeight() - getHeight(i)), 0);
hologramNPC.teleport(tp, TeleportCause.PLUGIN);
}
if (line.ticks > 0 && --line.ticks == 0) {
@ -323,6 +333,7 @@ public class HologramTrait extends Trait {
if (!updateName)
continue;
line.setText(text);
hologramNPC.data().set(NPC.Metadata.NAMEPLATE_VISIBLE, npc.getRawName().length() > 0);
}
@ -385,6 +396,10 @@ public class HologramTrait extends Trait {
reloadLineHolograms();
}
public void setUseTextDisplay(boolean useTextDisplay) {
this.useTextDisplay = useTextDisplay;
}
public enum HologramDirection {
BOTTOM_UP,
TOP_DOWN;
@ -433,12 +448,4 @@ public class HologramTrait extends Trait {
}
private static final Pattern ITEM_MATCHER = Pattern.compile("<item:(.*?)([:].*?)?>");
private static boolean SUPPORTS_TEXT_DISPLAY = true;
static {
try {
EntityType.valueOf("TEXT_DISPLAY");
} catch (IllegalArgumentException e) {
SUPPORTS_TEXT_DISPLAY = false;
}
}
}

View File

@ -10,7 +10,6 @@ import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_19_R3.CraftServer;
import org.bukkit.craftbukkit.v1_19_R3.entity.CraftPlayer;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.metadata.MetadataValue;
import org.bukkit.plugin.Plugin;
@ -511,7 +510,7 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
@Override
public boolean canSee(org.bukkit.entity.Entity entity) {
if (entity != null && entity.getType() == EntityType.ITEM_FRAME) {
if (entity != null && entity.getType().name().contains("ITEM_FRAME")) {
return false; // optimise for large maps in item frames
}
return super.canSee(entity);

View File

@ -1,9 +1,12 @@
package net.citizensnpcs.nms.v1_19_R3.entity.nonliving;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_19_R3.CraftServer;
import org.bukkit.craftbukkit.v1_19_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_19_R3.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_19_R3.entity.CraftItemDisplay;
import org.bukkit.craftbukkit.v1_19_R3.inventory.CraftItemStack;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
@ -30,6 +33,14 @@ public class ItemDisplayController extends MobEntityController {
super(EntityItemDisplayNPC.class);
}
@Override
protected org.bukkit.entity.Entity createEntity(Location at, NPC npc) {
final EntityItemDisplayNPC handle = new EntityItemDisplayNPC(EntityType.ITEM_DISPLAY,
((CraftWorld) at.getWorld()).getHandle(), npc);
handle.setItemStack(CraftItemStack.asNMSCopy(npc.getItemProvider().get()));
return handle.getBukkitEntity();
}
@Override
public org.bukkit.entity.ItemDisplay getBukkitEntity() {
return (org.bukkit.entity.ItemDisplay) super.getBukkitEntity();

View File

@ -431,9 +431,9 @@ public class CustomEntityRegistry extends DefaultedMappedRegistry<EntityType<?>>
minecraftClassMap.put(EntityType.SHULKER, Shulker.class);
minecraftClassMap.put(EntityType.SHULKER_BULLET, ShulkerBullet.class);
minecraftClassMap.put(EntityType.SNIFFER, net.minecraft.world.entity.animal.sniffer.Sniffer.class);
minecraftClassMap.put(EntityType.BLOCK_DISPLAY, Display.ItemDisplay.class);
minecraftClassMap.put(EntityType.ITEM_DISPLAY, Display.TextDisplay.class);
minecraftClassMap.put(EntityType.TEXT_DISPLAY, Display.BlockDisplay.class);
minecraftClassMap.put(EntityType.BLOCK_DISPLAY, Display.BlockDisplay.class);
minecraftClassMap.put(EntityType.ITEM_DISPLAY, Display.ItemDisplay.class);
minecraftClassMap.put(EntityType.TEXT_DISPLAY, Display.TextDisplay.class);
minecraftClassMap.put(EntityType.INTERACTION, net.minecraft.world.entity.Interaction.class);
minecraftClassMap.put(EntityType.SILVERFISH, Silverfish.class);
minecraftClassMap.put(EntityType.SKELETON, Skeleton.class);