Fixes for hologram display entities

This commit is contained in:
fullwall 2023-10-23 01:58:06 +08:00
parent 627811ca7a
commit e889476e7b
15 changed files with 98 additions and 39 deletions

View File

@ -82,6 +82,7 @@ import net.citizensnpcs.npc.profile.ProfileFetcher;
import net.citizensnpcs.npc.skin.Skin; import net.citizensnpcs.npc.skin.Skin;
import net.citizensnpcs.trait.ClickRedirectTrait; import net.citizensnpcs.trait.ClickRedirectTrait;
import net.citizensnpcs.trait.CommandTrait; import net.citizensnpcs.trait.CommandTrait;
import net.citizensnpcs.trait.HologramTrait;
import net.citizensnpcs.trait.ScriptTrait; import net.citizensnpcs.trait.ScriptTrait;
import net.citizensnpcs.trait.ShopTrait; import net.citizensnpcs.trait.ShopTrait;
import net.citizensnpcs.util.Messages; import net.citizensnpcs.util.Messages;
@ -561,6 +562,16 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
return 0; return 0;
return Iterables.size(npcRegistry); 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", () -> { metrics.addCustomChart(new Metrics.AdvancedPie("traits", () -> {
Map<String, Integer> res = Maps.newHashMap(); Map<String, Integer> res = Maps.newHashMap();
for (NPC npc : npcRegistry) { for (NPC npc : npcRegistry) {

View File

@ -287,7 +287,7 @@ public class EventListen implements Listener {
} }
return; return;
} }
event.setCancelled(npc.isProtected());
if (event instanceof EntityDamageByEntityEvent) { if (event instanceof EntityDamageByEntityEvent) {
NPCDamageByEntityEvent damageEvent = new NPCDamageByEntityEvent(npc, (EntityDamageByEntityEvent) event); NPCDamageByEntityEvent damageEvent = new NPCDamageByEntityEvent(npc, (EntityDamageByEntityEvent) event);
Bukkit.getPluginManager().callEvent(damageEvent); Bukkit.getPluginManager().callEvent(damageEvent);
@ -436,6 +436,7 @@ public class EventListen implements Listener {
if (npc.hasTrait(ClickRedirectTrait.class)) { if (npc.hasTrait(ClickRedirectTrait.class)) {
npc = npc.getOrAddTrait(ClickRedirectTrait.class).getRedirectNPC(); npc = npc.getOrAddTrait(ClickRedirectTrait.class).getRedirectNPC();
} }
if (npc.hasTrait(PlayerFilter.class)) { if (npc.hasTrait(PlayerFilter.class)) {
event.setCancelled(npc.getOrAddTrait(PlayerFilter.class).onSeenByPlayer(event.getPlayer())); event.setCancelled(npc.getOrAddTrait(PlayerFilter.class).onSeenByPlayer(event.getPlayer()));
} }

View File

@ -176,6 +176,8 @@ public class Settings {
FOLLOW_ACROSS_WORLDS("Whether /npc follow will teleport across worlds to follow its target", FOLLOW_ACROSS_WORLDS("Whether /npc follow will teleport across worlds to follow its target",
"npc.follow.teleport-across-worlds", false), "npc.follow.teleport-across-worlds", false),
HIGHLIGHT_COLOUR("general.color-scheme.message-highlight", "yellow"), 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)", HOLOGRAM_UPDATE_RATE("How often to update hologram names (including placeholders)",
"npc.hologram.update-rate-ticks", "npc.hologram.update-rate", "1s"), "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", INITIAL_PLAYER_JOIN_SKIN_PACKET_DELAY("How long to wait before sending skins to joined players",
@ -200,7 +202,7 @@ public class Settings {
"npc.pathfinding.maximum-new-pathfinder-iterations", "npc.pathfinding.new-finder.maximum-iterations", "npc.pathfinding.maximum-new-pathfinder-iterations", "npc.pathfinding.new-finder.maximum-iterations",
768), 768),
MAXIMUM_VISITED_NODES("The maximum number of blocks to check when MINECRAFT pathfinding", 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>"), MESSAGE_COLOUR("general.color-scheme.message", "<green>"),
NEW_PATHFINDER_CHECK_BOUNDING_BOXES( NEW_PATHFINDER_CHECK_BOUNDING_BOXES(
"Whether to check bounding boxes when pathfinding such as between fences, inside doors, or other half-blocks", "Whether to check bounding boxes when pathfinding such as between fences, inside doors, or other half-blocks",

View File

@ -51,6 +51,7 @@ public class AdminCommands {
return; return;
} }
} }
Messaging.sendTr(sender, Messages.CITIZENS_RELOADING); Messaging.sendTr(sender, Messages.CITIZENS_RELOADING);
try { try {
plugin.reload(); plugin.reload();

View File

@ -408,6 +408,7 @@ public class NPCCommands {
} else if (Setting.DEFAULT_BLOCK_BREAKER_RADIUS.asDouble() > 0) { } else if (Setting.DEFAULT_BLOCK_BREAKER_RADIUS.asDouble() > 0) {
cfg.radius(Setting.DEFAULT_BLOCK_BREAKER_RADIUS.asDouble()); cfg.radius(Setting.DEFAULT_BLOCK_BREAKER_RADIUS.asDouble());
} }
BlockBreaker breaker = npc.getBlockBreaker(args.getSenderTargetBlockLocation().getBlock(), cfg); BlockBreaker breaker = npc.getBlockBreaker(args.getSenderTargetBlockLocation().getBlock(), cfg);
npc.getDefaultGoalController().addBehavior(StatusMapper.singleUse(breaker), 1); npc.getDefaultGoalController().addBehavior(StatusMapper.singleUse(breaker), 1);
} }
@ -733,6 +734,7 @@ public class NPCCommands {
if (args.hasFlag('t') || temporaryTicks != null) { if (args.hasFlag('t') || temporaryTicks != null) {
registry = temporaryRegistry; registry = temporaryRegistry;
} }
if (item != null) { if (item != null) {
ItemStack stack = Util.parseItemStack(null, item); ItemStack stack = Util.parseItemStack(null, item);
npc = registry.createNPCUsingItem(type, name, stack); npc = registry.createNPCUsingItem(type, name, stack);

View File

@ -143,6 +143,7 @@ public class CitizensNPC extends AbstractNPC {
public void faceLocation(Location location) { public void faceLocation(Location location) {
if (!isSpawned()) if (!isSpawned())
return; return;
Util.faceLocation(getEntity(), location); Util.faceLocation(getEntity(), location);
} }
@ -191,7 +192,7 @@ public class CitizensNPC extends AbstractNPC {
@Override @Override
public void load(final DataKey root) { public void load(final DataKey root) {
super.load(root); super.load(root);
// Spawn the NPC
CurrentLocation spawnLocation = getOrAddTrait(CurrentLocation.class); CurrentLocation spawnLocation = getOrAddTrait(CurrentLocation.class);
if (getOrAddTrait(Spawned.class).shouldSpawn() && spawnLocation.getLocation() != null) { if (getOrAddTrait(Spawned.class).shouldSpawn() && spawnLocation.getLocation() != null) {
if (spawnLocation.getLocation() != null) { if (spawnLocation.getLocation() != null) {
@ -224,8 +225,10 @@ public class CitizensNPC extends AbstractNPC {
@Override @Override
public void save(DataKey root) { public void save(DataKey root) {
super.save(root); super.save(root);
if (!data().get(NPC.Metadata.SHOULD_SAVE, true)) if (!data().get(NPC.Metadata.SHOULD_SAVE, true))
return; return;
navigator.save(root.getRelative("navigator")); navigator.save(root.getRelative("navigator"));
} }
@ -252,10 +255,12 @@ public class CitizensNPC extends AbstractNPC {
prev = getEntity().getLocation(); prev = getEntity().getLocation();
despawn(DespawnReason.PENDING_RESPAWN); despawn(DespawnReason.PENDING_RESPAWN);
} }
PacketNPC packet = getTraitNullable(PacketNPC.class); PacketNPC packet = getTraitNullable(PacketNPC.class);
if (packet != null) { if (packet != null) {
newController = packet.wrap(newController); newController = packet.wrap(newController);
} }
entityController = newController; entityController = newController;
if (wasSpawned) { if (wasSpawned) {
spawn(prev, SpawnReason.RESPAWN); spawn(prev, SpawnReason.RESPAWN);
@ -457,14 +462,17 @@ public class CitizensNPC extends AbstractNPC {
public void teleport(Location location, TeleportCause reason) { public void teleport(Location location, TeleportCause reason) {
if (!isSpawned()) if (!isSpawned())
return; return;
if (hasTrait(SitTrait.class) && getOrAddTrait(SitTrait.class).isSitting()) { if (hasTrait(SitTrait.class) && getOrAddTrait(SitTrait.class).isSitting()) {
getOrAddTrait(SitTrait.class).setSitting(location); getOrAddTrait(SitTrait.class).setSitting(location);
} }
Location npcLoc = getEntity().getLocation(); Location npcLoc = getEntity().getLocation();
if (isSpawned() && npcLoc.getWorld() == location.getWorld()) { if (isSpawned() && npcLoc.getWorld() == location.getWorld()) {
if (npcLoc.distance(location) < 1) { if (npcLoc.distance(location) < 1) {
NMS.setHeadYaw(getEntity(), location.getYaw()); NMS.setHeadYaw(getEntity(), location.getYaw());
} }
if (getEntity().getType() == EntityType.PLAYER && !getEntity().isInsideVehicle() if (getEntity().getType() == EntityType.PLAYER && !getEntity().isInsideVehicle()
&& NMS.getPassengers(getEntity()).size() == 0) { && NMS.getPassengers(getEntity()).size() == 0) {
NPCTeleportEvent event = new NPCTeleportEvent(this, location); NPCTeleportEvent event = new NPCTeleportEvent(this, location);
@ -475,6 +483,7 @@ public class CitizensNPC extends AbstractNPC {
return; return;
} }
} }
super.teleport(location, reason); super.teleport(location, reason);
} }
@ -602,14 +611,20 @@ public class CitizensNPC extends AbstractNPC {
} }
private void updateFlyableState() { private void updateFlyableState() {
if (!CitizensAPI.hasImplementation())
return;
EntityType type = isSpawned() ? getEntity().getType() : getOrAddTrait(MobType.class).getType(); EntityType type = isSpawned() ? getEntity().getType() : getOrAddTrait(MobType.class).getType();
if (type == null) if (type == null)
return; return;
if (!Util.isAlwaysFlyable(type)) if (!Util.isAlwaysFlyable(type))
return; return;
if (!data().has(NPC.Metadata.FLYABLE)) { if (!data().has(NPC.Metadata.FLYABLE)) {
data().setPersistent(NPC.Metadata.FLYABLE, true); data().setPersistent(NPC.Metadata.FLYABLE, true);
} }
if (!hasTrait(Gravity.class)) { if (!hasTrait(Gravity.class)) {
getOrAddTrait(Gravity.class).setEnabled(true); getOrAddTrait(Gravity.class).setEnabled(true);
} }
@ -624,8 +639,10 @@ public class CitizensNPC extends AbstractNPC {
private void updateUsingItemState(Player player) { private void updateUsingItemState(Player player) {
boolean useItem = data().get(NPC.Metadata.USING_HELD_ITEM, false), boolean useItem = data().get(NPC.Metadata.USING_HELD_ITEM, false),
offhand = data().get(NPC.Metadata.USING_OFFHAND_ITEM, false); offhand = data().get(NPC.Metadata.USING_OFFHAND_ITEM, false);
if (!SUPPORT_USE_ITEM) if (!SUPPORT_USE_ITEM)
return; return;
try { try {
if (useItem) { if (useItem) {
NMS.playAnimation(PlayerAnimation.STOP_USE_ITEM, player, 64); NMS.playAnimation(PlayerAnimation.STOP_USE_ITEM, player, 64);

View File

@ -302,24 +302,31 @@ public class HologramTrait extends Trait {
} }
} }
boolean updatePosition = currentLoc.getWorld() != npc.getStoredLocation().getWorld() Location npcLoc = npc.getStoredLocation();
|| currentLoc.distance(npc.getStoredLocation()) >= 0.001 || lastNameplateVisible != nameplateVisible boolean updatePosition = Setting.HOLOGRAM_ALWAYS_UPDATE_POSITION.asBoolean()
|| Math.abs(lastEntityHeight - getEntityHeight()) >= 0.05; || currentLoc.getWorld() != npcLoc.getWorld() || currentLoc.distance(npcLoc) >= 0.001
|| lastNameplateVisible != nameplateVisible || Math.abs(lastEntityHeight - getEntityHeight()) >= 0.05;
boolean updateName = false; boolean updateName = false;
if (t++ >= Setting.HOLOGRAM_UPDATE_RATE.asTicks() + Util.getFastRandom().nextInt(3) /* add some jitter */) { if (t++ >= Setting.HOLOGRAM_UPDATE_RATE.asTicks() + Util.getFastRandom().nextInt(3) /* add some jitter */) {
t = 0; t = 0;
updateName = true; updateName = true;
} }
lastNameplateVisible = nameplateVisible; lastNameplateVisible = nameplateVisible;
if (updatePosition) { if (updatePosition) {
currentLoc = npc.getStoredLocation(); currentLoc = npcLoc.clone();
lastEntityHeight = getEntityHeight(); lastEntityHeight = getEntityHeight();
} }
if (nameLine != null && nameLine.hologram.isSpawned()) { if (nameLine != null && nameLine.hologram.isSpawned()) {
if (updatePosition && !useDisplayEntities) { 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) { if (updateName) {
@ -330,21 +337,27 @@ public class HologramTrait extends Trait {
for (int i = 0; i < lines.size(); i++) { for (int i = 0; i < lines.size(); i++) {
HologramLine line = lines.get(i); HologramLine line = lines.get(i);
NPC hologramNPC = line.hologram; NPC hologramNPC = line.hologram;
if (hologramNPC == null || !hologramNPC.isSpawned()) if (hologramNPC == null || !hologramNPC.isSpawned())
continue; continue;
if (updatePosition && !useDisplayEntities) {
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) { if (line.ticks > 0 && --line.ticks == 0) {
line.removeNPC(); line.removeNPC();
lines.remove(i--); lines.remove(i--);
continue; continue;
} }
if (updatePosition && !useDisplayEntities) {
Location tp = npcLoc.clone().add(0, lastEntityHeight
+ (direction == HologramDirection.BOTTOM_UP ? getHeight(i) : getMaxHeight() - getHeight(i)), 0);
hologramNPC.teleport(tp, TeleportCause.PLUGIN);
}
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; String text = line.text;
if (ITEM_MATCHER.matcher(text).matches()) { if (ITEM_MATCHER.matcher(text).matches()) {
hologramNPC.data().set(NPC.Metadata.NAMEPLATE_VISIBLE, false); hologramNPC.data().set(NPC.Metadata.NAMEPLATE_VISIBLE, false);
@ -432,6 +445,7 @@ public class HologramTrait extends Trait {
} else if (type.equalsIgnoreCase("bottom")) { } else if (type.equalsIgnoreCase("bottom")) {
lines.get(idx).mb = margin; lines.get(idx).mb = margin;
} }
reloadLineHolograms(); reloadLineHolograms();
} }

View File

@ -72,6 +72,7 @@ public class WardenTrait extends Trait {
trait.addAnger(entity, anger); trait.addAnger(entity, anger);
} }
} }
if (!output.isEmpty()) { if (!output.isEmpty()) {
Messaging.send(sender, output.trim()); Messaging.send(sender, output.trim());
} else { } else {

View File

@ -17,9 +17,12 @@ import net.citizensnpcs.util.PlayerAnimation;
public class AnimationTrigger implements WaypointTrigger { public class AnimationTrigger implements WaypointTrigger {
@Persist(required = true) @Persist(required = true)
private final List<PlayerAnimation> animations; private List<PlayerAnimation> animations = Lists.newArrayList();
@Persist @Persist
private final Location at; private Location at;
public AnimationTrigger() {
}
public AnimationTrigger(Collection<PlayerAnimation> collection, Location loc) { public AnimationTrigger(Collection<PlayerAnimation> collection, Location loc) {
animations = Lists.newArrayList(collection); animations = Lists.newArrayList(collection);
@ -35,9 +38,11 @@ public class AnimationTrigger implements WaypointTrigger {
public void onWaypointReached(NPC npc, Location waypoint) { public void onWaypointReached(NPC npc, Location waypoint) {
if (npc.getEntity().getType() != EntityType.PLAYER) if (npc.getEntity().getType() != EntityType.PLAYER)
return; return;
if (at != null) { if (at != null) {
npc.teleport(at, TeleportCause.PLUGIN); npc.teleport(at, TeleportCause.PLUGIN);
} }
Player player = (Player) npc.getEntity(); Player player = (Player) npc.getEntity();
for (PlayerAnimation animation : animations) { for (PlayerAnimation animation : animations) {
animation.play(player); animation.play(player);

View File

@ -40,15 +40,18 @@ public class AnimationTriggerPrompt extends StringPrompt implements WaypointTrig
} }
return this; return this;
} }
if (input.equalsIgnoreCase("finish")) { if (input.equalsIgnoreCase("finish")) {
context.setSessionData(WaypointTriggerPrompt.CREATED_TRIGGER_KEY, new AnimationTrigger(animations, at)); context.setSessionData(WaypointTriggerPrompt.CREATED_TRIGGER_KEY, new AnimationTrigger(animations, at));
return (Prompt) context.getSessionData(WaypointTriggerPrompt.RETURN_PROMPT_KEY); return (Prompt) context.getSessionData(WaypointTriggerPrompt.RETURN_PROMPT_KEY);
} }
PlayerAnimation animation = Util.matchEnum(PlayerAnimation.values(), input); PlayerAnimation animation = Util.matchEnum(PlayerAnimation.values(), input);
if (animation == null) { if (animation == null) {
Messaging.sendErrorTr((CommandSender) context.getForWhom(), Messages.INVALID_ANIMATION, input, Messaging.sendErrorTr((CommandSender) context.getForWhom(), Messages.INVALID_ANIMATION, input,
getValidAnimations()); getValidAnimations());
} }
animations.add(animation); animations.add(animation);
Messaging.sendTr((CommandSender) context.getForWhom(), Messages.ANIMATION_ADDED, input); Messaging.sendTr((CommandSender) context.getForWhom(), Messages.ANIMATION_ADDED, input);
return this; return this;

View File

@ -5,6 +5,7 @@ import java.util.Collection;
import org.bukkit.Location; import org.bukkit.Location;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.persistence.Persist; import net.citizensnpcs.api.persistence.Persist;
@ -12,10 +13,13 @@ import net.citizensnpcs.util.Util;
public class CommandTrigger implements WaypointTrigger { public class CommandTrigger implements WaypointTrigger {
@Persist(required = true) @Persist(required = true)
private final Collection<String> commands; private Collection<String> commands = Lists.newArrayList();
public CommandTrigger() {
}
public CommandTrigger(Collection<String> commands) { public CommandTrigger(Collection<String> commands) {
this.commands = commands; this.commands = Lists.newArrayList(commands);
} }
@Override @Override

View File

@ -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.database-connection-failed=Unable to connect to database, falling back to YAML
citizens.notifications.error-reloading=Error occured while reloading, see console. citizens.notifications.error-reloading=Error occured while reloading, see console.
citizens.notifications.exception-updating-npc=Exception while updating {0}: {1}. 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.locale=Using locale {0}.
citizens.notifications.metrics-load-error=Unable to start metrics: {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. citizens.notifications.missing-translations=Missing translations file for locale {0}. Defaulting to en locale.

View File

@ -15,7 +15,6 @@ import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS; import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util; import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
@ -208,9 +207,9 @@ public class RabbitController extends MobEntityController {
@Override @Override
public void setVariant(Variant variant) { public void setVariant(Variant variant) {
if (npc != null) { if (npc != null) {
if (NMSImpl.getRabbitTypeField() == null) if (NMSImpl.RABBIT_TYPE_DATAWATCHER == null)
return; return;
this.entityData.set(NMSImpl.getRabbitTypeField(), variant.id()); this.entityData.set(NMSImpl.RABBIT_TYPE_DATAWATCHER, variant.id());
return; return;
} }
super.setVariant(variant); super.setVariant(variant);

View File

@ -101,6 +101,7 @@ public class CitizensEntityTracker extends ChunkMap.TrackedEntity {
if (REQUIRES_SYNC == null) { if (REQUIRES_SYNC == null) {
REQUIRES_SYNC = !Bukkit.isPrimaryThread(); REQUIRES_SYNC = !Bukkit.isPrimaryThread();
} }
boolean cancelled = Util.callPossiblySync(() -> { boolean cancelled = Util.callPossiblySync(() -> {
NPCSeenByPlayerEvent event = new NPCSeenByPlayerEvent(npc, entityplayer.getBukkitEntity()); NPCSeenByPlayerEvent event = new NPCSeenByPlayerEvent(npc, entityplayer.getBukkitEntity());
try { try {
@ -109,8 +110,10 @@ public class CitizensEntityTracker extends ChunkMap.TrackedEntity {
REQUIRES_SYNC = true; REQUIRES_SYNC = true;
throw e; throw e;
} }
if (event.isCancelled()) if (event.isCancelled())
return true; return true;
Integer trackingRange = npc.data().<Integer> get(NPC.Metadata.TRACKING_RANGE); Integer trackingRange = npc.data().<Integer> get(NPC.Metadata.TRACKING_RANGE);
if (TRACKING_RANGE_SETTER != null && trackingRange != null if (TRACKING_RANGE_SETTER != null && trackingRange != null
&& npc.data().get("last-tracking-range", -1) != trackingRange.intValue()) { && npc.data().get("last-tracking-range", -1) != trackingRange.intValue()) {
@ -131,15 +134,6 @@ public class CitizensEntityTracker extends ChunkMap.TrackedEntity {
super.updatePlayer(entityplayer); super.updatePlayer(entityplayer);
} }
private static int getUpdateInterval(TrackedEntity entry) {
try {
return (int) UPDATE_INTERVAL.invoke(TRACKER_ENTRY.invoke(entry));
} catch (Throwable e) {
e.printStackTrace();
}
return 0;
}
private static boolean getTrackDelta(TrackedEntity entry) { private static boolean getTrackDelta(TrackedEntity entry) {
try { try {
return (boolean) TRACK_DELTA.invoke(TRACKER_ENTRY.invoke(entry)); return (boolean) TRACK_DELTA.invoke(TRACKER_ENTRY.invoke(entry));
@ -167,13 +161,22 @@ public class CitizensEntityTracker extends ChunkMap.TrackedEntity {
return 0; return 0;
} }
private static final MethodHandle UPDATE_INTERVAL = NMS.getGetter(ServerEntity.class, "h"); private static int getUpdateInterval(TrackedEntity entry) {
private static final MethodHandle TRACK_DELTA = NMS.getGetter(ServerEntity.class, "i"); try {
return (int) UPDATE_INTERVAL.invoke(TRACKER_ENTRY.invoke(entry));
} catch (Throwable e) {
e.printStackTrace();
}
return 0;
}
private static volatile Boolean REQUIRES_SYNC; private static volatile Boolean REQUIRES_SYNC;
private static final MethodHandle TRACK_DELTA = NMS.getGetter(ServerEntity.class, "i");
private static final MethodHandle TRACKER = NMS.getFirstGetter(TrackedEntity.class, Entity.class); private static final MethodHandle TRACKER = NMS.getFirstGetter(TrackedEntity.class, Entity.class);
private static final MethodHandle TRACKER_ENTRY = NMS.getFirstGetter(TrackedEntity.class, ServerEntity.class); private static final MethodHandle TRACKER_ENTRY = NMS.getFirstGetter(TrackedEntity.class, ServerEntity.class);
private static final MethodHandle TRACKING_RANGE = NMS.getFirstGetter(TrackedEntity.class, int.class); private static final MethodHandle TRACKING_RANGE = NMS.getFirstGetter(TrackedEntity.class, int.class);
private static final MethodHandle TRACKING_RANGE_SETTER = NMS.getFirstFinalSetter(TrackedEntity.class, int.class); private static final MethodHandle TRACKING_RANGE_SETTER = NMS.getFirstFinalSetter(TrackedEntity.class, int.class);
private static final MethodHandle TRACKING_SET_GETTER = NMS.getFirstGetter(TrackedEntity.class, Set.class); private static final MethodHandle TRACKING_SET_GETTER = NMS.getFirstGetter(TrackedEntity.class, Set.class);
private static final MethodHandle TRACKING_SET_SETTER = NMS.getFirstFinalSetter(TrackedEntity.class, Set.class); private static final MethodHandle TRACKING_SET_SETTER = NMS.getFirstFinalSetter(TrackedEntity.class, Set.class);
private static final MethodHandle UPDATE_INTERVAL = NMS.getGetter(ServerEntity.class, "h");
} }

View File

@ -1788,7 +1788,7 @@ public class NMSImpl implements NMSBridge {
public void updateMountedInteractionHeight(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity mount, public void updateMountedInteractionHeight(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity mount,
double offset) { double offset) {
Interaction handle = (Interaction) getHandle(entity); Interaction handle = (Interaction) getHandle(entity);
offset += -0.5 + getHandle(mount).getDimensions(Pose.SITTING).height * 0.75; offset += handle.getMyRidingOffset(getHandle(mount));
((org.bukkit.entity.Interaction) entity).setInteractionHeight((float) offset); ((org.bukkit.entity.Interaction) entity).setInteractionHeight((float) offset);
mount.addPassenger(entity); mount.addPassenger(entity);
handle.setPose(Pose.SNIFFING); handle.setPose(Pose.SNIFFING);
@ -2222,10 +2222,6 @@ public class NMSImpl implements NMSBridge {
return toSend; return toSend;
} }
public static EntityDataAccessor<Integer> getRabbitTypeField() {
return RABBIT_TYPE_DATAWATCHER;
}
public static EntityDimensions getSize(Entity entity) { public static EntityDimensions getSize(Entity entity) {
try { try {
return (EntityDimensions) SIZE_FIELD_GETTER.invoke(entity); return (EntityDimensions) SIZE_FIELD_GETTER.invoke(entity);
@ -2576,7 +2572,7 @@ public class NMSImpl implements NMSBridge {
VecDeltaCodec.class); VecDeltaCodec.class);
private static final MethodHandle PUFFERFISH_DEFLATE = NMS.getSetter(Pufferfish.class, "bU"); private static final MethodHandle PUFFERFISH_DEFLATE = NMS.getSetter(Pufferfish.class, "bU");
private static final MethodHandle PUFFERFISH_INFLATE = NMS.getSetter(Pufferfish.class, "bT"); private static final MethodHandle PUFFERFISH_INFLATE = NMS.getSetter(Pufferfish.class, "bT");
private static EntityDataAccessor<Integer> RABBIT_TYPE_DATAWATCHER = null; public static EntityDataAccessor<Integer> RABBIT_TYPE_DATAWATCHER = null;
private static final Random RANDOM = Util.getFastRandom(); private static final Random RANDOM = Util.getFastRandom();
private static final MethodHandle SERVER_ENTITY_GETTER = NMS.getFirstGetter(TrackedEntity.class, private static final MethodHandle SERVER_ENTITY_GETTER = NMS.getFirstGetter(TrackedEntity.class,
ServerEntity.class); ServerEntity.class);