diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt index 24d1d97be..4e38d1cf2 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt @@ -1,5 +1,6 @@ package ru.dbotthepony.mc.otm.container +import it.unimi.dsi.fastutil.ints.IntAVLTreeSet import net.minecraft.world.item.ItemStack import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.ListTag @@ -9,6 +10,7 @@ import kotlin.jvm.JvmOverloads import net.minecraft.world.entity.player.Player import net.minecraft.world.level.block.entity.BlockEntity import ru.dbotthepony.mc.otm.core.ifHas +import ru.dbotthepony.mc.otm.core.set import java.util.* @Suppress("UNUSED") @@ -59,7 +61,7 @@ open class MatteryContainer(val watcher: Runnable, private val size: Int) : Cont setChanged() } - fun deserializeNBT(tag: ListTag?) { + private fun deserializeNBT(tag: ListTag?) { Arrays.fill(slots, ItemStack.EMPTY) if (tag == null) { @@ -67,8 +69,39 @@ open class MatteryContainer(val watcher: Runnable, private val size: Int) : Cont return } + var isIndexed = true + for (i in 0 until tag.size.coerceAtMost(size)) { - slots[i] = ItemStack.of(tag[i] as CompoundTag) + if (!(tag[i] as CompoundTag).contains("slotIndex")) { + isIndexed = false + break + } + } + + if (isIndexed) { + val freeSlots = IntAVLTreeSet() + + for (i in 0 until size) + freeSlots.add(i) + + for (i in 0 until tag.size.coerceAtMost(size)) { + val nbt = tag[i] as CompoundTag + var slotID = nbt.getInt("slotIndex") + + if (freeSlots.remove(slotID)) { + slots[slotID] = ItemStack.of(nbt) + } else if (freeSlots.isEmpty()) { + break + } else { + slotID = freeSlots.firstInt() + freeSlots.remove(slotID) + slots[slotID] = ItemStack.of(nbt) + } + } + } else { + for (i in 0 until tag.size.coerceAtMost(size)) { + slots[i] = ItemStack.of(tag[i] as CompoundTag) + } } setChanged() @@ -91,8 +124,12 @@ open class MatteryContainer(val watcher: Runnable, private val size: Int) : Cont fun serializeNBT(): ListTag { return ListTag().also { - for (i in 0 until size) { - it.add(this[i].serializeNBT()) + for ((i, item) in slots.withIndex()) { + if (!item.isEmpty) { + it.add(item.serializeNBT().also { + it["slotIndex"] = i + }) + } } } }