BlockLootSubProvider.java

net.minecraft.data.loot.BlockLootSubProvider

信息

  • 全限定名:net.minecraft.data.loot.BlockLootSubProvider
  • 类型:public abstract class
  • 包:net.minecraft.data.loot
  • 源码路径:src/main/java/net/minecraft/data/loot/BlockLootSubProvider.java
  • 起始行号:L79
  • 实现:LootTableSubProvider
  • 职责:

    TODO

字段/常量

  • registries

    • 类型: HolderLookup.Provider
    • 修饰符: protected final
    • 源码定位: L80
    • 说明:

      TODO

  • explosionResistant

    • 类型: Set<Item>
    • 修饰符: private final
    • 源码定位: L81
    • 说明:

      TODO

  • enabledFeatures

    • 类型: FeatureFlagSet
    • 修饰符: private final
    • 源码定位: L82
    • 说明:

      TODO

  • map

    • 类型: Map<ResourceKey<LootTable>,LootTable.Builder>
    • 修饰符: private final
    • 源码定位: L83
    • 说明:

      TODO

  • NORMAL_LEAVES_SAPLING_CHANCES

    • 类型: float[]
    • 修饰符: protected static final
    • 源码定位: L84
    • 说明:

      TODO

  • NORMAL_LEAVES_STICK_CHANCES

    • 类型: float[]
    • 修饰符: private static final
    • 源码定位: L85
    • 说明:

      TODO

内部类/嵌套类型

构造器

protected BlockLootSubProvider(Set<Item> explosionResistant, FeatureFlagSet enabledFeatures, HolderLookup.Provider registries) @ L123

  • 构造器名:BlockLootSubProvider
  • 源码定位:L123
  • 修饰符:protected

参数:

  • explosionResistant: Set
  • enabledFeatures: FeatureFlagSet
  • registries: HolderLookup.Provider

说明:

TODO

方法

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

protected LootItemCondition.Builder hasSilkTouch() @ L87

  • 方法名:hasSilkTouch
  • 源码定位:L87
  • 返回类型:LootItemCondition.Builder
  • 修饰符:protected

参数:

说明:

TODO

protected LootItemCondition.Builder doesNotHaveSilkTouch() @ L107

  • 方法名:doesNotHaveSilkTouch
  • 源码定位:L107
  • 返回类型:LootItemCondition.Builder
  • 修饰符:protected

参数:

说明:

TODO

protected LootItemCondition.Builder hasShears() @ L111

  • 方法名:hasShears
  • 源码定位:L111
  • 返回类型:LootItemCondition.Builder
  • 修饰符:protected

参数:

说明:

TODO

private LootItemCondition.Builder hasShearsOrSilkTouch() @ L115

  • 方法名:hasShearsOrSilkTouch
  • 源码定位:L115
  • 返回类型:LootItemCondition.Builder
  • 修饰符:private

参数:

说明:

TODO

private LootItemCondition.Builder doesNotHaveShearsOrSilkTouch() @ L119

  • 方法名:doesNotHaveShearsOrSilkTouch
  • 源码定位:L119
  • 返回类型:LootItemCondition.Builder
  • 修饰符:private

参数:

说明:

TODO

protected <T extends FunctionUserBuilder<T>> T applyExplosionDecay(ItemLike type, FunctionUserBuilder<T> builder) @ L129

  • 方法名:applyExplosionDecay
  • 源码定位:L129
  • 返回类型:<T extends FunctionUserBuilder> T
  • 修饰符:protected

参数:

  • type: ItemLike
  • builder: FunctionUserBuilder

说明:

TODO

protected <T extends ConditionUserBuilder<T>> T applyExplosionCondition(ItemLike type, ConditionUserBuilder<T> builder) @ L133

  • 方法名:applyExplosionCondition
  • 源码定位:L133
  • 返回类型:<T extends ConditionUserBuilder> T
  • 修饰符:protected

参数:

  • type: ItemLike
  • builder: ConditionUserBuilder

说明:

TODO

public LootTable.Builder createSingleItemTable(ItemLike drop) @ L137

  • 方法名:createSingleItemTable
  • 源码定位:L137
  • 返回类型:LootTable.Builder
  • 修饰符:public

参数:

  • drop: ItemLike

说明:

TODO

private static LootTable.Builder createSelfDropDispatchTable(Block original, LootItemCondition.Builder condition, LootPoolEntryContainer.Builder<?> entry) @ L142

  • 方法名:createSelfDropDispatchTable
  • 源码定位:L142
  • 返回类型:LootTable.Builder
  • 修饰符:private static

参数:

  • original: Block
  • condition: LootItemCondition.Builder
  • entry: LootPoolEntryContainer.Builder<?>

说明:

TODO

protected LootTable.Builder createSilkTouchDispatchTable(Block original, LootPoolEntryContainer.Builder<?> entry) @ L147

  • 方法名:createSilkTouchDispatchTable
  • 源码定位:L147
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • original: Block
  • entry: LootPoolEntryContainer.Builder<?>

说明:

TODO

protected LootTable.Builder createShearsDispatchTable(Block original, LootPoolEntryContainer.Builder<?> entry) @ L151

  • 方法名:createShearsDispatchTable
  • 源码定位:L151
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • original: Block
  • entry: LootPoolEntryContainer.Builder<?>

说明:

TODO

protected LootTable.Builder createSilkTouchOrShearsDispatchTable(Block original, LootPoolEntryContainer.Builder<?> entry) @ L155

  • 方法名:createSilkTouchOrShearsDispatchTable
  • 源码定位:L155
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • original: Block
  • entry: LootPoolEntryContainer.Builder<?>

说明:

TODO

protected LootTable.Builder createSingleItemTableWithSilkTouch(Block original, ItemLike drop) @ L159

  • 方法名:createSingleItemTableWithSilkTouch
  • 源码定位:L159
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • original: Block
  • drop: ItemLike

说明:

TODO

protected LootTable.Builder createSingleItemTable(ItemLike drop, NumberProvider count) @ L165

  • 方法名:createSingleItemTable
  • 源码定位:L165
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • drop: ItemLike
  • count: NumberProvider

