PlaySoundCommand.java

net.minecraft.server.commands.PlaySoundCommand

信息

  • 全限定名:net.minecraft.server.commands.PlaySoundCommand
  • 类型:public class
  • 包:net.minecraft.server.commands
  • 源码路径:src/main/java/net/minecraft/server/commands/PlaySoundCommand.java
  • 起始行号:L30
  • 职责:

    TODO

字段/常量

  • ERROR_TOO_FAR
    • 类型: SimpleCommandExceptionType
    • 修饰符: private static final
    • 源码定位: L31
    • 说明:

      TODO

内部类/嵌套类型

构造器

方法

下面的方法块按源码顺序生成。

public static void register(CommandDispatcher<CommandSourceStack> dispatcher) @ L33

  • 方法名:register
  • 源码定位:L33
  • 返回类型:void
  • 修饰符:public static

参数:

  • dispatcher: CommandDispatcher

说明:

TODO

private static LiteralArgumentBuilder<CommandSourceStack> source(SoundSource source) @ L56

  • 方法名:source
  • 源码定位:L56
  • 返回类型:LiteralArgumentBuilder
  • 修饰符:private static

参数:

  • source: SoundSource

说明:

TODO

private static Collection<ServerPlayer> getCallingPlayerAsCollection(ServerPlayer player) @ L147

  • 方法名:getCallingPlayerAsCollection
  • 源码定位:L147
  • 返回类型:Collection
  • 修饰符:private static

参数:

  • player: ServerPlayer

说明:

TODO

private static int playSound(CommandSourceStack source, Collection<ServerPlayer> players, Identifier sound, SoundSource soundSource, Vec3 position, float volume, float pitch, float minVolume) @ L151

  • 方法名:playSound
  • 源码定位:L151
  • 返回类型:int
  • 修饰符:private static

参数:

  • source: CommandSourceStack
  • players: Collection
  • sound: Identifier
  • soundSource: SoundSource
  • position: Vec3
  • volume: float
  • pitch: float
  • minVolume: float

说明:

TODO

代码

public class PlaySoundCommand {
    private static final SimpleCommandExceptionType ERROR_TOO_FAR = new SimpleCommandExceptionType(Component.translatable("commands.playsound.failed"));
 
    public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
        RequiredArgumentBuilder<CommandSourceStack, Identifier> name = Commands.argument("sound", IdentifierArgument.id())
            .suggests(SuggestionProviders.cast(SuggestionProviders.AVAILABLE_SOUNDS))
            .executes(
                c -> playSound(
                    c.getSource(),
                    getCallingPlayerAsCollection(c.getSource().getPlayer()),
                    IdentifierArgument.getId(c, "sound"),
                    SoundSource.MASTER,
                    c.getSource().getPosition(),
                    1.0F,
                    1.0F,
                    0.0F
                )
            );
 
        for (SoundSource source : SoundSource.values()) {
            name.then(source(source));
        }
 
