AdvancementRewards.java

net.minecraft.advancements.AdvancementRewards

信息

  • 全限定名:net.minecraft.advancements.AdvancementRewards
  • 类型:public record
  • 包:net.minecraft.advancements
  • 源码路径:src/main/java/net/minecraft/advancements/AdvancementRewards.java
  • 起始行号:L27
  • 职责:

    TODO

字段/常量

  • CODEC

    • 类型: Codec<AdvancementRewards>
    • 修饰符: public static final
    • 源码定位: L28
    • 说明:

      TODO

  • EMPTY

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

      TODO

内部类/嵌套类型

  • net.minecraft.advancements.AdvancementRewards.Builder
    • 类型: class
    • 修饰符: public static
    • 源码定位: L92
    • 说明:

      TODO

构造器

方法

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

public void grant(ServerPlayer player) @ L39

  • 方法名:grant
  • 源码定位:L39
  • 返回类型:void
  • 修饰符:public

参数:

  • player: ServerPlayer

说明:

TODO

代码

public record AdvancementRewards(int experience, List<ResourceKey<LootTable>> loot, List<ResourceKey<Recipe<?>>> recipes, Optional<CacheableFunction> function) {
    public static final Codec<AdvancementRewards> CODEC = RecordCodecBuilder.create(
        i -> i.group(
                Codec.INT.optionalFieldOf("experience", 0).forGetter(AdvancementRewards::experience),
                LootTable.KEY_CODEC.listOf().optionalFieldOf("loot", List.of()).forGetter(AdvancementRewards::loot),
                Recipe.KEY_CODEC.listOf().optionalFieldOf("recipes", List.of()).forGetter(AdvancementRewards::recipes),
                CacheableFunction.CODEC.optionalFieldOf("function").forGetter(AdvancementRewards::function)
            )
            .apply(i, AdvancementRewards::new)
    );
    public static final AdvancementRewards EMPTY = new AdvancementRewards(0, List.of(), List.of(), Optional.empty());
 
    public void grant(ServerPlayer player) {
        player.giveExperiencePoints(this.experience);
        ServerLevel level = player.level();
        MinecraftServer server = level.getServer();
        LootParams params = new LootParams.Builder(level)
            .withParameter(LootContextParams.THIS_ENTITY, player)
            .withParameter(LootContextParams.ORIGIN, player.position())
            .create(LootContextParamSets.ADVANCEMENT_REWARD);
        boolean changes = false;
 
        for (ResourceKey<LootTable> lootTable : this.loot) {
            for (ItemStack itemStack : server.reloadableRegistries().getLootTable(lootTable).getRandomItems(params)) {
                if (player.addItem(itemStack)) {
                    level.playSound(
                        null,
                        player.getX(),
                        player.getY(),
                        player.getZ(),
                        SoundEvents.ITEM_PICKUP,
                        SoundSource.PLAYERS,
                        0.2F,
                        ((player.getRandom().nextFloat() - player.getRandom().nextFloat()) * 0.7F + 1.0F) * 2.0F
                    );
                    changes = true;
                } else {
                    ItemEntity drop = player.drop(itemStack, false);
                    if (drop != null) {
                        drop.setNoPickUpDelay();
                        drop.setTarget(player.getUUID());
                    }
                }
            }
        }
 
        if (changes) {
            player.containerMenu.broadcastChanges();
        }
 
        if (!this.recipes.isEmpty()) {
            player.awardRecipesByKey(this.recipes);
        }
 
        this.function
            .flatMap(function -> function.get(server.getFunctions()))
            .ifPresent(
                function -> server.getFunctions()
                    .execute(
                        (CommandFunction<CommandSourceStack>)function,
                        player.createCommandSourceStack().withSuppressedOutput().withPermission(LevelBasedPermissionSet.GAMEMASTER)
                    )
            );
    }
 
    public static class Builder {
        private int experience;
        private final ImmutableList.Builder<ResourceKey<LootTable>> loot = ImmutableList.builder();
        private final ImmutableList.Builder<ResourceKey<Recipe<?>>> recipes = ImmutableList.builder();
        private Optional<Identifier> function = Optional.empty();
 
        public static AdvancementRewards.Builder experience(int amount) {
            return new AdvancementRewards.Builder().addExperience(amount);
        }
 
        public AdvancementRewards.Builder addExperience(int amount) {
            this.experience += amount;
            return this;
        }
 
        public static AdvancementRewards.Builder loot(ResourceKey<LootTable> id) {
            return new AdvancementRewards.Builder().addLootTable(id);
        }
 
        public AdvancementRewards.Builder addLootTable(ResourceKey<LootTable> id) {
            this.loot.add(id);
            return this;
        }
 
        public static AdvancementRewards.Builder recipe(ResourceKey<Recipe<?>> id) {
            return new AdvancementRewards.Builder().addRecipe(id);
        }
 
        public AdvancementRewards.Builder addRecipe(ResourceKey<Recipe<?>> id) {
            this.recipes.add(id);
            return this;
        }
 
        public static AdvancementRewards.Builder function(Identifier id) {
            return new AdvancementRewards.Builder().runs(id);
        }
 
        public AdvancementRewards.Builder runs(Identifier function) {
            this.function = Optional.of(function);
            return this;
        }
 
        public AdvancementRewards build() {
            return new AdvancementRewards(this.experience, this.loot.build(), this.recipes.build(), this.function.map(CacheableFunction::new));
        }
    }
}

引用的其他类

  • ServerPlayer

    • 引用位置: 参数
  • LootParams

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