ItemStack already has codec

This commit is contained in:
DBotThePony 2023-05-08 00:10:10 +07:00
parent 2ca00563e8
commit 73e082aeea
Signed by: DBot
GPG Key ID: DCC23B5715498507

View File

@ -1,114 +0,0 @@
package ru.dbotthepony.mc.otm.data
import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import com.google.gson.JsonPrimitive
import com.google.gson.JsonSerializationContext
import com.google.gson.JsonSerializer
import com.google.gson.JsonSyntaxException
import com.google.gson.TypeAdapter
import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonToken
import com.google.gson.stream.JsonWriter
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.codecs.ListCodec
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import net.minecraftforge.registries.ForgeRegistries
import ru.dbotthepony.mc.otm.core.registryName
import ru.dbotthepony.mc.otm.core.nbt.set
import ru.dbotthepony.mc.otm.core.set
import java.lang.reflect.Type
object ItemStackCodec : Codec<ItemStack>, TypeAdapter<ItemStack>(), JsonSerializer<ItemStack>, JsonDeserializer<ItemStack> {
override fun <T : Any> encode(input: ItemStack, ops: DynamicOps<T>, prefix: T): DataResult<T> {
require(prefix == ops.empty()) { "Non-empty prefix: $prefix" }
return ForgeRegistries.ITEMS.codec.encode(input.item, ops, ops.empty()).flatMap {
DataResult.success(ops.createMap(linkedMapOf(
ops.createString("id") to it,
ops.createString("count") to ops.createInt(input.count)
)))
}
}
override fun <T : Any> decode(ops: DynamicOps<T>, input: T): DataResult<Pair<ItemStack, T>> {
return ops.getMap(input).flatMap {
val item = it["id"]?.let { ForgeRegistries.ITEMS.codec.decode(ops, it) }?.result()?.orElse(null)?.first
val count = it["count"]?.let(ops::getNumberValue)?.result()?.orElse(null)?.toInt() ?: return@flatMap DataResult.error { "Invalid item count" }
if (item == null || item == Items.AIR) {
return@flatMap DataResult.error { "Unknown item type $item" }
}
DataResult.success(ItemStack(item, count))
}.map { Pair.of(it, ops.empty()) }
}
val LIST = ListCodec(this)
override fun write(out: JsonWriter, value: ItemStack) {
out.beginObject()
out.name("id")
out.value(value.item.registryName!!.toString())
out.name("count")
out.value(value.count)
out.endObject()
}
override fun read(reader: JsonReader): ItemStack {
reader.beginObject()
var id: String? = null
var count: Int? = null
while (reader.peek() != JsonToken.END_OBJECT) {
when (val it = reader.nextName()) {
"id" -> id = reader.nextString()
"count" -> count = reader.nextInt()
else -> throw JsonSyntaxException("Unknown json key $it")
}
}
reader.endObject()
val item = ForgeRegistries.ITEMS.getValue(ResourceLocation(id ?: return ItemStack.EMPTY)) ?: return ItemStack.EMPTY
return ItemStack(item, count ?: 1)
}
override fun serialize(src: ItemStack, typeOfSrc: Type, context: JsonSerializationContext): JsonElement {
return serialize(src)
}
fun serialize(src: ItemStack): JsonElement {
return JsonObject().also {
it["id"] = JsonPrimitive(src.item.registryName!!.toString())
it["count"] = JsonPrimitive(src.count)
}
}
override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): ItemStack {
return deserialize(json)
}
fun deserialize(json: JsonElement): ItemStack {
if (json !is JsonObject) {
throw JsonSyntaxException("ItemStack json element must be JsonObject, ${json::class.qualifiedName} given")
}
val item = ForgeRegistries.ITEMS.getValue(ResourceLocation(json["id"]?.asString ?: return ItemStack.EMPTY)) ?: return ItemStack.EMPTY
val count = json["count"]?.asInt ?: 1
return ItemStack(item, count)
}
}