PhysicalConnectivity/src/main/kotlin/net/shadowfacts/phycon/block/netinterface/InterfaceBlockEntity.kt

136 lines
4.3 KiB
Kotlin
Raw Normal View History

2021-02-28 18:48:39 +00:00
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
2021-03-04 03:00:21 +00:00
import net.minecraft.block.BlockState
import net.minecraft.item.ItemStack
2021-12-22 23:59:51 +00:00
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
2021-02-28 18:48:39 +00:00
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.*
2021-03-04 03:00:21 +00:00
import net.shadowfacts.phycon.util.ClientConfigurableDevice
import kotlin.math.min
/**
* @author shadowfacts
*/
2021-12-22 23:59:51 +00:00
class InterfaceBlockEntity(pos: BlockPos, state: BlockState): DeviceBlockEntity(PhyBlockEntities.INTERFACE, pos, state),
2021-02-15 01:01:33 +00:00
ItemStackPacketHandler,
NetworkStackProvider,
2021-03-04 03:00:21 +00:00
NetworkStackReceiver,
ClientConfigurableDevice {
private val facing: Direction
get() = cachedState[FaceDeviceBlock.FACING]
2021-03-04 03:00:21 +00:00
override var providerPriority = 0
2021-03-04 04:13:09 +00:00
override var receiverPriority = 0
2021-03-05 00:44:31 +00:00
var syncPriorities = true
2021-03-04 03:00:21 +00:00
// 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
}
}
2021-12-22 23:59:51 +00:00
override fun toCommonTag(tag: NbtCompound) {
2021-03-04 03:00:21 +00:00
super.toCommonTag(tag)
writeDeviceConfiguration(tag)
}
2021-12-22 23:59:51 +00:00
override fun fromCommonTag(tag: NbtCompound) {
2021-03-04 03:00:21 +00:00
super.fromCommonTag(tag)
loadDeviceConfiguration(tag)
}
2021-12-22 23:59:51 +00:00
override fun writeDeviceConfiguration(tag: NbtCompound) {
2021-03-04 03:00:21 +00:00
tag.putInt("ProviderPriority", providerPriority)
2021-03-04 04:13:09 +00:00
tag.putInt("ReceiverPriority", receiverPriority)
2021-03-05 00:44:31 +00:00
tag.putBoolean("SyncPriorities", syncPriorities)
2021-03-04 03:00:21 +00:00
}
2021-12-22 23:59:51 +00:00
override fun loadDeviceConfiguration(tag: NbtCompound) {
2021-03-04 03:00:21 +00:00
providerPriority = tag.getInt("ProviderPriority")
2021-03-04 04:13:09 +00:00
receiverPriority = tag.getInt("ReceiverPriority")
2021-03-05 00:44:31 +00:00
syncPriorities = tag.getBoolean("SyncPriorities")
2021-03-04 03:00:21 +00:00
}
}