Mark pose dirty on NPC link to player

This commit is contained in:
fullwall 2024-08-25 23:17:03 +08:00
parent b984fb9312
commit 067badad58
15 changed files with 85 additions and 10 deletions

View File

@ -465,6 +465,7 @@ public class EventListen implements Listener {
@EventHandler(ignoreCancelled = true) @EventHandler(ignoreCancelled = true)
public void onNPCLinkToPlayer(NPCLinkToPlayerEvent event) { public void onNPCLinkToPlayer(NPCLinkToPlayerEvent event) {
NPC npc = event.getNPC(); NPC npc = event.getNPC();
NMS.markPoseDirty(npc.getEntity());
if (npc.getEntity() instanceof SkinnableEntity) { if (npc.getEntity() instanceof SkinnableEntity) {
SkinnableEntity skinnable = (SkinnableEntity) npc.getEntity(); SkinnableEntity skinnable = (SkinnableEntity) npc.getEntity();
if (skinnable.getSkinTracker().getSkin() != null) { if (skinnable.getSkinTracker().getSkin() != null) {

View File

@ -346,8 +346,7 @@ public class CitizensNPC extends AbstractNPC {
} }
} }
NMS.setLocationDirectly(getEntity(), at); NMS.setLocationDirectly(getEntity(), at);
NMS.setHeadYaw(getEntity(), at.getYaw()); NMS.setHeadAndBodyYaw(getEntity(), at.getYaw());
NMS.setBodyYaw(getEntity(), at.getYaw());
// Paper now doesn't actually set entities as valid for a few ticks while adding entities to chunks // 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 // Need to check the entity is really valid for a few ticks before finalising spawning

View File

@ -27,7 +27,6 @@ public class EntityPoseTrait extends Trait {
public void setPose(EntityPose pose) { public void setPose(EntityPose pose) {
this.pose = pose; this.pose = pose;
} }
public enum EntityPose { public enum EntityPose {

View File

@ -24,6 +24,7 @@ public class SleepTrait extends Trait {
@Override @Override
public void onDespawn() { public void onDespawn() {
npc.getOrAddTrait(EntityPoseTrait.class).setPose(null);
sleeping = false; sleeping = false;
} }
@ -38,9 +39,10 @@ public class SleepTrait extends Trait {
} }
return; return;
} }
if (sleeping)
return;
if (npc.getEntity() instanceof Player) { if (npc.getEntity() instanceof Player) {
Player player = (Player) npc.getEntity(); Player player = (Player) npc.getEntity();
npc.getOrAddTrait(EntityPoseTrait.class).setPose(EntityPose.SLEEPING);
if (SUPPORT_BLOCKDATA) { if (SUPPORT_BLOCKDATA) {
try { try {
if (at.getBlock().getBlockData() instanceof Bed || at.getBlock().getState() instanceof Bed) { if (at.getBlock().getBlockData() instanceof Bed || at.getBlock().getState() instanceof Bed) {
@ -55,6 +57,7 @@ public class SleepTrait extends Trait {
} else { } else {
NMS.sleep(player, true); NMS.sleep(player, true);
} }
npc.getOrAddTrait(EntityPoseTrait.class).setPose(EntityPose.SLEEPING);
sleeping = true; sleeping = true;
} else if (npc.getEntity() instanceof Villager) { } else if (npc.getEntity() instanceof Villager) {
sleeping = ((Villager) npc.getEntity()).sleep(at); sleeping = ((Villager) npc.getEntity()).sleep(at);

View File

@ -723,6 +723,10 @@ public class NMS {
BRIDGE.look(bhandle, btarget); 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) { public static void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) {
BRIDGE.mount(entity, passenger); BRIDGE.mount(entity, passenger);
} }

View File

@ -130,7 +130,7 @@ public interface NMSBridge {
public float getVerticalMovement(Entity entity); public float getVerticalMovement(Entity entity);
public default Collection<Player> getViewingPlayers(Entity entity) { public default Collection<Player> getViewingPlayers(Entity entity) {
return ((Player) entity).getTrackedBy(); return entity.getTrackedBy();
} }
public double getWidth(Entity entity); public double getWidth(Entity entity);
@ -150,9 +150,6 @@ public interface NMSBridge {
public boolean isValid(Entity entity); public boolean isValid(Entity entity);
public default void positionInteractionText(Player player, Entity interaction, Entity mount, double height) {
}
public void load(CommandManager commands); public void load(CommandManager commands);
public void look(Entity from, Entity to); 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 void look(Entity entity, Location to, boolean headOnly, boolean immediate);
public default void markPoseDirty(Entity tracker) {
}
public void mount(Entity entity, Entity passenger); public void mount(Entity entity, Entity passenger);
public default void onPlayerInfoAdd(Player player, Object source, Function<UUID, MirrorTrait> mirrorTraits) { public default void onPlayerInfoAdd(Player player, Object source, Function<UUID, MirrorTrait> mirrorTraits) {
@ -174,6 +174,9 @@ public interface NMSBridge {
public Runnable playerTicker(NPC npc, Player entity); 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 registerEntityClass(Class<?> clazz);
public void remove(Entity entity); public void remove(Entity entity);

View File

@ -616,11 +616,15 @@ public class Util {
} }
private static String BEDROCK_NAME_PREFIX = "."; 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 boolean SUPPORTS_BUKKIT_GETENTITY = true;
private static final DecimalFormat TWO_DIGIT_DECIMAL = new DecimalFormat(); private static final DecimalFormat TWO_DIGIT_DECIMAL = new DecimalFormat();
static { static {
try {
DUMMY_SCOREBOARD = Bukkit.getScoreboardManager().getNewScoreboard();
} catch (NullPointerException e) {
}
TWO_DIGIT_DECIMAL.setMaximumFractionDigits(2); TWO_DIGIT_DECIMAL.setMaximumFractionDigits(2);
try { try {
Bukkit.class.getMethod("getEntity", UUID.class); Bukkit.class.getMethod("getEntity", UUID.class);

View File

@ -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 @Override
public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) { public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) {
if (NMSImpl.getHandle(passenger) == null) if (NMSImpl.getHandle(passenger) == null)
@ -2203,6 +2208,7 @@ public class NMSImpl implements NMSBridge {
true, EntityPlayer.class, boolean.class); true, EntityPlayer.class, boolean.class);
private static final Map<Class<?>, EntityTypes<?>> CITIZENS_ENTITY_TYPES = Maps.newHashMap(); private static final Map<Class<?>, EntityTypes<?>> CITIZENS_ENTITY_TYPES = Maps.newHashMap();
private static final MethodHandle CRAFT_BOSSBAR_HANDLE_FIELD = NMS.getSetter(CraftBossBar.class, "handle"); private static final MethodHandle CRAFT_BOSSBAR_HANDLE_FIELD = NMS.getSetter(CraftBossBar.class, "handle");
private static DataWatcherObject<EntityPose> DATA_POSE = null;
private static final float DEFAULT_SPEED = 1F; private static final float DEFAULT_SPEED = 1F;
private static final MethodHandle ENDERDRAGON_BATTLE_FIELD = NMS.getGetter(EntityEnderDragon.class, "bP"); private static final MethodHandle ENDERDRAGON_BATTLE_FIELD = NMS.getGetter(EntityEnderDragon.class, "bP");
public static MethodHandle ENDERDRAGON_CHECK_WALLS = NMS.getFirstMethodHandleWithReturnType(EntityEnderDragon.class, 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 final MethodHandle SIZE_FIELD_SETTER = NMS.getSetter(Entity.class, "size");
private static Field SKULL_PROFILE_FIELD; private static Field SKULL_PROFILE_FIELD;
private static MethodHandle TEAM_FIELD; private static MethodHandle TEAM_FIELD;
static { static {
try { try {
ENTITY_REGISTRY = new CustomEntityRegistry( ENTITY_REGISTRY = new CustomEntityRegistry(
@ -2267,5 +2274,10 @@ public class NMSImpl implements NMSBridge {
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
e.printStackTrace(); e.printStackTrace();
} }
try {
DATA_POSE = (DataWatcherObject<EntityPose>) NMS.getGetter(Entity.class, "X").invoke();
} catch (Throwable e) {
e.printStackTrace();
}
} }
} }

View File

@ -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 @Override
public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) { public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) {
if (NMSImpl.getHandle(passenger) == null) if (NMSImpl.getHandle(passenger) == null)
@ -2285,6 +2290,7 @@ public class NMSImpl implements NMSBridge {
true, EntityPlayer.class, boolean.class); true, EntityPlayer.class, boolean.class);
private static final Map<Class<?>, EntityTypes<?>> CITIZENS_ENTITY_TYPES = Maps.newHashMap(); private static final Map<Class<?>, EntityTypes<?>> CITIZENS_ENTITY_TYPES = Maps.newHashMap();
private static final MethodHandle CRAFT_BOSSBAR_HANDLE_FIELD = NMS.getSetter(CraftBossBar.class, "handle"); private static final MethodHandle CRAFT_BOSSBAR_HANDLE_FIELD = NMS.getSetter(CraftBossBar.class, "handle");
private static DataWatcherObject<EntityPose> DATA_POSE = null;
private static final float DEFAULT_SPEED = 1F; private static final float DEFAULT_SPEED = 1F;
private static final MethodHandle ENDERDRAGON_BATTLE_FIELD = NMS.getGetter(EntityEnderDragon.class, "bN"); private static final MethodHandle ENDERDRAGON_BATTLE_FIELD = NMS.getGetter(EntityEnderDragon.class, "bN");
public static MethodHandle ENDERDRAGON_CHECK_WALLS = NMS.getFirstMethodHandleWithReturnType(EntityEnderDragon.class, public static MethodHandle ENDERDRAGON_CHECK_WALLS = NMS.getFirstMethodHandleWithReturnType(EntityEnderDragon.class,
@ -2353,5 +2359,10 @@ public class NMSImpl implements NMSBridge {
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
e.printStackTrace(); e.printStackTrace();
} }
try {
DATA_POSE = (DataWatcherObject<EntityPose>) NMS.getGetter(Entity.class, "U").invoke();
} catch (Throwable e) {
e.printStackTrace();
}
} }
} }

View File

@ -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 @Override
public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) { public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) {
if (NMSImpl.getHandle(passenger) == null) 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 final MethodHandle CRAFT_BOSSBAR_HANDLE_FIELD = NMS.getSetter(CraftBossBar.class, "handle");
private static MethodHandle CRAFTSOUND_GETSOUND = NMS.getMethodHandle(CraftSound.class, "getSound", false, private static MethodHandle CRAFTSOUND_GETSOUND = NMS.getMethodHandle(CraftSound.class, "getSound", false,
Sound.class); Sound.class);
private static DataWatcherObject<EntityPose> DATA_POSE = null;
private static final float DEFAULT_SPEED = 1F; private static final float DEFAULT_SPEED = 1F;
private static final MethodHandle ENDERDRAGON_BATTLE_FIELD = NMS.getGetter(EntityEnderDragon.class, "bF"); private static final MethodHandle ENDERDRAGON_BATTLE_FIELD = NMS.getGetter(EntityEnderDragon.class, "bF");
public static MethodHandle ENDERDRAGON_CHECK_WALLS = NMS.getFirstMethodHandleWithReturnType(EntityEnderDragon.class, public static MethodHandle ENDERDRAGON_CHECK_WALLS = NMS.getFirstMethodHandleWithReturnType(EntityEnderDragon.class,
@ -2379,5 +2385,10 @@ public class NMSImpl implements NMSBridge {
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
e.printStackTrace(); e.printStackTrace();
} }
try {
DATA_POSE = (DataWatcherObject<EntityPose>) NMS.getGetter(Entity.class, "T").invoke();
} catch (Throwable e) {
e.printStackTrace();
}
} }
} }

View File

@ -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 @Override
public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) { public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) {
if (NMSImpl.getHandle(passenger) == null) if (NMSImpl.getHandle(passenger) == null)
@ -2298,6 +2303,7 @@ public class NMSImpl implements NMSBridge {
private static final Map<Class<?>, net.minecraft.world.entity.EntityType<?>> CITIZENS_ENTITY_TYPES = Maps private static final Map<Class<?>, net.minecraft.world.entity.EntityType<?>> CITIZENS_ENTITY_TYPES = Maps
.newHashMap(); .newHashMap();
private static final MethodHandle CRAFT_BOSSBAR_HANDLE_FIELD = NMS.getSetter(CraftBossBar.class, "handle"); private static final MethodHandle CRAFT_BOSSBAR_HANDLE_FIELD = NMS.getSetter(CraftBossBar.class, "handle");
private static EntityDataAccessor<Pose> DATA_POSE = null;
private static final float DEFAULT_SPEED = 1F; private static final float DEFAULT_SPEED = 1F;
public static MethodHandle ENDERDRAGON_CHECK_WALLS = NMS.getFirstMethodHandleWithReturnType(EnderDragon.class, true, public static MethodHandle ENDERDRAGON_CHECK_WALLS = NMS.getFirstMethodHandleWithReturnType(EnderDragon.class, true,
boolean.class, AABB.class); boolean.class, AABB.class);
@ -2359,6 +2365,7 @@ public class NMSImpl implements NMSBridge {
try { try {
RABBIT_TYPE_DATAWATCHER = (EntityDataAccessor<Integer>) NMS RABBIT_TYPE_DATAWATCHER = (EntityDataAccessor<Integer>) NMS
.getFirstStaticGetter(Rabbit.class, EntityDataAccessor.class).invoke(); .getFirstStaticGetter(Rabbit.class, EntityDataAccessor.class).invoke();
DATA_POSE = (EntityDataAccessor<Pose>) NMS.getGetter(Entity.class, "ad").invoke();
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@ -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 @Override
public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) { public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) {
if (NMSImpl.getHandle(passenger) == null) if (NMSImpl.getHandle(passenger) == null)
@ -2346,6 +2351,7 @@ public class NMSImpl implements NMSBridge {
private static final Map<Class<?>, net.minecraft.world.entity.EntityType<?>> CITIZENS_ENTITY_TYPES = Maps private static final Map<Class<?>, net.minecraft.world.entity.EntityType<?>> CITIZENS_ENTITY_TYPES = Maps
.newHashMap(); .newHashMap();
private static final MethodHandle CRAFT_BOSSBAR_HANDLE_FIELD = NMS.getSetter(CraftBossBar.class, "handle"); private static final MethodHandle CRAFT_BOSSBAR_HANDLE_FIELD = NMS.getSetter(CraftBossBar.class, "handle");
private static EntityDataAccessor<Pose> DATA_POSE = null;
private static final float DEFAULT_SPEED = 1F; private static final float DEFAULT_SPEED = 1F;
public static MethodHandle ENDERDRAGON_CHECK_WALLS = NMS.getFirstMethodHandleWithReturnType(EnderDragon.class, true, public static MethodHandle ENDERDRAGON_CHECK_WALLS = NMS.getFirstMethodHandleWithReturnType(EnderDragon.class, true,
boolean.class, AABB.class); boolean.class, AABB.class);
@ -2414,6 +2420,7 @@ public class NMSImpl implements NMSBridge {
try { try {
RABBIT_TYPE_DATAWATCHER = (EntityDataAccessor<Integer>) NMS RABBIT_TYPE_DATAWATCHER = (EntityDataAccessor<Integer>) NMS
.getFirstStaticGetter(Rabbit.class, EntityDataAccessor.class).invoke(); .getFirstStaticGetter(Rabbit.class, EntityDataAccessor.class).invoke();
DATA_POSE = (EntityDataAccessor<Pose>) NMS.getGetter(Entity.class, "ad").invoke();
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@ -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 @Override
public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) { public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) {
if (getHandle(passenger) == null) if (getHandle(passenger) == null)
@ -2609,7 +2614,6 @@ public class NMSImpl implements NMSBridge {
private static final MethodHandle NAVIGATION_PATHFINDER = NMS.getFirstFinalSetter(PathNavigation.class, private static final MethodHandle NAVIGATION_PATHFINDER = NMS.getFirstFinalSetter(PathNavigation.class,
PathFinder.class); PathFinder.class);
private static final MethodHandle NAVIGATION_WORLD_FIELD = NMS.getFirstSetter(PathNavigation.class, Level.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, private static final MethodHandle PLAYER_CHUNK_MAP_VIEW_DISTANCE_GETTER = NMS.getFirstGetter(ChunkMap.class,
int.class); int.class);
private static final MethodHandle PLAYER_CHUNK_MAP_VIEW_DISTANCE_SETTER = NMS.getFirstSetter(ChunkMap.class, private static final MethodHandle PLAYER_CHUNK_MAP_VIEW_DISTANCE_SETTER = NMS.getFirstSetter(ChunkMap.class,

View File

@ -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 @Override
public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) { public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) {
if (getHandle(passenger) == null) if (getHandle(passenger) == null)

View File

@ -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 @Override
public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) { public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) {
if (getHandle(passenger) == null) if (getHandle(passenger) == null)