说明:

TODO

protected LootTable.Builder createSingleItemTableWithSilkTouch(Block original, ItemLike drop, NumberProvider count) @ L178

  • 方法名:createSingleItemTableWithSilkTouch
  • 源码定位:L178
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • original: Block
  • drop: ItemLike
  • count: NumberProvider

说明:

TODO

private LootTable.Builder createSilkTouchOnlyTable(ItemLike drop) @ L185

  • 方法名:createSilkTouchOnlyTable
  • 源码定位:L185
  • 返回类型:LootTable.Builder
  • 修饰符:private

参数:

  • drop: ItemLike

说明:

TODO

private LootTable.Builder createPotFlowerItemTable(ItemLike flower) @ L190

  • 方法名:createPotFlowerItemTable
  • 源码定位:L190
  • 返回类型:LootTable.Builder
  • 修饰符:private

参数:

  • flower: ItemLike

说明:

TODO

protected LootTable.Builder createSlabItemTable(Block slab) @ L200

  • 方法名:createSlabItemTable
  • 源码定位:L200
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • slab: Block

说明:

TODO

protected <T extends Comparable<T> &StringRepresentable> LootTable.Builder createSinglePropConditionTable(Block drop, Property<T> property, T value) @ L221

  • 方法名:createSinglePropConditionTable
  • 源码定位:L221
  • 返回类型:<T extends Comparable &StringRepresentable> LootTable.Builder
  • 修饰符:protected

参数:

  • drop: Block
  • property: Property
  • value: T

说明:

TODO

protected LootTable.Builder createNameableBlockEntityTable(Block drop) @ L239

  • 方法名:createNameableBlockEntityTable
  • 源码定位:L239
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • drop: Block

说明:

TODO

protected LootTable.Builder createShulkerBoxDrop(Block shulkerBox) @ L254

  • 方法名:createShulkerBoxDrop
  • 源码定位:L254
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • shulkerBox: Block

说明:

TODO

protected LootTable.Builder createCopperOreDrops(Block block) @ L275

  • 方法名:createCopperOreDrops
  • 源码定位:L275
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • block: Block

说明:

TODO

protected LootTable.Builder createLapisOreDrops(Block block) @ L288

  • 方法名:createLapisOreDrops
  • 源码定位:L288
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • block: Block

说明:

TODO

protected LootTable.Builder createRedstoneOreDrops(Block block) @ L301

  • 方法名:createRedstoneOreDrops
  • 源码定位:L301
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • block: Block

说明:

TODO

protected LootTable.Builder createBannerDrop(Block original) @ L314

  • 方法名:createBannerDrop
  • 源码定位:L314
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • original: Block

说明:

TODO

protected LootTable.Builder createBeeNestDrop(Block original) @ L336

  • 方法名:createBeeNestDrop
  • 源码定位:L336
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • original: Block

说明:

TODO

protected LootTable.Builder createBeeHiveDrop(Block original) @ L350

  • 方法名:createBeeHiveDrop
  • 源码定位:L350
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • original: Block

说明:

TODO

protected LootTable.Builder createCaveVinesDrop(Block original) @ L365

  • 方法名:createCaveVinesDrop
  • 源码定位:L365
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • original: Block

说明:

TODO

protected LootTable.Builder createCopperGolemStatueBlock(Block block) @ L377

  • 方法名:createCopperGolemStatueBlock
  • 源码定位:L377
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • block: Block

说明:

TODO

protected LootTable.Builder createOreDrop(Block original, Item drop) @ L393

  • 方法名:createOreDrop
  • 源码定位:L393
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • original: Block
  • drop: Item

说明:

TODO

protected LootTable.Builder createMushroomBlockDrop(Block original, ItemLike drop) @ L403

  • 方法名:createMushroomBlockDrop
  • 源码定位:L403
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • original: Block
  • drop: ItemLike

说明:

TODO

protected LootTable.Builder createGrassDrops(Block original) @ L415

  • 方法名:createGrassDrops
  • 源码定位:L415
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • original: Block

说明:

TODO

public LootTable.Builder createStemDrops(Block block, Item drop) @ L428

  • 方法名:createStemDrops
  • 源码定位:L428
  • 返回类型:LootTable.Builder
  • 修饰符:public

参数:

  • block: Block
  • drop: Item

说明:

TODO

public LootTable.Builder createAttachedStemDrops(Block block, Item drop) @ L450

  • 方法名:createAttachedStemDrops
  • 源码定位:L450
  • 返回类型:LootTable.Builder
  • 修饰符:public

参数:

  • block: Block
  • drop: Item

说明:

TODO

protected LootTable.Builder createShearsOnlyDrop(ItemLike drop) @ L462

  • 方法名:createShearsOnlyDrop
  • 源码定位:L462
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • drop: ItemLike

说明:

TODO

protected LootTable.Builder createShearsOrSilkTouchOnlyDrop(ItemLike drop) @ L467

  • 方法名:createShearsOrSilkTouchOnlyDrop
  • 源码定位:L467
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • drop: ItemLike

说明:

TODO

protected LootTable.Builder createMultifaceBlockDrops(Block block, LootItemCondition.Builder condition) @ L472

  • 方法名:createMultifaceBlockDrops
  • 源码定位:L472
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • block: Block
  • condition: LootItemCondition.Builder

说明:

TODO

protected LootTable.Builder createMultifaceBlockDrops(Block block) @ L497

  • 方法名:createMultifaceBlockDrops
  • 源码定位:L497
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • block: Block

说明:

TODO

protected LootTable.Builder createMossyCarpetBlockDrops(Block block) @ L521

  • 方法名:createMossyCarpetBlockDrops
  • 源码定位:L521
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • block: Block

说明:

TODO

protected LootTable.Builder createLeavesDrops(Block original, Block sapling, float... saplingChances) @ L538

  • 方法名:createLeavesDrops
  • 源码定位:L538
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • original: Block
  • sapling: Block
  • saplingChances: float…

说明:

TODO

protected LootTable.Builder createOakLeavesDrops(Block original, Block sapling, float... saplingChances) @ L558

  • 方法名:createOakLeavesDrops
  • 源码定位:L558
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • original: Block
  • sapling: Block
  • saplingChances: float…

