136 lines
4.3 KiB
Kotlin
136 lines
4.3 KiB
Kotlin
package net.shadowfacts.phycon.block.netinterface
|
|
|
|
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.block.BlockState
|
|
import net.minecraft.item.ItemStack
|
|
import net.minecraft.nbt.NbtCompound
|
|
import net.minecraft.util.math.BlockPos
|
|
import net.minecraft.util.math.Direction
|
|
import net.shadowfacts.phycon.api.packet.Packet
|
|
import net.shadowfacts.phycon.init.PhyBlockEntities
|
|
import net.shadowfacts.phycon.block.DeviceBlockEntity
|
|
import net.shadowfacts.phycon.block.FaceDeviceBlock
|
|
import net.shadowfacts.phycon.component.ItemStackPacketHandler
|
|
import net.shadowfacts.phycon.component.NetworkStackProvider
|
|
import net.shadowfacts.phycon.component.NetworkStackReceiver
|
|
import net.shadowfacts.phycon.component.handleItemStack
|
|
import net.shadowfacts.phycon.packet.*
|
|
import net.shadowfacts.phycon.util.ClientConfigurableDevice
|
|
import kotlin.math.min
|
|
|
|
/**
|
|
* @author shadowfacts
|
|
*/
|
|
class InterfaceBlockEntity(pos: BlockPos, state: BlockState): DeviceBlockEntity(PhyBlockEntities.INTERFACE, pos, state),
|
|
ItemStackPacketHandler,
|
|
NetworkStackProvider,
|
|
NetworkStackReceiver,
|
|
ClientConfigurableDevice {
|
|
|
|
private val facing: Direction
|
|
get() = cachedState[FaceDeviceBlock.FACING]
|
|
|
|
override var providerPriority = 0
|
|
override var receiverPriority = 0
|
|
var syncPriorities = true
|
|
|
|
// todo: should this be a weak ref?
|
|
private var inventory: GroupedItemInv? = null
|
|
|
|
fun updateInventory() {
|
|
val offsetPos = pos.offset(facing)
|
|
val option = SearchOptions.inDirection(facing)
|
|
inventory = ItemAttributes.GROUPED_INV.getFirstOrNull(world, offsetPos, option)
|
|
}
|
|
|
|
private fun getInventory(): GroupedItemInv? {
|
|
// if we don't have an inventory, try to get one
|
|
// this happens when readAll is called before a neighbor state changes, such as immediately after world load
|
|
if (inventory == null) updateInventory()
|
|
return inventory
|
|
}
|
|
|
|
override fun handle(packet: Packet) {
|
|
when (packet) {
|
|
is RequestInventoryPacket -> handleRequestInventory(packet)
|
|
is LocateStackPacket -> handleLocateStack(packet)
|
|
is ExtractStackPacket -> handleExtractStack(packet)
|
|
is CheckCapacityPacket -> handleCheckCapacity(packet)
|
|
is ItemStackPacket -> handleItemStack(packet)
|
|
}
|
|
}
|
|
|
|
private fun handleRequestInventory(packet: RequestInventoryPacket) {
|
|
getInventory()?.also { inv ->
|
|
sendPacket(ReadInventoryPacket(inv, ipAddress, packet.source))
|
|
}
|
|
}
|
|
|
|
private fun handleLocateStack(packet: LocateStackPacket) {
|
|
getInventory()?.also { inv ->
|
|
val amount = inv.getAmount(packet.stack)
|
|
sendPacket(StackLocationPacket(packet.stack, amount, this, ipAddress, packet.source))
|
|
}
|
|
}
|
|
|
|
private fun handleExtractStack(packet: ExtractStackPacket) {
|
|
getInventory()?.also { inv ->
|
|
var amount = packet.amount
|
|
while (amount > 0) {
|
|
val extracted = inv.extract(packet.stack, min(amount, packet.stack.maxCount))
|
|
if (extracted.isEmpty) {
|
|
break
|
|
} else {
|
|
amount -= extracted.count
|
|
sendPacket(ItemStackPacket(extracted, ipAddress, packet.source))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun handleCheckCapacity(packet: CheckCapacityPacket) {
|
|
getInventory()?.also { inv ->
|
|
val remaining = inv.attemptInsertion(packet.stack, Simulation.SIMULATE)
|
|
val couldAccept = packet.stack.count - remaining.count
|
|
sendPacket(CapacityPacket(packet.stack, couldAccept, this, ipAddress, packet.source))
|
|
}
|
|
}
|
|
|
|
override fun doHandleItemStack(packet: ItemStackPacket): ItemStack {
|
|
val inventory = getInventory()
|
|
if (inventory != null) {
|
|
val remaining = inventory.insert(packet.stack)
|
|
// whatever could not be inserted will be sent back to the packet's source
|
|
return remaining
|
|
} else {
|
|
return packet.stack
|
|
}
|
|
}
|
|
|
|
override fun toCommonTag(tag: NbtCompound) {
|
|
super.toCommonTag(tag)
|
|
writeDeviceConfiguration(tag)
|
|
}
|
|
|
|
override fun fromCommonTag(tag: NbtCompound) {
|
|
super.fromCommonTag(tag)
|
|
loadDeviceConfiguration(tag)
|
|
}
|
|
|
|
override fun writeDeviceConfiguration(tag: NbtCompound) {
|
|
tag.putInt("ProviderPriority", providerPriority)
|
|
tag.putInt("ReceiverPriority", receiverPriority)
|
|
tag.putBoolean("SyncPriorities", syncPriorities)
|
|
}
|
|
|
|
override fun loadDeviceConfiguration(tag: NbtCompound) {
|
|
providerPriority = tag.getInt("ProviderPriority")
|
|
receiverPriority = tag.getInt("ReceiverPriority")
|
|
syncPriorities = tag.getBoolean("SyncPriorities")
|
|
}
|
|
|
|
}
|