mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-19 15:09:15 +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");
|
||||
|
||||
@@ -172,6 +172,7 @@ public abstract class CraftEngine implements Plugin {
|
||||
// collect illegal characters from minecraft:default font
|
||||
this.fontManager.delayedLoad();
|
||||
this.advancementManager.delayedLoad();
|
||||
this.soundManager.delayedLoad();
|
||||
if (reloadRecipe) {
|
||||
// convert data pack recipes
|
||||
this.recipeManager.delayedLoad();
|
||||
|
||||
@@ -8,6 +8,7 @@ import net.momirealms.craftengine.core.plugin.config.ConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.config.IdSectionConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.util.*;
|
||||
import org.incendo.cloud.suggestion.Suggestion;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
@@ -21,6 +22,7 @@ public abstract class AbstractSoundManager implements SoundManager {
|
||||
protected final SoundParser soundParser;
|
||||
protected final SongParser songParser;
|
||||
protected final Map<Integer, Key> customSoundsInRegistry = new HashMap<>();
|
||||
protected final List<Suggestion> soundSuggestions = new ArrayList<>();
|
||||
|
||||
public AbstractSoundManager(CraftEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
@@ -43,6 +45,22 @@ public abstract class AbstractSoundManager implements SoundManager {
|
||||
this.byId.clear();
|
||||
this.byNamespace.clear();
|
||||
this.songs.clear();
|
||||
this.soundSuggestions.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delayedLoad() {
|
||||
for (Key key : VANILLA_SOUND_EVENTS) {
|
||||
this.soundSuggestions.add(Suggestion.suggestion(key.asString()));
|
||||
}
|
||||
for (Key key : this.byId.keySet()) {
|
||||
this.soundSuggestions.add(Suggestion.suggestion(key.asString()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Suggestion> cachedSoundSuggestions() {
|
||||
return this.soundSuggestions;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -57,6 +57,11 @@ public record SoundData(Key id, SoundValue volume, SoundValue pitch) {
|
||||
}
|
||||
|
||||
static SoundValue ranged(float min, float max) {
|
||||
if (min > max) {
|
||||
return new Ranged(max, min);
|
||||
} else if (min == max) {
|
||||
return SoundValue.fixed(max);
|
||||
}
|
||||
return new Ranged(min, max);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,9 @@ package net.momirealms.craftengine.core.sound;
|
||||
import net.momirealms.craftengine.core.plugin.Manageable;
|
||||
import net.momirealms.craftengine.core.plugin.config.ConfigParser;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import org.incendo.cloud.suggestion.Suggestion;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface SoundManager extends Manageable {
|
||||
@@ -12,5 +14,7 @@ public interface SoundManager extends Manageable {
|
||||
|
||||
ConfigParser[] parsers();
|
||||
|
||||
List<Suggestion> cachedSoundSuggestions();
|
||||
|
||||
Map<Key, SoundEvent> sounds();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user