package net.minecraft.world.level.storage.loot; import com.mojang.serialization.Codec; import java.util.function.Function; import java.util.function.UnaryOperator; import net.minecraft.util.ExtraCodecs; import net.minecraft.util.StringRepresentable; import net.minecraft.util.context.ContextKey; import net.minecraft.world.entity.Entity; import net.minecraft.world.item.ItemInstance; import net.minecraft.world.level.block.entity.BlockEntity; import org.jspecify.annotations.Nullable; public interface LootContextArg { Codec> ENTITY_OR_BLOCK = createArgCodec( builder -> builder.anyOf(LootContext.EntityTarget.values()).anyOf(LootContext.BlockEntityTarget.values()) ); @Nullable R get(LootContext context); ContextKey contextParam(); static LootContextArg cast(final LootContextArg original) { return (LootContextArg)original; } static Codec> createArgCodec(final UnaryOperator> consumer) { return ((LootContextArg.ArgCodecBuilder)consumer.apply(new LootContextArg.ArgCodecBuilder())).build(); } public static final class ArgCodecBuilder { private final ExtraCodecs.LateBoundIdMapper> sources = new ExtraCodecs.LateBoundIdMapper<>(); private ArgCodecBuilder() { } public LootContextArg.ArgCodecBuilder anyOf( final T[] targets, final Function nameGetter, final Function> argFactory ) { for (T target : targets) { this.sources.put((String)nameGetter.apply(target), (LootContextArg)argFactory.apply(target)); } return this; } public LootContextArg.ArgCodecBuilder anyOf(final T[] targets, final Function> argFactory) { return this.anyOf(targets, StringRepresentable::getSerializedName, argFactory); } public > LootContextArg.ArgCodecBuilder anyOf(final T[] targets) { return this.anyOf(targets, x$0 -> LootContextArg.cast((LootContextArg)x$0)); } public LootContextArg.ArgCodecBuilder anyEntity(final Function, ? extends LootContextArg> function) { return this.anyOf(LootContext.EntityTarget.values(), target -> (LootContextArg)function.apply(target.contextParam())); } public LootContextArg.ArgCodecBuilder anyBlockEntity(final Function, ? extends LootContextArg> function) { return this.anyOf(LootContext.BlockEntityTarget.values(), target -> (LootContextArg)function.apply(target.contextParam())); } public LootContextArg.ArgCodecBuilder anyItemStack(final Function, ? extends LootContextArg> function) { return this.anyOf(LootContext.ItemStackTarget.values(), target -> (LootContextArg)function.apply(target.contextParam())); } private Codec> build() { return this.sources.codec(Codec.STRING); } } public interface Getter extends LootContextArg { @Nullable R get(T value); @Override ContextKey contextParam(); @Nullable @Override default R get(final LootContext context) { T value = context.getOptionalParameter((ContextKey)this.contextParam()); return value != null ? this.get(value) : null; } } public interface SimpleGetter extends LootContextArg { @Override ContextKey contextParam(); @Nullable @Override default T get(final LootContext context) { return context.getOptionalParameter((ContextKey)this.contextParam()); } } }