161 lines
5.5 KiB
Kotlin
161 lines
5.5 KiB
Kotlin
package moe.nea.firmament.repo
|
|
|
|
import kotlinx.serialization.KSerializer
|
|
import kotlinx.serialization.SerialName
|
|
import kotlinx.serialization.Serializable
|
|
import kotlinx.serialization.builtins.MapSerializer
|
|
import kotlinx.serialization.descriptors.SerialDescriptor
|
|
import kotlinx.serialization.encoding.Decoder
|
|
import kotlinx.serialization.encoding.Encoder
|
|
import kotlinx.serialization.json.JsonArray
|
|
import kotlinx.serialization.json.JsonDecoder
|
|
import kotlinx.serialization.json.JsonElement
|
|
import kotlinx.serialization.json.JsonObject
|
|
import kotlinx.serialization.json.JsonPrimitive
|
|
import kotlinx.serialization.serializer
|
|
import net.minecraft.item.Item
|
|
import net.minecraft.registry.RegistryKey
|
|
import net.minecraft.registry.RegistryKeys
|
|
import net.minecraft.util.Identifier
|
|
import moe.nea.firmament.util.ReforgeId
|
|
import moe.nea.firmament.util.SkyblockId
|
|
import moe.nea.firmament.util.skyblock.ItemType
|
|
import moe.nea.firmament.util.skyblock.Rarity
|
|
|
|
@Serializable
|
|
data class Reforge(
|
|
val reforgeName: String,
|
|
@SerialName("internalName") val reforgeStone: SkyblockId? = null,
|
|
val nbtModifier: ReforgeId? = null,
|
|
val requiredRarities: List<Rarity>? = null,
|
|
val itemTypes: @Serializable(with = ReforgeEligibilityFilter.ItemTypesSerializer::class) List<ReforgeEligibilityFilter>? = null,
|
|
val allowOn: List<ReforgeEligibilityFilter>? = null,
|
|
val reforgeCosts: RarityMapped<Double>? = null,
|
|
val reforgeAbility: RarityMapped<String>? = null,
|
|
val reforgeStats: RarityMapped<Map<String, Double>>? = null,
|
|
) {
|
|
val eligibleItems get() = allowOn ?: itemTypes ?: listOf()
|
|
|
|
val statUniverse: Set<String> = Rarity.entries.flatMapTo(mutableSetOf()) {
|
|
reforgeStats?.get(it)?.keys ?: emptySet()
|
|
}
|
|
|
|
@Serializable(with = ReforgeEligibilityFilter.Serializer::class)
|
|
sealed interface ReforgeEligibilityFilter {
|
|
object ItemTypesSerializer : KSerializer<List<ReforgeEligibilityFilter>> {
|
|
override val descriptor: SerialDescriptor
|
|
get() = JsonElement.serializer().descriptor
|
|
|
|
override fun deserialize(decoder: Decoder): List<ReforgeEligibilityFilter> {
|
|
decoder as JsonDecoder
|
|
val jsonElement = decoder.decodeJsonElement()
|
|
if (jsonElement is JsonPrimitive && jsonElement.isString) {
|
|
return jsonElement.content.split("/").map { AllowsItemType(ItemType.ofName(it)) }
|
|
}
|
|
if (jsonElement is JsonArray) {
|
|
return decoder.json.decodeFromJsonElement(serializer<List<ReforgeEligibilityFilter>>(), jsonElement)
|
|
}
|
|
jsonElement as JsonObject
|
|
val filters = mutableListOf<ReforgeEligibilityFilter>()
|
|
jsonElement["internalName"]?.let {
|
|
decoder.json.decodeFromJsonElement(serializer<List<SkyblockId>>(), it).forEach {
|
|
filters.add(AllowsInternalName(it))
|
|
}
|
|
}
|
|
jsonElement["itemId"]?.let {
|
|
decoder.json.decodeFromJsonElement(serializer<List<String>>(), it).forEach {
|
|
val ident = Identifier.tryParse(it)
|
|
if (ident != null)
|
|
filters.add(AllowsVanillaItemType(RegistryKey.of(RegistryKeys.ITEM, ident)))
|
|
}
|
|
}
|
|
return filters
|
|
}
|
|
|
|
override fun serialize(encoder: Encoder, value: List<ReforgeEligibilityFilter>) {
|
|
TODO("Not yet implemented")
|
|
}
|
|
}
|
|
|
|
object Serializer : KSerializer<ReforgeEligibilityFilter> {
|
|
override val descriptor: SerialDescriptor
|
|
get() = serializer<JsonElement>().descriptor
|
|
|
|
override fun deserialize(decoder: Decoder): ReforgeEligibilityFilter {
|
|
val jsonObject = serializer<JsonObject>().deserialize(decoder)
|
|
jsonObject["internalName"]?.let {
|
|
return AllowsInternalName(SkyblockId((it as JsonPrimitive).content))
|
|
}
|
|
jsonObject["itemType"]?.let {
|
|
return AllowsItemType(ItemType.ofName((it as JsonPrimitive).content))
|
|
}
|
|
jsonObject["minecraftId"]?.let {
|
|
return AllowsVanillaItemType(RegistryKey.of(RegistryKeys.ITEM,
|
|
Identifier.of((it as JsonPrimitive).content)))
|
|
}
|
|
error("Unknown item type")
|
|
}
|
|
|
|
override fun serialize(encoder: Encoder, value: ReforgeEligibilityFilter) {
|
|
TODO("Not yet implemented")
|
|
}
|
|
|
|
}
|
|
|
|
data class AllowsItemType(val itemType: ItemType) : ReforgeEligibilityFilter
|
|
data class AllowsInternalName(val internalName: SkyblockId) : ReforgeEligibilityFilter
|
|
data class AllowsVanillaItemType(val minecraftId: RegistryKey<Item>) : ReforgeEligibilityFilter
|
|
}
|
|
|
|
|
|
val reforgeId get() = nbtModifier ?: ReforgeId(reforgeName.lowercase())
|
|
|
|
@Serializable(with = RarityMapped.Serializer::class)
|
|
sealed interface RarityMapped<T> {
|
|
fun get(rarity: Rarity?): T?
|
|
|
|
class Serializer<T>(
|
|
val values: KSerializer<T>
|
|
) : KSerializer<RarityMapped<T>> {
|
|
override val descriptor: SerialDescriptor
|
|
get() = JsonElement.serializer().descriptor
|
|
|
|
val indirect = MapSerializer(Rarity.serializer(), values)
|
|
override fun deserialize(decoder: Decoder): RarityMapped<T> {
|
|
decoder as JsonDecoder
|
|
val element = decoder.decodeJsonElement()
|
|
if (element is JsonObject) {
|
|
return PerRarity(decoder.json.decodeFromJsonElement(indirect, element))
|
|
} else {
|
|
return Direct(decoder.json.decodeFromJsonElement(values, element))
|
|
}
|
|
}
|
|
|
|
override fun serialize(encoder: Encoder, value: RarityMapped<T>) {
|
|
when (value) {
|
|
is Direct<T> ->
|
|
values.serialize(encoder, value.value)
|
|
|
|
is PerRarity<T> ->
|
|
indirect.serialize(encoder, value.values)
|
|
}
|
|
}
|
|
}
|
|
|
|
@Serializable
|
|
data class Direct<T>(val value: T) : RarityMapped<T> {
|
|
override fun get(rarity: Rarity?): T {
|
|
return value
|
|
}
|
|
}
|
|
|
|
@Serializable
|
|
data class PerRarity<T>(val values: Map<Rarity, T>) : RarityMapped<T> {
|
|
override fun get(rarity: Rarity?): T? {
|
|
return values[rarity]
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|