Move loot modifiers to 'convenient' and 'powerful' codecs

UndefinedBHVR — 22.08.2021
"Unconventional" is an understatement, there's some things there that are just.. "This is the worst way possible to do this, why would you do this Mojang?"
This commit is contained in:
DBotThePony 2022-08-19 12:32:01 +07:00
parent 3d520a1a15
commit fc736528dd
Signed by: DBot
GPG Key ID: DCC23B5715498507
2 changed files with 95 additions and 95 deletions

View File

@ -1,12 +1,12 @@
package ru.dbotthepony.mc.otm.data package ru.dbotthepony.mc.otm.data
import com.google.common.collect.ImmutableList import com.google.common.collect.ImmutableList
import com.google.gson.JsonArray import com.google.gson.*
import com.google.gson.JsonObject
import com.google.gson.JsonParseException
import com.mojang.serialization.Codec import com.mojang.serialization.Codec
import com.mojang.serialization.DataResult import com.mojang.serialization.DataResult
import com.mojang.serialization.DynamicOps import com.mojang.serialization.Dynamic
import com.mojang.serialization.JsonOps
import com.mojang.serialization.codecs.RecordCodecBuilder
import it.unimi.dsi.fastutil.objects.ObjectArrayList import it.unimi.dsi.fastutil.objects.ObjectArrayList
import net.minecraft.resources.ResourceLocation import net.minecraft.resources.ResourceLocation
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
@ -19,6 +19,29 @@ import net.minecraftforge.common.loot.LootModifier
import net.minecraftforge.registries.ForgeRegistries import net.minecraftforge.registries.ForgeRegistries
import ru.dbotthepony.mc.otm.registryName import ru.dbotthepony.mc.otm.registryName
// 1.19 do be like overengineering already overengineered stuff beyond any recognition
private fun getJson(it: Dynamic<Any?>): JsonElement {
val value = it.value ?: throw NullPointerException("value was null")
return value as? JsonElement ?: it.ops.convertTo(JsonOps.INSTANCE, it)
}
private val LootPoolCodec: Codec<Array<LootPool>> by lazy {
val serializer = Deserializers.createLootTableSerializer().create()
Codec.PASSTHROUGH.flatXmap({
try {
DataResult.success(serializer.fromJson(getJson(it as Dynamic<Any?>), Array<LootPool>::class.java))
} catch(err: JsonSyntaxException) {
DataResult.error(err.message)
}
}, {
try {
DataResult.success(Dynamic(JsonOps.INSTANCE, serializer.toJsonTree(it)))
} catch(err: JsonSyntaxException) {
DataResult.error(err.message)
}
})
}
class LootTableAppender(conditions: Array<out LootItemCondition>, private vararg val pools: LootPool) : LootModifier(conditions) { class LootTableAppender(conditions: Array<out LootItemCondition>, private vararg val pools: LootPool) : LootModifier(conditions) {
override fun doApply(generatedLoot: ObjectArrayList<ItemStack>, context: LootContext): ObjectArrayList<ItemStack> { override fun doApply(generatedLoot: ObjectArrayList<ItemStack>, context: LootContext): ObjectArrayList<ItemStack> {
@ -27,51 +50,25 @@ class LootTableAppender(conditions: Array<out LootItemCondition>, private vararg
} }
override fun codec(): Codec<out IGlobalLootModifier> { override fun codec(): Codec<out IGlobalLootModifier> {
return Companion return CODEC
} }
companion object : Codec<LootTableAppender> { companion object {
override fun <T : Any?> encode(input: LootTableAppender?, ops: DynamicOps<T>?, prefix: T): DataResult<T> { val CODEC: Codec<LootTableAppender> by lazy {
return DataResult.error("NYI") RecordCodecBuilder.create {
codecStart(it).and(
LootPoolCodec.fieldOf("pools").forGetter { appender -> appender.pools as Array<LootPool> }
).apply(it, ::LootTableAppender)
} }
override fun <T : Any?> decode(
ops: DynamicOps<T>?,
input: T
): DataResult<com.mojang.datafixers.util.Pair<LootTableAppender, T>> {
return DataResult.error("NYI")
} }
private val lootPoolGson = Deserializers.createLootTableSerializer().create()
/*override fun read(
location: ResourceLocation,
`object`: JsonObject,
ailootcondition: Array<out LootItemCondition>
): LootTableAppender {
val pools = lootPoolGson.fromJson(`object`["pools"], Array<LootPool>::class.java) ?: throw JsonParseException("Invalid 'pools' entry")
pools.forEach {
@Suppress("UNNECESSARY_NOT_NULL_ASSERTION")
it!!
}
return LootTableAppender(ailootcondition, *pools)
}
override fun write(instance: LootTableAppender): JsonObject {
val build = makeConditions(instance.conditions)
build.add("pools", lootPoolGson.toJsonTree(instance.pools))
return build
}*/
} }
} }
class LootTableBasicAppender(conditions: Array<out LootItemCondition>, items: List<Pair<ItemStack, Double>>) : LootModifier(conditions) { class LootTableBasicAppender(conditions: Array<out LootItemCondition>, entries: List<Pair<ItemStack, Double>>) : LootModifier(conditions) {
private val items = ImmutableList.copyOf(items) private val entries = ImmutableList.copyOf(entries)
constructor(conditions: Array<out LootItemCondition>, vararg items: Pair<ItemStack, Double>) : this(conditions, items.toList())
override fun doApply(generatedLoot: ObjectArrayList<ItemStack>, context: LootContext): ObjectArrayList<ItemStack> { override fun doApply(generatedLoot: ObjectArrayList<ItemStack>, context: LootContext): ObjectArrayList<ItemStack> {
for ((item, chance) in items) { for ((item, chance) in entries) {
if (context.random.nextDouble() <= chance) { if (context.random.nextDouble() <= chance) {
generatedLoot.add(item.copy()) generatedLoot.add(item.copy())
} }
@ -81,49 +78,40 @@ class LootTableBasicAppender(conditions: Array<out LootItemCondition>, items: Li
} }
override fun codec(): Codec<out IGlobalLootModifier> { override fun codec(): Codec<out IGlobalLootModifier> {
return Companion return CODEC
} }
companion object : Codec<LootTableBasicAppender> { companion object {
override fun <T : Any?> encode(input: LootTableBasicAppender?, ops: DynamicOps<T>?, prefix: T): DataResult<T> { val ItemPairListCodec: Codec<List<Pair<ItemStack, Double>>> by lazy {
return DataResult.error("NYI") Codec.PASSTHROUGH.flatXmap({
} try {
override fun <T : Any?> decode(
ops: DynamicOps<T>?,
input: T
): DataResult<com.mojang.datafixers.util.Pair<LootTableBasicAppender, T>> {
return DataResult.error("NYI")
}
/*override fun read(
location: ResourceLocation,
obj: JsonObject,
ailootcondition: Array<out LootItemCondition>
): LootTableBasicAppender {
val entries = ArrayList<Pair<ItemStack, Double>>() val entries = ArrayList<Pair<ItemStack, Double>>()
for (entry in obj["entries"].asJsonArray) { for (entry in getJson(it as Dynamic<Any?>).asJsonArray) {
entry as JsonObject entry as JsonObject
val item = entry["item"]?.asJsonObject ?: throw JsonParseException("Missing 'item'") val item = entry["item"]?.asJsonObject ?: throw JsonParseException("Missing 'item'")
val name = item["name"]?.asString ?: throw JsonParseException("Missing 'item.name'") val name = item["name"]?.asString ?: throw JsonParseException("Missing 'item.name'")
val count = item["count"]?.asInt ?: throw JsonParseException("Missing 'item.count'") val count = item["count"]?.asInt ?: throw JsonParseException("Missing 'item.count'")
val chance = entry["chance"]?.asDouble ?: throw JsonParseException("Missing 'chance'") val chance = entry["chance"]?.asDouble ?: throw JsonParseException("Missing 'chance'")
val itemObj = ForgeRegistries.ITEMS.getValue(ResourceLocation(name)) ?: throw JsonParseException("Unknown item $name") val itemObj = ForgeRegistries.ITEMS.getValue(ResourceLocation(name))
?: throw JsonParseException("Unknown item $name")
val stack = ItemStack(itemObj, count) val stack = ItemStack(itemObj, count)
entries.add(stack to chance) entries.add(stack to chance)
} }
return LootTableBasicAppender(ailootcondition, ImmutableList.copyOf(entries)) DataResult.success(entries)
} catch (err: JsonSyntaxException) {
DataResult.error(err.message)
} catch (err: JsonParseException) {
DataResult.error(err.message)
} }
}, {
override fun write(instance: LootTableBasicAppender): JsonObject { try {
val obj = makeConditions(instance.conditions)
val listing = JsonArray() val listing = JsonArray()
for ((item, chance) in instance.items) { for ((item, chance) in it) {
val entry = JsonObject() val entry = JsonObject()
entry.add("item", JsonObject().also { entry.add("item", JsonObject().also {
@ -136,9 +124,21 @@ class LootTableBasicAppender(conditions: Array<out LootItemCondition>, items: Li
listing.add(entry) listing.add(entry)
} }
obj.add("entries", listing) DataResult.success(Dynamic(JsonOps.INSTANCE, listing))
} catch (err: JsonSyntaxException) {
DataResult.error(err.message)
} catch (err: JsonParseException) {
DataResult.error(err.message)
}
})
}
return obj val CODEC: Codec<LootTableBasicAppender> by lazy {
}*/ RecordCodecBuilder.create {
codecStart(it).and(
ItemPairListCodec.fieldOf("entries").forGetter { appender -> appender.entries }
).apply(it, ::LootTableBasicAppender)
}
}
} }
} }

View File

@ -11,8 +11,8 @@ import ru.dbotthepony.mc.otm.data.LootTableBasicAppender
object LootModifiers { object LootModifiers {
private val registry = DeferredRegister.create(ForgeRegistries.Keys.GLOBAL_LOOT_MODIFIER_SERIALIZERS, OverdriveThatMatters.MOD_ID) private val registry = DeferredRegister.create(ForgeRegistries.Keys.GLOBAL_LOOT_MODIFIER_SERIALIZERS, OverdriveThatMatters.MOD_ID)
val LOOT_TABLE_APPENDER: Codec<LootTableAppender> by registry.register("loot_table_appender") { LootTableAppender.Companion } val LOOT_TABLE_APPENDER: Codec<LootTableAppender> by registry.register("loot_appender") { LootTableAppender.CODEC }
val LOOT_TABLE_BASIC_APPENDER: Codec<LootTableBasicAppender> by registry.register("loot_table_basic_appender") { LootTableBasicAppender.Companion } val LOOT_TABLE_BASIC_APPENDER: Codec<LootTableBasicAppender> by registry.register("loot_appender_basic") { LootTableBasicAppender.CODEC }
internal fun register() { internal fun register() {
registry.register(FMLJavaModLoadingContext.get().modEventBus) registry.register(FMLJavaModLoadingContext.get().modEventBus)