Don't cancel NPC - NPC mount events, NMS#mount uses optional boolean flag to force mount. /npc blockbreaker adds to NPC inventory by default

This commit is contained in:
fullwall 2023-11-05 02:03:57 +08:00
parent a42812c4c4
commit 840ab30108
21 changed files with 163 additions and 55 deletions

View File

@ -290,6 +290,7 @@ public class EventListen implements Listener {
}
return;
}
event.setCancelled(npc.isProtected());
if (event instanceof EntityDamageByEntityEvent) {
@ -349,6 +350,7 @@ public class EventListen implements Listener {
NPC npc = CitizensAPI.getNPCRegistry().getNPC(event.getEntity());
if (npc == null || npc.getEntity().getType() != EntityType.PLAYER)
return;
event.setCancelled(true);
npc.despawn(DespawnReason.PENDING_RESPAWN);
event.getTo().getChunk();
@ -442,7 +444,7 @@ public class EventListen implements Listener {
HologramTrait ht = crt.getRedirectNPC().getTraitNullable(HologramTrait.class);
if (ht != null) {
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(),
() -> ht.onHologramSeenByPlayer(npc, event.getPlayer()), 3);
() -> ht.onHologramSeenByPlayer(npc, event.getPlayer()), 2);
}
}
}
@ -741,10 +743,14 @@ public class EventListen implements Listener {
|| event.getVehicle() instanceof Minecart)) {
event.setCancelled(true);
}
return;
}
if (npc.getEntity() instanceof Vehicle
&& (!npc.hasTrait(Controllable.class) || !npc.getTraitNullable(Controllable.class).isEnabled())) {
if (rider != null || !(npc instanceof Vehicle))
return;
if (!npc.hasTrait(Controllable.class) || !npc.getTraitNullable(Controllable.class).isEnabled()) {
event.setCancelled(true);
}
}

View File