说明:

TODO

protected LootTable.Builder createMangroveLeavesDrops(Block block) @ L576

  • 方法名:createMangroveLeavesDrops
  • 源码定位:L576
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • block: Block

说明:

TODO

protected LootTable.Builder createCropDrops(Block original, Item cropDrop, Item seedDrop, LootItemCondition.Builder isMaxAge) @ L587

  • 方法名:createCropDrops
  • 源码定位:L587
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • original: Block
  • cropDrop: Item
  • seedDrop: Item
  • isMaxAge: LootItemCondition.Builder

说明:

TODO

protected LootTable.Builder createDoublePlantShearsDrop(Block block) @ L604

  • 方法名:createDoublePlantShearsDrop
  • 源码定位:L604
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • block: Block

说明:

TODO

protected LootTable.Builder createDoublePlantWithSeedDrops(Block block, Block drop) @ L611

  • 方法名:createDoublePlantWithSeedDrops
  • 源码定位:L611
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • block: Block
  • drop: Block

说明:

TODO

protected LootTable.Builder createCandleDrops(Block block) @ L661

  • 方法名:createCandleDrops
  • 源码定位:L661
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • block: Block

说明:

TODO

public LootTable.Builder createSegmentedBlockDrops(Block block) @ L683

  • 方法名:createSegmentedBlockDrops
  • 源码定位:L683
  • 返回类型:LootTable.Builder
  • 修饰符:public

参数:

  • block: Block

说明:

TODO

protected static LootTable.Builder createCandleCakeDrops(Block candle) @ L710

  • 方法名:createCandleCakeDrops
  • 源码定位:L710
  • 返回类型:LootTable.Builder
  • 修饰符:protected static

参数:

  • candle: Block

说明:

TODO

public static LootTable.Builder noDrop() @ L714

  • 方法名:noDrop
  • 源码定位:L714
  • 返回类型:LootTable.Builder
  • 修饰符:public static

参数:

说明:

TODO

protected abstract void generate() @ L718

  • 方法名:generate
  • 源码定位:L718
  • 返回类型:void
  • 修饰符:protected abstract

参数:

说明:

TODO

public void generate(BiConsumer<ResourceKey<LootTable>,LootTable.Builder> output) @ L720

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

参数:

  • output: BiConsumer<ResourceKey,LootTable.Builder>

说明:

TODO

protected void addNetherVinesDropTable(Block vineBlock, Block plantBlock) @ L752

  • 方法名:addNetherVinesDropTable
  • 源码定位:L752
  • 返回类型:void
  • 修饰符:protected

参数:

  • vineBlock: Block
  • plantBlock: Block

说明:

TODO

protected LootTable.Builder createDoorTable(Block block) @ L763

  • 方法名:createDoorTable
  • 源码定位:L763
  • 返回类型:LootTable.Builder
  • 修饰符:protected

参数:

  • block: Block

说明:

TODO

protected void dropPottedContents(Block potted) @ L767

  • 方法名:dropPottedContents
  • 源码定位:L767
  • 返回类型:void
  • 修饰符:protected

参数:

  • potted: Block

说明:

TODO

protected void otherWhenSilkTouch(Block block, Block other) @ L771

  • 方法名:otherWhenSilkTouch
  • 源码定位:L771
  • 返回类型:void
  • 修饰符:protected

参数:

  • block: Block
  • other: Block

说明:

TODO

protected void dropOther(Block block, ItemLike drop) @ L775

  • 方法名:dropOther
  • 源码定位:L775
  • 返回类型:void
  • 修饰符:protected

参数:

  • block: Block
  • drop: ItemLike

说明:

TODO

protected void dropWhenSilkTouch(Block block) @ L779

  • 方法名:dropWhenSilkTouch
  • 源码定位:L779
  • 返回类型:void
  • 修饰符:protected

参数:

  • block: Block

说明:

TODO

protected void dropSelf(Block block) @ L783

  • 方法名:dropSelf
  • 源码定位:L783
  • 返回类型:void
  • 修饰符:protected

参数:

  • block: Block

说明:

TODO

protected void add(Block block, Function<Block,LootTable.Builder> builder) @ L787

  • 方法名:add
  • 源码定位:L787
  • 返回类型:void
  • 修饰符:protected

参数:

  • block: Block
  • builder: Function<Block,LootTable.Builder>

说明:

TODO

protected void add(Block block, LootTable.Builder builder) @ L791

  • 方法名:add
  • 源码定位:L791
  • 返回类型:void
  • 修饰符:protected

参数:

  • block: Block
  • builder: LootTable.Builder

说明:

TODO

代码

public abstract class BlockLootSubProvider implements LootTableSubProvider {
    protected final HolderLookup.Provider registries;
    private final Set<Item> explosionResistant;
    private final FeatureFlagSet enabledFeatures;
    private final Map<ResourceKey<LootTable>, LootTable.Builder> map = new HashMap<>();
    protected static final float[] NORMAL_LEAVES_SAPLING_CHANCES = new float[]{0.05F, 0.0625F, 0.083333336F, 0.1F};
    private static final float[] NORMAL_LEAVES_STICK_CHANCES = new float[]{0.02F, 0.022222223F, 0.025F, 0.033333335F, 0.1F};
 
    protected LootItemCondition.Builder hasSilkTouch() {
        return MatchTool.toolMatches(
            ItemPredicate.Builder.item()
                .withComponents(
                    DataComponentMatchers.Builder.components()
                        .partial(
                            DataComponentPredicates.ENCHANTMENTS,
                            EnchantmentsPredicate.enchantments(
                                List.of(
                                    new EnchantmentPredicate(
                                        this.registries.lookupOrThrow(Registries.ENCHANTMENT).getOrThrow(Enchantments.SILK_TOUCH), MinMaxBounds.Ints.atLeast(1)
                                    )
                                )
                            )
                        )
                        .build()
                )
        );
    }
 
    protected LootItemCondition.Builder doesNotHaveSilkTouch() {
        return this.hasSilkTouch().invert();
    }
 
