package net.minecraft.client.renderer.item.properties.select; import com.google.common.collect.HashMultiset; import com.google.common.collect.Multiset; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import java.util.List; import java.util.stream.Collectors; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.renderer.item.SelectItemModel; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.ItemDisplayContext; import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.Nullable; @Environment(EnvType.CLIENT) public interface SelectItemModelProperty { @Nullable T get(ItemStack stack, @Nullable ClientLevel level, @Nullable LivingEntity entity, int seed, ItemDisplayContext displayContext); SelectItemModelProperty.Type, T> type(); @Environment(EnvType.CLIENT) public record Type

, T>(MapCodec> switchCodec) { public static

, T> SelectItemModelProperty.Type create(MapCodec

mapCodec, Codec codec) { Codec>> codec2 = SelectItemModel.SwitchCase.codec(codec) .listOf() .validate( list -> { if (list.isEmpty()) { return DataResult.error(() -> "Empty case list"); } else { Multiset multiset = HashMultiset.create(); for (SelectItemModel.SwitchCase switchCase : list) { multiset.addAll(switchCase.values()); } return multiset.size() != multiset.entrySet().size() ? DataResult.error( () -> "Duplicate case conditions: " + (String)multiset.entrySet() .stream() .filter(entry -> entry.getCount() > 1) .map(entry -> entry.getElement().toString()) .collect(Collectors.joining(", ")) ) : DataResult.success(list); } } ); MapCodec> mapCodec2 = RecordCodecBuilder.mapCodec( instance -> instance.group( mapCodec.forGetter(SelectItemModel.UnbakedSwitch::property), codec2.fieldOf("cases").forGetter(SelectItemModel.UnbakedSwitch::cases) ) .apply(instance, SelectItemModel.UnbakedSwitch::new) ); return new SelectItemModelProperty.Type<>(mapCodec2); } } }