mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-23 08:59:27 +00:00
改进totem指令
This commit is contained in:
@@ -30,10 +30,12 @@ import org.incendo.cloud.bukkit.parser.selector.MultiplePlayerSelectorParser;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.context.CommandInput;
|
||||
import org.incendo.cloud.parser.flag.CommandFlag;
|
||||
import org.incendo.cloud.parser.standard.FloatParser;
|
||||
import org.incendo.cloud.suggestion.Suggestion;
|
||||
import org.incendo.cloud.suggestion.SuggestionProvider;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class TotemAnimationCommand extends BukkitCommandFeature<CommandSender> {
|
||||
@@ -46,6 +48,7 @@ public class TotemAnimationCommand extends BukkitCommandFeature<CommandSender> {
|
||||
public Command.Builder<? extends CommandSender> assembleCommand(CommandManager<CommandSender> manager, Command.Builder<CommandSender> builder) {
|
||||
return builder
|
||||
.flag(FlagKeys.SILENT_FLAG)
|
||||
.flag(CommandFlag.builder("no-sound"))
|
||||
.required("players", MultiplePlayerSelectorParser.multiplePlayerSelectorParser())
|
||||
.required("id", NamespacedKeyParser.namespacedKeyComponent().suggestionProvider(new SuggestionProvider<>() {
|
||||
@Override
|
||||
@@ -53,7 +56,16 @@ public class TotemAnimationCommand extends BukkitCommandFeature<CommandSender> {
|
||||
return CompletableFuture.completedFuture(plugin().itemManager().cachedTotemSuggestions());
|
||||
}
|
||||
}))
|
||||
.flag(CommandFlag.builder("sound").withComponent(NamespacedKeyParser.namespacedKeyParser()).build())
|
||||
.optional("sound", NamespacedKeyParser.namespacedKeyComponent().suggestionProvider(new SuggestionProvider<>() {
|
||||
@Override
|
||||
public @NonNull CompletableFuture<? extends @NonNull Iterable<? extends @NonNull Suggestion>> suggestionsFuture(@NonNull CommandContext<Object> context, @NonNull CommandInput input) {
|
||||
return CompletableFuture.completedFuture(plugin().soundManager().cachedSoundSuggestions());
|
||||
}
|
||||
}))
|
||||
.optional("volume", FloatParser.floatParser(0f))
|
||||
.optional("pitch", FloatParser.floatParser(0f, 2f))
|
||||
.optional("min-volume", FloatParser.floatParser(0f))
|
||||
.optional("min-pitch", FloatParser.floatParser(0f, 2f))
|
||||
.handler(context -> {
|
||||
NamespacedKey namespacedKey = context.get("id");
|
||||
Key key = Key.of(namespacedKey.namespace(), namespacedKey.value());
|
||||
@@ -62,6 +74,16 @@ public class TotemAnimationCommand extends BukkitCommandFeature<CommandSender> {
|
||||
handleFeedback(context, MessageConstants.COMMAND_TOTEM_NOT_TOTEM, Component.text(key.toString()));
|
||||
return;
|
||||
}
|
||||
Optional<NamespacedKey> soundKey = context.optional("sound");
|
||||
SoundData soundData = null;
|
||||
if (soundKey.isPresent()) {
|
||||
float volume = context.getOrDefault("volume", 1.0f);
|
||||
float pitch = context.getOrDefault("pitch", 1.0f);
|
||||
float minVolume = context.getOrDefault("min-volume", 1.0f);
|
||||
float minPitch = context.getOrDefault("min-pitch", 1.0f);
|
||||
soundData = SoundData.of(KeyUtils.namespacedKey2Key(soundKey.get()), SoundData.SoundValue.ranged(minVolume, volume), SoundData.SoundValue.ranged(minPitch, pitch));
|
||||
}
|
||||
boolean removeSound = context.flags().hasFlag("no-sound");
|
||||
MultiplePlayerSelector selector = context.get("players");
|
||||
for (Player player : selector.values()) {
|
||||
BukkitServerPlayer serverPlayer = BukkitAdaptors.adapt(player);
|
||||
@@ -69,13 +91,11 @@ public class TotemAnimationCommand extends BukkitCommandFeature<CommandSender> {
|
||||
if (VersionHelper.isOrAbove1_21_2()) {
|
||||
item.setJavaComponent(ComponentTypes.DEATH_PROTECTION, Map.of());
|
||||
}
|
||||
NamespacedKey soundKey = context.flags().get("sound");
|
||||
SoundData soundData = null;
|
||||
if (soundKey != null) {
|
||||
soundData = SoundData.of(KeyUtils.namespacedKey2Key(soundKey), SoundData.SoundValue.FIXED_1, SoundData.SoundValue.FIXED_1);
|
||||
}
|
||||
PlayerUtils.sendTotemAnimation(serverPlayer, item, soundData);
|
||||
// TODO 存在第一次进服 未正确移除图腾声音的问题
|
||||
PlayerUtils.sendTotemAnimation(serverPlayer, item, soundData, removeSound);
|
||||
}
|
||||
|
||||
// TODO 消息提示
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.momirealms.craftengine.bukkit.util;
|
||||
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
|
||||
import net.momirealms.craftengine.bukkit.item.ComponentTypes;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
|
||||
@@ -56,15 +57,19 @@ public final class PlayerUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendTotemAnimation(Player player, Item<ItemStack> totem, @Nullable SoundData sound) {
|
||||
public static void sendTotemAnimation(Player player, Item<ItemStack> totem, @Nullable SoundData sound, boolean removeSound) {
|
||||
List<Object> packets = new ArrayList<>();
|
||||
try {
|
||||
Object totemItem = totem.getLiteralObject();
|
||||
Item<?> previousMainHandItem = player.getItemInHand(InteractionHand.MAIN_HAND);
|
||||
boolean flag = previousMainHandItem.id().equals(ItemKeys.TOTEM_OF_UNDYING);
|
||||
boolean isMainHandTotem;
|
||||
if (VersionHelper.isOrAbove1_21_2()) {
|
||||
isMainHandTotem = previousMainHandItem.hasComponent(ComponentTypes.DEATH_PROTECTION);
|
||||
} else {
|
||||
isMainHandTotem = previousMainHandItem.id().equals(ItemKeys.TOTEM_OF_UNDYING);
|
||||
}
|
||||
Object previousOffHandItem = player.getItemInHand(InteractionHand.OFF_HAND).getLiteralObject();
|
||||
|
||||
if (flag) {
|
||||
if (isMainHandTotem) {
|
||||
packets.add(NetworkReflections.constructor$ClientboundSetEquipmentPacket.newInstance(
|
||||
player.entityID(), List.of(Pair.of(CoreReflections.instance$EquipmentSlot$MAINHAND, BukkitItemManager.instance().uniqueEmptyItem().item().getLiteralObject()))
|
||||
));
|
||||
@@ -73,7 +78,7 @@ public final class PlayerUtils {
|
||||
player.entityID(), List.of(Pair.of(CoreReflections.instance$EquipmentSlot$OFFHAND, totemItem))
|
||||
));
|
||||
packets.add(NetworkReflections.constructor$ClientboundEntityEventPacket.newInstance(player.serverPlayer(), (byte) 35));
|
||||
if (flag) {
|
||||
if (isMainHandTotem) {
|
||||
packets.add(NetworkReflections.constructor$ClientboundSetEquipmentPacket.newInstance(
|
||||
player.entityID(), List.of(Pair.of(CoreReflections.instance$EquipmentSlot$MAINHAND, previousMainHandItem.getLiteralObject()))
|
||||
));
|
||||
@@ -81,12 +86,13 @@ public final class PlayerUtils {
|
||||
packets.add(NetworkReflections.constructor$ClientboundSetEquipmentPacket.newInstance(
|
||||
player.entityID(), List.of(Pair.of(CoreReflections.instance$EquipmentSlot$OFFHAND, previousOffHandItem))
|
||||
));
|
||||
|
||||
if (sound != null) {
|
||||
if (sound != null || removeSound) {
|
||||
packets.add(NetworkReflections.constructor$ClientboundStopSoundPacket.newInstance(
|
||||
FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", "item.totem.use"),
|
||||
CoreReflections.instance$SoundSource$PLAYERS
|
||||
));
|
||||
}
|
||||
if (sound != null) {
|
||||
packets.add(FastNMS.INSTANCE.constructor$ClientboundSoundPacket(
|
||||
FastNMS.INSTANCE.method$Holder$direct(FastNMS.INSTANCE.constructor$SoundEvent(KeyUtils.toResourceLocation(sound.id()), Optional.empty())),
|
||||
CoreReflections.instance$SoundSource$PLAYERS,
|
||||
@@ -94,7 +100,6 @@ public final class PlayerUtils {
|
||||
RandomUtils.generateRandomLong()
|
||||
));
|
||||
}
|
||||
|
||||
player.sendPackets(packets, false);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
BukkitCraftEngine.instance().logger().warn("Failed to send totem animation");
|
||||
|
||||
Reference in New Issue
Block a user