PhysicalConnectivity/src/main/kotlin/net/shadowfacts/phycon/block/terminal/TerminalBufferInventory.kt

89 lines
2.1 KiB
Kotlin

package net.shadowfacts.phycon.block.terminal
import alexiil.mc.lib.attributes.item.ItemStackUtil
import net.minecraft.inventory.SimpleInventory
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NbtCompound
import net.minecraft.nbt.NbtIntArray
import net.shadowfacts.phycon.util.fromTag
import net.shadowfacts.phycon.util.toTag
import kotlin.math.min
/**
* @author shadowfacts
*/
class TerminalBufferInventory(size: Int): SimpleInventory(size) {
enum class Mode {
TO_NETWORK, FROM_NETWORK, UNASSIGNED
}
var modes = Array(size) { Mode.UNASSIGNED }
private set
fun toTag(): NbtCompound {
val compound = NbtCompound()
compound.put("Inventory", (this as SimpleInventory).toTag())
compound.put("Modes", NbtIntArray(modes.map(Mode::ordinal)))
return compound
}
fun fromTag(tag: NbtCompound) {
val inventory = tag.getList("Inventory", 10)
(this as SimpleInventory).fromTag(inventory)
tag.getIntArray("Modes").forEachIndexed { i, it -> modes[i] = Mode.values()[it] }
}
fun insert(stack: ItemStack, mode: Mode): ItemStack {
var remaining = stack.copy()
for (slot in 0 until size()) {
if (modes[slot] != mode && modes[slot] != Mode.UNASSIGNED) continue
remaining = tryInsert(stack, slot, mode)
if (remaining.isEmpty) {
break
}
}
return remaining
}
private fun tryInsert(stack: ItemStack, slot: Int, mode: Mode): ItemStack {
val current = getStack(slot)
if (current.isEmpty) {
setStack(slot, stack)
markSlot(slot, mode)
return ItemStack.EMPTY
} else if (ItemStackUtil.areEqualIgnoreAmounts(stack, current)) {
val toTransfer = min(current.maxCount - current.count, stack.count)
current.count += toTransfer
stack.count -= toTransfer
markSlot(slot, mode)
return stack
} else {
return stack
}
}
override fun setStack(slot: Int, stack: ItemStack) {
if (stack.isEmpty) {
modes[slot] = Mode.UNASSIGNED
}
super.setStack(slot, stack)
}
override fun clear() {
super.clear()
this.modes = Array(size()) { Mode.UNASSIGNED }
}
fun getMode(slot: Int): Mode {
return modes[slot]
}
fun markSlot(slot: Int, mode: Mode) {
modes[slot] = mode
}
}