EntitySelectorOptions.java

net.minecraft.commands.arguments.selector.options.EntitySelectorOptions

信息

  • 全限定名:net.minecraft.commands.arguments.selector.options.EntitySelectorOptions
  • 类型:public class
  • 包:net.minecraft.commands.arguments.selector.options
  • 源码路径:src/main/java/net/minecraft/commands/arguments/selector/options/EntitySelectorOptions.java
  • 起始行号:L54
  • 职责:

    TODO

字段/常量

  • LOGGER

    • 类型: Logger
    • 修饰符: private static final
    • 源码定位: L55
    • 说明:

      TODO

  • OPTIONS

    • 类型: Map<String,EntitySelectorOptions.Option>
    • 修饰符: private static final
    • 源码定位: L56
    • 说明:

      TODO

  • ERROR_UNKNOWN_OPTION

    • 类型: DynamicCommandExceptionType
    • 修饰符: public static final
    • 源码定位: L57
    • 说明:

      TODO

  • ERROR_INAPPLICABLE_OPTION

    • 类型: DynamicCommandExceptionType
    • 修饰符: public static final
    • 源码定位: L60
    • 说明:

      TODO

  • ERROR_RANGE_NEGATIVE

    • 类型: SimpleCommandExceptionType
    • 修饰符: public static final
    • 源码定位: L63
    • 说明:

      TODO

  • ERROR_LEVEL_NEGATIVE

    • 类型: SimpleCommandExceptionType
    • 修饰符: public static final
    • 源码定位: L66
    • 说明:

      TODO

  • ERROR_LIMIT_TOO_SMALL

    • 类型: SimpleCommandExceptionType
    • 修饰符: public static final
    • 源码定位: L69
    • 说明:

      TODO

  • ERROR_SORT_UNKNOWN

    • 类型: DynamicCommandExceptionType
    • 修饰符: public static final
    • 源码定位: L72
    • 说明:

      TODO

  • ERROR_GAME_MODE_INVALID

    • 类型: DynamicCommandExceptionType
    • 修饰符: public static final
    • 源码定位: L75
    • 说明:

      TODO

  • ERROR_ENTITY_TYPE_INVALID

    • 类型: DynamicCommandExceptionType
    • 修饰符: public static final
    • 源码定位: L78
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.commands.arguments.selector.options.EntitySelectorOptions.Modifier

    • 类型: interface
    • 修饰符: public
    • 源码定位: L522
    • 说明:

      TODO

  • net.minecraft.commands.arguments.selector.options.EntitySelectorOptions.Option

    • 类型: record
    • 修饰符: private
    • 源码定位: L526
    • 说明:

      TODO

构造器

方法

下面的方法块按源码顺序生成。

private static void register(String name, EntitySelectorOptions.Modifier modifier, Predicate<EntitySelectorParser> predicate, Component description) @ L82

  • 方法名:register
  • 源码定位:L82
  • 返回类型:void
  • 修饰符:private static

参数:

  • name: String
  • modifier: EntitySelectorOptions.Modifier
  • predicate: Predicate
  • description: Component

说明:

TODO

public static void bootStrap() @ L86

  • 方法名:bootStrap
  • 源码定位:L86
  • 返回类型:void
  • 修饰符:public static

参数:

说明:

TODO

public static EntitySelectorOptions.Modifier get(EntitySelectorParser parser, String key, int start) @ L497

  • 方法名:get
  • 源码定位:L497
  • 返回类型:EntitySelectorOptions.Modifier
  • 修饰符:public static

参数:

  • parser: EntitySelectorParser
  • key: String
  • start: int

说明:

TODO

public static void suggestNames(EntitySelectorParser parser, SuggestionsBuilder builder) @ L511

  • 方法名:suggestNames
  • 源码定位:L511
  • 返回类型:void
  • 修饰符:public static

参数:

  • parser: EntitySelectorParser
  • builder: SuggestionsBuilder

说明:

TODO

代码

