Prioritize slots with filter or items across all chests
This commit is contained in:
parent
85c4aa4dc4
commit
5b1ae12f85
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user