EntityLootSubProvider.java

net.minecraft.data.loot.EntityLootSubProvider

信息

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

    TODO

字段/常量

  • registries

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

      TODO

  • allowed

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

      TODO

  • required

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

      TODO

  • map

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

      TODO

内部类/嵌套类型

构造器

protected EntityLootSubProvider(FeatureFlagSet enabledFeatures, HolderLookup.Provider registries) @ L87

  • 构造器名:EntityLootSubProvider
  • 源码定位:L87
  • 修饰符:protected

参数:

  • enabledFeatures: FeatureFlagSet
  • registries: HolderLookup.Provider

说明:

TODO

protected EntityLootSubProvider(FeatureFlagSet allowed, FeatureFlagSet required, HolderLookup.Provider registries) @ L91

  • 构造器名:EntityLootSubProvider
  • 源码定位:L91
  • 修饰符:protected

参数:

  • allowed: FeatureFlagSet
  • required: FeatureFlagSet
  • registries: HolderLookup.Provider

说明:

TODO

方法

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

protected final AnyOfCondition.Builder shouldSmeltLoot() @ L54

  • 方法名:shouldSmeltLoot
  • 源码定位:L54
  • 返回类型:AnyOfCondition.Builder
  • 修饰符:protected final

参数:

说明:

TODO

public static LootPool.Builder createSheepDispatchPool(Map<DyeColor,ResourceKey<LootTable>> tableNames) @ L97

  • 方法名:createSheepDispatchPool
  • 源码定位:L97
  • 返回类型:LootPool.Builder
  • 修饰符:public static

参数:

  • tableNames: Map<DyeColor,ResourceKey>

说明:

TODO

public abstract void generate() @ L121

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

参数:

说明:

TODO

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

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

参数:

  • output: BiConsumer<ResourceKey,LootTable.Builder>

说明:

TODO

protected LootItemCondition.Builder killedByFrog(HolderGetter<EntityType<?>> entityTypes) @ L176

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

参数:

  • entityTypes: HolderGetter<EntityType<?>>

说明:

TODO

protected LootItemCondition.Builder killedByFrogVariant(HolderGetter<EntityType<?>> entityTypes, HolderGetter<FrogVariant> frogVariants, ResourceKey<FrogVariant> variant) @ L182

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

参数:

  • entityTypes: HolderGetter<EntityType<?>>
  • frogVariants: HolderGetter
  • variant: ResourceKey

说明:

TODO

protected void add(EntityType<?> type, LootTable.Builder builder) @ L199

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

参数:

  • type: EntityType<?>
  • builder: LootTable.Builder

说明:

TODO

protected void add(EntityType<?> type, ResourceKey<LootTable> lootTable, LootTable.Builder builder) @ L203

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

参数:

  • type: EntityType<?>
  • lootTable: ResourceKey
  • builder: LootTable.Builder

说明:

TODO

代码

public abstract class EntityLootSubProvider implements LootTableSubProvider {
    protected final HolderLookup.Provider registries;
    private final FeatureFlagSet allowed;
    private final FeatureFlagSet required;
    private final Map<EntityType<?>, Map<ResourceKey<LootTable>, LootTable.Builder>> map = Maps.newHashMap();
 
    protected final AnyOfCondition.Builder shouldSmeltLoot() {
        HolderLookup.RegistryLookup<Enchantment> enchantmentsRegistry = this.registries.lookupOrThrow(Registries.ENCHANTMENT);
        return AnyOfCondition.anyOf(
            LootItemEntityPropertyCondition.hasProperties(
                LootContext.EntityTarget.THIS, EntityPredicate.Builder.entity().flags(EntityFlagsPredicate.Builder.flags().setOnFire(true))
            ),
            LootItemEntityPropertyCondition.hasProperties(
                LootContext.EntityTarget.DIRECT_ATTACKER,
                EntityPredicate.Builder.entity()
                    .equipment(
                        EntityEquipmentPredicate.Builder.equipment()
                            .mainhand(
                                ItemPredicate.Builder.item()
                                    .withComponents(
                                        DataComponentMatchers.Builder.components()
                                            .partial(
                                                DataComponentPredicates.ENCHANTMENTS,
                                                EnchantmentsPredicate.enchantments(
                                                    List.of(
                                                        new EnchantmentPredicate(
                                                            enchantmentsRegistry.getOrThrow(EnchantmentTags.SMELTS_LOOT), MinMaxBounds.Ints.ANY
                                                        )
                                                    )
                                                )
                                            )
                                            .build()
                                    )
                            )
                    )
            )
        );
    }
 
    protected EntityLootSubProvider(FeatureFlagSet enabledFeatures, HolderLookup.Provider registries) {
        this(enabledFeatures, enabledFeatures, registries);
    }
 