    protected LootItemCondition.Builder hasShears() {
        return MatchTool.toolMatches(ItemPredicate.Builder.item().of(this.registries.lookupOrThrow(Registries.ITEM), Items.SHEARS));
    }
 
    private LootItemCondition.Builder hasShearsOrSilkTouch() {
        return this.hasShears().or(this.hasSilkTouch());
    }
 
    private LootItemCondition.Builder doesNotHaveShearsOrSilkTouch() {
        return this.hasShearsOrSilkTouch().invert();
    }
 
    protected BlockLootSubProvider(Set<Item> explosionResistant, FeatureFlagSet enabledFeatures, HolderLookup.Provider registries) {
        this.explosionResistant = explosionResistant;
        this.enabledFeatures = enabledFeatures;
        this.registries = registries;
    }
 
    protected <T extends FunctionUserBuilder<T>> T applyExplosionDecay(ItemLike type, FunctionUserBuilder<T> builder) {
        return !this.explosionResistant.contains(type.asItem()) ? builder.apply(ApplyExplosionDecay.explosionDecay()) : builder.unwrap();
    }
 
    protected <T extends ConditionUserBuilder<T>> T applyExplosionCondition(ItemLike type, ConditionUserBuilder<T> builder) {
        return !this.explosionResistant.contains(type.asItem()) ? builder.when(ExplosionCondition.survivesExplosion()) : builder.unwrap();
    }
 
    public LootTable.Builder createSingleItemTable(ItemLike drop) {
        return LootTable.lootTable()
            .withPool(this.applyExplosionCondition(drop, LootPool.lootPool().setRolls(ConstantValue.exactly(1.0F)).add(LootItem.lootTableItem(drop))));
    }
 
    private static LootTable.Builder createSelfDropDispatchTable(Block original, LootItemCondition.Builder condition, LootPoolEntryContainer.Builder<?> entry) {
        return LootTable.lootTable()
            .withPool(LootPool.lootPool().setRolls(ConstantValue.exactly(1.0F)).add(LootItem.lootTableItem(original).when(condition).otherwise(entry)));
    }
 
    protected LootTable.Builder createSilkTouchDispatchTable(Block original, LootPoolEntryContainer.Builder<?> entry) {
        return createSelfDropDispatchTable(original, this.hasSilkTouch(), entry);
    }
 
    protected LootTable.Builder createShearsDispatchTable(Block original, LootPoolEntryContainer.Builder<?> entry) {
        return createSelfDropDispatchTable(original, this.hasShears(), entry);
    }
 
    protected LootTable.Builder createSilkTouchOrShearsDispatchTable(Block original, LootPoolEntryContainer.Builder<?> entry) {
        return createSelfDropDispatchTable(original, this.hasShearsOrSilkTouch(), entry);
    }
 
    protected LootTable.Builder createSingleItemTableWithSilkTouch(Block original, ItemLike drop) {
        return this.createSilkTouchDispatchTable(
            original, (LootPoolEntryContainer.Builder<?>)this.applyExplosionCondition(original, LootItem.lootTableItem(drop))
        );
    }
 
    protected LootTable.Builder createSingleItemTable(ItemLike drop, NumberProvider count) {
        return LootTable.lootTable()
            .withPool(
                LootPool.lootPool()
                    .setRolls(ConstantValue.exactly(1.0F))
                    .add(
                        (LootPoolEntryContainer.Builder<?>)this.applyExplosionDecay(
                            drop, LootItem.lootTableItem(drop).apply(SetItemCountFunction.setCount(count))
                        )
                    )
            );
    }
 
    protected LootTable.Builder createSingleItemTableWithSilkTouch(Block original, ItemLike drop, NumberProvider count) {
        return this.createSilkTouchDispatchTable(
            original,
            (LootPoolEntryContainer.Builder<?>)this.applyExplosionDecay(original, LootItem.lootTableItem(drop).apply(SetItemCountFunction.setCount(count)))
        );
    }
 
    private LootTable.Builder createSilkTouchOnlyTable(ItemLike drop) {
        return LootTable.lootTable()
            .withPool(LootPool.lootPool().when(this.hasSilkTouch()).setRolls(ConstantValue.exactly(1.0F)).add(LootItem.lootTableItem(drop)));
    }
 
    private LootTable.Builder createPotFlowerItemTable(ItemLike flower) {
        return LootTable.lootTable()
            .withPool(
                this.applyExplosionCondition(
                    Blocks.FLOWER_POT, LootPool.lootPool().setRolls(ConstantValue.exactly(1.0F)).add(LootItem.lootTableItem(Blocks.FLOWER_POT))
                )
            )
            .withPool(this.applyExplosionCondition(flower, LootPool.lootPool().setRolls(ConstantValue.exactly(1.0F)).add(LootItem.lootTableItem(flower))));
    }
 
    protected LootTable.Builder createSlabItemTable(Block slab) {
        return LootTable.lootTable()
            .withPool(
                LootPool.lootPool()
                    .setRolls(ConstantValue.exactly(1.0F))
                    .add(
                        (LootPoolEntryContainer.Builder<?>)this.applyExplosionDecay(
                            slab,
                            LootItem.lootTableItem(slab)
                                .apply(
                                    SetItemCountFunction.setCount(ConstantValue.exactly(2.0F))
                                        .when(
                                            LootItemBlockStatePropertyCondition.hasBlockStateProperties(slab)
                                                .setProperties(StatePropertiesPredicate.Builder.properties().hasProperty(SlabBlock.TYPE, SlabType.DOUBLE))
                                        )
                                )
                        )
                    )
            );
    }
 
    protected <T extends Comparable<T> & StringRepresentable> LootTable.Builder createSinglePropConditionTable(Block drop, Property<T> property, T value) {
        return LootTable.lootTable()
            .withPool(
                this.applyExplosionCondition(
                    drop,
                    LootPool.lootPool()
                        .setRolls(ConstantValue.exactly(1.0F))
                        .add(
                            LootItem.lootTableItem(drop)
                                .when(
                                    LootItemBlockStatePropertyCondition.hasBlockStateProperties(drop)
                                        .setProperties(StatePropertiesPredicate.Builder.properties().hasProperty(property, value))
                                )
                        )
                )
            );
    }
 
