Exosuit Probe drops!
This commit is contained in:
parent
47e9840365
commit
38334ec9e7
@ -1,45 +1,61 @@
|
|||||||
package ru.dbotthepony.mc.otm.datagen.loot
|
package ru.dbotthepony.mc.otm.datagen.loot
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
|
import net.minecraft.world.entity.EntityType
|
||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
|
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition
|
||||||
|
import net.minecraft.world.level.storage.loot.predicates.LootItemKilledByPlayerCondition
|
||||||
import net.minecraftforge.common.loot.LootTableIdCondition
|
import net.minecraftforge.common.loot.LootTableIdCondition
|
||||||
|
import ru.dbotthepony.mc.otm.data.ChanceWithPlaytimeCondition
|
||||||
|
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.LootTableBasicAppender
|
import ru.dbotthepony.mc.otm.data.LootTableBasicAppender
|
||||||
|
import ru.dbotthepony.mc.otm.data.LootTableSeparatedAppender
|
||||||
import ru.dbotthepony.mc.otm.registry.MItems
|
import ru.dbotthepony.mc.otm.registry.MItems
|
||||||
|
|
||||||
|
fun LootTableIdCondition(location: String): LootItemCondition {
|
||||||
|
return LootTableIdCondition.Builder(ResourceLocation("minecraft", location)).build()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun LootTableIdCondition(location: ResourceLocation): LootItemCondition {
|
||||||
|
return LootTableIdCondition.Builder(location).build()
|
||||||
|
}
|
||||||
|
|
||||||
fun addLootModifiers(it: LootModifiers) {
|
fun addLootModifiers(it: LootModifiers) {
|
||||||
it.add("dungeon_pill", LootTableBasicAppender(
|
it.add("dungeon_pill", LootTableSeparatedAppender(
|
||||||
arrayOf(LootTableIdCondition.Builder(ResourceLocation("chests/simple_dungeon")).build()),
|
arrayOf(LootTableIdCondition.Builder(ResourceLocation("chests/simple_dungeon")).build()),
|
||||||
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,
|
||||||
ItemStack(MItems.PILL_HEAL, 1) to 0.75,
|
ItemStack(MItems.PILL_HEAL, 1) to 0.75,
|
||||||
))
|
))
|
||||||
|
|
||||||
it.add("mineshaft_pill", LootTableBasicAppender(
|
it.add("mineshaft_pill", LootTableSeparatedAppender(
|
||||||
arrayOf(LootTableIdCondition.Builder(ResourceLocation("chests/abandoned_mineshaft")).build()),
|
arrayOf(LootTableIdCondition.Builder(ResourceLocation("chests/abandoned_mineshaft")).build()),
|
||||||
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,
|
||||||
ItemStack(MItems.PILL_HEAL, 1) to 0.4,
|
ItemStack(MItems.PILL_HEAL, 1) to 0.4,
|
||||||
))
|
))
|
||||||
|
|
||||||
it.add("mineshaft_nutrient_paste", LootTableBasicAppender(
|
it.add("mineshaft_nutrient_paste", LootTableSeparatedAppender(
|
||||||
arrayOf(LootTableIdCondition.Builder(ResourceLocation("chests/abandoned_mineshaft")).build()),
|
arrayOf(LootTableIdCondition.Builder(ResourceLocation("chests/abandoned_mineshaft")).build()),
|
||||||
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", LootTableBasicAppender(
|
it.add("desert_pyramid_pill", LootTableSeparatedAppender(
|
||||||
arrayOf(LootTableIdCondition.Builder(ResourceLocation("chests/abandoned_mineshaft")).build()),
|
arrayOf(LootTableIdCondition.Builder(ResourceLocation("chests/abandoned_mineshaft")).build()),
|
||||||
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,
|
||||||
))
|
))
|
||||||
|
|
||||||
it.add("jungle_temple_pill", LootTableBasicAppender(
|
it.add("jungle_temple_pill", LootTableSeparatedAppender(
|
||||||
arrayOf(LootTableIdCondition.Builder(ResourceLocation("chests/jungle_temple")).build()),
|
arrayOf(LootTableIdCondition.Builder(ResourceLocation("chests/jungle_temple")).build()),
|
||||||
ItemStack(MItems.PILL_ANDROID, 1) to 0.5
|
ItemStack(MItems.PILL_ANDROID, 1) to 0.5
|
||||||
))
|
))
|
||||||
|
|
||||||
it.add("end_city_modifications", LootTableBasicAppender(
|
it.add("end_city_modifications", LootTableSeparatedAppender(
|
||||||
arrayOf(LootTableIdCondition.Builder(ResourceLocation("chests/end_city_treasure")).build()),
|
arrayOf(LootTableIdCondition.Builder(ResourceLocation("chests/end_city_treasure")).build()),
|
||||||
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,
|
||||||
@ -47,16 +63,36 @@ fun addLootModifiers(it: LootModifiers) {
|
|||||||
ItemStack(MItems.ZPM_BATTERY, 1) to 0.005,
|
ItemStack(MItems.ZPM_BATTERY, 1) to 0.005,
|
||||||
))
|
))
|
||||||
|
|
||||||
it.add("shipwreck_supply_pill", LootTableBasicAppender(
|
it.add("shipwreck_supply_pill", LootTableSeparatedAppender(
|
||||||
arrayOf(LootTableIdCondition.Builder(ResourceLocation("chests/shipwreck_supply")).build()),
|
arrayOf(LootTableIdCondition.Builder(ResourceLocation("chests/shipwreck_supply")).build()),
|
||||||
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,
|
||||||
))
|
))
|
||||||
|
|
||||||
it.add("shipwreck_supply_nutrient_paste", LootTableBasicAppender(
|
it.add("shipwreck_supply_nutrient_paste", LootTableSeparatedAppender(
|
||||||
arrayOf(LootTableIdCondition.Builder(ResourceLocation("chests/shipwreck_supply")).build()),
|
arrayOf(LootTableIdCondition.Builder(ResourceLocation("chests/shipwreck_supply")).build()),
|
||||||
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,
|
||||||
ItemStack(MItems.NUTRIENT_PASTE, 38) to 0.1,
|
ItemStack(MItems.NUTRIENT_PASTE, 38) to 0.1,
|
||||||
))
|
))
|
||||||
|
|
||||||
|
it.add("exosuit_probe_enderman_drop", LootTableBasicAppender(
|
||||||
|
arrayOf(
|
||||||
|
LootTableIdCondition(EntityType.ENDERMAN.defaultLootTable),
|
||||||
|
HasExosuitCondition.INVERTED,
|
||||||
|
KilledByRealPlayer,
|
||||||
|
ChanceWithPlaytimeCondition(
|
||||||
|
minPlaytime = 20 * 60 * 10,
|
||||||
|
maxPlaytime = 20 * 60 * 120,
|
||||||
|
minProbability = 0.1,
|
||||||
|
maxProbability = 0.5,
|
||||||
|
),
|
||||||
|
ItemInInventoryCondition(
|
||||||
|
ItemStack(MItems.EXOSUIT_PROBE)
|
||||||
|
).invert().build()
|
||||||
|
),
|
||||||
|
listOf(
|
||||||
|
ItemStack(MItems.EXOSUIT_PROBE)
|
||||||
|
)
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package ru.dbotthepony.mc.otm.capability
|
package ru.dbotthepony.mc.otm.capability
|
||||||
|
|
||||||
|
import com.google.common.collect.Streams
|
||||||
import net.minecraft.core.Direction
|
import net.minecraft.core.Direction
|
||||||
import net.minecraft.world.entity.player.Player
|
import net.minecraft.world.entity.player.Player
|
||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
@ -11,9 +12,11 @@ import net.minecraftforge.fml.ModList
|
|||||||
import ru.dbotthepony.mc.otm.compat.mekanism.getMekanismEnergySided
|
import ru.dbotthepony.mc.otm.compat.mekanism.getMekanismEnergySided
|
||||||
import ru.dbotthepony.mc.otm.compat.mekanism.mekanismEnergy
|
import ru.dbotthepony.mc.otm.compat.mekanism.mekanismEnergy
|
||||||
import ru.dbotthepony.mc.otm.container.iterator
|
import ru.dbotthepony.mc.otm.container.iterator
|
||||||
|
import ru.dbotthepony.mc.otm.container.stream
|
||||||
import ru.dbotthepony.mc.otm.core.iterator
|
import ru.dbotthepony.mc.otm.core.iterator
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||||
import ru.dbotthepony.mc.otm.core.orNull
|
import ru.dbotthepony.mc.otm.core.orNull
|
||||||
|
import java.util.stream.Stream
|
||||||
|
|
||||||
val ICapabilityProvider.matteryPlayer: MatteryPlayerCapability? get() = getCapability(MatteryCapability.MATTERY_PLAYER).orNull()
|
val ICapabilityProvider.matteryPlayer: MatteryPlayerCapability? get() = getCapability(MatteryCapability.MATTERY_PLAYER).orNull()
|
||||||
|
|
||||||
@ -145,6 +148,16 @@ fun ICapabilityProvider.getMatteryEnergySided(side: Direction? = null): LazyOpti
|
|||||||
return LazyOptional.empty()
|
return LazyOptional.empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Player.itemStream(): Stream<out ItemStack> {
|
||||||
|
matteryPlayer?.let {
|
||||||
|
if (it.hasExoSuit) {
|
||||||
|
return Streams.concat(inventory.stream(), it.exoSuitContainer.stream())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return inventory.stream()
|
||||||
|
}
|
||||||
|
|
||||||
fun Player.extendedItemIterator(): MutableIterator<ItemStack> {
|
fun Player.extendedItemIterator(): MutableIterator<ItemStack> {
|
||||||
return object : MutableIterator<ItemStack> {
|
return object : MutableIterator<ItemStack> {
|
||||||
private val regular = this@extendedItemIterator.inventory.iterator()
|
private val regular = this@extendedItemIterator.inventory.iterator()
|
||||||
|
@ -0,0 +1,77 @@
|
|||||||
|
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 net.minecraft.world.level.storage.loot.LootContext
|
||||||
|
import net.minecraft.world.level.storage.loot.Serializer
|
||||||
|
import net.minecraft.world.level.storage.loot.parameters.LootContextParams
|
||||||
|
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition
|
||||||
|
import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType
|
||||||
|
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
||||||
|
import ru.dbotthepony.mc.otm.core.set
|
||||||
|
import ru.dbotthepony.mc.otm.registry.MLootItemConditions
|
||||||
|
|
||||||
|
class ChanceWithPlaytimeCondition(
|
||||||
|
val minPlaytime: Int = 0,
|
||||||
|
val maxPlaytime: Int,
|
||||||
|
val minProbability: Double,
|
||||||
|
val maxProbability: Double
|
||||||
|
) : LootItemCondition, LootItemCondition.Builder {
|
||||||
|
init {
|
||||||
|
require(minPlaytime <= maxPlaytime) { "Invalid playtime range: min $minPlaytime, max $maxPlaytime" }
|
||||||
|
require(minProbability <= maxProbability) { "Invalid probability range: min $minProbability, max $maxProbability" }
|
||||||
|
|
||||||
|
require(maxProbability <= 1.0) { "Excessive max probability: $maxProbability" }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun test(t: LootContext): Boolean {
|
||||||
|
return t[LootContextParams.LAST_DAMAGE_PLAYER]?.matteryPlayer?.let {
|
||||||
|
val chance: Double
|
||||||
|
|
||||||
|
if (it.ticksIExist < minPlaytime) {
|
||||||
|
chance = minProbability
|
||||||
|
} else if (it.ticksIExist >= maxPlaytime) {
|
||||||
|
chance = maxProbability
|
||||||
|
} else {
|
||||||
|
chance = minProbability + (maxProbability - minProbability) * (it.ticksIExist - minPlaytime).toDouble() / (maxPlaytime - minPlaytime).toDouble()
|
||||||
|
}
|
||||||
|
|
||||||
|
return t.random.nextDouble() <= chance
|
||||||
|
} ?: (t.random.nextDouble() <= minProbability)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getType(): LootItemConditionType {
|
||||||
|
return MLootItemConditions.CHANCE_WITH_PLAYTIME
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun build(): LootItemCondition {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object : Serializer<ChanceWithPlaytimeCondition> {
|
||||||
|
override fun serialize(
|
||||||
|
p_79325_: JsonObject,
|
||||||
|
p_79326_: ChanceWithPlaytimeCondition,
|
||||||
|
p_79327_: JsonSerializationContext
|
||||||
|
) {
|
||||||
|
p_79325_["minPlaytime"] = JsonPrimitive(p_79326_.minPlaytime)
|
||||||
|
p_79325_["maxPlaytime"] = JsonPrimitive(p_79326_.maxPlaytime)
|
||||||
|
p_79325_["minProbability"] = JsonPrimitive(p_79326_.minProbability)
|
||||||
|
p_79325_["maxProbability"] = JsonPrimitive(p_79326_.maxProbability)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deserialize(
|
||||||
|
p_79323_: JsonObject,
|
||||||
|
p_79324_: JsonDeserializationContext
|
||||||
|
): ChanceWithPlaytimeCondition {
|
||||||
|
return ChanceWithPlaytimeCondition(
|
||||||
|
minPlaytime = p_79323_["minPlaytime"].asInt,
|
||||||
|
maxPlaytime = p_79323_["maxPlaytime"].asInt,
|
||||||
|
minProbability = p_79323_["minProbability"].asDouble,
|
||||||
|
maxProbability = p_79323_["maxProbability"].asDouble,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
src/main/kotlin/ru/dbotthepony/mc/otm/data/Ext.kt
Normal file
13
src/main/kotlin/ru/dbotthepony/mc/otm/data/Ext.kt
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.data
|
||||||
|
|
||||||
|
import com.mojang.serialization.DataResult
|
||||||
|
import net.minecraft.world.level.storage.loot.LootContext
|
||||||
|
import net.minecraft.world.level.storage.loot.parameters.LootContextParam
|
||||||
|
|
||||||
|
operator fun <T> LootContext.get(param: LootContextParam<T>): T? {
|
||||||
|
return getParamOrNull(param)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> DataResult<T>.getOrNull(): T? {
|
||||||
|
return get().left().orElse(null)
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.data
|
||||||
|
|
||||||
|
import com.google.gson.JsonDeserializationContext
|
||||||
|
import com.google.gson.JsonObject
|
||||||
|
import com.google.gson.JsonSerializationContext
|
||||||
|
import net.minecraft.world.level.storage.loot.LootContext
|
||||||
|
import net.minecraft.world.level.storage.loot.Serializer
|
||||||
|
import net.minecraft.world.level.storage.loot.parameters.LootContextParams
|
||||||
|
import net.minecraft.world.level.storage.loot.predicates.InvertedLootItemCondition
|
||||||
|
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition
|
||||||
|
import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType
|
||||||
|
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
||||||
|
import ru.dbotthepony.mc.otm.registry.MLootItemConditions
|
||||||
|
|
||||||
|
object HasExosuitCondition : LootItemCondition, Serializer<HasExosuitCondition>, LootItemCondition.Builder {
|
||||||
|
override fun test(t: LootContext): Boolean {
|
||||||
|
t[LootContextParams.LAST_DAMAGE_PLAYER]?.matteryPlayer?.let {
|
||||||
|
return it.hasExoSuit
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getType(): LootItemConditionType {
|
||||||
|
return MLootItemConditions.HAS_EXOSUIT
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun serialize(p_79325_: JsonObject, p_79326_: HasExosuitCondition, p_79327_: JsonSerializationContext) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deserialize(p_79323_: JsonObject, p_79324_: JsonDeserializationContext): HasExosuitCondition {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun build(): LootItemCondition {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
val INVERTED: LootItemCondition = InvertedLootItemCondition.invert(this).build()
|
||||||
|
}
|
@ -0,0 +1,91 @@
|
|||||||
|
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.resources.ResourceLocation
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
|
import net.minecraft.world.item.Items
|
||||||
|
import net.minecraft.world.level.storage.loot.LootContext
|
||||||
|
import net.minecraft.world.level.storage.loot.Serializer
|
||||||
|
import net.minecraft.world.level.storage.loot.parameters.LootContextParams
|
||||||
|
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition
|
||||||
|
import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType
|
||||||
|
import net.minecraftforge.registries.ForgeRegistries
|
||||||
|
import ru.dbotthepony.mc.otm.capability.itemStream
|
||||||
|
import ru.dbotthepony.mc.otm.core.registryName
|
||||||
|
import ru.dbotthepony.mc.otm.core.set
|
||||||
|
import ru.dbotthepony.mc.otm.registry.MLootItemConditions
|
||||||
|
|
||||||
|
class ItemInInventoryCondition(
|
||||||
|
val item: ItemStack,
|
||||||
|
val matchDamage: Boolean = false,
|
||||||
|
val matchNBT: Boolean = false
|
||||||
|
) : LootItemCondition, LootItemCondition.Builder {
|
||||||
|
override fun test(t: LootContext): Boolean {
|
||||||
|
val matches = t[LootContextParams.LAST_DAMAGE_PLAYER]?.itemStream()?.filter {
|
||||||
|
if (matchDamage && matchNBT) {
|
||||||
|
it.item == item.item && it.tag == item.tag && it.damageValue == item.damageValue
|
||||||
|
} else if (matchDamage) {
|
||||||
|
it.item == item.item && it.damageValue == item.damageValue
|
||||||
|
} else if (matchNBT) {
|
||||||
|
it.item == item.item && it.tag == item.tag
|
||||||
|
} else {
|
||||||
|
it.item == item.item
|
||||||
|
}
|
||||||
|
} ?: return false
|
||||||
|
|
||||||
|
var count = 0
|
||||||
|
|
||||||
|
for (match in matches) {
|
||||||
|
count += match.count
|
||||||
|
|
||||||
|
if (count >= item.count) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getType(): LootItemConditionType {
|
||||||
|
return MLootItemConditions.ITEM_IN_INVENTORY
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun build(): LootItemCondition {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object : Serializer<ItemInInventoryCondition> {
|
||||||
|
override fun serialize(
|
||||||
|
p_79325_: JsonObject,
|
||||||
|
p_79326_: ItemInInventoryCondition,
|
||||||
|
p_79327_: JsonSerializationContext
|
||||||
|
) {
|
||||||
|
p_79325_["item"] = JsonPrimitive(p_79326_.item.item.registryName!!.toString())
|
||||||
|
p_79325_["itemCount"] = JsonPrimitive(p_79326_.item.count)
|
||||||
|
p_79325_["matchDamage"] = JsonPrimitive(p_79326_.matchDamage)
|
||||||
|
p_79325_["matchNBT"] = JsonPrimitive(p_79326_.matchNBT)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deserialize(p_79323_: JsonObject, p_79324_: JsonDeserializationContext): ItemInInventoryCondition {
|
||||||
|
val item = p_79323_["item"]?.asString ?: throw JsonSyntaxException("Missing item")
|
||||||
|
val itemCount = p_79323_["itemCount"]?.asInt ?: throw JsonSyntaxException("Missing itemCount")
|
||||||
|
val matchDamage = p_79323_["matchDamage"]?.asBoolean ?: throw JsonSyntaxException("Missing matchDamage")
|
||||||
|
val matchNBT = p_79323_["matchNBT"]?.asBoolean ?: throw JsonSyntaxException("Missing matchNBT")
|
||||||
|
|
||||||
|
val getItem = ForgeRegistries.ITEMS.getValue(ResourceLocation(item))
|
||||||
|
|
||||||
|
if (getItem == null || getItem == Items.AIR) {
|
||||||
|
throw JsonSyntaxException("Invalid item $item")
|
||||||
|
}
|
||||||
|
|
||||||
|
return ItemInInventoryCondition(
|
||||||
|
ItemStack(getItem, itemCount),
|
||||||
|
matchDamage, matchNBT
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
39
src/main/kotlin/ru/dbotthepony/mc/otm/data/ItemStackCodec.kt
Normal file
39
src/main/kotlin/ru/dbotthepony/mc/otm/data/ItemStackCodec.kt
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.data
|
||||||
|
|
||||||
|
import com.mojang.datafixers.util.Pair
|
||||||
|
import com.mojang.serialization.Codec
|
||||||
|
import com.mojang.serialization.DataResult
|
||||||
|
import com.mojang.serialization.DynamicOps
|
||||||
|
import com.mojang.serialization.codecs.ListCodec
|
||||||
|
import net.minecraft.resources.ResourceLocation
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
|
import net.minecraft.world.item.Items
|
||||||
|
import net.minecraftforge.registries.ForgeRegistries
|
||||||
|
|
||||||
|
object ItemStackCodec : Codec<ItemStack> {
|
||||||
|
override fun <T : Any?> encode(input: ItemStack, ops: DynamicOps<T>, prefix: T): DataResult<T> {
|
||||||
|
require(prefix == ops.empty()) { "Non-empty prefix: $prefix" }
|
||||||
|
|
||||||
|
return ForgeRegistries.ITEMS.codec.encode(input.item, ops, ops.empty()).map {
|
||||||
|
ops.createMap(mapOf(
|
||||||
|
ops.createString("id") to it,
|
||||||
|
ops.createString("count") to ops.createInt(input.count)
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <T : Any?> decode(ops: DynamicOps<T>, input: T): DataResult<Pair<ItemStack, T>> {
|
||||||
|
return ops.getMap(input).flatMap {
|
||||||
|
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")
|
||||||
|
|
||||||
|
if (item == null || item == Items.AIR) {
|
||||||
|
return@flatMap DataResult.error("Unknown item type $item")
|
||||||
|
}
|
||||||
|
|
||||||
|
DataResult.success(ItemStack(item, count))
|
||||||
|
}.map { Pair.of(it, ops.empty()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
val LIST = ListCodec(this)
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.data
|
||||||
|
|
||||||
|
import com.google.gson.JsonDeserializationContext
|
||||||
|
import com.google.gson.JsonObject
|
||||||
|
import com.google.gson.JsonSerializationContext
|
||||||
|
import net.minecraft.world.level.storage.loot.LootContext
|
||||||
|
import net.minecraft.world.level.storage.loot.Serializer
|
||||||
|
import net.minecraft.world.level.storage.loot.parameters.LootContextParams
|
||||||
|
import net.minecraft.world.level.storage.loot.predicates.InvertedLootItemCondition
|
||||||
|
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition
|
||||||
|
import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType
|
||||||
|
import net.minecraftforge.common.util.FakePlayer
|
||||||
|
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
||||||
|
import ru.dbotthepony.mc.otm.registry.MLootItemConditions
|
||||||
|
|
||||||
|
object KilledByRealPlayer : LootItemCondition, Serializer<KilledByRealPlayer>, LootItemCondition.Builder {
|
||||||
|
override fun test(t: LootContext): Boolean {
|
||||||
|
return t.hasParam(LootContextParams.LAST_DAMAGE_PLAYER) && t[LootContextParams.LAST_DAMAGE_PLAYER] !is FakePlayer
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getType(): LootItemConditionType {
|
||||||
|
return MLootItemConditions.HAS_EXOSUIT
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun serialize(p_79325_: JsonObject, p_79326_: KilledByRealPlayer, p_79327_: JsonSerializationContext) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deserialize(p_79323_: JsonObject, p_79324_: JsonDeserializationContext): KilledByRealPlayer {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun build(): LootItemCondition {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
val INVERTED: LootItemCondition = InvertedLootItemCondition.invert(this).build()
|
||||||
|
}
|
@ -64,7 +64,7 @@ class LootTableAppender(conditions: Array<out LootItemCondition>, private vararg
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LootTableBasicAppender(conditions: Array<out LootItemCondition>, entries: List<Pair<ItemStack, Double>>) : LootModifier(conditions) {
|
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())
|
constructor(conditions: Array<out LootItemCondition>, vararg entries: Pair<ItemStack, Double>) : this(conditions, entries.toList())
|
||||||
|
|
||||||
private val entries = ImmutableList.copyOf(entries)
|
private val entries = ImmutableList.copyOf(entries)
|
||||||
@ -135,11 +135,11 @@ class LootTableBasicAppender(conditions: Array<out LootItemCondition>, entries:
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
val CODEC: Codec<LootTableBasicAppender> by lazy {
|
val CODEC: Codec<LootTableSeparatedAppender> by lazy {
|
||||||
RecordCodecBuilder.create {
|
RecordCodecBuilder.create {
|
||||||
codecStart(it).and(
|
codecStart(it).and(
|
||||||
ItemPairListCodec.fieldOf("entries").forGetter { appender -> appender.entries }
|
ItemPairListCodec.fieldOf("entries").forGetter { appender -> appender.entries }
|
||||||
).apply(it, ::LootTableBasicAppender)
|
).apply(it, ::LootTableSeparatedAppender)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.data
|
||||||
|
|
||||||
|
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 ru.dbotthepony.mc.otm.core.ImmutableList
|
||||||
|
|
||||||
|
class LootTableBasicAppender(
|
||||||
|
conditions: Array<out LootItemCondition>,
|
||||||
|
items: List<ItemStack>
|
||||||
|
) : LootModifier(conditions) {
|
||||||
|
private val items = ImmutableList(items.size) { items[it].copy() }
|
||||||
|
|
||||||
|
override fun codec(): Codec<out IGlobalLootModifier> {
|
||||||
|
return CODEC
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun doApply(
|
||||||
|
generatedLoot: ObjectArrayList<ItemStack>,
|
||||||
|
context: LootContext
|
||||||
|
): ObjectArrayList<ItemStack> {
|
||||||
|
generatedLoot.addAll(items)
|
||||||
|
return generatedLoot
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val CODEC: Codec<LootTableBasicAppender> by lazy {
|
||||||
|
RecordCodecBuilder.create {
|
||||||
|
codecStart(it).and(ItemStackCodec.LIST.fieldOf("items").forGetter { it.items }).apply(it, ::LootTableBasicAppender)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,18 +1,19 @@
|
|||||||
package ru.dbotthepony.mc.otm.registry
|
package ru.dbotthepony.mc.otm.registry
|
||||||
|
|
||||||
import net.minecraftforge.eventbus.api.IEventBus
|
import net.minecraftforge.eventbus.api.IEventBus
|
||||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext
|
|
||||||
import net.minecraftforge.registries.DeferredRegister
|
import net.minecraftforge.registries.DeferredRegister
|
||||||
import net.minecraftforge.registries.ForgeRegistries
|
import net.minecraftforge.registries.ForgeRegistries
|
||||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||||
import ru.dbotthepony.mc.otm.data.LootTableAppender
|
import ru.dbotthepony.mc.otm.data.LootTableAppender
|
||||||
import ru.dbotthepony.mc.otm.data.LootTableBasicAppender
|
import ru.dbotthepony.mc.otm.data.LootTableBasicAppender
|
||||||
|
import ru.dbotthepony.mc.otm.data.LootTableSeparatedAppender
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
registry.register("loot_appender") { LootTableAppender.CODEC }
|
registry.register("loot_appender") { LootTableAppender.CODEC }
|
||||||
|
registry.register("loot_appender_separated") { LootTableSeparatedAppender.CODEC }
|
||||||
registry.register("loot_appender_basic") { LootTableBasicAppender.CODEC }
|
registry.register("loot_appender_basic") { LootTableBasicAppender.CODEC }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
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
|
||||||
|
import ru.dbotthepony.mc.otm.data.HasExosuitCondition
|
||||||
|
import ru.dbotthepony.mc.otm.data.ItemInInventoryCondition
|
||||||
|
import ru.dbotthepony.mc.otm.data.KilledByRealPlayer
|
||||||
|
|
||||||
|
object MLootItemConditions {
|
||||||
|
val HAS_EXOSUIT = LootItemConditionType(HasExosuitCondition)
|
||||||
|
val KILLED_BY_REAL_PLAYER = LootItemConditionType(KilledByRealPlayer)
|
||||||
|
val CHANCE_WITH_PLAYTIME = LootItemConditionType(ChanceWithPlaytimeCondition)
|
||||||
|
val ITEM_IN_INVENTORY = LootItemConditionType(ItemInInventoryCondition)
|
||||||
|
|
||||||
|
internal fun register(event: RegisterEvent) {
|
||||||
|
if (event.getVanillaRegistry<LootItemConditionType>() == Registry.LOOT_CONDITION_TYPE) {
|
||||||
|
Registry.LOOT_CONDITION_TYPE.register(ResourceLocation(OverdriveThatMatters.MOD_ID, "has_exosuit"), HAS_EXOSUIT)
|
||||||
|
Registry.LOOT_CONDITION_TYPE.register(ResourceLocation(OverdriveThatMatters.MOD_ID, "chance_with_playtime"), CHANCE_WITH_PLAYTIME)
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -223,6 +223,7 @@ object MRegistry {
|
|||||||
fun initialize(bus: IEventBus) {
|
fun initialize(bus: IEventBus) {
|
||||||
bus.addListener(this::register)
|
bus.addListener(this::register)
|
||||||
bus.addListener(MStats::registerVanilla)
|
bus.addListener(MStats::registerVanilla)
|
||||||
|
bus.addListener(MLootItemConditions::register)
|
||||||
|
|
||||||
MBlocks.register(bus)
|
MBlocks.register(bus)
|
||||||
MBlockEntities.register(bus)
|
MBlockEntities.register(bus)
|
||||||
|
Loading…
Reference in New Issue
Block a user