User Tools

Site Tools


tutorial:command_suggestions

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
tutorial:command_suggestions [2021/09/17 04:49] – ↷ Page moved and renamed from tutorials:commands:suggestions to tutorial:command_suggestions solidblocktutorial:command_suggestions [2023/11/18 12:06] (current) solidblock
Line 3: Line 3:
 ====== Command Suggestions ====== ====== Command Suggestions ======
  
-Brigadier allows specification of custom suggestions for arguments. In Minecraft, these suggestions are sent to the client as a user is typing out the command.+Brigadier allows specification of custom suggestions for arguments. In Minecraft, these suggestions are sent to the client as a user is typing out the command. Besides, some argument types can have their default suggestion providers calculated directly in client, which is not focused in this article.
  
 ===== Suggestion Providers ===== ===== Suggestion Providers =====
  
-A ''SuggestionProvider'' is used to make a list of suggestions that will be sent to the client. A suggestion provider is a functional interface that takes a ''CommandContext'' and a ''SuggestionBuilder'' and returns some ''Suggestions''. The ''SuggestionProvider'' returns a [[https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/util/concurrent/CompletableFuture.html|CompletableFuture]] as the suggestions may not be available immediately. +A ''SuggestionProvider'' is used to make a list of suggestions that will be sent to the client. A suggestion provider is a functional interface that takes a ''CommandContext'' and a ''SuggestionBuilder'' and returns some ''Suggestions''. The ''SuggestionProvider'' returns a ''CompletableFuture'' as the suggestions may not be available immediately.
  
 Suggestions can be contextual since a suggestion provider gives you access to the current command context. Suggestions can be contextual since a suggestion provider gives you access to the current command context.
Line 14: Line 13:
 ===== An example suggestion provider ===== ===== An example suggestion provider =====
  
-For example lets say you want to suggest all attributes an entity could have.+For example let'say you want to suggest all attributes an entity could have.
  
 <code java [enable_line_numbers="true", highlight_lines_extra="4"]> <code java [enable_line_numbers="true", highlight_lines_extra="4"]>
