Skip to content

Commit

Permalink
Fixes for hologram display entities
Browse files Browse the repository at this point in the history
  • Loading branch information
fullwall committed Oct 22, 2023
1 parent 627811c commit e889476
Show file tree
Hide file tree
Showing 15 changed files with 97 additions and 38 deletions.
11 changes: 11 additions & 0 deletions main/src/main/java/net/citizensnpcs/Citizens.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
import net.citizensnpcs.npc.skin.Skin;
import net.citizensnpcs.trait.ClickRedirectTrait;
import net.citizensnpcs.trait.CommandTrait;
import net.citizensnpcs.trait.HologramTrait;
import net.citizensnpcs.trait.ScriptTrait;
import net.citizensnpcs.trait.ShopTrait;
import net.citizensnpcs.util.Messages;
Expand Down Expand Up @@ -561,6 +562,16 @@ private void startMetrics() {
return 0;
return Iterables.size(npcRegistry);
}));
metrics.addCustomChart(new Metrics.AdvancedPie("hologram_direction", () -> {
Map<String, Integer> res = Maps.newHashMap();
for (NPC npc : npcRegistry) {
HologramTrait hg = npc.getTraitNullable(HologramTrait.class);
if (hg != null) {
res.put(hg.getDirection().name(), res.getOrDefault(hg.getDirection().name(), 0) + 1);
}
}
return res;
}));
metrics.addCustomChart(new Metrics.AdvancedPie("traits", () -> {
Map<String, Integer> res = Maps.newHashMap();
for (NPC npc : npcRegistry) {
Expand Down
3 changes: 2 additions & 1 deletion main/src/main/java/net/citizensnpcs/EventListen.java
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ public void onEntityDamage(EntityDamageEvent event) {
}
return;
}
event.setCancelled(npc.isProtected());

if (event instanceof EntityDamageByEntityEvent) {
NPCDamageByEntityEvent damageEvent = new NPCDamageByEntityEvent(npc, (EntityDamageByEntityEvent) event);
Bukkit.getPluginManager().callEvent(damageEvent);
Expand Down Expand Up @@ -436,6 +436,7 @@ public void onNPCSeenByPlayer(NPCSeenByPlayerEvent event) {
if (npc.hasTrait(ClickRedirectTrait.class)) {
npc = npc.getOrAddTrait(ClickRedirectTrait.class).getRedirectNPC();
}

if (npc.hasTrait(PlayerFilter.class)) {
event.setCancelled(npc.getOrAddTrait(PlayerFilter.class).onSeenByPlayer(event.getPlayer()));
}
Expand Down
4 changes: 3 additions & 1 deletion main/src/main/java/net/citizensnpcs/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ public void loadFromKey(DataKey root) {
FOLLOW_ACROSS_WORLDS("Whether /npc follow will teleport across worlds to follow its target",
"npc.follow.teleport-across-worlds", false),
HIGHLIGHT_COLOUR("general.color-scheme.message-highlight", "yellow"),
HOLOGRAM_ALWAYS_UPDATE_POSITION("Whether to always update the hologram position every tick.",
"npc.hologram.always-update-position", false),
HOLOGRAM_UPDATE_RATE("How often to update hologram names (including placeholders)",
"npc.hologram.update-rate-ticks", "npc.hologram.update-rate", "1s"),
INITIAL_PLAYER_JOIN_SKIN_PACKET_DELAY("How long to wait before sending skins to joined players",
Expand All @@ -200,7 +202,7 @@ public void loadFromKey(DataKey root) {
"npc.pathfinding.maximum-new-pathfinder-iterations", "npc.pathfinding.new-finder.maximum-iterations",
768),
MAXIMUM_VISITED_NODES("The maximum number of blocks to check when MINECRAFT pathfinding",
"npc.pathfinding.maximum-visited-nodes", "npc.pathfinding.maximum-visited-blocks", 768),
"npc.pathfinding.maximum-visited-nodes", "npc.pathfinding.maximum-visited-blocks", 1024),
MESSAGE_COLOUR("general.color-scheme.message", "<green>"),
NEW_PATHFINDER_CHECK_BOUNDING_BOXES(
"Whether to check bounding boxes when pathfinding such as between fences, inside doors, or other half-blocks",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public void reload(CommandContext args, CommandSender sender, NPC npc) throws Co
return;
}
}

Messaging.sendTr(sender, Messages.CITIZENS_RELOADING);
try {
plugin.reload();
Expand Down
2 changes: 2 additions & 0 deletions main/src/main/java/net/citizensnpcs/commands/NPCCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@ public void breakblock(CommandContext args, CommandSender sender, NPC npc, @Flag
} else if (Setting.DEFAULT_BLOCK_BREAKER_RADIUS.asDouble() > 0) {
cfg.radius(Setting.DEFAULT_BLOCK_BREAKER_RADIUS.asDouble());
}

BlockBreaker breaker = npc.getBlockBreaker(args.getSenderTargetBlockLocation().getBlock(), cfg);
npc.getDefaultGoalController().addBehavior(StatusMapper.singleUse(breaker), 1);
}
Expand Down Expand Up @@ -733,6 +734,7 @@ public void create(CommandContext args, CommandSender sender, NPC npc, @Flag("at
if (args.hasFlag('t') || temporaryTicks != null) {
registry = temporaryRegistry;
}

if (item != null) {
ItemStack stack = Util.parseItemStack(null, item);
npc = registry.createNPCUsingItem(type, name, stack);
Expand Down
19 changes: 18 additions & 1 deletion main/src/main/java/net/citizensnpcs/npc/CitizensNPC.java
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ public void destroy() {
public void faceLocation(Location location) {
if (!isSpawned())
return;

Util.faceLocation(getEntity(), location);
}

Expand Down Expand Up @@ -191,7 +192,7 @@ public boolean isUpdating(NPCUpdate update) {
@Override
public void load(final DataKey root) {
super.load(root);
// Spawn the NPC

CurrentLocation spawnLocation = getOrAddTrait(CurrentLocation.class);
if (getOrAddTrait(Spawned.class).shouldSpawn() && spawnLocation.getLocation() != null) {
if (spawnLocation.getLocation() != null) {
Expand Down Expand Up @@ -224,8 +225,10 @@ private void resetCachedCoord() {
@Override
public void save(DataKey root) {
super.save(root);

if (!data().get(NPC.Metadata.SHOULD_SAVE, true))
return;

navigator.save(root.getRelative("navigator"));
}

Expand All @@ -252,10 +255,12 @@ public void setEntityController(EntityController newController) {
prev = getEntity().getLocation();
despawn(DespawnReason.PENDING_RESPAWN);
}

PacketNPC packet = getTraitNullable(PacketNPC.class);
if (packet != null) {
newController = packet.wrap(newController);
}

entityController = newController;
if (wasSpawned) {
spawn(prev, SpawnReason.RESPAWN);
Expand Down Expand Up @@ -457,14 +462,17 @@ public void run() {
public void teleport(Location location, TeleportCause reason) {
if (!isSpawned())
return;

if (hasTrait(SitTrait.class) && getOrAddTrait(SitTrait.class).isSitting()) {
getOrAddTrait(SitTrait.class).setSitting(location);
}

Location npcLoc = getEntity().getLocation();
if (isSpawned() && npcLoc.getWorld() == location.getWorld()) {
if (npcLoc.distance(location) < 1) {
NMS.setHeadYaw(getEntity(), location.getYaw());
}

if (getEntity().getType() == EntityType.PLAYER && !getEntity().isInsideVehicle()
&& NMS.getPassengers(getEntity()).size() == 0) {
NPCTeleportEvent event = new NPCTeleportEvent(this, location);
Expand All @@ -475,6 +483,7 @@ public void teleport(Location location, TeleportCause reason) {
return;
}
}

super.teleport(location, reason);
}

Expand Down Expand Up @@ -602,14 +611,20 @@ private void updateCustomNameVisibility() {
}

private void updateFlyableState() {
if (!CitizensAPI.hasImplementation())
return;

EntityType type = isSpawned() ? getEntity().getType() : getOrAddTrait(MobType.class).getType();
if (type == null)
return;

if (!Util.isAlwaysFlyable(type))
return;

if (!data().has(NPC.Metadata.FLYABLE)) {
data().setPersistent(NPC.Metadata.FLYABLE, true);
}

if (!hasTrait(Gravity.class)) {
getOrAddTrait(Gravity.class).setEnabled(true);
}
Expand All @@ -624,8 +639,10 @@ private void updateScoreboard() {
private void updateUsingItemState(Player player) {
boolean useItem = data().get(NPC.Metadata.USING_HELD_ITEM, false),
offhand = data().get(NPC.Metadata.USING_OFFHAND_ITEM, false);

if (!SUPPORT_USE_ITEM)
return;

try {
if (useItem) {
NMS.playAnimation(PlayerAnimation.STOP_USE_ITEM, player, 64);
Expand Down
34 changes: 24 additions & 10 deletions main/src/main/java/net/citizensnpcs/trait/HologramTrait.java
Original file line number Diff line number Diff line change
Expand Up @@ -302,24 +302,31 @@ public void run() {
}
}

boolean updatePosition = currentLoc.getWorld() != npc.getStoredLocation().getWorld()
|| currentLoc.distance(npc.getStoredLocation()) >= 0.001 || lastNameplateVisible != nameplateVisible
|| Math.abs(lastEntityHeight - getEntityHeight()) >= 0.05;
Location npcLoc = npc.getStoredLocation();
boolean updatePosition = Setting.HOLOGRAM_ALWAYS_UPDATE_POSITION.asBoolean()
|| currentLoc.getWorld() != npcLoc.getWorld() || currentLoc.distance(npcLoc) >= 0.001
|| lastNameplateVisible != nameplateVisible || Math.abs(lastEntityHeight - getEntityHeight()) >= 0.05;
boolean updateName = false;

if (t++ >= Setting.HOLOGRAM_UPDATE_RATE.asTicks() + Util.getFastRandom().nextInt(3) /* add some jitter */) {
t = 0;
updateName = true;
}

lastNameplateVisible = nameplateVisible;

if (updatePosition) {
currentLoc = npc.getStoredLocation();
currentLoc = npcLoc.clone();
lastEntityHeight = getEntityHeight();
}

if (nameLine != null && nameLine.hologram.isSpawned()) {
if (updatePosition && !useDisplayEntities) {
nameLine.hologram.teleport(currentLoc.clone().add(0, getEntityHeight(), 0), TeleportCause.PLUGIN);
nameLine.hologram.teleport(npcLoc.clone().add(0, getEntityHeight(), 0), TeleportCause.PLUGIN);
}

if (useDisplayEntities && nameLine.hologram.getEntity().getVehicle() == null) {
NMS.updateMountedInteractionHeight(nameLine.hologram.getEntity(), npc.getEntity(), 0);
}

if (updateName) {
Expand All @@ -330,19 +337,25 @@ public void run() {
for (int i = 0; i < lines.size(); i++) {
HologramLine line = lines.get(i);
NPC hologramNPC = line.hologram;

if (hologramNPC == null || !hologramNPC.isSpawned())
continue;

if (line.ticks > 0 && --line.ticks == 0) {
line.removeNPC();
lines.remove(i--);
continue;
}

if (updatePosition && !useDisplayEntities) {
Location tp = currentLoc.clone().add(0, lastEntityHeight
Location tp = npcLoc.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) {
line.removeNPC();
lines.remove(i--);
continue;
if (useDisplayEntities && hologramNPC.getEntity().getVehicle() == null) {
NMS.updateMountedInteractionHeight(hologramNPC.getEntity(), npc.getEntity(),
(direction == HologramDirection.BOTTOM_UP ? getHeight(i) : getMaxHeight() - getHeight(i)));
}

String text = line.text;
Expand Down Expand Up @@ -432,6 +445,7 @@ public void setMargin(int idx, String type, double margin) {
} else if (type.equalsIgnoreCase("bottom")) {
lines.get(idx).mb = margin;
}

reloadLineHolograms();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ public static void Warden(CommandContext args, CommandSender sender, NPC npc,
trait.addAnger(entity, anger);
}
}

if (!output.isEmpty()) {
Messaging.send(sender, output.trim());
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@

public class AnimationTrigger implements WaypointTrigger {
@Persist(required = true)
private final List<PlayerAnimation> animations;
private List<PlayerAnimation> animations = Lists.newArrayList();
@Persist
private final Location at;
private Location at;

public AnimationTrigger() {
}

public AnimationTrigger(Collection<PlayerAnimation> collection, Location loc) {
animations = Lists.newArrayList(collection);
Expand All @@ -35,9 +38,11 @@ public String description() {
public void onWaypointReached(NPC npc, Location waypoint) {
if (npc.getEntity().getType() != EntityType.PLAYER)
return;

if (at != null) {
npc.teleport(at, TeleportCause.PLUGIN);
}

Player player = (Player) npc.getEntity();
for (PlayerAnimation animation : animations) {
animation.play(player);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,18 @@ public Prompt acceptInput(ConversationContext context, String input) {
}
return this;
}

if (input.equalsIgnoreCase("finish")) {
context.setSessionData(WaypointTriggerPrompt.CREATED_TRIGGER_KEY, new AnimationTrigger(animations, at));
return (Prompt) context.getSessionData(WaypointTriggerPrompt.RETURN_PROMPT_KEY);
}

PlayerAnimation animation = Util.matchEnum(PlayerAnimation.values(), input);
if (animation == null) {
Messaging.sendErrorTr((CommandSender) context.getForWhom(), Messages.INVALID_ANIMATION, input,
getValidAnimations());
}

animations.add(animation);
Messaging.sendTr((CommandSender) context.getForWhom(), Messages.ANIMATION_ADDED, input);
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,21 @@
import org.bukkit.Location;

import com.google.common.base.Joiner;
import com.google.common.collect.Lists;

import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.persistence.Persist;
import net.citizensnpcs.util.Util;

public class CommandTrigger implements WaypointTrigger {
@Persist(required = true)
private final Collection<String> commands;
private Collection<String> commands = Lists.newArrayList();

public CommandTrigger() {
}

public CommandTrigger(Collection<String> commands) {
this.commands = commands;
this.commands = Lists.newArrayList(commands);
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion main/src/main/resources/messages_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ citizens.nms-errors.updating-pathfinding-range=Could not update pathfinding rang
citizens.notifications.database-connection-failed=Unable to connect to database, falling back to YAML
citizens.notifications.error-reloading=Error occured while reloading, see console.
citizens.notifications.exception-updating-npc=Exception while updating {0}: {1}.
citizens.notifications.incompatible-version=v{0} is not compatible with Minecraft v{1} - try upgrading Minecraft or Citizens. Disabling...
citizens.notifications.incompatible-version=v{0} is not compatible with Minecraft {1} - try upgrading Minecraft or Citizens. Disabling...
citizens.notifications.locale=Using locale {0}.
citizens.notifications.metrics-load-error=Unable to start metrics: {0}.
citizens.notifications.missing-translations=Missing translations file for locale {0}. Defaulting to en locale.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;

import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel;
Expand Down Expand Up @@ -208,9 +207,9 @@ public boolean save(CompoundTag save) {
@Override
public void setVariant(Variant variant) {
if (npc != null) {
if (NMSImpl.getRabbitTypeField() == null)
if (NMSImpl.RABBIT_TYPE_DATAWATCHER == null)
return;
this.entityData.set(NMSImpl.getRabbitTypeField(), variant.id());
this.entityData.set(NMSImpl.RABBIT_TYPE_DATAWATCHER, variant.id());
return;
}
super.setVariant(variant);
Expand Down

0 comments on commit e889476

Please sign in to comment.