i once again demand объяснение почему mojang datafixerupper настолько УЕБАНСКИЙ

This commit is contained in:
DBotThePony 2022-10-10 17:38:16 +07:00
parent a6d0957a5f
commit 130617d793
Signed by: DBot
GPG Key ID: DCC23B5715498507
5 changed files with 90 additions and 114 deletions

View File

@ -13,7 +13,7 @@ import ru.dbotthepony.mc.otm.data.IRandomizableItem
import ru.dbotthepony.mc.otm.data.ItemInInventoryCondition import ru.dbotthepony.mc.otm.data.ItemInInventoryCondition
import ru.dbotthepony.mc.otm.data.KilledByRealPlayer import ru.dbotthepony.mc.otm.data.KilledByRealPlayer
import ru.dbotthepony.mc.otm.data.BasicLootAppender import ru.dbotthepony.mc.otm.data.BasicLootAppender
import ru.dbotthepony.mc.otm.data.LootTableSeparatedAppender import ru.dbotthepony.mc.otm.data.PlainLootAppender
import ru.dbotthepony.mc.otm.data.RandomizableItemLootAppender import ru.dbotthepony.mc.otm.data.RandomizableItemLootAppender
import ru.dbotthepony.mc.otm.registry.MItems import ru.dbotthepony.mc.otm.registry.MItems
@ -26,7 +26,7 @@ fun LootTableIdCondition(location: ResourceLocation): LootItemCondition {
} }
fun addLootModifiers(it: LootModifiers) { fun addLootModifiers(it: LootModifiers) {
it.add("dungeon_pill", LootTableSeparatedAppender( it.add("dungeon_pill", PlainLootAppender(
arrayOf(LootTableIdCondition(BuiltInLootTables.SIMPLE_DUNGEON)), arrayOf(LootTableIdCondition(BuiltInLootTables.SIMPLE_DUNGEON)),
ItemStack(MItems.PILL_ANDROID, 1) to 0.4, ItemStack(MItems.PILL_ANDROID, 1) to 0.4,
ItemStack(MItems.PILL_HEAL, 2) to 0.5, ItemStack(MItems.PILL_HEAL, 2) to 0.5,
@ -41,7 +41,7 @@ fun addLootModifiers(it: LootModifiers) {
) )
)) ))
it.add("mineshaft_pill", LootTableSeparatedAppender( it.add("mineshaft_pill", PlainLootAppender(
arrayOf(LootTableIdCondition(BuiltInLootTables.ABANDONED_MINESHAFT)), arrayOf(LootTableIdCondition(BuiltInLootTables.ABANDONED_MINESHAFT)),
ItemStack(MItems.PILL_ANDROID, 1) to 0.075, ItemStack(MItems.PILL_ANDROID, 1) to 0.075,
ItemStack(MItems.PILL_HEAL, 2) to 0.1, ItemStack(MItems.PILL_HEAL, 2) to 0.1,
@ -56,14 +56,14 @@ fun addLootModifiers(it: LootModifiers) {
) )
)) ))
it.add("mineshaft_nutrient_paste", LootTableSeparatedAppender( it.add("mineshaft_nutrient_paste", PlainLootAppender(
arrayOf(LootTableIdCondition(BuiltInLootTables.ABANDONED_MINESHAFT)), arrayOf(LootTableIdCondition(BuiltInLootTables.ABANDONED_MINESHAFT)),
ItemStack(MItems.NUTRIENT_PASTE, 6) to 0.5, ItemStack(MItems.NUTRIENT_PASTE, 6) to 0.5,
ItemStack(MItems.NUTRIENT_PASTE, 8) to 0.35, ItemStack(MItems.NUTRIENT_PASTE, 8) to 0.35,
ItemStack(MItems.NUTRIENT_PASTE, 12) to 0.15, ItemStack(MItems.NUTRIENT_PASTE, 12) to 0.15,
)) ))
it.add("desert_pyramid_pill", LootTableSeparatedAppender( it.add("desert_pyramid_pill", PlainLootAppender(
arrayOf(LootTableIdCondition(BuiltInLootTables.DESERT_PYRAMID)), arrayOf(LootTableIdCondition(BuiltInLootTables.DESERT_PYRAMID)),
ItemStack(MItems.PILL_ANDROID, 1) to 0.05, ItemStack(MItems.PILL_ANDROID, 1) to 0.05,
ItemStack(MItems.PILL_HEAL, 1) to 0.3, ItemStack(MItems.PILL_HEAL, 1) to 0.3,
@ -77,7 +77,7 @@ fun addLootModifiers(it: LootModifiers) {
) )
)) ))
it.add("jungle_temple_pill", LootTableSeparatedAppender( it.add("jungle_temple_pill", PlainLootAppender(
arrayOf(LootTableIdCondition(BuiltInLootTables.JUNGLE_TEMPLE)), arrayOf(LootTableIdCondition(BuiltInLootTables.JUNGLE_TEMPLE)),
ItemStack(MItems.PILL_ANDROID, 1) to 0.5 ItemStack(MItems.PILL_ANDROID, 1) to 0.5
)) ))
@ -90,7 +90,7 @@ fun addLootModifiers(it: LootModifiers) {
) )
)) ))
it.add("end_city_modifications", LootTableSeparatedAppender( it.add("end_city_modifications", PlainLootAppender(
arrayOf(LootTableIdCondition(BuiltInLootTables.END_CITY_TREASURE)), arrayOf(LootTableIdCondition(BuiltInLootTables.END_CITY_TREASURE)),
ItemStack(MItems.PILL_ANDROID, 1) to 0.1, ItemStack(MItems.PILL_ANDROID, 1) to 0.1,
ItemStack(MItems.PILL_HUMANE, 1) to 0.3, ItemStack(MItems.PILL_HUMANE, 1) to 0.3,
@ -107,7 +107,7 @@ fun addLootModifiers(it: LootModifiers) {
) )
)) ))
it.add("shipwreck_supply_pill", LootTableSeparatedAppender( it.add("shipwreck_supply_pill", PlainLootAppender(
arrayOf(LootTableIdCondition(BuiltInLootTables.SHIPWRECK_SUPPLY)), arrayOf(LootTableIdCondition(BuiltInLootTables.SHIPWRECK_SUPPLY)),
ItemStack(MItems.PILL_HUMANE, 1) to 0.4, ItemStack(MItems.PILL_HUMANE, 1) to 0.4,
ItemStack(MItems.PILL_HEAL, 1) to 0.6, ItemStack(MItems.PILL_HEAL, 1) to 0.6,
@ -116,7 +116,7 @@ fun addLootModifiers(it: LootModifiers) {
ItemStack(MItems.PILL_HEAL, 1) to 0.6, ItemStack(MItems.PILL_HEAL, 1) to 0.6,
)) ))
it.add("shipwreck_supply_nutrient_paste", LootTableSeparatedAppender( it.add("shipwreck_supply_nutrient_paste", PlainLootAppender(
arrayOf(LootTableIdCondition(BuiltInLootTables.SHIPWRECK_SUPPLY)), arrayOf(LootTableIdCondition(BuiltInLootTables.SHIPWRECK_SUPPLY)),
ItemStack(MItems.NUTRIENT_PASTE, 12) to 0.85, ItemStack(MItems.NUTRIENT_PASTE, 12) to 0.85,
ItemStack(MItems.NUTRIENT_PASTE, 24) to 0.35, ItemStack(MItems.NUTRIENT_PASTE, 24) to 0.35,

View File

@ -26,18 +26,18 @@ import ru.dbotthepony.mc.otm.core.set
import java.lang.reflect.Type import java.lang.reflect.Type
object ItemStackCodec : Codec<ItemStack>, TypeAdapter<ItemStack>(), JsonSerializer<ItemStack>, JsonDeserializer<ItemStack> { object ItemStackCodec : Codec<ItemStack>, TypeAdapter<ItemStack>(), JsonSerializer<ItemStack>, JsonDeserializer<ItemStack> {
override fun <T : Any?> encode(input: ItemStack, ops: DynamicOps<T>, prefix: T): DataResult<T> { override fun <T : Any> encode(input: ItemStack, ops: DynamicOps<T>, prefix: T): DataResult<T> {
require(prefix == ops.empty()) { "Non-empty prefix: $prefix" } require(prefix == ops.empty()) { "Non-empty prefix: $prefix" }
return ForgeRegistries.ITEMS.codec.encode(input.item, ops, ops.empty()).map { return ForgeRegistries.ITEMS.codec.encode(input.item, ops, ops.empty()).flatMap {
ops.createMap(mapOf( DataResult.success(ops.createMap(linkedMapOf(
ops.createString("id") to it, ops.createString("id") to it,
ops.createString("count") to ops.createInt(input.count) ops.createString("count") to ops.createInt(input.count)
)) )))
} }
} }
override fun <T : Any?> decode(ops: DynamicOps<T>, input: T): DataResult<Pair<ItemStack, T>> { override fun <T : Any> decode(ops: DynamicOps<T>, input: T): DataResult<Pair<ItemStack, T>> {
return ops.getMap(input).flatMap { return ops.getMap(input).flatMap {
val item = it["id"]?.let { ForgeRegistries.ITEMS.codec.decode(ops, it) }?.result()?.orElse(null)?.first 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") val count = it["count"]?.let(ops::getNumberValue)?.result()?.orElse(null)?.toInt() ?: return@flatMap DataResult.error("Invalid item count")

View File

@ -8,7 +8,6 @@ import com.mojang.serialization.Dynamic
import com.mojang.serialization.JsonOps import com.mojang.serialization.JsonOps
import com.mojang.serialization.codecs.RecordCodecBuilder 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.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.storage.loot.Deserializers import net.minecraft.world.level.storage.loot.Deserializers
import net.minecraft.world.level.storage.loot.LootContext import net.minecraft.world.level.storage.loot.LootContext
@ -16,34 +15,15 @@ import net.minecraft.world.level.storage.loot.LootPool
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition import net.minecraft.world.level.storage.loot.predicates.LootItemCondition
import net.minecraftforge.common.loot.IGlobalLootModifier import net.minecraftforge.common.loot.IGlobalLootModifier
import net.minecraftforge.common.loot.LootModifier import net.minecraftforge.common.loot.LootModifier
import net.minecraftforge.registries.ForgeRegistries import java.util.Arrays
import ru.dbotthepony.mc.otm.core.registryName import java.util.stream.Stream
// 1.19 do be like overengineering already overengineered stuff beyond any recognition class LootPoolAppender(conditions: Array<out LootItemCondition>, pools: Stream<LootPool>) : LootModifier(conditions) {
private fun getJson(it: Dynamic<Any?>): JsonElement { private val pools = pools.collect(ImmutableList.toImmutableList())
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 { constructor(conditions: Array<out LootItemCondition>, pools: Collection<LootPool>) : this(conditions, pools.stream())
val serializer = Deserializers.createLootTableSerializer().create() constructor(conditions: Array<out LootItemCondition>, vararg pools: LootPool) : this(conditions, Arrays.stream(pools))
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 LootPoolAppender(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> {
pools.forEach { it.addRandomItems(generatedLoot::add, context) } pools.forEach { it.addRandomItems(generatedLoot::add, context) }
return generatedLoot return generatedLoot
@ -54,93 +34,37 @@ class LootPoolAppender(conditions: Array<out LootItemCondition>, private vararg
} }
companion object { companion object {
val CODEC: Codec<LootPoolAppender> by lazy { // same bro
RecordCodecBuilder.create { private fun getJson(it: Dynamic<Any?>): JsonElement {
codecStart(it).and( val value = it.value ?: throw NullPointerException("value was null")
LootPoolCodec.fieldOf("pools").forGetter { appender -> appender.pools as Array<LootPool> } return value as? JsonElement ?: it.ops.convertTo(JsonOps.INSTANCE, it)
).apply(it, ::LootPoolAppender)
}
}
}
}
class LootTableSeparatedAppender(conditions: Array<out LootItemCondition>, entries: List<Pair<ItemStack, Double>>) : LootModifier(conditions) {
constructor(conditions: Array<out LootItemCondition>, vararg entries: Pair<ItemStack, Double>) : this(conditions, entries.toList())
private val entries = ImmutableList.copyOf(entries)
override fun doApply(generatedLoot: ObjectArrayList<ItemStack>, context: LootContext): ObjectArrayList<ItemStack> {
for ((item, chance) in entries) {
if (context.random.nextDouble() <= chance) {
generatedLoot.add(item.copy())
}
} }
return generatedLoot private val lootPoolCodec: Codec<List<LootPool>>
}
override fun codec(): Codec<out IGlobalLootModifier> { init {
return CODEC val serializer = Deserializers.createLootTableSerializer().create()
}
companion object { lootPoolCodec = Codec.list(Codec.PASSTHROUGH.flatXmap({
val ItemPairListCodec: Codec<List<Pair<ItemStack, Double>>> by lazy {
Codec.PASSTHROUGH.flatXmap({
try { try {
val entries = ArrayList<Pair<ItemStack, Double>>() DataResult.success(serializer.fromJson(getJson(it as Dynamic<Any?>), LootPool::class.java))
} catch(err: JsonSyntaxException) {
for (entry in getJson(it as Dynamic<Any?>).asJsonArray) {
entry as JsonObject
val item = entry["item"]?.asJsonObject ?: throw JsonParseException("Missing 'item'")
val name = item["name"]?.asString ?: throw JsonParseException("Missing 'item.name'")
val count = item["count"]?.asInt ?: throw JsonParseException("Missing 'item.count'")
val chance = entry["chance"]?.asDouble ?: throw JsonParseException("Missing 'chance'")
val itemObj = ForgeRegistries.ITEMS.getValue(ResourceLocation(name))
?: throw JsonParseException("Unknown item $name")
val stack = ItemStack(itemObj, count)
entries.add(stack to chance)
}
DataResult.success(entries)
} catch (err: JsonSyntaxException) {
DataResult.error(err.message)
} catch (err: JsonParseException) {
DataResult.error(err.message) DataResult.error(err.message)
} }
}, { }, {
try { try {
val listing = JsonArray() DataResult.success(Dynamic(JsonOps.INSTANCE, serializer.toJsonTree(it)))
} catch(err: JsonSyntaxException) {
for ((item, chance) in it) {
val entry = JsonObject()
entry.add("item", JsonObject().also {
it.addProperty("name", item.item.registryName!!.toString())
it.addProperty("count", item.count)
})
entry.addProperty("chance", chance)
listing.add(entry)
}
DataResult.success(Dynamic(JsonOps.INSTANCE, listing))
} catch (err: JsonSyntaxException) {
DataResult.error(err.message)
} catch (err: JsonParseException) {
DataResult.error(err.message) DataResult.error(err.message)
} }
}) }))
} }
val CODEC: Codec<LootTableSeparatedAppender> by lazy { val CODEC: Codec<LootPoolAppender> =
RecordCodecBuilder.create { RecordCodecBuilder.create {
codecStart(it).and( codecStart(it).and(
ItemPairListCodec.fieldOf("entries").forGetter { appender -> appender.entries } lootPoolCodec.fieldOf("pools").forGetter(LootPoolAppender::pools)
).apply(it, ::LootTableSeparatedAppender) ).apply(it, ::LootPoolAppender)
} }
}
} }
} }

View File

@ -0,0 +1,52 @@
package ru.dbotthepony.mc.otm.data
import com.google.common.collect.ImmutableList
import com.mojang.serialization.Codec
import com.mojang.serialization.codecs.RecordCodecBuilder
import it.unimi.dsi.fastutil.objects.ObjectArrayList
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.storage.loot.LootContext
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition
import net.minecraftforge.common.loot.IGlobalLootModifier
import net.minecraftforge.common.loot.LootModifier
import java.util.*
import java.util.stream.Stream
class PlainLootAppender(conditions: Array<out LootItemCondition>, entries: Stream<Pair<ItemStack, Double>>) : LootModifier(conditions) {
constructor(conditions: Array<out LootItemCondition>, vararg entries: Pair<ItemStack, Double>) : this(conditions, Arrays.stream(entries))
constructor(conditions: Array<out LootItemCondition>, entries: Collection<Pair<ItemStack, Double>>) : this(conditions, entries.stream())
private val entries = entries.map { it.first.copy() to it.second }.collect(ImmutableList.toImmutableList())
override fun doApply(generatedLoot: ObjectArrayList<ItemStack>, context: LootContext): ObjectArrayList<ItemStack> {
for ((item, chance) in entries) {
if (context.random.nextDouble() <= chance) {
generatedLoot.add(item.copy())
}
}
return generatedLoot
}
override fun codec(): Codec<out IGlobalLootModifier> {
return CODEC
}
companion object {
private val paircodec: Codec<Pair<ItemStack, Double>> = RecordCodecBuilder.create {
it.group(
ItemStackCodec.fieldOf("item").forGetter { it.first },
Codec.DOUBLE.fieldOf("chance").forGetter { it.second }
).apply(it, ::Pair)
}
private val pairlistcodec = Codec.list(paircodec)
val CODEC: Codec<PlainLootAppender> =
RecordCodecBuilder.create {
codecStart(it).and(
pairlistcodec.fieldOf("entries").forGetter(PlainLootAppender::entries)
).apply(it, ::PlainLootAppender)
}
}
}

View File

@ -6,7 +6,7 @@ import net.minecraftforge.registries.ForgeRegistries
import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.data.LootPoolAppender import ru.dbotthepony.mc.otm.data.LootPoolAppender
import ru.dbotthepony.mc.otm.data.BasicLootAppender import ru.dbotthepony.mc.otm.data.BasicLootAppender
import ru.dbotthepony.mc.otm.data.LootTableSeparatedAppender import ru.dbotthepony.mc.otm.data.PlainLootAppender
import ru.dbotthepony.mc.otm.data.RandomizableItemLootAppender import ru.dbotthepony.mc.otm.data.RandomizableItemLootAppender
object LootModifiers { object LootModifiers {
@ -14,7 +14,7 @@ object LootModifiers {
init { init {
registry.register("loot_appender") { LootPoolAppender.CODEC } registry.register("loot_appender") { LootPoolAppender.CODEC }
registry.register("loot_appender_separated") { LootTableSeparatedAppender.CODEC } registry.register("loot_appender_separated") { PlainLootAppender.CODEC }
registry.register("loot_appender_basic") { BasicLootAppender.CODEC } registry.register("loot_appender_basic") { BasicLootAppender.CODEC }
registry.register("randomizable_item_loot_appender") { RandomizableItemLootAppender.Companion } registry.register("randomizable_item_loot_appender") { RandomizableItemLootAppender.Companion }
} }