From faba736bd7838301a47440470de2b459da168fc0 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Sat, 22 Mar 2025 17:10:26 +0700 Subject: [PATCH] Considerably improve upgrade container performance --- .../mc/otm/container/UpgradeContainer.kt | 82 +++++++++++++++---- 1 file changed, 68 insertions(+), 14 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/UpgradeContainer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/UpgradeContainer.kt index e18a3d427..e3dae88f8 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/UpgradeContainer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/UpgradeContainer.kt @@ -26,28 +26,62 @@ class UpgradeContainer( override val upgradeTypes: Set get() = setOf() - private fun positiveDecimals(fn: (IMatteryUpgrade) -> Decimal, reducer: (Decimal, Decimal) -> Decimal): Decimal { + private inline fun positiveDecimals(fn: (IMatteryUpgrade) -> Decimal, reducer: (Decimal, Decimal) -> Decimal): Decimal { if (isEmpty) return Decimal.ZERO - return iterator() - .map { (it.getCapability(MatteryCapability.UPGRADE)?.let(fn) ?: Decimal.ZERO).moreThanZero() * it.count } - .reduce(Decimal.ZERO, reducer) + var result = Decimal.ZERO + + for (it in iterator()) { + val cap = it.getCapability(MatteryCapability.UPGRADE) ?: continue + val value = fn(cap) + + if (value > Decimal.ZERO) { + if (it.count == 1) { + result = reducer(result, value ) + } else { + result = reducer(result, value * it.count) + } + } + } + + return result } - private fun anyDecimals(fn: (IMatteryUpgrade) -> Decimal, reducer: (Decimal, Decimal) -> Decimal): Decimal { + private inline fun anyDecimals(fn: (IMatteryUpgrade) -> Decimal, reducer: (Decimal, Decimal) -> Decimal): Decimal { if (isEmpty) return Decimal.ZERO - return iterator() - .map { (it.getCapability(MatteryCapability.UPGRADE)?.let(fn) ?: Decimal.ZERO) * it.count } - .reduce(Decimal.ZERO, reducer) + var result = Decimal.ZERO + + for (it in iterator()) { + val cap = it.getCapability(MatteryCapability.UPGRADE) ?: continue + val value = fn(cap) + + if (it.count == 1) { + result = reducer(result, value) + } else { + result = reducer(result, value * it.count) + } + } + + return result + } + + override val speedBonus: Double get() { + if (isEmpty) + return 0.0 + + return sumOf { (it.getCapability(MatteryCapability.UPGRADE)?.speedBonus ?: 0.0) * it.count } + } + + override val processingItems: Int get() { + if (isEmpty) + return 0 + + return sumOf { (it.getCapability(MatteryCapability.UPGRADE)?.processingItems ?: 0).coerceAtLeast(0) * it.count } } - override val speedBonus: Double - get() = if (isEmpty) 0.0 else iterator().map { (it.getCapability(MatteryCapability.UPGRADE)?.speedBonus ?: 0.0) * it.count }.reduce(0.0) { a, b -> a + b } - override val processingItems: Int - get() = if (isEmpty) 0 else iterator().map { (it.getCapability(MatteryCapability.UPGRADE)?.processingItems ?: 0).coerceAtLeast(0) * it.count }.reduce(0) { a, b -> a + b } override val energyStorageFlat: Decimal get() = positiveDecimals(IMatteryUpgrade::energyStorageFlat, Decimal::plus) override val energyStorage: Decimal @@ -58,8 +92,28 @@ class UpgradeContainer( get() = positiveDecimals(IMatteryUpgrade::matterStorage, Decimal::plus) override val energyConsumed: Decimal get() = anyDecimals(IMatteryUpgrade::energyConsumed, Decimal::plus) - override val failureMultiplier: Double - get() = if (isEmpty) 1.0 else iterator().map { (it.getCapability(MatteryCapability.UPGRADE)?.failureMultiplier ?: 1.0).coerceAtLeast(0.0).pow(it.count.toDouble()) }.reduce(1.0) { a, b -> a * b } + + override val failureMultiplier: Double get() { + if (isEmpty) + return 1.0 + + var result = 1.0 + + for (it in iterator()) { + val cap = it.getCapability(MatteryCapability.UPGRADE) ?: continue + val chance = cap.failureMultiplier.coerceAtLeast(0.0) + + if (chance == 0.0) + return 0.0 + else if (it.count == 1) + result *= chance + else + result *= chance.pow(it.count) + } + + return result + } + override val energyThroughputFlat: Decimal get() = positiveDecimals(IMatteryUpgrade::energyThroughputFlat, Decimal::plus) override val energyThroughput: Decimal