diff --git a/main/src/main/java/net/citizensnpcs/npc/CitizensNPCRegistry.java b/main/src/main/java/net/citizensnpcs/npc/CitizensNPCRegistry.java index 49cea2d80..4299db601 100644 --- a/main/src/main/java/net/citizensnpcs/npc/CitizensNPCRegistry.java +++ b/main/src/main/java/net/citizensnpcs/npc/CitizensNPCRegistry.java @@ -16,6 +16,7 @@ import com.google.common.base.Preconditions; import com.google.common.collect.Maps; import gnu.trove.map.hash.TIntObjectHashMap; +import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.api.CitizensAPI; import net.citizensnpcs.api.event.DespawnReason; import net.citizensnpcs.api.event.NPCCreateEvent; @@ -25,6 +26,7 @@ import net.citizensnpcs.api.npc.NPCRegistry; import net.citizensnpcs.api.trait.Trait; import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.trait.ArmorStandTrait; +import net.citizensnpcs.trait.LookClose; import net.citizensnpcs.util.NMS; public class CitizensNPCRegistry implements NPCRegistry { @@ -53,6 +55,9 @@ public class CitizensNPCRegistry implements NPCRegistry { if (type == EntityType.ARMOR_STAND && !npc.hasTrait(ArmorStandTrait.class)) { npc.addTrait(ArmorStandTrait.class); } + if (Setting.DEFAULT_LOOK_CLOSE.asBoolean()) { + npc.addTrait(LookClose.class); + } return npc; } diff --git a/main/src/main/java/net/citizensnpcs/util/NMS.java b/main/src/main/java/net/citizensnpcs/util/NMS.java index 1ec8667ac..223d4d9ce 100644 --- a/main/src/main/java/net/citizensnpcs/util/NMS.java +++ b/main/src/main/java/net/citizensnpcs/util/NMS.java @@ -148,10 +148,14 @@ public class NMS { BRIDGE.loadPlugins(); } - public static void look(org.bukkit.entity.Entity entity, float yaw, float pitch) { + public static void look(Entity entity, float yaw, float pitch) { BRIDGE.look(entity, yaw, pitch); } + public static void look(org.bukkit.entity.Entity entity, Location to, boolean headOnly) { + BRIDGE.look(entity, to, headOnly); + } + public static void look(org.bukkit.entity.Entity bhandle, org.bukkit.entity.Entity btarget) { BRIDGE.look(bhandle, btarget); } diff --git a/main/src/main/java/net/citizensnpcs/util/NMSBridge.java b/main/src/main/java/net/citizensnpcs/util/NMSBridge.java index 039719a0c..3f26b1fd2 100644 --- a/main/src/main/java/net/citizensnpcs/util/NMSBridge.java +++ b/main/src/main/java/net/citizensnpcs/util/NMSBridge.java @@ -80,6 +80,8 @@ public interface NMSBridge { public void look(Entity entity, float yaw, float pitch); + public void look(Entity entity, Location to, boolean headOnly); + public void mount(Entity entity, Entity passenger); public void openHorseScreen(Horse horse, Player equipper); diff --git a/main/src/main/java/net/citizensnpcs/util/Util.java b/main/src/main/java/net/citizensnpcs/util/Util.java index babe89314..6465e8197 100644 --- a/main/src/main/java/net/citizensnpcs/util/Util.java +++ b/main/src/main/java/net/citizensnpcs/util/Util.java @@ -64,25 +64,7 @@ public class Util { public static void faceLocation(Entity entity, Location to, boolean headOnly) { if (to == null || entity.getWorld() != to.getWorld()) return; - Location fromLocation = entity.getLocation(FROM_LOCATION); - double xDiff, yDiff, zDiff; - xDiff = to.getX() - fromLocation.getX(); - yDiff = to.getY() - fromLocation.getY(); - zDiff = to.getZ() - fromLocation.getZ(); - - double distanceXZ = Math.sqrt(xDiff * xDiff + zDiff * zDiff); - double distanceY = Math.sqrt(distanceXZ * distanceXZ + yDiff * yDiff); - - double yaw = Math.toDegrees(Math.acos(xDiff / distanceXZ)); - double pitch = Math.toDegrees(Math.acos(yDiff / distanceY)) - 90; - if (zDiff < 0.0) - yaw += Math.abs(180 - yaw) * 2; - - if (headOnly) { - NMS.setHeadYaw(entity, (float) yaw - 90); - } else { - NMS.look(entity, (float) yaw - 90, (float) pitch); - } + NMS.look(entity, to, headOnly); } public static Location getEyeLocation(Entity entity) { @@ -171,5 +153,4 @@ public class Util { } private static final Location AT_LOCATION = new Location(null, 0, 0, 0); - private static final Location FROM_LOCATION = new Location(null, 0, 0, 0); } diff --git a/v1_10_R1/src/main/java/net/citizensnpcs/nms/v1_10_R1/entity/EntityHumanNPC.java b/v1_10_R1/src/main/java/net/citizensnpcs/nms/v1_10_R1/entity/EntityHumanNPC.java index 3444af2e0..a3a8d0e18 100644 --- a/v1_10_R1/src/main/java/net/citizensnpcs/nms/v1_10_R1/entity/EntityHumanNPC.java +++ b/v1_10_R1/src/main/java/net/citizensnpcs/nms/v1_10_R1/entity/EntityHumanNPC.java @@ -369,6 +369,10 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable controllerLook.a(target, yawOffset, renderOffset); } + public void setTargetLook(Location target) { + controllerLook.a(target.getX(), target.getY(), target.getZ(), target.getYaw(), target.getPitch()); + } + public void updateAI() { controllerMove.c(); controllerLook.a(); @@ -469,6 +473,5 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable } private static final float EPSILON = 0.005F; - private static final Location LOADED_LOCATION = new Location(null, 0, 0, 0); } 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 5666b83be..85d4eb497 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 @@ -585,6 +585,38 @@ public class NMSImpl implements NMSBridge { handle.pitch = pitch; } + @Override + public void look(org.bukkit.entity.Entity entity, Location to, boolean headOnly) { + Entity handle = NMSImpl.getHandle(entity); + if (headOnly || (!(handle instanceof EntityInsentient) && !(handle instanceof EntityHumanNPC))) { + Location fromLocation = entity.getLocation(FROM_LOCATION); + double xDiff, yDiff, zDiff; + xDiff = to.getX() - fromLocation.getX(); + yDiff = to.getY() - fromLocation.getY(); + zDiff = to.getZ() - fromLocation.getZ(); + + double distanceXZ = Math.sqrt(xDiff * xDiff + zDiff * zDiff); + double distanceY = Math.sqrt(distanceXZ * distanceXZ + yDiff * yDiff); + + double yaw = Math.toDegrees(Math.acos(xDiff / distanceXZ)); + double pitch = Math.toDegrees(Math.acos(yDiff / distanceY)) - 90; + if (zDiff < 0.0) + yaw += Math.abs(180 - yaw) * 2; + + if (headOnly) { + setHeadYaw(entity, (float) yaw - 90); + } else { + look(entity, (float) yaw - 90, (float) pitch); + } + } + if (handle instanceof EntityInsentient) { + ((EntityInsentient) handle).getControllerLook().a(to.getX(), to.getY(), to.getZ(), to.getYaw(), + to.getPitch()); + } else if (handle instanceof EntityHumanNPC) { + ((EntityHumanNPC) handle).setTargetLook(to); + } + } + @Override public void look(org.bukkit.entity.Entity from, org.bukkit.entity.Entity to) { Entity handle = NMSImpl.getHandle(from), target = NMSImpl.getHandle(to); @@ -1315,11 +1347,13 @@ 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"); private static final Field ENDERDRAGON_BATTLE_FIELD = NMS.getField(EntityEnderDragon.class, "bK"); private static Map, Integer> ENTITY_CLASS_TO_INT; private static Map, String> ENTITY_CLASS_TO_NAME; + private static final Location FROM_LOCATION = new Location(null, 0, 0, 0); public static Field GOAL_FIELD = NMS.getField(PathfinderGoalSelector.class, "b"); private static final Field JUMP_FIELD = NMS.getField(EntityLiving.class, "be"); private static Method MAKE_REQUEST; @@ -1330,11 +1364,8 @@ public class NMSImpl implements NMSBridge { private static final Field RABBIT_FIELD = NMS.getField(EntityRabbit.class, "bx"); private static final Random RANDOM = Util.getFastRandom(); private static Field SKULL_PROFILE_FIELD; - private static Field TRACKED_ENTITY_SET = NMS.getField(EntityTracker.class, "c"); - private static final Field WITHER_BOSS_BAR_FIELD = NMS.getField(EntityWither.class, "bG"); - static { try { Field field = NMS.getField(EntityTypes.class, "f"); diff --git a/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/entity/EntityHumanNPC.java b/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/entity/EntityHumanNPC.java index 2c202b6d1..ba07d12fc 100644 --- a/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/entity/EntityHumanNPC.java +++ b/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/entity/EntityHumanNPC.java @@ -380,6 +380,10 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable controllerLook.a(target, yawOffset, renderOffset); } + public void setTargetLook(Location target) { + controllerLook.a(target.getX(), target.getY(), target.getZ(), target.getYaw(), target.getPitch()); + } + public void updateAI() { controllerMove.c(); controllerLook.a(); 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 36a7f1e37..defddff03 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 @@ -617,6 +617,38 @@ public class NMSImpl implements NMSBridge { handle.pitch = pitch; } + @Override + public void look(org.bukkit.entity.Entity entity, Location to, boolean headOnly) { + Entity handle = NMSImpl.getHandle(entity); + if (headOnly || (!(handle instanceof EntityInsentient) && !(handle instanceof EntityHumanNPC))) { + Location fromLocation = entity.getLocation(FROM_LOCATION); + double xDiff, yDiff, zDiff; + xDiff = to.getX() - fromLocation.getX(); + yDiff = to.getY() - fromLocation.getY(); + zDiff = to.getZ() - fromLocation.getZ(); + + double distanceXZ = Math.sqrt(xDiff * xDiff + zDiff * zDiff); + double distanceY = Math.sqrt(distanceXZ * distanceXZ + yDiff * yDiff); + + double yaw = Math.toDegrees(Math.acos(xDiff / distanceXZ)); + double pitch = Math.toDegrees(Math.acos(yDiff / distanceY)) - 90; + if (zDiff < 0.0) + yaw += Math.abs(180 - yaw) * 2; + + if (headOnly) { + setHeadYaw(entity, (float) yaw - 90); + } else { + look(entity, (float) yaw - 90, (float) pitch); + } + } + if (handle instanceof EntityInsentient) { + ((EntityInsentient) handle).getControllerLook().a(to.getX(), to.getY(), to.getZ(), to.getYaw(), + to.getPitch()); + } else if (handle instanceof EntityHumanNPC) { + ((EntityHumanNPC) handle).setTargetLook(to); + } + } + @Override public void look(org.bukkit.entity.Entity from, org.bukkit.entity.Entity to) { Entity handle = NMSImpl.getHandle(from), target = NMSImpl.getHandle(to); @@ -1357,10 +1389,12 @@ 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"); private static final Field ENDERDRAGON_BATTLE_FIELD = NMS.getField(EntityEnderDragon.class, "bJ"); private static CustomEntityRegistry ENTITY_REGISTRY; + private static final Location FROM_LOCATION = new Location(null, 0, 0, 0); public static Field GOAL_FIELD = NMS.getField(PathfinderGoalSelector.class, "b"); private static final Field JUMP_FIELD = NMS.getField(EntityLiving.class, "bd"); private static Method MAKE_REQUEST; @@ -1372,6 +1406,7 @@ public class NMSImpl implements NMSBridge { private static final Random RANDOM = Util.getFastRandom(); private static Field SKULL_PROFILE_FIELD; private static Field TRACKED_ENTITY_SET = NMS.getField(EntityTracker.class, "c"); + private static final Field WITHER_BOSS_BAR_FIELD = NMS.getField(EntityWither.class, "bF"); static {