diff --git a/main/src/main/java/net/citizensnpcs/EventListen.java b/main/src/main/java/net/citizensnpcs/EventListen.java index 02320e259..b63e9e76c 100644 --- a/main/src/main/java/net/citizensnpcs/EventListen.java +++ b/main/src/main/java/net/citizensnpcs/EventListen.java @@ -465,6 +465,7 @@ public class EventListen implements Listener { @EventHandler(ignoreCancelled = true) public void onNPCLinkToPlayer(NPCLinkToPlayerEvent event) { NPC npc = event.getNPC(); + NMS.markPoseDirty(npc.getEntity()); if (npc.getEntity() instanceof SkinnableEntity) { SkinnableEntity skinnable = (SkinnableEntity) npc.getEntity(); if (skinnable.getSkinTracker().getSkin() != null) { diff --git a/main/src/main/java/net/citizensnpcs/npc/CitizensNPC.java b/main/src/main/java/net/citizensnpcs/npc/CitizensNPC.java index 6563bcdae..bdb2ced86 100644 --- a/main/src/main/java/net/citizensnpcs/npc/CitizensNPC.java +++ b/main/src/main/java/net/citizensnpcs/npc/CitizensNPC.java @@ -346,8 +346,7 @@ public class CitizensNPC extends AbstractNPC { } } NMS.setLocationDirectly(getEntity(), at); - NMS.setHeadYaw(getEntity(), at.getYaw()); - NMS.setBodyYaw(getEntity(), at.getYaw()); + NMS.setHeadAndBodyYaw(getEntity(), at.getYaw()); // Paper now doesn't actually set entities as valid for a few ticks while adding entities to chunks // Need to check the entity is really valid for a few ticks before finalising spawning diff --git a/main/src/main/java/net/citizensnpcs/trait/EntityPoseTrait.java b/main/src/main/java/net/citizensnpcs/trait/EntityPoseTrait.java index 08f0183a3..a3ac175c3 100644 --- a/main/src/main/java/net/citizensnpcs/trait/EntityPoseTrait.java +++ b/main/src/main/java/net/citizensnpcs/trait/EntityPoseTrait.java @@ -27,7 +27,6 @@ public class EntityPoseTrait extends Trait { public void setPose(EntityPose pose) { this.pose = pose; - } public enum EntityPose { diff --git a/main/src/main/java/net/citizensnpcs/trait/SleepTrait.java b/main/src/main/java/net/citizensnpcs/trait/SleepTrait.java index fb2c1aa6b..e02cb67a0 100644 --- a/main/src/main/java/net/citizensnpcs/trait/SleepTrait.java +++ b/main/src/main/java/net/citizensnpcs/trait/SleepTrait.java @@ -24,6 +24,7 @@ public class SleepTrait extends Trait { @Override public void onDespawn() { + npc.getOrAddTrait(EntityPoseTrait.class).setPose(null); sleeping = false; } @@ -38,9 +39,10 @@ public class SleepTrait extends Trait { } return; } + if (sleeping) + return; if (npc.getEntity() instanceof Player) { Player player = (Player) npc.getEntity(); - npc.getOrAddTrait(EntityPoseTrait.class).setPose(EntityPose.SLEEPING); if (SUPPORT_BLOCKDATA) { try { if (at.getBlock().getBlockData() instanceof Bed || at.getBlock().getState() instanceof Bed) { @@ -55,6 +57,7 @@ public class SleepTrait extends Trait { } else { NMS.sleep(player, true); } + npc.getOrAddTrait(EntityPoseTrait.class).setPose(EntityPose.SLEEPING); sleeping = true; } else if (npc.getEntity() instanceof Villager) { sleeping = ((Villager) npc.getEntity()).sleep(at); diff --git a/main/src/main/java/net/citizensnpcs/util/NMS.java b/main/src/main/java/net/citizensnpcs/util/NMS.java index d2a6467df..94afd5ba6 100644 --- a/main/src/main/java/net/citizensnpcs/util/NMS.java +++ b/main/src/main/java/net/citizensnpcs/util/NMS.java @@ -723,6 +723,10 @@ public class NMS { BRIDGE.look(bhandle, btarget); } + public static void markPoseDirty(Entity tracker) { + BRIDGE.markPoseDirty(tracker); + } + public static void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) { BRIDGE.mount(entity, passenger); } diff --git a/main/src/main/java/net/citizensnpcs/util/NMSBridge.java b/main/src/main/java/net/citizensnpcs/util/NMSBridge.java index fe76b69c8..cf23505c1 100644 --- a/main/src/main/java/net/citizensnpcs/util/NMSBridge.java +++ b/main/src/main/java/net/citizensnpcs/util/NMSBridge.java @@ -130,7 +130,7 @@ public interface NMSBridge { public float getVerticalMovement(Entity entity); public default Collection getViewingPlayers(Entity entity) { - return ((Player) entity).getTrackedBy(); + return entity.getTrackedBy(); } public double getWidth(Entity entity); @@ -150,9 +150,6 @@ public interface NMSBridge { public boolean isValid(Entity entity); - public default void positionInteractionText(Player player, Entity interaction, Entity mount, double height) { - } - public void load(CommandManager commands); public void look(Entity from, Entity to); @@ -161,6 +158,9 @@ public interface NMSBridge { public void look(Entity entity, Location to, boolean headOnly, boolean immediate); + public default void markPoseDirty(Entity tracker) { + } + public void mount(Entity entity, Entity passenger); public default void onPlayerInfoAdd(Player player, Object source, Function mirrorTraits) { @@ -174,6 +174,9 @@ public interface NMSBridge { public Runnable playerTicker(NPC npc, Player entity); + public default void positionInteractionText(Player player, Entity interaction, Entity mount, double height) { + } + public void registerEntityClass(Class clazz); public void remove(Entity entity); diff --git a/main/src/main/java/net/citizensnpcs/util/Util.java b/main/src/main/java/net/citizensnpcs/util/Util.java index dd52acbfa..4bc9b1775 100644 --- a/main/src/main/java/net/citizensnpcs/util/Util.java +++ b/main/src/main/java/net/citizensnpcs/util/Util.java @@ -616,11 +616,15 @@ public class Util { } private static String BEDROCK_NAME_PREFIX = "."; - private static final Scoreboard DUMMY_SCOREBOARD = Bukkit.getScoreboardManager().getNewScoreboard(); + private static Scoreboard DUMMY_SCOREBOARD; private static boolean SUPPORTS_BUKKIT_GETENTITY = true; private static final DecimalFormat TWO_DIGIT_DECIMAL = new DecimalFormat(); static { + try { + DUMMY_SCOREBOARD = Bukkit.getScoreboardManager().getNewScoreboard(); + } catch (NullPointerException e) { + } TWO_DIGIT_DECIMAL.setMaximumFractionDigits(2); try { Bukkit.class.getMethod("getEntity", UUID.class); diff --git a/v1_14_R1/src/main/java/net/citizensnpcs/nms/v1_14_R1/util/NMSImpl.java b/v1_14_R1/src/main/java/net/citizensnpcs/nms/v1_14_R1/util/NMSImpl.java index 135415842..5f1e7f5be 100644 --- a/v1_14_R1/src/main/java/net/citizensnpcs/nms/v1_14_R1/util/NMSImpl.java +++ b/v1_14_R1/src/main/java/net/citizensnpcs/nms/v1_14_R1/util/NMSImpl.java @@ -1042,6 +1042,11 @@ public class NMSImpl implements NMSBridge { } } + @Override + public void markPoseDirty(org.bukkit.entity.Entity entity) { + getHandle(entity).getDataWatcher().markDirty(DATA_POSE); + } + @Override public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) { if (NMSImpl.getHandle(passenger) == null) @@ -2203,6 +2208,7 @@ public class NMSImpl implements NMSBridge { true, EntityPlayer.class, boolean.class); private static final Map, EntityTypes> CITIZENS_ENTITY_TYPES = Maps.newHashMap(); private static final MethodHandle CRAFT_BOSSBAR_HANDLE_FIELD = NMS.getSetter(CraftBossBar.class, "handle"); + private static DataWatcherObject DATA_POSE = null; private static final float DEFAULT_SPEED = 1F; private static final MethodHandle ENDERDRAGON_BATTLE_FIELD = NMS.getGetter(EntityEnderDragon.class, "bP"); public static MethodHandle ENDERDRAGON_CHECK_WALLS = NMS.getFirstMethodHandleWithReturnType(EntityEnderDragon.class, @@ -2252,6 +2258,7 @@ public class NMSImpl implements NMSBridge { private static final MethodHandle SIZE_FIELD_SETTER = NMS.getSetter(Entity.class, "size"); private static Field SKULL_PROFILE_FIELD; private static MethodHandle TEAM_FIELD; + static { try { ENTITY_REGISTRY = new CustomEntityRegistry( @@ -2267,5 +2274,10 @@ public class NMSImpl implements NMSBridge { } catch (IllegalAccessException e) { e.printStackTrace(); } + try { + DATA_POSE = (DataWatcherObject) NMS.getGetter(Entity.class, "X").invoke(); + } catch (Throwable e) { + e.printStackTrace(); + } } } diff --git a/v1_15_R1/src/main/java/net/citizensnpcs/nms/v1_15_R1/util/NMSImpl.java b/v1_15_R1/src/main/java/net/citizensnpcs/nms/v1_15_R1/util/NMSImpl.java index c6f1dfb48..68f8e3645 100644 --- a/v1_15_R1/src/main/java/net/citizensnpcs/nms/v1_15_R1/util/NMSImpl.java +++ b/v1_15_R1/src/main/java/net/citizensnpcs/nms/v1_15_R1/util/NMSImpl.java @@ -1059,6 +1059,11 @@ public class NMSImpl implements NMSBridge { } } + @Override + public void markPoseDirty(org.bukkit.entity.Entity entity) { + getHandle(entity).getDataWatcher().markDirty(DATA_POSE); + } + @Override public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) { if (NMSImpl.getHandle(passenger) == null) @@ -2285,6 +2290,7 @@ public class NMSImpl implements NMSBridge { true, EntityPlayer.class, boolean.class); private static final Map, EntityTypes> CITIZENS_ENTITY_TYPES = Maps.newHashMap(); private static final MethodHandle CRAFT_BOSSBAR_HANDLE_FIELD = NMS.getSetter(CraftBossBar.class, "handle"); + private static DataWatcherObject DATA_POSE = null; private static final float DEFAULT_SPEED = 1F; private static final MethodHandle ENDERDRAGON_BATTLE_FIELD = NMS.getGetter(EntityEnderDragon.class, "bN"); public static MethodHandle ENDERDRAGON_CHECK_WALLS = NMS.getFirstMethodHandleWithReturnType(EntityEnderDragon.class, @@ -2353,5 +2359,10 @@ public class NMSImpl implements NMSBridge { } catch (IllegalAccessException e) { e.printStackTrace(); } + try { + DATA_POSE = (DataWatcherObject) NMS.getGetter(Entity.class, "U").invoke(); + } catch (Throwable e) { + e.printStackTrace(); + } } } diff --git a/v1_16_R3/src/main/java/net/citizensnpcs/nms/v1_16_R3/util/NMSImpl.java b/v1_16_R3/src/main/java/net/citizensnpcs/nms/v1_16_R3/util/NMSImpl.java index 6698cf401..d6f986d24 100644 --- a/v1_16_R3/src/main/java/net/citizensnpcs/nms/v1_16_R3/util/NMSImpl.java +++ b/v1_16_R3/src/main/java/net/citizensnpcs/nms/v1_16_R3/util/NMSImpl.java @@ -1089,6 +1089,11 @@ public class NMSImpl implements NMSBridge { } } + @Override + public void markPoseDirty(org.bukkit.entity.Entity entity) { + getHandle(entity).getDataWatcher().markDirty(DATA_POSE); + } + @Override public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) { if (NMSImpl.getHandle(passenger) == null) @@ -2314,6 +2319,7 @@ public class NMSImpl implements NMSBridge { private static final MethodHandle CRAFT_BOSSBAR_HANDLE_FIELD = NMS.getSetter(CraftBossBar.class, "handle"); private static MethodHandle CRAFTSOUND_GETSOUND = NMS.getMethodHandle(CraftSound.class, "getSound", false, Sound.class); + private static DataWatcherObject DATA_POSE = null; private static final float DEFAULT_SPEED = 1F; private static final MethodHandle ENDERDRAGON_BATTLE_FIELD = NMS.getGetter(EntityEnderDragon.class, "bF"); public static MethodHandle ENDERDRAGON_CHECK_WALLS = NMS.getFirstMethodHandleWithReturnType(EntityEnderDragon.class, @@ -2379,5 +2385,10 @@ public class NMSImpl implements NMSBridge { } catch (IllegalAccessException e) { e.printStackTrace(); } + try { + DATA_POSE = (DataWatcherObject) NMS.getGetter(Entity.class, "T").invoke(); + } catch (Throwable e) { + e.printStackTrace(); + } } } diff --git a/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/NMSImpl.java b/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/NMSImpl.java index 82b07e0d7..52129d588 100644 --- a/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/NMSImpl.java +++ b/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/NMSImpl.java @@ -1097,6 +1097,11 @@ public class NMSImpl implements NMSBridge { } } + @Override + public void markPoseDirty(org.bukkit.entity.Entity entity) { + getHandle(entity).getEntityData().markDirty(DATA_POSE); + } + @Override public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) { if (NMSImpl.getHandle(passenger) == null) @@ -2298,6 +2303,7 @@ public class NMSImpl implements NMSBridge { private static final Map, net.minecraft.world.entity.EntityType> CITIZENS_ENTITY_TYPES = Maps .newHashMap(); private static final MethodHandle CRAFT_BOSSBAR_HANDLE_FIELD = NMS.getSetter(CraftBossBar.class, "handle"); + private static EntityDataAccessor DATA_POSE = null; private static final float DEFAULT_SPEED = 1F; public static MethodHandle ENDERDRAGON_CHECK_WALLS = NMS.getFirstMethodHandleWithReturnType(EnderDragon.class, true, boolean.class, AABB.class); @@ -2359,6 +2365,7 @@ public class NMSImpl implements NMSBridge { try { RABBIT_TYPE_DATAWATCHER = (EntityDataAccessor) NMS .getFirstStaticGetter(Rabbit.class, EntityDataAccessor.class).invoke(); + DATA_POSE = (EntityDataAccessor) NMS.getGetter(Entity.class, "ad").invoke(); } catch (Throwable e) { e.printStackTrace(); } diff --git a/v1_18_R2/src/main/java/net/citizensnpcs/nms/v1_18_R2/util/NMSImpl.java b/v1_18_R2/src/main/java/net/citizensnpcs/nms/v1_18_R2/util/NMSImpl.java index 868181602..aec5c3427 100644 --- a/v1_18_R2/src/main/java/net/citizensnpcs/nms/v1_18_R2/util/NMSImpl.java +++ b/v1_18_R2/src/main/java/net/citizensnpcs/nms/v1_18_R2/util/NMSImpl.java @@ -1106,6 +1106,11 @@ public class NMSImpl implements NMSBridge { } } + @Override + public void markPoseDirty(org.bukkit.entity.Entity entity) { + getHandle(entity).getEntityData().markDirty(DATA_POSE); + } + @Override public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) { if (NMSImpl.getHandle(passenger) == null) @@ -2346,6 +2351,7 @@ public class NMSImpl implements NMSBridge { private static final Map, net.minecraft.world.entity.EntityType> CITIZENS_ENTITY_TYPES = Maps .newHashMap(); private static final MethodHandle CRAFT_BOSSBAR_HANDLE_FIELD = NMS.getSetter(CraftBossBar.class, "handle"); + private static EntityDataAccessor DATA_POSE = null; private static final float DEFAULT_SPEED = 1F; public static MethodHandle ENDERDRAGON_CHECK_WALLS = NMS.getFirstMethodHandleWithReturnType(EnderDragon.class, true, boolean.class, AABB.class); @@ -2414,6 +2420,7 @@ public class NMSImpl implements NMSBridge { try { RABBIT_TYPE_DATAWATCHER = (EntityDataAccessor) NMS .getFirstStaticGetter(Rabbit.class, EntityDataAccessor.class).invoke(); + DATA_POSE = (EntityDataAccessor) NMS.getGetter(Entity.class, "ad").invoke(); } catch (Throwable e) { e.printStackTrace(); } diff --git a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/NMSImpl.java b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/NMSImpl.java index 0c75f6bd2..3080decda 100644 --- a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/NMSImpl.java +++ b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/NMSImpl.java @@ -1170,6 +1170,11 @@ public class NMSImpl implements NMSBridge { } } + @Override + public void markPoseDirty(org.bukkit.entity.Entity entity) { + getHandle(entity).getEntityData().markDirty(DATA_POSE); + } + @Override public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) { if (getHandle(passenger) == null) @@ -2609,7 +2614,6 @@ public class NMSImpl implements NMSBridge { private static final MethodHandle NAVIGATION_PATHFINDER = NMS.getFirstFinalSetter(PathNavigation.class, PathFinder.class); private static final MethodHandle NAVIGATION_WORLD_FIELD = NMS.getFirstSetter(PathNavigation.class, Level.class); - private static final Location PACKET_CACHE_LOCATION = new Location(null, 0, 0, 0); private static final MethodHandle PLAYER_CHUNK_MAP_VIEW_DISTANCE_GETTER = NMS.getFirstGetter(ChunkMap.class, int.class); private static final MethodHandle PLAYER_CHUNK_MAP_VIEW_DISTANCE_SETTER = NMS.getFirstSetter(ChunkMap.class, diff --git a/v1_20_R4/src/main/java/net/citizensnpcs/nms/v1_20_R4/util/NMSImpl.java b/v1_20_R4/src/main/java/net/citizensnpcs/nms/v1_20_R4/util/NMSImpl.java index 1e8eb3084..98d49ae98 100644 --- a/v1_20_R4/src/main/java/net/citizensnpcs/nms/v1_20_R4/util/NMSImpl.java +++ b/v1_20_R4/src/main/java/net/citizensnpcs/nms/v1_20_R4/util/NMSImpl.java @@ -1171,6 +1171,11 @@ public class NMSImpl implements NMSBridge { } } + @Override + public void markPoseDirty(org.bukkit.entity.Entity entity) { + getHandle(entity).getEntityData().markDirty(DATA_POSE); + } + @Override public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) { if (getHandle(passenger) == null) diff --git a/v1_21_R1/src/main/java/net/citizensnpcs/nms/v1_21_R1/util/NMSImpl.java b/v1_21_R1/src/main/java/net/citizensnpcs/nms/v1_21_R1/util/NMSImpl.java index 790703c03..74480a517 100644 --- a/v1_21_R1/src/main/java/net/citizensnpcs/nms/v1_21_R1/util/NMSImpl.java +++ b/v1_21_R1/src/main/java/net/citizensnpcs/nms/v1_21_R1/util/NMSImpl.java @@ -1150,6 +1150,11 @@ public class NMSImpl implements NMSBridge { } } + @Override + public void markPoseDirty(org.bukkit.entity.Entity entity) { + getHandle(entity).getEntityData().markDirty(DATA_POSE); + } + @Override public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) { if (getHandle(passenger) == null)