        dispatcher.register(Commands.literal("playsound").requires(Commands.hasPermission(Commands.LEVEL_GAMEMASTERS)).then(name));
    }
 
    private static LiteralArgumentBuilder<CommandSourceStack> source(SoundSource source) {
        return Commands.literal(source.getName())
            .executes(
                c -> playSound(
                    c.getSource(),
                    getCallingPlayerAsCollection(c.getSource().getPlayer()),
                    IdentifierArgument.getId(c, "sound"),
                    source,
                    c.getSource().getPosition(),
                    1.0F,
                    1.0F,
                    0.0F
                )
            )
            .then(
                Commands.argument("targets", EntityArgument.players())
                    .executes(
                        c -> playSound(
                            c.getSource(),
                            EntityArgument.getPlayers(c, "targets"),
                            IdentifierArgument.getId(c, "sound"),
                            source,
                            c.getSource().getPosition(),
                            1.0F,
                            1.0F,
                            0.0F
                        )
                    )
                    .then(
                        Commands.argument("pos", Vec3Argument.vec3())
                            .executes(
                                c -> playSound(
                                    c.getSource(),
                                    EntityArgument.getPlayers(c, "targets"),
                                    IdentifierArgument.getId(c, "sound"),
                                    source,
                                    Vec3Argument.getVec3(c, "pos"),
                                    1.0F,
                                    1.0F,
                                    0.0F
                                )
                            )
                            .then(
                                Commands.argument("volume", FloatArgumentType.floatArg(0.0F))
                                    .executes(
                                        c -> playSound(
                                            c.getSource(),
                                            EntityArgument.getPlayers(c, "targets"),
                                            IdentifierArgument.getId(c, "sound"),
                                            source,
                                            Vec3Argument.getVec3(c, "pos"),
                                            c.getArgument("volume", Float.class),
                                            1.0F,
                                            0.0F
                                        )
                                    )
                                    .then(
                                        Commands.argument("pitch", FloatArgumentType.floatArg(0.0F, 2.0F))
                                            .executes(
                                                c -> playSound(
                                                    c.getSource(),
                                                    EntityArgument.getPlayers(c, "targets"),
                                                    IdentifierArgument.getId(c, "sound"),
                                                    source,
                                                    Vec3Argument.getVec3(c, "pos"),
                                                    c.getArgument("volume", Float.class),
                                                    c.getArgument("pitch", Float.class),
                                                    0.0F
                                                )
                                            )
                                            .then(
                                                Commands.argument("minVolume", FloatArgumentType.floatArg(0.0F, 1.0F))
                                                    .executes(
                                                        c -> playSound(
                                                            c.getSource(),
                                                            EntityArgument.getPlayers(c, "targets"),
                                                            IdentifierArgument.getId(c, "sound"),
                                                            source,
                                                            Vec3Argument.getVec3(c, "pos"),
                                                            c.getArgument("volume", Float.class),
                                                            c.getArgument("pitch", Float.class),
                                                            c.getArgument("minVolume", Float.class)
                                                        )
                                                    )
                                            )
                                    )
                            )
                    )
            );
    }
 
    private static Collection<ServerPlayer> getCallingPlayerAsCollection(@Nullable ServerPlayer player) {
        return player != null ? List.of(player) : List.of();
    }
 
    private static int playSound(
        CommandSourceStack source,
        Collection<ServerPlayer> players,
        Identifier sound,
        SoundSource soundSource,
        Vec3 position,
        float volume,
        float pitch,
        float minVolume
    ) throws CommandSyntaxException {
        Holder<SoundEvent> soundHolder = Holder.direct(SoundEvent.createVariableRangeEvent(sound));
        double maxDistSqr = Mth.square(soundHolder.value().getRange(volume));
        ServerLevel level = source.getLevel();
        long seed = level.getRandom().nextLong();
        List<ServerPlayer> playedFor = new ArrayList<>();
 
        for (ServerPlayer player : players) {
            if (player.level() == level) {
                double deltaX = position.x - player.getX();
                double deltaY = position.y - player.getY();
                double deltaZ = position.z - player.getZ();
                double distSqr = deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ;
                Vec3 localPosition = position;
                float localVolume = volume;
                if (distSqr > maxDistSqr) {
                    if (minVolume <= 0.0F) {
                        continue;
                    }
 
                    double distance = Math.sqrt(distSqr);
                    localPosition = new Vec3(
                        player.getX() + deltaX / distance * 2.0, player.getY() + deltaY / distance * 2.0, player.getZ() + deltaZ / distance * 2.0
                    );
                    localVolume = minVolume;
                }
 
                player.connection
                    .send(
                        new ClientboundSoundPacket(soundHolder, soundSource, localPosition.x(), localPosition.y(), localPosition.z(), localVolume, pitch, seed)
                    );
                playedFor.add(player);
            }
        }
 
        int count = playedFor.size();
        if (count == 0) {
            throw ERROR_TOO_FAR.create();
        } else {
            if (count == 1) {
                source.sendSuccess(
                    () -> Component.translatable("commands.playsound.success.single", Component.translationArg(sound), playedFor.getFirst().getDisplayName()),
                    true
                );
            } else {
                source.sendSuccess(() -> Component.translatable("commands.playsound.success.multiple", Component.translationArg(sound), count), true);
            }
 
            return count;
        }
    }
}

引用的其他类

  • CommandSourceStack

    • 引用位置: 参数/返回值
  • Commands

    • 引用位置: 方法调用
    • 关联成员: Commands.argument(), Commands.hasPermission(), Commands.literal()
  • EntityArgument

    • 引用位置: 方法调用
    • 关联成员: EntityArgument.getPlayers(), EntityArgument.players()
  • IdentifierArgument

    • 引用位置: 方法调用
    • 关联成员: IdentifierArgument.getId(), IdentifierArgument.id()
  • Vec3Argument

    • 引用位置: 方法调用
    • 关联成员: Vec3Argument.getVec3(), Vec3Argument.vec3()
  • SuggestionProviders

    • 引用位置: 方法调用
    • 关联成员: SuggestionProviders.cast()
  • Holder

    • 引用位置: 方法调用
    • 关联成员: Holder.direct()
  • Component

    • 引用位置: 方法调用
    • 关联成员: Component.translatable(), Component.translationArg()
  • ClientboundSoundPacket

    • 引用位置: 构造调用
    • 关联成员: ClientboundSoundPacket()
  • Identifier

    • 引用位置: 参数
  • ServerPlayer

    • 引用位置: 参数/返回值
  • SoundEvent

    • 引用位置: 方法调用
    • 关联成员: SoundEvent.createVariableRangeEvent()
  • SoundSource

    • 引用位置: 参数/方法调用
    • 关联成员: SoundSource.values()
  • Mth

    • 引用位置: 方法调用
    • 关联成员: Mth.square()
  • Vec3

    • 引用位置: 参数/构造调用
    • 关联成员: Vec3()