Always use slotted addItem implementation in containers
This commit is contained in:
parent
01215d647c
commit
70c5382e9d
@ -1,7 +1,6 @@
|
||||
package ru.dbotthepony.mc.otm.container
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntCollection
|
||||
import it.unimi.dsi.fastutil.ints.IntSet
|
||||
import net.minecraft.world.Container
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.entity.player.StackedContents
|
||||
@ -253,60 +252,102 @@ interface IEnhancedContainer<out S : IContainerSlot> : Container, RecipeInput, I
|
||||
return list
|
||||
}
|
||||
|
||||
fun addItem(stack: ItemStack, simulate: Boolean, slots: IntCollection = slotRange, onlyIntoExisting: Boolean = false, popTime: Int? = null): ItemStack {
|
||||
private fun addItem(stack: ItemStack, simulate: Boolean, filterPass: Boolean, slots: IntCollection, onlyIntoExisting: Boolean, popTime: Int?, ignoreFilters: Boolean): ItemStack {
|
||||
if (stack.isEmpty || slots.isEmpty())
|
||||
return stack
|
||||
|
||||
val copy = stack.copy()
|
||||
|
||||
// двигаем в одинаковые слоты
|
||||
for (slot in slotWithItemIterator(stack.item, slots)) {
|
||||
if (ItemStack.isSameItemSameComponents(this[slot], copy)) {
|
||||
val slotStack = this[slot]
|
||||
val slotLimit = getMaxStackSize(slot, slotStack)
|
||||
for (i in slotWithItemIterator(stack.item, slots)) {
|
||||
val slot = containerSlot(i)
|
||||
|
||||
if (slotStack.count < slotLimit) {
|
||||
val newCount = (slotStack.count + copy.count).coerceAtMost(slotLimit)
|
||||
val diff = newCount - slotStack.count
|
||||
val condition: Boolean
|
||||
|
||||
if (slot is IFilteredContainerSlot) {
|
||||
condition = (ignoreFilters || !slot.isForbiddenForAutomation) &&
|
||||
ItemStack.isSameItemSameComponents(slot.item, stack) &&
|
||||
(ignoreFilters || !filterPass && !slot.hasFilter || filterPass && slot.hasFilter && slot.testSlotFilter(stack))
|
||||
} else {
|
||||
condition = (ignoreFilters || !filterPass) && ItemStack.isSameItemSameComponents(slot.item, stack)
|
||||
}
|
||||
|
||||
if (condition) {
|
||||
val slotLimit = slot.maxStackSize(slot.item)
|
||||
|
||||
if (slot.item.count < slotLimit) {
|
||||
val newCount = (slot.item.count + stack.count).coerceAtMost(slotLimit)
|
||||
val diff = newCount - slot.item.count
|
||||
|
||||
if (!simulate) {
|
||||
slotStack.count = newCount
|
||||
setChanged(slot)
|
||||
slot.item.count = newCount
|
||||
slot.setChanged()
|
||||
|
||||
if (popTime != null) {
|
||||
slotStack.popTime = popTime
|
||||
slot.item.popTime = popTime
|
||||
}
|
||||
}
|
||||
|
||||
copy.shrink(diff)
|
||||
stack.shrink(diff)
|
||||
|
||||
if (copy.isEmpty) {
|
||||
if (stack.isEmpty)
|
||||
return ItemStack.EMPTY
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!onlyIntoExisting) {
|
||||
// двигаем в пустые слоты
|
||||
for (slot in emptySlotIndexIterator(slots)) {
|
||||
val diff = copy.count.coerceAtMost(getMaxStackSize(slot, stack))
|
||||
for (i in emptySlotIndexIterator(slots)) {
|
||||
val slot = containerSlot(i)
|
||||
|
||||
if (!simulate) {
|
||||
val copyToPut = copy.copy()
|
||||
copyToPut.count = diff
|
||||
this[slot] = copyToPut
|
||||
setChanged()
|
||||
val condition: Boolean
|
||||
|
||||
if (slot is IFilteredContainerSlot) {
|
||||
condition = (ignoreFilters || !slot.isForbiddenForAutomation) &&
|
||||
(ignoreFilters || !filterPass && !slot.hasFilter || filterPass && slot.hasFilter && slot.testSlotFilter(stack))
|
||||
} else {
|
||||
condition = ignoreFilters || !filterPass
|
||||
}
|
||||
|
||||
copy.shrink(diff)
|
||||
if (condition) {
|
||||
val diff = stack.count.coerceAtMost(slot.maxStackSize(stack))
|
||||
|
||||
if (copy.isEmpty)
|
||||
return ItemStack.EMPTY
|
||||
if (!simulate) {
|
||||
val copyToPut = stack.copy()
|
||||
copyToPut.count = diff
|
||||
slot.item = copyToPut
|
||||
|
||||
if (popTime != null) {
|
||||
copyToPut.popTime = popTime
|
||||
}
|
||||
}
|
||||
|
||||
stack.shrink(diff)
|
||||
|
||||
if (stack.isEmpty)
|
||||
return ItemStack.EMPTY
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return copy
|
||||
return stack
|
||||
}
|
||||
|
||||
/**
|
||||
* Hint used internally by [IEnhancedContainer] to potentially speed up default method implementations
|
||||
*/
|
||||
val hasFilterableSlots: Boolean
|
||||
get() = false
|
||||
|
||||
fun addItem(stack: ItemStack, simulate: Boolean, slots: IntCollection = slotRange, onlyIntoExisting: Boolean = false, popTime: Int? = null, ignoreFilters: Boolean = false): ItemStack {
|
||||
if (stack.isEmpty || slots.isEmpty())
|
||||
return stack
|
||||
|
||||
if (ignoreFilters || !hasFilterableSlots) {
|
||||
return addItem(stack.copy(), simulate, filterPass = true, slots, onlyIntoExisting = onlyIntoExisting, popTime = popTime, ignoreFilters = true)
|
||||
} else {
|
||||
var copy = addItem(stack.copy(), simulate, filterPass = true, slots, onlyIntoExisting = onlyIntoExisting, popTime = popTime, ignoreFilters = false)
|
||||
copy = addItem(copy, simulate, filterPass = false, slots, onlyIntoExisting = onlyIntoExisting, popTime = popTime, ignoreFilters = false)
|
||||
return copy
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -314,20 +355,20 @@ interface IEnhancedContainer<out S : IContainerSlot> : Container, RecipeInput, I
|
||||
*
|
||||
* @return Whenever [stack] was modified
|
||||
*/
|
||||
fun consumeItem(stack: ItemStack, simulate: Boolean, slots: IntCollection = slotRange, onlyIntoExisting: Boolean = false, popTime: Int? = null): Boolean {
|
||||
if (stack.isEmpty || slots.isEmpty())
|
||||
fun consumeItem(stack: ItemStack, simulate: Boolean, slots: IntCollection = slotRange, onlyIntoExisting: Boolean = false, popTime: Int? = null, ignoreFilters: Boolean = false): Boolean {
|
||||
if (stack.isEmpty)
|
||||
return false
|
||||
|
||||
val result = addItem(stack, simulate, slots, onlyIntoExisting, popTime)
|
||||
val result = addItem(stack, simulate = simulate, slots = slots, onlyIntoExisting = onlyIntoExisting, popTime = popTime, ignoreFilters = ignoreFilters)
|
||||
if (!simulate) stack.count = result.count
|
||||
return result.count != stack.count
|
||||
}
|
||||
|
||||
fun fullyAddItem(stack: ItemStack, slots: IntCollection = slotRange, onlyIntoExisting: Boolean = false, popTime: Int? = null): Boolean {
|
||||
if (!addItem(stack, true, slots, onlyIntoExisting, popTime).isEmpty)
|
||||
fun fullyAddItem(stack: ItemStack, slots: IntCollection = slotRange, onlyIntoExisting: Boolean = false, popTime: Int? = null, ignoreFilters: Boolean = false): Boolean {
|
||||
if (!addItem(stack, simulate = true, slots = slots, popTime = popTime, onlyIntoExisting = onlyIntoExisting, ignoreFilters = ignoreFilters).isEmpty)
|
||||
return false
|
||||
|
||||
return addItem(stack, false, slots, onlyIntoExisting, popTime).isEmpty
|
||||
return addItem(stack, simulate = false, slots = slots, popTime = popTime, onlyIntoExisting = onlyIntoExisting, ignoreFilters = ignoreFilters).isEmpty
|
||||
}
|
||||
|
||||
fun stream(): Stream<ItemStack> {
|
||||
|
@ -1,7 +1,5 @@
|
||||
package ru.dbotthepony.mc.otm.container
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntCollection
|
||||
import it.unimi.dsi.fastutil.ints.IntSet
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import ru.dbotthepony.kommons.collect.any
|
||||
|
||||
@ -33,147 +31,6 @@ interface ISlottedContainer<out S : IContainerSlot> : IEnhancedContainer<S> {
|
||||
containerSlot(slot).item = itemStack
|
||||
}
|
||||
|
||||
private fun addItem(stack: ItemStack, simulate: Boolean, filterPass: Boolean, slots: IntCollection, onlyIntoExisting: Boolean, popTime: Int?, ignoreFilters: Boolean): ItemStack {
|
||||
if (stack.isEmpty || slots.isEmpty())
|
||||
return stack
|
||||
|
||||
// двигаем в одинаковые слоты
|
||||
for (i in slotWithItemIterator(stack.item, slots)) {
|
||||
val slot = containerSlot(i)
|
||||
|
||||
val condition: Boolean
|
||||
|
||||
if (slot is IFilteredContainerSlot) {
|
||||
condition = (ignoreFilters || !slot.isForbiddenForAutomation) &&
|
||||
ItemStack.isSameItemSameComponents(slot.item, stack) &&
|
||||
(ignoreFilters || !filterPass && !slot.hasFilter || filterPass && slot.hasFilter && slot.testSlotFilter(stack))
|
||||
} else {
|
||||
condition = (ignoreFilters || !filterPass) && ItemStack.isSameItemSameComponents(slot.item, stack)
|
||||
}
|
||||
|
||||
if (condition) {
|
||||
val slotLimit = slot.maxStackSize(slot.item)
|
||||
|
||||
if (slot.item.count < slotLimit) {
|
||||
val newCount = (slot.item.count + stack.count).coerceAtMost(slotLimit)
|
||||
val diff = newCount - slot.item.count
|
||||
|
||||
if (!simulate) {
|
||||
slot.item.count = newCount
|
||||
slot.setChanged()
|
||||
|
||||
if (popTime != null) {
|
||||
slot.item.popTime = popTime
|
||||
}
|
||||
}
|
||||
|
||||
stack.shrink(diff)
|
||||
|
||||
if (stack.isEmpty)
|
||||
return ItemStack.EMPTY
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!onlyIntoExisting) {
|
||||
for (i in emptySlotIndexIterator(slots)) {
|
||||
val slot = containerSlot(i)
|
||||
|
||||
val condition: Boolean
|
||||
|
||||
if (slot is IFilteredContainerSlot) {
|
||||
condition = (ignoreFilters || !slot.isForbiddenForAutomation) &&
|
||||
(ignoreFilters || !filterPass && !slot.hasFilter || filterPass && slot.hasFilter && slot.testSlotFilter(stack))
|
||||
} else {
|
||||
condition = ignoreFilters || !filterPass
|
||||
}
|
||||
|
||||
if (condition) {
|
||||
val diff = stack.count.coerceAtMost(slot.maxStackSize(stack))
|
||||
|
||||
if (!simulate) {
|
||||
val copyToPut = stack.copy()
|
||||
copyToPut.count = diff
|
||||
slot.item = copyToPut
|
||||
|
||||
if (popTime != null) {
|
||||
copyToPut.popTime = popTime
|
||||
}
|
||||
}
|
||||
|
||||
stack.shrink(diff)
|
||||
|
||||
if (stack.isEmpty)
|
||||
return ItemStack.EMPTY
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return stack
|
||||
}
|
||||
|
||||
/**
|
||||
* Hint used internally by [ISlottedContainer] to potentially speed up default method implementations
|
||||
*/
|
||||
val hasFilterableSlots: Boolean
|
||||
override val hasFilterableSlots: Boolean
|
||||
get() = slotIterator().any { it is IFilteredContainerSlot }
|
||||
|
||||
fun addItem(stack: ItemStack, simulate: Boolean, slots: IntCollection = slotRange, onlyIntoExisting: Boolean = false, popTime: Int? = null, ignoreFilters: Boolean): ItemStack {
|
||||
if (stack.isEmpty || slots.isEmpty())
|
||||
return stack
|
||||
|
||||
if (ignoreFilters || !hasFilterableSlots) {
|
||||
return addItem(stack.copy(), simulate, filterPass = true, slots, onlyIntoExisting = onlyIntoExisting, popTime = popTime, ignoreFilters = true)
|
||||
} else {
|
||||
var copy = addItem(stack.copy(), simulate, filterPass = true, slots, onlyIntoExisting = onlyIntoExisting, popTime = popTime, ignoreFilters = false)
|
||||
copy = addItem(copy, simulate, filterPass = false, slots, onlyIntoExisting = onlyIntoExisting, popTime = popTime, ignoreFilters = false)
|
||||
return copy
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Unlike [addItem], modifies original [stack]
|
||||
*
|
||||
* @return Whenever [stack] was modified
|
||||
*/
|
||||
fun consumeItem(stack: ItemStack, simulate: Boolean, slots: IntCollection = slotRange, onlyIntoExisting: Boolean = false, popTime: Int? = null, ignoreFilters: Boolean): Boolean {
|
||||
if (stack.isEmpty)
|
||||
return false
|
||||
|
||||
val result = addItem(stack, simulate = simulate, slots = slots, onlyIntoExisting = onlyIntoExisting, popTime = popTime, ignoreFilters = ignoreFilters)
|
||||
if (!simulate) stack.count = result.count
|
||||
return result.count != stack.count
|
||||
}
|
||||
|
||||
fun fullyAddItem(stack: ItemStack, slots: IntCollection = slotRange, onlyIntoExisting: Boolean = false, popTime: Int? = null, ignoreFilters: Boolean): Boolean {
|
||||
if (!addItem(stack, simulate = true, slots = slots, popTime = popTime, onlyIntoExisting = onlyIntoExisting, ignoreFilters = ignoreFilters).isEmpty)
|
||||
return false
|
||||
|
||||
return addItem(stack, simulate = false, slots = slots, popTime = popTime, onlyIntoExisting = onlyIntoExisting, ignoreFilters = ignoreFilters).isEmpty
|
||||
}
|
||||
|
||||
override fun addItem(
|
||||
stack: ItemStack,
|
||||
simulate: Boolean,
|
||||
slots: IntCollection,
|
||||
onlyIntoExisting: Boolean,
|
||||
popTime: Int?
|
||||
): ItemStack {
|
||||
return addItem(stack, simulate = simulate, slots = slots, onlyIntoExisting = onlyIntoExisting, popTime = popTime, ignoreFilters = false)
|
||||
}
|
||||
|
||||
override fun consumeItem(
|
||||
stack: ItemStack,
|
||||
simulate: Boolean,
|
||||
slots: IntCollection,
|
||||
onlyIntoExisting: Boolean,
|
||||
popTime: Int?
|
||||
): Boolean {
|
||||
return consumeItem(stack, simulate = simulate, slots = slots, onlyIntoExisting = onlyIntoExisting, popTime = popTime, ignoreFilters = false)
|
||||
}
|
||||
|
||||
override fun fullyAddItem(stack: ItemStack, slots: IntCollection, onlyIntoExisting: Boolean, popTime: Int?): Boolean {
|
||||
return fullyAddItem(stack, slots = slots, onlyIntoExisting = onlyIntoExisting, popTime = popTime, ignoreFilters = false)
|
||||
}
|
||||
}
|
||||
|
@ -19,4 +19,7 @@ class ExopackContainer(size: Int, val player: MatteryPlayer) : EnhancedContainer
|
||||
override fun containerSlot(slot: Int): IPlayerInventorySlot {
|
||||
return Slot(slot)
|
||||
}
|
||||
|
||||
override val hasFilterableSlots: Boolean
|
||||
get() = true
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user