    protected LootTable.Builder createNameableBlockEntityTable(Block drop) {
        return LootTable.lootTable()
            .withPool(
                this.applyExplosionCondition(
                    drop,
                    LootPool.lootPool()
                        .setRolls(ConstantValue.exactly(1.0F))
                        .add(
                            LootItem.lootTableItem(drop)
                                .apply(CopyComponentsFunction.copyComponentsFromBlockEntity(LootContextParams.BLOCK_ENTITY).include(DataComponents.CUSTOM_NAME))
                        )
                )
            );
    }
 
    protected LootTable.Builder createShulkerBoxDrop(Block shulkerBox) {
        return LootTable.lootTable()
            .withPool(
                this.applyExplosionCondition(
                    shulkerBox,
                    LootPool.lootPool()
                        .setRolls(ConstantValue.exactly(1.0F))
                        .add(
                            LootItem.lootTableItem(shulkerBox)
                                .apply(
                                    CopyComponentsFunction.copyComponentsFromBlockEntity(LootContextParams.BLOCK_ENTITY)
                                        .include(DataComponents.CUSTOM_NAME)
                                        .include(DataComponents.CONTAINER)
                                        .include(DataComponents.LOCK)
                                        .include(DataComponents.CONTAINER_LOOT)
                                )
                        )
                )
            );
    }
 
    protected LootTable.Builder createCopperOreDrops(Block block) {
        HolderLookup.RegistryLookup<Enchantment> enchantments = this.registries.lookupOrThrow(Registries.ENCHANTMENT);
        return this.createSilkTouchDispatchTable(
            block,
            (LootPoolEntryContainer.Builder<?>)this.applyExplosionDecay(
                block,
                LootItem.lootTableItem(Items.RAW_COPPER)
                    .apply(SetItemCountFunction.setCount(UniformGenerator.between(2.0F, 5.0F)))
                    .apply(ApplyBonusCount.addOreBonusCount(enchantments.getOrThrow(Enchantments.FORTUNE)))
            )
        );
    }
 
    protected LootTable.Builder createLapisOreDrops(Block block) {
        HolderLookup.RegistryLookup<Enchantment> enchantments = this.registries.lookupOrThrow(Registries.ENCHANTMENT);
        return this.createSilkTouchDispatchTable(
            block,
            (LootPoolEntryContainer.Builder<?>)this.applyExplosionDecay(
                block,
                LootItem.lootTableItem(Items.LAPIS_LAZULI)
                    .apply(SetItemCountFunction.setCount(UniformGenerator.between(4.0F, 9.0F)))
                    .apply(ApplyBonusCount.addOreBonusCount(enchantments.getOrThrow(Enchantments.FORTUNE)))
            )
        );
    }
 
    protected LootTable.Builder createRedstoneOreDrops(Block block) {
        HolderLookup.RegistryLookup<Enchantment> enchantments = this.registries.lookupOrThrow(Registries.ENCHANTMENT);
        return this.createSilkTouchDispatchTable(
            block,
            (LootPoolEntryContainer.Builder<?>)this.applyExplosionDecay(
                block,
                LootItem.lootTableItem(Items.REDSTONE)
                    .apply(SetItemCountFunction.setCount(UniformGenerator.between(4.0F, 5.0F)))
                    .apply(ApplyBonusCount.addUniformBonusCount(enchantments.getOrThrow(Enchantments.FORTUNE)))
            )
        );
    }
 
    protected LootTable.Builder createBannerDrop(Block original) {
        return LootTable.lootTable()
            .withPool(
                this.applyExplosionCondition(
                    original,
                    LootPool.lootPool()
                        .setRolls(ConstantValue.exactly(1.0F))
                        .add(
                            LootItem.lootTableItem(original)
                                .apply(
                                    CopyComponentsFunction.copyComponentsFromBlockEntity(LootContextParams.BLOCK_ENTITY)
                                        .include(DataComponents.CUSTOM_NAME)
                                        .include(DataComponents.ITEM_NAME)
                                        .include(DataComponents.TOOLTIP_DISPLAY)
                                        .include(DataComponents.BANNER_PATTERNS)
                                        .include(DataComponents.RARITY)
                                )
                        )
                )
            );
    }
 
    protected LootTable.Builder createBeeNestDrop(Block original) {
        return LootTable.lootTable()
            .withPool(
                LootPool.lootPool()
                    .when(this.hasSilkTouch())
                    .setRolls(ConstantValue.exactly(1.0F))
                    .add(
                        LootItem.lootTableItem(original)
                            .apply(CopyComponentsFunction.copyComponentsFromBlockEntity(LootContextParams.BLOCK_ENTITY).include(DataComponents.BEES))
                            .apply(CopyBlockState.copyState(original).copy(BeehiveBlock.HONEY_LEVEL))
                    )
            );
    }
 
    protected LootTable.Builder createBeeHiveDrop(Block original) {
        return LootTable.lootTable()
            .withPool(
                LootPool.lootPool()
                    .setRolls(ConstantValue.exactly(1.0F))
                    .add(
                        LootItem.lootTableItem(original)
                            .when(this.hasSilkTouch())
                            .apply(CopyComponentsFunction.copyComponentsFromBlockEntity(LootContextParams.BLOCK_ENTITY).include(DataComponents.BEES))
                            .apply(CopyBlockState.copyState(original).copy(BeehiveBlock.HONEY_LEVEL))
                            .otherwise(LootItem.lootTableItem(original))
                    )
            );
    }
 
    protected LootTable.Builder createCaveVinesDrop(Block original) {
        return LootTable.lootTable()
            .withPool(
                LootPool.lootPool()
                    .add(LootItem.lootTableItem(Items.GLOW_BERRIES))
                    .when(
                        LootItemBlockStatePropertyCondition.hasBlockStateProperties(original)
                            .setProperties(StatePropertiesPredicate.Builder.properties().hasProperty(CaveVines.BERRIES, true))
                    )
            );
    }
 
