Remove LibBlockAttributes ItemStackCollections use

This commit is contained in:
Shadowfacts 2024-07-14 15:43:56 -07:00
parent d782d43e1b
commit 7e71a1e03d
8 changed files with 66 additions and 43 deletions

View File

@ -1,6 +1,6 @@
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.storage.Storage
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 dispatchStackTimeout = INSERTION_TIMEOUT
// TODO: need a ItemVariant -> Int/Long map
val cachedNetItems = ItemStackCollections.intMap()
val cachedNetItems = Object2IntOpenHashMap<ItemVariant>()
private var requestInventoryTimestamp: Long? = null
// todo: multiple players could have the terminal open simultaneously
@ -142,7 +141,7 @@ abstract class AbstractTerminalBlockEntity(type: BlockEntityType<*>, pos: BlockP
val transaction = Transaction.openOuter()
for (view in inventory.iterator(transaction)) {
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()
}

View File

@ -1,24 +1,20 @@
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.SlotActionType
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.entity.player.PlayerInventory
import net.minecraft.item.ItemStack
import net.minecraft.network.PacketByteBuf
import net.minecraft.screen.ScreenHandler
import net.minecraft.screen.ScreenHandlerType
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.Identifier
import net.minecraft.util.registry.Registry
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.util.SortMode
import net.shadowfacts.phycon.util.TerminalSettings
import net.shadowfacts.phycon.util.copyWithCount
import net.shadowfacts.phycon.util.name
import java.lang.ref.WeakReference
import kotlin.math.ceil
import kotlin.math.max
@ -49,7 +45,7 @@ abstract class AbstractTerminalScreenHandler<T : AbstractTerminalBlockEntity>(
field = value
if (terminal.world!!.isClient) {
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
}
}
// 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)
}
@ -273,5 +271,5 @@ abstract class AbstractTerminalScreenHandler<T : AbstractTerminalBlockEntity>(
fun isBufferSlot(id: Int) = id in bufferSlotsStart until 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)
}

View File

@ -1,7 +1,9 @@
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.transfer.v1.item.ItemVariant
import net.minecraft.block.BlockState
import net.minecraft.entity.player.PlayerEntity
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.toTag
import java.util.LinkedList
import kotlin.math.min
/**
* @author shadowfacts
@ -52,20 +53,23 @@ class CraftingTerminalBlockEntity(pos: BlockPos, state: BlockState) :
}
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()) {
val craftingInvStack = craftingInv.getStack(i)
if (craftingInvStack.isEmpty) continue
if (craftingInvStack.count >= craftingInvStack.maxCount) continue
if (craftingInvStack !in amounts) amounts[craftingInvStack] = IntArray(9) { 0 }
amounts[craftingInvStack]!![i] = min(maxAmount, craftingInvStack.maxCount - craftingInvStack.count)
stackToSlotsMap.mergeInt(ItemVariant.of(craftingInvStack), 1 shl i, or)
}
for ((stack, amountPerSlot) in amounts) {
val total = amountPerSlot.sum()
val request = CraftingStackLocateRequest(stack, total, counter, amountPerSlot)
for ((variant, slots) in stackToSlotsMap) {
val total = slots.countOneBits()
val stack = variant.toStack()
val request = CraftingStackLocateRequest(stack, total, counter, slots)
pendingRequests.add(request)
sendPacket(LocateStackPacket(stack, ipAddress))
}
@ -90,19 +94,19 @@ class CraftingTerminalBlockEntity(pos: BlockPos, state: BlockState) :
if (currentStack.count >= currentStack.maxCount) continue
if (!currentStack.equalsIgnoringAmount(remaining)) continue
val toInsert =
minOf(remaining.count, currentStack.maxCount - currentStack.count, craftingReq.amountPerSlot[i])
currentStack.count += toInsert
remaining.count -= toInsert
craftingReq.amountPerSlot[i] -= toInsert
craftingReq.received += toInsert
currentStack.count += 1
remaining.count -= 1
craftingReq.slots = craftingReq.slots and (1 shl i).inv()
craftingReq.received += 1
if (remaining.isEmpty) {
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)
}
@ -132,7 +136,10 @@ class CraftingTerminalBlockEntity(pos: BlockPos, state: BlockState) :
stack: ItemStack,
amount: Int,
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) {
var received: Int = 0
}

View File

@ -10,9 +10,7 @@ import net.minecraft.network.PacketByteBuf
import net.shadowfacts.phycon.PhysicalConnectivityClient
import net.shadowfacts.phycon.block.terminal.AbstractTerminalBlockEntity
import net.shadowfacts.phycon.block.terminal.AbstractTerminalScreenHandler
import net.shadowfacts.phycon.util.TerminalSettings
import net.shadowfacts.phycon.util.readItemStackWithoutCount
import net.shadowfacts.phycon.util.writeItemStackWithoutCount
import net.shadowfacts.phycon.util.*
/**
* @author shadowfacts
@ -35,7 +33,7 @@ object S2CTerminalUpdateDisplayedItems : ClientReceiver {
buf.writeVarInt(entries.size)
for (e in entries) {
buf.writeItemStackWithoutCount(e.stack)
buf.writeItemVariant(e.variant)
buf.writeVarInt(e.amount)
}
@ -58,7 +56,7 @@ object S2CTerminalUpdateDisplayedItems : ClientReceiver {
val entryCount = buf.readVarInt()
val entries = ArrayList<AbstractTerminalScreenHandler.Entry>(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()
PhysicalConnectivityClient.terminalSettings.fromTag(buf.readNbt()!!)

View File

@ -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 }
}

View File

@ -6,6 +6,10 @@ import net.minecraft.item.ItemStack
* @author shadowfacts
*/
fun ItemStack.copyWithCount(count: Int): ItemStack {
return copy().also { it.count = count }
}
fun ItemStack.equalsIgnoringAmount(other: ItemStack): Boolean {
if (this.isEmpty) return other.isEmpty
if (other.isEmpty) return false

View File

@ -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)
}

View File

@ -1,5 +1,6 @@
package net.shadowfacts.phycon.util
import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant
import net.minecraft.item.Item
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NbtCompound
@ -35,3 +36,11 @@ fun PacketByteBuf.readItemStackWithoutCount(): ItemStack {
stack
}
}
fun PacketByteBuf.writeItemVariant(variant: ItemVariant) {
variant.toPacket(this)
}
fun PacketByteBuf.readItemVariant(): ItemVariant {
return ItemVariant.fromPacket(this)
}