132 lines
4.5 KiB
Java
132 lines
4.5 KiB
Java
package net.minecraft.server.commands;
|
|
|
|
import com.mojang.brigadier.CommandDispatcher;
|
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
|
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
|
import java.util.function.Predicate;
|
|
import net.minecraft.commands.CommandBuildContext;
|
|
import net.minecraft.commands.CommandSourceStack;
|
|
import net.minecraft.commands.Commands;
|
|
import net.minecraft.commands.arguments.blocks.BlockInput;
|
|
import net.minecraft.commands.arguments.blocks.BlockStateArgument;
|
|
import net.minecraft.commands.arguments.coordinates.BlockPosArgument;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.network.chat.Component;
|
|
import net.minecraft.server.level.ServerLevel;
|
|
import net.minecraft.world.level.block.state.pattern.BlockInWorld;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
public class SetBlockCommand {
|
|
private static final SimpleCommandExceptionType ERROR_FAILED = new SimpleCommandExceptionType(Component.translatable("commands.setblock.failed"));
|
|
|
|
public static void register(CommandDispatcher<CommandSourceStack> dispatcher, CommandBuildContext buildContext) {
|
|
Predicate<BlockInWorld> predicate = blockInWorld -> blockInWorld.getLevel().isEmptyBlock(blockInWorld.getPos());
|
|
dispatcher.register(
|
|
Commands.literal("setblock")
|
|
.requires(commandSourceStack -> commandSourceStack.hasPermission(2))
|
|
.then(
|
|
Commands.argument("pos", BlockPosArgument.blockPos())
|
|
.then(
|
|
Commands.argument("block", BlockStateArgument.block(buildContext))
|
|
.executes(
|
|
commandContext -> setBlock(
|
|
commandContext.getSource(),
|
|
BlockPosArgument.getLoadedBlockPos(commandContext, "pos"),
|
|
BlockStateArgument.getBlock(commandContext, "block"),
|
|
SetBlockCommand.Mode.REPLACE,
|
|
null,
|
|
false
|
|
)
|
|
)
|
|
.then(
|
|
Commands.literal("destroy")
|
|
.executes(
|
|
commandContext -> setBlock(
|
|
commandContext.getSource(),
|
|
BlockPosArgument.getLoadedBlockPos(commandContext, "pos"),
|
|
BlockStateArgument.getBlock(commandContext, "block"),
|
|
SetBlockCommand.Mode.DESTROY,
|
|
null,
|
|
false
|
|
)
|
|
)
|
|
)
|
|
.then(
|
|
Commands.literal("keep")
|
|
.executes(
|
|
commandContext -> setBlock(
|
|
commandContext.getSource(),
|
|
BlockPosArgument.getLoadedBlockPos(commandContext, "pos"),
|
|
BlockStateArgument.getBlock(commandContext, "block"),
|
|
SetBlockCommand.Mode.REPLACE,
|
|
predicate,
|
|
false
|
|
)
|
|
)
|
|
)
|
|
.then(
|
|
Commands.literal("replace")
|
|
.executes(
|
|
commandContext -> setBlock(
|
|
commandContext.getSource(),
|
|
BlockPosArgument.getLoadedBlockPos(commandContext, "pos"),
|
|
BlockStateArgument.getBlock(commandContext, "block"),
|
|
SetBlockCommand.Mode.REPLACE,
|
|
null,
|
|
false
|
|
)
|
|
)
|
|
)
|
|
.then(
|
|
Commands.literal("strict")
|
|
.executes(
|
|
commandContext -> setBlock(
|
|
commandContext.getSource(),
|
|
BlockPosArgument.getLoadedBlockPos(commandContext, "pos"),
|
|
BlockStateArgument.getBlock(commandContext, "block"),
|
|
SetBlockCommand.Mode.REPLACE,
|
|
null,
|
|
true
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
);
|
|
}
|
|
|
|
private static int setBlock(
|
|
CommandSourceStack source, BlockPos pos, BlockInput block, SetBlockCommand.Mode mode, @Nullable Predicate<BlockInWorld> filter, boolean strict
|
|
) throws CommandSyntaxException {
|
|
ServerLevel serverLevel = source.getLevel();
|
|
if (serverLevel.isDebug()) {
|
|
throw ERROR_FAILED.create();
|
|
} else if (filter != null && !filter.test(new BlockInWorld(serverLevel, pos, true))) {
|
|
throw ERROR_FAILED.create();
|
|
} else {
|
|
boolean bl;
|
|
if (mode == SetBlockCommand.Mode.DESTROY) {
|
|
serverLevel.destroyBlock(pos, true);
|
|
bl = !block.getState().isAir() || !serverLevel.getBlockState(pos).isAir();
|
|
} else {
|
|
bl = true;
|
|
}
|
|
|
|
if (bl && !block.place(serverLevel, pos, 2 | (strict ? 816 : 256))) {
|
|
throw ERROR_FAILED.create();
|
|
} else {
|
|
if (!strict) {
|
|
serverLevel.updateNeighborsAt(pos, block.getState().getBlock());
|
|
}
|
|
|
|
source.sendSuccess(() -> Component.translatable("commands.setblock.success", pos.getX(), pos.getY(), pos.getZ()), true);
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static enum Mode {
|
|
REPLACE,
|
|
DESTROY;
|
|
}
|
|
}
|