    protected LootTable.Builder createCopperGolemStatueBlock(Block block) {
        return LootTable.lootTable()
            .withPool(
                this.applyExplosionCondition(
                    block,
                    LootPool.lootPool()
                        .setRolls(ConstantValue.exactly(1.0F))
                        .add(
                            LootItem.lootTableItem(block)
                                .apply(CopyComponentsFunction.copyComponentsFromBlockEntity(LootContextParams.BLOCK_ENTITY).include(DataComponents.CUSTOM_NAME))
                                .apply(CopyBlockState.copyState(block).copy(CopperGolemStatueBlock.POSE))
                        )
                )
            );
    }
 
    protected LootTable.Builder createOreDrop(Block original, Item drop) {
        HolderLookup.RegistryLookup<Enchantment> enchantments = this.registries.lookupOrThrow(Registries.ENCHANTMENT);
        return this.createSilkTouchDispatchTable(
            original,
            (LootPoolEntryContainer.Builder<?>)this.applyExplosionDecay(
                original, LootItem.lootTableItem(drop).apply(ApplyBonusCount.addOreBonusCount(enchantments.getOrThrow(Enchantments.FORTUNE)))
            )
        );
    }
 
    protected LootTable.Builder createMushroomBlockDrop(Block original, ItemLike drop) {
        return this.createSilkTouchDispatchTable(
            original,
            (LootPoolEntryContainer.Builder<?>)this.applyExplosionDecay(
                original,
                LootItem.lootTableItem(drop)
                    .apply(SetItemCountFunction.setCount(UniformGenerator.between(-6.0F, 2.0F)))
                    .apply(LimitCount.limitCount(IntRange.lowerBound(0)))
            )
        );
    }
 
    protected LootTable.Builder createGrassDrops(Block original) {
        HolderLookup.RegistryLookup<Enchantment> enchantments = this.registries.lookupOrThrow(Registries.ENCHANTMENT);
        return this.createShearsDispatchTable(
            original,
            (LootPoolEntryContainer.Builder<?>)this.applyExplosionDecay(
                original,
                LootItem.lootTableItem(Items.WHEAT_SEEDS)
                    .when(LootItemRandomChanceCondition.randomChance(0.125F))
                    .apply(ApplyBonusCount.addUniformBonusCount(enchantments.getOrThrow(Enchantments.FORTUNE), 2))
            )
        );
    }
 
    public LootTable.Builder createStemDrops(Block block, Item drop) {
        return LootTable.lootTable()
            .withPool(
                this.applyExplosionDecay(
                    block,
                    LootPool.lootPool()
                        .setRolls(ConstantValue.exactly(1.0F))
                        .add(
                            LootItem.lootTableItem(drop)
                                .apply(
                                    StemBlock.AGE.getPossibleValues(),
                                    age -> SetItemCountFunction.setCount(BinomialDistributionGenerator.binomial(3, (age + 1) / 15.0F))
                                        .when(
                                            LootItemBlockStatePropertyCondition.hasBlockStateProperties(block)
                                                .setProperties(StatePropertiesPredicate.Builder.properties().hasProperty(StemBlock.AGE, age.intValue()))
                                        )
                                )
                        )
                )
            );
    }
 
    public LootTable.Builder createAttachedStemDrops(Block block, Item drop) {
        return LootTable.lootTable()
            .withPool(
                this.applyExplosionDecay(
                    block,
                    LootPool.lootPool()
                        .setRolls(ConstantValue.exactly(1.0F))
                        .add(LootItem.lootTableItem(drop).apply(SetItemCountFunction.setCount(BinomialDistributionGenerator.binomial(3, 0.53333336F))))
                )
            );
    }
 
    protected LootTable.Builder createShearsOnlyDrop(ItemLike drop) {
        return LootTable.lootTable()
            .withPool(LootPool.lootPool().setRolls(ConstantValue.exactly(1.0F)).when(this.hasShears()).add(LootItem.lootTableItem(drop)));
    }
 
    protected LootTable.Builder createShearsOrSilkTouchOnlyDrop(ItemLike drop) {
        return LootTable.lootTable()
            .withPool(LootPool.lootPool().setRolls(ConstantValue.exactly(1.0F)).when(this.hasShearsOrSilkTouch()).add(LootItem.lootTableItem(drop)));
    }
 
    protected LootTable.Builder createMultifaceBlockDrops(Block block, LootItemCondition.Builder condition) {
        return LootTable.lootTable()
            .withPool(
                LootPool.lootPool()
                    .add(
                        (LootPoolEntryContainer.Builder<?>)this.applyExplosionDecay(
                            block,
                            LootItem.lootTableItem(block)
                                .when(condition)
                                .apply(
                                    Direction.values(),
                                    dir -> SetItemCountFunction.setCount(ConstantValue.exactly(1.0F), true)
                                        .when(
                                            LootItemBlockStatePropertyCondition.hasBlockStateProperties(block)
                                                .setProperties(
                                                    StatePropertiesPredicate.Builder.properties().hasProperty(MultifaceBlock.getFaceProperty(dir), true)
                                                )
                                        )
                                )
                                .apply(SetItemCountFunction.setCount(ConstantValue.exactly(-1.0F), true))
                        )
                    )
            );
    }
 
    protected LootTable.Builder createMultifaceBlockDrops(Block block) {
        return LootTable.lootTable()
            .withPool(
                LootPool.lootPool()
                    .add(
                        (LootPoolEntryContainer.Builder<?>)this.applyExplosionDecay(
                            block,
                            LootItem.lootTableItem(block)
                                .apply(
                                    Direction.values(),
                                    dir -> SetItemCountFunction.setCount(ConstantValue.exactly(1.0F), true)
                                        .when(
                                            LootItemBlockStatePropertyCondition.hasBlockStateProperties(block)
                                                .setProperties(
                                                    StatePropertiesPredicate.Builder.properties().hasProperty(MultifaceBlock.getFaceProperty(dir), true)
                                                )
                                        )
                                )
                                .apply(SetItemCountFunction.setCount(ConstantValue.exactly(-1.0F), true))
                        )
                    )
            );
    }
 
