From 8d1c2854f69df7c6b7547744420b1312927ceaa6 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Wed, 17 Feb 2021 22:39:37 -0500 Subject: [PATCH] Improve Miner handling of excess items --- .../network/block/miner/MinerBlockEntity.kt | 28 ++++++++++++++++--- .../component/ItemStackPacketHandler.kt | 12 +++++--- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/main/kotlin/net/shadowfacts/phycon/network/block/miner/MinerBlockEntity.kt b/src/main/kotlin/net/shadowfacts/phycon/network/block/miner/MinerBlockEntity.kt index f210534..40deab2 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/network/block/miner/MinerBlockEntity.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/network/block/miner/MinerBlockEntity.kt @@ -14,7 +14,11 @@ import net.shadowfacts.phycon.api.packet.Packet import net.shadowfacts.phycon.api.util.IPAddress import net.shadowfacts.phycon.init.PhyBlockEntities import net.shadowfacts.phycon.network.DeviceBlockEntity +import net.shadowfacts.phycon.network.block.terminal.TerminalBlockEntity +import net.shadowfacts.phycon.network.component.NetworkStackDispatcher import net.shadowfacts.phycon.network.component.NetworkStackProvider +import net.shadowfacts.phycon.network.component.handleItemStack +import net.shadowfacts.phycon.network.component.spawnItemStack import net.shadowfacts.phycon.network.packet.* import kotlin.math.min @@ -22,18 +26,24 @@ import kotlin.math.min * @author shadowfacts */ class MinerBlockEntity: DeviceBlockEntity(PhyBlockEntities.MINER), - NetworkStackProvider { + NetworkStackProvider, + NetworkStackDispatcher { private val facing: Direction get() = cachedState[MinerBlock.FACING] private val invProxy = MinerInvProxy(this) + override val pendingInsertions = mutableListOf() + override val dispatchStackTimeout = TerminalBlockEntity.INSERTION_TIMEOUT + override fun handle(packet: Packet) { when (packet) { is RequestInventoryPacket -> handleRequestInventory(packet) is LocateStackPacket -> handleLocateStack(packet) is ExtractStackPacket -> handleExtractStack(packet) + is CapacityPacket -> handleCapacity(packet) + is ItemStackPacket -> handleItemStack(packet) } } @@ -50,7 +60,7 @@ class MinerBlockEntity: DeviceBlockEntity(PhyBlockEntities.MINER), private fun handleExtractStack(packet: ExtractStackPacket) { // always recalculate immediately before breaking - val drops = invProxy.getDrops(true) + val drops = invProxy.getDrops(recalculate = true) if (invProxy.getAmount(packet.stack) > 0) { world!!.breakBlock(pos.offset(facing), false) @@ -77,11 +87,18 @@ class MinerBlockEntity: DeviceBlockEntity(PhyBlockEntities.MINER), // dump any remaining drops into the network for (droppedStack in drops) { if (droppedStack.isEmpty) continue - sendPacket(ItemStackPacket(droppedStack, ipAddress, IPAddress.BROADCAST)) + dispatchItemStack(droppedStack) } } } + override fun doHandleItemStack(packet: ItemStackPacket): ItemStack { + // miner can't receive stacks, so remaining is the entire packet stack + return packet.stack + } + + override fun createPendingInsertion(stack: ItemStack) = PendingInsertion(stack, counter) + class MinerInvProxy(val miner: MinerBlockEntity): GroupedItemInvView { private var cachedState: BlockState? = null private var cachedDrops: List? = null @@ -96,7 +113,7 @@ class MinerBlockEntity: DeviceBlockEntity(PhyBlockEntities.MINER), fun getDrops(recalculate: Boolean = false): List { val targetPos = pos.offset(facing) val realState = world.getBlockState(targetPos) - // todo: does BlockState.equals actually work? + // todo: does BlockState.equals actually work or is reference equality fine for BlockStates? if (cachedDrops == null || realState != cachedState || recalculate) { cachedState = realState val be = if (realState.block.hasBlockEntity()) world.getBlockEntity(targetPos) else null @@ -124,4 +141,7 @@ class MinerBlockEntity: DeviceBlockEntity(PhyBlockEntities.MINER), } } + class PendingInsertion(stack: ItemStack, timestamp: Long): NetworkStackDispatcher.PendingInsertion(stack, timestamp) { + } + } \ No newline at end of file diff --git a/src/main/kotlin/net/shadowfacts/phycon/network/component/ItemStackPacketHandler.kt b/src/main/kotlin/net/shadowfacts/phycon/network/component/ItemStackPacketHandler.kt index a049719..64e92f3 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/network/component/ItemStackPacketHandler.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/network/component/ItemStackPacketHandler.kt @@ -14,13 +14,11 @@ interface ItemStackPacketHandler: PacketSink, PacketSource { fun doHandleItemStack(packet: ItemStackPacket): ItemStack } -fun BE.handleItemStack(packet: ItemStackPacket) where BE: BlockEntity, BE: ItemStackPacketHandler { +fun Self.handleItemStack(packet: ItemStackPacket) where Self: BlockEntity, Self: ItemStackPacketHandler { // todo: is 5 a good number? // the max bounce count should always be odd, so the item is spawned in-world at the if (packet.bounceCount == 5) { - // todo: calculate entity spawn point by finding non-obstructed location - val entity = ItemEntity(world!!, pos.x.toDouble(), pos.y + 1.0, pos.z.toDouble(), packet.stack) - world!!.spawnEntity(entity) + spawnItemStack(packet.stack) return } val remainder = doHandleItemStack(packet) @@ -28,4 +26,10 @@ fun BE.handleItemStack(packet: ItemStackPacket) where BE: BlockEntity, BE: if (!remainder.isEmpty) { sendPacket(ItemStackPacket(remainder, packet.bounceCount + 1, ipAddress, packet.source)) } +} + +fun Self.spawnItemStack(stack: ItemStack) where Self: BlockEntity, Self: ItemStackPacketHandler { + // todo: calculate entity spawn point by finding non-obstructed location + val entity = ItemEntity(world!!, pos.x.toDouble(), pos.y + 1.0, pos.z.toDouble(), stack) + world!!.spawnEntity(entity) } \ No newline at end of file