From a1e6d28aff1a8c2beca426a59bd4eaf193712d6e Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Thu, 15 Sep 2022 20:47:06 +0700 Subject: [PATCH] Curios slots support inside itemStream --- .../ru/dbotthepony/mc/otm/capability/Ext.kt | 16 ++++++++-- .../mc/otm/compat/curios/CuriosCompat.kt | 28 +++++++++++++++++ .../mc/otm/container/ContainerSpliterator.kt | 5 +++ .../otm/container/ItemHandlerSpliterator.kt | 31 +++++++++++++++++++ .../mc/otm/data/ItemInInventoryCondition.kt | 4 +++ 5 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/container/ItemHandlerSpliterator.kt diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/Ext.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/Ext.kt index 6e0ba62d8..df0bc7f95 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/Ext.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/Ext.kt @@ -9,6 +9,8 @@ import net.minecraftforge.common.capabilities.ICapabilityProvider import net.minecraftforge.common.util.LazyOptional import net.minecraftforge.energy.IEnergyStorage import net.minecraftforge.fml.ModList +import ru.dbotthepony.mc.otm.compat.curios.curiosStream +import ru.dbotthepony.mc.otm.compat.curios.isCuriosLoaded import ru.dbotthepony.mc.otm.compat.mekanism.getMekanismEnergySided import ru.dbotthepony.mc.otm.compat.mekanism.mekanismEnergy import ru.dbotthepony.mc.otm.container.iterator @@ -148,14 +150,24 @@ fun ICapabilityProvider.getMatteryEnergySided(side: Direction? = null): LazyOpti return LazyOptional.empty() } +/** + * DO NOT modify returned ItemStacks! + */ fun Player.itemStream(): Stream { + val streams = ArrayList>() + streams.add(inventory.stream()) + matteryPlayer?.let { if (it.hasExoSuit) { - return Streams.concat(inventory.stream(), it.exoSuitContainer.stream()) + streams.add(it.exoSuitContainer.stream()) } } - return inventory.stream() + if (isCuriosLoaded) { + streams.add(curiosStream()) + } + + return Streams.concat(*streams.toTypedArray()) } fun Player.extendedItemIterator(): MutableIterator { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/curios/CuriosCompat.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/curios/CuriosCompat.kt index 6488f31ef..6d082b317 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/curios/CuriosCompat.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/curios/CuriosCompat.kt @@ -1,14 +1,18 @@ package ru.dbotthepony.mc.otm.compat.curios +import com.google.common.collect.Streams import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap import net.minecraft.world.entity.player.Player import net.minecraft.world.inventory.Slot +import net.minecraft.world.item.ItemStack import net.minecraftforge.fml.ModList import ru.dbotthepony.mc.otm.capability.MatteryCapability +import ru.dbotthepony.mc.otm.container.stream import ru.dbotthepony.mc.otm.core.orNull import top.theillusivec4.curios.api.CuriosApi import top.theillusivec4.curios.common.inventory.CosmeticCurioSlot import top.theillusivec4.curios.common.inventory.CurioSlot +import java.util.stream.Stream val isCuriosLoaded by lazy { ModList.get().isLoaded(CuriosApi.MODID) @@ -50,3 +54,27 @@ val Player.curiosSlots: Collection> get() { return getCuriosSlotsImpl() } + +private fun Player.curiosStreamImpl(includeCosmetics: Boolean): Stream { + val handler = getCapability(MatteryCapability.CURIOS_INVENTORY).orNull() ?: return Stream.empty() + + val result = ArrayList>() + + for ((identifier, curio) in handler.curios) { + result.add(curio.stacks.stream()) + + if (includeCosmetics && curio.hasCosmetic()) { + result.add(curio.cosmeticStacks.stream()) + } + } + + return Streams.concat(*result.toTypedArray()) +} + +fun Player.curiosStream(includeCosmetics: Boolean = true): Stream { + if (!isCuriosLoaded) { + return Stream.empty() + } + + return curiosStreamImpl(includeCosmetics) +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/ContainerSpliterator.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/ContainerSpliterator.kt index c22763bb5..180ee8954 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/ContainerSpliterator.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/ContainerSpliterator.kt @@ -8,6 +8,11 @@ import java.util.stream.Stream import java.util.stream.StreamSupport class ContainerSpliterator(private val container: Container, offset: Int = 0, private val maxPos: Int = container.containerSize) : ObjectSpliterators.AbstractIndexBasedSpliterator(offset) { + init { + require(offset >= 0) { "Invalid offset $offset" } + require(offset + maxPos <= container.containerSize) { "$offset -> $maxPos while having only size of ${container.containerSize}!" } + } + override fun get(location: Int): ItemStack { return container[location] } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/ItemHandlerSpliterator.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/ItemHandlerSpliterator.kt new file mode 100644 index 000000000..6a9b11aab --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/ItemHandlerSpliterator.kt @@ -0,0 +1,31 @@ +package ru.dbotthepony.mc.otm.container + +import it.unimi.dsi.fastutil.objects.ObjectSpliterator +import it.unimi.dsi.fastutil.objects.ObjectSpliterators +import net.minecraft.world.item.ItemStack +import net.minecraftforge.items.IItemHandler +import java.util.Spliterator +import java.util.stream.Stream +import java.util.stream.StreamSupport + +class ItemHandlerSpliterator(private val handler: IItemHandler, offset: Int = 0, private val maxPos: Int = handler.slots) : ObjectSpliterators.AbstractIndexBasedSpliterator(offset) { + init { + require(offset >= 0) { "Invalid offset $offset" } + require(offset + maxPos <= handler.slots) { "$offset -> $maxPos while having only size of ${handler.slots}!" } + } + + override fun get(location: Int): ItemStack { + return handler.getStackInSlot(location) + } + + override fun getMaxPos(): Int { + return maxPos + } + + override fun makeForSplit(pos: Int, maxPos: Int): ObjectSpliterator { + return ItemHandlerSpliterator(handler, pos, maxPos) + } +} + +fun IItemHandler.spliterator(): Spliterator = ItemHandlerSpliterator(this) +fun IItemHandler.stream(): Stream = StreamSupport.stream(spliterator(), false) 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 e53e47492..82dc80850 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/data/ItemInInventoryCondition.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/data/ItemInInventoryCondition.kt @@ -26,6 +26,10 @@ class ItemInInventoryCondition( ) : LootItemCondition, LootItemCondition.Builder { override fun test(t: LootContext): Boolean { val matches = t[LootContextParams.LAST_DAMAGE_PLAYER]?.itemStream()?.filter { + if (it.isEmpty) { + return@filter false + } + if (matchDamage && matchNBT) { it.item == item.item && it.tag == item.tag && it.damageValue == item.damageValue } else if (matchDamage) {