    protected LootTable.Builder createMossyCarpetBlockDrops(Block block) {
        return LootTable.lootTable()
            .withPool(
                LootPool.lootPool()
                    .add(
                        (LootPoolEntryContainer.Builder<?>)this.applyExplosionDecay(
                            block,
                            LootItem.lootTableItem(block)
                                .when(
                                    LootItemBlockStatePropertyCondition.hasBlockStateProperties(block)
                                        .setProperties(StatePropertiesPredicate.Builder.properties().hasProperty(MossyCarpetBlock.BASE, true))
                                )
                        )
                    )
            );
    }
 
    protected LootTable.Builder createLeavesDrops(Block original, Block sapling, float... saplingChances) {
        HolderLookup.RegistryLookup<Enchantment> enchantments = this.registries.lookupOrThrow(Registries.ENCHANTMENT);
        return this.createSilkTouchOrShearsDispatchTable(
                original,
                ((LootPoolSingletonContainer.Builder)this.applyExplosionCondition(original, LootItem.lootTableItem(sapling)))
                    .when(BonusLevelTableCondition.bonusLevelFlatChance(enchantments.getOrThrow(Enchantments.FORTUNE), saplingChances))
            )
            .withPool(
                LootPool.lootPool()
                    .setRolls(ConstantValue.exactly(1.0F))
                    .when(this.doesNotHaveShearsOrSilkTouch())
                    .add(
                        ((LootPoolSingletonContainer.Builder)this.applyExplosionDecay(
                                original, LootItem.lootTableItem(Items.STICK).apply(SetItemCountFunction.setCount(UniformGenerator.between(1.0F, 2.0F)))
                            ))
                            .when(BonusLevelTableCondition.bonusLevelFlatChance(enchantments.getOrThrow(Enchantments.FORTUNE), NORMAL_LEAVES_STICK_CHANCES))
                    )
            );
    }
 
    protected LootTable.Builder createOakLeavesDrops(Block original, Block sapling, float... saplingChances) {
        HolderLookup.RegistryLookup<Enchantment> enchantments = this.registries.lookupOrThrow(Registries.ENCHANTMENT);
        return this.createLeavesDrops(original, sapling, saplingChances)
            .withPool(
                LootPool.lootPool()
                    .setRolls(ConstantValue.exactly(1.0F))
                    .when(this.doesNotHaveShearsOrSilkTouch())
                    .add(
                        ((LootPoolSingletonContainer.Builder)this.applyExplosionCondition(original, LootItem.lootTableItem(Items.APPLE)))
                            .when(
                                BonusLevelTableCondition.bonusLevelFlatChance(
                                    enchantments.getOrThrow(Enchantments.FORTUNE), 0.005F, 0.0055555557F, 0.00625F, 0.008333334F, 0.025F
                                )
                            )
                    )
            );
    }
 
    protected LootTable.Builder createMangroveLeavesDrops(Block block) {
        HolderLookup.RegistryLookup<Enchantment> enchantments = this.registries.lookupOrThrow(Registries.ENCHANTMENT);
        return this.createSilkTouchOrShearsDispatchTable(
            block,
            ((LootPoolSingletonContainer.Builder)this.applyExplosionDecay(
                    Blocks.MANGROVE_LEAVES, LootItem.lootTableItem(Items.STICK).apply(SetItemCountFunction.setCount(UniformGenerator.between(1.0F, 2.0F)))
                ))
                .when(BonusLevelTableCondition.bonusLevelFlatChance(enchantments.getOrThrow(Enchantments.FORTUNE), NORMAL_LEAVES_STICK_CHANCES))
        );
    }
 
    protected LootTable.Builder createCropDrops(Block original, Item cropDrop, Item seedDrop, LootItemCondition.Builder isMaxAge) {
        HolderLookup.RegistryLookup<Enchantment> enchantments = this.registries.lookupOrThrow(Registries.ENCHANTMENT);
        return this.applyExplosionDecay(
            original,
            LootTable.lootTable()
                .withPool(LootPool.lootPool().add(LootItem.lootTableItem(cropDrop).when(isMaxAge).otherwise(LootItem.lootTableItem(seedDrop))))
                .withPool(
                    LootPool.lootPool()
                        .when(isMaxAge)
                        .add(
                            LootItem.lootTableItem(seedDrop)
                                .apply(ApplyBonusCount.addBonusBinomialDistributionCount(enchantments.getOrThrow(Enchantments.FORTUNE), 0.5714286F, 3))
                        )
                )
        );
    }
 
    protected LootTable.Builder createDoublePlantShearsDrop(Block block) {
        return LootTable.lootTable()
            .withPool(
                LootPool.lootPool().when(this.hasShears()).add(LootItem.lootTableItem(block).apply(SetItemCountFunction.setCount(ConstantValue.exactly(2.0F))))
            );
    }
 
    protected LootTable.Builder createDoublePlantWithSeedDrops(Block block, Block drop) {
        HolderLookup.RegistryLookup<Block> blocks = this.registries.lookupOrThrow(Registries.BLOCK);
        LootPoolEntryContainer.Builder<?> dropEntry = LootItem.lootTableItem(drop)
            .apply(SetItemCountFunction.setCount(ConstantValue.exactly(2.0F)))
            .when(this.hasShears())
            .otherwise(
                ((LootPoolSingletonContainer.Builder)this.applyExplosionCondition(block, LootItem.lootTableItem(Items.WHEAT_SEEDS)))
                    .when(LootItemRandomChanceCondition.randomChance(0.125F))
            );
        return LootTable.lootTable()
            .withPool(
                LootPool.lootPool()
                    .add(dropEntry)
                    .when(
                        LootItemBlockStatePropertyCondition.hasBlockStateProperties(block)
                            .setProperties(StatePropertiesPredicate.Builder.properties().hasProperty(DoublePlantBlock.HALF, DoubleBlockHalf.LOWER))
                    )
                    .when(
                        LocationCheck.checkLocation(
                            LocationPredicate.Builder.location()
                                .setBlock(
                                    BlockPredicate.Builder.block()
                                        .of(blocks, block)
                                        .setProperties(StatePropertiesPredicate.Builder.properties().hasProperty(DoublePlantBlock.HALF, DoubleBlockHalf.UPPER))
                                ),
                            new BlockPos(0, 1, 0)
                        )
                    )
            )
            .withPool(
                LootPool.lootPool()
                    .add(dropEntry)
                    .when(
                        LootItemBlockStatePropertyCondition.hasBlockStateProperties(block)
                            .setProperties(StatePropertiesPredicate.Builder.properties().hasProperty(DoublePlantBlock.HALF, DoubleBlockHalf.UPPER))
                    )
                    .when(
                        LocationCheck.checkLocation(
                            LocationPredicate.Builder.location()
                                .setBlock(
                                    BlockPredicate.Builder.block()
                                        .of(blocks, block)
                                        .setProperties(StatePropertiesPredicate.Builder.properties().hasProperty(DoublePlantBlock.HALF, DoubleBlockHalf.LOWER))
                                ),
                            new BlockPos(0, -1, 0)
                        )
                    )
            );
    }
 
