Prioritize non-filtered slots when taking items first

This commit is contained in:
DBotThePony 2025-03-19 11:29:47 +07:00
parent bd4622fc0d
commit 85c4aa4dc4
Signed by: DBot
GPG Key ID: DCC23B5715498507

View File

@ -16,6 +16,37 @@ import ru.dbotthepony.mc.otm.core.util.asKey
import ru.dbotthepony.mc.otm.core.util.asKeyOrNull
class QuickMoveInput(private val menu: MatteryMenu, val from: Collection<Slot>, val to: Collection<Slot>, val mode: Mode, val dontTouchFilteredSlots: Boolean = true) {
object HasItemComparator : Comparator<Slot> {
override fun compare(a: Slot, b: Slot): Int {
val hasItemA = a.item.isNotEmpty
val hasItemB = b.item.isNotEmpty
if (hasItemA == hasItemB)
return 0
else if (hasItemA)
return -1
else
return 1
}
}
object HasFilterComparator : Comparator<Slot> {
override fun compare(a: Slot, b: Slot): Int {
val slotA = a.containerSlotOrNull()
val slotB = b.containerSlotOrNull()
val hasFilterA = slotA is IFilteredContainerSlot && slotA.hasFilter
val hasFilterB = slotB is IFilteredContainerSlot && slotB.hasFilter
if (hasFilterA == hasFilterB)
return 0
else if (hasFilterA)
return -1
else
return 1
}
}
enum class Mode(val iconFromStorage: AbstractMatterySprite, val iconToStorage: AbstractMatterySprite) {
RESTOCK(
Widgets18.RESTOCK_FROM_STORAGE,
@ -30,7 +61,14 @@ class QuickMoveInput(private val menu: MatteryMenu, val from: Collection<Slot>,
for (key in intersect) {
val slotsTo = itemsTo[key]!!
itemsFrom[key]!!.forEach { moveItemStackTo(player, it, slotsTo) }
val slotsFrom = itemsFrom[key]!!
if (!dontTouchFilteredSlots) {
// touch filtered slots last
slotsFrom.sortWith(HasFilterComparator.reversed())
}
slotsFrom.forEach { moveItemStackTo(player, it, slotsTo) }
}
}
},
@ -49,6 +87,12 @@ class QuickMoveInput(private val menu: MatteryMenu, val from: Collection<Slot>,
for (key in intersect) {
val slotsTo = prioritySortSlots(itemsTo[key]!!, key.asItemStack())
val slotsFrom = itemsFrom[key]!!
if (!dontTouchFilteredSlots) {
// touch filtered slots last
slotsFrom.sortWith(HasFilterComparator.reversed())
}
slotsFrom.removeIf { moveItemStackTo(player, it, slotsTo, sort = false); it.item.isEmpty }
var moveAny = false
slotsFrom.forEach { moveAny = moveItemStackTo(player, it, emptyTo, sort = false) || moveAny }
@ -150,40 +194,20 @@ class QuickMoveInput(private val menu: MatteryMenu, val from: Collection<Slot>,
return true
}
fun prioritySortSlots(slots: Collection<Slot>, filterItem: ItemStack? = null): MutableList<Slot> {
val sortedSlots = ArrayList(slots)
private val itemFilterSlotComparator = HasItemComparator.thenComparing(HasFilterComparator)
sortedSlots.removeIf {
fun <T : MutableList<Slot>> prioritySortSlotsInPlace(slots: T, filterItem: ItemStack? = null): T {
slots.removeIf {
val slot = it.containerSlotOrNull()
it.isOverCapacity || filterItem != null && !it.mayPlace(filterItem) || slot is IFilteredContainerSlot && slot.isForbiddenForAutomation
}
sortedSlots.sortWith { a, b ->
val hasItemA = a.item.isNotEmpty
val hasItemB = b.item.isNotEmpty
slots.sortWith(itemFilterSlotComparator)
return slots
}
if (hasItemA && hasItemB)
return@sortWith 0
else if (hasItemA)
return@sortWith -1
else if (hasItemB)
return@sortWith 1
val slotA = a.containerSlotOrNull()
val slotB = b.containerSlotOrNull()
val hasFilterA = slotA is IFilteredContainerSlot && slotA.hasFilter
val hasFilterB = slotB is IFilteredContainerSlot && slotB.hasFilter
if (hasFilterA && hasFilterB || !hasFilterA && !hasFilterB)
return@sortWith 0
else if (hasFilterA)
return@sortWith -1
else
return@sortWith 1
}
return sortedSlots
fun prioritySortSlots(slots: Collection<Slot>, filterItem: ItemStack? = null): MutableList<Slot> {
return prioritySortSlotsInPlace(ArrayList(slots), filterItem)
}
fun moveItemStackToSlots(item: ItemStack, slots: Collection<Slot>, simulate: Boolean = false, sort: Boolean = true): ItemStack {