Move around and update container apis

This commit is contained in:
DBotThePony 2023-08-19 19:51:19 +07:00
parent 9d79e52c43
commit 67f97dfba6
Signed by: DBot
GPG Key ID: DCC23B5715498507
34 changed files with 343 additions and 250 deletions

View File

@ -10,7 +10,6 @@ import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerLevel import net.minecraft.server.level.ServerLevel
import net.minecraft.server.level.ServerPlayer import net.minecraft.server.level.ServerPlayer
import net.minecraft.sounds.SoundSource import net.minecraft.sounds.SoundSource
import net.minecraft.world.Container
import net.minecraft.world.Containers import net.minecraft.world.Containers
import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.entity.player.Player import net.minecraft.world.entity.player.Player
@ -20,7 +19,6 @@ import net.minecraft.world.level.Level
import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.gameevent.GameEvent import net.minecraft.world.level.gameevent.GameEvent
import net.minecraft.world.level.storage.loot.LootContext
import net.minecraft.world.level.storage.loot.LootParams import net.minecraft.world.level.storage.loot.LootParams
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets
import net.minecraft.world.level.storage.loot.parameters.LootContextParams import net.minecraft.world.level.storage.loot.parameters.LootContextParams

View File

@ -105,15 +105,13 @@ class PainterBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryDe
override fun tick() { override fun tick() {
super.tick() super.tick()
val i = dyeInput.iterator() for (slot in dyeInput.slotIterator()) {
val dye = DyeColor.entries.firstOrNull { slot.item.`is`(it.tag) } ?: continue
for (item in i) {
val dye = DyeColor.entries.firstOrNull { item.`is`(it.tag) } ?: continue
val stored = dyeStored(dye) val stored = dyeStored(dye)
if (stored + HUE_PER_ITEM <= MAX_STORAGE) { if (stored + HUE_PER_ITEM <= MAX_STORAGE) {
item.shrink(1) slot.item.shrink(1)
i.setChanged() slot.setChanged()
dyeStored[dye] = stored + HUE_PER_ITEM dyeStored[dye] = stored + HUE_PER_ITEM
} }
} }

View File

@ -183,13 +183,13 @@ class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) :
if (isBottling) { if (isBottling) {
var any = false var any = false
var idle = false var idle = false
val iterator = bottling.iterator()
for (item in iterator) { for (slot in bottling.slotIterator()) {
val item = slot.item
item.getCapability(MatteryCapability.MATTER).ifPresentK { item.getCapability(MatteryCapability.MATTER).ifPresentK {
if (!it.missingMatter.isPositive) { if (!it.missingMatter.isPositive) {
unbottling.consumeItem(item, false) unbottling.consumeItem(item, false)
iterator.setChanged() slot.setChanged()
} else { } else {
any = true any = true
initialCapacity = initialCapacity ?: it.storedMatter initialCapacity = initialCapacity ?: it.storedMatter
@ -215,7 +215,7 @@ class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) :
if (spitItemsWhenCantWork) { if (spitItemsWhenCantWork) {
unbottling.consumeItem(item, false) unbottling.consumeItem(item, false)
iterator.setChanged() slot.setChanged()
} }
} }
} }
@ -237,11 +237,9 @@ class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) :
if (!matter.missingMatter.isPositive) { if (!matter.missingMatter.isPositive) {
if (spitItemsWhenCantWork) { if (spitItemsWhenCantWork) {
val iterator = unbottling.iterator() for (slot in unbottling.slotIterator()) {
bottling.consumeItem(slot.item, false)
for (item in iterator) { slot.setChanged()
bottling.consumeItem(item, false)
iterator.setChanged()
} }
} }
@ -251,12 +249,13 @@ class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) :
var any = false var any = false
val iterator = unbottling.iterator() for (slot in unbottling.slotIterator()) {
for (item in iterator) { val item = slot.item
item.getCapability(MatteryCapability.MATTER).ifPresentK { item.getCapability(MatteryCapability.MATTER).ifPresentK {
if (!it.storedMatter.isPositive) { if (!it.storedMatter.isPositive) {
bottling.consumeItem(item, false) bottling.consumeItem(item, false)
iterator.setChanged() slot.setChanged()
} else { } else {
any = true any = true
initialCapacity = initialCapacity ?: it.storedMatter initialCapacity = initialCapacity ?: it.storedMatter

View File

@ -1,6 +1,5 @@
package ru.dbotthepony.mc.otm.block.entity.matter package ru.dbotthepony.mc.otm.block.entity.matter
import com.google.common.collect.Streams
import javax.annotation.ParametersAreNonnullByDefault import javax.annotation.ParametersAreNonnullByDefault
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.level.block.state.BlockState
@ -18,8 +17,6 @@ import net.minecraft.world.level.block.Block
import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity
import ru.dbotthepony.mc.otm.capability.matter.* import ru.dbotthepony.mc.otm.capability.matter.*
import ru.dbotthepony.mc.otm.container.HandlerFilter import ru.dbotthepony.mc.otm.container.HandlerFilter
import ru.dbotthepony.mc.otm.container.iterator
import ru.dbotthepony.mc.otm.container.stream
import ru.dbotthepony.mc.otm.core.collect.filterNotNull import ru.dbotthepony.mc.otm.core.collect.filterNotNull
import ru.dbotthepony.mc.otm.core.collect.map import ru.dbotthepony.mc.otm.core.collect.map
import ru.dbotthepony.mc.otm.core.filterNotNull import ru.dbotthepony.mc.otm.core.filterNotNull

View File

@ -44,7 +44,8 @@ import kotlin.collections.HashMap
import ru.dbotthepony.mc.otm.client.render.Widgets8 import ru.dbotthepony.mc.otm.client.render.Widgets8
import ru.dbotthepony.mc.otm.container.CombinedContainer import ru.dbotthepony.mc.otm.container.CombinedContainer
import ru.dbotthepony.mc.otm.container.addItem import ru.dbotthepony.mc.otm.container.addItem
import ru.dbotthepony.mc.otm.container.fullIterator import ru.dbotthepony.mc.otm.container.util.iterator
import ru.dbotthepony.mc.otm.container.util.slotIterator
import ru.dbotthepony.mc.otm.core.collect.map import ru.dbotthepony.mc.otm.core.collect.map
import ru.dbotthepony.mc.otm.core.collect.toList import ru.dbotthepony.mc.otm.core.collect.toList
import ru.dbotthepony.mc.otm.core.isNotEmpty import ru.dbotthepony.mc.otm.core.isNotEmpty
@ -58,13 +59,15 @@ interface IItemMonitorPlayerSettings {
var ascendingSort: Boolean var ascendingSort: Boolean
} }
private fun takeOne(inventory: CombinedContainer?, item: ItemStack): Boolean { private fun takeOne(inventory: Container?, item: ItemStack): Boolean {
val iterator = inventory?.optimizedIterator() ?: return false val iterator = inventory?.slotIterator() ?: return false
for (slot in iterator) {
val stack = slot.item
for (stack in iterator) {
if (stack.equals(item, false)) { if (stack.equals(item, false)) {
stack.shrink(1) stack.shrink(1)
inventory.setChanged() slot.setChanged()
return true return true
} }
} }
@ -343,7 +346,7 @@ class ItemMonitorBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte
check(residue.size == craftingGrid.containerSize) { "Container and residue list sizes mismatch: ${residue.size} != ${craftingGrid.containerSize}" } check(residue.size == craftingGrid.containerSize) { "Container and residue list sizes mismatch: ${residue.size} != ${craftingGrid.containerSize}" }
val combinedInventory = craftingPlayer.matteryPlayer?.combinedInventory val combinedInventory = craftingPlayer.matteryPlayer?.combinedInventory
val copy = craftingGrid.fullIterator().map { it.copy() }.toList() val copy = craftingGrid.iterator(true).map { it.copy() }.toList()
// удаляем по одному предмету из сетки крафта // удаляем по одному предмету из сетки крафта
for (slot in 0 until craftingGrid.containerSize) { for (slot in 0 until craftingGrid.containerSize) {

View File

@ -26,9 +26,9 @@ import ru.dbotthepony.mc.otm.compat.curios.curiosStream
import ru.dbotthepony.mc.otm.compat.curios.isCuriosLoaded import ru.dbotthepony.mc.otm.compat.curios.isCuriosLoaded
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.awareStream import ru.dbotthepony.mc.otm.container.util.awareStream
import ru.dbotthepony.mc.otm.container.iterator import ru.dbotthepony.mc.otm.capability.iterator
import ru.dbotthepony.mc.otm.container.stream import ru.dbotthepony.mc.otm.container.util.iterator
import ru.dbotthepony.mc.otm.core.collect.AwareItemStack import ru.dbotthepony.mc.otm.core.collect.AwareItemStack
import ru.dbotthepony.mc.otm.core.collect.ContainerItemStackEntry import ru.dbotthepony.mc.otm.core.collect.ContainerItemStackEntry
import ru.dbotthepony.mc.otm.core.collect.concatIterators import ru.dbotthepony.mc.otm.core.collect.concatIterators
@ -38,7 +38,6 @@ import ru.dbotthepony.mc.otm.core.isNotEmpty
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.orNull import ru.dbotthepony.mc.otm.core.orNull
import ru.dbotthepony.mc.otm.core.util.formatFluidLevel import ru.dbotthepony.mc.otm.core.util.formatFluidLevel
import java.util.IdentityHashMap
import java.util.stream.Stream import java.util.stream.Stream
private val LOGGER = LogManager.getLogger() private val LOGGER = LogManager.getLogger()

View File

@ -1,8 +1,9 @@
package ru.dbotthepony.mc.otm.container package ru.dbotthepony.mc.otm.capability
import it.unimi.dsi.fastutil.objects.ObjectIterators.AbstractIndexBasedIterator import it.unimi.dsi.fastutil.objects.ObjectIterators.AbstractIndexBasedIterator
import net.minecraftforge.fluids.FluidStack import net.minecraftforge.fluids.FluidStack
import net.minecraftforge.fluids.capability.IFluidHandler import net.minecraftforge.fluids.capability.IFluidHandler
import ru.dbotthepony.mc.otm.container.get
class FluidHandlerIterator(private val handler: IFluidHandler, initialPosition: Int = 0) : AbstractIndexBasedIterator<FluidStack>(0, initialPosition) { class FluidHandlerIterator(private val handler: IFluidHandler, initialPosition: Int = 0) : AbstractIndexBasedIterator<FluidStack>(0, initialPosition) {
init { init {

View File

@ -1,9 +1,10 @@
package ru.dbotthepony.mc.otm.container package ru.dbotthepony.mc.otm.capability
import it.unimi.dsi.fastutil.objects.ObjectSpliterator import it.unimi.dsi.fastutil.objects.ObjectSpliterator
import it.unimi.dsi.fastutil.objects.ObjectSpliterators.AbstractIndexBasedSpliterator import it.unimi.dsi.fastutil.objects.ObjectSpliterators.AbstractIndexBasedSpliterator
import net.minecraftforge.fluids.FluidStack import net.minecraftforge.fluids.FluidStack
import net.minecraftforge.fluids.capability.IFluidHandler import net.minecraftforge.fluids.capability.IFluidHandler
import ru.dbotthepony.mc.otm.container.get
import java.util.Spliterator import java.util.Spliterator
import java.util.stream.Stream import java.util.stream.Stream
import java.util.stream.StreamSupport import java.util.stream.StreamSupport

View File

@ -82,8 +82,8 @@ import ru.dbotthepony.mc.otm.config.ExopackConfig
import ru.dbotthepony.mc.otm.container.CombinedContainer import ru.dbotthepony.mc.otm.container.CombinedContainer
import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.container.get import ru.dbotthepony.mc.otm.container.get
import ru.dbotthepony.mc.otm.container.iterator import ru.dbotthepony.mc.otm.capability.iterator
import ru.dbotthepony.mc.otm.container.stream import ru.dbotthepony.mc.otm.container.util.slotIterator
import ru.dbotthepony.mc.otm.container.vanishCursedItems import ru.dbotthepony.mc.otm.container.vanishCursedItems
import ru.dbotthepony.mc.otm.core.* import ru.dbotthepony.mc.otm.core.*
import ru.dbotthepony.mc.otm.core.collect.UUIDIntModifiersMap import ru.dbotthepony.mc.otm.core.collect.UUIDIntModifiersMap
@ -130,13 +130,9 @@ import kotlin.collections.ArrayDeque
import kotlin.reflect.KMutableProperty1 import kotlin.reflect.KMutableProperty1
private fun Player.dropContainer(container: Container, spill: Boolean = true, setThrower: Boolean = false) { private fun Player.dropContainer(container: Container, spill: Boolean = true, setThrower: Boolean = false) {
val iterator = container.iterator() for (slot in container.slotIterator()) {
drop(slot.item, spill, setThrower)
for (item in iterator) { slot.remove()
if (item.isNotEmpty) {
drop(item, spill, setThrower)
iterator.remove()
}
} }
} }

View File

@ -23,9 +23,9 @@ import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.RectangleButtonPanel import ru.dbotthepony.mc.otm.client.screen.panels.button.RectangleButtonPanel
import ru.dbotthepony.mc.otm.compat.cos.CosmeticToggleButton.Companion.BUTTON_ACTIVE import ru.dbotthepony.mc.otm.compat.cos.CosmeticToggleButton.Companion.BUTTON_ACTIVE
import ru.dbotthepony.mc.otm.compat.cos.CosmeticToggleButton.Companion.BUTTON_INACTIVE import ru.dbotthepony.mc.otm.compat.cos.CosmeticToggleButton.Companion.BUTTON_INACTIVE
import ru.dbotthepony.mc.otm.container.awareStream import ru.dbotthepony.mc.otm.container.util.awareStream
import ru.dbotthepony.mc.otm.container.iterator import ru.dbotthepony.mc.otm.capability.iterator
import ru.dbotthepony.mc.otm.container.stream import ru.dbotthepony.mc.otm.container.util.iterator
import ru.dbotthepony.mc.otm.core.collect.AwareItemStack import ru.dbotthepony.mc.otm.core.collect.AwareItemStack
import ru.dbotthepony.mc.otm.core.collect.emptyIterator import ru.dbotthepony.mc.otm.core.collect.emptyIterator
import ru.dbotthepony.mc.otm.menu.MatterySlot import ru.dbotthepony.mc.otm.menu.MatterySlot

View File

@ -4,15 +4,14 @@ import com.google.common.collect.Streams
import net.minecraft.world.entity.player.Player import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.Slot import net.minecraft.world.inventory.Slot
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.minecraftforge.api.distmarker.Dist
import net.minecraftforge.fml.ModList import net.minecraftforge.fml.ModList
import net.minecraftforge.fml.loading.FMLEnvironment import net.minecraftforge.fml.loading.FMLEnvironment
import net.minecraftforge.network.PacketDistributor import net.minecraftforge.network.PacketDistributor
import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.matteryPlayer import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.container.awareStream import ru.dbotthepony.mc.otm.container.util.awareStream
import ru.dbotthepony.mc.otm.container.iterator import ru.dbotthepony.mc.otm.capability.iterator
import ru.dbotthepony.mc.otm.container.stream import ru.dbotthepony.mc.otm.container.util.iterator
import ru.dbotthepony.mc.otm.core.collect.AwareItemStack import ru.dbotthepony.mc.otm.core.collect.AwareItemStack
import ru.dbotthepony.mc.otm.core.collect.concatIterators import ru.dbotthepony.mc.otm.core.collect.concatIterators
import ru.dbotthepony.mc.otm.core.collect.emptyIterator import ru.dbotthepony.mc.otm.core.collect.emptyIterator

View File

@ -4,13 +4,16 @@ import com.google.common.collect.ImmutableList
import com.google.common.collect.ImmutableMap import com.google.common.collect.ImmutableMap
import com.google.common.collect.ImmutableSet import com.google.common.collect.ImmutableSet
import it.unimi.dsi.fastutil.ints.IntAVLTreeSet import it.unimi.dsi.fastutil.ints.IntAVLTreeSet
import it.unimi.dsi.fastutil.ints.IntOpenHashSet
import it.unimi.dsi.fastutil.ints.IntSet import it.unimi.dsi.fastutil.ints.IntSet
import it.unimi.dsi.fastutil.objects.Object2ObjectFunction import it.unimi.dsi.fastutil.objects.Object2ObjectFunction
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap
import net.minecraft.world.Container import net.minecraft.world.Container
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
import ru.dbotthepony.mc.otm.container.util.ContainerSlot
import ru.dbotthepony.mc.otm.container.util.IContainerSlot
import ru.dbotthepony.mc.otm.container.util.IIterableContainer
import ru.dbotthepony.mc.otm.container.util.iterator
import ru.dbotthepony.mc.otm.core.GetterSetter import ru.dbotthepony.mc.otm.core.GetterSetter
import ru.dbotthepony.mc.otm.core.collect.concatIterators import ru.dbotthepony.mc.otm.core.collect.concatIterators
import ru.dbotthepony.mc.otm.core.collect.filter import ru.dbotthepony.mc.otm.core.collect.filter
@ -21,26 +24,10 @@ import ru.dbotthepony.mc.otm.core.stream
import java.util.LinkedList import java.util.LinkedList
import java.util.stream.Stream import java.util.stream.Stream
class CombinedContainer(containers: Stream<Pair<Container, Iterator<Int>>>) : Container { class CombinedContainer(containers: Stream<Pair<Container, Iterator<Int>>>) : Container, IIterableContainer {
constructor(vararg containers: Container) : this(containers.stream().map { it to (0 until it.containerSize).iterator() }) constructor(vararg containers: Container) : this(containers.stream().map { it to (0 until it.containerSize).iterator() })
constructor(containers: Collection<Container>) : this(containers.stream().map { it to (0 until it.containerSize).iterator() }) constructor(containers: Collection<Container>) : this(containers.stream().map { it to (0 until it.containerSize).iterator() })
class ContainerSlot(val container: Container, val containerIndex: Int) : GetterSetter<ItemStack> {
var item: ItemStack
get() = container[containerIndex]
set(value) { container[containerIndex] = value }
override fun get(): ItemStack {
return item
}
override fun accept(t: ItemStack) {
item = t
}
val isEmpty: Boolean get() = item.isEmpty
}
private val slots: List<ContainerSlot> private val slots: List<ContainerSlot>
private val slotsMap: Map<Container, List<ContainerSlot>> private val slotsMap: Map<Container, List<ContainerSlot>>
private val containers: Set<Container> private val containers: Set<Container>
@ -60,7 +47,7 @@ class CombinedContainer(containers: Stream<Pair<Container, Iterator<Int>>>) : Co
for (slot in slots) { for (slot in slots) {
if (validator.add(slot)) { if (validator.add(slot)) {
i++ i++
val slotObj = ContainerSlot(container, slot) val slotObj = ContainerSlot(slot, container)
list.add(slotObj) list.add(slotObj)
slotList.add(slotObj) slotList.add(slotObj)
} else { } else {
@ -131,12 +118,12 @@ class CombinedContainer(containers: Stream<Pair<Container, Iterator<Int>>>) : Co
override fun removeItem(index: Int, count: Int): ItemStack { override fun removeItem(index: Int, count: Int): ItemStack {
val data = slots.getOrNull(index) ?: return ItemStack.EMPTY val data = slots.getOrNull(index) ?: return ItemStack.EMPTY
return data.container.removeItem(data.containerIndex, count) return data.container.removeItem(data.slot, count)
} }
override fun removeItemNoUpdate(index: Int): ItemStack { override fun removeItemNoUpdate(index: Int): ItemStack {
val data = slots.getOrNull(index) ?: return ItemStack.EMPTY val data = slots.getOrNull(index) ?: return ItemStack.EMPTY
return data.container.removeItemNoUpdate(data.containerIndex) return data.container.removeItemNoUpdate(data.slot)
} }
override fun setItem(index: Int, value: ItemStack) { override fun setItem(index: Int, value: ItemStack) {
@ -153,7 +140,7 @@ class CombinedContainer(containers: Stream<Pair<Container, Iterator<Int>>>) : Co
val data = slots.getOrNull(index) ?: return val data = slots.getOrNull(index) ?: return
if (data.container is MatteryContainer) { if (data.container is MatteryContainer) {
data.container.setChanged(data.containerIndex) data.container.setChanged(data.slot)
} else { } else {
data.container.setChanged() data.container.setChanged()
} }
@ -167,13 +154,20 @@ class CombinedContainer(containers: Stream<Pair<Container, Iterator<Int>>>) : Co
return true return true
} }
fun optimizedIterator(): Iterator<ItemStack> { override fun iterator(nonEmpty: Boolean): Iterator<ItemStack> {
return concatIterators( return concatIterators(
fullCoverage.iterator().flatMap { it.iterator() }, fullCoverage.iterator().flatMap { it.iterator(nonEmpty) },
notFullCoverage.values.iterator().flatMap { it.iterator() }.map { it.item }.filter { it.isNotEmpty } notFullCoverage.values.iterator().flatMap { it.iterator() }.map { it.item }.let { if (nonEmpty) it.filter { it.isNotEmpty } else it }
) )
} }
override fun slotIterator(nonEmpty: Boolean): Iterator<IContainerSlot> {
if (nonEmpty)
return slots.iterator().filter { it.isNotEmpty }
return slots.iterator()
}
class Builder { class Builder {
private var built = false private var built = false
private val values = LinkedList<Pair<Container, Iterator<Int>>>() private val values = LinkedList<Pair<Container, Iterator<Int>>>()

View File

@ -1,7 +1,6 @@
package ru.dbotthepony.mc.otm.container package ru.dbotthepony.mc.otm.container
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import net.minecraftforge.items.IItemHandler import net.minecraftforge.items.IItemHandler
class ContainerHandler @JvmOverloads internal constructor( class ContainerHandler @JvmOverloads internal constructor(

View File

@ -11,8 +11,11 @@ import net.minecraft.world.inventory.CraftingContainer
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.enchantment.EnchantmentHelper.hasVanishingCurse import net.minecraft.world.item.enchantment.EnchantmentHelper.hasVanishingCurse
import net.minecraftforge.fluids.capability.IFluidHandler import net.minecraftforge.fluids.capability.IFluidHandler
import ru.dbotthepony.mc.otm.container.util.ItemStackHashStrategy
import ru.dbotthepony.mc.otm.container.util.slotIterator
import ru.dbotthepony.mc.otm.core.addAll import ru.dbotthepony.mc.otm.core.addAll
import ru.dbotthepony.mc.otm.core.isNotEmpty import ru.dbotthepony.mc.otm.core.isNotEmpty
import ru.dbotthepony.mc.otm.core.util.ItemStackSorter
import kotlin.math.roundToInt import kotlin.math.roundToInt
@Suppress("nothing_to_inline") @Suppress("nothing_to_inline")
@ -87,11 +90,9 @@ fun Container.addItem(stack: ItemStack, range: IntRange, simulate: Boolean = fal
fun Container.addItem(stack: ItemStack, simulate: Boolean): ItemStack = addItem(stack, 0 until containerSize, simulate) fun Container.addItem(stack: ItemStack, simulate: Boolean): ItemStack = addItem(stack, 0 until containerSize, simulate)
fun Container.vanishCursedItems() { fun Container.vanishCursedItems() {
val iterator = iterator() for (slot in slotIterator()) {
if (hasVanishingCurse(slot.item)) {
for (item in iterator) { slot.remove()
if (item.isNotEmpty && hasVanishingCurse(item)) {
iterator.remove()
} }
} }
} }

View File

@ -1,82 +0,0 @@
package ru.dbotthepony.mc.otm.container
import it.unimi.dsi.fastutil.objects.ObjectIterators
import net.minecraft.world.Container
import net.minecraft.world.item.ItemStack
import ru.dbotthepony.mc.otm.core.isNotEmpty
class ContainerIterator(private val container: Container) : IContainerIterator {
private var index = 0
private var lastIndex = -1
override fun hasNext(): Boolean {
while (index < container.containerSize) {
if (container[index].isNotEmpty) {
return true
}
index++
}
return false
}
override fun next(): ItemStack {
if (!hasNext()) {
throw NoSuchElementException()
}
lastIndex = index
return container[index++]
}
override fun remove() {
if (lastIndex == -1) {
throw NoSuchElementException()
}
container[lastIndex] = ItemStack.EMPTY
lastIndex = -1
}
override fun setChanged() {
container.setChanged()
}
}
fun Container.iterator(): IContainerIterator {
return if (this is MatteryContainer) {
iterator()
} else {
ContainerIterator(this)
}
}
class FullContainerIterator(val container: Container, initialPos: Int = 0) : MutableIterator<ItemStack>, ObjectIterators.AbstractIndexBasedListIterator<ItemStack>(0, initialPos), IContainerIterator {
override fun remove(location: Int) {
pos++
container[location] = ItemStack.EMPTY
}
override fun get(location: Int): ItemStack {
return container[location]
}
override fun getMaxPos(): Int {
return container.containerSize
}
override fun add(location: Int, k: ItemStack?) {
throw UnsupportedOperationException()
}
override fun set(location: Int, k: ItemStack) {
container[location] = k
}
override fun setChanged() {
container.setChanged()
}
}
fun Container.fullIterator() = FullContainerIterator(this)

View File

@ -4,7 +4,7 @@ import net.minecraft.world.item.ItemStack
import net.minecraftforge.common.ForgeHooks import net.minecraftforge.common.ForgeHooks
import net.minecraftforge.common.capabilities.ForgeCapabilities import net.minecraftforge.common.capabilities.ForgeCapabilities
import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.core.ifPresentK import ru.dbotthepony.mc.otm.capability.stream
import ru.dbotthepony.mc.otm.core.isNotEmpty import ru.dbotthepony.mc.otm.core.isNotEmpty
interface HandlerFilter { interface HandlerFilter {

View File

@ -0,0 +1,84 @@
package ru.dbotthepony.mc.otm.container
import net.minecraft.world.Container
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
import java.util.function.Predicate
// passthrough all default methods to fix Kotlin bug related to implementation delegation not properly working on Java interfaces
// https://youtrack.jetbrains.com/issue/KT-55080/Change-the-behavior-of-inheritance-delegation-to-delegates-implementing-Java-interfaces-with-default-methods
interface IContainer : Container {
override fun getMaxStackSize(): Int {
return super.getMaxStackSize()
}
override fun startOpen(player: Player) {
super.startOpen(player)
}
override fun stopOpen(player: Player) {
super.stopOpen(player)
}
override fun canPlaceItem(slot: Int, itemStack: ItemStack): Boolean {
return super.canPlaceItem(slot, itemStack)
}
override fun canTakeItem(container: Container, slot: Int, itemStack: ItemStack): Boolean {
return super.canTakeItem(container, slot, itemStack)
}
override fun countItem(item: Item): Int {
return super.countItem(item)
}
override fun hasAnyOf(items: Set<Item>): Boolean {
return super.hasAnyOf(items)
}
override fun hasAnyMatching(predicate: Predicate<ItemStack>): Boolean {
return super.hasAnyMatching(predicate)
}
companion object {
fun wrap(container: Container): IContainer {
if (container is IContainer)
return container
else
return object : IContainer, Container by container {
override fun getMaxStackSize(): Int {
return container.getMaxStackSize()
}
override fun startOpen(player: Player) {
container.startOpen(player)
}
override fun stopOpen(player: Player) {
container.stopOpen(player)
}
override fun canPlaceItem(slot: Int, itemStack: ItemStack): Boolean {
return container.canPlaceItem(slot, itemStack)
}
override fun canTakeItem(container: Container, slot: Int, itemStack: ItemStack): Boolean {
return container.canTakeItem(container, slot, itemStack)
}
override fun countItem(item: Item): Int {
return container.countItem(item)
}
override fun hasAnyOf(items: Set<Item>): Boolean {
return container.hasAnyOf(items)
}
override fun hasAnyMatching(predicate: Predicate<ItemStack>): Boolean {
return container.hasAnyMatching(predicate)
}
}
}
}
}

View File

@ -1,12 +0,0 @@
package ru.dbotthepony.mc.otm.container
import net.minecraft.world.item.ItemStack
interface IContainerIterator : MutableIterator<ItemStack> {
/**
* Notifies underlying container that last returned [ItemStack] was modified
*
* @throws NoSuchElementException
*/
fun setChanged()
}

View File

@ -11,7 +11,6 @@ import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.ListTag import net.minecraft.nbt.ListTag
import net.minecraft.nbt.Tag import net.minecraft.nbt.Tag
import net.minecraft.resources.ResourceLocation import net.minecraft.resources.ResourceLocation
import net.minecraft.world.Container
import kotlin.jvm.JvmOverloads import kotlin.jvm.JvmOverloads
import net.minecraft.world.entity.player.Player import net.minecraft.world.entity.player.Player
import net.minecraft.world.entity.player.StackedContents import net.minecraft.world.entity.player.StackedContents
@ -20,10 +19,15 @@ import net.minecraft.world.item.Item
import net.minecraft.world.item.Items import net.minecraft.world.item.Items
import net.minecraftforge.common.util.INBTSerializable import net.minecraftforge.common.util.INBTSerializable
import net.minecraftforge.registries.ForgeRegistries import net.minecraftforge.registries.ForgeRegistries
import ru.dbotthepony.mc.otm.container.util.ContainerSlot
import ru.dbotthepony.mc.otm.container.util.IContainerSlot
import ru.dbotthepony.mc.otm.container.util.IIterableContainer
import ru.dbotthepony.mc.otm.core.addSorted import ru.dbotthepony.mc.otm.core.addSorted
import ru.dbotthepony.mc.otm.core.collect.any import ru.dbotthepony.mc.otm.core.collect.any
import ru.dbotthepony.mc.otm.core.collect.count import ru.dbotthepony.mc.otm.core.collect.count
import ru.dbotthepony.mc.otm.core.collect.emptyIterator
import ru.dbotthepony.mc.otm.core.collect.filter import ru.dbotthepony.mc.otm.core.collect.filter
import ru.dbotthepony.mc.otm.core.collect.map
import ru.dbotthepony.mc.otm.core.isNotEmpty import ru.dbotthepony.mc.otm.core.isNotEmpty
import ru.dbotthepony.mc.otm.core.nbt.map import ru.dbotthepony.mc.otm.core.nbt.map
import ru.dbotthepony.mc.otm.core.nbt.set import ru.dbotthepony.mc.otm.core.nbt.set
@ -39,11 +43,11 @@ import java.util.function.Predicate
import java.util.function.Supplier import java.util.function.Supplier
import java.util.stream.Stream import java.util.stream.Stream
import java.util.stream.StreamSupport import java.util.stream.StreamSupport
import kotlin.NoSuchElementException
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
import kotlin.collections.Iterator
@Suppress("UNUSED") @Suppress("UNUSED")
open class MatteryContainer(protected val watcher: Runnable, private val size: Int) : Container, Iterable<ItemStack>, INBTSerializable<Tag?>, StackedContentsCompatible { open class MatteryContainer(protected val watcher: Runnable, private val size: Int) : IContainer, IIterableContainer, Iterable<ItemStack>, INBTSerializable<Tag?>, StackedContentsCompatible {
constructor(size: Int) : this({}, size) constructor(size: Int) : this({}, size)
init { init {
@ -553,7 +557,7 @@ open class MatteryContainer(protected val watcher: Runnable, private val size: I
} }
} }
private inner class Iterator : IContainerIterator { private inner class Iterator : kotlin.collections.Iterator<ItemStack> {
init { init {
indicesReferenced = true indicesReferenced = true
} }
@ -569,24 +573,6 @@ open class MatteryContainer(protected val watcher: Runnable, private val size: I
lastIndex = parent.nextInt() lastIndex = parent.nextInt()
return getItem(lastIndex) return getItem(lastIndex)
} }
override fun remove() {
if (lastIndex == -1) {
throw NoSuchElementException()
}
parent.remove()
setItem(lastIndex, ItemStack.EMPTY)
lastIndex = -1
}
override fun setChanged() {
if (lastIndex == -1) {
throw NoSuchElementException()
}
setChanged(lastIndex)
}
} }
private inner class Spliterator(private val parent: IntSpliterator) : java.util.Spliterator<ItemStack> { private inner class Spliterator(private val parent: IntSpliterator) : java.util.Spliterator<ItemStack> {
@ -609,38 +595,46 @@ open class MatteryContainer(protected val watcher: Runnable, private val size: I
} }
} }
private object EmptyIterator : IContainerIterator { final override fun iterator(): kotlin.collections.Iterator<ItemStack> {
override fun hasNext(): Boolean {
return false
}
override fun next(): ItemStack {
throw NoSuchElementException()
}
override fun remove() {
throw NoSuchElementException()
}
override fun setChanged() {
throw NoSuchElementException()
}
}
final override fun iterator(): IContainerIterator {
if (isEmpty) { if (isEmpty) {
return EmptyIterator return emptyIterator()
} }
return Iterator() return Iterator()
} }
final override fun iterator(nonEmpty: Boolean): kotlin.collections.Iterator<ItemStack> {
if (!nonEmpty) {
return (0 until size).iterator().map { slots[it] }
} else if (isEmpty) {
return emptyIterator()
} else {
return Iterator()
}
}
final override fun slotIterator(): kotlin.collections.Iterator<IContainerSlot> {
indicesReferenced = true
return nonEmptyIndices.iterator().map { ContainerSlot(it, this) }
}
final override fun slotIterator(nonEmpty: Boolean): kotlin.collections.Iterator<IContainerSlot> {
if (!nonEmpty) {
return (0 until size).iterator().map { ContainerSlot(it, this) }
} else if (isEmpty) {
return emptyIterator()
} else {
indicesReferenced = true
return nonEmptyIndices.iterator().map { ContainerSlot(it, this) }
}
}
final override fun countItem(item: Item): Int { final override fun countItem(item: Item): Int {
return iterator().filter { it.item == item }.count().toInt() return iterator().filter { it.item == item }.count().toInt()
} }
final override fun hasAnyOf(set: Set<Item>): Boolean { final override fun hasAnyOf(items: Set<Item>): Boolean {
return iterator().any { it.item in set } return iterator().any { it.item in items }
} }
final override fun hasAnyMatching(predicate: Predicate<ItemStack>): Boolean { final override fun hasAnyMatching(predicate: Predicate<ItemStack>): Boolean {

View File

@ -3,9 +3,8 @@ package ru.dbotthepony.mc.otm.container
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap
import net.minecraft.world.Container import net.minecraft.world.Container
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import java.util.Arrays
class ShadowContainer(private val parent: Container) : Container by parent { class ShadowContainer(private val parent: Container) : IContainer by IContainer.wrap(parent) {
private val shadowed = Int2ObjectArrayMap<ItemStack>(0) private val shadowed = Int2ObjectArrayMap<ItemStack>(0)
override fun clearContent() { override fun clearContent() {

View File

@ -1,12 +1,12 @@
package ru.dbotthepony.mc.otm.container package ru.dbotthepony.mc.otm.container
import net.minecraft.world.Container
import net.minecraft.world.entity.player.StackedContents import net.minecraft.world.entity.player.StackedContents
import net.minecraft.world.inventory.CraftingContainer import net.minecraft.world.inventory.CraftingContainer
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import ru.dbotthepony.mc.otm.container.util.iterator
import ru.dbotthepony.mc.otm.core.collect.toList import ru.dbotthepony.mc.otm.core.collect.toList
class ShadowCraftingContainer(private val parent: CraftingContainer) : Container by ShadowContainer(parent), CraftingContainer { class ShadowCraftingContainer(private val parent: CraftingContainer) : IContainer by ShadowContainer(parent), CraftingContainer {
override fun fillStackedContents(contents: StackedContents) { override fun fillStackedContents(contents: StackedContents) {
for (item in iterator()) { for (item in iterator()) {
contents.accountStack(item) contents.accountStack(item)

View File

@ -1,9 +1,10 @@
package ru.dbotthepony.mc.otm.container package ru.dbotthepony.mc.otm.container.util
import it.unimi.dsi.fastutil.objects.ObjectSpliterator import it.unimi.dsi.fastutil.objects.ObjectSpliterator
import it.unimi.dsi.fastutil.objects.ObjectSpliterators import it.unimi.dsi.fastutil.objects.ObjectSpliterators
import net.minecraft.world.Container import net.minecraft.world.Container
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import ru.dbotthepony.mc.otm.container.get
import ru.dbotthepony.mc.otm.core.collect.AwareItemStack import ru.dbotthepony.mc.otm.core.collect.AwareItemStack
import ru.dbotthepony.mc.otm.core.collect.ContainerItemStackEntry import ru.dbotthepony.mc.otm.core.collect.ContainerItemStackEntry
import java.util.stream.Stream import java.util.stream.Stream

View File

@ -1,4 +1,4 @@
package ru.dbotthepony.mc.otm.container package ru.dbotthepony.mc.otm.container.util
import it.unimi.dsi.fastutil.objects.ObjectSpliterator import it.unimi.dsi.fastutil.objects.ObjectSpliterator
import it.unimi.dsi.fastutil.objects.ObjectSpliterators import it.unimi.dsi.fastutil.objects.ObjectSpliterators

View File

@ -1,4 +1,4 @@
package ru.dbotthepony.mc.otm.container package ru.dbotthepony.mc.otm.container.util
import it.unimi.dsi.fastutil.Hash import it.unimi.dsi.fastutil.Hash
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack

View File

@ -0,0 +1,123 @@
package ru.dbotthepony.mc.otm.container.util
import net.minecraft.world.Container
import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.container.get
import ru.dbotthepony.mc.otm.container.set
import ru.dbotthepony.mc.otm.core.GetterSetter
import ru.dbotthepony.mc.otm.core.collect.filter
import ru.dbotthepony.mc.otm.core.collect.map
import ru.dbotthepony.mc.otm.core.isNotEmpty
interface IContainerSlot : GetterSetter<ItemStack> {
val slot: Int
val container: Container
operator fun component1() = slot
operator fun component2() = item
val isForbiddenForAutomation: Boolean get() {
val container = container
if (container is MatteryContainer) {
return container.isSlotForbiddenForAutomation(slot)
} else {
return false
}
}
val filter: Item? get() {
val container = container
if (container is MatteryContainer) {
return container.getSlotFilter(slot)
} else {
return null
}
}
val hasFilter: Boolean
get() = filter != null
fun remove() {
container[slot] = ItemStack.EMPTY
}
override fun get(): ItemStack {
return container[slot]
}
override fun accept(t: ItemStack) {
container[slot] = t
}
fun setChanged() {
val container = container
if (container is MatteryContainer) {
container.setChanged(slot)
} else {
container.setChanged()
}
}
var item: ItemStack
get() = container[slot]
set(value) { container[slot] = value }
val isEmpty: Boolean
get() = container[slot].isEmpty
val isNotEmpty: Boolean
get() = container[slot].isNotEmpty
}
class ContainerSlot(override val slot: Int, override val container: Container) : IContainerSlot {
init {
require(slot in 0 until container.containerSize) { "Slot out of bounds: $slot (container: $container with size ${container.containerSize})" }
}
}
interface IIterableContainer : Iterable<ItemStack> {
/**
* Iterates over non-empty itemstacks of this container
*/
override fun iterator(): Iterator<ItemStack> {
return iterator(true)
}
fun iterator(nonEmpty: Boolean): Iterator<ItemStack>
/**
* Iterates non-empty slots of this container
*/
fun slotIterator(): Iterator<IContainerSlot> {
return slotIterator(true)
}
fun slotIterator(nonEmpty: Boolean): Iterator<IContainerSlot>
}
operator fun Container.iterator() = iterator(true)
fun Container.iterator(nonEmpty: Boolean): Iterator<ItemStack> {
if (this is IIterableContainer) {
return iterator(nonEmpty)
} else if (nonEmpty) {
return (0 until containerSize).iterator().map { this[it] }.filter { it.isNotEmpty }
} else {
return (0 until containerSize).iterator().map { this[it] }
}
}
fun Container.slotIterator(nonEmpty: Boolean = true): Iterator<IContainerSlot> {
if (this is IIterableContainer) {
return slotIterator(nonEmpty)
} else if (nonEmpty) {
return (0 until containerSize).iterator().filter { this[it].isNotEmpty }.map { ContainerSlot(it, this) }
} else {
return (0 until containerSize).iterator().map { ContainerSlot(it, this) }
}
}

View File

@ -34,10 +34,12 @@ import net.minecraftforge.fluids.FluidUtil
import net.minecraftforge.fluids.capability.IFluidHandler import net.minecraftforge.fluids.capability.IFluidHandler
import ru.dbotthepony.mc.otm.capability.fluid.ItemMatteryFluidHandler import ru.dbotthepony.mc.otm.capability.fluid.ItemMatteryFluidHandler
import ru.dbotthepony.mc.otm.capability.fluidLevel import ru.dbotthepony.mc.otm.capability.fluidLevel
import ru.dbotthepony.mc.otm.capability.iterator
import ru.dbotthepony.mc.otm.capability.moveFluid import ru.dbotthepony.mc.otm.capability.moveFluid
import ru.dbotthepony.mc.otm.container.get import ru.dbotthepony.mc.otm.container.get
import ru.dbotthepony.mc.otm.container.stream import ru.dbotthepony.mc.otm.container.util.stream
import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.collect.any
import ru.dbotthepony.mc.otm.core.ifPresentK import ru.dbotthepony.mc.otm.core.ifPresentK
import ru.dbotthepony.mc.otm.core.immutableList import ru.dbotthepony.mc.otm.core.immutableList
import ru.dbotthepony.mc.otm.core.immutableMap import ru.dbotthepony.mc.otm.core.immutableMap
@ -223,7 +225,7 @@ class FluidCapsuleItem(val capacity: IntSupplier) : Item(Properties().stacksTo(6
override fun canInteract(item: ItemStack, player: Player, context: Context): Boolean { override fun canInteract(item: ItemStack, player: Player, context: Context): Boolean {
val target = player.level().getBlockEntity(context.blockPos)?.getCapability(ForgeCapabilities.FLUID_HANDLER, context.side)?.orNull() ?: return false val target = player.level().getBlockEntity(context.blockPos)?.getCapability(ForgeCapabilities.FLUID_HANDLER, context.side)?.orNull() ?: return false
val cap = item.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).orNull() ?: return false val cap = item.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).orNull() ?: return false
return target.stream().anyMatch { !it.isEmpty } || cap.stream().anyMatch { !it.isEmpty } return target.iterator().any { !it.isEmpty } || cap.iterator().any { !it.isEmpty }
} }
override fun interact(item: ItemStack, player: Player, context: Context): InteractionResult { override fun interact(item: ItemStack, player: Player, context: Context): InteractionResult {

View File

@ -71,7 +71,7 @@ import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive
import ru.dbotthepony.mc.otm.client.isShiftDown import ru.dbotthepony.mc.otm.client.isShiftDown
import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.container.set import ru.dbotthepony.mc.otm.container.set
import ru.dbotthepony.mc.otm.container.stream import ru.dbotthepony.mc.otm.container.util.stream
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.TextComponent import ru.dbotthepony.mc.otm.core.TextComponent
import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent

View File

@ -11,7 +11,9 @@ import net.minecraft.world.inventory.*
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
import ru.dbotthepony.mc.otm.compat.curios.curiosSlots import ru.dbotthepony.mc.otm.compat.curios.curiosSlots
import ru.dbotthepony.mc.otm.container.iterator import ru.dbotthepony.mc.otm.capability.iterator
import ru.dbotthepony.mc.otm.container.util.iterator
import ru.dbotthepony.mc.otm.container.util.slotIterator
import ru.dbotthepony.mc.otm.menu.input.InstantBooleanInput import ru.dbotthepony.mc.otm.menu.input.InstantBooleanInput
import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget
import ru.dbotthepony.mc.otm.network.ExopackCarriedPacket import ru.dbotthepony.mc.otm.network.ExopackCarriedPacket
@ -164,16 +166,14 @@ class ExopackInventoryMenu(val capability: MatteryPlayerCapability) : MatteryMen
craftingResultContainer.clearContent() craftingResultContainer.clearContent()
if (!player.level().isClientSide) { if (!player.level().isClientSide) {
val iterator = craftingGrid.iterator() for (slot in craftingGrid.slotIterator()) {
val leftover = moveItemStackToSlots(slot.item, playerInventorySlots)
for (itemStack in iterator) {
val leftover = moveItemStackToSlots(itemStack, playerInventorySlots)
if (!leftover.isEmpty) { if (!leftover.isEmpty) {
player.drop(leftover, true) player.drop(leftover, true)
} }
iterator.remove() slot.remove()
} }
} }
} }

View File

@ -16,8 +16,9 @@ import net.minecraft.world.item.crafting.ShapedRecipe
import net.minecraft.world.level.Level import net.minecraft.world.level.Level
import net.minecraftforge.common.crafting.IShapedRecipe import net.minecraftforge.common.crafting.IShapedRecipe
import ru.dbotthepony.mc.otm.capability.matteryEnergy import ru.dbotthepony.mc.otm.capability.matteryEnergy
import ru.dbotthepony.mc.otm.container.iterator import ru.dbotthepony.mc.otm.capability.iterator
import ru.dbotthepony.mc.otm.container.stream import ru.dbotthepony.mc.otm.container.util.iterator
import ru.dbotthepony.mc.otm.container.util.stream
import ru.dbotthepony.mc.otm.core.filterNotNull import ru.dbotthepony.mc.otm.core.filterNotNull
class EnergyContainerRecipe(val parent: ShapedRecipe) : CraftingRecipe, IShapedRecipe<CraftingContainer> by parent { class EnergyContainerRecipe(val parent: ShapedRecipe) : CraftingRecipe, IShapedRecipe<CraftingContainer> by parent {
@ -84,7 +85,7 @@ class EnergyContainerRecipe(val parent: ShapedRecipe) : CraftingRecipe, IShapedR
if (itemStack.isEnchantable) { if (itemStack.isEnchantable) {
for (it in container.iterator()) { for (it in container.iterator()) {
if (!it.isEmpty && it.isEnchanted) { if (it.isEnchanted) {
for ((key, value) in it.allEnchantments) { for ((key, value) in it.allEnchantments) {
itemStack.enchant(key, value) itemStack.enchant(key, value)
} }

View File

@ -15,7 +15,7 @@ import net.minecraft.world.item.crafting.Ingredient
import net.minecraft.world.item.crafting.RecipeSerializer import net.minecraft.world.item.crafting.RecipeSerializer
import net.minecraft.world.level.Level import net.minecraft.world.level.Level
import net.minecraftforge.common.Tags import net.minecraftforge.common.Tags
import ru.dbotthepony.mc.otm.container.stream import ru.dbotthepony.mc.otm.container.util.stream
import ru.dbotthepony.mc.otm.core.isActuallyEmpty import ru.dbotthepony.mc.otm.core.isActuallyEmpty
import ru.dbotthepony.mc.otm.core.isNotEmpty import ru.dbotthepony.mc.otm.core.isNotEmpty
import ru.dbotthepony.mc.otm.core.set import ru.dbotthepony.mc.otm.core.set

View File

@ -8,7 +8,7 @@ import net.minecraft.world.item.crafting.Recipe
import net.minecraft.world.item.crafting.RecipeSerializer import net.minecraft.world.item.crafting.RecipeSerializer
import ru.dbotthepony.mc.otm.data.Codec2RecipeSerializer import ru.dbotthepony.mc.otm.data.Codec2RecipeSerializer
// overrides all methods to fix Kotlin bug related to implementation delegation (to allow easy optics) // passthrough all default methods to fix Kotlin bug related to implementation delegation not properly working on Java interfaces
// https://youtrack.jetbrains.com/issue/KT-55080/Change-the-behavior-of-inheritance-delegation-to-delegates-implementing-Java-interfaces-with-default-methods // https://youtrack.jetbrains.com/issue/KT-55080/Change-the-behavior-of-inheritance-delegation-to-delegates-implementing-Java-interfaces-with-default-methods
interface IMatteryRecipe<C : Container> : Recipe<C> { interface IMatteryRecipe<C : Container> : Recipe<C> {
override fun getRemainingItems(p_44004_: C): NonNullList<ItemStack> { override fun getRemainingItems(p_44004_: C): NonNullList<ItemStack> {

View File

@ -10,16 +10,14 @@ import net.minecraft.resources.ResourceLocation
import net.minecraft.world.inventory.CraftingContainer import net.minecraft.world.inventory.CraftingContainer
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.crafting.Ingredient import net.minecraft.world.item.crafting.Ingredient
import net.minecraft.world.item.crafting.Recipe
import net.minecraft.world.item.crafting.RecipeSerializer import net.minecraft.world.item.crafting.RecipeSerializer
import net.minecraft.world.item.crafting.RecipeType import net.minecraft.world.item.crafting.RecipeType
import net.minecraft.world.level.Level import net.minecraft.world.level.Level
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.capability.matter.matter import ru.dbotthepony.mc.otm.capability.matter.matter
import ru.dbotthepony.mc.otm.capability.matteryEnergy import ru.dbotthepony.mc.otm.capability.matteryEnergy
import ru.dbotthepony.mc.otm.container.iterator import ru.dbotthepony.mc.otm.capability.iterator
import ru.dbotthepony.mc.otm.container.util.iterator
import ru.dbotthepony.mc.otm.core.collect.filterNotNull import ru.dbotthepony.mc.otm.core.collect.filterNotNull
import ru.dbotthepony.mc.otm.core.collect.forEach
import ru.dbotthepony.mc.otm.core.collect.map import ru.dbotthepony.mc.otm.core.collect.map
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.nbt.set import ru.dbotthepony.mc.otm.core.nbt.set

View File

@ -19,7 +19,7 @@ import net.minecraft.world.item.crafting.RecipeType
import net.minecraft.world.item.crafting.ShapedRecipe import net.minecraft.world.item.crafting.ShapedRecipe
import net.minecraft.world.level.Level import net.minecraft.world.level.Level
import net.minecraftforge.common.crafting.IShapedRecipe import net.minecraftforge.common.crafting.IShapedRecipe
import ru.dbotthepony.mc.otm.container.stream import ru.dbotthepony.mc.otm.container.util.stream
import ru.dbotthepony.mc.otm.core.nbt.set import ru.dbotthepony.mc.otm.core.nbt.set
import ru.dbotthepony.mc.otm.core.registryName import ru.dbotthepony.mc.otm.core.registryName
import ru.dbotthepony.mc.otm.core.set import ru.dbotthepony.mc.otm.core.set

View File

@ -23,7 +23,8 @@ import net.minecraft.world.item.ItemStack
import ru.dbotthepony.mc.otm.capability.matteryPlayer import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.container.CombinedContainer import ru.dbotthepony.mc.otm.container.CombinedContainer
import ru.dbotthepony.mc.otm.container.get import ru.dbotthepony.mc.otm.container.get
import ru.dbotthepony.mc.otm.container.iterator import ru.dbotthepony.mc.otm.capability.iterator
import ru.dbotthepony.mc.otm.container.util.iterator
import ru.dbotthepony.mc.otm.core.collect.flatMap import ru.dbotthepony.mc.otm.core.collect.flatMap
import ru.dbotthepony.mc.otm.core.collect.toList import ru.dbotthepony.mc.otm.core.collect.toList
import ru.dbotthepony.mc.otm.core.isNotEmpty import ru.dbotthepony.mc.otm.core.isNotEmpty
@ -178,9 +179,8 @@ object MatteryInventoryChangeTrigger : CriterionTrigger<InventoryChangeTrigger.T
} else if (this.predicates.size > 1) { } else if (this.predicates.size > 1) {
val unsatisfied = ObjectArrayList(this.predicates) val unsatisfied = ObjectArrayList(this.predicates)
unsatisfied.removeIf { it.matches(ItemStack.EMPTY) } unsatisfied.removeIf { it.matches(ItemStack.EMPTY) }
val iterator = if (inventory is CombinedContainer) inventory.optimizedIterator() else inventory.iterator()
for (inventoryItem in iterator) { for (inventoryItem in inventory) {
unsatisfied.removeIf { it.matches(inventoryItem) } unsatisfied.removeIf { it.matches(inventoryItem) }
if (unsatisfied.isEmpty) break if (unsatisfied.isEmpty) break
} }