    protected LootTable.Builder createCandleDrops(Block block) {
        return LootTable.lootTable()
            .withPool(
                LootPool.lootPool()
                    .setRolls(ConstantValue.exactly(1.0F))
                    .add(
                        (LootPoolEntryContainer.Builder<?>)this.applyExplosionDecay(
                            block,
                            LootItem.lootTableItem(block)
                                .apply(
                                    List.of(2, 3, 4),
                                    count -> SetItemCountFunction.setCount(ConstantValue.exactly(count.intValue()))
                                        .when(
                                            LootItemBlockStatePropertyCondition.hasBlockStateProperties(block)
                                                .setProperties(StatePropertiesPredicate.Builder.properties().hasProperty(CandleBlock.CANDLES, count.intValue()))
                                        )
                                )
                        )
                    )
            );
    }
 
    public LootTable.Builder createSegmentedBlockDrops(Block block) {
        return block instanceof SegmentableBlock segmentableBlock
            ? LootTable.lootTable()
                .withPool(
                    LootPool.lootPool()
                        .setRolls(ConstantValue.exactly(1.0F))
                        .add(
                            (LootPoolEntryContainer.Builder<?>)this.applyExplosionDecay(
                                block,
                                LootItem.lootTableItem(block)
                                    .apply(
                                        IntStream.rangeClosed(1, 4).boxed().toList(),
                                        count -> SetItemCountFunction.setCount(ConstantValue.exactly(count.intValue()))
                                            .when(
                                                LootItemBlockStatePropertyCondition.hasBlockStateProperties(block)
                                                    .setProperties(
                                                        StatePropertiesPredicate.Builder.properties()
                                                            .hasProperty(segmentableBlock.getSegmentAmountProperty(), count.intValue())
                                                    )
                                            )
                                    )
                            )
                        )
                )
            : noDrop();
    }
 
    protected static LootTable.Builder createCandleCakeDrops(Block candle) {
        return LootTable.lootTable().withPool(LootPool.lootPool().setRolls(ConstantValue.exactly(1.0F)).add(LootItem.lootTableItem(candle)));
    }
 
    public static LootTable.Builder noDrop() {
        return LootTable.lootTable();
    }
 
    protected abstract void generate();
 
    @Override
    public void generate(BiConsumer<ResourceKey<LootTable>, LootTable.Builder> output) {
        this.generate();
        Set<ResourceKey<LootTable>> seen = new HashSet<>();
 
        for (Block block : BuiltInRegistries.BLOCK) {
            if (block.isEnabled(this.enabledFeatures)) {
                block.getLootTable()
                    .ifPresent(
                        lootTable -> {
                            if (seen.add((ResourceKey<LootTable>)lootTable)) {
                                LootTable.Builder builder = this.map.remove(lootTable);
                                if (builder == null) {
                                    throw new IllegalStateException(
                                        String.format(
                                            Locale.ROOT, "Missing loottable '%s' for '%s'", lootTable.identifier(), BuiltInRegistries.BLOCK.getKey(block)
                                        )
                                    );
                                }
 
                                output.accept((ResourceKey<LootTable>)lootTable, builder);
                            }
                        }
                    );
            }
        }
 
        if (!this.map.isEmpty()) {
            throw new IllegalStateException("Created block loot tables for non-blocks: " + this.map.keySet());
        }
    }
 
    protected void addNetherVinesDropTable(Block vineBlock, Block plantBlock) {
        HolderLookup.RegistryLookup<Enchantment> enchantments = this.registries.lookupOrThrow(Registries.ENCHANTMENT);
        LootTable.Builder builder = this.createSilkTouchOrShearsDispatchTable(
            vineBlock,
            LootItem.lootTableItem(vineBlock)
                .when(BonusLevelTableCondition.bonusLevelFlatChance(enchantments.getOrThrow(Enchantments.FORTUNE), 0.33F, 0.55F, 0.77F, 1.0F))
        );
        this.add(vineBlock, builder);
        this.add(plantBlock, builder);
    }
 
    protected LootTable.Builder createDoorTable(Block block) {
        return this.createSinglePropConditionTable(block, DoorBlock.HALF, DoubleBlockHalf.LOWER);
    }
 
    protected void dropPottedContents(Block potted) {
        this.add(potted, block -> this.createPotFlowerItemTable(((FlowerPotBlock)block).getPotted()));
    }
 
    protected void otherWhenSilkTouch(Block block, Block other) {
        this.add(block, this.createSilkTouchOnlyTable(other));
    }
 
    protected void dropOther(Block block, ItemLike drop) {
        this.add(block, this.createSingleItemTable(drop));
    }
 
    protected void dropWhenSilkTouch(Block block) {
        this.otherWhenSilkTouch(block, block);
    }
 
    protected void dropSelf(Block block) {
        this.dropOther(block, block);
    }
 
    protected void add(Block block, Function<Block, LootTable.Builder> builder) {
        this.add(block, builder.apply(block));
    }
 
    protected void add(Block block, LootTable.Builder builder) {
        this.map.put(block.getLootTable().orElseThrow(() -> new IllegalStateException("Block " + block + " does not have loot table")), builder);
    }
}

引用的其他类