public class EntitySelectorOptions {
    private static final Logger LOGGER = LogUtils.getLogger();
    private static final Map<String, EntitySelectorOptions.Option> OPTIONS = Maps.newHashMap();
    public static final DynamicCommandExceptionType ERROR_UNKNOWN_OPTION = new DynamicCommandExceptionType(
        name -> Component.translatableEscape("argument.entity.options.unknown", name)
    );
    public static final DynamicCommandExceptionType ERROR_INAPPLICABLE_OPTION = new DynamicCommandExceptionType(
        name -> Component.translatableEscape("argument.entity.options.inapplicable", name)
    );
    public static final SimpleCommandExceptionType ERROR_RANGE_NEGATIVE = new SimpleCommandExceptionType(
        Component.translatable("argument.entity.options.distance.negative")
    );
    public static final SimpleCommandExceptionType ERROR_LEVEL_NEGATIVE = new SimpleCommandExceptionType(
        Component.translatable("argument.entity.options.level.negative")
    );
    public static final SimpleCommandExceptionType ERROR_LIMIT_TOO_SMALL = new SimpleCommandExceptionType(
        Component.translatable("argument.entity.options.limit.toosmall")
    );
    public static final DynamicCommandExceptionType ERROR_SORT_UNKNOWN = new DynamicCommandExceptionType(
        name -> Component.translatableEscape("argument.entity.options.sort.irreversible", name)
    );
    public static final DynamicCommandExceptionType ERROR_GAME_MODE_INVALID = new DynamicCommandExceptionType(
        name -> Component.translatableEscape("argument.entity.options.mode.invalid", name)
    );
    public static final DynamicCommandExceptionType ERROR_ENTITY_TYPE_INVALID = new DynamicCommandExceptionType(
        type -> Component.translatableEscape("argument.entity.options.type.invalid", type)
    );
 
    private static void register(String name, EntitySelectorOptions.Modifier modifier, Predicate<EntitySelectorParser> predicate, Component description) {
        OPTIONS.put(name, new EntitySelectorOptions.Option(modifier, predicate, description));
    }
 
