145 lines
4.0 KiB
Kotlin
145 lines
4.0 KiB
Kotlin
package net.shadowfacts.phycon.network.block.terminal
|
|
|
|
import alexiil.mc.lib.attributes.item.GroupedItemInv
|
|
import alexiil.mc.lib.attributes.item.ItemStackCollections
|
|
import net.fabricmc.fabric.api.block.entity.BlockEntityClientSerializable
|
|
import net.fabricmc.fabric.api.container.ContainerProviderRegistry
|
|
import net.minecraft.entity.player.PlayerEntity
|
|
import net.minecraft.inventory.BasicInventory
|
|
import net.minecraft.inventory.Inventory
|
|
import net.minecraft.inventory.InventoryListener
|
|
import net.minecraft.item.ItemStack
|
|
import net.minecraft.nbt.CompoundTag
|
|
import net.minecraft.nbt.ListTag
|
|
import net.shadowfacts.phycon.api.packet.Packet
|
|
import net.shadowfacts.phycon.api.util.MACAddress
|
|
import net.shadowfacts.phycon.init.PhyBlockEntities
|
|
import net.shadowfacts.phycon.network.DeviceBlockEntity
|
|
import net.shadowfacts.phycon.network.packet.DeviceRemovedPacket
|
|
import net.shadowfacts.phycon.network.packet.ReadInventoryPacket
|
|
import net.shadowfacts.phycon.network.packet.RequestInventoryPacket
|
|
import net.shadowfacts.phycon.util.fromTag
|
|
import net.shadowfacts.phycon.util.toTag
|
|
|
|
/**
|
|
* @author shadowfacts
|
|
*/
|
|
class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL), InventoryListener, BlockEntityClientSerializable {
|
|
|
|
private val inventoryCache = mutableMapOf<MACAddress, GroupedItemInv>()
|
|
val internalBuffer = BasicInventory(18)
|
|
|
|
private var observers = 0
|
|
val cachedNetItems = ItemStackCollections.intMap()
|
|
var cachedSortedNetItems = listOf<ItemStack>()
|
|
var counter = 0
|
|
|
|
init {
|
|
internalBuffer.addListener(this)
|
|
}
|
|
|
|
override fun handlePacket(packet: Packet) {
|
|
when (packet) {
|
|
is ReadInventoryPacket -> handleReadInventory(packet)
|
|
is DeviceRemovedPacket -> handleDeviceRemoved(packet)
|
|
}
|
|
}
|
|
|
|
private fun handleReadInventory(packet: ReadInventoryPacket) {
|
|
inventoryCache[packet.source] = packet.inventory
|
|
}
|
|
|
|
private fun handleDeviceRemoved(packet: DeviceRemovedPacket) {
|
|
inventoryCache.remove(packet.source)
|
|
}
|
|
|
|
private fun updateNetItems() {
|
|
cachedNetItems.clear()
|
|
for (inventory in inventoryCache.values) {
|
|
for (stack in inventory.storedStacks) {
|
|
val amount = inventory.getAmount(stack)
|
|
cachedNetItems.mergeInt(stack, amount) { a, b -> a + b }
|
|
}
|
|
}
|
|
}
|
|
|
|
fun addObserver() {
|
|
observers++
|
|
}
|
|
|
|
fun removeObserver() {
|
|
observers--
|
|
}
|
|
|
|
override fun tick() {
|
|
super.tick()
|
|
|
|
if (observers > 0 && (++counter % 20) == 0) {
|
|
counter = 0
|
|
if (world!!.isClient) {
|
|
println(cachedNetItems)
|
|
} else {
|
|
updateNetItems()
|
|
sync()
|
|
}
|
|
}
|
|
}
|
|
|
|
fun onActivate(player: PlayerEntity) {
|
|
if (!world!!.isClient) {
|
|
inventoryCache.clear()
|
|
enqueueToSingle(RequestInventoryPacket(macAddress))
|
|
ContainerProviderRegistry.INSTANCE.openContainer(TerminalContainer.ID, player) { buf ->
|
|
buf.writeBlockPos(pos)
|
|
}
|
|
}
|
|
addObserver()
|
|
}
|
|
|
|
override fun onInvChange(inv: Inventory) {
|
|
if (inv == internalBuffer) {
|
|
markDirty()
|
|
sync()
|
|
}
|
|
}
|
|
|
|
override fun toTag(tag: CompoundTag): CompoundTag {
|
|
tag.put("InternalBuffer", internalBuffer.toTag())
|
|
return super.toTag(tag)
|
|
}
|
|
|
|
override fun fromTag(tag: CompoundTag) {
|
|
super.fromTag(tag)
|
|
internalBuffer.fromTag(tag.getList("InternalBuffer", 10))
|
|
}
|
|
|
|
override fun toClientTag(tag: CompoundTag): CompoundTag {
|
|
tag.put("InternalBuffer", internalBuffer.toTag())
|
|
val list = ListTag()
|
|
tag.put("CachedNetItems", list)
|
|
for ((stack, amount) in cachedNetItems) {
|
|
val entryTag = stack.toTag(CompoundTag())
|
|
entryTag.putInt("NetAmount", amount)
|
|
list.add(entryTag)
|
|
}
|
|
return tag
|
|
}
|
|
|
|
override fun fromClientTag(tag: CompoundTag) {
|
|
internalBuffer.fromTag(tag.getList("InternalBuffer", 10))
|
|
val list = tag.getList("CachedNetItems", 10)
|
|
cachedNetItems.clear()
|
|
for (entryTag in list) {
|
|
val stack = ItemStack.fromTag(entryTag as CompoundTag)
|
|
val netAmount = entryTag.getInt("NetAmount")
|
|
cachedNetItems[stack] = netAmount
|
|
}
|
|
cachedSortedNetItems = cachedNetItems.object2IntEntrySet().sortedByDescending { it.intValue }.map {
|
|
val stack = it.key.copy()
|
|
stack.count = it.intValue
|
|
stack
|
|
}
|
|
}
|
|
|
|
}
|