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