-class AttributeSuggestionProvider implements SuggestionProvider<ServerCommandSource> {+public class AttributeSuggestionProvider implements SuggestionProvider<ServerCommandSource> {
     @Override     @Override
     public CompletableFuture<Suggestions> getSuggestions(CommandContext<ServerCommandSource> context, SuggestionsBuilder builder) throws CommandSyntaxException {     public CompletableFuture<Suggestions> getSuggestions(CommandContext<ServerCommandSource> context, SuggestionsBuilder builder) throws CommandSyntaxException {
Line 29: Line 28:
  
 <code java [enable_line_numbers="true"]> <code java [enable_line_numbers="true"]>
-class AttributeSuggestionProvider implements SuggestionProvider<ServerCommandSource> {+public class AttributeSuggestionProvider implements SuggestionProvider<ServerCommandSource> {
     @Override     @Override
     public CompletableFuture<Suggestions> getSuggestions(CommandContext<ServerCommandSource> context, SuggestionsBuilder builder) {     public CompletableFuture<Suggestions> getSuggestions(CommandContext<ServerCommandSource> context, SuggestionsBuilder builder) {
         Identifier entityTypeId = context.getArgument("type", Identifier.class);         Identifier entityTypeId = context.getArgument("type", Identifier.class);
-        EntityType<?> entityType = Registry.ENTITY_TYPE.getOrEmpty(entityTypeId).orElse(null);+        EntityType<?> entityType = Registries.ENTITY_TYPE.getOrEmpty(entityTypeId).orElse(null); 
 +        // For versions before 1.19.3, use ''Registry.ENTITY_TYPE'' instead.
                  
         if (!DefaultAttributeContainer.hasDefinitionFor(entityType)) {         if (!DefaultAttributeContainer.hasDefinitionFor(entityType)) {
-            // TODO: Fail+            return Suggestions.empty()
         }         }
                  
         DefaultAttributeContainer attributeContainer = DefaultAttributeRegistry.get(entityType);         DefaultAttributeContainer attributeContainer = DefaultAttributeRegistry.get(entityType);
         // You will need mixin to get the 'instances map'. Lets assume we can just access it for the sake of the tutorial         // You will need mixin to get the 'instances map'. Lets assume we can just access it for the sake of the tutorial
-        for (EntityAttribute attribute : attributeContainer.instances().keySet()) { +        for (EntityAttribute attribute : attributeContainer.instances.keySet()) { 
-            Identifier attributeId = Registry.ATTRIBUTE.getId(attribute); +            Identifier attributeId = Registries.ATTRIBUTE.getId(attribute); 
-            if (attributeId != null) {+            if (attributeId != null && CommandSource.shouldSuggest(builder.getRemaining(), attributeId.toString())) {
             ...             ...
 </code> </code>
 +
 +The check of ''CommandSource.shouldSuggest'' is intended to suggest only results that match the inputed part, which is ''builder.getRemaining()'', which is the part between the beginning of the argument and the cursor.
  
 In order to have a suggestion appear on the client, you must add the suggestion to the builder. This can be done through one of the ''suggest'' methods. Some of these handle numbers, and a few support showing a tooltip. In order to have a suggestion appear on the client, you must add the suggestion to the builder. This can be done through one of the ''suggest'' methods. Some of these handle numbers, and a few support showing a tooltip.
  
 <code java [enable_line_numbers="true", highlight_lines_extra="4"]> <code java [enable_line_numbers="true", highlight_lines_extra="4"]>
-for (EntityAttribute attribute : attributeContainer.instances().keySet()) { +        for (EntityAttribute attribute : attributeContainer.instances.keySet()) { 
-    Identifier attributeId = Registry.ATTRIBUTE.getId(attribute); +            Identifier attributeId = Registries.ATTRIBUTE.getId(attribute); 
-    if (attributeId != null) { +            if (attributeId != null && CommandSource.shouldSuggest(builder.getRemaining(), attributeId.toString())) { 
-       builder.suggest(attributeId.toString()); +               builder.suggest(attributeId.toString()); 
-    +            
-}+        }
 </code> </code>
  
Line 63: Line 65:
  
 <code java [enable_line_numbers="true"]> <code java [enable_line_numbers="true"]>
-return builder.buildFuture();+        return builder.buildFuture();
 </code> </code>
  
Line 69: Line 71:
  
 <code java [enable_line_numbers="true"]> <code java [enable_line_numbers="true"]>
-class AttributeSuggestionProvider implements SuggestionProvider<ServerCommandSource> {+public class AttributeSuggestionProvider implements SuggestionProvider<ServerCommandSource> {
     @Override     @Override
     public CompletableFuture<Suggestions> getSuggestions(CommandContext<ServerCommandSource> context, SuggestionsBuilder builder) {     public CompletableFuture<Suggestions> getSuggestions(CommandContext<ServerCommandSource> context, SuggestionsBuilder builder) {
         Identifier entityTypeId = context.getArgument("type", Identifier.class);         Identifier entityTypeId = context.getArgument("type", Identifier.class);
-        EntityType<?> entityType = Registry.ENTITY_TYPE.getOrEmpty(entityTypeId).orElse(null);+        EntityType<?> entityType = Registries.ENTITY_TYPE.getOrEmpty(entityTypeId).orElse(null);
                  
         if (!DefaultAttributeContainer.hasDefinitionFor(entityType)) {         if (!DefaultAttributeContainer.hasDefinitionFor(entityType)) {
-            // TODO: Fail+            return Suggestions.empty()
         }         }
                  
         DefaultAttributeContainer attributeContainer = DefaultAttributeRegistry.get(entityType);         DefaultAttributeContainer attributeContainer = DefaultAttributeRegistry.get(entityType);
         // You will need mixin to get the 'instances map'. Lets assume we can just access it for the sake of the tutorial         // You will need mixin to get the 'instances map'. Lets assume we can just access it for the sake of the tutorial
-        for (EntityAttribute attribute : attributeContainer.instances().keySet()) { +        for (EntityAttribute attribute : attributeContainer.instances.keySet()) { 
-            Identifier attributeId = Registry.ATTRIBUTE.getId(attribute); +            Identifier attributeId = Registries.ATTRIBUTE.getId(attribute); 
-            if (attributeId != null) {+            if (attributeId != null && CommandSource.shouldSuggest(builder.getRemaining(), attributeId.toString())) {
                 builder.suggest(attributeId.toString());                 builder.suggest(attributeId.toString());
             }             }
Line 109: Line 111:
  
 ^ Type                ^ Field/Method                            ^ ^ Type                ^ Field/Method                            ^
-| Summonable entities | SuggestionProviders.SUMMONABLE_ENTITIES | +| Summonable entities | ''SuggestionProviders.SUMMONABLE_ENTITIES'' 
-| Available sounds    | SuggestionProviders.AVAILABLE_SOUNDS    | +| Available sounds    | ''SuggestionProviders.AVAILABLE_SOUNDS''    | 
-| Loot Tables         | LootCommand.SUGGESTION_PROVIDER         | +| Loot Tables         ''LootCommand.SUGGESTION_PROVIDER''         | 
-| Biomes              | SuggestionProviders.ALL_BIOMES          |+| Biomes              | ''SuggestionProviders.ALL_BIOMES''          |
  
 ===== Utilities in CommandSource ===== ===== Utilities in CommandSource =====
  
-''CommandSource'' contains a few utility methods to help remove boilerplate when making the suggestions. +''CommandSource'' contains a few utility methods to help remove boilerplate when making the suggestions. Many of the utility methods involve returning completed suggestions from a ''Stream'' or ''Set'' of Identifiers, positions or matching strings
-Many of the utility methods involve returning completed suggestions from a ''Stream'' or ''Set'' of Identifiers, positions or matching strings.+ 
 +In the example above, we can simplify it to: 
 +<code java> 
 +        DefaultAttributeContainer attributeContainer = DefaultAttributeRegistry.get(entityType); 
 +        // You will need mixin to get the 'instances map'. Lets assume we can just access it for the sake of the tutorial 
 +        return CommandSource.suggestMatching(Iterables.transform(attributeContainer.instances.keySet(), Identifier::toString), builder); 
 +         
 +        // you can also use stream: 
 +        return CommandSource.suggestMatching(attributeContainer.instances.keySet().stream().map(Identifier::toString), builder); 
 +</code> 
 + 
 +===== Builder offsets ===== 
 +Most cases the suggestions appear from the beginning of the argument, such as the example above. However, sometimes suggestions appear in the middle of the argument. For example, in a block state argument, you input ''oak_stairs['', and then suggestions should be property names of the block (''facing'', ''waterlogged'', ...). The suggestion appears after the left square bracket. 
 + 
 +In this case, you should use ''builder.createOffset(offset)'', where ''offset'' is the position of the new suggestion builder.
  
 ===== Other command tutorials ===== ===== Other command tutorials =====
  
-[[tutorial:commands#advanced_concepts|Click here]] to view the other command tutorials.+For other command tutorials, see the sidebar.
tutorial/command_suggestions.1631854158.txt.gz · Last modified: 2021/09/17 04:49 by solidblock