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 } }