    public static void bootStrap() {
        if (OPTIONS.isEmpty()) {
            register("name", parser -> {
                int start = parser.getReader().getCursor();
                boolean not = parser.shouldInvertValue();
                String name = parser.getReader().readString();
                if (parser.hasNameNotEquals() && !not) {
                    parser.getReader().setCursor(start);
                    throw ERROR_INAPPLICABLE_OPTION.createWithContext(parser.getReader(), "name");
                } else {
                    if (not) {
                        parser.setHasNameNotEquals(true);
                    } else {
                        parser.setHasNameEquals(true);
                    }
 
                    parser.addPredicate(e -> e.getPlainTextName().equals(name) != not);
                }
            }, s -> !s.hasNameEquals(), Component.translatable("argument.entity.options.name.description"));
            register("distance", parser -> {
                int start = parser.getReader().getCursor();
                MinMaxBounds.Doubles value = MinMaxBounds.Doubles.fromReader(parser.getReader());
                if ((!value.min().isPresent() || !((Double)value.min().get() < 0.0)) && (!value.max().isPresent() || !((Double)value.max().get() < 0.0))) {
                    parser.setDistance(value);
                    parser.setWorldLimited();
                } else {
                    parser.getReader().setCursor(start);
                    throw ERROR_RANGE_NEGATIVE.createWithContext(parser.getReader());
                }
            }, s -> s.getDistance() == null, Component.translatable("argument.entity.options.distance.description"));
            register("level", parser -> {
                int start = parser.getReader().getCursor();
                MinMaxBounds.Ints value = MinMaxBounds.Ints.fromReader(parser.getReader());
                if ((!value.min().isPresent() || (Integer)value.min().get() >= 0) && (!value.max().isPresent() || (Integer)value.max().get() >= 0)) {
                    parser.setLevel(value);
                    parser.setIncludesEntities(false);
                } else {
                    parser.getReader().setCursor(start);
                    throw ERROR_LEVEL_NEGATIVE.createWithContext(parser.getReader());
                }
            }, s -> s.getLevel() == null, Component.translatable("argument.entity.options.level.description"));
            register("x", parser -> {
                parser.setWorldLimited();
                parser.setX(parser.getReader().readDouble());
            }, s -> s.getX() == null, Component.translatable("argument.entity.options.x.description"));
            register("y", parser -> {
                parser.setWorldLimited();
                parser.setY(parser.getReader().readDouble());
            }, s -> s.getY() == null, Component.translatable("argument.entity.options.y.description"));
            register("z", parser -> {
                parser.setWorldLimited();
                parser.setZ(parser.getReader().readDouble());
            }, s -> s.getZ() == null, Component.translatable("argument.entity.options.z.description"));
            register("dx", parser -> {
                parser.setWorldLimited();
                parser.setDeltaX(parser.getReader().readDouble());
            }, s -> s.getDeltaX() == null, Component.translatable("argument.entity.options.dx.description"));
            register("dy", parser -> {
                parser.setWorldLimited();
                parser.setDeltaY(parser.getReader().readDouble());
            }, s -> s.getDeltaY() == null, Component.translatable("argument.entity.options.dy.description"));
            register("dz", parser -> {
                parser.setWorldLimited();
                parser.setDeltaZ(parser.getReader().readDouble());
            }, s -> s.getDeltaZ() == null, Component.translatable("argument.entity.options.dz.description"));
            register(
                "x_rotation",
                parser -> parser.setRotX(MinMaxBounds.FloatDegrees.fromReader(parser.getReader())),
                s -> s.getRotX() == null,
                Component.translatable("argument.entity.options.x_rotation.description")
            );
            register(
                "y_rotation",
                parser -> parser.setRotY(MinMaxBounds.FloatDegrees.fromReader(parser.getReader())),
                s -> s.getRotY() == null,
                Component.translatable("argument.entity.options.y_rotation.description")
            );
            register("limit", parser -> {
                int start = parser.getReader().getCursor();
                int count = parser.getReader().readInt();
                if (count < 1) {
                    parser.getReader().setCursor(start);
                    throw ERROR_LIMIT_TOO_SMALL.createWithContext(parser.getReader());
                } else {
                    parser.setMaxResults(count);
                    parser.setLimited(true);
                }
            }, s -> !s.isCurrentEntity() && !s.isLimited(), Component.translatable("argument.entity.options.limit.description"));
            register("sort", parser -> {
                int start = parser.getReader().getCursor();
                String name = parser.getReader().readUnquotedString();
                parser.setSuggestions((b, n) -> SharedSuggestionProvider.suggest(Arrays.asList("nearest", "furthest", "random", "arbitrary"), b));
 
                parser.setOrder(switch (name) {
                    case "nearest" -> EntitySelectorParser.ORDER_NEAREST;
                    case "furthest" -> EntitySelectorParser.ORDER_FURTHEST;
                    case "random" -> EntitySelectorParser.ORDER_RANDOM;
                    case "arbitrary" -> EntitySelector.ORDER_ARBITRARY;
                    default -> {
                        parser.getReader().setCursor(start);
                        throw ERROR_SORT_UNKNOWN.createWithContext(parser.getReader(), name);
                    }
                });
                parser.setSorted(true);
            }, s -> !s.isCurrentEntity() && !s.isSorted(), Component.translatable("argument.entity.options.sort.description"));
            register("gamemode", parser -> {
                parser.setSuggestions((b, m) -> {
                    String prefix = b.getRemaining().toLowerCase(Locale.ROOT);
                    boolean addNormal = !parser.hasGamemodeNotEquals();
                    boolean addInverted = true;
                    if (!prefix.isEmpty()) {
                        if (prefix.charAt(0) == '!') {
                            addNormal = false;
                            prefix = prefix.substring(1);
                        } else {
                            addInverted = false;
                        }
                    }
 
                    for (GameType type : GameType.values()) {
                        if (type.getName().toLowerCase(Locale.ROOT).startsWith(prefix)) {
                            if (addInverted) {
                                b.suggest("!" + type.getName());
                            }
 
                            if (addNormal) {
                                b.suggest(type.getName());
                            }
                        }
                    }
 
                    return b.buildFuture();
                });
                int start = parser.getReader().getCursor();
                boolean inverted = parser.shouldInvertValue();
                if (parser.hasGamemodeNotEquals() && !inverted) {
                    parser.getReader().setCursor(start);
                    throw ERROR_INAPPLICABLE_OPTION.createWithContext(parser.getReader(), "gamemode");
                } else {
                    String name = parser.getReader().readUnquotedString();
                    GameType expected = GameType.byName(name, null);
                    if (expected == null) {
                        parser.getReader().setCursor(start);
                        throw ERROR_GAME_MODE_INVALID.createWithContext(parser.getReader(), name);
                    } else {
                        parser.setIncludesEntities(false);
                        parser.addPredicate(e -> {
                            if (e instanceof ServerPlayer player) {
                                GameType current = player.gameMode();
                                return current == expected ^ inverted;
                            } else {
                                return false;
                            }
                        });
                        if (inverted) {
                            parser.setHasGamemodeNotEquals(true);
                        } else {
                            parser.setHasGamemodeEquals(true);
                        }
                    }
                }
            }, s -> !s.hasGamemodeEquals(), Component.translatable("argument.entity.options.gamemode.description"));
            register("team", parser -> {
                boolean inverted = parser.shouldInvertValue();
                String expected = parser.getReader().readUnquotedString();
                parser.addPredicate(e -> {
                    Team current = e.getTeam();
                    String currentName = current == null ? "" : current.getName();
                    return currentName.equals(expected) != inverted;
                });
                if (inverted) {
                    parser.setHasTeamNotEquals(true);
                } else {
                    parser.setHasTeamEquals(true);
                }
            }, s -> !s.hasTeamEquals(), Component.translatable("argument.entity.options.team.description"));
            register(
                "type",
                parser -> {
                    parser.setSuggestions(
                        (b, m) -> {
                            SharedSuggestionProvider.suggestResource(BuiltInRegistries.ENTITY_TYPE.keySet(), b, String.valueOf('!'));
                            SharedSuggestionProvider.suggestResource(BuiltInRegistries.ENTITY_TYPE.getTags().map(tag -> tag.key().location()), b, "!#");
                            if (!parser.isTypeLimitedInversely()) {
                                SharedSuggestionProvider.suggestResource(BuiltInRegistries.ENTITY_TYPE.keySet(), b);
                                SharedSuggestionProvider.suggestResource(
                                    BuiltInRegistries.ENTITY_TYPE.getTags().map(tag -> tag.key().location()), b, String.valueOf('#')
                                );
                            }
 
                            return b.buildFuture();
                        }
                    );
                    int start = parser.getReader().getCursor();
                    boolean inverted = parser.shouldInvertValue();
                    if (parser.isTypeLimitedInversely() && !inverted) {
                        parser.getReader().setCursor(start);
                        throw ERROR_INAPPLICABLE_OPTION.createWithContext(parser.getReader(), "type");
                    } else {
                        if (inverted) {
                            parser.setTypeLimitedInversely();
                        }
 
                        if (parser.isTag()) {
                            TagKey<EntityType<?>> id = TagKey.create(Registries.ENTITY_TYPE, Identifier.read(parser.getReader()));
                            parser.addPredicate(e -> e.is(id) != inverted);
                        } else {
                            Identifier id = Identifier.read(parser.getReader());
                            EntityType<?> type = BuiltInRegistries.ENTITY_TYPE.getOptional(id).orElseThrow(() -> {
                                parser.getReader().setCursor(start);
                                return ERROR_ENTITY_TYPE_INVALID.createWithContext(parser.getReader(), id.toString());
                            });
                            if (Objects.equals(EntityType.PLAYER, type) && !inverted) {
                                parser.setIncludesEntities(false);
                            }
 
                            parser.addPredicate(e -> Objects.equals(type, e.getType()) != inverted);
                            if (!inverted) {
                                parser.limitToType(type);
                            }
                        }
                    }
                },
                s -> !s.isTypeLimited(),
                Component.translatable("argument.entity.options.type.description")
            );
            register("tag", parser -> {
                boolean inverted = parser.shouldInvertValue();
                String tag = parser.getReader().readUnquotedString();
                parser.addPredicate(e -> "".equals(tag) ? e.entityTags().isEmpty() != inverted : e.entityTags().contains(tag) != inverted);
            }, s -> true, Component.translatable("argument.entity.options.tag.description"));
            register("nbt", parser -> {
                boolean inverted = parser.shouldInvertValue();
                CompoundTag tag = TagParser.parseCompoundAsArgument(parser.getReader());
                parser.addPredicate(e -> {
                    boolean var9;
                    try (ProblemReporter.ScopedCollector reporter = new ProblemReporter.ScopedCollector(e.problemPath(), LOGGER)) {
                        TagValueOutput output = TagValueOutput.createWithContext(reporter, e.registryAccess());
                        e.saveWithoutId(output);
                        if (e instanceof ServerPlayer player) {
                            ItemStack selected = player.getInventory().getSelectedItem();
                            if (!selected.isEmpty()) {
                                output.store("SelectedItem", ItemStack.CODEC, selected);
                            }
                        }
 
                        var9 = NbtUtils.compareNbt(tag, output.buildResult(), true) != inverted;
                    }
 
                    return var9;
                });
            }, s -> true, Component.translatable("argument.entity.options.nbt.description"));
            register("scores", parser -> {
                StringReader reader = parser.getReader();
                Map<String, MinMaxBounds.Ints> expected = Maps.newHashMap();
                reader.expect('{');
                reader.skipWhitespace();
 
                while (reader.canRead() && reader.peek() != '}') {
                    reader.skipWhitespace();
                    String name = reader.readUnquotedString();
                    reader.skipWhitespace();
                    reader.expect('=');
                    reader.skipWhitespace();
                    MinMaxBounds.Ints value = MinMaxBounds.Ints.fromReader(reader);
                    expected.put(name, value);
                    reader.skipWhitespace();
                    if (reader.canRead() && reader.peek() == ',') {
                        reader.skip();
                    }
                }
 
                reader.expect('}');
                if (!expected.isEmpty()) {
                    parser.addPredicate(entity -> {
                        Scoreboard scoreboard = entity.level().getServer().getScoreboard();
 
                        for (Entry<String, MinMaxBounds.Ints> entry : expected.entrySet()) {
                            Objective objective = scoreboard.getObjective(entry.getKey());
                            if (objective == null) {
                                return false;
                            }
 
                            ReadOnlyScoreInfo scoreInfo = scoreboard.getPlayerScoreInfo(entity, objective);
                            if (scoreInfo == null) {
                                return false;
                            }
 
                            if (!entry.getValue().matches(scoreInfo.value())) {
                                return false;
                            }
                        }
 
                        return true;
                    });
                }
 
                parser.setHasScores(true);
            }, s -> !s.hasScores(), Component.translatable("argument.entity.options.scores.description"));
            register("advancements", parser -> {
                StringReader reader = parser.getReader();
                Map<Identifier, Predicate<AdvancementProgress>> expected = Maps.newHashMap();
                reader.expect('{');
                reader.skipWhitespace();
 
                while (reader.canRead() && reader.peek() != '}') {
                    reader.skipWhitespace();
                    Identifier name = Identifier.read(reader);
                    reader.skipWhitespace();
                    reader.expect('=');
                    reader.skipWhitespace();
                    if (reader.canRead() && reader.peek() == '{') {
                        Map<String, Predicate<CriterionProgress>> progress = Maps.newHashMap();
                        reader.skipWhitespace();
                        reader.expect('{');
                        reader.skipWhitespace();
 
                        while (reader.canRead() && reader.peek() != '}') {
                            reader.skipWhitespace();
                            String criterion = reader.readUnquotedString();
                            reader.skipWhitespace();
                            reader.expect('=');
                            reader.skipWhitespace();
                            boolean value = reader.readBoolean();
                            progress.put(criterion, p -> p.isDone() == value);
                            reader.skipWhitespace();
                            if (reader.canRead() && reader.peek() == ',') {
                                reader.skip();
                            }
                        }
 
                        reader.skipWhitespace();
                        reader.expect('}');
                        reader.skipWhitespace();
                        expected.put(name, p -> {
                            for (Entry<String, Predicate<CriterionProgress>> entry : progress.entrySet()) {
                                CriterionProgress criterionx = p.getCriterion(entry.getKey());
                                if (criterionx == null || !entry.getValue().test(criterionx)) {
                                    return false;
                                }
                            }
 
                            return true;
                        });
                    } else {
                        boolean value = reader.readBoolean();
                        expected.put(name, p -> p.isDone() == value);
                    }
 
                    reader.skipWhitespace();
                    if (reader.canRead() && reader.peek() == ',') {
                        reader.skip();
                    }
                }
 
                reader.expect('}');
                if (!expected.isEmpty()) {
                    parser.addPredicate(e -> {
                        if (!(e instanceof ServerPlayer player)) {
                            return false;
                        } else {
                            PlayerAdvancements advancements = player.getAdvancements();
                            ServerAdvancementManager serverAdvancements = player.level().getServer().getAdvancements();
 
                            for (Entry<Identifier, Predicate<AdvancementProgress>> entry : expected.entrySet()) {
                                AdvancementHolder advancement = serverAdvancements.get(entry.getKey());
                                if (advancement == null || !entry.getValue().test(advancements.getOrStartProgress(advancement))) {
                                    return false;
                                }
                            }
 
                            return true;
                        }
                    });
                    parser.setIncludesEntities(false);
                }
 
                parser.setHasAdvancements(true);
            }, s -> !s.hasAdvancements(), Component.translatable("argument.entity.options.advancements.description"));
            register(
                "predicate",
                parser -> {
                    boolean inverted = parser.shouldInvertValue();
                    ResourceKey<LootItemCondition> id = ResourceKey.create(Registries.PREDICATE, Identifier.read(parser.getReader()));
                    parser.addPredicate(
                        entity -> {
                            if (entity.level() instanceof ServerLevel level) {
                                Optional<LootItemCondition> condition = level.getServer().reloadableRegistries().lookup().get(id).map(Holder::value);
                                if (condition.isEmpty()) {
                                    return false;
                                } else {
                                    LootParams lootParams = new LootParams.Builder(level)
                                        .withParameter(LootContextParams.THIS_ENTITY, entity)
                                        .withParameter(LootContextParams.ORIGIN, entity.position())
                                        .create(LootContextParamSets.SELECTOR);
                                    LootContext context = new LootContext.Builder(lootParams).create(Optional.empty());
                                    context.pushVisitedElement(LootContext.createVisitedEntry(condition.get()));
                                    return inverted ^ condition.get().test(context);
                                }
                            } else {
                                return false;
                            }
                        }
                    );
                },
                s -> true,
                Component.translatable("argument.entity.options.predicate.description")
            );
        }
    }
 
