Get rid of basic and plant loot appenders

Almost fixes #191
This commit is contained in:
DBotThePony 2022-10-27 14:17:22 +07:00
parent ef074721f8
commit 486a668e8a
Signed by: DBot
GPG Key ID: DCC23B5715498507
11 changed files with 114 additions and 120 deletions

View File

@ -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<out LootItemCondition>,
items: Stream<ItemStack>
): LootPoolAppender {
return LootPoolAppender(conditions, items.map {
lootPool {
item(it.item) {
setCount(it.count)
}
}.build()
})
}
@Suppress("FunctionName")
fun BasicLootAppender(
conditions: Array<out LootItemCondition>,
vararg items: ItemStack
) = BasicLootAppender(conditions, Arrays.stream(items))
@Suppress("FunctionName")
fun PlainLootAppender(
conditions: Array<out LootItemCondition>,
items: Stream<Pair<ItemStack, Double>>
): 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<out LootItemCondition>,
vararg items: Pair<ItemStack, Double>
) = PlainLootAppender(conditions, Arrays.stream(items))
class LootModifiers(generator: DataGenerator) : GlobalLootModifierProvider(generator, DataGen.MOD_ID) {
private val lambdas = ArrayList<(LootModifiers) -> Unit>()

View File

@ -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()
}

View File

@ -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<ResourceLocation, LootTable.Builder>
private typealias LootTableCallback = Consumer<LootTableSaver>
@ -45,6 +44,8 @@ private typealias LootTableCallbackProvider = Supplier<LootTableCallback>
private typealias LootTuple = Pair<LootTableCallbackProvider, LootContextParamSet>
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 : LootPoolSingletonContainer.Builder<*>> 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 : LootItemConditionalFunction.Builder<*>> T.blockStateCondition(bl
return this
}
fun <T : LootItemConditionalFunction.Builder<*>> 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<Int>, value: Int): StatePropertiesPredicate.Builder = hasProperty(property, value)
operator fun StatePropertiesPredicate.Builder.set(property: Property<Boolean>, value: Boolean): StatePropertiesPredicate.Builder = hasProperty(property, value)

View File

@ -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<out LootItemCondition>,
items: Stream<ItemStack>
) : LootModifier(conditions) {
constructor(
conditions: Array<out LootItemCondition>,
items: Collection<ItemStack>
) : this(conditions, items.stream())
constructor(
conditions: Array<out LootItemCondition>,
vararg items: ItemStack
) : this(conditions, Arrays.stream(items))
private val items = items.map { it.copy() }.collect(ImmutableList.toImmutableList())
override fun codec(): Codec<out IGlobalLootModifier> {
return CODEC
}
override fun doApply(
generatedLoot: ObjectArrayList<ItemStack>,
context: LootContext
): ObjectArrayList<ItemStack> {
for (item in items)
generatedLoot.add(item.copy())
return generatedLoot
}
companion object {
val CODEC: Codec<BasicLootAppender> by lazy {
RecordCodecBuilder.create {
codecStart(it)
.and(ItemStackCodec.LIST.fieldOf("items").forGetter(BasicLootAppender::items))
.apply(it, ::BasicLootAppender)
}
}
}
}

View File

@ -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<ChanceCondition> {
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"))
}
}
}

View File

@ -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,

View File

@ -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,

View File

@ -25,7 +25,10 @@ class LootPoolAppender(conditions: Array<out LootItemCondition>, pools: Stream<L
constructor(conditions: Array<out LootItemCondition>, vararg pools: LootPool) : this(conditions, Arrays.stream(pools))
override fun doApply(generatedLoot: ObjectArrayList<ItemStack>, context: LootContext): ObjectArrayList<ItemStack> {
pools.forEach { it.addRandomItems(generatedLoot::add, context) }
for (pool in pools) {
pool.addRandomItems(generatedLoot::add, context)
}
return generatedLoot
}

View File

@ -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<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

@ -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) {

View File

@ -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<LootItemConditionType>() == 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)
}
}
}