Send remainder of partially-inserted stacks back to source
This commit is contained in:
parent
d61ed8b7cc
commit
26134cea9d
|
@ -0,0 +1,15 @@
|
|||
package net.shadowfacts.phycon.api;
|
||||
|
||||
import net.shadowfacts.phycon.api.packet.Packet;
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
public interface PacketSource {
|
||||
// todo: better name for this
|
||||
void sendToSingle(Packet packet);
|
||||
|
||||
void sendToAll(Packet packet);
|
||||
|
||||
void sendToAll(Packet packet, Iterable<PacketSink> destinations);
|
||||
}
|
|
@ -4,18 +4,16 @@ import net.minecraft.block.BlockState
|
|||
import net.minecraft.block.entity.BlockEntity
|
||||
import net.minecraft.block.entity.BlockEntityType
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.util.Tickable
|
||||
import net.shadowfacts.phycon.api.PacketSink
|
||||
import net.shadowfacts.phycon.api.PacketSource
|
||||
import net.shadowfacts.phycon.api.packet.Packet
|
||||
import net.shadowfacts.phycon.api.util.MACAddress
|
||||
import net.shadowfacts.phycon.network.packet.DeviceRemovedPacket
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
abstract class DeviceBlockEntity(type: BlockEntityType<*>): BlockEntity(type), PacketSink {
|
||||
abstract class DeviceBlockEntity(type: BlockEntityType<*>): BlockEntity(type), PacketSink, PacketSource {
|
||||
|
||||
var macAddress = MACAddress.random()
|
||||
protected set
|
||||
|
@ -48,8 +46,7 @@ abstract class DeviceBlockEntity(type: BlockEntityType<*>): BlockEntity(type), P
|
|||
destination.handle(packet)
|
||||
}
|
||||
|
||||
// todo: better name for this
|
||||
fun sendToSingle(packet: Packet) {
|
||||
override fun sendToSingle(packet: Packet) {
|
||||
val destinations = NetworkUtil.findDestinations(world!!, pos)
|
||||
if (destinations.size != 1) {
|
||||
// todo: handle this better
|
||||
|
@ -59,11 +56,11 @@ abstract class DeviceBlockEntity(type: BlockEntityType<*>): BlockEntity(type), P
|
|||
send(packet, destinations.first())
|
||||
}
|
||||
|
||||
fun sendToAll(packet: Packet) {
|
||||
override fun sendToAll(packet: Packet) {
|
||||
sendToAll(packet, NetworkUtil.findDestinations(world!!, pos))
|
||||
}
|
||||
|
||||
fun sendToAll(packet: Packet, destinations: Iterable<PacketSink>) {
|
||||
override fun sendToAll(packet: Packet, destinations: Iterable<PacketSink>) {
|
||||
destinations.forEach {
|
||||
it.handle(packet)
|
||||
}
|
||||
|
|
|
@ -4,17 +4,19 @@ import alexiil.mc.lib.attributes.SearchOptions
|
|||
import alexiil.mc.lib.attributes.Simulation
|
||||
import alexiil.mc.lib.attributes.item.GroupedItemInv
|
||||
import alexiil.mc.lib.attributes.item.ItemAttributes
|
||||
import net.minecraft.entity.ItemEntity
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.util.math.Direction
|
||||
import net.shadowfacts.phycon.api.packet.Packet
|
||||
import net.shadowfacts.phycon.init.PhyBlockEntities
|
||||
import net.shadowfacts.phycon.network.DeviceBlockEntity
|
||||
import net.shadowfacts.phycon.network.component.ItemStackPacketHandler
|
||||
import net.shadowfacts.phycon.network.component.handleItemStack
|
||||
import net.shadowfacts.phycon.network.packet.*
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
class InterfaceBlockEntity: DeviceBlockEntity(PhyBlockEntities.INTERFACE) {
|
||||
class InterfaceBlockEntity: DeviceBlockEntity(PhyBlockEntities.INTERFACE), ItemStackPacketHandler {
|
||||
|
||||
private val facing: Direction
|
||||
get() = world!!.getBlockState(pos)[InterfaceBlock.FACING]
|
||||
|
@ -73,21 +75,14 @@ class InterfaceBlockEntity: DeviceBlockEntity(PhyBlockEntities.INTERFACE) {
|
|||
}
|
||||
}
|
||||
|
||||
private fun handleItemStack(packet: ItemStackPacket) {
|
||||
override fun doHandleItemStack(packet: ItemStackPacket): ItemStack {
|
||||
val inventory = getInventory()
|
||||
if (inventory != null) {
|
||||
val remaining = inventory.insert(packet.stack)
|
||||
if (!remaining.isEmpty) {
|
||||
// todo: should this send whatever was left back to the terminal instead of dropping it?
|
||||
// todo: calculate entity spawn point by finding non-obstructed location
|
||||
val entity = ItemEntity(world!!, pos.x.toDouble(), pos.y + 1.0, pos.z.toDouble(), remaining)
|
||||
world!!.spawnEntity(entity)
|
||||
}
|
||||
// whatever could not be inserted will be sent back to the packet's source
|
||||
return remaining
|
||||
} else {
|
||||
// todo: should the stack back to the terminal instead of dropping it?
|
||||
// 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)
|
||||
return packet.stack
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap
|
|||
import net.fabricmc.fabric.api.block.entity.BlockEntityClientSerializable
|
||||
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.entity.ItemEntity
|
||||
import net.minecraft.entity.player.PlayerEntity
|
||||
import net.minecraft.entity.player.PlayerInventory
|
||||
import net.minecraft.inventory.Inventory
|
||||
|
@ -25,6 +24,8 @@ import net.shadowfacts.phycon.api.util.MACAddress
|
|||
import net.shadowfacts.phycon.init.PhyBlockEntities
|
||||
import net.shadowfacts.phycon.network.DeviceBlockEntity
|
||||
import net.shadowfacts.phycon.network.block.netinterface.InterfaceBlockEntity
|
||||
import net.shadowfacts.phycon.network.component.ItemStackPacketHandler
|
||||
import net.shadowfacts.phycon.network.component.handleItemStack
|
||||
import net.shadowfacts.phycon.network.packet.*
|
||||
import java.util.*
|
||||
import kotlin.math.min
|
||||
|
@ -32,7 +33,7 @@ import kotlin.math.min
|
|||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL), InventoryChangedListener, BlockEntityClientSerializable, Tickable {
|
||||
class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL), InventoryChangedListener, BlockEntityClientSerializable, Tickable, ItemStackPacketHandler {
|
||||
|
||||
companion object {
|
||||
val LOCATE_REQUEST_TIMEOUT = 40 // ticks
|
||||
|
@ -89,18 +90,15 @@ class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL), Invento
|
|||
}
|
||||
}
|
||||
|
||||
private fun handleItemStack(packet: ItemStackPacket) {
|
||||
override fun doHandleItemStack(packet: ItemStackPacket): ItemStack {
|
||||
val remaining = internalBuffer.insertFromNetwork(packet.stack)
|
||||
if (!remaining.isEmpty) {
|
||||
// todo: calculate entity spawn point by finding non-obstructed location
|
||||
val entity = ItemEntity(world!!, pos.x.toDouble(), pos.y + 1.0, pos.z.toDouble(), remaining)
|
||||
world!!.spawnEntity(entity)
|
||||
}
|
||||
|
||||
// this happens outside the normal update loop because by receiving the item stack packet
|
||||
// we "know" how much the count in the source inventory has changed
|
||||
updateNetItems()
|
||||
sync()
|
||||
|
||||
return remaining
|
||||
}
|
||||
|
||||
private fun handleCapacity(packet: CapacityPacket) {
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package net.shadowfacts.phycon.network.component
|
||||
|
||||
import net.minecraft.block.entity.BlockEntity
|
||||
import net.minecraft.entity.ItemEntity
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.shadowfacts.phycon.api.PacketSink
|
||||
import net.shadowfacts.phycon.api.PacketSource
|
||||
import net.shadowfacts.phycon.network.packet.ItemStackPacket
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
interface ItemStackPacketHandler: PacketSink, PacketSource {
|
||||
fun doHandleItemStack(packet: ItemStackPacket): ItemStack
|
||||
}
|
||||
|
||||
fun <BE> BE.handleItemStack(packet: ItemStackPacket) where BE: BlockEntity, BE: 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)
|
||||
return
|
||||
}
|
||||
val remainder = doHandleItemStack(packet)
|
||||
// if there are any items remaining, send them back to the source with incremented bounce count
|
||||
if (!remainder.isEmpty) {
|
||||
sendToSingle(ItemStackPacket(remainder, packet.bounceCount + 1, macAddress, packet.source))
|
||||
}
|
||||
}
|
|
@ -6,5 +6,6 @@ import net.shadowfacts.phycon.api.util.MACAddress
|
|||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
class ItemStackPacket(val stack: ItemStack, source: MACAddress, destination: MACAddress): BasePacket(source, destination) {
|
||||
class ItemStackPacket(val stack: ItemStack, val bounceCount: Int, source: MACAddress, destination: MACAddress): BasePacket(source, destination) {
|
||||
constructor(stack: ItemStack, source: MACAddress, destination: MACAddress): this(stack, 0, source, destination)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue