关于协议:本文章的代码在“Creative Commons Zero v1.0”协议下共享,允许你在你自己的模组中使用本模组展示的代码示例。
====== 命令建议 ======
Brigadier 允许你为参数指定建议。在 Minecraft 中,这些建议会在玩家输入命令时发送至客户端。
===== 建议提供器 =====
“建议提供器”(''SuggestionProvider'')用于制作将会发送至客户端的建议的列表。建议提供器是一个函数性接口,接收一个 ''CommandContext'' 和一个 ''SuggestionBuilder'' 并返回一些 ''Suggestions''。''SuggestionProvider'' 返回一个 [[https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/util/concurrent/CompletableFuture.html|CompletableFuture]],因为这些建议并不一定立即可用。
命令的建议是带有环境的,因为建议提供器给予你当前的命令环境。
===== 示例建议提供器 =====
假设你需要建议实体能够拥有的所有属性。
class AttributeSuggestionProvider implements SuggestionProvider {
@Override
public CompletableFuture getSuggestions(CommandContext context, SuggestionsBuilder builder) throws CommandSyntaxException {
Identifier entityTypeId = context.getArgument("type", Identifier.class);
...
因为我们有命令环境,我们可以此建议提供器所对应的参数之前的所有参数。
Next is a bunch of boilerplate code
class AttributeSuggestionProvider implements SuggestionProvider {
@Override
public CompletableFuture getSuggestions(CommandContext context, SuggestionsBuilder builder) {
Identifier entityTypeId = context.getArgument("type", Identifier.class);
EntityType> entityType = Registries.ENTITY_TYPE.getOrEmpty(entityTypeId).orElse(null);
// 对于 1.19.3 之前的版本,请使用 ''Registry.ENTITY_TYPE''。
if (!DefaultAttributeContainer.hasDefinitionFor(entityType)) {
// TODO: 失败时
}
DefaultAttributeContainer attributeContainer = DefaultAttributeRegistry.get(entityType);
// 你会需要 mixin 来得到这个“instance map”。在本教程中,假设我们可以访问它。
for (EntityAttribute attribute : attributeContainer.instances().keySet()) {
Identifier attributeId = Registries.ATTRIBUTE.getId(attribute);
if (attributeId != null) {
...
为了让建议出现在客户端上,你必须给 builder 添加建议,方法就是使用其 ''suggest'' 方法。有些会处理数字,有些则显示一个提示。
for (EntityAttribute attribute : attributeContainer.instances().keySet()) {
Identifier attributeId = Registries.ATTRIBUTE.getId(attribute);
if (attributeId != null) {
builder.suggest(attributeId.toString());
}
}
你还可以使用 ''add(SuggestionBuilder)'' 方法让结果与另一个 suggestion builder 结合起来。
最后,你需要将需要返回的建议 build 了,方法就是使用 ''buildFuture'' 方法。
return builder.buildFuture();
最终的结果:
class AttributeSuggestionProvider implements SuggestionProvider {
@Override
public CompletableFuture getSuggestions(CommandContext context, SuggestionsBuilder builder) {
Identifier entityTypeId = context.getArgument("type", Identifier.class);
EntityType> entityType = Registries.ENTITY_TYPE.getOrEmpty(entityTypeId).orElse(null);
if (!DefaultAttributeContainer.hasDefinitionFor(entityType)) {
// TODO: 失败时
}
DefaultAttributeContainer attributeContainer = DefaultAttributeRegistry.get(entityType);
// 你会需要 mixin 来得到这个“instance map”。在本教程中,假设我们可以访问它。
for (EntityAttribute attribute : attributeContainer.instances().keySet()) {
Identifier attributeId = Registries.ATTRIBUTE.getId(attribute);
if (attributeId != null) {
builder.suggest(attributeId.toString());
}
}
return builder.buildFuture();
}
}
===== 使用建议提供器 =====
现在你有了建议提供器,是时候使用这个提供,注意这个提供器对纯文本参数(literal)不适用。
注册参数时,你可以使用 ''suggests(SuggestionProvider)'' 方法可设置建议提供器。这会应用到 ''RequiredArgumentBuilder'',就像下面这样:
argument(argumentName, word())
.suggests(CompletionProviders.suggestedStrings())
.then(/* 剩余的命令 */));
===== 内置的建议提供器 =====
Minecraft 包括了几个内置的建议提供器,包括:
^ 类型 ^ 字段/方法 ^
| 可召唤的实体 | ''SuggestionProviders.SUMMONABLE_ENTITIES'' |
| 可用的声音 | ''SuggestionProviders.AVAILABLE_SOUNDS'' |
| 战利品表 | ''LootCommand.SUGGESTION_PROVIDER'' |
| 生物群系 | ''SuggestionProviders.ALL_BIOMES'' |
===== CommandSource 中的工具 =====
''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.
===== 其他命令教程 =====
[[commands#高级概念|点击此处查看其他命令教程]]。