    protected EntityLootSubProvider(FeatureFlagSet allowed, FeatureFlagSet required, HolderLookup.Provider registries) {
        this.allowed = allowed;
        this.required = required;
        this.registries = registries;
    }
 
    public static LootPool.Builder createSheepDispatchPool(Map<DyeColor, ResourceKey<LootTable>> tableNames) {
        AlternativesEntry.Builder variants = AlternativesEntry.alternatives();
 
        for (Entry<DyeColor, ResourceKey<LootTable>> e : tableNames.entrySet()) {
            variants = variants.otherwise(
                NestedLootTable.lootTableReference(e.getValue())
                    .when(
                        LootItemEntityPropertyCondition.hasProperties(
                            LootContext.EntityTarget.THIS,
                            EntityPredicate.Builder.entity()
                                .components(
                                    DataComponentMatchers.Builder.components()
                                        .exact(DataComponentExactPredicate.expect(DataComponents.SHEEP_COLOR, e.getKey()))
                                        .build()
                                )
                                .subPredicate(SheepPredicate.hasWool())
                        )
                    )
            );
        }
 
        return LootPool.lootPool().add(variants);
    }
 
    public abstract void generate();
 
    @Override
    public void generate(BiConsumer<ResourceKey<LootTable>, LootTable.Builder> output) {
        this.generate();
        Set<ResourceKey<LootTable>> seen = new HashSet<>();
        BuiltInRegistries.ENTITY_TYPE
            .listElements()
            .forEach(
                holder -> {
                    EntityType<?> type = holder.value();
                    if (type.isEnabled(this.allowed)) {
                        Optional<ResourceKey<LootTable>> defaultLootTable = type.getDefaultLootTable();
                        if (defaultLootTable.isPresent()) {
                            Map<ResourceKey<LootTable>, LootTable.Builder> builders = this.map.remove(type);
                            if (type.isEnabled(this.required) && (builders == null || !builders.containsKey(defaultLootTable.get()))) {
                                throw new IllegalStateException(
                                    String.format(Locale.ROOT, "Missing loottable '%s' for '%s'", defaultLootTable.get(), holder.key().identifier())
                                );
                            }
 
                            if (builders != null) {
                                builders.forEach(
                                    (id, builder) -> {
                                        if (!seen.add((ResourceKey<LootTable>)id)) {
                                            throw new IllegalStateException(
                                                String.format(Locale.ROOT, "Duplicate loottable '%s' for '%s'", id, holder.key().identifier())
                                            );
                                        } else {
                                            output.accept((ResourceKey<LootTable>)id, builder);
                                        }
                                    }
                                );
                            }
                        } else {
                            Map<ResourceKey<LootTable>, LootTable.Builder> buildersx = this.map.remove(type);
                            if (buildersx != null) {
                                throw new IllegalStateException(
                                    String.format(
                                        Locale.ROOT,
                                        "Weird loottables '%s' for '%s', not a LivingEntity so should not have loot",
                                        buildersx.keySet().stream().map(r -> r.identifier().toString()).collect(Collectors.joining(",")),
                                        holder.key().identifier()
                                    )
                                );
                            }
                        }
                    }
                }
            );
        if (!this.map.isEmpty()) {
            throw new IllegalStateException("Created loot tables for entities not supported by datapack: " + this.map.keySet());
        }
    }
 
    protected LootItemCondition.Builder killedByFrog(HolderGetter<EntityType<?>> entityTypes) {
        return DamageSourceCondition.hasDamageSource(
            DamageSourcePredicate.Builder.damageType().source(EntityPredicate.Builder.entity().of(entityTypes, EntityType.FROG))
        );
    }
 
    protected LootItemCondition.Builder killedByFrogVariant(
        HolderGetter<EntityType<?>> entityTypes, HolderGetter<FrogVariant> frogVariants, ResourceKey<FrogVariant> variant
    ) {
        return DamageSourceCondition.hasDamageSource(
            DamageSourcePredicate.Builder.damageType()
                .source(
                    EntityPredicate.Builder.entity()
                        .of(entityTypes, EntityType.FROG)
                        .components(
                            DataComponentMatchers.Builder.components()
                                .exact(DataComponentExactPredicate.expect(DataComponents.FROG_VARIANT, frogVariants.getOrThrow(variant)))
                                .build()
                        )
                )
        );
    }
 
    protected void add(EntityType<?> type, LootTable.Builder builder) {
        this.add(type, type.getDefaultLootTable().orElseThrow(() -> new IllegalStateException("Entity " + type + " has no loot table")), builder);
    }
 
    protected void add(EntityType<?> type, ResourceKey<LootTable> lootTable, LootTable.Builder builder) {
        this.map.computeIfAbsent(type, k -> new HashMap<>()).put(lootTable, builder);
    }
}

引用的其他类