tutorial:commands
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
tutorial:commands [2019/07/29 19:19] – started fixing english errors but it's way too long lmao fudge | tutorial:commands [2019/08/22 03:55] – [A very basic command] Change ArgumentBuilders to CommandManager i509vcb | ||
---|---|---|---|
Line 16: | Line 16: | ||
Below are a few examples of how the commands can be registered. | Below are a few examples of how the commands can be registered. | ||
- | <code java> | + | <code java [enable_line_numbers=" |
CommandRegistry.INSTANCE.register(false, | CommandRegistry.INSTANCE.register(false, | ||
Line 33: | Line 33: | ||
Wait isn't this the exact same command from the Brigadier tutorial? Well yes it is but it is here to help explain the structure of a command. | Wait isn't this the exact same command from the Brigadier tutorial? Well yes it is but it is here to help explain the structure of a command. | ||
- | <code java> | + | <code java [enable_line_numbers=" |
// The root of the command. This must be a literal argument. | // The root of the command. This must be a literal argument. | ||
- | dispatcher.register(LiteralArgumentBuilder.literal(" | + | dispatcher.register(CommandManager.literal(" |
// Then add an argument named bar that is an integer | // Then add an argument named bar that is an integer | ||
- | .then(RequiredArgumentBuilder.argument(" | + | .then(CommandManager.argument(" |
// The command to be executed if the command " | // The command to be executed if the command " | ||
.executes(ctx -> { | .executes(ctx -> { | ||
Line 79: | Line 79: | ||
And your imports would look something like this: | And your imports would look something like this: | ||
- | <code java> | + | <code java [enable_line_numbers=" |
import static com.mojang.brigadier.arguments.StringArgumentType.getString; | import static com.mojang.brigadier.arguments.StringArgumentType.getString; | ||
import static com.mojang.brigadier.arguments.StringArgumentType.word; | import static com.mojang.brigadier.arguments.StringArgumentType.word; | ||
Line 104: | Line 104: | ||
The example below is a dynamically changing SuggestionProvider that lists several words for a StringArgumentType to demonstrate how it works: | The example below is a dynamically changing SuggestionProvider that lists several words for a StringArgumentType to demonstrate how it works: | ||
- | <code java> | + | <code java [enable_line_numbers=" |
public static SuggestionProvider< | public static SuggestionProvider< | ||
return (ctx, builder) -> getSuggestionsBuilder(builder, | return (ctx, builder) -> getSuggestionsBuilder(builder, | ||
Line 131: | Line 131: | ||
To use the suggestion you would append it right after the argument you want to recommend arguments for. This can be any argument and the normal client side exception popups will still work. Note this cannot be applied to literals. | To use the suggestion you would append it right after the argument you want to recommend arguments for. This can be any argument and the normal client side exception popups will still work. Note this cannot be applied to literals. | ||
- | <code java> | + | <code java [enable_line_numbers=" |
argument(argumentName, | argument(argumentName, | ||
.suggests(CompletionProviders.suggestedStrings()) | .suggests(CompletionProviders.suggestedStrings()) | ||
Line 143: | Line 143: | ||
For example this may look like the following: | For example this may look like the following: | ||
- | <code java> | + | <code java [enable_line_numbers=" |
dispatcher.register(literal(" | dispatcher.register(literal(" | ||
.requires(source -> source.hasPermissionLevel(4)) | .requires(source -> source.hasPermissionLevel(4)) | ||
Line 161: | Line 161: | ||
Below is a coin flip command to show an example of exceptions in use. | Below is a coin flip command to show an example of exceptions in use. | ||
- | <code java> | + | <code java [enable_line_numbers=" |
dispatcher.register(CommandManager.literal(" | dispatcher.register(CommandManager.literal(" | ||
.executes(ctx -> { | .executes(ctx -> { | ||
Line 176: | Line 176: | ||
Though you are not just limited to a single type of exception as Brigadier also supplies Dynamic exceptions. | Though you are not just limited to a single type of exception as Brigadier also supplies Dynamic exceptions. | ||
- | <code java> | + | <code java [enable_line_numbers=" |
DynamicCommandExceptionType used_name = new DynamicCommandExceptionType(name -> { | DynamicCommandExceptionType used_name = new DynamicCommandExceptionType(name -> { | ||
return new LiteralText(" | return new LiteralText(" | ||
Line 189: | Line 189: | ||
Redirects are Brigadier' | Redirects are Brigadier' | ||
- | <code java> | + | <code java [enable_line_numbers=" |
public static void register(CommandDispatcher< | public static void register(CommandDispatcher< | ||
LiteralCommandNode node = registerMain(dispatcher); | LiteralCommandNode node = registerMain(dispatcher); | ||
Line 210: | Line 210: | ||
The redirect registers a branch into the command tree, where the dispatcher is told when executing a redirected command to instead look on a different branch for more arguments and executes blocks. The literal argument that the redirect is placed on will also rename first literal on the targeted branch in the new command. | The redirect registers a branch into the command tree, where the dispatcher is told when executing a redirected command to instead look on a different branch for more arguments and executes blocks. The literal argument that the redirect is placed on will also rename first literal on the targeted branch in the new command. | ||
- | Redirects | + | Redirects |
- | + | ||
- | <code java> | + | |
- | public static void register(CommandDispatcher< | + | |
- | LiteralCommandNode node = registerShortened(dispatcher); | + | |
- | dispatcher.register(literal(" | + | |
- | .then(literal(" | + | |
- | .redirect(node))); | + | |
- | } | + | |
- | + | ||
- | public static LiteralCommandNode registerShortened(CommandDispatcher< | + | |
- | return dispatcher.register(literal(" | + | |
- | .then(argument(" | + | |
- | .executes(ctx -> execute(ctx)))); | + | |
- | } | + | |
- | </ | + | |
===== ServerCommandSource ===== | ===== ServerCommandSource ===== | ||
Line 231: | Line 216: | ||
What if you wanted a command that the CommandSource must be an entity to execute? The ServerCommandSource provides this option with a couple of methods | What if you wanted a command that the CommandSource must be an entity to execute? The ServerCommandSource provides this option with a couple of methods | ||
- | <code java> | + | <code java [enable_line_numbers=" |
ServerCommandSource source = ctx.getSource(); | ServerCommandSource source = ctx.getSource(); | ||
// Get the source. This will always work. | // Get the source. This will always work. | ||
Line 250: | Line 235: | ||
The ServerCommandSource also provides other information about the sender of the command. | The ServerCommandSource also provides other information about the sender of the command. | ||
- | <code java> | + | <code java [enable_line_numbers=" |
source.getPosition(); | source.getPosition(); | ||
// Get's the sender' | // Get's the sender' | ||
Line 276: | Line 261: | ||
=== Broadcast a message === | === Broadcast a message === | ||
- | <code java> | + | <code java [enable_line_numbers=" |
public static void register(CommandDispatcher< | public static void register(CommandDispatcher< | ||
dispatcher.register(literal(" | dispatcher.register(literal(" | ||
Line 297: | Line 282: | ||
First the basic code where we register " | First the basic code where we register " | ||
- | <code java> | + | <code java [enable_line_numbers=" |
public static LiteralCommandNode register(CommandDispatcher< | public static LiteralCommandNode register(CommandDispatcher< | ||
return dispatcher.register(literal(" | return dispatcher.register(literal(" | ||
Line 306: | Line 291: | ||
Then since we only want to give to players, we check if the CommandSource is a player. But we can use '' | Then since we only want to give to players, we check if the CommandSource is a player. But we can use '' | ||
- | <code java> | + | <code java [enable_line_numbers=" |
public static int giveDiamond(CommandContext< | public static int giveDiamond(CommandContext< | ||
ServerCommandSource source = ctx.getSource(); | ServerCommandSource source = ctx.getSource(); | ||
Line 315: | Line 300: | ||
Then we add to the player' | Then we add to the player' | ||
- | <code java> | + | <code java [enable_line_numbers=" |
if(!player.inventory.insertStack(new ItemStack(Items.DIAMOND))){ | if(!player.inventory.insertStack(new ItemStack(Items.DIAMOND))){ | ||
throw new SimpleCommandExceptionType(new TranslateableText(" | throw new SimpleCommandExceptionType(new TranslateableText(" | ||
Line 331: | Line 316: | ||
First create an entry into the CommandDispatcher that takes a literal of antioch with an optional argument of the location to summon the entity at. | First create an entry into the CommandDispatcher that takes a literal of antioch with an optional argument of the location to summon the entity at. | ||
- | <code java> | + | <code java [enable_line_numbers=" |
public static void register(CommandDispatcher< | public static void register(CommandDispatcher< | ||
dispatcher.register(literal(" | dispatcher.register(literal(" | ||
Line 342: | Line 327: | ||
Then the creation and messages behind the joke. | Then the creation and messages behind the joke. | ||
- | <code java> | + | <code java [enable_line_numbers=" |
public static int antioch(ServerCommandSource source, BlockPos blockPos) throws CommandSyntaxException { | public static int antioch(ServerCommandSource source, BlockPos blockPos) throws CommandSyntaxException { | ||
Line 356: | Line 341: | ||
return 1; | return 1; | ||
} | } | ||
+ | </ | ||
+ | |||
+ | === Finding Biomes via Command === | ||
+ | |||
+ | This example shows examples of redirects, exceptions, suggestions and a tiny bit of text. Note this command when used works but can take a bit of time to work similarly to ''/ | ||
+ | <code java [enable_line_numbers=" | ||
+ | public class CommandLocateBiome { | ||
+ | // First make method to register | ||
+ | public static void register(CommandDispatcher< | ||
+ | LiteralCommandNode< | ||
+ | .then(argument(" | ||
+ | .then(argument(" | ||
+ | .executes(ctx -> execute(ctx.getSource(), | ||
+ | .executes(ctx -> execute(ctx.getSource(), | ||
+ | // Register redirect | ||
+ | dispatcher.register(literal(" | ||
+ | .redirect(basenode)); | ||
+ | } | ||
+ | // Beginning of the method | ||
+ | private static int execute(ServerCommandSource source, Identifier biomeId, int range) throws CommandSyntaxException { | ||
+ | Biome biome = Registry.BIOME.get(biomeId); | ||
+ | | ||
+ | if(biome == null) { // Since the argument is an Identifier we need to check if the identifier actually exists in the registry | ||
+ | throw new SimpleCommandExceptionType(new TranslatableText(" | ||
+ | } | ||
+ | | ||
+ | List< | ||
+ | bio.add(biome); | ||
+ | | ||
+ | ServerWorld world = source.getWorld(); | ||
+ | | ||
+ | BiomeSource bsource = world.getChunkManager().getChunkGenerator().getBiomeSource(); | ||
+ | | ||
+ | BlockPos loc = new BlockPos(source.getPosition()); | ||
+ | // Now here is the heaviest part of the method. | ||
+ | BlockPos pos = bsource.locateBiome(loc.getX(), | ||
+ | | ||
+ | // Since this method can return null if it failed to find a biome | ||
+ | if(pos == null) { | ||
+ | throw new SimpleCommandExceptionType(new TranslatableText(" | ||
+ | } | ||
+ | | ||
+ | int distance = MathHelper.floor(getDistance(loc.getX(), | ||
+ | // Popup text that can suggest commands. This is the exact same system that /locate uses. | ||
+ | Text teleportButtonPopup = Texts.bracketed(new TranslatableText(" | ||
+ | style_1x.setColor(Formatting.GREEN).setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, | ||
+ | }); | ||
+ | | ||
+ | source.sendFeedback(new TranslatableText(" | ||
+ | |||
+ | return 1; | ||
+ | } | ||
+ | // Just a normal old 2d distance method. | ||
+ | private static float getDistance(int int_1, int int_2, int int_3, int int_4) { | ||
+ | int int_5 = int_3 - int_1; | ||
+ | int int_6 = int_4 - int_2; | ||
+ | |||
+ | return MathHelper.sqrt((float) (int_5 * int_5 + int_6 * int_6)); | ||
+ | } | ||
+ | | ||
+ | | ||
+ | |||
+ | public static class BiomeCompletionProvider { | ||
+ | // This provides suggestions of what biomes can be selected. Since this uses the registry, mods that add new biomes will work without modification. | ||
+ | public static final SuggestionProvider< | ||
+ | Registry.BIOME.getIds().stream().forEach(identifier -> builder.suggest(identifier.toString(), | ||
+ | return builder.buildFuture(); | ||
+ | }); | ||
+ | | ||
+ | } | ||
</ | </ | ||
tutorial/commands.txt · Last modified: 2024/02/23 14:22 by allen1210