package net.minecraft.resources; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; import com.mojang.serialization.DynamicOps; import com.mojang.serialization.Lifecycle; import java.util.Optional; import net.minecraft.core.Holder; import net.minecraft.core.HolderGetter; import net.minecraft.core.HolderOwner; import net.minecraft.core.Registry; public final class RegistryFixedCodec implements Codec> { private final ResourceKey> registryKey; public static RegistryFixedCodec create(ResourceKey> registryKey) { return new RegistryFixedCodec<>(registryKey); } private RegistryFixedCodec(ResourceKey> registryKey) { this.registryKey = registryKey; } public DataResult encode(Holder holder, DynamicOps ops, T value) { if (ops instanceof RegistryOps registryOps) { Optional> optional = registryOps.owner(this.registryKey); if (optional.isPresent()) { if (!holder.canSerializeIn((HolderOwner)optional.get())) { return DataResult.error(() -> "Element " + holder + " is not valid in current registry set"); } return holder.unwrap() .map( resourceKey -> ResourceLocation.CODEC.encode(resourceKey.location(), ops, value), object -> DataResult.error(() -> "Elements from registry " + this.registryKey + " can't be serialized to a value") ); } } return DataResult.error(() -> "Can't access registry " + this.registryKey); } @Override public DataResult, T>> decode(DynamicOps dynamicOps, T object) { if (dynamicOps instanceof RegistryOps registryOps) { Optional> optional = registryOps.getter(this.registryKey); if (optional.isPresent()) { return ResourceLocation.CODEC .decode(dynamicOps, object) .flatMap( pair -> { ResourceLocation resourceLocation = (ResourceLocation)pair.getFirst(); return ((DataResult)((HolderGetter)optional.get()) .get(ResourceKey.create(this.registryKey, resourceLocation)) .map(DataResult::success) .orElseGet(() -> DataResult.error(() -> "Failed to get element " + resourceLocation))) .map(reference -> Pair.of(reference, pair.getSecond())) .setLifecycle(Lifecycle.stable()); } ); } } return DataResult.error(() -> "Can't access registry " + this.registryKey); } public String toString() { return "RegistryFixedCodec[" + this.registryKey + "]"; } }