VanillaAdventureAdvancements.java

net.minecraft.data.advancements.packs.VanillaAdventureAdvancements

信息

  • 全限定名:net.minecraft.data.advancements.packs.VanillaAdventureAdvancements
  • 类型:public class
  • 包:net.minecraft.data.advancements.packs
  • 源码路径:src/main/java/net/minecraft/data/advancements/packs/VanillaAdventureAdvancements.java
  • 起始行号:L109
  • 实现:AdvancementSubProvider
  • 职责:

    TODO

字段/常量

  • LOGGER

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

      TODO

  • DISTANCE_FROM_BOTTOM_TO_TOP

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

      TODO

  • Y_COORDINATE_AT_TOP

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

      TODO

  • Y_COORDINATE_AT_BOTTOM

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

      TODO

  • BEDROCK_THICKNESS

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

      TODO

  • EXCEPTIONS_BY_EXPECTED_CATEGORIES

    • 类型: Map<MobCategory,Set<EntityType<?>>>
    • 修饰符: private static final
    • 源码定位: L115
    • 说明:

      TODO

  • MOBS_TO_KILL

    • 类型: List<EntityType<?>>
    • 修饰符: private static final
    • 源码定位: L118
    • 说明:

      TODO

内部类/嵌套类型

构造器

方法

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

private static Criterion<LightningStrikeTrigger.TriggerInstance> fireCountAndBystander(MinMaxBounds.Ints fireCount, Optional<EntityPredicate> bystander) @ L162

  • 方法名:fireCountAndBystander
  • 源码定位:L162
  • 返回类型:Criterion<LightningStrikeTrigger.TriggerInstance>
  • 修饰符:private static

参数:

  • fireCount: MinMaxBounds.Ints
  • bystander: Optional

说明:

TODO

private static Criterion<UsingItemTrigger.TriggerInstance> lookAtThroughItem(EntityPredicate.Builder lookingAt, ItemPredicate.Builder with) @ L174

  • 方法名:lookAtThroughItem
  • 源码定位:L174
  • 返回类型:Criterion<UsingItemTrigger.TriggerInstance>
  • 修饰符:private static

参数:

  • lookingAt: EntityPredicate.Builder
  • with: ItemPredicate.Builder

说明:

TODO

public void generate(HolderLookup.Provider registries, Consumer<AdvancementHolder> output) @ L180

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

参数:

  • registries: HolderLookup.Provider
  • output: Consumer

说明:

TODO

public static AdvancementHolder createMonsterHunterAdvancement(AdvancementHolder parent, Consumer<AdvancementHolder> output, HolderGetter<EntityType<?>> entityTypes, List<EntityType<?>> mobsToKill) @ L1029

  • 方法名:createMonsterHunterAdvancement
  • 源码定位:L1029
  • 返回类型:AdvancementHolder
  • 修饰符:public static

参数:

  • parent: AdvancementHolder
  • output: Consumer
  • entityTypes: HolderGetter<EntityType<?>>
  • mobsToKill: List<EntityType<?>>

说明:

TODO

private static Criterion<ItemUsedOnLocationTrigger.TriggerInstance> placedBlockReadByComparator(HolderGetter<Block> blocks, Block block) @ L1063

  • 方法名:placedBlockReadByComparator
  • 源码定位:L1063
  • 返回类型:Criterion<ItemUsedOnLocationTrigger.TriggerInstance>
  • 修饰符:private static

参数:

  • blocks: HolderGetter
  • block: Block

说明:

TODO

private static Criterion<ItemUsedOnLocationTrigger.TriggerInstance> placedComparatorReadingBlock(HolderGetter<Block> blocks, Block block) @ L1083

  • 方法名:placedComparatorReadingBlock
  • 源码定位:L1083
  • 返回类型:Criterion<ItemUsedOnLocationTrigger.TriggerInstance>
  • 修饰符:private static

参数:

  • blocks: HolderGetter
  • block: Block

说明:

TODO

private static Criterion<ItemUsedOnLocationTrigger.TriggerInstance> placedBlockActivatesCreakingHeart(HolderGetter<Block> blocks, TagKey<Block> block) @ L1103

  • 方法名:placedBlockActivatesCreakingHeart
  • 源码定位:L1103
  • 返回类型:Criterion<ItemUsedOnLocationTrigger.TriggerInstance>
  • 修饰符:private static

参数:

  • blocks: HolderGetter
  • block: TagKey

说明:

TODO

private static Advancement.Builder smithingWithStyle(Advancement.Builder advancement) @ L1129

  • 方法名:smithingWithStyle
  • 源码定位:L1129
  • 返回类型:Advancement.Builder
  • 修饰符:private static

参数:

  • advancement: Advancement.Builder

说明:

TODO

private static Advancement.Builder craftingANewLook(Advancement.Builder advancement) @ L1151

  • 方法名:craftingANewLook
  • 源码定位:L1151
  • 返回类型:Advancement.Builder
  • 修饰符:private static

参数:

  • advancement: Advancement.Builder

说明:

TODO

private static Advancement.Builder respectingTheRemnantsCriterions(HolderGetter<Item> items, Advancement.Builder advancement) @ L1163

  • 方法名:respectingTheRemnantsCriterions
  • 源码定位:L1163
  • 返回类型:Advancement.Builder
  • 修饰符:private static

参数:

  • items: HolderGetter
  • advancement: Advancement.Builder

说明:

TODO

protected static void createAdventuringTime(HolderLookup.Provider registries, Consumer<AdvancementHolder> output, AdvancementHolder sleepInBed, MultiNoiseBiomeSourceParameterList.Preset preset) @ L1181

  • 方法名:createAdventuringTime
  • 源码定位:L1181
  • 返回类型:void
  • 修饰符:protected static

参数:

  • registries: HolderLookup.Provider
  • output: Consumer
  • sleepInBed: AdvancementHolder
  • preset: MultiNoiseBiomeSourceParameterList.Preset

说明:

TODO

private static Advancement.Builder addMobsToKill(Advancement.Builder advancement, HolderGetter<EntityType<?>> entityTypes, List<EntityType<?>> mobsToKill) @ L1200

  • 方法名:addMobsToKill
  • 源码定位:L1200
  • 返回类型:Advancement.Builder
  • 修饰符:private static

参数:

  • advancement: Advancement.Builder
  • entityTypes: HolderGetter<EntityType<?>>
  • mobsToKill: List<EntityType<?>>

说明:

TODO

protected static Advancement.Builder addBiomes(Advancement.Builder advancement, HolderLookup.Provider registries, List<ResourceKey<Biome>> explorableBiomes) @ L1210

  • 方法名:addBiomes
  • 源码定位:L1210
  • 返回类型:Advancement.Builder
  • 修饰符:protected static

参数:

  • advancement: Advancement.Builder
  • registries: HolderLookup.Provider
  • explorableBiomes: List<ResourceKey>

说明:

TODO

private static List<EntityType<?>> validateMobsToKill(List<EntityType<?>> data, HolderLookup<EntityType<?>> entityTypes) @ L1222

  • 方法名:validateMobsToKill
  • 源码定位:L1222
  • 返回类型:List<EntityType<?>>
  • 修饰符:private static

参数:

  • data: List<EntityType<?>>
  • entityTypes: HolderLookup<EntityType<?>>

说明:

TODO

代码

