mirror of
https://github.com/CitizensDev/Citizens2.git
synced 2024-11-22 02:25:57 +01:00
fix: stop mobs from targeting NPCs when they are no longer targetable (#3171)
This commit is contained in:
parent
c1def34749
commit
81d54bba57
@ -4,6 +4,7 @@ import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import net.citizensnpcs.trait.TrackTargetedByTrait;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
@ -12,6 +13,7 @@ import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.FishHook;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Minecart;
|
||||
import org.bukkit.entity.Mob;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Snowman;
|
||||
import org.bukkit.entity.Vehicle;
|
||||
@ -445,15 +447,37 @@ public class EventListen implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onEntityTarget(EntityTargetEvent event) {
|
||||
NPC npc = plugin.getNPCRegistry().getNPC(event.getTarget());
|
||||
if (npc == null)
|
||||
return;
|
||||
|
||||
final Entity targeted = event.getTarget();
|
||||
NPC npc = plugin.getNPCRegistry().getNPC(targeted);
|
||||
final Entity cause = event.getEntity();
|
||||
if (npc != null) {
|
||||
final EntityTargetNPCEvent targetNPCEvent = new EntityTargetNPCEvent(event, npc);
|
||||
targetNPCEvent.setCancelled(!npc.data().get(NPC.Metadata.TARGETABLE, !npc.isProtected()));
|
||||
Bukkit.getPluginManager().callEvent(targetNPCEvent);
|
||||
if (targetNPCEvent.isCancelled()) {
|
||||
event.setCancelled(true);
|
||||
} else {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
if (!(cause instanceof Mob)) {
|
||||
return;
|
||||
}
|
||||
final TrackTargetedByTrait beTargetedBy = npc.getOrAddTrait(TrackTargetedByTrait.class);
|
||||
beTargetedBy.add(cause.getUniqueId());
|
||||
}
|
||||
} else {
|
||||
if (cause instanceof Mob) {
|
||||
final LivingEntity previousTarget = ((Mob) cause).getTarget();
|
||||
if (previousTarget == null) { // normally it is impossible
|
||||
return;
|
||||
}
|
||||
final NPC previousAsNPC = plugin.getNPCRegistry().getNPC(previousTarget);
|
||||
if (previousAsNPC != null) {
|
||||
final TrackTargetedByTrait beTargetedBy = previousAsNPC.getOrAddTrait(TrackTargetedByTrait.class);
|
||||
beTargetedBy.remove(cause.getUniqueId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.citizensnpcs.trait.TrackTargetedByTrait;
|
||||
import org.bukkit.Art;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
@ -3418,6 +3419,12 @@ public class NPCCommands {
|
||||
NMS.addOrRemoveFromPlayerList(npc.getEntity(), false);
|
||||
}
|
||||
}
|
||||
if (!targetable) {
|
||||
final TrackTargetedByTrait trackTargetedByTrait = npc.getTraitNullable(TrackTargetedByTrait.class);
|
||||
if (trackTargetedByTrait != null) { // may not be targeted by anything so prevent possible garbages
|
||||
trackTargetedByTrait.clearTargets();
|
||||
}
|
||||
}
|
||||
Messaging.sendTr(sender, targetable ? Messages.TARGETABLE_SET : Messages.TARGETABLE_UNSET, npc.getName());
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@ import net.citizensnpcs.trait.Anchors;
|
||||
import net.citizensnpcs.trait.ArmorStandTrait;
|
||||
import net.citizensnpcs.trait.AttributeTrait;
|
||||
import net.citizensnpcs.trait.BatTrait;
|
||||
import net.citizensnpcs.trait.TrackTargetedByTrait;
|
||||
import net.citizensnpcs.trait.BoundingBoxTrait;
|
||||
import net.citizensnpcs.trait.ClickRedirectTrait;
|
||||
import net.citizensnpcs.trait.CommandTrait;
|
||||
@ -103,6 +104,7 @@ public class CitizensTraitFactory implements TraitFactory {
|
||||
registerTrait(TraitInfo.create(ItemFrameTrait.class));
|
||||
registerTrait(TraitInfo.create(LookClose.class));
|
||||
registerTrait(TraitInfo.create(PaintingTrait.class));
|
||||
registerTrait(TraitInfo.create(TrackTargetedByTrait.class));
|
||||
registerTrait(TraitInfo.create(MirrorTrait.class).optInToStats());
|
||||
registerTrait(TraitInfo.create(MountTrait.class));
|
||||
registerTrait(TraitInfo.create(MobType.class).asDefaultTrait());
|
||||
|
@ -0,0 +1,54 @@
|
||||
package net.citizensnpcs.trait;
|
||||
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.trait.TraitName;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Mob;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
@TraitName("tracktargetedby")
|
||||
public class TrackTargetedByTrait extends Trait {
|
||||
private Set<UUID> beTargetedBy;
|
||||
|
||||
public TrackTargetedByTrait() {
|
||||
super("tracktargetedby");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDespawn() {
|
||||
clearTargets();
|
||||
}
|
||||
|
||||
// Only for internal use
|
||||
public void add(UUID uuid) {
|
||||
if (beTargetedBy == null) {
|
||||
beTargetedBy = new HashSet<>();
|
||||
}
|
||||
beTargetedBy.add(uuid);
|
||||
}
|
||||
|
||||
// Only for internal use
|
||||
public void remove(UUID uuid) {
|
||||
if (beTargetedBy != null) {
|
||||
beTargetedBy.remove(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
public void clearTargets() {
|
||||
if (beTargetedBy != null) {
|
||||
for (UUID entityUUID : beTargetedBy) {
|
||||
final Entity entity = Bukkit.getEntity(entityUUID);
|
||||
if (entity instanceof Mob) {
|
||||
if (entity.isValid()) {
|
||||
((Mob) entity).setTarget(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
beTargetedBy = null;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user