Prioritize slots with filter or items across all chests

This commit is contained in:
DBotThePony 2025-03-19 16:50:43 +07:00
parent 85c4aa4dc4
commit 5b1ae12f85
Signed by: DBot
GPG Key ID: DCC23B5715498507
2 changed files with 43 additions and 30 deletions

View File

@ -16,20 +16,21 @@ 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) {
/**
* slots with items come first
*/
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
return hasItemB.compareTo(hasItemA)
}
}
/**
* slots with filters come first
*/
object HasFilterComparator : Comparator<Slot> {
override fun compare(a: Slot, b: Slot): Int {
val slotA = a.containerSlotOrNull()
@ -38,12 +39,7 @@ class QuickMoveInput(private val menu: MatteryMenu, val from: Collection<Slot>,
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
return hasFilterB.compareTo(hasFilterA)
}
}

View File

@ -9,16 +9,12 @@ import net.minecraft.network.codec.StreamCodec
import net.minecraft.network.protocol.common.custom.CustomPacketPayload
import net.minecraft.network.protocol.game.ClientboundSetCarriedItemPacket
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.entity.ai.attributes.Attributes
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.inventory.Slot
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.ChunkPos
import net.minecraft.world.level.ClipBlockStateContext
import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.phys.Vec3
import net.neoforged.neoforge.common.NeoForgeMod
import net.neoforged.neoforge.network.handling.IPayloadContext
import org.apache.logging.log4j.LogManager
import ru.dbotthepony.kommons.math.RGBAColor
@ -28,10 +24,11 @@ import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.player.MatteryPlayer
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.container.IFilteredContainerSlot
import ru.dbotthepony.mc.otm.container.get
import ru.dbotthepony.mc.otm.container.set
import ru.dbotthepony.mc.otm.container.util.containerSlotOrNull
import ru.dbotthepony.mc.otm.core.ResourceLocation
import ru.dbotthepony.mc.otm.core.getChunkNow
import ru.dbotthepony.mc.otm.core.math.Vector
import ru.dbotthepony.mc.otm.core.math.component1
import ru.dbotthepony.mc.otm.core.math.component2
@ -467,21 +464,41 @@ class QuickStackPacket(
findCaps.sortBy { it.first.blockPos.distToCenterSqr(player.position) }
val eyes = player.eyePosition
val ignoreBlockstates = HashSet<BlockState>()
findCaps.forEach { (b, _) -> ignoreBlockstates.add(b.blockState) }
val ignorePositions = HashSet<BlockPos>()
findCaps.forEach { (b) -> ignorePositions.add(b.blockPos) }
val level = player.serverLevel()
for ((blockEntity, cap) in findCaps) {
// don't interact through walls
val trace = player.serverLevel().isBlockInLine(ClipBlockStateContext(eyes, Vector.atCenterOf(blockEntity.blockPos)) {
!it.isAir && it !in ignoreBlockstates
})
// don't interact through walls
// but interact through chests
findCaps.removeIf { (b) ->
BlockGetter.traverseBlocks(eyes, Vector.atCenterOf(b.blockPos), null, { _, pos -> if (pos !in ignorePositions && !level.getBlockState(pos).isAir) true else null }, { false })
}
if (trace.blockPos == blockEntity.blockPos) {
if (fromExopack)
mode.move(player.matteryPlayer.exoPackMenu.playerCombinedInventorySlots, cap.getSlotsFor(player), player)
else
mode.move(cap.getSlotsFor(player), player.matteryPlayer.exoPackMenu.playerInventorySlots, player, false)
if (fromExopack) {
val prioritySlots = ArrayList<Slot>()
val regularSlots = ArrayList<Collection<Slot>>()
for ((_, cap) in findCaps) {
val slots = cap.getSlotsFor(player)
slots.forEach {
val slot = it.containerSlotOrNull()
if (it.hasItem() || slot is IFilteredContainerSlot && slot.hasFilter)
prioritySlots.add(it)
}
regularSlots.add(slots)
}
mode.move(player.matteryPlayer.exoPackMenu.playerCombinedInventorySlots, prioritySlots, player)
regularSlots.forEach {
mode.move(player.matteryPlayer.exoPackMenu.playerCombinedInventorySlots, it, player)
}
} else {
for ((_, cap) in findCaps)
mode.move(cap.getSlotsFor(player), player.matteryPlayer.exoPackMenu.playerInventorySlots, player, false)
}
}