Optimize Container.balance

This commit is contained in:
DBotThePony 2023-06-23 23:42:30 +07:00
parent 4f7c9ea176
commit dbf28efe89
Signed by: DBot
GPG Key ID: DCC23B5715498507

View File

@ -13,6 +13,7 @@ import net.minecraftforge.fluids.capability.IFluidHandler
import ru.dbotthepony.mc.otm.core.addAll
import ru.dbotthepony.mc.otm.core.collect.iterator
import ru.dbotthepony.mc.otm.core.collect.nonEmpty
import ru.dbotthepony.mc.otm.core.isNotEmpty
import kotlin.math.roundToInt
operator fun Container.set(index: Int, value: ItemStack) = setItem(index, value)
@ -119,7 +120,7 @@ inline fun Container.forEachNonEmpty(lambda: (ItemStack) -> Unit) {
}
fun Container.balance(slots: IntSet) {
if (slots.isEmpty()) return
if (slots.isEmpty() || !slots.any { getItem(it).isNotEmpty }) return
val empty = IntArrayList()
val itemTypes = Object2ObjectOpenCustomHashMap<ItemStack, IntAVLTreeSet>(ItemStackHashStrategy)
@ -140,12 +141,15 @@ fun Container.balance(slots: IntSet) {
// только один вид предмета, просто балансируем его во все слоты
if (itemTypes.size == 1) {
val (item, list) = itemTypes.entries.first()
var count = list.stream().mapToInt { getItem(it).count }.sum()
var count = 0
for (i in list.intIterator()) count += getItem(i).count
var ghostChanges = false
// всего предметов меньше, чем слотов
if (count < slots.size) {
for (slot in list.intIterator()) {
getItem(slot).count = 1
ghostChanges = true
}
count -= list.size
@ -157,6 +161,7 @@ fun Container.balance(slots: IntSet) {
if (count > 0) {
getItem(list.firstInt()).count += count
ghostChanges = true
}
} else {
// всего предметов больше, чем слотов
@ -164,17 +169,17 @@ fun Container.balance(slots: IntSet) {
var leftover = count - perSlot * slots.size
for (i in slots.intIterator()) {
setItem(i, item.copyWithCount(perSlot))
}
val target = perSlot + leftover.coerceAtMost(1)
for (i in slots.intIterator()) {
if (leftover <= 0) break
getItem(i).count++
leftover--
if (getItem(i).count != target) {
setItem(i, item.copyWithCount(target))
}
if (leftover > 0) leftover--
}
}
setChanged()
if (ghostChanges) setChanged()
return
}