Compare commits

...

2 Commits

4 changed files with 82 additions and 179 deletions

View File

@ -76,6 +76,8 @@ class CombinedContainer<S : IContainerSlot>(containers: Stream<Pair<IEnhancedCon
.collect(ImmutableMap.toImmutableMap({ it.key }, { it.value })) .collect(ImmutableMap.toImmutableMap({ it.key }, { it.value }))
} }
override val hasFilterableSlots: Boolean = super.hasFilterableSlots
override fun clearContent() { override fun clearContent() {
for (container in fullCoverage) { for (container in fullCoverage) {
container.clearContent() container.clearContent()

View File

@ -1,7 +1,6 @@
package ru.dbotthepony.mc.otm.container package ru.dbotthepony.mc.otm.container
import it.unimi.dsi.fastutil.ints.IntCollection import it.unimi.dsi.fastutil.ints.IntCollection
import it.unimi.dsi.fastutil.ints.IntSet
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.entity.player.StackedContents import net.minecraft.world.entity.player.StackedContents
@ -253,60 +252,102 @@ interface IEnhancedContainer<out S : IContainerSlot> : Container, RecipeInput, I
return list 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()) if (stack.isEmpty || slots.isEmpty())
return stack return stack
val copy = stack.copy()
// двигаем в одинаковые слоты // двигаем в одинаковые слоты
for (slot in slotWithItemIterator(stack.item, slots)) { for (i in slotWithItemIterator(stack.item, slots)) {
if (ItemStack.isSameItemSameComponents(this[slot], copy)) { val slot = containerSlot(i)
val slotStack = this[slot]
val slotLimit = getMaxStackSize(slot, slotStack)
if (slotStack.count < slotLimit) { val condition: Boolean
val newCount = (slotStack.count + copy.count).coerceAtMost(slotLimit)
val diff = newCount - slotStack.count 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) { if (!simulate) {
slotStack.count = newCount slot.item.count = newCount
setChanged(slot) slot.setChanged()
if (popTime != null) { 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 return ItemStack.EMPTY
}
} }
} }
} }
if (!onlyIntoExisting) { if (!onlyIntoExisting) {
// двигаем в пустые слоты for (i in emptySlotIndexIterator(slots)) {
for (slot in emptySlotIndexIterator(slots)) { val slot = containerSlot(i)
val diff = copy.count.coerceAtMost(getMaxStackSize(slot, stack))
if (!simulate) { val condition: Boolean
val copyToPut = copy.copy()
copyToPut.count = diff if (slot is IFilteredContainerSlot) {
this[slot] = copyToPut condition = (ignoreFilters || !slot.isForbiddenForAutomation) &&
setChanged() (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) if (!simulate) {
return ItemStack.EMPTY 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 * @return Whenever [stack] was modified
*/ */
fun consumeItem(stack: ItemStack, simulate: Boolean, slots: IntCollection = slotRange, onlyIntoExisting: Boolean = false, popTime: Int? = null): Boolean { fun consumeItem(stack: ItemStack, simulate: Boolean, slots: IntCollection = slotRange, onlyIntoExisting: Boolean = false, popTime: Int? = null, ignoreFilters: Boolean = false): Boolean {
if (stack.isEmpty || slots.isEmpty()) if (stack.isEmpty)
return false 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 if (!simulate) stack.count = result.count
return result.count != stack.count return result.count != stack.count
} }
fun fullyAddItem(stack: ItemStack, slots: IntCollection = slotRange, onlyIntoExisting: Boolean = false, popTime: Int? = null): Boolean { fun fullyAddItem(stack: ItemStack, slots: IntCollection = slotRange, onlyIntoExisting: Boolean = false, popTime: Int? = null, ignoreFilters: Boolean = false): Boolean {
if (!addItem(stack, true, slots, onlyIntoExisting, popTime).isEmpty) if (!addItem(stack, simulate = true, slots = slots, popTime = popTime, onlyIntoExisting = onlyIntoExisting, ignoreFilters = ignoreFilters).isEmpty)
return false 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> { fun stream(): Stream<ItemStack> {

View File

@ -1,7 +1,5 @@
package ru.dbotthepony.mc.otm.container 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 net.minecraft.world.item.ItemStack
import ru.dbotthepony.kommons.collect.any import ru.dbotthepony.kommons.collect.any
@ -33,147 +31,6 @@ interface ISlottedContainer<out S : IContainerSlot> : IEnhancedContainer<S> {
containerSlot(slot).item = itemStack containerSlot(slot).item = itemStack
} }
private fun addItem(stack: ItemStack, simulate: Boolean, filterPass: Boolean, slots: IntCollection, onlyIntoExisting: Boolean, popTime: Int?, ignoreFilters: Boolean): ItemStack { override val hasFilterableSlots: Boolean
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
get() = slotIterator().any { it is IFilteredContainerSlot } 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)
}
} }

View File

@ -19,4 +19,7 @@ class ExopackContainer(size: Int, val player: MatteryPlayer) : EnhancedContainer
override fun containerSlot(slot: Int): IPlayerInventorySlot { override fun containerSlot(slot: Int): IPlayerInventorySlot {
return Slot(slot) return Slot(slot)
} }
override val hasFilterableSlots: Boolean
get() = true
} }