Implement new metadata

This commit is contained in:
fullwall 2023-08-06 18:57:42 +08:00
parent 6fd768992a
commit 8719c1f182
15 changed files with 116 additions and 61 deletions

View File

@ -238,6 +238,9 @@ public class Settings {
PLAYER_TELEPORT_DELAY("npc.delay-player-teleport-ticks", "npc.delay-player-teleport", -1),
REMOVE_PLAYERS_FROM_PLAYER_LIST("Whether to remove NPCs from the Java list of players",
"npc.player.remove-from-list", true),
RESET_YAW_ON_SPAWN(
"Whether to reset NPC yaw on spawn. Currently this is implemented by an arm swing animation due to Minecraft limitations.",
"npc.default.reset-yaw-on-spawn", true),
RESOURCE_PACK_PATH("The resource pack path to save resource packs to", "general.resource-pack-path",
"plugins/Citizens/resourcepack"),
SAVE_TASK_DELAY("How often to save NPCs to disk", "storage.save-task.delay", "1hr"),

View File

@ -23,7 +23,6 @@ import org.bukkit.Sound;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Ageable;
@ -673,7 +672,7 @@ public class NPCCommands {
@Command(
aliases = { "npc" },
usage = "create [name] ((-b(aby),u(nspawned),s(ilent),t(emporary),c(enter),p(acket)) --at [x:y:z:world] --type [type] --item (item) --trait ['trait1, trait2...'] --model [model name] --nameplate [true|false|hover] --temporaryticks [ticks] --registry [registry name]",
usage = "create [name] ((-b(aby),u(nspawned),s(ilent),t(emporary),c(enter),p(acket)) --at [x,y,z,world] --type [type] --item (item) --trait ['trait1, trait2...'] --model [model name] --nameplate [true|false|hover] --temporaryticks [ticks] --registry [registry name]",
desc = "Create a new NPC",
flags = "bustpc",
modifiers = { "create" },
@ -766,12 +765,7 @@ public class NPCCommands {
npc.addTrait(PacketNPC.class);
}
Location spawnLoc = null;
if (sender instanceof Player) {
spawnLoc = args.getSenderLocation();
} else if (sender instanceof BlockCommandSender) {
spawnLoc = args.getSenderLocation();
}
Location spawnLoc = args.getSenderLocation();
CommandSenderCreateNPCEvent event = sender instanceof Player ? new PlayerCreateNPCEvent((Player) sender, npc)
: new CommandSenderCreateNPCEvent(sender, npc);
@ -2254,6 +2248,21 @@ public class NPCCommands {
npc.getName());
}
@Command(
aliases = { "npc" },
usage = "playsound [sound] (volume) (pitch)",
desc = "Plays a sound at the NPC's location",
modifiers = { "playsound" },
min = 2,
max = 4,
permission = "citizens.npc.playsound")
@Requirements(selected = true, ownership = true)
public void playsound(CommandContext args, CommandSender sender, NPC npc, @Arg(1) String sound,
@Arg(value = 2, defValue = "1") Float volume, @Arg(value = 3, defValue = "1") Float pitch)
throws CommandException {
npc.getEntity().getWorld().playSound(npc.getEntity(), sound, volume, pitch);
}
@Command(
aliases = { "npc" },
usage = "pose (--save [name] (-d) | --mirror [name] (-d) | --assume [name] | --remove [name] | --default [name]) (--yaw yaw) (--pitch pitch) (-a)",

View File

@ -11,6 +11,7 @@ import java.util.function.Supplier;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import com.google.common.collect.Iterables;
@ -62,8 +63,9 @@ public class RotationTrait extends Trait {
return lrs;
}
private double getEyeY() {
return NMS.getHeight(npc.getEntity());
private Location getEyeLocation() {
return npc instanceof LivingEntity ? ((LivingEntity) npc.getEntity()).getEyeLocation()
: npc.getEntity().getLocation();
}
/**
@ -89,18 +91,6 @@ public class RotationTrait extends Trait {
return globalSession;
}
private double getX() {
return npc.getStoredLocation().getX();
}
private double getY() {
return npc.getStoredLocation().getY();
}
private double getZ() {
return npc.getStoredLocation().getZ();
}
@Override
public void run() {
if (!npc.isSpawned())
@ -427,9 +417,8 @@ public class RotationTrait extends Trait {
* The target entity to face
*/
public void rotateToFace(Entity target) {
Location loc = target.getLocation();
loc.setY(loc.getY() + NMS.getHeight(target));
rotateToFace(loc);
rotateToFace(
target instanceof LivingEntity ? ((LivingEntity) target).getEyeLocation() : target.getLocation());
}
/**
@ -441,14 +430,17 @@ public class RotationTrait extends Trait {
public void rotateToFace(Location target) {
t = 0;
targetPitch = () -> {
double dx = target.getX() - getX();
double dy = target.getY() - (getY() + getEyeY());
double dz = target.getZ() - getZ();
Location from = getEyeLocation();
double dx = target.getX() - from.getX();
double dy = target.getY() - from.getY();
double dz = target.getZ() - from.getZ();
double diag = Math.sqrt((float) (dx * dx + dz * dz));
return (float) -Math.toDegrees(Math.atan2(dy, diag));
};
targetYaw = () -> {
return (float) Math.toDegrees(Math.atan2(target.getZ() - getZ(), target.getX() - getX())) - 90.0F;
Location from = getEyeLocation();
return (float) Math.toDegrees(Math.atan2(target.getZ() - from.getZ(), target.getX() - from.getX()))
- 90.0F;
};
}

View File

@ -134,6 +134,9 @@ public class ShopTrait extends Trait {
public void display(Player sender) {
if (viewPermission != null && !sender.hasPermission(viewPermission))
return;
if (!Setting.SHOP_GLOBAL_VIEW_PERMISSION.asString().isEmpty()
&& !sender.hasPermission(Setting.SHOP_GLOBAL_VIEW_PERMISSION.asString()))
return;
if (pages.size() == 0) {
Messaging.sendError(sender, "Empty shop");
return;

View File

@ -21,6 +21,7 @@ import net.citizensnpcs.util.NMS;
import net.minecraft.server.v1_11_R1.Entity;
import net.minecraft.server.v1_11_R1.EntityPlayer;
import net.minecraft.server.v1_11_R1.EntityTrackerEntry;
import net.minecraft.server.v1_11_R1.PacketPlayOutAnimation;
public class PlayerlistTrackerEntry extends EntityTrackerEntry {
private Entity tracker;
@ -90,6 +91,12 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry {
final EntityPlayer entityplayer = lastUpdatedPlayer;
NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity());
lastUpdatedPlayer = null;
NPC npc = ((NPCHolder) tracker).getNPC();
if (npc.data().get(NPC.Metadata.RESET_YAW_ON_SPAWN, Setting.RESET_YAW_ON_SPAWN.asBoolean())) {
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(),
() -> NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new PacketPlayOutAnimation(tracker, 0)),
1);
}
if (!Setting.DISABLE_TABLIST.asBoolean())
return;
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(),

View File

@ -22,6 +22,7 @@ import net.citizensnpcs.util.NMS;
import net.minecraft.server.v1_12_R1.Entity;
import net.minecraft.server.v1_12_R1.EntityPlayer;
import net.minecraft.server.v1_12_R1.EntityTrackerEntry;
import net.minecraft.server.v1_12_R1.PacketPlayOutAnimation;
public class PlayerlistTrackerEntry extends EntityTrackerEntry {
private final Entity tracker;
@ -91,6 +92,12 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry {
final EntityPlayer entityplayer = lastUpdatedPlayer;
NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity());
lastUpdatedPlayer = null;
NPC npc = ((NPCHolder) tracker).getNPC();
if (npc.data().get(NPC.Metadata.RESET_YAW_ON_SPAWN, Setting.RESET_YAW_ON_SPAWN.asBoolean())) {
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(),
() -> NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new PacketPlayOutAnimation(tracker, 0)),
1);
}
if (!Setting.DISABLE_TABLIST.asBoolean())
return;
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(),

View File

@ -91,9 +91,12 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry {
final EntityPlayer entityplayer = lastUpdatedPlayer;
NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity());
lastUpdatedPlayer = null;
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> {
NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new PacketPlayOutAnimation(tracker, 0));
}, 1);
NPC npc = ((NPCHolder) tracker).getNPC();
if (npc.data().get(NPC.Metadata.RESET_YAW_ON_SPAWN, Setting.RESET_YAW_ON_SPAWN.asBoolean())) {
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(),
() -> NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new PacketPlayOutAnimation(tracker, 0)),
1);
}
if (!Setting.DISABLE_TABLIST.asBoolean())
return;
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(),

View File

@ -91,9 +91,12 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker {
return;
final EntityPlayer entityplayer = lastUpdatedPlayer;
NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity());
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> {
NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new PacketPlayOutAnimation(tracker, 0));
}, 1);
NPC npc = ((NPCHolder) tracker).getNPC();
if (npc.data().get(NPC.Metadata.RESET_YAW_ON_SPAWN, Setting.RESET_YAW_ON_SPAWN.asBoolean())) {
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(),
() -> NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new PacketPlayOutAnimation(tracker, 0)),
1);
}
if (!Setting.DISABLE_TABLIST.asBoolean())
return;
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(),

View File

@ -91,9 +91,12 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker {
return;
final EntityPlayer entityplayer = lastUpdatedPlayer;
NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity());
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> {
NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new PacketPlayOutAnimation(tracker, 0));
}, 1);
NPC npc = ((NPCHolder) tracker).getNPC();
if (npc.data().get(NPC.Metadata.RESET_YAW_ON_SPAWN, Setting.RESET_YAW_ON_SPAWN.asBoolean())) {
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(),
() -> NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new PacketPlayOutAnimation(tracker, 0)),
1);
}
if (!Setting.DISABLE_TABLIST.asBoolean())
return;
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(),

View File

@ -91,9 +91,12 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker {
return;
final EntityPlayer entityplayer = lastUpdatedPlayer;
NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity());
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> {
NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new PacketPlayOutAnimation(tracker, 0));
}, 1);
NPC npc = ((NPCHolder) tracker).getNPC();
if (npc.data().get(NPC.Metadata.RESET_YAW_ON_SPAWN, Setting.RESET_YAW_ON_SPAWN.asBoolean())) {
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(),
() -> NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new PacketPlayOutAnimation(tracker, 0)),
1);
}
if (!Setting.DISABLE_TABLIST.asBoolean())
return;
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(),

View File

@ -40,9 +40,12 @@ public class PlayerlistTracker extends ChunkMap.TrackedEntity {
return;
final ServerPlayer entityplayer = lastUpdatedPlayer;
NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity());
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> {
NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new ClientboundAnimatePacket(tracker, 0));
}, 1);
NPC npc = ((NPCHolder) tracker).getNPC();
if (npc.data().get(NPC.Metadata.RESET_YAW_ON_SPAWN, Setting.RESET_YAW_ON_SPAWN.asBoolean())) {
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(),
() -> NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new ClientboundAnimatePacket(tracker, 0)),
1);
}
if (!Setting.DISABLE_TABLIST.asBoolean())
return;
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(),

View File

@ -40,9 +40,12 @@ public class PlayerlistTracker extends ChunkMap.TrackedEntity {
return;
final ServerPlayer entityplayer = lastUpdatedPlayer;
NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity());
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> {
NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new ClientboundAnimatePacket(tracker, 0));
}, 1);
NPC npc = ((NPCHolder) tracker).getNPC();
if (npc.data().get(NPC.Metadata.RESET_YAW_ON_SPAWN, Setting.RESET_YAW_ON_SPAWN.asBoolean())) {
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(),
() -> NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new ClientboundAnimatePacket(tracker, 0)),
1);
}
if (!Setting.DISABLE_TABLIST.asBoolean())
return;
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> {

View File

@ -61,15 +61,22 @@ public class CitizensEntityTracker extends ChunkMap.TrackedEntity {
if (tracker.isRemoved() || tracker.getBukkitEntity().getType() != EntityType.PLAYER)
return;
final ServerPlayer entityplayer = lastUpdatedPlayer;
NPC npc = ((NPCHolder) tracker).getNPC();
boolean resetYaw = npc.data().get(NPC.Metadata.RESET_YAW_ON_SPAWN, Setting.RESET_YAW_ON_SPAWN.asBoolean());
boolean sendTabRemove = NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity());
if (!sendTabRemove || !Setting.DISABLE_TABLIST.asBoolean()) {
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(),
() -> NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new ClientboundAnimatePacket(tracker, 0)),
1);
if (resetYaw) {
Bukkit.getScheduler()
.scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> NMSImpl
.sendPacket(entityplayer.getBukkitEntity(), new ClientboundAnimatePacket(tracker, 0)),
1);
}
return;
}
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> {
NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new ClientboundAnimatePacket(tracker, 0));
if (resetYaw) {
NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new ClientboundAnimatePacket(tracker, 0));
}
NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity());
}, Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks());
}

View File

@ -68,18 +68,25 @@ public class CitizensEntityTracker extends ChunkMap.TrackedEntity {
NMSImpl.sendPacket(entityplayer.getBukkitEntity(),
new ClientboundRotateHeadPacket(tracker, (byte) (tracker.getYHeadRot() * 256.0F / 360.0F)));
}, Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks() + 1);
NPC npc = ((NPCHolder) tracker).getNPC();
boolean resetYaw = npc.data().get(NPC.Metadata.RESET_YAW_ON_SPAWN, Setting.RESET_YAW_ON_SPAWN.asBoolean());
boolean sendTabRemove = NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity());
if (!sendTabRemove || !Setting.DISABLE_TABLIST.asBoolean()) {
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(),
() -> NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new ClientboundAnimatePacket(tracker, 0)),
1);
if (resetYaw) {
Bukkit.getScheduler()
.scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> NMSImpl
.sendPacket(entityplayer.getBukkitEntity(), new ClientboundAnimatePacket(tracker, 0)),
1);
}
return;
}
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> {
if (tracker.isRemoved() || entityplayer.isRemoved())
return;
NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity());
NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new ClientboundAnimatePacket(tracker, 0));
if (resetYaw) {
NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new ClientboundAnimatePacket(tracker, 0));
}
}, Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks());
}

View File

@ -39,14 +39,16 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry {
final EntityPlayer entityplayer = lastUpdatedPlayer;
NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity());
lastUpdatedPlayer = null;
NPC npc = ((NPCHolder) tracker).getNPC();
if (npc.data().get(NPC.Metadata.RESET_YAW_ON_SPAWN, Setting.RESET_YAW_ON_SPAWN.asBoolean())) {
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(),
() -> NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new PacketPlayOutAnimation(tracker, 0)),
1);
}
if (!Setting.DISABLE_TABLIST.asBoolean())
return;
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() {
@Override
public void run() {
NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new PacketPlayOutAnimation(tracker, 0));
NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity());
}
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> {
NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity());
}, Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks());
}