diff --git a/src/main/java/net/citizensnpcs/EventListen.java b/src/main/java/net/citizensnpcs/EventListen.java index 007d090d6..79bdff06f 100644 --- a/src/main/java/net/citizensnpcs/EventListen.java +++ b/src/main/java/net/citizensnpcs/EventListen.java @@ -218,7 +218,8 @@ public class EventListen implements Listener { NPC npc = npcRegistry.getNPC(event.getTarget()); if (npc == null) return; - event.setCancelled(npc.data().get(NPC.DEFAULT_PROTECTED_METADATA, true)); + event.setCancelled(!npc.data().get(NPC.TARGETABLE_METADATA, + !npc.data().get(NPC.DEFAULT_PROTECTED_METADATA, true))); Bukkit.getPluginManager().callEvent(new EntityTargetNPCEvent(event, npc)); } diff --git a/src/main/java/net/citizensnpcs/commands/NPCCommands.java b/src/main/java/net/citizensnpcs/commands/NPCCommands.java index b65e3c119..fd09a7c17 100644 --- a/src/main/java/net/citizensnpcs/commands/NPCCommands.java +++ b/src/main/java/net/citizensnpcs/commands/NPCCommands.java @@ -1134,6 +1134,25 @@ public class NPCCommands { Messaging.sendTr(sender, Messages.SPEED_MODIFIER_SET, newSpeed); } + @Command( + aliases = { "npc" }, + usage = "targetable", + desc = "Toggles an NPC's targetability", + modifiers = { "targetable" }, + min = 1, + max = 1, + permission = "citizens.npc.targetable") + public void targetable(CommandContext args, CommandSender sender, NPC npc) { + boolean targetable = !npc.data().get(NPC.TARGETABLE_METADATA, + npc.data().get(NPC.DEFAULT_PROTECTED_METADATA, true)); + if (args.hasFlag('t')) { + npc.data().set(NPC.TARGETABLE_METADATA, targetable); + } else { + npc.data().setPersistent(NPC.TARGETABLE_METADATA, targetable); + } + Messaging.sendTr(sender, targetable ? Messages.TARGETABLE_SET : Messages.TARGETABLE_UNSET, npc.getName()); + } + @Command( aliases = { "npc" }, usage = "tp", diff --git a/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java b/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java index 3ef779693..a1969541c 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java @@ -30,6 +30,7 @@ import net.minecraft.server.v1_6_R2.MinecraftServer; import net.minecraft.server.v1_6_R2.Navigation; import net.minecraft.server.v1_6_R2.NetworkManager; import net.minecraft.server.v1_6_R2.Packet; +import net.minecraft.server.v1_6_R2.Packet201PlayerInfo; import net.minecraft.server.v1_6_R2.Packet35EntityHeadRotation; import net.minecraft.server.v1_6_R2.Packet5EntityEquipment; import net.minecraft.server.v1_6_R2.PlayerInteractManager; @@ -55,6 +56,7 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder { private final CitizensNPC npc; private final Location packetLocationCache = new Location(null, 0, 0, 0); private int packetUpdateCount; + private int useListName = -1; public EntityHumanNPC(MinecraftServer minecraftServer, World world, String string, PlayerInteractManager playerInteractManager, NPC npc) { @@ -171,7 +173,7 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder { // gravity. also works around an entity.onGround not updating issue // (onGround is normally updated by the client) } - if (!npc.data().get("removefromplayerlist", true)) { + if (!npc.data().get("removefromplayerlist", Setting.REMOVE_PLAYERS_FROM_PLAYER_LIST.asBoolean())) { h(); } if (Math.abs(motX) < EPSILON && Math.abs(motY) < EPSILON && Math.abs(motZ) < EPSILON) @@ -238,18 +240,24 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder { private void updatePackets(boolean navigating) { if (++packetUpdateCount >= 30) { Location current = getBukkitEntity().getLocation(packetLocationCache); - Packet[] packets = new Packet[navigating ? 5 : 6]; + Packet[] packets = new Packet[navigating ? 6 : 7]; if (!navigating) { - packets[5] = new Packet35EntityHeadRotation(id, + packets[6] = new Packet35EntityHeadRotation(id, (byte) MathHelper.d(NMS.getHeadYaw(this) * 256.0F / 360.0F)); } for (int i = 0; i < 5; i++) { packets[i] = new Packet5EntityEquipment(id, i, getEquipment(i)); } - NMS.sendPacketsNearby(current, packets); boolean removeFromPlayerList = Setting.REMOVE_PLAYERS_FROM_PLAYER_LIST.asBoolean(); NMS.addOrRemoveFromPlayerList(getBukkitEntity(), npc.data().get("removefromplayerlist", removeFromPlayerList)); + int useListName = removeFromPlayerList ? 0 : 1; + if (useListName != this.useListName || this.useListName == -1) { + this.useListName = useListName; + packets[5] = new Packet201PlayerInfo(getBukkitEntity().getPlayerListName(), !removeFromPlayerList, + removeFromPlayerList ? 9999 : ping); + } + NMS.sendPacketsNearby(current, packets); packetUpdateCount = 0; } } diff --git a/src/main/java/net/citizensnpcs/util/Messages.java b/src/main/java/net/citizensnpcs/util/Messages.java index 790e8e977..105c0e471 100644 --- a/src/main/java/net/citizensnpcs/util/Messages.java +++ b/src/main/java/net/citizensnpcs/util/Messages.java @@ -174,6 +174,8 @@ public class Messages { public static final String SKIPPING_INVALID_POSE = "citizens.notifications.skipping-invalid-pose"; public static final String SPEED_MODIFIER_ABOVE_LIMIT = "citizens.commands.npc.speed.modifier-above-limit"; public static final String SPEED_MODIFIER_SET = "citizens.commands.npc.speed.set"; + public static final String TARGETABLE_SET = "citizens.commands.npc.targetable.set"; + public static final String TARGETABLE_UNSET = "citizens.commands.npc.targetable.unset"; public static final String TELEPORT_NPC_LOCATION_NOT_FOUND = "citizens.commands.npc.tp.location-not-found"; public static final String TELEPORTED_TO_NPC = "citizens.commands.npc.tp.teleported"; public static final String TEMPLATE_APPLIED = "citizens.commands.template.applied"; diff --git a/src/main/java/net/citizensnpcs/util/NMS.java b/src/main/java/net/citizensnpcs/util/NMS.java index 0754cefa3..faf3f3fa8 100644 --- a/src/main/java/net/citizensnpcs/util/NMS.java +++ b/src/main/java/net/citizensnpcs/util/NMS.java @@ -209,6 +209,8 @@ public class NMS { } public static void sendPacket(Player player, Packet packet) { + if (packet == null) + return; ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); } diff --git a/src/main/resources/messages_en.properties b/src/main/resources/messages_en.properties index 7174bacae..50aefb738 100644 --- a/src/main/resources/messages_en.properties +++ b/src/main/resources/messages_en.properties @@ -91,6 +91,8 @@ citizens.commands.npc.spawn.no-location=No stored location available - command m citizens.commands.npc.spawn.spawned=You spawned [[{0}]]. citizens.commands.npc.speed.modifier-above-limit=Speed is above the limit. citizens.commands.npc.speed.set=NPC speed modifier set to [[{0}]]. +citizens.commands.npc.targetable.set=[[{0}]] can now be targeted by mobs. +citizens.commands.npc.targetable.unset=[[{0}]] can no longer be targeted by mobs. citizens.commands.npc.tp.teleported=You teleported to [[{0}]]. citizens.commands.npc.tp.location-not-found=Couldn't find the target NPC's location. citizens.commands.npc.tpto.success=Teleported successfully.