Allow /npc select to work with blocks

This commit is contained in:
fullwall 2023-03-14 20:55:33 +08:00
parent 6d03d3ce62
commit 6a19f19aa9
3 changed files with 68 additions and 87 deletions

View File

@ -509,6 +509,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
despawnNPCs(false); despawnNPCs(false);
ProfileFetcher.reset(); ProfileFetcher.reset();
Skin.clearCache(); Skin.clearCache();
getServer().getPluginManager().callEvent(new CitizensPreReloadEvent()); getServer().getPluginManager().callEvent(new CitizensPreReloadEvent());
saves.reloadFromSource(); saves.reloadFromSource();

View File

@ -49,7 +49,7 @@ public class CitizensPlaceholders extends PlaceholderExpansion {
case "citizens_nearest_npc_id": case "citizens_nearest_npc_id":
Location location = player.getPlayer().getLocation(); Location location = player.getPlayer().getLocation();
Optional<NPC> closestNPC = player.getPlayer().getNearbyEntities(12.5, 25, 12.5).stream() Optional<NPC> closestNPC = player.getPlayer().getNearbyEntities(25, 25, 25).stream()
.map(CitizensAPI.getNPCRegistry()::getNPC).filter(e -> e != null && e.getEntity() != player) .map(CitizensAPI.getNPCRegistry()::getNPC).filter(e -> e != null && e.getEntity() != player)
.min((a, b) -> Double.compare(a.getEntity().getLocation().distanceSquared(location), .min((a, b) -> Double.compare(a.getEntity().getLocation().distanceSquared(location),
b.getEntity().getLocation().distanceSquared(location))); b.getEntity().getLocation().distanceSquared(location)));

View File

@ -14,6 +14,7 @@ import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
@ -851,16 +852,13 @@ public class NPCCommands {
permission = "citizens.npc.despawn") permission = "citizens.npc.despawn")
@Requirements @Requirements
public void despawn(final CommandContext args, final CommandSender sender, NPC npc) throws CommandException { public void despawn(final CommandContext args, final CommandSender sender, NPC npc) throws CommandException {
NPCCommandSelector.Callback callback = new NPCCommandSelector.Callback() { NPCCommandSelector.Callback callback = npc1 -> {
@Override if (npc1 == null) {
public void run(NPC npc) throws CommandException { throw new CommandException(Messages.NO_NPC_WITH_ID_FOUND, args.getString(1));
if (npc == null) {
throw new CommandException(Messages.NO_NPC_WITH_ID_FOUND, args.getString(1));
}
npc.getOrAddTrait(Spawned.class).setSpawned(false);
npc.despawn(DespawnReason.REMOVAL);
Messaging.sendTr(sender, Messages.NPC_DESPAWNED, npc.getName());
} }
npc1.getOrAddTrait(Spawned.class).setSpawned(false);
npc1.despawn(DespawnReason.REMOVAL);
Messaging.sendTr(sender, Messages.NPC_DESPAWNED, npc1.getName());
}; };
if (npc == null || args.argsLength() == 2) { if (npc == null || args.argsLength() == 2) {
if (args.argsLength() < 2) { if (args.argsLength() < 2) {
@ -967,22 +965,19 @@ public class NPCCommands {
OfflinePlayer player = Bukkit.getOfflinePlayer(name); OfflinePlayer player = Bukkit.getOfflinePlayer(name);
if (!player.hasPlayedBefore() && !player.isOnline()) { if (!player.hasPlayedBefore() && !player.isOnline()) {
NPCCommandSelector.Callback callback = new NPCCommandSelector.Callback() { NPCCommandSelector.Callback callback = followingNPC -> {
@Override if (followingNPC == null)
public void run(NPC followingNPC) throws CommandException { throw new CommandException(CommandMessages.MUST_HAVE_SELECTED);
if (followingNPC == null) if (!(sender instanceof ConsoleCommandSender)
throw new CommandException(CommandMessages.MUST_HAVE_SELECTED); && !followingNPC.getOrAddTrait(Owner.class).isOwnedBy(sender))
if (!(sender instanceof ConsoleCommandSender) throw new CommandException(CommandMessages.MUST_BE_OWNER);
&& !followingNPC.getOrAddTrait(Owner.class).isOwnedBy(sender)) if (followingNPC.getEntity() instanceof Player) {
throw new CommandException(CommandMessages.MUST_BE_OWNER); boolean following = followingNPC.getOrAddTrait(FollowTrait.class)
if (followingNPC.getEntity() instanceof Player) { .toggle((Player) followingNPC.getEntity(), protect);
boolean following = followingNPC.getOrAddTrait(FollowTrait.class) Messaging.sendTr(sender, following ? Messages.FOLLOW_SET : Messages.FOLLOW_UNSET, npc.getName(),
.toggle((Player) followingNPC.getEntity(), protect); followingNPC.getName());
Messaging.sendTr(sender, following ? Messages.FOLLOW_SET : Messages.FOLLOW_UNSET, npc.getName(), } else {
followingNPC.getName()); throw new CommandException();
} else {
throw new CommandException();
}
} }
}; };
NPCCommandSelector.startWithCallback(callback, CitizensAPI.getNPCRegistry(), sender, args, NPCCommandSelector.startWithCallback(callback, CitizensAPI.getNPCRegistry(), sender, args,
@ -2334,20 +2329,16 @@ public class NPCCommands {
Messaging.sendTr(sender, Messages.REMOVED_ALL_NPCS); Messaging.sendTr(sender, Messages.REMOVED_ALL_NPCS);
return; return;
} else { } else {
NPCCommandSelector.Callback callback = new NPCCommandSelector.Callback() { NPCCommandSelector.Callback callback = npc1 -> {
@Override if (npc1 == null)
public void run(NPC npc) throws CommandException { throw new CommandException(CommandMessages.MUST_HAVE_SELECTED);
if (npc == null) if (!(sender instanceof ConsoleCommandSender) && !npc1.getOrAddTrait(Owner.class).isOwnedBy(sender))
throw new CommandException(CommandMessages.MUST_HAVE_SELECTED); throw new CommandException(CommandMessages.MUST_BE_OWNER);
if (!(sender instanceof ConsoleCommandSender) if (!sender.hasPermission("citizens.npc.remove") && !sender.hasPermission("citizens.admin"))
&& !npc.getOrAddTrait(Owner.class).isOwnedBy(sender)) throw new NoPermissionsException();
throw new CommandException(CommandMessages.MUST_BE_OWNER); history.add(sender, new RemoveNPCHistoryItem(npc1));
if (!sender.hasPermission("citizens.npc.remove") && !sender.hasPermission("citizens.admin")) npc1.destroy(sender);
throw new NoPermissionsException(); Messaging.sendTr(sender, Messages.NPC_REMOVED, npc1.getName(), npc1.getId());
history.add(sender, new RemoveNPCHistoryItem(npc));
npc.destroy(sender);
Messaging.sendTr(sender, Messages.NPC_REMOVED, npc.getName(), npc.getId());
}
}; };
NPCCommandSelector.startWithCallback(callback, CitizensAPI.getNPCRegistry(), sender, args, NPCCommandSelector.startWithCallback(callback, CitizensAPI.getNPCRegistry(), sender, args,
args.getString(1)); args.getString(1));
@ -2511,35 +2502,27 @@ public class NPCCommands {
public void select(CommandContext args, final CommandSender sender, final NPC npc, public void select(CommandContext args, final CommandSender sender, final NPC npc,
@Flag(value = "range", defValue = "10") double range, @Flag("registry") String registryName) @Flag(value = "range", defValue = "10") double range, @Flag("registry") String registryName)
throws CommandException { throws CommandException {
NPCCommandSelector.Callback callback = new NPCCommandSelector.Callback() { NPCCommandSelector.Callback callback = toSelect -> {
@Override if (toSelect == null)
public void run(NPC toSelect) throws CommandException { throw new CommandException(Messages.NPC_NOT_FOUND);
if (toSelect == null) if (npc != null && toSelect.getId() == npc.getId())
throw new CommandException(Messages.NPC_NOT_FOUND); throw new CommandException(Messages.NPC_ALREADY_SELECTED);
if (npc != null && toSelect.getId() == npc.getId()) selector.select(sender, toSelect);
throw new CommandException(Messages.NPC_ALREADY_SELECTED); Messaging.sendWithNPC(sender, Setting.SELECTION_MESSAGE.asString(), toSelect);
selector.select(sender, toSelect);
Messaging.sendWithNPC(sender, Setting.SELECTION_MESSAGE.asString(), toSelect);
}
}; };
NPCRegistry registry = registryName != null ? CitizensAPI.getNamedNPCRegistry(registryName) NPCRegistry registry = registryName != null ? CitizensAPI.getNamedNPCRegistry(registryName)
: CitizensAPI.getNPCRegistry(); : CitizensAPI.getNPCRegistry();
if (registry == null) if (registry == null)
throw new CommandException(Messages.UNKNOWN_NPC_REGISTRY, args.getFlag("registry")); throw new CommandException(Messages.UNKNOWN_NPC_REGISTRY, args.getFlag("registry"));
if (args.argsLength() <= 1) { if (args.argsLength() <= 1) {
if (!(sender instanceof Player)) if (args.getSenderLocation() == null)
throw new ServerCommandException(); throw new ServerCommandException();
Entity player = (Player) sender;
final Location location = args.getSenderLocation(); final Location location = args.getSenderLocation();
List<Entity> search = player.getNearbyEntities(range, range, range); List<NPC> search = location.getWorld().getNearbyEntities(location, range, range, range).stream()
Collections.sort(search, (o1, o2) -> { .map(e -> registry.getNPC(e)).filter(e -> e != null).collect(Collectors.toList());
double d = o1.getLocation().distanceSquared(location) - o2.getLocation().distanceSquared(location); Collections.sort(search, (o1, o2) -> Double.compare(o1.getEntity().getLocation().distanceSquared(location),
return d > 0 ? 1 : d < 0 ? -1 : 0; o2.getEntity().getLocation().distanceSquared(location)));
}); for (NPC test : search) {
for (Entity possibleNPC : search) {
NPC test = registry.getNPC(possibleNPC);
if (test == null)
continue;
if (test.hasTrait(ClickRedirectTrait.class)) { if (test.hasTrait(ClickRedirectTrait.class)) {
test = test.getTraitNullable(ClickRedirectTrait.class).getRedirectNPC(); test = test.getTraitNullable(ClickRedirectTrait.class).getRedirectNPC();
} }
@ -2861,33 +2844,30 @@ public class NPCCommands {
permission = "citizens.npc.spawn") permission = "citizens.npc.spawn")
@Requirements(ownership = true) @Requirements(ownership = true)
public void spawn(final CommandContext args, final CommandSender sender, NPC npc) throws CommandException { public void spawn(final CommandContext args, final CommandSender sender, NPC npc) throws CommandException {
NPCCommandSelector.Callback callback = new NPCCommandSelector.Callback() { NPCCommandSelector.Callback callback = respawn -> {
@Override if (respawn == null) {
public void run(NPC respawn) throws CommandException { if (args.argsLength() > 1) {
if (respawn == null) { throw new CommandException(Messages.NO_NPC_WITH_ID_FOUND, args.getString(1));
if (args.argsLength() > 1) { } else {
throw new CommandException(Messages.NO_NPC_WITH_ID_FOUND, args.getString(1)); throw new CommandException(CommandMessages.MUST_HAVE_SELECTED);
} else {
throw new CommandException(CommandMessages.MUST_HAVE_SELECTED);
}
} }
if (respawn.isSpawned()) { }
throw new CommandException(Messages.NPC_ALREADY_SPAWNED, respawn.getName()); if (respawn.isSpawned()) {
} throw new CommandException(Messages.NPC_ALREADY_SPAWNED, respawn.getName());
Location location = respawn.getOrAddTrait(CurrentLocation.class).getLocation(); }
if (location == null || args.hasValueFlag("location")) { Location location = respawn.getOrAddTrait(CurrentLocation.class).getLocation();
if (args.getSenderLocation() == null) if (location == null || args.hasValueFlag("location")) {
throw new CommandException(Messages.NO_STORED_SPAWN_LOCATION); if (args.getSenderLocation() == null)
throw new CommandException(Messages.NO_STORED_SPAWN_LOCATION);
location = args.getSenderLocation(); location = args.getSenderLocation();
} }
if (args.hasFlag('l') && !Util.isLoaded(location)) { if (args.hasFlag('l') && !Util.isLoaded(location)) {
location.getChunk().load(); location.getChunk().load();
} }
if (respawn.spawn(location, SpawnReason.COMMAND)) { if (respawn.spawn(location, SpawnReason.COMMAND)) {
selector.select(sender, respawn); selector.select(sender, respawn);
Messaging.sendTr(sender, Messages.NPC_SPAWNED, respawn.getName()); Messaging.sendTr(sender, Messages.NPC_SPAWNED, respawn.getName());
}
} }
}; };
if (args.argsLength() > 1) { if (args.argsLength() > 1) {
@ -2931,7 +2911,7 @@ public class NPCCommands {
} }
if (range != null) { if (range != null) {
npc.getEntity().getNearbyEntities(range / 2, range, range / 2).forEach((e) -> { npc.getEntity().getNearbyEntities(range, range, range).forEach(e -> {
if (!CitizensAPI.getNPCRegistry().isNPC(e)) { if (!CitizensAPI.getNPCRegistry().isNPC(e)) {
context.addRecipient(e); context.addRecipient(e);
} }