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 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, val dontTouchFilteredSlots: Boolean = true) {
/**
* slots with items come first
*/
object HasItemComparator : Comparator<Slot> { object HasItemComparator : Comparator<Slot> {
override fun compare(a: Slot, b: Slot): Int { override fun compare(a: Slot, b: Slot): Int {
val hasItemA = a.item.isNotEmpty val hasItemA = a.item.isNotEmpty
val hasItemB = b.item.isNotEmpty val hasItemB = b.item.isNotEmpty
if (hasItemA == hasItemB) return hasItemB.compareTo(hasItemA)
return 0
else if (hasItemA)
return -1
else
return 1
} }
} }
/**
* slots with filters come first
*/
object HasFilterComparator : Comparator<Slot> { object HasFilterComparator : Comparator<Slot> {
override fun compare(a: Slot, b: Slot): Int { override fun compare(a: Slot, b: Slot): Int {
val slotA = a.containerSlotOrNull() 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 hasFilterA = slotA is IFilteredContainerSlot && slotA.hasFilter
val hasFilterB = slotB is IFilteredContainerSlot && slotB.hasFilter val hasFilterB = slotB is IFilteredContainerSlot && slotB.hasFilter
if (hasFilterA == hasFilterB) return hasFilterB.compareTo(hasFilterA)
return 0
else if (hasFilterA)
return -1
else
return 1
} }
} }

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.common.custom.CustomPacketPayload
import net.minecraft.network.protocol.game.ClientboundSetCarriedItemPacket import net.minecraft.network.protocol.game.ClientboundSetCarriedItemPacket
import net.minecraft.server.level.ServerPlayer 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.entity.player.Inventory
import net.minecraft.world.inventory.Slot import net.minecraft.world.inventory.Slot
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.ChunkPos 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.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 net.neoforged.neoforge.network.handling.IPayloadContext
import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.LogManager
import ru.dbotthepony.kommons.math.RGBAColor 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.player.matteryPlayer import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.client.minecraft 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.get
import ru.dbotthepony.mc.otm.container.set 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.ResourceLocation
import ru.dbotthepony.mc.otm.core.getChunkNow
import ru.dbotthepony.mc.otm.core.math.Vector import ru.dbotthepony.mc.otm.core.math.Vector
import ru.dbotthepony.mc.otm.core.math.component1 import ru.dbotthepony.mc.otm.core.math.component1
import ru.dbotthepony.mc.otm.core.math.component2 import ru.dbotthepony.mc.otm.core.math.component2
@ -467,21 +464,41 @@ class QuickStackPacket(
findCaps.sortBy { it.first.blockPos.distToCenterSqr(player.position) } findCaps.sortBy { it.first.blockPos.distToCenterSqr(player.position) }
val eyes = player.eyePosition val eyes = player.eyePosition
val ignoreBlockstates = HashSet<BlockState>() val ignorePositions = HashSet<BlockPos>()
findCaps.forEach { (b, _) -> ignoreBlockstates.add(b.blockState) } findCaps.forEach { (b) -> ignorePositions.add(b.blockPos) }
val level = player.serverLevel()
for ((blockEntity, cap) in findCaps) {
// don't interact through walls // don't interact through walls
val trace = player.serverLevel().isBlockInLine(ClipBlockStateContext(eyes, Vector.atCenterOf(blockEntity.blockPos)) { // but interact through chests
!it.isAir && it !in ignoreBlockstates 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)
} }
} }