    public static EntitySelectorOptions.Modifier get(EntitySelectorParser parser, String key, int start) throws CommandSyntaxException {
        EntitySelectorOptions.Option option = OPTIONS.get(key);
        if (option != null) {
            if (option.canUse.test(parser)) {
                return option.modifier;
            } else {
                throw ERROR_INAPPLICABLE_OPTION.createWithContext(parser.getReader(), key);
            }
        } else {
            parser.getReader().setCursor(start);
            throw ERROR_UNKNOWN_OPTION.createWithContext(parser.getReader(), key);
        }
    }
 
    public static void suggestNames(EntitySelectorParser parser, SuggestionsBuilder builder) {
        String lowerPrefix = builder.getRemaining().toLowerCase(Locale.ROOT);
 
        for (Entry<String, EntitySelectorOptions.Option> entry : OPTIONS.entrySet()) {
            if (entry.getValue().canUse.test(parser) && entry.getKey().toLowerCase(Locale.ROOT).startsWith(lowerPrefix)) {
                builder.suggest(entry.getKey() + "=", entry.getValue().description);
            }
        }
    }
 
    @FunctionalInterface
    public interface Modifier {
        void handle(EntitySelectorParser parser) throws CommandSyntaxException;
    }
 
    private record Option(EntitySelectorOptions.Modifier modifier, Predicate<EntitySelectorParser> canUse, Component description) {
    }
}

