United 'getTriggeredUniques' modifier filtering

This commit is contained in:
yairm210 2024-11-01 14:41:52 +02:00
parent 8a97573c7d
commit 194161b723
10 changed files with 53 additions and 70 deletions

View File

@ -169,19 +169,17 @@ object Battle {
fun triggerVictoryUniques(ourUnit: MapUnitCombatant, enemy: MapUnitCombatant) { fun triggerVictoryUniques(ourUnit: MapUnitCombatant, enemy: MapUnitCombatant) {
val stateForConditionals = StateForConditionals(civInfo = ourUnit.getCivInfo(), val stateForConditionals = StateForConditionals(civInfo = ourUnit.getCivInfo(),
ourCombatant = ourUnit, theirCombatant = enemy, tile = attackedTile) ourCombatant = ourUnit, theirCombatant = enemy, tile = attackedTile)
for (unique in ourUnit.unit.getTriggeredUniques(UniqueType.TriggerUponDefeatingUnit, stateForConditionals)) for (unique in ourUnit.unit.getTriggeredUniques(UniqueType.TriggerUponDefeatingUnit, stateForConditionals)
if (unique.getModifiers(UniqueType.TriggerUponDefeatingUnit).any { enemy.unit.matchesFilter(it.params[0]) }) { enemy.unit.matchesFilter(it.params[0]) })
UniqueTriggerActivation.triggerUnique(unique, ourUnit.unit, triggerNotificationText = "due to our [${ourUnit.getName()}] defeating a [${enemy.getName()}]") UniqueTriggerActivation.triggerUnique(unique, ourUnit.unit, triggerNotificationText = "due to our [${ourUnit.getName()}] defeating a [${enemy.getName()}]")
} }
fun triggerDamageUniquesForUnit(triggeringUnit: MapUnitCombatant, enemy: MapUnitCombatant, combatAction: CombatAction){ fun triggerDamageUniquesForUnit(triggeringUnit: MapUnitCombatant, enemy: MapUnitCombatant, combatAction: CombatAction){
val stateForConditionals = StateForConditionals(civInfo = triggeringUnit.getCivInfo(), val stateForConditionals = StateForConditionals(civInfo = triggeringUnit.getCivInfo(),
ourCombatant = triggeringUnit, theirCombatant = enemy, tile = attackedTile, combatAction = combatAction) ourCombatant = triggeringUnit, theirCombatant = enemy, tile = attackedTile, combatAction = combatAction)
for (unique in triggeringUnit.unit.getTriggeredUniques(UniqueType.TriggerUponDamagingUnit, stateForConditionals)){ for (unique in triggeringUnit.unit.getTriggeredUniques(UniqueType.TriggerUponDamagingUnit, stateForConditionals)
if (unique.getModifiers(UniqueType.TriggerUponDamagingUnit).none { enemy.matchesFilter(it.params[0]) }) { enemy.matchesFilter(it.params[0]) }){
continue
if (unique.params[0] == Constants.targetUnit){ if (unique.params[0] == Constants.targetUnit){
UniqueTriggerActivation.triggerUnique(unique, enemy.unit, triggerNotificationText = "due to our [${enemy.getName()}] being damaged by a [${triggeringUnit.getName()}]") UniqueTriggerActivation.triggerUnique(unique, enemy.unit, triggerNotificationText = "due to our [${enemy.getName()}] being damaged by a [${triggeringUnit.getName()}]")
} else { } else {
@ -344,14 +342,14 @@ object Battle {
val attackerDamageDealt = defenderHealthBefore - defender.getHealth() val attackerDamageDealt = defenderHealthBefore - defender.getHealth()
if (attacker is MapUnitCombatant) if (attacker is MapUnitCombatant)
for (unique in attacker.unit.getTriggeredUniques(UniqueType.TriggerUponLosingHealth)) for (unique in attacker.unit.getTriggeredUniques(UniqueType.TriggerUponLosingHealth)
if (unique.modifiers.any { it.params[0].toInt() <= defenderDamageDealt }) { it.params[0].toInt() <= defenderDamageDealt })
UniqueTriggerActivation.triggerUnique(unique, attacker.unit, triggerNotificationText = "due to losing [$defenderDamageDealt] HP") UniqueTriggerActivation.triggerUnique(unique, attacker.unit, triggerNotificationText = "due to losing [$defenderDamageDealt] HP")
if (defender is MapUnitCombatant) if (defender is MapUnitCombatant)
for (unique in defender.unit.getTriggeredUniques(UniqueType.TriggerUponLosingHealth)) for (unique in defender.unit.getTriggeredUniques(UniqueType.TriggerUponLosingHealth)
if (unique.modifiers.any { it.params[0].toInt() <= attackerDamageDealt }) { it.params[0].toInt() <= attackerDamageDealt })
UniqueTriggerActivation.triggerUnique(unique, defender.unit, triggerNotificationText = "due to losing [$attackerDamageDealt] HP") UniqueTriggerActivation.triggerUnique(unique, defender.unit, triggerNotificationText = "due to losing [$attackerDamageDealt] HP")
plunderFromDamage(attacker, defender, attackerDamageDealt) plunderFromDamage(attacker, defender, attackerDamageDealt)
return DamageDealt(attackerDamageDealt, defenderDamageDealt) return DamageDealt(attackerDamageDealt, defenderDamageDealt)

View File

@ -186,8 +186,6 @@ class CityConstructions : IsPartOfGameInfoSerialization {
fun getCurrentConstruction(): IConstruction = getConstruction(currentConstructionFromQueue) fun getCurrentConstruction(): IConstruction = getConstruction(currentConstructionFromQueue)
fun isAllBuilt(buildingList: List<String>): Boolean = buildingList.all { isBuilt(it) }
fun isBuilt(buildingName: String): Boolean = builtBuildings.contains(buildingName) fun isBuilt(buildingName: String): Boolean = builtBuildings.contains(buildingName)
// Note: There was a isEnqueued here functionally identical to isBeingConstructedOrEnqueued, // Note: There was a isEnqueued here functionally identical to isBeingConstructedOrEnqueued,
@ -566,14 +564,13 @@ class CityConstructions : IsPartOfGameInfoSerialization {
if (!unique.hasTriggerConditional() && unique.conditionalsApply(stateForConditionals)) if (!unique.hasTriggerConditional() && unique.conditionalsApply(stateForConditionals))
UniqueTriggerActivation.triggerUnique(unique, city, triggerNotificationText = triggerNotificationText) UniqueTriggerActivation.triggerUnique(unique, city, triggerNotificationText = triggerNotificationText)
for (unique in city.civ.getTriggeredUniques(UniqueType.TriggerUponConstructingBuilding, stateForConditionals)) for (unique in city.civ.getTriggeredUniques(UniqueType.TriggerUponConstructingBuilding, stateForConditionals)
if (unique.getModifiers(UniqueType.TriggerUponConstructingBuilding).any { building.matchesFilter(it.params[0])} ) { building.matchesFilter(it.params[0]) })
UniqueTriggerActivation.triggerUnique(unique, city, triggerNotificationText = triggerNotificationText) UniqueTriggerActivation.triggerUnique(unique, city, triggerNotificationText = triggerNotificationText)
for (unique in city.civ.getTriggeredUniques(UniqueType.TriggerUponConstructingBuildingCityFilter, stateForConditionals)) for (unique in city.civ.getTriggeredUniques(UniqueType.TriggerUponConstructingBuildingCityFilter, stateForConditionals)
if (unique.getModifiers(UniqueType.TriggerUponConstructingBuildingCityFilter).any { { building.matchesFilter(it.params[0]) && city.matchesFilter(it.params[1]) })
building.matchesFilter(it.params[0]) && city.matchesFilter(it.params[1]) }) UniqueTriggerActivation.triggerUnique(unique, city, triggerNotificationText = triggerNotificationText)
UniqueTriggerActivation.triggerUnique(unique, city, triggerNotificationText = triggerNotificationText)
} }
fun removeBuilding(buildingName: String) { fun removeBuilding(buildingName: String) {

View File

@ -541,18 +541,18 @@ class Civilization : IsPartOfGameInfoSerialization {
fun getTriggeredUniques( fun getTriggeredUniques(
trigger: UniqueType, trigger: UniqueType,
stateForConditionals: StateForConditionals = StateForConditionals(this), stateForConditionals: StateForConditionals = StateForConditionals(this),
modifierFilter: (Unique) -> Boolean = { true } triggerFilter: (Unique) -> Boolean = { true }
) : Iterable<Unique> = sequence { ) : Iterable<Unique> = sequence {
yieldAll(nation.uniqueMap.getTriggeredUniques(trigger, stateForConditionals, modifierFilter)) yieldAll(nation.uniqueMap.getTriggeredUniques(trigger, stateForConditionals, triggerFilter))
yieldAll(cities.asSequence() yieldAll(cities.asSequence()
.flatMap { city -> city.cityConstructions.builtBuildingUniqueMap.getTriggeredUniques(trigger, stateForConditionals, modifierFilter) } .flatMap { city -> city.cityConstructions.builtBuildingUniqueMap.getTriggeredUniques(trigger, stateForConditionals, triggerFilter) }
) )
if (religionManager.religion != null) if (religionManager.religion != null)
yieldAll(religionManager.religion!!.founderBeliefUniqueMap.getTriggeredUniques(trigger, stateForConditionals, modifierFilter)) yieldAll(religionManager.religion!!.founderBeliefUniqueMap.getTriggeredUniques(trigger, stateForConditionals, triggerFilter))
yieldAll(policies.policyUniques.getTriggeredUniques(trigger, stateForConditionals, modifierFilter)) yieldAll(policies.policyUniques.getTriggeredUniques(trigger, stateForConditionals, triggerFilter))
yieldAll(tech.techUniques.getTriggeredUniques(trigger, stateForConditionals, modifierFilter)) yieldAll(tech.techUniques.getTriggeredUniques(trigger, stateForConditionals, triggerFilter))
yieldAll(getEra().uniqueMap.getTriggeredUniques (trigger, stateForConditionals, modifierFilter)) yieldAll(getEra().uniqueMap.getTriggeredUniques (trigger, stateForConditionals, triggerFilter))
yieldAll(gameInfo.ruleset.globalUniques.uniqueMap.getTriggeredUniques(trigger, stateForConditionals, modifierFilter)) yieldAll(gameInfo.ruleset.globalUniques.uniqueMap.getTriggeredUniques(trigger, stateForConditionals, triggerFilter))
}.toList() // Triggers can e.g. add buildings which contain triggers, causing concurrent modification errors }.toList() // Triggers can e.g. add buildings which contain triggers, causing concurrent modification errors

View File

@ -234,9 +234,8 @@ class PolicyManager : IsPartOfGameInfoSerialization {
if (!unique.hasTriggerConditional() && unique.conditionalsApply(StateForConditionals(civInfo))) if (!unique.hasTriggerConditional() && unique.conditionalsApply(StateForConditionals(civInfo)))
UniqueTriggerActivation.triggerUnique(unique, civInfo, triggerNotificationText = triggerNotificationText) UniqueTriggerActivation.triggerUnique(unique, civInfo, triggerNotificationText = triggerNotificationText)
for (unique in civInfo.getTriggeredUniques(UniqueType.TriggerUponAdoptingPolicyOrBelief)) for (unique in civInfo.getTriggeredUniques(UniqueType.TriggerUponAdoptingPolicyOrBelief) {it.params[0] == policy.name})
if (unique.getModifiers(UniqueType.TriggerUponAdoptingPolicyOrBelief).any { it.params[0] == policy.name }) UniqueTriggerActivation.triggerUnique(unique, civInfo, triggerNotificationText = triggerNotificationText)
UniqueTriggerActivation.triggerUnique(unique, civInfo, triggerNotificationText = triggerNotificationText)
civInfo.cache.updateCivResources() civInfo.cache.updateCivResources()

View File

@ -316,9 +316,8 @@ class TechManager : IsPartOfGameInfoSerialization {
if (!unique.hasTriggerConditional() && unique.conditionalsApply(StateForConditionals(civInfo))) if (!unique.hasTriggerConditional() && unique.conditionalsApply(StateForConditionals(civInfo)))
UniqueTriggerActivation.triggerUnique(unique, civInfo, triggerNotificationText = triggerNotificationText) UniqueTriggerActivation.triggerUnique(unique, civInfo, triggerNotificationText = triggerNotificationText)
for (unique in civInfo.getTriggeredUniques(UniqueType.TriggerUponResearch)) for (unique in civInfo.getTriggeredUniques(UniqueType.TriggerUponResearch) { newTech.matchesFilter(it.params[0]) })
if (unique.getModifiers(UniqueType.TriggerUponResearch).any { newTech.matchesFilter(it.params[0]) }) UniqueTriggerActivation.triggerUnique(unique, civInfo, triggerNotificationText = triggerNotificationText)
UniqueTriggerActivation.triggerUnique(unique, civInfo, triggerNotificationText = triggerNotificationText)
val revealedResources = getRuleset().tileResources.values.filter { techName == it.revealedBy } val revealedResources = getRuleset().tileResources.values.filter { techName == it.revealedBy }
@ -464,7 +463,7 @@ class TechManager : IsPartOfGameInfoSerialization {
val eraNames = erasPassed.map { it.name }.toHashSet() val eraNames = erasPassed.map { it.name }.toHashSet()
for (unique in civInfo.getTriggeredUniques(UniqueType.TriggerUponEnteringEra)) for (unique in civInfo.getTriggeredUniques(UniqueType.TriggerUponEnteringEra))
for (eraName in eraNames) for (eraName in eraNames)
if (unique.modifiers.any { it.type == UniqueType.TriggerUponEnteringEra && it.params[0] == eraName }) if (unique.getModifiers(UniqueType.TriggerUponEnteringEra).any { it.params[0] == eraName })
UniqueTriggerActivation.triggerUnique( UniqueTriggerActivation.triggerUnique(
unique, unique,
civInfo, civInfo,

View File

@ -103,9 +103,9 @@ class UnitManager(val civInfo: Civilization) {
if (!unique.hasTriggerConditional() && unique.conditionalsApply(StateForConditionals(civInfo, unit = unit))) if (!unique.hasTriggerConditional() && unique.conditionalsApply(StateForConditionals(civInfo, unit = unit)))
UniqueTriggerActivation.triggerUnique(unique, unit, triggerNotificationText = triggerNotificationText) UniqueTriggerActivation.triggerUnique(unique, unit, triggerNotificationText = triggerNotificationText)
for (unique in civInfo.getTriggeredUniques(UniqueType.TriggerUponGainingUnit)) for (unique in civInfo.getTriggeredUniques(UniqueType.TriggerUponGainingUnit)
if (unique.getModifiers(UniqueType.TriggerUponGainingUnit).any { unit.matchesFilter(it.params[0]) }) { unit.matchesFilter(it.params[0]) })
UniqueTriggerActivation.triggerUnique(unique, unit, triggerNotificationText = triggerNotificationText) UniqueTriggerActivation.triggerUnique(unique, unit, triggerNotificationText = triggerNotificationText)
if (unit.getResourceRequirementsPerTurn().isNotEmpty()) if (unit.getResourceRequirementsPerTurn().isNotEmpty())
civInfo.cache.updateCivResources() civInfo.cache.updateCivResources()

View File

@ -300,11 +300,11 @@ class MapUnit : IsPartOfGameInfoSerialization {
} }
fun getTriggeredUniques( fun getTriggeredUniques(
trigger: UniqueType, trigger: UniqueType,
stateForConditionals: StateForConditionals = StateForConditionals(civInfo = civ, unit = this), stateForConditionals: StateForConditionals = StateForConditionals(civInfo = civ, unit = this),
modifierFilter: (Unique) -> Boolean = { true } triggerFilter: (Unique) -> Boolean = { true }
): Sequence<Unique> { ): Sequence<Unique> {
return tempUniquesMap.getTriggeredUniques(trigger, stateForConditionals, modifierFilter) return tempUniquesMap.getTriggeredUniques(trigger, stateForConditionals, triggerFilter)
} }
@ -834,10 +834,9 @@ class MapUnit : IsPartOfGameInfoSerialization {
/** Destroys the unit and gives stats if its a great person */ /** Destroys the unit and gives stats if its a great person */
fun consume() { fun consume() {
for (unique in civ.getTriggeredUniques(UniqueType.TriggerUponExpendingUnit)) for (unique in civ.getTriggeredUniques(UniqueType.TriggerUponExpendingUnit){ matchesFilter(it.params[0]) })
if (unique.getModifiers(UniqueType.TriggerUponExpendingUnit).any { matchesFilter(it.params[0]) }) UniqueTriggerActivation.triggerUnique(unique, this,
UniqueTriggerActivation.triggerUnique(unique, this, triggerNotificationText = "due to expending our [${this.name}]")
triggerNotificationText = "due to expending our [${this.name}]")
destroy() destroy()
} }
@ -1041,10 +1040,8 @@ class MapUnit : IsPartOfGameInfoSerialization {
statuses.add(status) statuses.add(status)
updateUniques() updateUniques()
for (unique in getTriggeredUniques(UniqueType.TriggerUponStatusGain)) for (unique in getTriggeredUniques(UniqueType.TriggerUponStatusGain){ it.params[0] == name })
if (unique.getModifiers(UniqueType.TriggerUponStatusGain) UniqueTriggerActivation.triggerUnique(unique, this)
.any { it.params[0] == name })
UniqueTriggerActivation.triggerUnique(unique, this)
} }
fun removeStatus(name:String){ fun removeStatus(name:String){
@ -1053,10 +1050,8 @@ class MapUnit : IsPartOfGameInfoSerialization {
updateUniques() updateUniques()
for (unique in getTriggeredUniques(UniqueType.TriggerUponStatusLoss)) for (unique in getTriggeredUniques(UniqueType.TriggerUponStatusLoss){ it.params[0] == name })
if (unique.getModifiers(UniqueType.TriggerUponStatusLoss) UniqueTriggerActivation.triggerUnique(unique, this)
.any { it.params[0] == name })
UniqueTriggerActivation.triggerUnique(unique, this)
} }

View File

@ -76,10 +76,8 @@ class UnitPromotions : IsPartOfGameInfoSerialization {
for (unique in unit.getTriggeredUniques(UniqueType.TriggerUponPromotion)) for (unique in unit.getTriggeredUniques(UniqueType.TriggerUponPromotion))
UniqueTriggerActivation.triggerUnique(unique, unit) UniqueTriggerActivation.triggerUnique(unique, unit)
for (unique in unit.getTriggeredUniques(UniqueType.TriggerUponPromotionGain)) for (unique in unit.getTriggeredUniques(UniqueType.TriggerUponPromotionGain){ it.params[0] == promotionName })
if (unique.getModifiers(UniqueType.TriggerUponPromotionGain) UniqueTriggerActivation.triggerUnique(unique, unit)
.any { it.params[0] == promotionName })
UniqueTriggerActivation.triggerUnique(unique, unit)
} }
if (!promotion.hasUnique(UniqueType.SkipPromotion)) if (!promotion.hasUnique(UniqueType.SkipPromotion))
@ -106,10 +104,8 @@ class UnitPromotions : IsPartOfGameInfoSerialization {
unit.updateUniques() unit.updateUniques()
unit.updateVisibleTiles() unit.updateVisibleTiles()
for (unique in unit.getTriggeredUniques(UniqueType.TriggerUponPromotionLoss)) for (unique in unit.getTriggeredUniques(UniqueType.TriggerUponPromotionLoss){ it.params[0] == promotionName })
if (unique.getModifiers(UniqueType.TriggerUponPromotionLoss) UniqueTriggerActivation.triggerUnique(unique, unit)
.any { it.params[0] == promotionName })
UniqueTriggerActivation.triggerUnique(unique, unit)
} }
} }

View File

@ -66,10 +66,9 @@ class UnitTurnManager(val unit: MapUnit) {
unit.addMovementMemory() unit.addMovementMemory()
for (unique in unit.getTriggeredUniques(UniqueType.TriggerUponEndingTurnInTile)) for (unique in unit.getTriggeredUniques(UniqueType.TriggerUponEndingTurnInTile)
if (unique.getModifiers(UniqueType.TriggerUponEndingTurnInTile).any { { unit.getTile().matchesFilter(it.params[0], unit.civ) })
unit.getTile().matchesFilter(it.params[0], unit.civ) }) UniqueTriggerActivation.triggerUnique(unique, unit)
UniqueTriggerActivation.triggerUnique(unique, unit)
} }

View File

@ -324,9 +324,9 @@ open class UniqueMap() {
fun getAllUniques() = innerUniqueMap.values.asSequence().flatten() fun getAllUniques() = innerUniqueMap.values.asSequence().flatten()
fun getTriggeredUniques(trigger: UniqueType, stateForConditionals: StateForConditionals, fun getTriggeredUniques(trigger: UniqueType, stateForConditionals: StateForConditionals,
modifierFilter: (Unique) -> Boolean = { true }): Sequence<Unique> { triggerFilter: (Unique) -> Boolean = { true }): Sequence<Unique> {
return getAllUniques().filter { unique -> return getAllUniques().filter { unique ->
unique.getModifiers(trigger).any(modifierFilter) && unique.conditionalsApply(stateForConditionals) unique.getModifiers(trigger).any(triggerFilter) && unique.conditionalsApply(stateForConditionals)
}.flatMap { it.getMultiplied(stateForConditionals) } }.flatMap { it.getMultiplied(stateForConditionals) }
} }