202 lines
7 KiB
Java
202 lines
7 KiB
Java
package net.minecraft.server.commands;
|
|
|
|
import com.mojang.brigadier.CommandDispatcher;
|
|
import com.mojang.brigadier.arguments.FloatArgumentType;
|
|
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
|
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
|
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
|
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
|
import java.util.Collection;
|
|
import java.util.List;
|
|
import net.minecraft.commands.CommandSourceStack;
|
|
import net.minecraft.commands.Commands;
|
|
import net.minecraft.commands.arguments.EntityArgument;
|
|
import net.minecraft.commands.arguments.ResourceLocationArgument;
|
|
import net.minecraft.commands.arguments.coordinates.Vec3Argument;
|
|
import net.minecraft.commands.synchronization.SuggestionProviders;
|
|
import net.minecraft.core.Holder;
|
|
import net.minecraft.network.chat.Component;
|
|
import net.minecraft.network.protocol.game.ClientboundSoundPacket;
|
|
import net.minecraft.resources.ResourceLocation;
|
|
import net.minecraft.server.level.ServerPlayer;
|
|
import net.minecraft.sounds.SoundEvent;
|
|
import net.minecraft.sounds.SoundSource;
|
|
import net.minecraft.util.Mth;
|
|
import net.minecraft.world.phys.Vec3;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
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, ResourceLocation> requiredArgumentBuilder = Commands.argument("sound", ResourceLocationArgument.id())
|
|
.suggests(SuggestionProviders.AVAILABLE_SOUNDS)
|
|
.executes(
|
|
commandContext -> playSound(
|
|
commandContext.getSource(),
|
|
getCallingPlayerAsCollection(commandContext.getSource().getPlayer()),
|
|
ResourceLocationArgument.getId(commandContext, "sound"),
|
|
SoundSource.MASTER,
|
|
commandContext.getSource().getPosition(),
|
|
1.0F,
|
|
1.0F,
|
|
0.0F
|
|
)
|
|
);
|
|
|
|
for (SoundSource soundSource : SoundSource.values()) {
|
|
requiredArgumentBuilder.then(source(soundSource));
|
|
}
|
|
|
|
dispatcher.register(Commands.literal("playsound").requires(commandSourceStack -> commandSourceStack.hasPermission(2)).then(requiredArgumentBuilder));
|
|
}
|
|
|
|
private static LiteralArgumentBuilder<CommandSourceStack> source(SoundSource category) {
|
|
return Commands.literal(category.getName())
|
|
.executes(
|
|
commandContext -> playSound(
|
|
commandContext.getSource(),
|
|
getCallingPlayerAsCollection(commandContext.getSource().getPlayer()),
|
|
ResourceLocationArgument.getId(commandContext, "sound"),
|
|
category,
|
|
commandContext.getSource().getPosition(),
|
|
1.0F,
|
|
1.0F,
|
|
0.0F
|
|
)
|
|
)
|
|
.then(
|
|
Commands.argument("targets", EntityArgument.players())
|
|
.executes(
|
|
commandContext -> playSound(
|
|
commandContext.getSource(),
|
|
EntityArgument.getPlayers(commandContext, "targets"),
|
|
ResourceLocationArgument.getId(commandContext, "sound"),
|
|
category,
|
|
commandContext.getSource().getPosition(),
|
|
1.0F,
|
|
1.0F,
|
|
0.0F
|
|
)
|
|
)
|
|
.then(
|
|
Commands.argument("pos", Vec3Argument.vec3())
|
|
.executes(
|
|
commandContext -> playSound(
|
|
commandContext.getSource(),
|
|
EntityArgument.getPlayers(commandContext, "targets"),
|
|
ResourceLocationArgument.getId(commandContext, "sound"),
|
|
category,
|
|
Vec3Argument.getVec3(commandContext, "pos"),
|
|
1.0F,
|
|
1.0F,
|
|
0.0F
|
|
)
|
|
)
|
|
.then(
|
|
Commands.argument("volume", FloatArgumentType.floatArg(0.0F))
|
|
.executes(
|
|
commandContext -> playSound(
|
|
commandContext.getSource(),
|
|
EntityArgument.getPlayers(commandContext, "targets"),
|
|
ResourceLocationArgument.getId(commandContext, "sound"),
|
|
category,
|
|
Vec3Argument.getVec3(commandContext, "pos"),
|
|
commandContext.<Float>getArgument("volume", Float.class),
|
|
1.0F,
|
|
0.0F
|
|
)
|
|
)
|
|
.then(
|
|
Commands.argument("pitch", FloatArgumentType.floatArg(0.0F, 2.0F))
|
|
.executes(
|
|
commandContext -> playSound(
|
|
commandContext.getSource(),
|
|
EntityArgument.getPlayers(commandContext, "targets"),
|
|
ResourceLocationArgument.getId(commandContext, "sound"),
|
|
category,
|
|
Vec3Argument.getVec3(commandContext, "pos"),
|
|
commandContext.<Float>getArgument("volume", Float.class),
|
|
commandContext.<Float>getArgument("pitch", Float.class),
|
|
0.0F
|
|
)
|
|
)
|
|
.then(
|
|
Commands.argument("minVolume", FloatArgumentType.floatArg(0.0F, 1.0F))
|
|
.executes(
|
|
commandContext -> playSound(
|
|
commandContext.getSource(),
|
|
EntityArgument.getPlayers(commandContext, "targets"),
|
|
ResourceLocationArgument.getId(commandContext, "sound"),
|
|
category,
|
|
Vec3Argument.getVec3(commandContext, "pos"),
|
|
commandContext.<Float>getArgument("volume", Float.class),
|
|
commandContext.<Float>getArgument("pitch", Float.class),
|
|
commandContext.<Float>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> targets,
|
|
ResourceLocation sound,
|
|
SoundSource category,
|
|
Vec3 pos,
|
|
float volume,
|
|
float pitch,
|
|
float minVolume
|
|
) throws CommandSyntaxException {
|
|
Holder<SoundEvent> holder = Holder.direct(SoundEvent.createVariableRangeEvent(sound));
|
|
double d = Mth.square(holder.value().getRange(volume));
|
|
int i = 0;
|
|
long l = source.getLevel().getRandom().nextLong();
|
|
|
|
for (ServerPlayer serverPlayer : targets) {
|
|
double e = pos.x - serverPlayer.getX();
|
|
double f = pos.y - serverPlayer.getY();
|
|
double g = pos.z - serverPlayer.getZ();
|
|
double h = e * e + f * f + g * g;
|
|
Vec3 vec3 = pos;
|
|
float j = volume;
|
|
if (h > d) {
|
|
if (minVolume <= 0.0F) {
|
|
continue;
|
|
}
|
|
|
|
double k = Math.sqrt(h);
|
|
vec3 = new Vec3(serverPlayer.getX() + e / k * 2.0, serverPlayer.getY() + f / k * 2.0, serverPlayer.getZ() + g / k * 2.0);
|
|
j = minVolume;
|
|
}
|
|
|
|
serverPlayer.connection.send(new ClientboundSoundPacket(holder, category, vec3.x(), vec3.y(), vec3.z(), j, pitch, l));
|
|
i++;
|
|
}
|
|
|
|
if (i == 0) {
|
|
throw ERROR_TOO_FAR.create();
|
|
} else {
|
|
if (targets.size() == 1) {
|
|
source.sendSuccess(
|
|
() -> Component.translatable(
|
|
"commands.playsound.success.single", Component.translationArg(sound), ((ServerPlayer)targets.iterator().next()).getDisplayName()
|
|
),
|
|
true
|
|
);
|
|
} else {
|
|
source.sendSuccess(() -> Component.translatable("commands.playsound.success.multiple", Component.translationArg(sound), targets.size()), true);
|
|
}
|
|
|
|
return i;
|
|
}
|
|
}
|
|
}
|