引用的其他类

  • MinMaxBounds

    • 引用位置: 方法调用
    • 关联成员: MinMaxBounds.Doubles.fromReader(), MinMaxBounds.FloatDegrees.fromReader(), MinMaxBounds.Ints.fromReader()
  • SharedSuggestionProvider

    • 引用位置: 方法调用
    • 关联成员: SharedSuggestionProvider.suggest(), SharedSuggestionProvider.suggestResource()
  • EntitySelectorParser

    • 引用位置: 参数
  • NbtUtils

    • 引用位置: 方法调用
    • 关联成员: NbtUtils.compareNbt()
  • TagParser

    • 引用位置: 方法调用
    • 关联成员: TagParser.parseCompoundAsArgument()
  • Component

    • 引用位置: 参数/方法调用
    • 关联成员: Component.translatable(), Component.translatableEscape()
  • Identifier

    • 引用位置: 方法调用
    • 关联成员: Identifier.read()
  • ResourceKey

    • 引用位置: 方法调用
    • 关联成员: ResourceKey.create()
  • TagKey

    • 引用位置: 方法调用
    • 关联成员: TagKey.create()
  • ProblemReporter

    • 引用位置: 方法调用/构造调用
    • 关联成员: ProblemReporter.ScopedCollector(), ScopedCollector()
  • GameType

    • 引用位置: 方法调用
    • 关联成员: GameType.byName(), GameType.values()
  • TagValueOutput

    • 引用位置: 方法调用
    • 关联成员: TagValueOutput.createWithContext()
  • LootContext

    • 引用位置: 方法调用/构造调用
    • 关联成员: Builder(), LootContext.Builder(), LootContext.createVisitedEntry()
  • LootParams

    • 引用位置: 方法调用/构造调用
    • 关联成员: Builder(), LootParams.Builder()