From deded77f34e1d04efd79bce98aff61a26cb30087 Mon Sep 17 00:00:00 2001 From: fullwall Date: Mon, 29 Jan 2024 22:24:43 +0800 Subject: [PATCH] Add a setNavigationType NMS method --- .../main/java/net/citizensnpcs/util/NMS.java | 17 ++++++--- .../java/net/citizensnpcs/util/NMSBridge.java | 3 ++ .../nms/v1_10_R1/util/NMSImpl.java | 31 ++++++++++++++++ .../nms/v1_11_R1/util/NMSImpl.java | 31 ++++++++++++++++ .../nms/v1_12_R1/util/NMSImpl.java | 31 ++++++++++++++++ .../nms/v1_13_R2/util/NMSImpl.java | 35 +++++++++++++++++-- .../nms/v1_14_R1/util/NMSImpl.java | 31 ++++++++++++++++ .../nms/v1_15_R1/util/NMSImpl.java | 31 ++++++++++++++++ .../nms/v1_16_R3/util/NMSImpl.java | 31 ++++++++++++++++ .../nms/v1_17_R1/util/NMSImpl.java | 31 ++++++++++++++++ .../nms/v1_18_R2/util/NMSImpl.java | 31 ++++++++++++++++ .../nms/v1_19_R3/util/NMSImpl.java | 31 ++++++++++++++++ .../nms/v1_20_R3/util/NMSImpl.java | 31 ++++++++++++++++ .../nms/v1_8_R3/util/NMSImpl.java | 28 +++++++++++++++ 14 files changed, 387 insertions(+), 6 deletions(-) diff --git a/main/src/main/java/net/citizensnpcs/util/NMS.java b/main/src/main/java/net/citizensnpcs/util/NMS.java index 1d48030e0..ab74489d4 100644 --- a/main/src/main/java/net/citizensnpcs/util/NMS.java +++ b/main/src/main/java/net/citizensnpcs/util/NMS.java @@ -70,6 +70,11 @@ public class NMS { // util class } + public enum MinecraftNavigationType { + GROUND, + WALL_CLIMB; + } + public static void activate(Entity entity) { BRIDGE.activate(entity); } @@ -150,15 +155,15 @@ public class NMS { return BRIDGE.createBundlePacket(packets); } + public static EntityPacketTracker createPacketTracker(Entity entity) { + return createPacketTracker(entity, new PacketAggregator()); + } + /* * Yggdrasil's default implementation of this method silently fails instead of throwing * an Exception like it should. */ - public static EntityPacketTracker createPacketTracker(Entity entity) { - return createPacketTracker(entity, new PacketAggregator()); - } - public static EntityPacketTracker createPacketTracker(Entity entity, PacketAggregator agg) { return BRIDGE.createPacketTracker(entity, agg); } @@ -847,6 +852,10 @@ public class NMS { BRIDGE.setNavigationTarget(handle, target, speed); } + public static void setNavigationType(Entity entity, MinecraftNavigationType type) { + BRIDGE.setNavigationType(entity, type); + } + public static void setNoGravity(Entity entity, boolean nogravity) { BRIDGE.setNoGravity(entity, nogravity); } diff --git a/main/src/main/java/net/citizensnpcs/util/NMSBridge.java b/main/src/main/java/net/citizensnpcs/util/NMSBridge.java index 7f39bcde5..9846ac6ca 100644 --- a/main/src/main/java/net/citizensnpcs/util/NMSBridge.java +++ b/main/src/main/java/net/citizensnpcs/util/NMSBridge.java @@ -45,6 +45,7 @@ import net.citizensnpcs.trait.MirrorTrait; import net.citizensnpcs.trait.versioned.CamelTrait.CamelPose; import net.citizensnpcs.trait.versioned.SnifferTrait.SnifferState; import net.citizensnpcs.util.EntityPacketTracker.PacketAggregator; +import net.citizensnpcs.util.NMS.MinecraftNavigationType; public interface NMSBridge { default void activate(Entity entity) { @@ -216,6 +217,8 @@ public interface NMSBridge { public void setNavigationTarget(Entity handle, Entity target, float speed); + public void setNavigationType(Entity entity, MinecraftNavigationType type); + public void setNoGravity(Entity entity, boolean nogravity); public default void setPandaSitting(Entity entity, boolean sitting) { diff --git a/v1_10_R1/src/main/java/net/citizensnpcs/nms/v1_10_R1/util/NMSImpl.java b/v1_10_R1/src/main/java/net/citizensnpcs/nms/v1_10_R1/util/NMSImpl.java index e4a2db980..15fd90c8a 100644 --- a/v1_10_R1/src/main/java/net/citizensnpcs/nms/v1_10_R1/util/NMSImpl.java +++ b/v1_10_R1/src/main/java/net/citizensnpcs/nms/v1_10_R1/util/NMSImpl.java @@ -182,6 +182,7 @@ import net.citizensnpcs.util.EntityPacketTracker; import net.citizensnpcs.util.EntityPacketTracker.PacketAggregator; import net.citizensnpcs.util.Messages; import net.citizensnpcs.util.NMS; +import net.citizensnpcs.util.NMS.MinecraftNavigationType; import net.citizensnpcs.util.NMSBridge; import net.citizensnpcs.util.PlayerAnimation; import net.citizensnpcs.util.Util; @@ -228,7 +229,9 @@ import net.minecraft.server.v1_10_R1.ItemStack; import net.minecraft.server.v1_10_R1.MathHelper; import net.minecraft.server.v1_10_R1.MinecraftKey; import net.minecraft.server.v1_10_R1.MobEffects; +import net.minecraft.server.v1_10_R1.Navigation; import net.minecraft.server.v1_10_R1.NavigationAbstract; +import net.minecraft.server.v1_10_R1.NavigationSpider; import net.minecraft.server.v1_10_R1.NetworkManager; import net.minecraft.server.v1_10_R1.Packet; import net.minecraft.server.v1_10_R1.PacketPlayOutAnimation; @@ -1240,6 +1243,32 @@ public class NMSImpl implements NMSBridge { NMSImpl.getNavigation(handle).a(NMSImpl.getHandle(target), speed); } + @Override + public void setNavigationType(org.bukkit.entity.Entity entity, MinecraftNavigationType type) { + Entity handle = getHandle(entity); + if (!(handle instanceof EntityInsentient)) + return; + EntityInsentient ei = (EntityInsentient) handle; + switch (type) { + case GROUND: + try { + ENTITY_NAVIGATION.invoke(ei, new Navigation(ei, ei.world)); + } catch (Throwable e) { + e.printStackTrace(); + } + break; + case WALL_CLIMB: + try { + ENTITY_NAVIGATION.invoke(ei, new NavigationSpider(ei, ei.world)); + } catch (Throwable e) { + e.printStackTrace(); + } + break; + default: + throw new UnsupportedOperationException(); + } + } + @Override public void setNoGravity(org.bukkit.entity.Entity entity, boolean enabled) { getHandle(entity).setNoGravity(enabled); @@ -1963,11 +1992,13 @@ public class NMSImpl implements NMSBridge { private static final Field ENDERDRAGON_BATTLE_BAR_FIELD = NMS.getField(EnderDragonBattle.class, "c"); private static final Field ENDERDRAGON_BATTLE_FIELD = NMS.getField(EntityEnderDragon.class, "bK"); + public static MethodHandle ENDERDRAGON_CHECK_WALLS = NMS.getFirstMethodHandleWithReturnType(EntityEnderDragon.class, true, boolean.class, AxisAlignedBB.class); private static DataWatcherObject ENDERMAN_ANGRY; private static Map, Integer> ENTITY_CLASS_TO_INT; private static Map, String> ENTITY_CLASS_TO_NAME; + private static MethodHandle ENTITY_NAVIGATION = NMS.getFirstSetter(EntityInsentient.class, Navigation.class); private static final MethodHandle ENTITY_TRACKER_ENTRY_X = NMS.getGetter(EntityTrackerEntry.class, "xLoc"); private static final MethodHandle ENTITY_TRACKER_ENTRY_Y = NMS.getGetter(EntityTrackerEntry.class, "yLoc"); private static final MethodHandle ENTITY_TRACKER_ENTRY_Z = NMS.getGetter(EntityTrackerEntry.class, "zLoc"); diff --git a/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/util/NMSImpl.java b/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/util/NMSImpl.java index d7441200b..09d5f123e 100644 --- a/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/util/NMSImpl.java +++ b/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/util/NMSImpl.java @@ -199,6 +199,7 @@ import net.citizensnpcs.util.EntityPacketTracker; import net.citizensnpcs.util.EntityPacketTracker.PacketAggregator; import net.citizensnpcs.util.Messages; import net.citizensnpcs.util.NMS; +import net.citizensnpcs.util.NMS.MinecraftNavigationType; import net.citizensnpcs.util.NMSBridge; import net.citizensnpcs.util.PlayerAnimation; import net.citizensnpcs.util.Util; @@ -248,7 +249,9 @@ import net.minecraft.server.v1_11_R1.ItemStack; import net.minecraft.server.v1_11_R1.MathHelper; import net.minecraft.server.v1_11_R1.MinecraftKey; import net.minecraft.server.v1_11_R1.MobEffects; +import net.minecraft.server.v1_11_R1.Navigation; import net.minecraft.server.v1_11_R1.NavigationAbstract; +import net.minecraft.server.v1_11_R1.NavigationSpider; import net.minecraft.server.v1_11_R1.NetworkManager; import net.minecraft.server.v1_11_R1.Packet; import net.minecraft.server.v1_11_R1.PacketPlayOutAnimation; @@ -1293,6 +1296,32 @@ public class NMSImpl implements NMSBridge { NMSImpl.getNavigation(handle).a(NMSImpl.getHandle(target), speed); } + @Override + public void setNavigationType(org.bukkit.entity.Entity entity, MinecraftNavigationType type) { + Entity handle = getHandle(entity); + if (!(handle instanceof EntityInsentient)) + return; + EntityInsentient ei = (EntityInsentient) handle; + switch (type) { + case GROUND: + try { + ENTITY_NAVIGATION.invoke(ei, new Navigation(ei, ei.world)); + } catch (Throwable e) { + e.printStackTrace(); + } + break; + case WALL_CLIMB: + try { + ENTITY_NAVIGATION.invoke(ei, new NavigationSpider(ei, ei.world)); + } catch (Throwable e) { + e.printStackTrace(); + } + break; + default: + throw new UnsupportedOperationException(); + } + } + @Override public void setNoGravity(org.bukkit.entity.Entity entity, boolean enabled) { getHandle(entity).setNoGravity(enabled); @@ -2020,10 +2049,12 @@ public class NMSImpl implements NMSBridge { private static final float DEFAULT_SPEED = 1F; private static final Field ENDERDRAGON_BATTLE_BAR_FIELD = NMS.getField(EnderDragonBattle.class, "c"); + private static final Field ENDERDRAGON_BATTLE_FIELD = NMS.getField(EntityEnderDragon.class, "bJ"); public static MethodHandle ENDERDRAGON_CHECK_WALLS = NMS.getFirstMethodHandleWithReturnType(EntityEnderDragon.class, true, boolean.class, AxisAlignedBB.class); private static DataWatcherObject ENDERMAN_ANGRY; + private static MethodHandle ENTITY_NAVIGATION = NMS.getFirstSetter(EntityInsentient.class, Navigation.class); private static CustomEntityRegistry ENTITY_REGISTRY; private static final MethodHandle ENTITY_TRACKER_ENTRY_X = NMS.getGetter(EntityTrackerEntry.class, "xLoc"); private static final MethodHandle ENTITY_TRACKER_ENTRY_Y = NMS.getGetter(EntityTrackerEntry.class, "yLoc"); diff --git a/v1_12_R1/src/main/java/net/citizensnpcs/nms/v1_12_R1/util/NMSImpl.java b/v1_12_R1/src/main/java/net/citizensnpcs/nms/v1_12_R1/util/NMSImpl.java index 28719d4d5..a529b0967 100644 --- a/v1_12_R1/src/main/java/net/citizensnpcs/nms/v1_12_R1/util/NMSImpl.java +++ b/v1_12_R1/src/main/java/net/citizensnpcs/nms/v1_12_R1/util/NMSImpl.java @@ -202,6 +202,7 @@ import net.citizensnpcs.util.EntityPacketTracker; import net.citizensnpcs.util.EntityPacketTracker.PacketAggregator; import net.citizensnpcs.util.Messages; import net.citizensnpcs.util.NMS; +import net.citizensnpcs.util.NMS.MinecraftNavigationType; import net.citizensnpcs.util.NMSBridge; import net.citizensnpcs.util.PlayerAnimation; import net.citizensnpcs.util.Util; @@ -252,7 +253,9 @@ import net.minecraft.server.v1_12_R1.ItemStack; import net.minecraft.server.v1_12_R1.MathHelper; import net.minecraft.server.v1_12_R1.MinecraftKey; import net.minecraft.server.v1_12_R1.MobEffects; +import net.minecraft.server.v1_12_R1.Navigation; import net.minecraft.server.v1_12_R1.NavigationAbstract; +import net.minecraft.server.v1_12_R1.NavigationSpider; import net.minecraft.server.v1_12_R1.NetworkManager; import net.minecraft.server.v1_12_R1.Packet; import net.minecraft.server.v1_12_R1.PacketPlayOutAnimation; @@ -1300,6 +1303,32 @@ public class NMSImpl implements NMSBridge { NMSImpl.getNavigation(handle).a(NMSImpl.getHandle(target), speed); } + @Override + public void setNavigationType(org.bukkit.entity.Entity entity, MinecraftNavigationType type) { + Entity handle = getHandle(entity); + if (!(handle instanceof EntityInsentient)) + return; + EntityInsentient ei = (EntityInsentient) handle; + switch (type) { + case GROUND: + try { + ENTITY_NAVIGATION.invoke(ei, new Navigation(ei, ei.world)); + } catch (Throwable e) { + e.printStackTrace(); + } + break; + case WALL_CLIMB: + try { + ENTITY_NAVIGATION.invoke(ei, new NavigationSpider(ei, ei.world)); + } catch (Throwable e) { + e.printStackTrace(); + } + break; + default: + throw new UnsupportedOperationException(); + } + } + @Override public void setNoGravity(org.bukkit.entity.Entity entity, boolean enabled) { getHandle(entity).setNoGravity(enabled); @@ -2027,10 +2056,12 @@ public class NMSImpl implements NMSBridge { private static final float DEFAULT_SPEED = 1F; private static final Field ENDERDRAGON_BATTLE_BAR_FIELD = NMS.getField(EnderDragonBattle.class, "c"); + private static final Field ENDERDRAGON_BATTLE_FIELD = NMS.getField(EntityEnderDragon.class, "bK"); public static MethodHandle ENDERDRAGON_CHECK_WALLS = NMS.getFirstMethodHandleWithReturnType(EntityEnderDragon.class, true, boolean.class, AxisAlignedBB.class); private static DataWatcherObject ENDERMAN_ANGRY; + private static MethodHandle ENTITY_NAVIGATION = NMS.getFirstSetter(EntityInsentient.class, Navigation.class); private static CustomEntityRegistry ENTITY_REGISTRY; private static final MethodHandle ENTITY_TRACKER_ENTRY_X = NMS.getGetter(EntityTrackerEntry.class, "xLoc"); private static final MethodHandle ENTITY_TRACKER_ENTRY_Y = NMS.getGetter(EntityTrackerEntry.class, "yLoc"); diff --git a/v1_13_R2/src/main/java/net/citizensnpcs/nms/v1_13_R2/util/NMSImpl.java b/v1_13_R2/src/main/java/net/citizensnpcs/nms/v1_13_R2/util/NMSImpl.java index 849a6ae72..eb859b996 100644 --- a/v1_13_R2/src/main/java/net/citizensnpcs/nms/v1_13_R2/util/NMSImpl.java +++ b/v1_13_R2/src/main/java/net/citizensnpcs/nms/v1_13_R2/util/NMSImpl.java @@ -215,6 +215,7 @@ import net.citizensnpcs.util.EntityPacketTracker; import net.citizensnpcs.util.EntityPacketTracker.PacketAggregator; import net.citizensnpcs.util.Messages; import net.citizensnpcs.util.NMS; +import net.citizensnpcs.util.NMS.MinecraftNavigationType; import net.citizensnpcs.util.NMSBridge; import net.citizensnpcs.util.PlayerAnimation; import net.citizensnpcs.util.Util; @@ -270,7 +271,9 @@ import net.minecraft.server.v1_13_R2.ItemStack; import net.minecraft.server.v1_13_R2.MathHelper; import net.minecraft.server.v1_13_R2.MinecraftKey; import net.minecraft.server.v1_13_R2.MobEffects; +import net.minecraft.server.v1_13_R2.Navigation; import net.minecraft.server.v1_13_R2.NavigationAbstract; +import net.minecraft.server.v1_13_R2.NavigationSpider; import net.minecraft.server.v1_13_R2.NetworkManager; import net.minecraft.server.v1_13_R2.Packet; import net.minecraft.server.v1_13_R2.PacketPlayOutAnimation; @@ -1337,6 +1340,32 @@ public class NMSImpl implements NMSBridge { NMSImpl.getNavigation(handle).a(NMSImpl.getHandle(target), speed); } + @Override + public void setNavigationType(org.bukkit.entity.Entity entity, MinecraftNavigationType type) { + Entity handle = getHandle(entity); + if (!(handle instanceof EntityInsentient)) + return; + EntityInsentient ei = (EntityInsentient) handle; + switch (type) { + case GROUND: + try { + ENTITY_NAVIGATION.invoke(ei, new Navigation(ei, ei.world)); + } catch (Throwable e) { + e.printStackTrace(); + } + break; + case WALL_CLIMB: + try { + ENTITY_NAVIGATION.invoke(ei, new NavigationSpider(ei, ei.world)); + } catch (Throwable e) { + e.printStackTrace(); + } + break; + default: + throw new UnsupportedOperationException(); + } + } + @Override public void setNoGravity(org.bukkit.entity.Entity entity, boolean enabled) { getHandle(entity).setNoGravity(enabled); @@ -1442,7 +1471,7 @@ public class NMSImpl implements NMSBridge { return; MethodHandle field = NMS.getFinalSetter(EntityTypes.class, "REGISTRY", false); if (field == null) { - field = NMS.getFinalSetter(IRegistry.class, "ENTITY_TYPE", false); + field = NMS.getFinalSetter(IRegistry.class, "ENTITY_TYPE"); } try { field.invoke(ENTITY_REGISTRY.get()); @@ -2157,6 +2186,7 @@ public class NMSImpl implements NMSBridge { private static final Field CRAFT_BOSSBAR_HANDLE_FIELD = NMS.getField(CraftBossBar.class, "handle"); private static final float DEFAULT_SPEED = 1F; + private static final Field ENDERDRAGON_BATTLE_BAR_FIELD = NMS.getField(EnderDragonBattle.class, "c", false); private static final Field ENDERDRAGON_BATTLE_FIELD = NMS.getField(EntityEnderDragon.class, "bR"); public static MethodHandle ENDERDRAGON_CHECK_WALLS = NMS.getFirstMethodHandleWithReturnType(EntityEnderDragon.class, @@ -2164,6 +2194,7 @@ public class NMSImpl implements NMSBridge { private static DataWatcherObject ENDERMAN_ANGRY; private static Method ENTITY_FISH_METHOD = NMS.getMethod(EntityFish.class, "t", false, boolean.class); private static Field ENTITY_FISH_NUM_IN_SCHOOL; + private static MethodHandle ENTITY_NAVIGATION = NMS.getFirstSetter(EntityInsentient.class, Navigation.class); private static CustomEntityRegistry ENTITY_REGISTRY; private static final MethodHandle ENTITY_TRACKER_ENTRY_X = NMS.getGetter(EntityTrackerEntry.class, "xLoc"); private static final MethodHandle ENTITY_TRACKER_ENTRY_Y = NMS.getGetter(EntityTrackerEntry.class, "yLoc"); @@ -2197,7 +2228,7 @@ public class NMSImpl implements NMSBridge { try { MethodHandle setter = NMS.getFinalSetter(EntityTypes.class, "REGISTRY", false); if (setter == null) { - setter = NMS.getFinalSetter(IRegistry.class, "ENTITY_TYPE", false); + setter = NMS.getFinalSetter(IRegistry.class, "ENTITY_TYPE"); } Field field = NMS.getField(EntityTypes.class, "REGISTRY", false); if (field == null) { 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 2e9eb8e5d..081f413a2 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 @@ -224,6 +224,7 @@ import net.citizensnpcs.util.EntityPacketTracker; import net.citizensnpcs.util.EntityPacketTracker.PacketAggregator; import net.citizensnpcs.util.Messages; import net.citizensnpcs.util.NMS; +import net.citizensnpcs.util.NMS.MinecraftNavigationType; import net.citizensnpcs.util.NMSBridge; import net.citizensnpcs.util.PlayerAnimation; import net.citizensnpcs.util.Util; @@ -286,7 +287,9 @@ import net.minecraft.server.v1_14_R1.ItemStack; import net.minecraft.server.v1_14_R1.MathHelper; import net.minecraft.server.v1_14_R1.MinecraftKey; import net.minecraft.server.v1_14_R1.MobEffects; +import net.minecraft.server.v1_14_R1.Navigation; import net.minecraft.server.v1_14_R1.NavigationAbstract; +import net.minecraft.server.v1_14_R1.NavigationSpider; import net.minecraft.server.v1_14_R1.NetworkManager; import net.minecraft.server.v1_14_R1.Packet; import net.minecraft.server.v1_14_R1.PacketPlayOutEntity.PacketPlayOutEntityLook; @@ -1375,6 +1378,32 @@ public class NMSImpl implements NMSBridge { NMSImpl.getNavigation(handle).a(NMSImpl.getHandle(target), speed); } + @Override + public void setNavigationType(org.bukkit.entity.Entity entity, MinecraftNavigationType type) { + Entity handle = getHandle(entity); + if (!(handle instanceof EntityInsentient)) + return; + EntityInsentient ei = (EntityInsentient) handle; + switch (type) { + case GROUND: + try { + ENTITY_NAVIGATION.invoke(ei, new Navigation(ei, ei.world)); + } catch (Throwable e) { + e.printStackTrace(); + } + break; + case WALL_CLIMB: + try { + ENTITY_NAVIGATION.invoke(ei, new NavigationSpider(ei, ei.world)); + } catch (Throwable e) { + e.printStackTrace(); + } + break; + default: + throw new UnsupportedOperationException(); + } + } + @Override public void setNoGravity(org.bukkit.entity.Entity entity, boolean enabled) { getHandle(entity).setNoGravity(enabled); @@ -2216,6 +2245,7 @@ public class NMSImpl implements NMSBridge { EntityType.SHULKER, EntityType.ENDERMITE, EntityType.ENDER_DRAGON, EntityType.BAT, EntityType.SLIME, EntityType.DOLPHIN, EntityType.MAGMA_CUBE, EntityType.HORSE, EntityType.GHAST, EntityType.SHULKER, EntityType.PHANTOM); + private static final MethodHandle BEHAVIOR_MAP = NMS.getGetter(BehaviorController.class, "c"); private static final MethodHandle BLOCK_POSITION_B_D = NMS.getMethodHandle(BlockPosition.PooledBlockPosition.class, "c", false, double.class, double.class, double.class); @@ -2232,6 +2262,7 @@ public class NMSImpl implements NMSBridge { private static final MethodHandle ENTITY_FISH_NUM_IN_SCHOOL = NMS.getSetter(EntityFishSchool.class, "c", false); private static final MethodHandle ENTITY_GET_SOUND_FALL = NMS.getMethodHandle(EntityLiving.class, "getSoundFall", true, int.class); + private static MethodHandle ENTITY_NAVIGATION = NMS.getFirstSetter(EntityInsentient.class, Navigation.class); private static final MethodHandle ENTITY_R = NMS.getMethodHandle(EntityLiving.class, "r", true, float.class); private static CustomEntityRegistry ENTITY_REGISTRY; private static final MethodHandle ENTITY_SETPOSE = NMS.getMethodHandle(Entity.class, "setPose", false, 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 84c8d78bd..f1acf66e6 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 @@ -226,6 +226,7 @@ import net.citizensnpcs.util.EntityPacketTracker; import net.citizensnpcs.util.EntityPacketTracker.PacketAggregator; import net.citizensnpcs.util.Messages; import net.citizensnpcs.util.NMS; +import net.citizensnpcs.util.NMS.MinecraftNavigationType; import net.citizensnpcs.util.NMSBridge; import net.citizensnpcs.util.PlayerAnimation; import net.citizensnpcs.util.Util; @@ -291,7 +292,9 @@ import net.minecraft.server.v1_15_R1.MathHelper; import net.minecraft.server.v1_15_R1.MinecraftKey; import net.minecraft.server.v1_15_R1.MinecraftServer; import net.minecraft.server.v1_15_R1.MobEffects; +import net.minecraft.server.v1_15_R1.Navigation; import net.minecraft.server.v1_15_R1.NavigationAbstract; +import net.minecraft.server.v1_15_R1.NavigationSpider; import net.minecraft.server.v1_15_R1.NetworkManager; import net.minecraft.server.v1_15_R1.Packet; import net.minecraft.server.v1_15_R1.PacketPlayOutEntity.PacketPlayOutEntityLook; @@ -1392,6 +1395,32 @@ public class NMSImpl implements NMSBridge { NMSImpl.getNavigation(handle).a(NMSImpl.getHandle(target), speed); } + @Override + public void setNavigationType(org.bukkit.entity.Entity entity, MinecraftNavigationType type) { + Entity handle = getHandle(entity); + if (!(handle instanceof EntityInsentient)) + return; + EntityInsentient ei = (EntityInsentient) handle; + switch (type) { + case GROUND: + try { + ENTITY_NAVIGATION.invoke(ei, new Navigation(ei, ei.world)); + } catch (Throwable e) { + e.printStackTrace(); + } + break; + case WALL_CLIMB: + try { + ENTITY_NAVIGATION.invoke(ei, new NavigationSpider(ei, ei.world)); + } catch (Throwable e) { + e.printStackTrace(); + } + break; + default: + throw new UnsupportedOperationException(); + } + } + @Override public void setNoGravity(org.bukkit.entity.Entity entity, boolean enabled) { Entity handle = getHandle(entity); @@ -2301,6 +2330,7 @@ public class NMSImpl implements NMSBridge { EntityType.SILVERFISH, EntityType.SHULKER, EntityType.ENDERMITE, EntityType.ENDER_DRAGON, EntityType.BAT, EntityType.SLIME, EntityType.DOLPHIN, EntityType.MAGMA_CUBE, EntityType.HORSE, EntityType.GHAST, EntityType.SHULKER, EntityType.PHANTOM); + private static final MethodHandle BEHAVIOR_MAP = NMS.getGetter(BehaviorController.class, "c"); private static final MethodHandle BUKKITENTITY_FIELD_SETTER = NMS.getSetter(Entity.class, "bukkitEntity"); private static final MethodHandle CHUNKMAP_UPDATE_PLAYER_STATUS = NMS.getMethodHandle(PlayerChunkMap.class, "a", @@ -2315,6 +2345,7 @@ public class NMSImpl implements NMSBridge { private static final MethodHandle ENTITY_FISH_NUM_IN_SCHOOL = NMS.getSetter(EntityFishSchool.class, "c", false); private static final MethodHandle ENTITY_GET_SOUND_FALL = NMS.getMethodHandle(EntityLiving.class, "getSoundFall", true, int.class); + private static MethodHandle ENTITY_NAVIGATION = NMS.getFirstSetter(EntityInsentient.class, Navigation.class); private static final MethodHandle ENTITY_R = NMS.getMethodHandle(EntityLiving.class, "r", true, float.class); private static CustomEntityRegistry ENTITY_REGISTRY; private static final MethodHandle ENTITY_SETPOSE = NMS.getMethodHandle(Entity.class, "setPose", false, 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 f23d64e79..384c112f8 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 @@ -234,6 +234,7 @@ import net.citizensnpcs.util.EntityPacketTracker; import net.citizensnpcs.util.EntityPacketTracker.PacketAggregator; import net.citizensnpcs.util.Messages; import net.citizensnpcs.util.NMS; +import net.citizensnpcs.util.NMS.MinecraftNavigationType; import net.citizensnpcs.util.NMSBridge; import net.citizensnpcs.util.PlayerAnimation; import net.citizensnpcs.util.Util; @@ -304,7 +305,9 @@ import net.minecraft.server.v1_16_R3.MathHelper; import net.minecraft.server.v1_16_R3.MinecraftKey; import net.minecraft.server.v1_16_R3.MinecraftServer; import net.minecraft.server.v1_16_R3.MobEffects; +import net.minecraft.server.v1_16_R3.Navigation; import net.minecraft.server.v1_16_R3.NavigationAbstract; +import net.minecraft.server.v1_16_R3.NavigationSpider; import net.minecraft.server.v1_16_R3.NetworkManager; import net.minecraft.server.v1_16_R3.Packet; import net.minecraft.server.v1_16_R3.PacketPlayOutEntity.PacketPlayOutEntityLook; @@ -1419,6 +1422,32 @@ public class NMSImpl implements NMSBridge { NMSImpl.getNavigation(handle).a(NMSImpl.getHandle(target), speed); } + @Override + public void setNavigationType(org.bukkit.entity.Entity entity, MinecraftNavigationType type) { + Entity handle = getHandle(entity); + if (!(handle instanceof EntityInsentient)) + return; + EntityInsentient ei = (EntityInsentient) handle; + switch (type) { + case GROUND: + try { + ENTITY_NAVIGATION.invoke(ei, new Navigation(ei, ei.world)); + } catch (Throwable e) { + e.printStackTrace(); + } + break; + case WALL_CLIMB: + try { + ENTITY_NAVIGATION.invoke(ei, new NavigationSpider(ei, ei.world)); + } catch (Throwable e) { + e.printStackTrace(); + } + break; + default: + throw new UnsupportedOperationException(); + } + } + @Override public void setNoGravity(org.bukkit.entity.Entity entity, boolean enabled) { Entity handle = getHandle(entity); @@ -2325,6 +2354,7 @@ public class NMSImpl implements NMSBridge { "advancementDataPlayer"); private static final MethodHandle ATTRIBUTE_MAP = NMS.getGetter(AttributeMapBase.class, "d"); + private static final MethodHandle ATTRIBUTE_PROVIDER_MAP = NMS.getGetter(AttributeProvider.class, "a"); private static final MethodHandle ATTRIBUTE_PROVIDER_MAP_SETTER = NMS.getFinalSetter(AttributeProvider.class, "a"); private static final Set BAD_CONTROLLER_LOOK = EnumSet.of(EntityType.POLAR_BEAR, EntityType.BEE, @@ -2347,6 +2377,7 @@ public class NMSImpl implements NMSBridge { private static final MethodHandle ENTITY_FISH_NUM_IN_SCHOOL = NMS.getSetter(EntityFishSchool.class, "c", false); private static final MethodHandle ENTITY_GET_SOUND_FALL = NMS.getMethodHandle(EntityLiving.class, "getSoundFall", true, int.class); + private static MethodHandle ENTITY_NAVIGATION = NMS.getFirstSetter(EntityInsentient.class, Navigation.class); private static CustomEntityRegistry ENTITY_REGISTRY; private static final MethodHandle ENTITY_SETPOSE_METHOD = NMS.getMethodHandle(Entity.class, "setPose", true, EntityPose.class); 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 c4b9a7b9a..c6a706315 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 @@ -236,6 +236,7 @@ import net.citizensnpcs.util.EntityPacketTracker; import net.citizensnpcs.util.EntityPacketTracker.PacketAggregator; import net.citizensnpcs.util.Messages; import net.citizensnpcs.util.NMS; +import net.citizensnpcs.util.NMS.MinecraftNavigationType; import net.citizensnpcs.util.NMSBridge; import net.citizensnpcs.util.PlayerAnimation; import net.citizensnpcs.util.Util; @@ -288,7 +289,9 @@ import net.minecraft.world.entity.ai.control.FlyingMoveControl; import net.minecraft.world.entity.ai.control.LookControl; import net.minecraft.world.entity.ai.control.MoveControl; import net.minecraft.world.entity.ai.goal.GoalSelector; +import net.minecraft.world.entity.ai.navigation.GroundPathNavigation; import net.minecraft.world.entity.ai.navigation.PathNavigation; +import net.minecraft.world.entity.ai.navigation.WallClimberNavigation; import net.minecraft.world.entity.animal.AbstractFish; import net.minecraft.world.entity.animal.AbstractSchoolingFish; import net.minecraft.world.entity.animal.Cat; @@ -1418,6 +1421,32 @@ public class NMSImpl implements NMSBridge { NMSImpl.getNavigation(handle).moveTo(NMSImpl.getHandle(target), speed); } + @Override + public void setNavigationType(org.bukkit.entity.Entity entity, MinecraftNavigationType type) { + Entity handle = getHandle(entity); + if (!(handle instanceof Mob)) + return; + Mob ei = (Mob) handle; + switch (type) { + case GROUND: + try { + ENTITY_NAVIGATION.invoke(ei, new GroundPathNavigation(ei, ei.level)); + } catch (Throwable e) { + e.printStackTrace(); + } + break; + case WALL_CLIMB: + try { + ENTITY_NAVIGATION.invoke(ei, new WallClimberNavigation(ei, ei.level)); + } catch (Throwable e) { + e.printStackTrace(); + } + break; + default: + throw new UnsupportedOperationException(); + } + } + @Override public void setNoGravity(org.bukkit.entity.Entity entity, boolean enabled) { Entity handle = getHandle(entity); @@ -2305,6 +2334,7 @@ public class NMSImpl implements NMSBridge { private static final MethodHandle ADVANCEMENTS_PLAYER_FIELD = NMS.getFinalSetter(ServerPlayer.class, "cr"); private static final MethodHandle ATTRIBUTE_PROVIDER_MAP = NMS.getFirstGetter(AttributeSupplier.class, Map.class); + private static final MethodHandle ATTRIBUTE_PROVIDER_MAP_SETTER = NMS.getFinalSetter(AttributeSupplier.class, "a"); private static final MethodHandle ATTRIBUTE_SUPPLIER = NMS.getFirstGetter(AttributeMap.class, AttributeSupplier.class); @@ -2326,6 +2356,7 @@ public class NMSImpl implements NMSBridge { private static final MethodHandle ENTITY_FISH_NUM_IN_SCHOOL = NMS.getSetter(AbstractSchoolingFish.class, "c"); private static final MethodHandle ENTITY_GET_SOUND_FALL = NMS.getMethodHandle(LivingEntity.class, "getSoundFall", true, int.class); + private static MethodHandle ENTITY_NAVIGATION = NMS.getFirstSetter(Mob.class, PathNavigation.class); private static CustomEntityRegistry ENTITY_REGISTRY; private static MethodHandle ENTITY_REGISTRY_SETTER; private static final MethodHandle FISHING_HOOK_LIFE = NMS.getSetter(FishingHook.class, "ap"); 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 143620816..737932091 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 @@ -237,6 +237,7 @@ import net.citizensnpcs.util.EntityPacketTracker; import net.citizensnpcs.util.EntityPacketTracker.PacketAggregator; import net.citizensnpcs.util.Messages; import net.citizensnpcs.util.NMS; +import net.citizensnpcs.util.NMS.MinecraftNavigationType; import net.citizensnpcs.util.NMSBridge; import net.citizensnpcs.util.PlayerAnimation; import net.citizensnpcs.util.Util; @@ -289,7 +290,9 @@ import net.minecraft.world.entity.ai.control.FlyingMoveControl; import net.minecraft.world.entity.ai.control.LookControl; import net.minecraft.world.entity.ai.control.MoveControl; import net.minecraft.world.entity.ai.goal.GoalSelector; +import net.minecraft.world.entity.ai.navigation.GroundPathNavigation; import net.minecraft.world.entity.ai.navigation.PathNavigation; +import net.minecraft.world.entity.ai.navigation.WallClimberNavigation; import net.minecraft.world.entity.animal.AbstractFish; import net.minecraft.world.entity.animal.AbstractSchoolingFish; import net.minecraft.world.entity.animal.Cat; @@ -1428,6 +1431,32 @@ public class NMSImpl implements NMSBridge { NMSImpl.getNavigation(handle).moveTo(NMSImpl.getHandle(target), speed); } + @Override + public void setNavigationType(org.bukkit.entity.Entity entity, MinecraftNavigationType type) { + Entity handle = getHandle(entity); + if (!(handle instanceof Mob)) + return; + Mob ei = (Mob) handle; + switch (type) { + case GROUND: + try { + ENTITY_NAVIGATION.invoke(ei, new GroundPathNavigation(ei, ei.level)); + } catch (Throwable e) { + e.printStackTrace(); + } + break; + case WALL_CLIMB: + try { + ENTITY_NAVIGATION.invoke(ei, new WallClimberNavigation(ei, ei.level)); + } catch (Throwable e) { + e.printStackTrace(); + } + break; + default: + throw new UnsupportedOperationException(); + } + } + @Override public void setNoGravity(org.bukkit.entity.Entity entity, boolean nogravity) { Entity handle = getHandle(entity); @@ -2359,6 +2388,7 @@ public class NMSImpl implements NMSBridge { EntityType.SHULKER, EntityType.PHANTOM); private static final MethodHandle BEHAVIOR_TREE_MAP = NMS.getGetter(Brain.class, "f"); + private static final MethodHandle BUKKITENTITY_FIELD_SETTER = NMS.getSetter(Entity.class, "bukkitEntity"); private static final MethodHandle CHUNKMAP_UPDATE_PLAYER_STATUS = NMS.getMethodHandle(ChunkMap.class, "a", true, ServerPlayer.class, boolean.class); @@ -2373,6 +2403,7 @@ public class NMSImpl implements NMSBridge { int.class); private static final MethodHandle ENTITY_GET_SOUND_FALL = NMS.getMethodHandle(LivingEntity.class, "c", true, int.class); + private static MethodHandle ENTITY_NAVIGATION = NMS.getFirstSetter(Mob.class, PathNavigation.class); private static CustomEntityRegistry ENTITY_REGISTRY; private static MethodHandle ENTITY_REGISTRY_SETTER; private static final MethodHandle FALLING_BLOCK_STATE_SETTER = NMS.getFirstSetter(FallingBlockEntity.class, 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 400c65295..7ee300441 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 @@ -261,6 +261,7 @@ import net.citizensnpcs.util.EntityPacketTracker; import net.citizensnpcs.util.EntityPacketTracker.PacketAggregator; import net.citizensnpcs.util.Messages; import net.citizensnpcs.util.NMS; +import net.citizensnpcs.util.NMS.MinecraftNavigationType; import net.citizensnpcs.util.NMSBridge; import net.citizensnpcs.util.PlayerAnimation; import net.citizensnpcs.util.Util; @@ -323,7 +324,9 @@ import net.minecraft.world.entity.ai.control.JumpControl; import net.minecraft.world.entity.ai.control.LookControl; import net.minecraft.world.entity.ai.control.MoveControl; import net.minecraft.world.entity.ai.goal.GoalSelector; +import net.minecraft.world.entity.ai.navigation.GroundPathNavigation; import net.minecraft.world.entity.ai.navigation.PathNavigation; +import net.minecraft.world.entity.ai.navigation.WallClimberNavigation; import net.minecraft.world.entity.animal.AbstractFish; import net.minecraft.world.entity.animal.AbstractSchoolingFish; import net.minecraft.world.entity.animal.Cat; @@ -1577,6 +1580,32 @@ public class NMSImpl implements NMSBridge { getNavigation(handle).moveTo(getHandle(target), speed); } + @Override + public void setNavigationType(org.bukkit.entity.Entity entity, MinecraftNavigationType type) { + Entity handle = getHandle(entity); + if (!(handle instanceof Mob)) + return; + Mob ei = (Mob) handle; + switch (type) { + case GROUND: + try { + ENTITY_NAVIGATION.invoke(ei, new GroundPathNavigation(ei, ei.level)); + } catch (Throwable e) { + e.printStackTrace(); + } + break; + case WALL_CLIMB: + try { + ENTITY_NAVIGATION.invoke(ei, new WallClimberNavigation(ei, ei.level)); + } catch (Throwable e) { + e.printStackTrace(); + } + break; + default: + throw new UnsupportedOperationException(); + } + } + @Override public void setNoGravity(org.bukkit.entity.Entity entity, boolean nogravity) { Entity handle = getHandle(entity); @@ -2573,6 +2602,7 @@ public class NMSImpl implements NMSBridge { private static final MethodHandle ADVANCEMENTS_PLAYER_SETTER = NMS.getFirstFinalSetter(ServerPlayer.class, PlayerAdvancements.class); + private static final MethodHandle ATTRIBUTE_PROVIDER_MAP = NMS.getFirstGetter(AttributeSupplier.class, Map.class); private static final MethodHandle ATTRIBUTE_PROVIDER_MAP_SETTER = NMS.getFirstFinalSetter(AttributeSupplier.class, Map.class); @@ -2598,6 +2628,7 @@ public class NMSImpl implements NMSBridge { private static EntityDataAccessor ENDERMAN_CREEPY = null; private static final MethodHandle ENTITY_FISH_NUM_IN_SCHOOL = NMS.getFirstSetter(AbstractSchoolingFish.class, int.class); + private static MethodHandle ENTITY_NAVIGATION = NMS.getFirstSetter(Mob.class, PathNavigation.class); private static CustomEntityRegistry ENTITY_REGISTRY; private static MethodHandle ENTITY_REGISTRY_SETTER; private static final MethodHandle FALLING_BLOCK_STATE_SETTER = NMS.getFirstSetter(FallingBlockEntity.class, diff --git a/v1_20_R3/src/main/java/net/citizensnpcs/nms/v1_20_R3/util/NMSImpl.java b/v1_20_R3/src/main/java/net/citizensnpcs/nms/v1_20_R3/util/NMSImpl.java index 2a1ad29dc..9a9599003 100644 --- a/v1_20_R3/src/main/java/net/citizensnpcs/nms/v1_20_R3/util/NMSImpl.java +++ b/v1_20_R3/src/main/java/net/citizensnpcs/nms/v1_20_R3/util/NMSImpl.java @@ -252,6 +252,7 @@ import net.citizensnpcs.util.EntityPacketTracker; import net.citizensnpcs.util.EntityPacketTracker.PacketAggregator; import net.citizensnpcs.util.Messages; import net.citizensnpcs.util.NMS; +import net.citizensnpcs.util.NMS.MinecraftNavigationType; import net.citizensnpcs.util.NMSBridge; import net.citizensnpcs.util.PlayerAnimation; import net.citizensnpcs.util.Util; @@ -313,7 +314,9 @@ import net.minecraft.world.entity.ai.control.JumpControl; import net.minecraft.world.entity.ai.control.LookControl; import net.minecraft.world.entity.ai.control.MoveControl; import net.minecraft.world.entity.ai.goal.GoalSelector; +import net.minecraft.world.entity.ai.navigation.GroundPathNavigation; import net.minecraft.world.entity.ai.navigation.PathNavigation; +import net.minecraft.world.entity.ai.navigation.WallClimberNavigation; import net.minecraft.world.entity.animal.AbstractFish; import net.minecraft.world.entity.animal.AbstractSchoolingFish; import net.minecraft.world.entity.animal.Cat; @@ -1540,6 +1543,32 @@ public class NMSImpl implements NMSBridge { getNavigation(handle).moveTo(getHandle(target), speed); } + @Override + public void setNavigationType(org.bukkit.entity.Entity entity, MinecraftNavigationType type) { + Entity handle = getHandle(entity); + if (!(handle instanceof Mob)) + return; + Mob ei = (Mob) handle; + switch (type) { + case GROUND: + try { + ENTITY_NAVIGATION.invoke(ei, new GroundPathNavigation(ei, ei.level())); + } catch (Throwable e) { + e.printStackTrace(); + } + break; + case WALL_CLIMB: + try { + ENTITY_NAVIGATION.invoke(ei, new WallClimberNavigation(ei, ei.level())); + } catch (Throwable e) { + e.printStackTrace(); + } + break; + default: + throw new UnsupportedOperationException(); + } + } + @Override public void setNoGravity(org.bukkit.entity.Entity entity, boolean nogravity) { Entity handle = getHandle(entity); @@ -2534,6 +2563,7 @@ public class NMSImpl implements NMSBridge { private static final MethodHandle ADVANCEMENTS_PLAYER_SETTER = NMS.getFirstFinalSetter(ServerPlayer.class, PlayerAdvancements.class); + private static final MethodHandle ATTRIBUTE_PROVIDER_MAP = NMS.getFirstGetter(AttributeSupplier.class, Map.class); private static final MethodHandle ATTRIBUTE_PROVIDER_MAP_SETTER = NMS.getFirstFinalSetter(AttributeSupplier.class, Map.class); @@ -2564,6 +2594,7 @@ public class NMSImpl implements NMSBridge { private static EntityDataAccessor ENDERMAN_CREEPY = null; private static final MethodHandle ENTITY_FISH_NUM_IN_SCHOOL = NMS.getFirstSetter(AbstractSchoolingFish.class, int.class); + private static MethodHandle ENTITY_NAVIGATION = NMS.getFirstSetter(Mob.class, PathNavigation.class); private static CustomEntityRegistry ENTITY_REGISTRY; private static MethodHandle ENTITY_REGISTRY_SETTER; private static final MethodHandle FALLING_BLOCK_STATE_SETTER = NMS.getFirstSetter(FallingBlockEntity.class, diff --git a/v1_8_R3/src/main/java/net/citizensnpcs/nms/v1_8_R3/util/NMSImpl.java b/v1_8_R3/src/main/java/net/citizensnpcs/nms/v1_8_R3/util/NMSImpl.java index 62f4afc2c..9c3409f75 100644 --- a/v1_8_R3/src/main/java/net/citizensnpcs/nms/v1_8_R3/util/NMSImpl.java +++ b/v1_8_R3/src/main/java/net/citizensnpcs/nms/v1_8_R3/util/NMSImpl.java @@ -166,6 +166,7 @@ import net.citizensnpcs.util.EntityPacketTracker; import net.citizensnpcs.util.EntityPacketTracker.PacketAggregator; import net.citizensnpcs.util.Messages; import net.citizensnpcs.util.NMS; +import net.citizensnpcs.util.NMS.MinecraftNavigationType; import net.citizensnpcs.util.NMSBridge; import net.citizensnpcs.util.PlayerAnimation; import net.citizensnpcs.util.Util; @@ -1158,6 +1159,32 @@ public class NMSImpl implements NMSBridge { NMSImpl.getNavigation(handle).a(NMSImpl.getHandle(target), speed); } + @Override + public void setNavigationType(org.bukkit.entity.Entity entity, MinecraftNavigationType type) { + Entity handle = getHandle(entity); + if (!(handle instanceof EntityInsentient)) + return; + EntityInsentient ei = (EntityInsentient) handle; + switch (type) { + case GROUND: + try { + ENTITY_NAVIGATION.invoke(ei, new Navigation(ei, ei.world)); + } catch (Throwable e) { + e.printStackTrace(); + } + break; + case WALL_CLIMB: + try { + ENTITY_NAVIGATION.invoke(ei, new net.minecraft.server.v1_8_R3.NavigationSpider(ei, ei.world)); + } catch (Throwable e) { + e.printStackTrace(); + } + break; + default: + throw new UnsupportedOperationException(); + } + } + @Override public void setNoGravity(org.bukkit.entity.Entity entity, boolean enabled) { if (!enabled || ((NPCHolder) entity).getNPC().getNavigator().isNavigating()) @@ -1818,6 +1845,7 @@ public class NMSImpl implements NMSBridge { private static Method ENTITY_ATTACK_A = NMS.getMethod(Entity.class, "a", true, EntityLiving.class, Entity.class); private static Map, Integer> ENTITY_CLASS_TO_INT; private static Map, String> ENTITY_CLASS_TO_NAME; + private static MethodHandle ENTITY_NAVIGATION = NMS.getFirstSetter(EntityInsentient.class, Navigation.class); private static final Location FROM_LOCATION = new Location(null, 0, 0, 0); private static Method GET_NMS_BLOCK = NMS.getMethod(CraftBlock.class, "getNMSBlock", false); private static Field GOAL_FIELD = NMS.getField(PathfinderGoalSelector.class, "b");