mirror of
https://github.com/yairm210/Unciv.git
synced 2025-01-25 10:26:05 +07:00
Fixed memory- and time-intensive unit maintenance checks (#6092)
Get all civwide unit discount uniques once, and then filter them by-conditional only when checking each specific unit. This saves a LOT of memory allocation and time. A result of the investigation at #5919.
This commit is contained in:
parent
0a336b3d99
commit
3908fbc9cf
@ -31,18 +31,25 @@ class CivInfoStats(val civInfo: CivilizationInfo) {
|
||||
unitsToPayFor = unitsToPayFor.filterNot {
|
||||
it.getTile().isCityCenter() && it.canGarrison()
|
||||
}
|
||||
// Handle unit maintenance discounts
|
||||
// Free Garrison already removed above from sequence
|
||||
// To try and avoid concurrent modifications leading to crashes,
|
||||
// we calculate the costs of one unit at a time.
|
||||
// Each unit starts with 1f aka 100% of cost, and then the discout is addded.
|
||||
|
||||
// Each unit starts with 1f aka 100% of cost, and then the discount is added.
|
||||
// Note all discounts are in the form of -X%, such as -25 for 25% reduction
|
||||
|
||||
val costsToPay = ArrayList<Float>()
|
||||
|
||||
// We IGNORE the conditionals when we get them civ-wide, so we won't need to do the same thing for EVERY unit in the civ.
|
||||
// This leads to massive memory and CPU time savings when calculating the maintenance!
|
||||
val civwideDiscountUniques = civInfo.getMatchingUniques(UniqueType.UnitMaintenanceDiscount, StateForConditionals.IgnoreConditionals).toList()
|
||||
|
||||
for (unit in unitsToPayFor) {
|
||||
val stateForConditionals = StateForConditionals(civInfo=civInfo, unit=unit)
|
||||
val stateForConditionals = StateForConditionals(civInfo = civInfo, unit = unit)
|
||||
var unitMaintenance = 1f
|
||||
for (unique in unit.getMatchingUniques(UniqueType.UnitMaintenanceDiscount, stateForConditionals, true)){
|
||||
val uniquesThatApply = unit.getMatchingUniques(
|
||||
UniqueType.UnitMaintenanceDiscount,
|
||||
stateForConditionals
|
||||
) + civwideDiscountUniques.asSequence()
|
||||
.filter { it.conditionalsApply(stateForConditionals) }
|
||||
for (unique in uniquesThatApply) {
|
||||
unitMaintenance *= unique.params[0].toPercent()
|
||||
}
|
||||
costsToPay.add(unitMaintenance)
|
||||
|
@ -19,4 +19,11 @@ data class StateForConditionals(
|
||||
val combatAction: CombatAction? = null,
|
||||
|
||||
val region: Region? = null,
|
||||
)
|
||||
|
||||
val ignoreConditionals:Boolean = false,
|
||||
) {
|
||||
|
||||
companion object {
|
||||
val IgnoreConditionals = StateForConditionals(ignoreConditionals = true)
|
||||
}
|
||||
}
|
@ -38,7 +38,8 @@ class Unique(val text: String, val sourceObjectType: UniqueTarget? = null, val s
|
||||
}
|
||||
|
||||
fun conditionalsApply(state: StateForConditionals?): Boolean {
|
||||
if (state == null) return conditionals.isEmpty()
|
||||
if (state == null) return conditionals.isEmpty()
|
||||
if (state.ignoreConditionals) return true
|
||||
for (condition in conditionals) {
|
||||
if (!conditionalApplies(condition, state)) return false
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user