@ -41,7 +41,9 @@ import org.bukkit.entity.Rabbit;
import org.bukkit.entity.Villager.Profession;
import org.bukkit.entity.Zombie;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
@ -185,6 +187,7 @@ public class NPCCommands {
} else {
npc.data().setPersistent(NPC.Metadata.ACTIVATION_RANGE, range);
}
Messaging.sendTr(sender, Messages.ACTIVATION_RANGE_SET, range);
}
@ -407,6 +410,18 @@ public class NPCCommands {
cfg.radius(Setting.DEFAULT_BLOCK_BREAKER_RADIUS.asDouble());
}
if (npc.getEntity() instanceof InventoryHolder) {
cfg.blockBreaker((block, itemstack) -> {
org.bukkit.inventory.Inventory inventory = ((InventoryHolder) npc.getEntity()).getInventory();
Location location = npc.getEntity().getLocation();
for (ItemStack drop : block.getDrops(itemstack)) {
for (ItemStack unadded : inventory.addItem(drop).values()) {
location.getWorld().dropItemNaturally(npc.getEntity().getLocation(), unadded);
}
}
});
}
BlockBreaker breaker = npc.getBlockBreaker(args.getSenderTargetBlockLocation().getBlock(), cfg);
npc.getDefaultGoalController().addBehavior(StatusMapper.singleUse(breaker), 1);
}
@ -1755,7 +1770,7 @@ public class NPCCommands {
@Command(
aliases = { "npc" },
usage = "mount (--onnpc <npc id>) (-c (ancel))",
usage = "mount (--onnpc <npc id|uuid>) (-c(ancel))",
desc = "Mounts a controllable NPC",
modifiers = { "mount" },
min = 1,
@ -1772,28 +1787,34 @@ public class NPCCommands {
} catch (IllegalArgumentException ex) {
mount = CitizensAPI.getNPCRegistry().getById(args.getFlagInteger("onnpc"));
}
if (mount == null || !mount.isSpawned()) {
if (mount == null || !mount.isSpawned())
throw new CommandException(Messaging.tr(Messages.MOUNT_NPC_MUST_BE_SPAWNED, onnpc));
}
if (mount.equals(npc)) {
if (mount.equals(npc))
throw new CommandException(Messages.TRIED_TO_MOUNT_NPC_ON_ITSELF);
}
NMS.mount(mount.getEntity(), npc.getEntity());
return;
} else if (args.hasFlag('c')) {
}
if (args.hasFlag('c')) {
npc.getOrAddTrait(MountTrait.class).unmount();
return;
}
boolean enabled = npc.hasTrait(Controllable.class) && npc.getOrAddTrait(Controllable.class).isEnabled();
if (!enabled) {
Messaging.sendTr(sender, Messages.NPC_NOT_CONTROLLABLE, npc.getName());
return;
}
if (!(sender instanceof Player)) {
if (!(sender instanceof Player))
throw new CommandException(CommandMessages.MUST_BE_INGAME);
}
Player player = (Player) sender;
boolean success = npc.getOrAddTrait(Controllable.class).mount(player);
if (!success) {
Messaging.sendTr(player, Messages.FAILED_TO_MOUNT_NPC, npc.getName());
}
@ -1941,6 +1962,7 @@ public class NPCCommands {
Messaging.sendTr(sender, Messages.NPC_OWNER, npc.getName(), ownerTrait.getOwner());
return;
}
OfflinePlayer p;
UUID uuid;
if (args.getString(1).equalsIgnoreCase("SERVER")) {
@ -1950,8 +1972,10 @@ public class NPCCommands {
} else {
uuid = UUID.fromString(args.getString(1));
}
if (ownerTrait.isOwnedBy(uuid))
throw new CommandException(Messages.ALREADY_OWNER, uuid, npc.getName());
ownerTrait.setOwner(uuid);
boolean serverOwner = uuid == null;
Messaging.sendTr(sender, serverOwner ? Messages.OWNER_SET_SERVER : Messages.OWNER_SET, npc.getName(), uuid);
@ -1998,6 +2022,7 @@ public class NPCCommands {
Messaging.sendTr(sender, Messages.PAINTING_ART_SET, npc.getName(), Util.prettyEnum(art));
return;
}
throw new CommandUsageException();
}
@ -2151,7 +2176,7 @@ public class NPCCommands {
if (rightclick != null) {
trait.setRightClick(rightclick);
Messaging.sendTr(sender,
rightclick ? Messages.PAUSEPATHFINDING_RIGHTCLICK_SET : Messages.PAUSEPATHFINDING_RIGHTCLICK_SET,
rightclick ? Messages.PAUSEPATHFINDING_RIGHTCLICK_SET : Messages.PAUSEPATHFINDING_RIGHTCLICK_UNSET,
npc.getName());
}
if (ticks != null) {
@ -2306,6 +2331,7 @@ public class NPCCommands {
if (yaw != null) {
loc.setYaw(yaw);
}
if (pitch != null) {
loc.setPitch(pitch);
}
@ -2506,8 +2532,10 @@ public class NPCCommands {
}
if (npc == null)
throw new CommandException(CommandMessages.MUST_HAVE_SELECTED);
if (!(sender instanceof ConsoleCommandSender) && !npc.getOrAddTrait(Owner.class).isOwnedBy(sender))
throw new CommandException(CommandMessages.MUST_BE_OWNER);
if (!sender.hasPermission("citizens.npc.remove") && !sender.hasPermission("citizens.admin"))
throw new NoPermissionsException();
@ -2578,6 +2606,7 @@ public class NPCCommands {
npc.getOrAddTrait(RotationTrait.class).getPhysicalSession().rotateToHave(yaw, pitch);
return;
}
if (yaw != null) {
NMS.setBodyYaw(npc.getEntity(), yaw);
if (npc.getEntity().getType() == EntityType.PLAYER) {
@ -2585,9 +2614,11 @@ public class NPCCommands {
PlayerAnimation.ARM_SWING.play((Player) npc.getEntity());
}
}
if (pitch != null) {
NMS.setPitch(npc.getEntity(), pitch);
}
if (head != null) {
NMS.setHeadYaw(npc.getEntity(), head);
}
@ -2613,10 +2644,12 @@ public class NPCCommands {
selector.select(sender, toSelect);
Messaging.sendWithNPC(sender, Setting.SELECTION_MESSAGE.asString(), toSelect);
};
NPCRegistry registry = registryName != null ? CitizensAPI.getNamedNPCRegistry(registryName)
: CitizensAPI.getNPCRegistry();
if (registry == null)
throw new CommandException(Messages.UNKNOWN_NPC_REGISTRY, args.getFlag("registry"));
if (args.argsLength() <= 1) {
if (args.getSenderLocation() == null)
throw new ServerCommandException();
@ -2649,6 +2682,7 @@ public class NPCCommands {
@Arg(2) ItemStack item) throws CommandException {
if (slot == null)
throw new CommandUsageException();
if (item == null && args.argsLength() == 3 && args.getString(2).equalsIgnoreCase("hand")) {
if (!(sender instanceof Player))
throw new ServerCommandException();
@ -2757,7 +2791,7 @@ public class NPCCommands {
@Command(
aliases = { "npc" },
usage = "skin (-e(xport) -c(lear) -l(atest)) [name] (or --url [url] --file [file] (-s(lim)) or -t [uuid/name] [data] [signature])",
usage = "skin (-e(xport) -c(lear) -l(atest) -s(kull)) [name] (or --url [url] --file [file] (-s(lim)) or -t [uuid/name] [data] [signature])",
desc = "Sets an NPC's skin name. Use -l to set the skin to always update to the latest",
modifiers = { "skin" },
min = 1,
@ -2776,9 +2810,11 @@ public class NPCCommands {
} else if (args.hasFlag('e')) {
if (trait.getTexture() == null)
throw new CommandException(Messages.SKIN_REQUIRED);
File skinsFolder = new File(CitizensAPI.getDataFolder(), "skins");
File skin = file == null ? new File(skinsFolder, npc.getUniqueId().toString() + ".png")
: new File(skinsFolder, file);
if (!skin.getParentFile().equals(skinsFolder) || !skin.getName().endsWith(".png"))
throw new CommandException(Messages.INVALID_SKIN_FILE, file);
@ -2788,6 +2824,7 @@ public class NPCCommands {
JSONObject textures = (JSONObject) data.get("textures");
JSONObject skinObj = (JSONObject) textures.get("SKIN");
URL textureUrl = new URL(skinObj.get("url").toString().replace("\\", ""));
if (!textureUrl.getHost().equals("textures.minecraft.net"))
throw new CommandException(Messages.ERROR_SETTING_SKIN_URL, "Mojang");
@ -2795,6 +2832,7 @@ public class NPCCommands {
FileOutputStream out = new FileOutputStream(skin)) {
out.getChannel().transferFrom(in, 0, 10000);
}
Messaging.send(sender, Messages.SKIN_EXPORTED, skin.getName());
} catch (Exception e) {
throw new CommandException("Couldn't parse texture: " + e.getMessage());
@ -2815,6 +2853,7 @@ public class NPCCommands {
() -> Messaging.sendErrorTr(sender, Messages.INVALID_SKIN_FILE, file));
return;
}
data = MojangSkinGenerator.generateFromPNG(Files.readAllBytes(skin.toPath()),
args.hasFlag('s'));
} else {
@ -2826,6 +2865,7 @@ public class NPCCommands {
JSONObject texture = (JSONObject) data.get("texture");
String textureEncoded = (String) texture.get("value");
String signature = (String) texture.get("signature");
Bukkit.getScheduler().runTask(CitizensAPI.getPlugin(), () -> {
try {
trait.setSkinPersistent(uuid, signature, textureEncoded);
@ -2846,6 +2886,7 @@ public class NPCCommands {
} else if (args.hasFlag('t')) {
if (args.argsLength() != 4)
throw new CommandException(Messages.SKIN_REQUIRED);
trait.setSkinPersistent(args.getString(1), args.getString(3), args.getString(2));
Messaging.sendTr(sender, Messages.SKIN_SET, npc.getName(), args.getString(1));
return;
@ -2866,6 +2907,7 @@ public class NPCCommands {
if (args.hasFlag('l')) {
trait.setShouldUpdateSkins(true);
}
skinName = args.getString(1);
}
Messaging.sendTr(sender, Messages.SKIN_SET, npc.getName(), skinName);
@ -2888,20 +2930,25 @@ public class NPCCommands {
if (cape != null) {
trait.setVisible(Layer.CAPE, cape);
}
if (hat != null) {
trait.setVisible(Layer.HAT, hat);
}
if (jacket != null) {
trait.setVisible(Layer.JACKET, jacket);
}
if (sleeves != null) {
trait.setVisible(Layer.LEFT_SLEEVE, sleeves);
trait.setVisible(Layer.RIGHT_SLEEVE, sleeves);
}
if (pants != null) {
trait.setVisible(Layer.LEFT_PANTS, pants);
trait.setVisible(Layer.RIGHT_PANTS, pants);
}
Messaging.sendTr(sender, Messages.SKIN_LAYERS_SET, npc.getName(), trait.isVisible(Layer.CAPE),
trait.isVisible(Layer.HAT), trait.isVisible(Layer.JACKET),
trait.isVisible(Layer.LEFT_SLEEVE) || trait.isVisible(Layer.RIGHT_SLEEVE),
@ -2923,6 +2970,7 @@ public class NPCCommands {
trait.describe(sender);
return;
}
int size = Math.max(-2, args.getInteger(1));
trait.setSize(size);
Messaging.sendTr(sender, Messages.SIZE_SET, npc.getName(), size);
@ -2952,9 +3000,11 @@ public class NPCCommands {
ambientSound = deathSound = hurtSound = "";
npc.data().setPersistent(NPC.Metadata.SILENT, true);
}
if (args.hasFlag('s')) {
npc.data().setPersistent(NPC.Metadata.SILENT, !npc.data().get(NPC.Metadata.SILENT, false));
}
if (args.hasFlag('d')) {
ambientSound = deathSound = hurtSound = null;
npc.data().setPersistent(NPC.Metadata.SILENT, false);
@ -2977,16 +3027,19 @@ public class NPCCommands {
hurtSound = args.getFlag("hurt").equals("d") ? null : args.getFlag("hurt");
}
}
if (deathSound == null) {
npc.data().remove(NPC.Metadata.DEATH_SOUND);
} else {
npc.data().setPersistent(NPC.Metadata.DEATH_SOUND, deathSound);
}
if (hurtSound == null) {
npc.data().remove(NPC.Metadata.HURT_SOUND);
} else {
npc.data().setPersistent(NPC.Metadata.HURT_SOUND, hurtSound);
}
if (ambientSound == null) {
npc.data().remove(NPC.Metadata.AMBIENT_SOUND);
} else {
@ -2996,17 +3049,21 @@ public class NPCCommands {
if (ambientSound != null && ambientSound.isEmpty()) {
ambientSound = "none";
}
if (hurtSound != null && hurtSound.isEmpty()) {
hurtSound = "none";
}
if (deathSound != null && deathSound.isEmpty()) {
deathSound = "none";
}
if ((!Strings.isNullOrEmpty(ambientSound) && !ambientSound.equals("none"))
|| (!Strings.isNullOrEmpty(deathSound) && !deathSound.equals("none"))
|| (!Strings.isNullOrEmpty(hurtSound) && !hurtSound.equals("none"))) {
npc.data().setPersistent(NPC.Metadata.SILENT, false);
}
Messaging.sendTr(sender, Messages.SOUND_SET, npc.getName(), ambientSound, hurtSound, deathSound);
}
@ -3047,6 +3104,7 @@ public class NPCCommands {
Messaging.sendTr(sender, Messages.NPC_SPAWNED, respawn.getName());
}
};
if (args.argsLength() > 1) {
NPCCommandSelector.startWithCallback(callback, CitizensAPI.getNPCRegistry(), sender, args,
args.getString(1));
@ -3450,12 +3508,15 @@ public class NPCCommands {
if (args.hasFlag('a')) {
trait.setAngry(!trait.isAngry());
}
if (args.hasFlag('s')) {
trait.setSitting(!trait.isSitting());
}
if (args.hasFlag('t')) {
trait.setTamed(!trait.isTamed());
}
if (collar != null) {
String unparsed = collar;
DyeColor color = null;
@ -3473,6 +3534,7 @@ public class NPCCommands {
throw new CommandException(Messages.COLLAR_COLOUR_NOT_SUPPORTED, unparsed);
trait.setCollarColor(color);
}
Messaging.sendTr(sender, Messages.WOLF_TRAIT_UPDATED, npc.getName(), trait.isAngry(), trait.isSitting(),
trait.isTamed(), trait.getCollarColor().name());
}

View File

@ -52,6 +52,8 @@ public class WaypointCommands {
if (index == null) {
index = waypoints.size();
}
if (index > waypoints.size() || index < 0)
throw new CommandException("Index out of range. Can't be more than " + waypoints.size());
waypoints.add(index, new Waypoint(loc));
Messaging.sendTr(sender, Messages.WAYPOINT_ADDED, Util.prettyPrintLocation(loc), index);
}
@ -65,8 +67,9 @@ public class WaypointCommands {
max = 1,
permission = "citizens.waypoints.disableteleport")
public void disableTeleporting(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
npc.data().setPersistent(NPC.Metadata.DISABLE_DEFAULT_STUCK_ACTION, !npc.data()
.get(NPC.Metadata.DISABLE_DEFAULT_STUCK_ACTION, !Setting.DEFAULT_STUCK_ACTION.asString().contains("teleport")));
npc.data().setPersistent(NPC.Metadata.DISABLE_DEFAULT_STUCK_ACTION,
!npc.data().get(NPC.Metadata.DISABLE_DEFAULT_STUCK_ACTION,
!Setting.DEFAULT_STUCK_ACTION.asString().contains("teleport")));
if (npc.data().get(NPC.Metadata.DISABLE_DEFAULT_STUCK_ACTION,
!Setting.DEFAULT_STUCK_ACTION.asString().contains("teleport"))) {
npc.getNavigator().getDefaultParameters().stuckAction(null);

View File

@ -34,21 +34,24 @@ public class CopierEditor extends Editor {
@EventHandler
public void onBlockClick(PlayerInteractEvent event) {
if (event.getClickedBlock() == null || !event.getPlayer().equals(player)) {
if (event.getClickedBlock() == null || !event.getPlayer().equals(player))
return;
}
NPC copy = npc.clone();
if (!copy.getRawName().equals(name)) {
copy.setName(name);
}
if (copy.isSpawned() && player.isOnline()) {
Location location = player.getLocation();
Location location = event.getClickedBlock().getLocation();
location.setYaw(player.getLocation().getYaw());
location.setPitch(player.getLocation().getPitch());
location.getChunk().load();
copy.teleport(location, TeleportCause.PLUGIN);
copy.getOrAddTrait(CurrentLocation.class).setLocation(location);
}
Messaging.sendTr(player, Messages.NPC_COPIED, npc.getName());
event.setCancelled(true);
}
}

View File

@ -73,6 +73,7 @@ public class CitizensNavigator implements Navigator, Runnable {
!Setting.DEFAULT_STUCK_ACTION.asString().contains("teleport"))) {
defaultParams.stuckAction(null);
}
defaultParams.examiner(new SwimmingExaminer(npc));
}
@ -155,18 +156,23 @@ public class CitizensNavigator implements Navigator, Runnable {
if (root.keyExists("pathfindingrange")) {
defaultParams.range((float) root.getDouble("pathfindingrange"));
}
if (root.keyExists("stationaryticks")) {
defaultParams.stationaryTicks(root.getInt("stationaryticks"));
}
if (root.keyExists("distancemargin")) {
defaultParams.distanceMargin(root.getDouble("distancemargin"));
}
if (root.keyExists("destinationteleportmargin")) {
defaultParams.destinationTeleportMargin(root.getDouble("destinationteleportmargin"));
}
if (root.keyExists("updatepathrate")) {
defaultParams.updatePathRate(root.getInt("updatepathrate"));
}
defaultParams.speedModifier((float) root.getDouble("speedmodifier", 1F));
defaultParams.avoidWater(root.getBoolean("avoidwater"));
if (!root.getBoolean("usedefaultstuckaction") && defaultParams.stuckAction() == TeleportStuckAction.INSTANCE) {
@ -182,6 +188,7 @@ public class CitizensNavigator implements Navigator, Runnable {
if (defaultParams.baseSpeed() == UNINITIALISED_SPEED) {
defaultParams.baseSpeed(NMS.getSpeedFor(npc));
}
updatePathfindingRange();
}
@ -190,14 +197,18 @@ public class CitizensNavigator implements Navigator, Runnable {
updateMountedStatus();
if (!isNavigating() || !npc.isSpawned() || isPaused())
return;
Location npcLoc = npc.getStoredLocation();
Location targetLoc = getTargetAsLocation();
if (!npcLoc.getWorld().equals(targetLoc.getWorld()) || localParams.range() < npcLoc.distance(targetLoc)) {
stopNavigating(CancelReason.STUCK);
return;
}
if (updateStationaryStatus())
return;
updatePathfindingRange();
boolean finished = executing.update();
if (!finished) {
@ -241,31 +252,37 @@ public class CitizensNavigator implements Navigator, Runnable {
} else {
root.removeKey("pathfindingrange");
}
if (defaultParams.stationaryTicks() != Setting.DEFAULT_STATIONARY_DURATION.asTicks()) {
root.setInt("stationaryticks", defaultParams.stationaryTicks());
} else {
root.removeKey("stationaryticks");
}
if (defaultParams.destinationTeleportMargin() != Setting.DEFAULT_DESTINATION_TELEPORT_MARGIN.asDouble()) {
root.setDouble("destinationteleportmargin", defaultParams.destinationTeleportMargin());
} else {
root.removeKey("destinationteleportmargin");
}
if (defaultParams.distanceMargin() != Setting.DEFAULT_DISTANCE_MARGIN.asDouble()) {
root.setDouble("distancemargin", defaultParams.distanceMargin());
} else {
root.removeKey("distancemargin");
}
if (defaultParams.updatePathRate() != Setting.DEFAULT_PATHFINDER_UPDATE_PATH_RATE.asTicks()) {
root.setInt("updatepathrate", defaultParams.updatePathRate());
} else {
root.removeKey("updatepathrate");
}
if (defaultParams.useNewPathfinder() != Setting.USE_NEW_PATHFINDER.asBoolean()) {
root.setBoolean("usenewpathfinder", defaultParams.useNewPathfinder());
} else {
root.removeKey("usenewpathfinder");
}
root.setDouble("speedmodifier", defaultParams.speedModifier());
root.setBoolean("avoidwater", defaultParams.avoidWater());
root.setBoolean("usedefaultstuckaction", defaultParams.stuckAction() == TeleportStuckAction.INSTANCE);
@ -283,10 +300,12 @@ public class CitizensNavigator implements Navigator, Runnable {
public void setStraightLineTarget(Entity target, boolean aggressive) {
if (!npc.isSpawned())
throw new IllegalStateException("npc is not spawned");
if (target == null) {
cancelNavigation();
return;
}
setTarget(params -> {
params.straightLineTargetingDistance(100000);
return new MCTargetStrategy(npc, target, aggressive, params);
@ -297,10 +316,12 @@ public class CitizensNavigator implements Navigator, Runnable {
public void setStraightLineTarget(Location target) {
if (!npc.isSpawned())
throw new IllegalStateException("npc is not spawned");
if (target == null) {
cancelNavigation();
return;
}
setTarget(params -> new StraightLineNavigationStrategy(npc, target.clone(), params));
}
@ -308,10 +329,12 @@ public class CitizensNavigator implements Navigator, Runnable {
public void setTarget(Entity target, boolean aggressive) {
if (!npc.isSpawned())
throw new IllegalStateException("npc is not spawned");
if (target == null) {
cancelNavigation();
return;
}
setTarget(params -> new MCTargetStrategy(npc, target, aggressive, params));
}
@ -331,6 +354,7 @@ public class CitizensNavigator implements Navigator, Runnable {
cancelNavigation();
return;
}
setTarget(params -> {
if (npc.isFlyable()) {
return new FlyingAStarNavigationStrategy(npc, path, params);
@ -350,6 +374,7 @@ public class CitizensNavigator implements Navigator, Runnable {
cancelNavigation();
return;
}
final Location target = targetIn.clone();
setTarget(params -> {
if (npc.isFlyable()) {
@ -366,6 +391,7 @@ public class CitizensNavigator implements Navigator, Runnable {
if (executing != null) {
executing.stop();
}
executing = null;
localParams = defaultParams;
@ -376,14 +402,17 @@ public class CitizensNavigator implements Navigator, Runnable {
npc.getEntity().setVelocity(velocity);
NMS.cancelMoveDestination(npc.getEntity());
}
if (!SUPPORT_CHUNK_TICKETS || !CitizensAPI.hasImplementation() || !CitizensAPI.getPlugin().isEnabled())
return;
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() {
@Override
public void run() {
updateTicket(isNavigating() ? executing.getTargetAsLocation() : null);
}
}, 10);
// Location loc = npc.getEntity().getLocation(STATIONARY_LOCATION);
// NMS.look(npc.getEntity(), loc.getYaw(), 0);
}
@ -391,26 +420,32 @@ public class CitizensNavigator implements Navigator, Runnable {
private void stopNavigating(CancelReason reason) {
if (!isNavigating())
return;
if (reason == CancelReason.STUCK && Messaging.isDebugging()) {
Messaging.debug(npc, "navigation ended, stuck", executing);
}
if (session != null) {
session.end();
session = null;
}
Iterator<NavigatorCallback> itr = localParams.callbacks().iterator();
List<NavigatorCallback> callbacks = new ArrayList<NavigatorCallback>();
while (itr.hasNext()) {
callbacks.add(itr.next());
itr.remove();
}
for (NavigatorCallback callback : callbacks) {
callback.onCompletion(reason);
}
if (reason == null) {
stopNavigating();
return;
}
if (reason == CancelReason.STUCK) {
StuckAction action = localParams.stuckAction();
NavigationStuckEvent event = new NavigationStuckEvent(this, action);
@ -423,6 +458,7 @@ public class CitizensNavigator implements Navigator, Runnable {
return;
}
}
NavigationCancelEvent event = new NavigationCancelEvent(this, reason);
PathStrategy old = executing;
Bukkit.getPluginManager().callEvent(event);
@ -466,9 +502,9 @@ public class CitizensNavigator implements Navigator, Runnable {
if (!isNavigating() || true)
return;
Entity vehicle = NMS.getVehicle(npc.getEntity());
if (!(vehicle instanceof NPCHolder)) {
if (!(vehicle instanceof NPCHolder))
return;
}
NPC mount = ((NPCHolder) vehicle).getNPC();
if (mount.getNavigator().isNavigating())
return;
@ -492,11 +528,13 @@ public class CitizensNavigator implements Navigator, Runnable {
private boolean updateStationaryStatus() {
if (localParams.stationaryTicks() < 0)
return false;
Location current = npc.getEntity().getLocation();
if (!SpigotUtil.checkYSafe(current.getY(), current.getWorld())) {
stopNavigating(CancelReason.STUCK);
return true;
}
if (lastX == current.getBlockX() && lastY == current.getBlockY() && lastZ == current.getBlockZ()) {
if (++stationaryTicks >= localParams.stationaryTicks()) {
stopNavigating(CancelReason.STUCK);
@ -505,6 +543,7 @@ public class CitizensNavigator implements Navigator, Runnable {
} else {
stationaryTicks = 0;
}
lastX = current.getBlockX();
lastY = current.getBlockY();
lastZ = current.getBlockZ();
@ -514,11 +553,13 @@ public class CitizensNavigator implements Navigator, Runnable {
private void updateTicket(Location target) {
if (!SUPPORT_CHUNK_TICKETS || !CitizensAPI.hasImplementation() || !CitizensAPI.getPlugin().isEnabled())
return;
if (target != null && this.activeTicket != null
&& new ChunkCoord(target.getChunk()).equals(new ChunkCoord(this.activeTicket.getChunk()))) {
this.activeTicket = target.clone();
return;
}
if (this.activeTicket != null) {
try {
this.activeTicket.getChunk().removePluginChunkTicket(CitizensAPI.getPlugin());
@ -527,10 +568,12 @@ public class CitizensNavigator implements Navigator, Runnable {
this.activeTicket = null;
}
}
if (target == null) {
this.activeTicket = null;
return;
}
this.activeTicket = target.clone();
try {
this.activeTicket.getChunk().addPluginChunkTicket(CitizensAPI.getPlugin());

View File

@ -105,7 +105,6 @@ public class HologramTrait extends Trait {
if (useDisplayEntities) {
hologramNPC = registry.createNPC(EntityType.INTERACTION, line);
hologramNPC.addTrait(new ClickRedirectTrait(npc));
hologramNPC.data().set(NPC.Metadata.NAMEPLATE_VISIBLE, true);
} else {
hologramNPC = registry.createNPC(EntityType.ARMOR_STAND, line);
hologramNPC.getOrAddTrait(ArmorStandTrait.class).setAsHelperEntityWithName(npc);

View File

@ -75,12 +75,12 @@ public abstract class AbstractBlockBreaker extends BlockBreaker {
@Override
public BehaviorStatus run() {
if (!entity.isValid()) {
if (!entity.isValid())
return BehaviorStatus.FAILURE;
}
if (!isDigging) {
if (!isDigging)
return BehaviorStatus.SUCCESS;
}
currentTick = (int) (System.currentTimeMillis() / 50);
if (configuration.radius() > 0) {
if (!inRange()) {
@ -104,10 +104,12 @@ public abstract class AbstractBlockBreaker extends BlockBreaker {
cancelNavigation();
}
}
Util.faceLocation(entity, location);
if (entity instanceof Player && currentTick % 5 == 0) {
PlayerAnimation.ARM_SWING.play((Player) entity);
}
if (entity.getWorld().getBlockAt(x, y, z).isEmpty()) {
return BehaviorStatus.SUCCESS;
} else {
@ -123,6 +125,7 @@ public abstract class AbstractBlockBreaker extends BlockBreaker {
currentDamage = modifiedDamage;
}
}
return BehaviorStatus.RUNNING;
}

View File

@ -28,9 +28,6 @@ public class Messages {
public static final String BEE_NO_NECTAR = "citizens.commands.npc.bee.no-nectar";
public static final String BEE_NOT_STUNG = "citizens.commands.npc.bee.not-stung";
public static final String BEE_STUNG = "citizens.commands.npc.bee.bee-stung";
public static final String BEHAVIOUR_HELP = "citizens.commands.npc.behaviour.help";
public static final String BEHAVIOURS_ADDED = "citizens.commands.npc.behaviour.added";
public static final String BEHAVIOURS_REMOVED = "citizens.commands.npc.behaviour.removed";
public static final String BOUNDING_BOX_SET = "citizens.commands.npc.hitbox.set";
public static final String CAMEL_POSE_SET = "citizens.commands.npc.camel.pose-set";
public static final String CANNOT_TELEPORT_ACROSS_WORLDS = "citizens.commands.npc.tphere.multiworld-not-allowed";
@ -91,9 +88,7 @@ public class Messages {
public static final String CONTROLLABLE_SET = "citizens.commands.npc.controllable.set";
public static final String COPIER_EDITOR_BEGIN = "citizens.editors.copier.begin";
public static final String COPIER_EDITOR_END = "citizens.editors.copier.end";
public static final String CURRENT_SCRIPTS = "citizens.commands.npc.script.current-scripts";
public static final String CURRENT_WAYPOINT_PROVIDER = "citizens.waypoints.current-provider";
public static final String DATABASE_CONNECTION_FAILED = "citizens.notifications.database-connection-failed";
public static final String DEFAULT_POSE_SET = "citizens.commands.npc.pose.default-pose-set";
public static final String DELAY_TRIGGER_PROMPT = "citizens.editors.waypoints.triggers.delay.prompt";
public static final String DESELECTED_NPC = "citizens.commands.npc.deselect";
@ -229,7 +224,6 @@ public class Messages {
public static final String LLAMA_STRENGTH_SET = "citizens.commands.npc.llama.strength-set";
public static final String LOAD_NAME_NOT_FOUND = "citizens.notifications.npc-name-not-found";
public static final String LOAD_TASK_NOT_SCHEDULED = "citizens.load-task-error";
public static final String LOAD_UNKNOWN_NPC_TYPE = "citizens.notifications.unknown-npc-type";
public static final String LOADED_ECONOMY = "citizens.economy.loaded";
public static final String LOCALE_NOTIFICATION = "citizens.notifications.locale";
public static final String LOOKCLOSE_DISABLE_WHEN_NAVIGATING = "citizens.commands.npc.lookclose.disable-when-navigating";
@ -260,7 +254,6 @@ public class Messages {
public static final String MIRROR_SET = "citizens.commands.npc.mirror.set";
public static final String MIRROR_UNSET = "citizens.commands.npc.mirror.unset";
public static final String MISSING_TP_CURSOR_BLOCK = "citizens.commands.npc.tphere.missing-cursor-block";
public static final String MISSING_TRANSLATIONS = "citizens.notifications.missing-translations";
public static final String MOBTYPE_CANNOT_BE_AGED = "citizens.commands.npc.age.cannot-be-aged";
public static final String MONEY_WITHDRAWN = "citizens.economy.money-withdrawn";
public static final String MOUNT_NPC_MUST_BE_SPAWNED = "citizens.commands.npc.mount.must-be-spawned";
@ -271,7 +264,6 @@ public class Messages {
public static final String NO_HORSE_MODIFIERS_GIVEN = "citizens.commands.npc.horse.no-modifiers";
public static final String NO_NPC_WITH_ID_FOUND = "citizens.commands.npc.spawn.missing-npc-id";
public static final String NO_STORED_SPAWN_LOCATION = "citizens.commands.npc.spawn.no-location";
public static final String NOT_LIVING_MOBTYPE = "citizens.commands.npc.create.not-living-mobtype";
public static final String NOT_USING_MINECRAFT_AI = "citizens.commands.npc.ai.stopped";
public static final String NPC_ALREADY_SELECTED = "citizens.commands.npc.select.already-selected";
public static final String NPC_ALREADY_SPAWNED = "citizens.commands.npc.spawn.already-spawned";
@ -357,7 +349,6 @@ public class Messages {
public static final String PROFESSION_SET = "citizens.commands.npc.profession.set";
public static final String PUFFERFISH_STATE_SET = "citizens.commands.npc.pufferfish.state-set";
public static final String RABBIT_TYPE_SET = "citizens.commands.npc.rabbittype.type-set";
public static final String REMOVE_INCORRECT_SYNTAX = "citizens.commands.npc.remove.incorrect-syntax";
public static final String REMOVED_ALL_NPCS = "citizens.commands.npc.remove.removed-all";
public static final String REMOVED_FROM_PLAYERLIST = "citizens.commands.npc.playerlist.removed";
public static final String RESPAWN_DELAY_DESCRIBE = "citizens.commands.npc.respawn.describe";
@ -382,7 +373,6 @@ public class Messages {
public static final String SKIN_REQUIRED = "citizens.commands.npc.skin.missing-skin";
public static final String SKIN_SET = "citizens.commands.npc.skin.set";
public static final String SKIN_URL_SET = "citizens.commands.npc.skin.skin-url-set";
public static final String SKIPPING_BROKEN_TRAIT = "citizens.notifications.skipping-broken-trait";
public static final String SKIPPING_INVALID_ANCHOR = "citizens.notifications.skipping-invalid-anchor";
public static final String SKIPPING_INVALID_POSE = "citizens.notifications.skipping-invalid-pose";
public static final String SNIFFER_STATE_SET = "citizens.commands.npc.sniffer.state-set";
@ -390,8 +380,6 @@ public class Messages {
public static final String SNOWMAN_DERP_STOPPED = "citizens.commands.npc.snowman.derp-stopped";
public static final String SOUND_INFO = "citizens.commands.npc.sound.info";
public static final String SOUND_SET = "citizens.commands.npc.sound.set";
public static final String SPAWN_NUMERIC_ID_ONLY = "citizens.commands.npc.spawn.numeric-id-only";
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 SPEED_TRIGGER_PROMPT = "citizens.editors.waypoints.triggers.speed.prompt";
public static final String SPELL_SET = "citizens.commands.npc.spellcaster.spell-set";
@ -441,7 +429,6 @@ public class Messages {
public static final String TROPICALFISH_PATTERN_SET = "citizens.commands.npc.tropicalfish.pattern-set";
public static final String UNDO_SUCCESSFUL = "citizens.commands.npc.undo.successful";
public static final String UNDO_UNSUCCESSFUL = "citizens.commands.npc.undo.unsuccessful";
public static final String UNKNOWN_COMMAND = "citizens.commands.unknown-command";
public static final String UNKNOWN_MATERIAL = "citizens.commands.npc.item.unknown-material";
public static final String UNKNOWN_NPC_REGISTRY = "citizens.commands.errors.unknown-registry";
public static final String UNKNOWN_PLAYER_ANIMATION = "citizens.commands.npc.panimate.unknown-animation";

View File

@ -898,7 +898,7 @@ public class NMSImpl implements NMSBridge {
public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) {
if (NMSImpl.getHandle(passenger) == null)
return;
NMSImpl.getHandle(passenger).startRiding(NMSImpl.getHandle(entity));
NMSImpl.getHandle(passenger).a(NMSImpl.getHandle(entity), true);
}
@Override

View File

@ -956,7 +956,7 @@ public class NMSImpl implements NMSBridge {
public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) {
if (NMSImpl.getHandle(passenger) == null)
return;
NMSImpl.getHandle(passenger).startRiding(NMSImpl.getHandle(entity));
NMSImpl.getHandle(passenger).a(NMSImpl.getHandle(entity), true);
}
@Override

View File

@ -21,7 +21,6 @@ import net.minecraft.server.v1_11_R1.EntityTrackerEntry;
public class PlayerlistTrackerEntry extends EntityTrackerEntry {
private Entity tracker;
private Map<EntityPlayer, Boolean> trackingMap;
public PlayerlistTrackerEntry(Entity entity, int i, int j, int k, boolean flag) {

View File

@ -966,7 +966,7 @@ public class NMSImpl implements NMSBridge {
public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) {
if (NMSImpl.getHandle(passenger) == null)
return;
NMSImpl.getHandle(passenger).startRiding(NMSImpl.getHandle(entity));
NMSImpl.getHandle(passenger).a(NMSImpl.getHandle(entity), true);
}
@Override

View File

@ -22,7 +22,6 @@ import net.minecraft.server.v1_12_R1.EntityTrackerEntry;
public class PlayerlistTrackerEntry extends EntityTrackerEntry {
private final Entity tracker;
private Map<EntityPlayer, Boolean> trackingMap;
public PlayerlistTrackerEntry(Entity entity, int i, int j, int k, boolean flag) {
@ -179,7 +178,6 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry {
private static MethodHandle TRACKING_MAP_SETTER;
private static final MethodHandle TRACKING_RANGE_SETTER = NMS.getFirstFinalSetter(EntityTrackerEntry.class,
int.class);
private static final MethodHandle TRACKING_SET_SETTER = NMS.getFirstFinalSetter(EntityTrackerEntry.class,
Set.class);
private static Field U = NMS.getField(EntityTrackerEntry.class, "u");

View File

@ -1002,7 +1002,7 @@ public class NMSImpl implements NMSBridge {
public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) {
if (NMSImpl.getHandle(passenger) == null)
return;
NMSImpl.getHandle(passenger).startRiding(NMSImpl.getHandle(entity));
NMSImpl.getHandle(passenger).a(NMSImpl.getHandle(entity), true);
}
@Override

View File

@ -1061,7 +1061,7 @@ public class NMSImpl implements NMSBridge {
public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) {
if (NMSImpl.getHandle(passenger) == null)
return;
NMSImpl.getHandle(passenger).startRiding(NMSImpl.getHandle(entity));
NMSImpl.getHandle(passenger).a(NMSImpl.getHandle(entity), true);
}
@Override

View File

@ -1078,7 +1078,7 @@ public class NMSImpl implements NMSBridge {
public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) {
if (NMSImpl.getHandle(passenger) == null)
return;
NMSImpl.getHandle(passenger).startRiding(NMSImpl.getHandle(entity));
NMSImpl.getHandle(passenger).a(NMSImpl.getHandle(entity), true);
}
@Override

View File

@ -1108,7 +1108,7 @@ public class NMSImpl implements NMSBridge {
public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) {
if (NMSImpl.getHandle(passenger) == null)
return;
NMSImpl.getHandle(passenger).startRiding(NMSImpl.getHandle(entity));
NMSImpl.getHandle(passenger).a(NMSImpl.getHandle(entity), true);
}
@Override

View File

@ -1110,7 +1110,7 @@ public class NMSImpl implements NMSBridge {
public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) {
if (NMSImpl.getHandle(passenger) == null)
return;
NMSImpl.getHandle(passenger).startRiding(NMSImpl.getHandle(entity));
NMSImpl.getHandle(passenger).startRiding(NMSImpl.getHandle(entity), true);
}
@Override

View File

@ -1118,7 +1118,7 @@ public class NMSImpl implements NMSBridge {
public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) {
if (NMSImpl.getHandle(passenger) == null)
return;
NMSImpl.getHandle(passenger).startRiding(NMSImpl.getHandle(entity));
NMSImpl.getHandle(passenger).startRiding(NMSImpl.getHandle(entity), true);
}
@Override

View File

@ -940,14 +940,14 @@ public class NMSImpl implements NMSBridge {
@Override
public void linkTextInteraction(org.bukkit.entity.Player player, org.bukkit.entity.Entity entity,
org.bukkit.entity.Entity mount, double offset) {
Interaction handle = (Interaction) getHandle(entity);
offset += -0.5 + getHandle(mount).getPassengersRidingOffset();
sendPacket(player,
new ClientboundBundlePacket(List.of(
new ClientboundSetEntityDataPacket(entity.getEntityId(),
List.of(new SynchedEntityData.DataItem<>(INTERACTION_WIDTH, 0f).value(),
new SynchedEntityData.DataItem<>(INTERACTION_HEIGHT, (float) offset).value(),
new SynchedEntityData.DataItem<>(DATA_POSE, Pose.CROAKING).value())),
new SynchedEntityData.DataItem<>(DATA_POSE, Pose.CROAKING).value(),
new SynchedEntityData.DataItem<>(DATA_NAME_VISIBLE, true).value())),
new ClientboundSetPassengersPacket(getHandle(mount)),
new ClientboundSetEntityDataPacket(entity.getEntityId(),
List.of(new SynchedEntityData.DataItem<>(INTERACTION_HEIGHT, 999999f).value())))));
@ -1190,7 +1190,7 @@ public class NMSImpl implements NMSBridge {
public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) {
if (getHandle(passenger) == null)
return;
getHandle(passenger).startRiding(getHandle(entity));
getHandle(passenger).startRiding(getHandle(entity), true);
}
@Override
@ -2595,6 +2595,7 @@ public class NMSImpl implements NMSBridge {
.newHashMap();
private static final MethodHandle CRAFT_BOSSBAR_HANDLE_FIELD = NMS.getFirstSetter(CraftBossBar.class,
ServerBossEvent.class);
private static EntityDataAccessor<Boolean> DATA_NAME_VISIBLE = null;
private static EntityDataAccessor<Pose> DATA_POSE = null;
private static final float DEFAULT_SPEED = 1F;
public static MethodHandle ENDERDRAGON_CHECK_WALLS = NMS.getFirstMethodHandleWithReturnType(EnderDragon.class, true,
@ -2689,6 +2690,7 @@ public class NMSImpl implements NMSBridge {
try {
DATA_POSE = (EntityDataAccessor<Pose>) NMS.getGetter(Entity.class, "ar").invoke();
DATA_NAME_VISIBLE = (EntityDataAccessor<Boolean>) NMS.getGetter(Entity.class, "aS").invoke();
} catch (Throwable e) {
e.printStackTrace();
}

View File

@ -923,7 +923,8 @@ public class NMSImpl implements NMSBridge {
new ClientboundSetEntityDataPacket(entity.getEntityId(),
List.of(new SynchedEntityData.DataItem<>(INTERACTION_WIDTH, 0f).value(),
new SynchedEntityData.DataItem<>(INTERACTION_HEIGHT, (float) offset).value(),
new SynchedEntityData.DataItem<>(DATA_POSE, Pose.CROAKING).value())),
new SynchedEntityData.DataItem<>(DATA_POSE, Pose.CROAKING).value(),
new SynchedEntityData.DataItem<>(DATA_NAME_VISIBLE, true).value())),
new ClientboundSetPassengersPacket(getHandle(mount)),
new ClientboundSetEntityDataPacket(entity.getEntityId(),
List.of(new SynchedEntityData.DataItem<>(INTERACTION_HEIGHT, 999999f).value())))));
@ -1166,7 +1167,7 @@ public class NMSImpl implements NMSBridge {
public void mount(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity passenger) {
if (getHandle(passenger) == null)
return;
getHandle(passenger).startRiding(getHandle(entity));
getHandle(passenger).startRiding(getHandle(entity), true);
}
@Override
@ -2577,6 +2578,7 @@ public class NMSImpl implements NMSBridge {
public static MethodHandle CONNECTION_PACKET_LISTENER = NMS.getSetter(Connection.class, "q");
private static final MethodHandle CRAFT_BOSSBAR_HANDLE_FIELD = NMS.getFirstSetter(CraftBossBar.class,
ServerBossEvent.class);
private static EntityDataAccessor<Boolean> DATA_NAME_VISIBLE = null;
private static EntityDataAccessor<Pose> DATA_POSE = null;
private static final float DEFAULT_SPEED = 1F;
public static final MethodHandle ENDERDRAGON_CHECK_WALLS = NMS.getFirstMethodHandleWithReturnType(EnderDragon.class,
@ -2675,6 +2677,7 @@ public class NMSImpl implements NMSBridge {
try {
DATA_POSE = (EntityDataAccessor<Pose>) NMS.getGetter(Entity.class, "as").invoke();
DATA_NAME_VISIBLE = (EntityDataAccessor<Boolean>) NMS.getGetter(Entity.class, "aV").invoke();
} catch (Throwable e) {
e.printStackTrace();
}