Compare commits

..

No commits in common. "85c4aa4dc4a9ec180ff343bc90480a8308608607" and "36f6a123953780a99900689a048c18c64c6260d5" have entirely different histories.

5 changed files with 44 additions and 68 deletions

View File

@ -24,7 +24,7 @@ class MatteryChestMenu(
} }
override val quickMoveToStorage = QuickMoveInput.create(this, playerCombinedInventorySlots, containerSlots) override val quickMoveToStorage = QuickMoveInput.create(this, playerCombinedInventorySlots, containerSlots)
override val quickMoveFromStorage = QuickMoveInput.create(this, containerSlots, playerInventorySlots, false) override val quickMoveFromStorage = QuickMoveInput.create(this, containerSlots, playerInventorySlots)
companion object { companion object {
@JvmStatic @JvmStatic

View File

@ -26,7 +26,7 @@ class MatteryShulkerBoxMenu(
} }
override val quickMoveToStorage = QuickMoveInput.create(this, playerCombinedInventorySlots, containerSlots) override val quickMoveToStorage = QuickMoveInput.create(this, playerCombinedInventorySlots, containerSlots)
override val quickMoveFromStorage = QuickMoveInput.create(this, containerSlots, playerInventorySlots, false) override val quickMoveFromStorage = QuickMoveInput.create(this, containerSlots, playerInventorySlots)
class Slot(container: Container, slot: Int) : MatteryMenuSlot(container, slot) { class Slot(container: Container, slot: Int) : MatteryMenuSlot(container, slot) {
override fun mayPlace(stack: ItemStack): Boolean { override fun mayPlace(stack: ItemStack): Boolean {

View File

@ -15,60 +15,22 @@ import ru.dbotthepony.mc.otm.core.util.ItemStackKey
import ru.dbotthepony.mc.otm.core.util.asKey import ru.dbotthepony.mc.otm.core.util.asKey
import ru.dbotthepony.mc.otm.core.util.asKeyOrNull 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) { class QuickMoveInput(private val menu: MatteryMenu, val from: Collection<Slot>, val to: Collection<Slot>, val mode: Mode) {
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) { enum class Mode(val iconFromStorage: AbstractMatterySprite, val iconToStorage: AbstractMatterySprite) {
RESTOCK( RESTOCK(
Widgets18.RESTOCK_FROM_STORAGE, Widgets18.RESTOCK_FROM_STORAGE,
Widgets18.RESTOCK_TO_STORAGE Widgets18.RESTOCK_TO_STORAGE
) { ) {
override fun move(from: Collection<Slot>, to: Collection<Slot>, player: Player, dontTouchFilteredSlots: Boolean) { override fun move(from: Collection<Slot>, to: Collection<Slot>, player: Player) {
if (from.isEmpty() || to.isEmpty()) return if (from.isEmpty() || to.isEmpty()) return
val (_, itemsFrom) = computeSlotLists(from, dontTouchFilteredSlots) val (_, itemsFrom) = computeSlotLists(from, true)
val (_, itemsTo) = computeSlotLists(to, false) val (_, itemsTo) = computeSlotLists(to, false)
val intersect = if (itemsFrom.size < itemsTo.size) itemsFrom.keys.filter { it in itemsTo.keys } else itemsTo.keys.filter { it in itemsFrom.keys } val intersect = if (itemsFrom.size < itemsTo.size) itemsFrom.keys.filter { it in itemsTo.keys } else itemsTo.keys.filter { it in itemsFrom.keys }
for (key in intersect) { for (key in intersect) {
val slotsTo = itemsTo[key]!! val slotsTo = itemsTo[key]!!
val slotsFrom = itemsFrom[key]!! itemsFrom[key]!!.forEach { moveItemStackTo(player, it, slotsTo) }
if (!dontTouchFilteredSlots) {
// touch filtered slots last
slotsFrom.sortWith(HasFilterComparator.reversed())
}
slotsFrom.forEach { moveItemStackTo(player, it, slotsTo) }
} }
} }
}, },
@ -77,9 +39,9 @@ class QuickMoveInput(private val menu: MatteryMenu, val from: Collection<Slot>,
Widgets18.RESTOCK_WITH_MOVE_FROM_STORAGE, Widgets18.RESTOCK_WITH_MOVE_FROM_STORAGE,
Widgets18.RESTOCK_WITH_MOVE_TO_STORAGE Widgets18.RESTOCK_WITH_MOVE_TO_STORAGE
) { ) {
override fun move(from: Collection<Slot>, to: Collection<Slot>, player: Player, dontTouchFilteredSlots: Boolean) { override fun move(from: Collection<Slot>, to: Collection<Slot>, player: Player) {
if (from.isEmpty() || to.isEmpty()) return if (from.isEmpty() || to.isEmpty()) return
val (_, itemsFrom) = computeSlotLists(from, dontTouchFilteredSlots) val (_, itemsFrom) = computeSlotLists(from, true)
val (emptyTo, itemsTo) = computeSlotLists(to, false) val (emptyTo, itemsTo) = computeSlotLists(to, false)
val intersect = if (itemsFrom.size < itemsTo.size) itemsFrom.keys.filter { it in itemsTo.keys } else itemsTo.keys.filter { it in itemsFrom.keys } val intersect = if (itemsFrom.size < itemsTo.size) itemsFrom.keys.filter { it in itemsTo.keys } else itemsTo.keys.filter { it in itemsFrom.keys }
@ -87,12 +49,6 @@ class QuickMoveInput(private val menu: MatteryMenu, val from: Collection<Slot>,
for (key in intersect) { for (key in intersect) {
val slotsTo = prioritySortSlots(itemsTo[key]!!, key.asItemStack()) val slotsTo = prioritySortSlots(itemsTo[key]!!, key.asItemStack())
val slotsFrom = itemsFrom[key]!! 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 } slotsFrom.removeIf { moveItemStackTo(player, it, slotsTo, sort = false); it.item.isEmpty }
var moveAny = false var moveAny = false
slotsFrom.forEach { moveAny = moveItemStackTo(player, it, emptyTo, sort = false) || moveAny } slotsFrom.forEach { moveAny = moveItemStackTo(player, it, emptyTo, sort = false) || moveAny }
@ -105,20 +61,20 @@ class QuickMoveInput(private val menu: MatteryMenu, val from: Collection<Slot>,
Widgets18.MOVE_EVERYTHING_FROM_STORAGE, Widgets18.MOVE_EVERYTHING_FROM_STORAGE,
Widgets18.MOVE_EVERYTHING_TO_STORAGE Widgets18.MOVE_EVERYTHING_TO_STORAGE
) { ) {
override fun move(from: Collection<Slot>, to: Collection<Slot>, player: Player, dontTouchFilteredSlots: Boolean) { override fun move(from: Collection<Slot>, to: Collection<Slot>, player: Player) {
if (from.isEmpty() || to.isEmpty()) return if (from.isEmpty() || to.isEmpty()) return
val toSorted = prioritySortSlots(to) val toSorted = prioritySortSlots(to)
from.forEach { from.forEach {
val slot = it.containerSlotOrNull() val slot = it.containerSlotOrNull()
if (!dontTouchFilteredSlots || slot !is IFilteredContainerSlot || !slot.hasFilter) if (slot !is IFilteredContainerSlot || !slot.hasFilter)
moveItemStackTo(player, it, toSorted, sort = false) moveItemStackTo(player, it, toSorted, sort = false)
} }
} }
}; };
abstract fun move(from: Collection<Slot>, to: Collection<Slot>, player: Player, dontTouchFilteredSlots: Boolean = true) abstract fun move(from: Collection<Slot>, to: Collection<Slot>, player: Player)
val textFromStorage: Component get() { val textFromStorage: Component get() {
return TranslatableComponent("otm.gui.quickmove_from.${name.lowercase()}") return TranslatableComponent("otm.gui.quickmove_from.${name.lowercase()}")
@ -136,12 +92,12 @@ class QuickMoveInput(private val menu: MatteryMenu, val from: Collection<Slot>,
} }
private fun handle() { private fun handle() {
mode.move(from, to, menu.player, dontTouchFilteredSlots) mode.move(from, to, menu.player)
} }
companion object { companion object {
fun create(menu: MatteryMenu, from: Collection<Slot>, to: Collection<Slot>, dontTouchFilteredSlots: Boolean = true): Map<Mode, QuickMoveInput> { fun create(menu: MatteryMenu, from: Collection<Slot>, to: Collection<Slot>): Map<Mode, QuickMoveInput> {
return Mode.entries.associateWith { QuickMoveInput(menu, from, to, it, dontTouchFilteredSlots) } return Mode.entries.associateWith { QuickMoveInput(menu, from, to, it) }
} }
private fun computeSlotLists(slots: Collection<Slot>, skipFilteredSlots: Boolean): Pair<MutableList<Slot>, MutableMap<ItemStackKey, MutableList<Slot>>> { private fun computeSlotLists(slots: Collection<Slot>, skipFilteredSlots: Boolean): Pair<MutableList<Slot>, MutableMap<ItemStackKey, MutableList<Slot>>> {
@ -194,20 +150,40 @@ class QuickMoveInput(private val menu: MatteryMenu, val from: Collection<Slot>,
return true return true
} }
private val itemFilterSlotComparator = HasItemComparator.thenComparing(HasFilterComparator) fun prioritySortSlots(slots: Collection<Slot>, filterItem: ItemStack? = null): MutableList<Slot> {
val sortedSlots = ArrayList(slots)
fun <T : MutableList<Slot>> prioritySortSlotsInPlace(slots: T, filterItem: ItemStack? = null): T { sortedSlots.removeIf {
slots.removeIf {
val slot = it.containerSlotOrNull() val slot = it.containerSlotOrNull()
it.isOverCapacity || filterItem != null && !it.mayPlace(filterItem) || slot is IFilteredContainerSlot && slot.isForbiddenForAutomation it.isOverCapacity || filterItem != null && !it.mayPlace(filterItem) || slot is IFilteredContainerSlot && slot.isForbiddenForAutomation
} }
slots.sortWith(itemFilterSlotComparator) sortedSlots.sortWith { a, b ->
return slots val hasItemA = a.item.isNotEmpty
} val hasItemB = b.item.isNotEmpty
fun prioritySortSlots(slots: Collection<Slot>, filterItem: ItemStack? = null): MutableList<Slot> { if (hasItemA && hasItemB)
return prioritySortSlotsInPlace(ArrayList(slots), filterItem) 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 moveItemStackToSlots(item: ItemStack, slots: Collection<Slot>, simulate: Boolean = false, sort: Boolean = true): ItemStack { fun moveItemStackToSlots(item: ItemStack, slots: Collection<Slot>, simulate: Boolean = false, sort: Boolean = true): ItemStack {

View File

@ -22,7 +22,7 @@ class CargoCrateMenu(
val sort = SortInput(this, actualContainer, playerSortSettings) val sort = SortInput(this, actualContainer, playerSortSettings)
val quickMoveToStorage = QuickMoveInput.create(this, playerCombinedInventorySlots, storageSlots) val quickMoveToStorage = QuickMoveInput.create(this, playerCombinedInventorySlots, storageSlots)
val quickMoveFromStorage = QuickMoveInput.create(this, storageSlots, playerInventorySlots, false) val quickMoveFromStorage = QuickMoveInput.create(this, storageSlots, playerInventorySlots)
init { init {
if (trackedPlayerOpen) { if (trackedPlayerOpen) {

View File

@ -480,7 +480,7 @@ class QuickStackPacket(
if (fromExopack) if (fromExopack)
mode.move(player.matteryPlayer.exoPackMenu.playerCombinedInventorySlots, cap.getSlotsFor(player), player) mode.move(player.matteryPlayer.exoPackMenu.playerCombinedInventorySlots, cap.getSlotsFor(player), player)
else else
mode.move(cap.getSlotsFor(player), player.matteryPlayer.exoPackMenu.playerInventorySlots, player, false) mode.move(cap.getSlotsFor(player), player.matteryPlayer.exoPackMenu.playerInventorySlots, player)
} }
} }
} }