Remove LibBlockAttributes ItemStackCollections use
This commit is contained in:
parent
d782d43e1b
commit
7e71a1e03d
|
@ -1,6 +1,6 @@
|
||||||
package net.shadowfacts.phycon.block.terminal
|
package net.shadowfacts.phycon.block.terminal
|
||||||
|
|
||||||
import alexiil.mc.lib.attributes.item.ItemStackCollections
|
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap
|
||||||
import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant
|
import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant
|
||||||
import net.fabricmc.fabric.api.transfer.v1.storage.Storage
|
import net.fabricmc.fabric.api.transfer.v1.storage.Storage
|
||||||
import net.fabricmc.fabric.api.transfer.v1.transaction.Transaction
|
import net.fabricmc.fabric.api.transfer.v1.transaction.Transaction
|
||||||
|
@ -52,8 +52,7 @@ abstract class AbstractTerminalBlockEntity(type: BlockEntityType<*>, pos: BlockP
|
||||||
override val pendingInsertions = mutableListOf<PendingInsertion>()
|
override val pendingInsertions = mutableListOf<PendingInsertion>()
|
||||||
override val dispatchStackTimeout = INSERTION_TIMEOUT
|
override val dispatchStackTimeout = INSERTION_TIMEOUT
|
||||||
|
|
||||||
// TODO: need a ItemVariant -> Int/Long map
|
val cachedNetItems = Object2IntOpenHashMap<ItemVariant>()
|
||||||
val cachedNetItems = ItemStackCollections.intMap()
|
|
||||||
private var requestInventoryTimestamp: Long? = null
|
private var requestInventoryTimestamp: Long? = null
|
||||||
|
|
||||||
// todo: multiple players could have the terminal open simultaneously
|
// todo: multiple players could have the terminal open simultaneously
|
||||||
|
@ -142,7 +141,7 @@ abstract class AbstractTerminalBlockEntity(type: BlockEntityType<*>, pos: BlockP
|
||||||
val transaction = Transaction.openOuter()
|
val transaction = Transaction.openOuter()
|
||||||
for (view in inventory.iterator(transaction)) {
|
for (view in inventory.iterator(transaction)) {
|
||||||
val amount = view.amount.toInt()
|
val amount = view.amount.toInt()
|
||||||
cachedNetItems.mergeInt(view.resource.toStack(), amount, IntBinaryOperator { a, b -> a + b })
|
cachedNetItems.mergeInt(view.resource, amount, IntBinaryOperator { a, b -> a + b })
|
||||||
}
|
}
|
||||||
transaction.close()
|
transaction.close()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,20 @@
|
||||||
package net.shadowfacts.phycon.block.terminal
|
package net.shadowfacts.phycon.block.terminal
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant
|
||||||
import net.minecraft.screen.slot.Slot
|
import net.minecraft.screen.slot.Slot
|
||||||
import net.minecraft.screen.slot.SlotActionType
|
import net.minecraft.screen.slot.SlotActionType
|
||||||
import net.minecraft.entity.player.PlayerEntity
|
import net.minecraft.entity.player.PlayerEntity
|
||||||
import net.minecraft.entity.player.PlayerInventory
|
import net.minecraft.entity.player.PlayerInventory
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.network.PacketByteBuf
|
|
||||||
import net.minecraft.screen.ScreenHandler
|
import net.minecraft.screen.ScreenHandler
|
||||||
import net.minecraft.screen.ScreenHandlerType
|
import net.minecraft.screen.ScreenHandlerType
|
||||||
import net.minecraft.server.network.ServerPlayerEntity
|
import net.minecraft.server.network.ServerPlayerEntity
|
||||||
import net.minecraft.util.Identifier
|
|
||||||
import net.minecraft.util.registry.Registry
|
import net.minecraft.util.registry.Registry
|
||||||
import net.shadowfacts.phycon.DefaultPlugin
|
import net.shadowfacts.phycon.DefaultPlugin
|
||||||
import net.shadowfacts.phycon.PhysicalConnectivity
|
|
||||||
import net.shadowfacts.phycon.init.PhyBlocks
|
|
||||||
import net.shadowfacts.phycon.init.PhyScreens
|
|
||||||
import net.shadowfacts.phycon.networking.S2CTerminalUpdateDisplayedItems
|
import net.shadowfacts.phycon.networking.S2CTerminalUpdateDisplayedItems
|
||||||
import net.shadowfacts.phycon.util.SortMode
|
import net.shadowfacts.phycon.util.SortMode
|
||||||
import net.shadowfacts.phycon.util.TerminalSettings
|
import net.shadowfacts.phycon.util.TerminalSettings
|
||||||
import net.shadowfacts.phycon.util.copyWithCount
|
import net.shadowfacts.phycon.util.name
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
import kotlin.math.ceil
|
import kotlin.math.ceil
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
|
@ -49,7 +45,7 @@ abstract class AbstractTerminalScreenHandler<T : AbstractTerminalBlockEntity>(
|
||||||
field = value
|
field = value
|
||||||
if (terminal.world!!.isClient) {
|
if (terminal.world!!.isClient) {
|
||||||
itemsForDisplay = value.map {
|
itemsForDisplay = value.map {
|
||||||
it.stack.copyWithCount(it.amount)
|
it.variant.toStack(it.amount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,6 +102,8 @@ abstract class AbstractTerminalScreenHandler<T : AbstractTerminalBlockEntity>(
|
||||||
return@filter true
|
return@filter true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// TODO: this is happening on the logical server, won't work with localization
|
||||||
|
// should filtering happen on the client?
|
||||||
it.key.name.string.contains(searchQuery, true)
|
it.key.name.string.contains(searchQuery, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,5 +271,5 @@ abstract class AbstractTerminalScreenHandler<T : AbstractTerminalBlockEntity>(
|
||||||
fun isBufferSlot(id: Int) = id in bufferSlotsStart until playerSlotsStart
|
fun isBufferSlot(id: Int) = id in bufferSlotsStart until playerSlotsStart
|
||||||
fun isPlayerSlot(id: Int) = id >= playerSlotsStart
|
fun isPlayerSlot(id: Int) = id >= playerSlotsStart
|
||||||
|
|
||||||
data class Entry(val stack: ItemStack, val amount: Int)
|
data class Entry(val variant: ItemVariant, val amount: Int)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package net.shadowfacts.phycon.block.terminal
|
package net.shadowfacts.phycon.block.terminal
|
||||||
|
|
||||||
import alexiil.mc.lib.attributes.item.ItemStackCollections
|
import it.unimi.dsi.fastutil.ints.IntBinaryOperator
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2IntArrayMap
|
||||||
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory
|
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory
|
||||||
|
import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.entity.player.PlayerEntity
|
import net.minecraft.entity.player.PlayerEntity
|
||||||
import net.minecraft.entity.player.PlayerInventory
|
import net.minecraft.entity.player.PlayerInventory
|
||||||
|
@ -20,7 +22,6 @@ import net.shadowfacts.phycon.util.equalsIgnoringAmount
|
||||||
import net.shadowfacts.phycon.util.fromTag
|
import net.shadowfacts.phycon.util.fromTag
|
||||||
import net.shadowfacts.phycon.util.toTag
|
import net.shadowfacts.phycon.util.toTag
|
||||||
import java.util.LinkedList
|
import java.util.LinkedList
|
||||||
import kotlin.math.min
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author shadowfacts
|
* @author shadowfacts
|
||||||
|
@ -52,20 +53,23 @@ class CraftingTerminalBlockEntity(pos: BlockPos, state: BlockState) :
|
||||||
}
|
}
|
||||||
|
|
||||||
fun requestItemsForCrafting(maxAmount: Int) {
|
fun requestItemsForCrafting(maxAmount: Int) {
|
||||||
val amounts = ItemStackCollections.map<IntArray>()
|
// use an array map because we have at most 9 items
|
||||||
|
// values are bitfields of which slots contain the item
|
||||||
|
val stackToSlotsMap = Object2IntArrayMap<ItemVariant>()
|
||||||
|
|
||||||
|
val or = IntBinaryOperator { a, b -> a or b }
|
||||||
for (i in 0 until craftingInv.size()) {
|
for (i in 0 until craftingInv.size()) {
|
||||||
val craftingInvStack = craftingInv.getStack(i)
|
val craftingInvStack = craftingInv.getStack(i)
|
||||||
if (craftingInvStack.isEmpty) continue
|
if (craftingInvStack.isEmpty) continue
|
||||||
if (craftingInvStack.count >= craftingInvStack.maxCount) continue
|
if (craftingInvStack.count >= craftingInvStack.maxCount) continue
|
||||||
|
|
||||||
if (craftingInvStack !in amounts) amounts[craftingInvStack] = IntArray(9) { 0 }
|
stackToSlotsMap.mergeInt(ItemVariant.of(craftingInvStack), 1 shl i, or)
|
||||||
amounts[craftingInvStack]!![i] = min(maxAmount, craftingInvStack.maxCount - craftingInvStack.count)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for ((stack, amountPerSlot) in amounts) {
|
for ((variant, slots) in stackToSlotsMap) {
|
||||||
val total = amountPerSlot.sum()
|
val total = slots.countOneBits()
|
||||||
val request = CraftingStackLocateRequest(stack, total, counter, amountPerSlot)
|
val stack = variant.toStack()
|
||||||
|
val request = CraftingStackLocateRequest(stack, total, counter, slots)
|
||||||
pendingRequests.add(request)
|
pendingRequests.add(request)
|
||||||
sendPacket(LocateStackPacket(stack, ipAddress))
|
sendPacket(LocateStackPacket(stack, ipAddress))
|
||||||
}
|
}
|
||||||
|
@ -90,19 +94,19 @@ class CraftingTerminalBlockEntity(pos: BlockPos, state: BlockState) :
|
||||||
if (currentStack.count >= currentStack.maxCount) continue
|
if (currentStack.count >= currentStack.maxCount) continue
|
||||||
if (!currentStack.equalsIgnoringAmount(remaining)) continue
|
if (!currentStack.equalsIgnoringAmount(remaining)) continue
|
||||||
|
|
||||||
val toInsert =
|
currentStack.count += 1
|
||||||
minOf(remaining.count, currentStack.maxCount - currentStack.count, craftingReq.amountPerSlot[i])
|
remaining.count -= 1
|
||||||
currentStack.count += toInsert
|
|
||||||
remaining.count -= toInsert
|
craftingReq.slots = craftingReq.slots and (1 shl i).inv()
|
||||||
craftingReq.amountPerSlot[i] -= toInsert
|
craftingReq.received += 1
|
||||||
craftingReq.received += toInsert
|
|
||||||
|
|
||||||
if (remaining.isEmpty) {
|
if (remaining.isEmpty) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (craftingReq.amountPerSlot.sum() == 0 || craftingReq.received >= craftingReq.totalResultAmount) {
|
// if slots == 0, there are no more slots needing items for this request
|
||||||
|
if (craftingReq.slots == 0 || craftingReq.received >= craftingReq.totalResultAmount) {
|
||||||
completedCraftingStackRequests.remove(craftingReq)
|
completedCraftingStackRequests.remove(craftingReq)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +136,10 @@ class CraftingTerminalBlockEntity(pos: BlockPos, state: BlockState) :
|
||||||
stack: ItemStack,
|
stack: ItemStack,
|
||||||
amount: Int,
|
amount: Int,
|
||||||
timestamp: Long,
|
timestamp: Long,
|
||||||
val amountPerSlot: IntArray,
|
/**
|
||||||
|
* Values are bitfields of which slots in the crafting inventory this request is for.
|
||||||
|
*/
|
||||||
|
var slots: Int,
|
||||||
) : StackLocateRequest(stack, amount, timestamp) {
|
) : StackLocateRequest(stack, amount, timestamp) {
|
||||||
var received: Int = 0
|
var received: Int = 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,7 @@ import net.minecraft.network.PacketByteBuf
|
||||||
import net.shadowfacts.phycon.PhysicalConnectivityClient
|
import net.shadowfacts.phycon.PhysicalConnectivityClient
|
||||||
import net.shadowfacts.phycon.block.terminal.AbstractTerminalBlockEntity
|
import net.shadowfacts.phycon.block.terminal.AbstractTerminalBlockEntity
|
||||||
import net.shadowfacts.phycon.block.terminal.AbstractTerminalScreenHandler
|
import net.shadowfacts.phycon.block.terminal.AbstractTerminalScreenHandler
|
||||||
import net.shadowfacts.phycon.util.TerminalSettings
|
import net.shadowfacts.phycon.util.*
|
||||||
import net.shadowfacts.phycon.util.readItemStackWithoutCount
|
|
||||||
import net.shadowfacts.phycon.util.writeItemStackWithoutCount
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author shadowfacts
|
* @author shadowfacts
|
||||||
|
@ -35,7 +33,7 @@ object S2CTerminalUpdateDisplayedItems : ClientReceiver {
|
||||||
|
|
||||||
buf.writeVarInt(entries.size)
|
buf.writeVarInt(entries.size)
|
||||||
for (e in entries) {
|
for (e in entries) {
|
||||||
buf.writeItemStackWithoutCount(e.stack)
|
buf.writeItemVariant(e.variant)
|
||||||
buf.writeVarInt(e.amount)
|
buf.writeVarInt(e.amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +56,7 @@ object S2CTerminalUpdateDisplayedItems : ClientReceiver {
|
||||||
val entryCount = buf.readVarInt()
|
val entryCount = buf.readVarInt()
|
||||||
val entries = ArrayList<AbstractTerminalScreenHandler.Entry>(entryCount)
|
val entries = ArrayList<AbstractTerminalScreenHandler.Entry>(entryCount)
|
||||||
for (i in 0 until entryCount) {
|
for (i in 0 until entryCount) {
|
||||||
entries.add(AbstractTerminalScreenHandler.Entry(buf.readItemStackWithoutCount(), buf.readVarInt()))
|
entries.add(AbstractTerminalScreenHandler.Entry(buf.readItemVariant(), buf.readVarInt()))
|
||||||
}
|
}
|
||||||
val query = buf.readString()
|
val query = buf.readString()
|
||||||
PhysicalConnectivityClient.terminalSettings.fromTag(buf.readNbt()!!)
|
PhysicalConnectivityClient.terminalSettings.fromTag(buf.readNbt()!!)
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
package net.shadowfacts.phycon.util
|
|
||||||
|
|
||||||
import net.minecraft.item.ItemStack
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author shadowfacts
|
|
||||||
*/
|
|
||||||
fun ItemStack.copyWithCount(count: Int): ItemStack {
|
|
||||||
return copy().also { it.count = count }
|
|
||||||
}
|
|
|
@ -6,6 +6,10 @@ import net.minecraft.item.ItemStack
|
||||||
* @author shadowfacts
|
* @author shadowfacts
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
fun ItemStack.copyWithCount(count: Int): ItemStack {
|
||||||
|
return copy().also { it.count = count }
|
||||||
|
}
|
||||||
|
|
||||||
fun ItemStack.equalsIgnoringAmount(other: ItemStack): Boolean {
|
fun ItemStack.equalsIgnoringAmount(other: ItemStack): Boolean {
|
||||||
if (this.isEmpty) return other.isEmpty
|
if (this.isEmpty) return other.isEmpty
|
||||||
if (other.isEmpty) return false
|
if (other.isEmpty) return false
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
package net.shadowfacts.phycon.util
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.text.Text
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author shadowfacts
|
||||||
|
*/
|
||||||
|
|
||||||
|
val ItemVariant.name: Text
|
||||||
|
get() {
|
||||||
|
// don't use toStack because that copies the NBT
|
||||||
|
// we assume that items don't mutate NBT in getName
|
||||||
|
val stack = ItemStack(this.item, 1)
|
||||||
|
stack.nbt = this.nbt
|
||||||
|
return item.getName(stack)
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package net.shadowfacts.phycon.util
|
package net.shadowfacts.phycon.util
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant
|
||||||
import net.minecraft.item.Item
|
import net.minecraft.item.Item
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.nbt.NbtCompound
|
import net.minecraft.nbt.NbtCompound
|
||||||
|
@ -35,3 +36,11 @@ fun PacketByteBuf.readItemStackWithoutCount(): ItemStack {
|
||||||
stack
|
stack
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun PacketByteBuf.writeItemVariant(variant: ItemVariant) {
|
||||||
|
variant.toPacket(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun PacketByteBuf.readItemVariant(): ItemVariant {
|
||||||
|
return ItemVariant.fromPacket(this)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue