perf: Decrease great general bonus calculation time

This commit is contained in:
yairm210 2024-09-15 20:09:48 +03:00
parent 0533347371
commit f5bf655d12
2 changed files with 13 additions and 8 deletions

View File

@ -20,7 +20,7 @@ object GreatGeneralImplementation {
}
/**
* Determine the "Great General" bonus for [unit] by searching for units carrying the [UniqueType.StrengthBonusInRadius] in the vicinity.
* Determine the "Great General" bonus for [ourUnitCombatant] by searching for units carrying the [UniqueType.StrengthBonusInRadius] in the vicinity.
*
* Used by [BattleDamage.getGeneralModifiers].
*
@ -89,16 +89,20 @@ object GreatGeneralImplementation {
// rank tiles and find best
val unitBonusRadius = generalBonusData.maxOfOrNull { it.radius }
?: return null
val militaryUnitToHasAttackableEnemies = HashMap<MapUnit, Boolean>()
return militaryUnitTilesInDistance
.maxByOrNull { unitTile ->
unitTile.getTilesInDistance(unitBonusRadius).sumOf { auraTile ->
val militaryUnit = auraTile.militaryUnit
unitTile.getTilesInDistance(unitBonusRadius).sumOf { affectedTile ->
val militaryUnit = affectedTile.militaryUnit
if (militaryUnit == null || militaryUnit.civ != general.civ || militaryUnit.isEmbarked()) 0
else if (TargetHelper.getAttackableEnemies(militaryUnit, militaryUnit.movement.getDistanceToTiles()).isEmpty()) 0
else if (militaryUnitToHasAttackableEnemies.getOrPut(militaryUnit) {
TargetHelper.getAttackableEnemies(militaryUnit, militaryUnit.movement.getDistanceToTiles()).isEmpty()
}) 0
else generalBonusData.firstOrNull {
// "Military" as commented above only a small optimization
auraTile.aerialDistanceTo(unitTile) <= it.radius
affectedTile.aerialDistanceTo(unitTile) <= it.radius
&& (it.filter == "Military" || militaryUnit.matchesFilter(it.filter))
}?.bonus ?: 0
}

View File

@ -64,17 +64,18 @@ class Unique(val text: String, val sourceObjectType: UniqueTarget? = null, val s
return conditionalsApply(StateForConditionals(civInfo, city))
}
fun conditionalsApply(state: StateForConditionals = StateForConditionals()): Boolean {
fun conditionalsApply(state: StateForConditionals): Boolean {
if (state.ignoreConditionals) return true
// Always allow Timed conditional uniques. They are managed elsewhere
if (isTimedTriggerable) return true
if (modifiers.isEmpty()) return true
for (modifier in modifiers) {
if (!Conditionals.conditionalApplies(this, modifier, state)) return false
}
return true
}
private fun getUniqueMultiplier(stateForConditionals: StateForConditionals = StateForConditionals()): Int {
private fun getUniqueMultiplier(stateForConditionals: StateForConditionals): Int {
val forEveryModifiers = getModifiers(UniqueType.ForEveryCountable)
val forEveryAmountModifiers = getModifiers(UniqueType.ForEveryAmountCountable)
var amount = 1
@ -92,7 +93,7 @@ class Unique(val text: String, val sourceObjectType: UniqueTarget? = null, val s
}
/** Multiplies the unique according to the multiplication conditionals */
fun getMultiplied(stateForConditionals: StateForConditionals = StateForConditionals()): Sequence<Unique> {
fun getMultiplied(stateForConditionals: StateForConditionals): Sequence<Unique> {
val multiplier = getUniqueMultiplier(stateForConditionals)
return EndlessSequenceOf(this).take(multiplier)
}