mirror of
https://github.com/CitizensDev/Citizens2.git
synced 2024-12-22 09:07:56 +01:00
feat: targetable trait (#3173)
This commit is contained in:
parent
69acf89ff9
commit
5c5cf51b3e
@ -4,6 +4,7 @@ import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import net.citizensnpcs.trait.TargetableTrait;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
@ -116,7 +117,6 @@ import net.citizensnpcs.trait.Controllable;
|
||||
import net.citizensnpcs.trait.CurrentLocation;
|
||||
import net.citizensnpcs.trait.HologramTrait.HologramRenderer;
|
||||
import net.citizensnpcs.trait.ShopTrait;
|
||||
import net.citizensnpcs.trait.TrackTargetedByTrait;
|
||||
import net.citizensnpcs.trait.versioned.SnowmanTrait;
|
||||
import net.citizensnpcs.util.ChunkCoord;
|
||||
import net.citizensnpcs.util.Messages;
|
||||
@ -452,7 +452,7 @@ public class EventListen implements Listener {
|
||||
final Entity targeter = event.getEntity();
|
||||
if (npc != null) {
|
||||
final EntityTargetNPCEvent targetNPCEvent = new EntityTargetNPCEvent(event, npc);
|
||||
targetNPCEvent.setCancelled(!npc.data().get(NPC.Metadata.TARGETABLE, !npc.isProtected()));
|
||||
targetNPCEvent.setCancelled(!npc.getOrAddTrait(TargetableTrait.class).isTargetable());
|
||||
Bukkit.getPluginManager().callEvent(targetNPCEvent);
|
||||
if (targetNPCEvent.isCancelled()) {
|
||||
event.setCancelled(true);
|
||||
@ -460,12 +460,12 @@ public class EventListen implements Listener {
|
||||
}
|
||||
if (event.isCancelled() || !(targeter instanceof Mob))
|
||||
return;
|
||||
npc.getOrAddTrait(TrackTargetedByTrait.class).add(targeter.getUniqueId());
|
||||
npc.getOrAddTrait(TargetableTrait.class).addTargeter(targeter.getUniqueId());
|
||||
} else if (targeter instanceof Mob) {
|
||||
final NPC prev = plugin.getNPCRegistry().getNPC(((Mob) targeter).getTarget());
|
||||
if (prev == null)
|
||||
return;
|
||||
prev.getOrAddTrait(TrackTargetedByTrait.class).remove(targeter.getUniqueId());
|
||||
prev.getOrAddTrait(TargetableTrait.class).removeTargeter(targeter.getUniqueId());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,7 +165,7 @@ import net.citizensnpcs.trait.SkinLayers;
|
||||
import net.citizensnpcs.trait.SkinLayers.Layer;
|
||||
import net.citizensnpcs.trait.SkinTrait;
|
||||
import net.citizensnpcs.trait.SlimeSize;
|
||||
import net.citizensnpcs.trait.TrackTargetedByTrait;
|
||||
import net.citizensnpcs.trait.TargetableTrait;
|
||||
import net.citizensnpcs.trait.WitherTrait;
|
||||
import net.citizensnpcs.trait.WolfModifiers;
|
||||
import net.citizensnpcs.trait.shop.StoredShops;
|
||||
@ -3401,12 +3401,9 @@ public class NPCCommands {
|
||||
flags = "t",
|
||||
permission = "citizens.npc.targetable")
|
||||
public void targetable(CommandContext args, CommandSender sender, NPC npc) {
|
||||
boolean targetable = !npc.data().get(NPC.Metadata.TARGETABLE, npc.isProtected());
|
||||
if (args.hasFlag('t')) {
|
||||
npc.data().set(NPC.Metadata.TARGETABLE, targetable);
|
||||
} else {
|
||||
npc.data().setPersistent(NPC.Metadata.TARGETABLE, targetable);
|
||||
}
|
||||
boolean targetable = !npc.getOrAddTrait(TargetableTrait.class).isTargetable();
|
||||
boolean persist = !args.hasFlag('t');
|
||||
npc.getOrAddTrait(TargetableTrait.class).setTargetable(targetable, persist);
|
||||
if (targetable && npc.getOrAddTrait(MobType.class).getType() == EntityType.PLAYER
|
||||
&& npc.shouldRemoveFromPlayerList()) {
|
||||
Messaging.sendTr(sender, Messages.TARGETABLE_PLAYERLIST_WARNING);
|
||||
@ -3419,12 +3416,6 @@ public class NPCCommands {
|
||||
NMS.addOrRemoveFromPlayerList(npc.getEntity(), false);
|
||||
}
|
||||
}
|
||||
if (!targetable) {
|
||||
final TrackTargetedByTrait trait = npc.getTraitNullable(TrackTargetedByTrait.class);
|
||||
if (trait != null) {
|
||||
trait.clearTargets();
|
||||
}
|
||||
}
|
||||
Messaging.sendTr(sender, targetable ? Messages.TARGETABLE_SET : Messages.TARGETABLE_UNSET, npc.getName());
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ import net.citizensnpcs.trait.SkinTrait;
|
||||
import net.citizensnpcs.trait.SleepTrait;
|
||||
import net.citizensnpcs.trait.SlimeSize;
|
||||
import net.citizensnpcs.trait.SneakTrait;
|
||||
import net.citizensnpcs.trait.TrackTargetedByTrait;
|
||||
import net.citizensnpcs.trait.TargetableTrait;
|
||||
import net.citizensnpcs.trait.VillagerProfession;
|
||||
import net.citizensnpcs.trait.WitherTrait;
|
||||
import net.citizensnpcs.trait.WolfModifiers;
|
||||
@ -104,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(TargetableTrait.class));
|
||||
registerTrait(TraitInfo.create(MirrorTrait.class).optInToStats());
|
||||
registerTrait(TraitInfo.create(MountTrait.class));
|
||||
registerTrait(TraitInfo.create(MobType.class).asDefaultTrait());
|
||||
|
111
main/src/main/java/net/citizensnpcs/trait/TargetableTrait.java
Normal file
111
main/src/main/java/net/citizensnpcs/trait/TargetableTrait.java
Normal file
@ -0,0 +1,111 @@
|
||||
package net.citizensnpcs.trait;
|
||||
|
||||
import net.citizensnpcs.api.exception.NPCLoadException;
|
||||
import net.citizensnpcs.api.persistence.Persist;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.trait.TraitName;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
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("targetable")
|
||||
public class TargetableTrait extends Trait {
|
||||
private Set<UUID> targeters;
|
||||
@Persist
|
||||
private Boolean state;
|
||||
private boolean shouldSave;
|
||||
|
||||
public TargetableTrait() {
|
||||
super("targetable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDespawn() {
|
||||
clearTargeters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(DataKey key) throws NPCLoadException {
|
||||
final Object rawState = key.getRaw("state");
|
||||
if (rawState instanceof Boolean) {
|
||||
state = (Boolean) rawState;
|
||||
shouldSave = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(DataKey key) {
|
||||
if (shouldSave) {
|
||||
if (state != null) {
|
||||
key.setBoolean("state", state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isTargetable() {
|
||||
if (state == null) {
|
||||
return !npc.isProtected();
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setTargetable(boolean state, boolean persistent) {
|
||||
if (this.state != state) {
|
||||
this.state = state;
|
||||
this.shouldSave = persistent;
|
||||
if (!state) {
|
||||
clearTargeters();
|
||||
}
|
||||
} else {
|
||||
if (!shouldSave && persistent) {
|
||||
this.shouldSave = true; // user want to persist it so here we go
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only for internal use
|
||||
public void addTargeter(UUID uuid) {
|
||||
if (targeters == null) {
|
||||
targeters = new HashSet<>();
|
||||
}
|
||||
targeters.add(uuid);
|
||||
}
|
||||
|
||||
// Only for internal use
|
||||
public void removeTargeter(UUID uuid) {
|
||||
if (targeters != null) {
|
||||
targeters.remove(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
public void clearTargeters() {
|
||||
if (targeters == null) {
|
||||
return;
|
||||
}
|
||||
if (SUPPORTS_GET_ENTITY) {
|
||||
for (UUID entityUUID : targeters) {
|
||||
final Entity entity = Bukkit.getEntity(entityUUID);
|
||||
if (entity instanceof Mob) {
|
||||
if (entity.isValid()) {
|
||||
((Mob) entity).setTarget(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
targeters = null;
|
||||
}
|
||||
|
||||
private static boolean SUPPORTS_GET_ENTITY = true;
|
||||
static {
|
||||
try {
|
||||
Bukkit.class.getMethod("getEntity", UUID.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
SUPPORTS_GET_ENTITY = false;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
package net.citizensnpcs.trait;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Mob;
|
||||
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.trait.TraitName;
|
||||
|
||||
@TraitName("tracktargetedby")
|
||||
public class TrackTargetedByTrait extends Trait {
|
||||
private Set<UUID> targetedBy;
|
||||
|
||||
public TrackTargetedByTrait() {
|
||||
super("tracktargetedby");
|
||||
}
|
||||
|
||||
public void add(UUID uuid) {
|
||||
if (targetedBy == null) {
|
||||
targetedBy = new HashSet<>();
|
||||
}
|
||||
targetedBy.add(uuid);
|
||||
}
|
||||
|
||||
public void clearTargets() {
|
||||
if (targetedBy == null)
|
||||
return;
|
||||
targetedBy = null;
|
||||
if (!SUPPORTS_GET_ENTITY)
|
||||
return;
|
||||
for (UUID uuid : targetedBy) {
|
||||
final Entity entity = Bukkit.getEntity(uuid);
|
||||
if (entity instanceof Mob) {
|
||||
if (entity.isValid()) {
|
||||
((Mob) entity).setTarget(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDespawn() {
|
||||
clearTargets();
|
||||
}
|
||||
|
||||
public void remove(UUID uuid) {
|
||||
if (targetedBy != null) {
|
||||
targetedBy.remove(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean SUPPORTS_GET_ENTITY = true;
|
||||
static {
|
||||
try {
|
||||
Bukkit.class.getMethod("getEntity", UUID.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
SUPPORTS_GET_ENTITY = false;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user