mirror of
https://github.com/CitizensDev/Citizens2.git
synced 2024-11-25 03:55:30 +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.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import net.citizensnpcs.trait.TrackTargetedByTrait;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@ -12,6 +13,7 @@ import org.bukkit.entity.EntityType;
|
|||||||
import org.bukkit.entity.FishHook;
|
import org.bukkit.entity.FishHook;
|
||||||
import org.bukkit.entity.LivingEntity;
|
import org.bukkit.entity.LivingEntity;
|
||||||
import org.bukkit.entity.Minecart;
|
import org.bukkit.entity.Minecart;
|
||||||
|
import org.bukkit.entity.Mob;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.entity.Snowman;
|
import org.bukkit.entity.Snowman;
|
||||||
import org.bukkit.entity.Vehicle;
|
import org.bukkit.entity.Vehicle;
|
||||||
@ -445,15 +447,37 @@ public class EventListen implements Listener {
|
|||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOWEST)
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
public void onEntityTarget(EntityTargetEvent event) {
|
public void onEntityTarget(EntityTargetEvent event) {
|
||||||
NPC npc = plugin.getNPCRegistry().getNPC(event.getTarget());
|
final Entity targeted = event.getTarget();
|
||||||
if (npc == null)
|
NPC npc = plugin.getNPCRegistry().getNPC(targeted);
|
||||||
return;
|
final Entity cause = event.getEntity();
|
||||||
|
if (npc != null) {
|
||||||
final EntityTargetNPCEvent targetNPCEvent = new EntityTargetNPCEvent(event, npc);
|
final EntityTargetNPCEvent targetNPCEvent = new EntityTargetNPCEvent(event, npc);
|
||||||
targetNPCEvent.setCancelled(!npc.data().get(NPC.Metadata.TARGETABLE, !npc.isProtected()));
|
targetNPCEvent.setCancelled(!npc.data().get(NPC.Metadata.TARGETABLE, !npc.isProtected()));
|
||||||
Bukkit.getPluginManager().callEvent(targetNPCEvent);
|
Bukkit.getPluginManager().callEvent(targetNPCEvent);
|
||||||
if (targetNPCEvent.isCancelled()) {
|
if (targetNPCEvent.isCancelled()) {
|
||||||
event.setCancelled(true);
|
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.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import net.citizensnpcs.trait.TrackTargetedByTrait;
|
||||||
import org.bukkit.Art;
|
import org.bukkit.Art;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
@ -3418,6 +3419,12 @@ public class NPCCommands {
|
|||||||
NMS.addOrRemoveFromPlayerList(npc.getEntity(), false);
|
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());
|
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.ArmorStandTrait;
|
||||||
import net.citizensnpcs.trait.AttributeTrait;
|
import net.citizensnpcs.trait.AttributeTrait;
|
||||||
import net.citizensnpcs.trait.BatTrait;
|
import net.citizensnpcs.trait.BatTrait;
|
||||||
|
import net.citizensnpcs.trait.TrackTargetedByTrait;
|
||||||
import net.citizensnpcs.trait.BoundingBoxTrait;
|
import net.citizensnpcs.trait.BoundingBoxTrait;
|
||||||
import net.citizensnpcs.trait.ClickRedirectTrait;
|
import net.citizensnpcs.trait.ClickRedirectTrait;
|
||||||
import net.citizensnpcs.trait.CommandTrait;
|
import net.citizensnpcs.trait.CommandTrait;
|
||||||
@ -103,6 +104,7 @@ public class CitizensTraitFactory implements TraitFactory {
|
|||||||
registerTrait(TraitInfo.create(ItemFrameTrait.class));
|
registerTrait(TraitInfo.create(ItemFrameTrait.class));
|
||||||
registerTrait(TraitInfo.create(LookClose.class));
|
registerTrait(TraitInfo.create(LookClose.class));
|
||||||
registerTrait(TraitInfo.create(PaintingTrait.class));
|
registerTrait(TraitInfo.create(PaintingTrait.class));
|
||||||
|
registerTrait(TraitInfo.create(TrackTargetedByTrait.class));
|
||||||
registerTrait(TraitInfo.create(MirrorTrait.class).optInToStats());
|
registerTrait(TraitInfo.create(MirrorTrait.class).optInToStats());
|
||||||
registerTrait(TraitInfo.create(MountTrait.class));
|
registerTrait(TraitInfo.create(MountTrait.class));
|
||||||
registerTrait(TraitInfo.create(MobType.class).asDefaultTrait());
|
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