public class VanillaAdventureAdvancements implements AdvancementSubProvider {
    private static final Logger LOGGER = LogUtils.getLogger();
    private static final int DISTANCE_FROM_BOTTOM_TO_TOP = 384;
    private static final int Y_COORDINATE_AT_TOP = 320;
    private static final int Y_COORDINATE_AT_BOTTOM = -64;
    private static final int BEDROCK_THICKNESS = 5;
    private static final Map<MobCategory, Set<EntityType<?>>> EXCEPTIONS_BY_EXPECTED_CATEGORIES = Map.of(
        MobCategory.MONSTER, Set.of(EntityType.GIANT, EntityType.ILLUSIONER, EntityType.WARDEN)
    );
    private static final List<EntityType<?>> MOBS_TO_KILL = Arrays.asList(
        EntityType.BLAZE,
        EntityType.BOGGED,
        EntityType.BREEZE,
        EntityType.CAMEL_HUSK,
        EntityType.CAVE_SPIDER,
        EntityType.CREAKING,
        EntityType.CREEPER,
        EntityType.DROWNED,
        EntityType.ELDER_GUARDIAN,
        EntityType.ENDER_DRAGON,
        EntityType.ENDERMAN,
        EntityType.ENDERMITE,
        EntityType.EVOKER,
        EntityType.GHAST,
        EntityType.GUARDIAN,
        EntityType.HOGLIN,
        EntityType.HUSK,
        EntityType.MAGMA_CUBE,
        EntityType.PARCHED,
        EntityType.PHANTOM,
        EntityType.PIGLIN,
        EntityType.PIGLIN_BRUTE,
        EntityType.PILLAGER,
        EntityType.RAVAGER,
        EntityType.SHULKER,
        EntityType.SILVERFISH,
        EntityType.SKELETON,
        EntityType.SLIME,
        EntityType.SPIDER,
        EntityType.STRAY,
        EntityType.VEX,
        EntityType.VINDICATOR,
        EntityType.WITCH,
        EntityType.WITHER_SKELETON,
        EntityType.WITHER,
        EntityType.ZOGLIN,
        EntityType.ZOMBIE_VILLAGER,
        EntityType.ZOMBIE,
        EntityType.ZOMBIE_HORSE,
        EntityType.ZOMBIFIED_PIGLIN,
        EntityType.ZOMBIE_NAUTILUS
    );
 
    private static Criterion<LightningStrikeTrigger.TriggerInstance> fireCountAndBystander(MinMaxBounds.Ints fireCount, Optional<EntityPredicate> bystander) {
        return LightningStrikeTrigger.TriggerInstance.lightningStrike(
            Optional.of(
                EntityPredicate.Builder.entity()
                    .distance(DistancePredicate.absolute(MinMaxBounds.Doubles.atMost(30.0)))
                    .subPredicate(LightningBoltPredicate.blockSetOnFire(fireCount))
                    .build()
            ),
            bystander
        );
    }
 
    private static Criterion<UsingItemTrigger.TriggerInstance> lookAtThroughItem(EntityPredicate.Builder lookingAt, ItemPredicate.Builder with) {
        return UsingItemTrigger.TriggerInstance.lookingAt(
            EntityPredicate.Builder.entity().subPredicate(PlayerPredicate.Builder.player().setLookingAt(lookingAt).build()), with
        );
    }
 
