From 486a668e8ac4d79d2f414d45434bd49aecd65d95 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Thu, 27 Oct 2022 14:17:22 +0700 Subject: [PATCH] Get rid of basic and plant loot appenders Almost fixes #191 --- .../mc/otm/datagen/loot/LootModifiers.kt | 47 ++++++++++++++++ .../mc/otm/datagen/loot/LootModifiersData.kt | 5 +- .../mc/otm/datagen/loot/LootTables.kt | 13 ++++- .../mc/otm/data/BasicLootAppender.kt | 54 ------------------- .../mc/otm/data/ChanceCondition.kt | 44 +++++++++++++++ .../otm/data/ChanceWithPlaytimeCondition.kt | 2 +- .../mc/otm/data/ItemInInventoryCondition.kt | 2 +- .../mc/otm/data/LootPoolAppender.kt | 5 +- .../mc/otm/data/PlainLootAppender.kt | 52 ------------------ .../mc/otm/registry/LootModifiers.kt | 6 +-- .../mc/otm/registry/MLootItemConditions.kt | 4 +- 11 files changed, 114 insertions(+), 120 deletions(-) delete mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/data/BasicLootAppender.kt create mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/data/ChanceCondition.kt delete mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/data/PlainLootAppender.kt diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootModifiers.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootModifiers.kt index e30f859ad..c79f373f3 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootModifiers.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootModifiers.kt @@ -1,8 +1,55 @@ package ru.dbotthepony.mc.otm.datagen.loot import net.minecraft.data.DataGenerator +import net.minecraft.world.item.ItemStack +import net.minecraft.world.level.storage.loot.predicates.LootItemCondition import net.minecraftforge.common.data.GlobalLootModifierProvider +import ru.dbotthepony.mc.otm.data.LootPoolAppender import ru.dbotthepony.mc.otm.datagen.DataGen +import java.util.Arrays +import java.util.stream.Stream + +@Suppress("FunctionName") +fun BasicLootAppender( + conditions: Array, + items: Stream +): LootPoolAppender { + return LootPoolAppender(conditions, items.map { + lootPool { + item(it.item) { + setCount(it.count) + } + }.build() + }) +} + +@Suppress("FunctionName") +fun BasicLootAppender( + conditions: Array, + vararg items: ItemStack +) = BasicLootAppender(conditions, Arrays.stream(items)) + +@Suppress("FunctionName") +fun PlainLootAppender( + conditions: Array, + items: Stream> +): LootPoolAppender { + return LootPoolAppender(conditions, items.map { + lootPool { + item(it.first.item) { + setCount(it.first.count) + } + + chanceCondition(it.second) + }.build() + }) +} + +@Suppress("FunctionName") +fun PlainLootAppender( + conditions: Array, + vararg items: Pair +) = PlainLootAppender(conditions, Arrays.stream(items)) class LootModifiers(generator: DataGenerator) : GlobalLootModifierProvider(generator, DataGen.MOD_ID) { private val lambdas = ArrayList<(LootModifiers) -> Unit>() diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootModifiersData.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootModifiersData.kt index 47fe28da8..9cd5a35bf 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootModifiersData.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootModifiersData.kt @@ -11,17 +11,16 @@ import ru.dbotthepony.mc.otm.data.ChanceWithPlaytimeCondition import ru.dbotthepony.mc.otm.data.HasExosuitCondition import ru.dbotthepony.mc.otm.data.IRandomizableItem import ru.dbotthepony.mc.otm.data.ItemInInventoryCondition -import ru.dbotthepony.mc.otm.data.KilledByRealPlayer -import ru.dbotthepony.mc.otm.data.BasicLootAppender import ru.dbotthepony.mc.otm.data.KilledByRealPlayerOrIndirectly -import ru.dbotthepony.mc.otm.data.PlainLootAppender import ru.dbotthepony.mc.otm.data.RandomizableItemLootAppender import ru.dbotthepony.mc.otm.registry.MItems +@Suppress("FunctionName") fun LootTableIdCondition(location: String): LootItemCondition { return LootTableIdCondition.Builder(ResourceLocation("minecraft", location)).build() } +@Suppress("FunctionName") fun LootTableIdCondition(location: ResourceLocation): LootItemCondition { return LootTableIdCondition.Builder(location).build() } diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootTables.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootTables.kt index 157ee486e..ccae782fe 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootTables.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootTables.kt @@ -33,11 +33,10 @@ import net.minecraft.world.level.storage.loot.providers.number.ConstantValue import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity -import ru.dbotthepony.mc.otm.core.registryName +import ru.dbotthepony.mc.otm.data.ChanceCondition import java.util.function.BiConsumer import java.util.function.Consumer import java.util.function.Supplier -import kotlin.reflect.full.isSubclassOf private typealias LootTableSaver = BiConsumer private typealias LootTableCallback = Consumer @@ -45,6 +44,8 @@ private typealias LootTableCallbackProvider = Supplier private typealias LootTuple = Pair inline fun LootTable.Builder.lootPool(configurator: LootPool.Builder.() -> Unit): LootTable.Builder = withPool(LootPool.lootPool().also(configurator)) +inline fun lootPool(configurator: LootPool.Builder.() -> Unit): LootPool.Builder = LootPool.lootPool().also(configurator) + inline fun LootPool.Builder.item(item: ItemLike, configurator: LootPoolSingletonContainer.Builder<*>.() -> Unit) { add(LootItem.lootTableItem(item).also(configurator)) } @@ -55,6 +56,9 @@ fun LootPool.Builder.setRolls(count: Float): LootPool.Builder = setRolls(Constan fun LootPool.Builder.setRolls(min: Int, max: Int): LootPool.Builder = setRolls(UniformGenerator.between(min.toFloat(), max.toFloat())) fun LootPool.Builder.setRolls(min: Float, max: Float): LootPool.Builder = setRolls(UniformGenerator.between(min, max)) +fun LootPool.Builder.condition(value: LootItemCondition.Builder): LootPool.Builder = `when`(value) +fun LootPool.Builder.chanceCondition(chance: Double): LootPool.Builder = condition(ChanceCondition(chance)) + fun > T.setCount(count: Int, configurator: LootItemConditionalFunction.Builder<*>.() -> Unit = {}): T { apply(SetItemCountFunction.setCount(ConstantValue.exactly(count.toFloat())).also(configurator)) return this @@ -90,6 +94,11 @@ inline fun > T.blockStateCondition(bl return this } +fun > T.chanceCondition(chance: Double): T { + condition(ChanceCondition(chance)) + return this +} + operator fun StatePropertiesPredicate.Builder.set(property: Property<*>, value: String): StatePropertiesPredicate.Builder = hasProperty(property, value) operator fun StatePropertiesPredicate.Builder.set(property: Property, value: Int): StatePropertiesPredicate.Builder = hasProperty(property, value) operator fun StatePropertiesPredicate.Builder.set(property: Property, value: Boolean): StatePropertiesPredicate.Builder = hasProperty(property, value) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/data/BasicLootAppender.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/data/BasicLootAppender.kt deleted file mode 100644 index 85bcac885..000000000 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/data/BasicLootAppender.kt +++ /dev/null @@ -1,54 +0,0 @@ -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.Arrays -import java.util.stream.Stream - -class BasicLootAppender( - conditions: Array, - items: Stream -) : LootModifier(conditions) { - constructor( - conditions: Array, - items: Collection - ) : this(conditions, items.stream()) - - constructor( - conditions: Array, - vararg items: ItemStack - ) : this(conditions, Arrays.stream(items)) - - private val items = items.map { it.copy() }.collect(ImmutableList.toImmutableList()) - - override fun codec(): Codec { - return CODEC - } - - override fun doApply( - generatedLoot: ObjectArrayList, - context: LootContext - ): ObjectArrayList { - for (item in items) - generatedLoot.add(item.copy()) - - return generatedLoot - } - - companion object { - val CODEC: Codec by lazy { - RecordCodecBuilder.create { - codecStart(it) - .and(ItemStackCodec.LIST.fieldOf("items").forGetter(BasicLootAppender::items)) - .apply(it, ::BasicLootAppender) - } - } - } -} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/data/ChanceCondition.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/data/ChanceCondition.kt new file mode 100644 index 000000000..78eb4d696 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/data/ChanceCondition.kt @@ -0,0 +1,44 @@ +package ru.dbotthepony.mc.otm.data + +import com.google.gson.JsonDeserializationContext +import com.google.gson.JsonObject +import com.google.gson.JsonPrimitive +import com.google.gson.JsonSerializationContext +import com.google.gson.JsonSyntaxException +import net.minecraft.world.level.storage.loot.LootContext +import net.minecraft.world.level.storage.loot.Serializer +import net.minecraft.world.level.storage.loot.predicates.LootItemCondition +import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType +import ru.dbotthepony.mc.otm.core.set +import ru.dbotthepony.mc.otm.registry.MLootItemConditions + +/** + * u serious? + */ +data class ChanceCondition(val chance: Double) : LootItemCondition, LootItemCondition.Builder { + init { + require(chance in 0.0 .. 1.0) { "Invalid chance: $chance" } + } + + override fun test(t: LootContext): Boolean { + return t.random.nextDouble() < chance + } + + override fun getType(): LootItemConditionType { + return MLootItemConditions.CHANCE + } + + override fun build(): LootItemCondition { + return this + } + + companion object : Serializer { + override fun serialize(p_79325_: JsonObject, p_79326_: ChanceCondition, p_79327_: JsonSerializationContext) { + p_79325_["chance"] = JsonPrimitive(p_79326_.chance) + } + + override fun deserialize(p_79323_: JsonObject, p_79324_: JsonDeserializationContext): ChanceCondition { + return ChanceCondition(p_79323_["chance"]?.asDouble ?: throw JsonSyntaxException("Invalid chance json element")) + } + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/data/ChanceWithPlaytimeCondition.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/data/ChanceWithPlaytimeCondition.kt index 4922085f4..da79a0e9f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/data/ChanceWithPlaytimeCondition.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/data/ChanceWithPlaytimeCondition.kt @@ -13,7 +13,7 @@ import ru.dbotthepony.mc.otm.capability.matteryPlayer import ru.dbotthepony.mc.otm.core.set import ru.dbotthepony.mc.otm.registry.MLootItemConditions -class ChanceWithPlaytimeCondition( +data class ChanceWithPlaytimeCondition( val minPlaytime: Int = 0, val maxPlaytime: Int, val minProbability: Double, diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/data/ItemInInventoryCondition.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/data/ItemInInventoryCondition.kt index ad9a33330..34d214c2b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/data/ItemInInventoryCondition.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/data/ItemInInventoryCondition.kt @@ -19,7 +19,7 @@ import ru.dbotthepony.mc.otm.core.registryName import ru.dbotthepony.mc.otm.core.set import ru.dbotthepony.mc.otm.registry.MLootItemConditions -class ItemInInventoryCondition( +data class ItemInInventoryCondition( val item: ItemStack, val matchDamage: Boolean = false, val matchNBT: Boolean = false, diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/data/LootPoolAppender.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/data/LootPoolAppender.kt index cf1b69275..27f792704 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/data/LootPoolAppender.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/data/LootPoolAppender.kt @@ -25,7 +25,10 @@ class LootPoolAppender(conditions: Array, pools: Stream, vararg pools: LootPool) : this(conditions, Arrays.stream(pools)) override fun doApply(generatedLoot: ObjectArrayList, context: LootContext): ObjectArrayList { - pools.forEach { it.addRandomItems(generatedLoot::add, context) } + for (pool in pools) { + pool.addRandomItems(generatedLoot::add, context) + } + return generatedLoot } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/data/PlainLootAppender.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/data/PlainLootAppender.kt deleted file mode 100644 index 614933aef..000000000 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/data/PlainLootAppender.kt +++ /dev/null @@ -1,52 +0,0 @@ -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, entries: Stream>) : LootModifier(conditions) { - constructor(conditions: Array, vararg entries: Pair) : this(conditions, Arrays.stream(entries)) - constructor(conditions: Array, entries: Collection>) : this(conditions, entries.stream()) - - private val entries = entries.map { it.first.copy() to it.second }.collect(ImmutableList.toImmutableList()) - - override fun doApply(generatedLoot: ObjectArrayList, context: LootContext): ObjectArrayList { - for ((item, chance) in entries) { - if (context.random.nextDouble() <= chance) { - generatedLoot.add(item.copy()) - } - } - - return generatedLoot - } - - override fun codec(): Codec { - return CODEC - } - - companion object { - private val paircodec: Codec> = 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 = - RecordCodecBuilder.create { - codecStart(it).and( - pairlistcodec.fieldOf("entries").forGetter(PlainLootAppender::entries) - ).apply(it, ::PlainLootAppender) - } - } -} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/LootModifiers.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/LootModifiers.kt index d9051b0b2..aa0eb0bb5 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/LootModifiers.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/LootModifiers.kt @@ -5,8 +5,6 @@ import net.minecraftforge.registries.DeferredRegister import net.minecraftforge.registries.ForgeRegistries import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.data.LootPoolAppender -import ru.dbotthepony.mc.otm.data.BasicLootAppender -import ru.dbotthepony.mc.otm.data.PlainLootAppender import ru.dbotthepony.mc.otm.data.RandomizableItemLootAppender object LootModifiers { @@ -14,9 +12,7 @@ object LootModifiers { init { registry.register("loot_appender") { LootPoolAppender.CODEC } - registry.register("loot_appender_separated") { PlainLootAppender.CODEC } - registry.register("loot_appender_basic") { BasicLootAppender.CODEC } - registry.register("randomizable_item_loot_appender") { RandomizableItemLootAppender.Companion } + registry.register("randomized_appender") { RandomizableItemLootAppender.Companion } } internal fun register(bus: IEventBus) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MLootItemConditions.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MLootItemConditions.kt index c8dd6339a..ec467d01e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MLootItemConditions.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MLootItemConditions.kt @@ -3,7 +3,6 @@ package ru.dbotthepony.mc.otm.registry import net.minecraft.core.Registry import net.minecraft.resources.ResourceLocation import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType -import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent import net.minecraftforge.registries.RegisterEvent import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.data.ChanceWithPlaytimeCondition @@ -11,6 +10,7 @@ import ru.dbotthepony.mc.otm.data.HasExosuitCondition import ru.dbotthepony.mc.otm.data.ItemInInventoryCondition import ru.dbotthepony.mc.otm.data.KilledByRealPlayer import ru.dbotthepony.mc.otm.data.KilledByRealPlayerOrIndirectly +import ru.dbotthepony.mc.otm.data.ChanceCondition object MLootItemConditions { val HAS_EXOSUIT = LootItemConditionType(HasExosuitCondition) @@ -18,6 +18,7 @@ object MLootItemConditions { val KILLED_BY_REAL_PLAYER_OR_INDIRECTLY = LootItemConditionType(KilledByRealPlayerOrIndirectly) val CHANCE_WITH_PLAYTIME = LootItemConditionType(ChanceWithPlaytimeCondition) val ITEM_IN_INVENTORY = LootItemConditionType(ItemInInventoryCondition) + val CHANCE = LootItemConditionType(ChanceCondition.Companion) internal fun register(event: RegisterEvent) { if (event.getVanillaRegistry() == Registry.LOOT_CONDITION_TYPE) { @@ -26,6 +27,7 @@ object MLootItemConditions { Registry.LOOT_CONDITION_TYPE.register(ResourceLocation(OverdriveThatMatters.MOD_ID, "item_in_inventory"), ITEM_IN_INVENTORY) Registry.LOOT_CONDITION_TYPE.register(ResourceLocation(OverdriveThatMatters.MOD_ID, "killed_by_real_player"), KILLED_BY_REAL_PLAYER) Registry.LOOT_CONDITION_TYPE.register(ResourceLocation(OverdriveThatMatters.MOD_ID, "killed_by_real_player_or_indirectly"), KILLED_BY_REAL_PLAYER_OR_INDIRECTLY) + Registry.LOOT_CONDITION_TYPE.register(ResourceLocation(OverdriveThatMatters.MOD_ID, "chance"), CHANCE) } } }