    @Override
    public void generate(HolderLookup.Provider registries, Consumer<AdvancementHolder> output) {
        HolderLookup<EntityType<?>> entityTypes = registries.lookupOrThrow(Registries.ENTITY_TYPE);
        HolderLookup<Item> items = registries.lookupOrThrow(Registries.ITEM);
        HolderLookup<Block> blocks = registries.lookupOrThrow(Registries.BLOCK);
        AdvancementHolder root = Advancement.Builder.advancement()
            .display(
                Items.MAP,
                Component.translatable("advancements.adventure.root.title"),
                Component.translatable("advancements.adventure.root.description"),
                Identifier.withDefaultNamespace("gui/advancements/backgrounds/adventure"),
                AdvancementType.TASK,
                false,
                false,
                false
            )
            .requirements(AdvancementRequirements.Strategy.OR)
            .addCriterion("killed_something", KilledTrigger.TriggerInstance.playerKilledEntity())
            .addCriterion("killed_by_something", KilledTrigger.TriggerInstance.entityKilledPlayer())
            .save(output, "adventure/root");
        AdvancementHolder sleepInBed = Advancement.Builder.advancement()
            .parent(root)
            .display(
                Blocks.RED_BED,
                Component.translatable("advancements.adventure.sleep_in_bed.title"),
                Component.translatable("advancements.adventure.sleep_in_bed.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .addCriterion("slept_in_bed", PlayerTrigger.TriggerInstance.sleptInBed())
            .save(output, "adventure/sleep_in_bed");
        createAdventuringTime(registries, output, sleepInBed, MultiNoiseBiomeSourceParameterList.Preset.OVERWORLD);
        AdvancementHolder trade = Advancement.Builder.advancement()
            .parent(root)
            .display(
                Items.EMERALD,
                Component.translatable("advancements.adventure.trade.title"),
                Component.translatable("advancements.adventure.trade.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .addCriterion("traded", TradeTrigger.TriggerInstance.tradedWithVillager())
            .save(output, "adventure/trade");
        Advancement.Builder.advancement()
            .parent(trade)
            .display(
                Items.EMERALD,
                Component.translatable("advancements.adventure.trade_at_world_height.title"),
                Component.translatable("advancements.adventure.trade_at_world_height.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .addCriterion(
                "trade_at_world_height",
                TradeTrigger.TriggerInstance.tradedWithVillager(
                    EntityPredicate.Builder.entity().located(LocationPredicate.Builder.atYLocation(MinMaxBounds.Doubles.atLeast(319.0)))
                )
            )
            .save(output, "adventure/trade_at_world_height");
        AdvancementHolder killAMob = createMonsterHunterAdvancement(root, output, entityTypes, validateMobsToKill(MOBS_TO_KILL, entityTypes));
        AdvancementHolder shootArrow = Advancement.Builder.advancement()
            .parent(killAMob)
            .display(
                Items.BOW,
                Component.translatable("advancements.adventure.shoot_arrow.title"),
                Component.translatable("advancements.adventure.shoot_arrow.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .addCriterion(
                "shot_arrow",
                PlayerHurtEntityTrigger.TriggerInstance.playerHurtEntityWithDamage(
                    DamagePredicate.Builder.damageInstance()
                        .type(
                            DamageSourcePredicate.Builder.damageType()
                                .tag(TagPredicate.is(DamageTypeTags.IS_PROJECTILE))
                                .direct(EntityPredicate.Builder.entity().of(entityTypes, EntityTypeTags.ARROWS))
                        )
                )
            )
            .save(output, "adventure/shoot_arrow");
        AdvancementHolder throwTrident = Advancement.Builder.advancement()
            .parent(killAMob)
            .display(
                Items.TRIDENT,
                Component.translatable("advancements.adventure.throw_trident.title"),
                Component.translatable("advancements.adventure.throw_trident.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .addCriterion(
                "shot_trident",
                PlayerHurtEntityTrigger.TriggerInstance.playerHurtEntityWithDamage(
                    DamagePredicate.Builder.damageInstance()
                        .type(
                            DamageSourcePredicate.Builder.damageType()
                                .tag(TagPredicate.is(DamageTypeTags.IS_PROJECTILE))
                                .direct(EntityPredicate.Builder.entity().of(entityTypes, EntityType.TRIDENT))
                        )
                )
            )
            .save(output, "adventure/throw_trident");
        Advancement.Builder.advancement()
            .parent(throwTrident)
            .display(
                Items.TRIDENT,
                Component.translatable("advancements.adventure.very_very_frightening.title"),
                Component.translatable("advancements.adventure.very_very_frightening.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .addCriterion(
                "struck_villager",
                ChanneledLightningTrigger.TriggerInstance.channeledLightning(EntityPredicate.Builder.entity().of(entityTypes, EntityType.VILLAGER))
            )
            .save(output, "adventure/very_very_frightening");
        Advancement.Builder.advancement()
            .parent(trade)
            .display(
                Blocks.CARVED_PUMPKIN,
                Component.translatable("advancements.adventure.summon_iron_golem.title"),
                Component.translatable("advancements.adventure.summon_iron_golem.description"),
                null,
                AdvancementType.GOAL,
                true,
                true,
                false
            )
            .addCriterion(
                "summoned_golem", SummonedEntityTrigger.TriggerInstance.summonedEntity(EntityPredicate.Builder.entity().of(entityTypes, EntityType.IRON_GOLEM))
            )
            .save(output, "adventure/summon_iron_golem");
        Advancement.Builder.advancement()
            .parent(shootArrow)
            .display(
                Items.ARROW,
                Component.translatable("advancements.adventure.sniper_duel.title"),
                Component.translatable("advancements.adventure.sniper_duel.description"),
                null,
                AdvancementType.CHALLENGE,
                true,
                true,
                false
            )
            .rewards(AdvancementRewards.Builder.experience(50))
            .addCriterion(
                "killed_skeleton",
                KilledTrigger.TriggerInstance.playerKilledEntity(
                    EntityPredicate.Builder.entity()
                        .of(entityTypes, EntityType.SKELETON)
                        .distance(DistancePredicate.horizontal(MinMaxBounds.Doubles.atLeast(50.0))),
                    DamageSourcePredicate.Builder.damageType().tag(TagPredicate.is(DamageTypeTags.IS_PROJECTILE))
                )
            )
            .save(output, "adventure/sniper_duel");
        Advancement.Builder.advancement()
            .parent(killAMob)
            .display(
                Items.TOTEM_OF_UNDYING,
                Component.translatable("advancements.adventure.totem_of_undying.title"),
                Component.translatable("advancements.adventure.totem_of_undying.description"),
                null,
                AdvancementType.GOAL,
                true,
                true,
                false
            )
            .addCriterion("used_totem", UsedTotemTrigger.TriggerInstance.usedTotem(items, Items.TOTEM_OF_UNDYING))
            .save(output, "adventure/totem_of_undying");
        Advancement.Builder.advancement()
            .parent(killAMob)
            .display(
                Items.IRON_SPEAR,
                Component.translatable("advancements.adventure.spear_many_mobs.title"),
                Component.translatable("advancements.adventure.spear_many_mobs.description"),
                null,
                AdvancementType.GOAL,
                true,
                true,
                false
            )
            .addCriterion("spear_many_mobs", SpearMobsTrigger.TriggerInstance.spearMobs(5))
            .save(output, "adventure/spear_many_mobs");
        AdvancementHolder olBetsy = Advancement.Builder.advancement()
            .parent(root)
            .display(
                Items.CROSSBOW,
                Component.translatable("advancements.adventure.ol_betsy.title"),
                Component.translatable("advancements.adventure.ol_betsy.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .addCriterion("shot_crossbow", ShotCrossbowTrigger.TriggerInstance.shotCrossbow(items, Items.CROSSBOW))
            .save(output, "adventure/ol_betsy");
        Advancement.Builder.advancement()
            .parent(olBetsy)
            .display(
                Items.CROSSBOW,
                Component.translatable("advancements.adventure.whos_the_pillager_now.title"),
                Component.translatable("advancements.adventure.whos_the_pillager_now.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .addCriterion(
                "kill_pillager",
                KilledByArrowTrigger.TriggerInstance.crossbowKilled(items, EntityPredicate.Builder.entity().of(entityTypes, EntityType.PILLAGER))
            )
            .save(output, "adventure/whos_the_pillager_now");
        Advancement.Builder.advancement()
            .parent(olBetsy)
            .display(
                Items.CROSSBOW,
                Component.translatable("advancements.adventure.two_birds_one_arrow.title"),
                Component.translatable("advancements.adventure.two_birds_one_arrow.description"),
                null,
                AdvancementType.CHALLENGE,
                true,
                true,
                false
            )
            .rewards(AdvancementRewards.Builder.experience(65))
            .addCriterion(
                "two_birds",
                KilledByArrowTrigger.TriggerInstance.crossbowKilled(
                    items,
                    EntityPredicate.Builder.entity().of(entityTypes, EntityType.PHANTOM),
                    EntityPredicate.Builder.entity().of(entityTypes, EntityType.PHANTOM)
                )
            )
            .save(output, "adventure/two_birds_one_arrow");
        Advancement.Builder.advancement()
            .parent(olBetsy)
            .display(
                Items.CROSSBOW,
                Component.translatable("advancements.adventure.arbalistic.title"),
                Component.translatable("advancements.adventure.arbalistic.description"),
                null,
                AdvancementType.CHALLENGE,
                true,
                true,
                true
            )
            .rewards(AdvancementRewards.Builder.experience(85))
            .addCriterion("arbalistic", KilledByArrowTrigger.TriggerInstance.crossbowKilled(items, MinMaxBounds.Ints.exactly(5)))
            .save(output, "adventure/arbalistic");
        HolderLookup.RegistryLookup<BannerPattern> patternLookup = registries.lookupOrThrow(Registries.BANNER_PATTERN);
        AdvancementHolder raidOmen = Advancement.Builder.advancement()
            .parent(root)
            .display(
                Raid.getOminousBannerTemplate(patternLookup),
                Component.translatable("advancements.adventure.voluntary_exile.title"),
                Component.translatable("advancements.adventure.voluntary_exile.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                true
            )
            .addCriterion(
                "voluntary_exile",
                KilledTrigger.TriggerInstance.playerKilledEntity(
                    EntityPredicate.Builder.entity()
                        .of(entityTypes, EntityTypeTags.RAIDERS)
                        .equipment(EntityEquipmentPredicate.captainPredicate(items, patternLookup))
                )
            )
            .save(output, "adventure/voluntary_exile");
        Advancement.Builder.advancement()
            .parent(raidOmen)
            .display(
                Raid.getOminousBannerTemplate(patternLookup),
                Component.translatable("advancements.adventure.hero_of_the_village.title"),
                Component.translatable("advancements.adventure.hero_of_the_village.description"),
                null,
                AdvancementType.CHALLENGE,
                true,
                true,
                true
            )
            .rewards(AdvancementRewards.Builder.experience(100))
            .addCriterion("hero_of_the_village", PlayerTrigger.TriggerInstance.raidWon())
            .save(output, "adventure/hero_of_the_village");
        Advancement.Builder.advancement()
            .parent(root)
            .display(
                Items.HONEY_BLOCK,
                Component.translatable("advancements.adventure.honey_block_slide.title"),
                Component.translatable("advancements.adventure.honey_block_slide.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .addCriterion("honey_block_slide", SlideDownBlockTrigger.TriggerInstance.slidesDownBlock(Blocks.HONEY_BLOCK))
            .save(output, "adventure/honey_block_slide");
        Advancement.Builder.advancement()
            .parent(shootArrow)
            .display(
                Items.TARGET,
                Component.translatable("advancements.adventure.bullseye.title"),
                Component.translatable("advancements.adventure.bullseye.description"),
                null,
                AdvancementType.CHALLENGE,
                true,
                true,
                false
            )
            .rewards(AdvancementRewards.Builder.experience(50))
            .addCriterion(
                "bullseye",
                TargetBlockTrigger.TriggerInstance.targetHit(
                    MinMaxBounds.Ints.exactly(15),
                    Optional.of(
                        EntityPredicate.wrap(EntityPredicate.Builder.entity().distance(DistancePredicate.horizontal(MinMaxBounds.Doubles.atLeast(30.0))))
                    )
                )
            )
            .save(output, "adventure/bullseye");
        Advancement.Builder.advancement()
            .parent(sleepInBed)
            .display(
                Items.LEATHER_BOOTS,
                Component.translatable("advancements.adventure.walk_on_powder_snow_with_leather_boots.title"),
                Component.translatable("advancements.adventure.walk_on_powder_snow_with_leather_boots.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .addCriterion(
                "walk_on_powder_snow_with_leather_boots",
                PlayerTrigger.TriggerInstance.walkOnBlockWithEquipment(blocks, items, Blocks.POWDER_SNOW, Items.LEATHER_BOOTS)
            )
            .save(output, "adventure/walk_on_powder_snow_with_leather_boots");
        Advancement.Builder.advancement()
            .parent(root)
            .display(
                Items.LIGHTNING_ROD,
                Component.translatable("advancements.adventure.lightning_rod_with_villager_no_fire.title"),
                Component.translatable("advancements.adventure.lightning_rod_with_villager_no_fire.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .addCriterion(
                "lightning_rod_with_villager_no_fire",
                fireCountAndBystander(MinMaxBounds.Ints.exactly(0), Optional.of(EntityPredicate.Builder.entity().of(entityTypes, EntityType.VILLAGER).build()))
            )
            .save(output, "adventure/lightning_rod_with_villager_no_fire");
        AdvancementHolder isItABird = Advancement.Builder.advancement()
            .parent(root)
            .display(
                Items.SPYGLASS,
                Component.translatable("advancements.adventure.spyglass_at_parrot.title"),
                Component.translatable("advancements.adventure.spyglass_at_parrot.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .addCriterion(
                "spyglass_at_parrot",
                lookAtThroughItem(EntityPredicate.Builder.entity().of(entityTypes, EntityType.PARROT), ItemPredicate.Builder.item().of(items, Items.SPYGLASS))
            )
            .save(output, "adventure/spyglass_at_parrot");
        AdvancementHolder isItABalloon = Advancement.Builder.advancement()
            .parent(isItABird)
            .display(
                Items.SPYGLASS,
                Component.translatable("advancements.adventure.spyglass_at_ghast.title"),
                Component.translatable("advancements.adventure.spyglass_at_ghast.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .addCriterion(
                "spyglass_at_ghast",
                lookAtThroughItem(EntityPredicate.Builder.entity().of(entityTypes, EntityType.GHAST), ItemPredicate.Builder.item().of(items, Items.SPYGLASS))
            )
            .save(output, "adventure/spyglass_at_ghast");
        Advancement.Builder.advancement()
            .parent(sleepInBed)
            .display(
                Items.JUKEBOX,
                Component.translatable("advancements.adventure.play_jukebox_in_meadows.title"),
                Component.translatable("advancements.adventure.play_jukebox_in_meadows.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .addCriterion(
                "play_jukebox_in_meadows",
                ItemUsedOnLocationTrigger.TriggerInstance.itemUsedOnBlock(
                    LocationPredicate.Builder.location()
                        .setBiomes(HolderSet.direct(registries.lookupOrThrow(Registries.BIOME).getOrThrow(Biomes.MEADOW)))
                        .setBlock(BlockPredicate.Builder.block().of(blocks, Blocks.JUKEBOX)),
                    ItemPredicate.Builder.item()
                        .withComponents(
                            DataComponentMatchers.Builder.components()
                                .partial(DataComponentPredicates.JUKEBOX_PLAYABLE, JukeboxPlayablePredicate.any())
                                .build()
                        )
                )
            )
            .save(output, "adventure/play_jukebox_in_meadows");
        Advancement.Builder.advancement()
            .parent(isItABalloon)
            .display(
                Items.SPYGLASS,
                Component.translatable("advancements.adventure.spyglass_at_dragon.title"),
                Component.translatable("advancements.adventure.spyglass_at_dragon.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .addCriterion(
                "spyglass_at_dragon",
                lookAtThroughItem(
                    EntityPredicate.Builder.entity().of(entityTypes, EntityType.ENDER_DRAGON), ItemPredicate.Builder.item().of(items, Items.SPYGLASS)
                )
            )
            .save(output, "adventure/spyglass_at_dragon");
        Advancement.Builder.advancement()
            .parent(root)
            .display(
                Items.WATER_BUCKET,
                Component.translatable("advancements.adventure.fall_from_world_height.title"),
                Component.translatable("advancements.adventure.fall_from_world_height.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .addCriterion(
                "fall_from_world_height",
                DistanceTrigger.TriggerInstance.fallFromHeight(
                    EntityPredicate.Builder.entity().located(LocationPredicate.Builder.atYLocation(MinMaxBounds.Doubles.atMost(-59.0))),
                    DistancePredicate.vertical(MinMaxBounds.Doubles.atLeast(379.0)),
                    LocationPredicate.Builder.atYLocation(MinMaxBounds.Doubles.atLeast(319.0))
                )
            )
            .save(output, "adventure/fall_from_world_height");
        Advancement.Builder.advancement()
            .parent(killAMob)
            .display(
                Blocks.SCULK_CATALYST,
                Component.translatable("advancements.adventure.kill_mob_near_sculk_catalyst.title"),
                Component.translatable("advancements.adventure.kill_mob_near_sculk_catalyst.description"),
                null,
                AdvancementType.CHALLENGE,
                true,
                true,
                false
            )
            .addCriterion("kill_mob_near_sculk_catalyst", KilledTrigger.TriggerInstance.playerKilledEntityNearSculkCatalyst())
            .save(output, "adventure/kill_mob_near_sculk_catalyst");
        Advancement.Builder.advancement()
            .parent(root)
            .display(
                Blocks.SCULK_SENSOR,
                Component.translatable("advancements.adventure.avoid_vibration.title"),
                Component.translatable("advancements.adventure.avoid_vibration.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .addCriterion("avoid_vibration", PlayerTrigger.TriggerInstance.avoidVibration())
            .save(output, "adventure/avoid_vibration");
        AdvancementHolder respectingTheRemnants = respectingTheRemnantsCriterions(items, Advancement.Builder.advancement())
            .parent(root)
            .display(
                Items.BRUSH,
                Component.translatable("advancements.adventure.salvage_sherd.title"),
                Component.translatable("advancements.adventure.salvage_sherd.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .save(output, "adventure/salvage_sherd");
        Advancement.Builder.advancement()
            .parent(respectingTheRemnants)
            .display(
                DecoratedPotBlockEntity.createDecoratedPotTemplate(
                    new PotDecorations(Optional.empty(), Optional.of(Items.HEART_POTTERY_SHERD), Optional.empty(), Optional.of(Items.EXPLORER_POTTERY_SHERD))
                ),
                Component.translatable("advancements.adventure.craft_decorated_pot_using_only_sherds.title"),
                Component.translatable("advancements.adventure.craft_decorated_pot_using_only_sherds.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .addCriterion(
                "pot_crafted_using_only_sherds",
                RecipeCraftedTrigger.TriggerInstance.craftedItem(
                    ResourceKey.create(Registries.RECIPE, Identifier.withDefaultNamespace("decorated_pot")),
                    List.of(
                        ItemPredicate.Builder.item().of(items, ItemTags.DECORATED_POT_SHERDS),
                        ItemPredicate.Builder.item().of(items, ItemTags.DECORATED_POT_SHERDS),
                        ItemPredicate.Builder.item().of(items, ItemTags.DECORATED_POT_SHERDS),
                        ItemPredicate.Builder.item().of(items, ItemTags.DECORATED_POT_SHERDS)
                    )
                )
            )
            .save(output, "adventure/craft_decorated_pot_using_only_sherds");
        AdvancementHolder craftingANewLook = craftingANewLook(Advancement.Builder.advancement())
            .parent(root)
            .display(
                Items.DUNE_ARMOR_TRIM_SMITHING_TEMPLATE,
                Component.translatable("advancements.adventure.trim_with_any_armor_pattern.title"),
                Component.translatable("advancements.adventure.trim_with_any_armor_pattern.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .save(output, "adventure/trim_with_any_armor_pattern");
        smithingWithStyle(Advancement.Builder.advancement())
            .parent(craftingANewLook)
            .display(
                Items.SILENCE_ARMOR_TRIM_SMITHING_TEMPLATE,
                Component.translatable("advancements.adventure.trim_with_all_exclusive_armor_patterns.title"),
                Component.translatable("advancements.adventure.trim_with_all_exclusive_armor_patterns.description"),
                null,
                AdvancementType.CHALLENGE,
                true,
                true,
                false
            )
            .rewards(AdvancementRewards.Builder.experience(150))
            .save(output, "adventure/trim_with_all_exclusive_armor_patterns");
        Advancement.Builder.advancement()
            .parent(root)
            .display(
                Items.CHISELED_BOOKSHELF,
                Component.translatable("advancements.adventure.read_power_from_chiseled_bookshelf.title"),
                Component.translatable("advancements.adventure.read_power_from_chiseled_bookshelf.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .requirements(AdvancementRequirements.Strategy.OR)
            .addCriterion("chiseled_bookshelf", placedBlockReadByComparator(blocks, Blocks.CHISELED_BOOKSHELF))
            .addCriterion("comparator", placedComparatorReadingBlock(blocks, Blocks.CHISELED_BOOKSHELF))
            .save(output, "adventure/read_power_of_chiseled_bookshelf");
        Advancement.Builder.advancement()
            .parent(root)
            .display(
                Items.ARMADILLO_SCUTE,
                Component.translatable("advancements.adventure.brush_armadillo.title"),
                Component.translatable("advancements.adventure.brush_armadillo.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .addCriterion(
                "brush_armadillo",
                PlayerInteractTrigger.TriggerInstance.itemUsedOnEntity(
                    ItemPredicate.Builder.item().of(items, Items.BRUSH),
                    Optional.of(EntityPredicate.wrap(EntityPredicate.Builder.entity().of(entityTypes, EntityType.ARMADILLO)))
                )
            )
            .save(output, "adventure/brush_armadillo");
        AdvancementHolder trialsEdition = Advancement.Builder.advancement()
            .parent(root)
            .display(
                Blocks.CHISELED_TUFF,
                Component.translatable("advancements.adventure.minecraft_trials_edition.title"),
                Component.translatable("advancements.adventure.minecraft_trials_edition.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .addCriterion(
                "minecraft_trials_edition",
                PlayerTrigger.TriggerInstance.located(
                    LocationPredicate.Builder.inStructure(registries.lookupOrThrow(Registries.STRUCTURE).getOrThrow(BuiltinStructures.TRIAL_CHAMBERS))
                )
            )
            .save(output, "adventure/minecraft_trials_edition");
        Advancement.Builder.advancement()
            .parent(trialsEdition)
            .display(
                Items.COPPER_BULB,
                Component.translatable("advancements.adventure.lighten_up.title"),
                Component.translatable("advancements.adventure.lighten_up.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .addCriterion(
                "lighten_up",
                ItemUsedOnLocationTrigger.TriggerInstance.itemUsedOnBlock(
                    LocationPredicate.Builder.location()
                        .setBlock(
                            BlockPredicate.Builder.block()
                                .of(
                                    blocks,
                                    Blocks.OXIDIZED_COPPER_BULB,
                                    Blocks.WEATHERED_COPPER_BULB,
                                    Blocks.EXPOSED_COPPER_BULB,
                                    Blocks.WAXED_OXIDIZED_COPPER_BULB,
                                    Blocks.WAXED_WEATHERED_COPPER_BULB,
                                    Blocks.WAXED_EXPOSED_COPPER_BULB
                                )
                                .setProperties(StatePropertiesPredicate.Builder.properties().hasProperty(CopperBulbBlock.LIT, true))
                        ),
                    ItemPredicate.Builder.item().of(items, VanillaHusbandryAdvancements.WAX_SCRAPING_TOOLS)
                )
            )
            .save(output, "adventure/lighten_up");
        AdvancementHolder underLockAndKey = Advancement.Builder.advancement()
            .parent(trialsEdition)
            .display(
                Items.TRIAL_KEY,
                Component.translatable("advancements.adventure.under_lock_and_key.title"),
                Component.translatable("advancements.adventure.under_lock_and_key.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .addCriterion(
                "under_lock_and_key",
                ItemUsedOnLocationTrigger.TriggerInstance.itemUsedOnBlock(
                    LocationPredicate.Builder.location()
                        .setBlock(
                            BlockPredicate.Builder.block()
                                .of(blocks, Blocks.VAULT)
                                .setProperties(StatePropertiesPredicate.Builder.properties().hasProperty(VaultBlock.OMINOUS, false))
                        ),
                    ItemPredicate.Builder.item().of(items, Items.TRIAL_KEY)
                )
            )
            .save(output, "adventure/under_lock_and_key");
        Advancement.Builder.advancement()
            .parent(underLockAndKey)
            .display(
                Items.OMINOUS_TRIAL_KEY,
                Component.translatable("advancements.adventure.revaulting.title"),
                Component.translatable("advancements.adventure.revaulting.description"),
                null,
                AdvancementType.GOAL,
                true,
                true,
                false
            )
            .addCriterion(
                "revaulting",
                ItemUsedOnLocationTrigger.TriggerInstance.itemUsedOnBlock(
                    LocationPredicate.Builder.location()
                        .setBlock(
                            BlockPredicate.Builder.block()
                                .of(blocks, Blocks.VAULT)
                                .setProperties(StatePropertiesPredicate.Builder.properties().hasProperty(VaultBlock.OMINOUS, true))
                        ),
                    ItemPredicate.Builder.item().of(items, Items.OMINOUS_TRIAL_KEY)
                )
            )
            .save(output, "adventure/revaulting");
        Advancement.Builder.advancement()
            .parent(trialsEdition)
            .display(
                Items.WIND_CHARGE,
                Component.translatable("advancements.adventure.blowback.title"),
                Component.translatable("advancements.adventure.blowback.description"),
                null,
                AdvancementType.CHALLENGE,
                true,
                true,
                false
            )
            .rewards(AdvancementRewards.Builder.experience(40))
            .addCriterion(
                "blowback",
                KilledTrigger.TriggerInstance.playerKilledEntity(
                    EntityPredicate.Builder.entity().of(entityTypes, EntityType.BREEZE),
                    DamageSourcePredicate.Builder.damageType()
                        .tag(TagPredicate.is(DamageTypeTags.IS_PROJECTILE))
                        .direct(EntityPredicate.Builder.entity().of(entityTypes, EntityType.BREEZE_WIND_CHARGE))
                )
            )
            .save(output, "adventure/blowback");
        Advancement.Builder.advancement()
            .parent(root)
            .display(
                Items.CRAFTER,
                Component.translatable("advancements.adventure.crafters_crafting_crafters.title"),
                Component.translatable("advancements.adventure.crafters_crafting_crafters.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .addCriterion(
                "crafter_crafted_crafter",
                RecipeCraftedTrigger.TriggerInstance.crafterCraftedItem(ResourceKey.create(Registries.RECIPE, Identifier.withDefaultNamespace("crafter")))
            )
            .save(output, "adventure/crafters_crafting_crafters");
        Advancement.Builder.advancement()
            .parent(root)
            .display(
                Items.LODESTONE,
                Component.translatable("advancements.adventure.use_lodestone.title"),
                Component.translatable("advancements.adventure.use_lodestone.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .addCriterion(
                "use_lodestone",
                ItemUsedOnLocationTrigger.TriggerInstance.itemUsedOnBlock(
                    LocationPredicate.Builder.location().setBlock(BlockPredicate.Builder.block().of(blocks, Blocks.LODESTONE)),
                    ItemPredicate.Builder.item().of(items, Items.COMPASS)
                )
            )
            .save(output, "adventure/use_lodestone");
        Advancement.Builder.advancement()
            .parent(trialsEdition)
            .display(
                Items.WIND_CHARGE,
                Component.translatable("advancements.adventure.who_needs_rockets.title"),
                Component.translatable("advancements.adventure.who_needs_rockets.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .addCriterion(
                "who_needs_rockets",
                FallAfterExplosionTrigger.TriggerInstance.fallAfterExplosion(
                    DistancePredicate.vertical(MinMaxBounds.Doubles.atLeast(7.0)), EntityPredicate.Builder.entity().of(entityTypes, EntityType.WIND_CHARGE)
                )
            )
            .save(output, "adventure/who_needs_rockets");
        Advancement.Builder.advancement()
            .parent(trialsEdition)
            .display(
                Items.MACE,
                Component.translatable("advancements.adventure.overoverkill.title"),
                Component.translatable("advancements.adventure.overoverkill.description"),
                null,
                AdvancementType.CHALLENGE,
                true,
                true,
                false
            )
            .rewards(AdvancementRewards.Builder.experience(50))
            .addCriterion(
                "overoverkill",
                PlayerHurtEntityTrigger.TriggerInstance.playerHurtEntityWithDamage(
                    DamagePredicate.Builder.damageInstance()
                        .dealtDamage(MinMaxBounds.Doubles.atLeast(100.0))
                        .type(
                            DamageSourcePredicate.Builder.damageType()
                                .tag(TagPredicate.is(DamageTypeTags.IS_MACE_SMASH))
                                .direct(
                                    EntityPredicate.Builder.entity()
                                        .of(entityTypes, EntityType.PLAYER)
                                        .equipment(EntityEquipmentPredicate.Builder.equipment().mainhand(ItemPredicate.Builder.item().of(items, Items.MACE)))
                                )
                        )
                )
            )
            .save(output, "adventure/overoverkill");
        Advancement.Builder.advancement()
            .parent(root)
            .display(
                Blocks.CREAKING_HEART,
                Component.translatable("advancements.adventure.heart_transplanter.title"),
                Component.translatable("advancements.adventure.heart_transplanter.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .requirements(AdvancementRequirements.Strategy.OR)
            .addCriterion(
                "place_creaking_heart_dormant",
                ItemUsedOnLocationTrigger.TriggerInstance.placedBlockWithProperties(
                    Blocks.CREAKING_HEART, BlockStateProperties.CREAKING_HEART_STATE, CreakingHeartState.DORMANT
                )
            )
            .addCriterion(
                "place_creaking_heart_awake",
                ItemUsedOnLocationTrigger.TriggerInstance.placedBlockWithProperties(
                    Blocks.CREAKING_HEART, BlockStateProperties.CREAKING_HEART_STATE, CreakingHeartState.AWAKE
                )
            )
            .addCriterion("place_pale_oak_log", placedBlockActivatesCreakingHeart(blocks, BlockTags.PALE_OAK_LOGS))
            .save(output, "adventure/heart_transplanter");
    }
 
    public static AdvancementHolder createMonsterHunterAdvancement(
        AdvancementHolder parent, Consumer<AdvancementHolder> output, HolderGetter<EntityType<?>> entityTypes, List<EntityType<?>> mobsToKill
    ) {
        AdvancementHolder killAMob = addMobsToKill(Advancement.Builder.advancement(), entityTypes, mobsToKill)
            .parent(parent)
            .display(
                Items.IRON_SWORD,
                Component.translatable("advancements.adventure.kill_a_mob.title"),
                Component.translatable("advancements.adventure.kill_a_mob.description"),
                null,
                AdvancementType.TASK,
                true,
                true,
                false
            )
            .requirements(AdvancementRequirements.Strategy.OR)
            .save(output, "adventure/kill_a_mob");
        addMobsToKill(Advancement.Builder.advancement(), entityTypes, mobsToKill)
            .parent(killAMob)
            .display(
                Items.DIAMOND_SWORD,
                Component.translatable("advancements.adventure.kill_all_mobs.title"),
                Component.translatable("advancements.adventure.kill_all_mobs.description"),
                null,
                AdvancementType.CHALLENGE,
                true,
                true,
                false
            )
            .rewards(AdvancementRewards.Builder.experience(100))
            .save(output, "adventure/kill_all_mobs");
        return killAMob;
    }
 
    private static Criterion<ItemUsedOnLocationTrigger.TriggerInstance> placedBlockReadByComparator(HolderGetter<Block> blocks, Block block) {
        LootItemCondition.Builder[] conditions = ComparatorBlock.FACING
            .getPossibleValues()
            .stream()
            .map(
                direction -> {
                    StatePropertiesPredicate.Builder comparatorProperties = StatePropertiesPredicate.Builder.properties()
                        .hasProperty(ComparatorBlock.FACING, direction);
                    BlockPredicate.Builder comparatorTest = BlockPredicate.Builder.block().of(blocks, Blocks.COMPARATOR).setProperties(comparatorProperties);
                    return LocationCheck.checkLocation(
                        LocationPredicate.Builder.location().setBlock(comparatorTest), new BlockPos(direction.getOpposite().getUnitVec3i())
                    );
                }
            )
            .toArray(LootItemCondition.Builder[]::new);
        return ItemUsedOnLocationTrigger.TriggerInstance.placedBlock(
            LootItemBlockStatePropertyCondition.hasBlockStateProperties(block), AnyOfCondition.anyOf(conditions)
        );
    }
 
    private static Criterion<ItemUsedOnLocationTrigger.TriggerInstance> placedComparatorReadingBlock(HolderGetter<Block> blocks, Block block) {
        LootItemCondition.Builder[] conditions = ComparatorBlock.FACING
            .getPossibleValues()
            .stream()
            .map(
                direction -> {
                    StatePropertiesPredicate.Builder comparatorProperties = StatePropertiesPredicate.Builder.properties()
                        .hasProperty(ComparatorBlock.FACING, direction);
                    LootItemBlockStatePropertyCondition.Builder comparatorTest = new LootItemBlockStatePropertyCondition.Builder(Blocks.COMPARATOR)
                        .setProperties(comparatorProperties);
                    LootItemCondition.Builder blockTest = LocationCheck.checkLocation(
                        LocationPredicate.Builder.location().setBlock(BlockPredicate.Builder.block().of(blocks, block)), new BlockPos(direction.getUnitVec3i())
                    );
                    return AllOfCondition.allOf(comparatorTest, blockTest);
                }
            )
            .toArray(LootItemCondition.Builder[]::new);
        return ItemUsedOnLocationTrigger.TriggerInstance.placedBlock(AnyOfCondition.anyOf(conditions));
    }
 
    private static Criterion<ItemUsedOnLocationTrigger.TriggerInstance> placedBlockActivatesCreakingHeart(HolderGetter<Block> blocks, TagKey<Block> block) {
        LootItemCondition.Builder[] conditions = Stream.of(Direction.values())
            .map(
                direction -> {
                    StatePropertiesPredicate.Builder creakingHeartProperties = StatePropertiesPredicate.Builder.properties()
                        .hasProperty(CreakingHeartBlock.AXIS, direction.getAxis());
                    BlockPredicate.Builder placedPaleOakLogBlock = BlockPredicate.Builder.block().of(blocks, block).setProperties(creakingHeartProperties);
                    Vec3i blockOffset = direction.getUnitVec3i();
                    LootItemCondition.Builder placedPaleOakLogTest = LocationCheck.checkLocation(
                        LocationPredicate.Builder.location().setBlock(placedPaleOakLogBlock)
                    );
                    LootItemCondition.Builder creakingHeartBlockTest = LocationCheck.checkLocation(
                        LocationPredicate.Builder.location()
                            .setBlock(BlockPredicate.Builder.block().of(blocks, Blocks.CREAKING_HEART).setProperties(creakingHeartProperties)),
                        new BlockPos(blockOffset)
                    );
                    LootItemCondition.Builder existingPaleOakLogTest = LocationCheck.checkLocation(
                        LocationPredicate.Builder.location().setBlock(placedPaleOakLogBlock), new BlockPos(blockOffset.multiply(2))
                    );
                    return AllOfCondition.allOf(placedPaleOakLogTest, creakingHeartBlockTest, existingPaleOakLogTest);
                }
            )
            .toArray(LootItemCondition.Builder[]::new);
        return ItemUsedOnLocationTrigger.TriggerInstance.placedBlock(AnyOfCondition.anyOf(conditions));
    }
 
    private static Advancement.Builder smithingWithStyle(Advancement.Builder advancement) {
        advancement.requirements(AdvancementRequirements.Strategy.AND);
        Set<Item> required = Set.of(
            Items.SPIRE_ARMOR_TRIM_SMITHING_TEMPLATE,
            Items.SNOUT_ARMOR_TRIM_SMITHING_TEMPLATE,
            Items.RIB_ARMOR_TRIM_SMITHING_TEMPLATE,
            Items.WARD_ARMOR_TRIM_SMITHING_TEMPLATE,
            Items.SILENCE_ARMOR_TRIM_SMITHING_TEMPLATE,
            Items.VEX_ARMOR_TRIM_SMITHING_TEMPLATE,
            Items.TIDE_ARMOR_TRIM_SMITHING_TEMPLATE,
            Items.WAYFINDER_ARMOR_TRIM_SMITHING_TEMPLATE
        );
        VanillaRecipeProvider.smithingTrims()
            .filter(trim -> required.contains(trim.template()))
            .forEach(
                trimTemplate -> advancement.addCriterion(
                    "armor_trimmed_" + trimTemplate.recipeId().identifier(), RecipeCraftedTrigger.TriggerInstance.craftedItem(trimTemplate.recipeId())
                )
            );
        return advancement;
    }
 
    private static Advancement.Builder craftingANewLook(Advancement.Builder advancement) {
        advancement.requirements(AdvancementRequirements.Strategy.OR);
        VanillaRecipeProvider.smithingTrims()
            .map(VanillaRecipeProvider.TrimTemplate::recipeId)
            .forEach(
                recipeId -> advancement.addCriterion(
                    "armor_trimmed_" + recipeId.identifier(), RecipeCraftedTrigger.TriggerInstance.craftedItem((ResourceKey<Recipe<?>>)recipeId)
                )
            );
        return advancement;
    }
 
    private static Advancement.Builder respectingTheRemnantsCriterions(HolderGetter<Item> items, Advancement.Builder advancement) {
        List<Pair<String, Criterion<LootTableTrigger.TriggerInstance>>> lootCriteria = List.of(
            Pair.of("desert_pyramid", LootTableTrigger.TriggerInstance.lootTableUsed(BuiltInLootTables.DESERT_PYRAMID_ARCHAEOLOGY)),
            Pair.of("desert_well", LootTableTrigger.TriggerInstance.lootTableUsed(BuiltInLootTables.DESERT_WELL_ARCHAEOLOGY)),
            Pair.of("ocean_ruin_cold", LootTableTrigger.TriggerInstance.lootTableUsed(BuiltInLootTables.OCEAN_RUIN_COLD_ARCHAEOLOGY)),
            Pair.of("ocean_ruin_warm", LootTableTrigger.TriggerInstance.lootTableUsed(BuiltInLootTables.OCEAN_RUIN_WARM_ARCHAEOLOGY)),
            Pair.of("trail_ruins_rare", LootTableTrigger.TriggerInstance.lootTableUsed(BuiltInLootTables.TRAIL_RUINS_ARCHAEOLOGY_RARE)),
            Pair.of("trail_ruins_common", LootTableTrigger.TriggerInstance.lootTableUsed(BuiltInLootTables.TRAIL_RUINS_ARCHAEOLOGY_COMMON))
        );
        lootCriteria.forEach(p -> advancement.addCriterion(p.getFirst(), p.getSecond()));
        String hasSherdCriterion = "has_sherd";
        advancement.addCriterion(
            "has_sherd", InventoryChangeTrigger.TriggerInstance.hasItems(ItemPredicate.Builder.item().of(items, ItemTags.DECORATED_POT_SHERDS))
        );
        advancement.requirements(new AdvancementRequirements(List.of(lootCriteria.stream().map(Pair::getFirst).toList(), List.of("has_sherd"))));
        return advancement;
    }
 
    protected static void createAdventuringTime(
        HolderLookup.Provider registries, Consumer<AdvancementHolder> output, AdvancementHolder sleepInBed, MultiNoiseBiomeSourceParameterList.Preset preset
    ) {
        addBiomes(Advancement.Builder.advancement(), registries, preset.usedBiomes().toList())
            .parent(sleepInBed)
            .display(
                Items.DIAMOND_BOOTS,
                Component.translatable("advancements.adventure.adventuring_time.title"),
                Component.translatable("advancements.adventure.adventuring_time.description"),
                null,
                AdvancementType.CHALLENGE,
                true,
                true,
                false
            )
            .rewards(AdvancementRewards.Builder.experience(500))
            .save(output, "adventure/adventuring_time");
    }
 
    private static Advancement.Builder addMobsToKill(Advancement.Builder advancement, HolderGetter<EntityType<?>> entityTypes, List<EntityType<?>> mobsToKill) {
        mobsToKill.forEach(
            mob -> advancement.addCriterion(
                BuiltInRegistries.ENTITY_TYPE.getKey((EntityType<?>)mob).toString(),
                KilledTrigger.TriggerInstance.playerKilledEntity(EntityPredicate.Builder.entity().of(entityTypes, (EntityType<?>)mob))
            )
        );
        return advancement;
    }
 
    protected static Advancement.Builder addBiomes(Advancement.Builder advancement, HolderLookup.Provider registries, List<ResourceKey<Biome>> explorableBiomes) {
        HolderGetter<Biome> biomeRegistry = registries.lookupOrThrow(Registries.BIOME);
 
        for (ResourceKey<Biome> biome : explorableBiomes) {
            advancement.addCriterion(
                biome.identifier().toString(), PlayerTrigger.TriggerInstance.located(LocationPredicate.Builder.inBiome(biomeRegistry.getOrThrow(biome)))
            );
        }
 
        return advancement;
    }
 
    private static List<EntityType<?>> validateMobsToKill(List<EntityType<?>> data, HolderLookup<EntityType<?>> entityTypes) {
        List<String> errors = new ArrayList<>();
        Set<? extends EntityType<?>> mobsToKill = Set.copyOf(data);
        Set<MobCategory> specifiedCategories = mobsToKill.stream().map(EntityType::getCategory).collect(Collectors.toSet());
        Set<MobCategory> categoryDifference = Sets.symmetricDifference(EXCEPTIONS_BY_EXPECTED_CATEGORIES.keySet(), specifiedCategories);
        if (!categoryDifference.isEmpty()) {
            errors.add(
                "Found EntityType with MobCategory only in either expected exceptions or kill_all_mobs advancement: "
                    + categoryDifference.stream().map(Object::toString).sorted().collect(Collectors.joining(", "))
            );
        }
 
        Set<EntityType<?>> entityTypeOverlap = Sets.intersection(
            EXCEPTIONS_BY_EXPECTED_CATEGORIES.values().stream().flatMap(Collection::stream).collect(Collectors.toSet()), mobsToKill
        );
        if (!entityTypeOverlap.isEmpty()) {
            errors.add(
                "Found EntityType in both expected exceptions and kill_all_mobs advancement: "
                    + entityTypeOverlap.stream().map(Object::toString).sorted().collect(Collectors.joining(", "))
            );
        }
 
        Map<MobCategory, Set<EntityType<?>>> doNotKillByCategory = entityTypes.listElements()
            .map(Holder.Reference::value)
            .filter(Predicate.not(mobsToKill::contains))
            .collect(Collectors.groupingBy(EntityType::getCategory, Collectors.toSet()));
        EXCEPTIONS_BY_EXPECTED_CATEGORIES.forEach(
            (exceptedCategory, exceptedTypes) -> {
                Set<EntityType<?>> exceptedDiff = Sets.difference(doNotKillByCategory.getOrDefault(exceptedCategory, Set.of()), (Set<?>)exceptedTypes);
                if (!exceptedDiff.isEmpty()) {
                    errors.add(
                        String.format(
                            Locale.ROOT,
                            "Found (new?) EntityType with MobCategory %s which are in neither expected exceptions nor kill_all_mobs advancement: %s",
                            exceptedCategory,
                            exceptedDiff.stream().map(Object::toString).sorted().collect(Collectors.joining(", "))
                        )
                    );
                }
            }
        );
        if (!errors.isEmpty()) {
            errors.forEach(LOGGER::error);
            throw new IllegalStateException("Found inconsistencies with kill_all_mobs advancement");
        } else {
            return data;
        }
    }
}

引用的其他类

  • Advancement

    • 引用位置: 参数/方法调用/返回值
    • 关联成员: Advancement.Builder.advancement()
  • AdvancementHolder

    • 引用位置: 参数/返回值
  • AdvancementRequirements

    • 引用位置: 构造调用
    • 关联成员: AdvancementRequirements()
  • AdvancementRewards

    • 引用位置: 方法调用
    • 关联成员: AdvancementRewards.Builder.experience()
  • Criterion

    • 引用位置: 返回值
  • BlockPredicate

    • 引用位置: 方法调用
    • 关联成员: BlockPredicate.Builder.block()
  • ChanneledLightningTrigger

    • 引用位置: 方法调用
    • 关联成员: ChanneledLightningTrigger.TriggerInstance.channeledLightning()
  • DamagePredicate

    • 引用位置: 方法调用
    • 关联成员: DamagePredicate.Builder.damageInstance()
  • DamageSourcePredicate

    • 引用位置: 方法调用
    • 关联成员: DamageSourcePredicate.Builder.damageType()
  • DataComponentMatchers

    • 引用位置: 方法调用
    • 关联成员: DataComponentMatchers.Builder.components()
  • DistancePredicate

    • 引用位置: 方法调用
    • 关联成员: DistancePredicate.absolute(), DistancePredicate.horizontal(), DistancePredicate.vertical()
  • DistanceTrigger

    • 引用位置: 方法调用
    • 关联成员: DistanceTrigger.TriggerInstance.fallFromHeight()
  • EntityEquipmentPredicate

    • 引用位置: 方法调用
    • 关联成员: EntityEquipmentPredicate.Builder.equipment(), EntityEquipmentPredicate.captainPredicate()
  • EntityPredicate

    • 引用位置: 参数/方法调用
    • 关联成员: EntityPredicate.Builder.entity(), EntityPredicate.wrap()
  • FallAfterExplosionTrigger

    • 引用位置: 方法调用
    • 关联成员: FallAfterExplosionTrigger.TriggerInstance.fallAfterExplosion()
  • InventoryChangeTrigger

    • 引用位置: 方法调用
    • 关联成员: InventoryChangeTrigger.TriggerInstance.hasItems()
  • ItemPredicate

    • 引用位置: 参数/方法调用
    • 关联成员: ItemPredicate.Builder.item()
  • ItemUsedOnLocationTrigger

    • 引用位置: 方法调用/返回值
    • 关联成员: ItemUsedOnLocationTrigger.TriggerInstance.itemUsedOnBlock(), ItemUsedOnLocationTrigger.TriggerInstance.placedBlock(), ItemUsedOnLocationTrigger.TriggerInstance.placedBlockWithProperties()
  • KilledByArrowTrigger

    • 引用位置: 方法调用
    • 关联成员: KilledByArrowTrigger.TriggerInstance.crossbowKilled()
  • KilledTrigger

    • 引用位置: 方法调用
    • 关联成员: KilledTrigger.TriggerInstance.entityKilledPlayer(), KilledTrigger.TriggerInstance.playerKilledEntity(), KilledTrigger.TriggerInstance.playerKilledEntityNearSculkCatalyst()
  • LightningBoltPredicate

    • 引用位置: 方法调用
    • 关联成员: LightningBoltPredicate.blockSetOnFire()
  • LightningStrikeTrigger

    • 引用位置: 方法调用/返回值
    • 关联成员: LightningStrikeTrigger.TriggerInstance.lightningStrike()
  • LocationPredicate

    • 引用位置: 方法调用
    • 关联成员: LocationPredicate.Builder.atYLocation(), LocationPredicate.Builder.inBiome(), LocationPredicate.Builder.inStructure(), LocationPredicate.Builder.location()
  • LootTableTrigger

    • 引用位置: 方法调用
    • 关联成员: LootTableTrigger.TriggerInstance.lootTableUsed()
  • MinMaxBounds

    • 引用位置: 参数/方法调用
    • 关联成员: MinMaxBounds.Doubles.atLeast(), MinMaxBounds.Doubles.atMost(), MinMaxBounds.Ints.exactly()
  • PlayerHurtEntityTrigger

    • 引用位置: 方法调用
    • 关联成员: PlayerHurtEntityTrigger.TriggerInstance.playerHurtEntityWithDamage()
  • PlayerInteractTrigger

    • 引用位置: 方法调用
    • 关联成员: PlayerInteractTrigger.TriggerInstance.itemUsedOnEntity()
  • PlayerPredicate

    • 引用位置: 方法调用
    • 关联成员: PlayerPredicate.Builder.player()
  • PlayerTrigger

    • 引用位置: 方法调用
    • 关联成员: PlayerTrigger.TriggerInstance.avoidVibration(), PlayerTrigger.TriggerInstance.located(), PlayerTrigger.TriggerInstance.raidWon(), PlayerTrigger.TriggerInstance.sleptInBed(), PlayerTrigger.TriggerInstance.walkOnBlockWithEquipment()
  • RecipeCraftedTrigger

    • 引用位置: 方法调用
    • 关联成员: RecipeCraftedTrigger.TriggerInstance.craftedItem(), RecipeCraftedTrigger.TriggerInstance.crafterCraftedItem()
  • ShotCrossbowTrigger

    • 引用位置: 方法调用
    • 关联成员: ShotCrossbowTrigger.TriggerInstance.shotCrossbow()
  • SlideDownBlockTrigger

    • 引用位置: 方法调用
    • 关联成员: SlideDownBlockTrigger.TriggerInstance.slidesDownBlock()
  • SpearMobsTrigger

    • 引用位置: 方法调用
    • 关联成员: SpearMobsTrigger.TriggerInstance.spearMobs()
  • StatePropertiesPredicate

    • 引用位置: 方法调用
    • 关联成员: StatePropertiesPredicate.Builder.properties()
  • SummonedEntityTrigger

    • 引用位置: 方法调用
    • 关联成员: SummonedEntityTrigger.TriggerInstance.summonedEntity()
  • TagPredicate

    • 引用位置: 方法调用
    • 关联成员: TagPredicate.is()
  • TargetBlockTrigger

    • 引用位置: 方法调用
    • 关联成员: TargetBlockTrigger.TriggerInstance.targetHit()
  • TradeTrigger

    • 引用位置: 方法调用
    • 关联成员: TradeTrigger.TriggerInstance.tradedWithVillager()
  • UsedTotemTrigger

    • 引用位置: 方法调用
    • 关联成员: UsedTotemTrigger.TriggerInstance.usedTotem()
  • UsingItemTrigger

    • 引用位置: 方法调用/返回值
    • 关联成员: UsingItemTrigger.TriggerInstance.lookingAt()
  • BlockPos

    • 引用位置: 构造调用
    • 关联成员: BlockPos()
  • Direction

    • 引用位置: 方法调用
    • 关联成员: Direction.values()
  • HolderGetter

    • 引用位置: 参数
  • HolderLookup

    • 引用位置: 参数
  • HolderSet

    • 引用位置: 方法调用
    • 关联成员: HolderSet.direct()
  • JukeboxPlayablePredicate

    • 引用位置: 方法调用
    • 关联成员: JukeboxPlayablePredicate.any()
  • AdvancementSubProvider

    • 引用位置: 实现
  • VanillaRecipeProvider

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

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

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

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

    • 引用位置: 参数
  • EntityType

    • 引用位置: 参数/字段/返回值
  • MobCategory

    • 引用位置: 字段
  • Raid

    • 引用位置: 方法调用
    • 关联成员: Raid.getOminousBannerTemplate()
  • Item

    • 引用位置: 参数
  • Biome

    • 引用位置: 参数
  • MultiNoiseBiomeSourceParameterList

    • 引用位置: 参数
  • Block

    • 引用位置: 参数
  • DecoratedPotBlockEntity

    • 引用位置: 方法调用
    • 关联成员: DecoratedPotBlockEntity.createDecoratedPotTemplate()
  • PotDecorations

    • 引用位置: 构造调用
    • 关联成员: PotDecorations()
  • AllOfCondition

    • 引用位置: 方法调用
    • 关联成员: AllOfCondition.allOf()
  • AnyOfCondition

    • 引用位置: 方法调用
    • 关联成员: AnyOfCondition.anyOf()
  • LocationCheck

    • 引用位置: 方法调用
    • 关联成员: LocationCheck.checkLocation()
  • LootItemBlockStatePropertyCondition

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