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

View File

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

View File

@ -541,18 +541,18 @@ class Civilization : IsPartOfGameInfoSerialization {
fun getTriggeredUniques(
trigger: UniqueType,
stateForConditionals: StateForConditionals = StateForConditionals(this),
modifierFilter: (Unique) -> Boolean = { true }
triggerFilter: (Unique) -> Boolean = { true }
) : Iterable<Unique> = sequence {
yieldAll(nation.uniqueMap.getTriggeredUniques(trigger, stateForConditionals, modifierFilter))
yieldAll(nation.uniqueMap.getTriggeredUniques(trigger, stateForConditionals, triggerFilter))
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)
yieldAll(religionManager.religion!!.founderBeliefUniqueMap.getTriggeredUniques(trigger, stateForConditionals, modifierFilter))
yieldAll(policies.policyUniques.getTriggeredUniques(trigger, stateForConditionals, modifierFilter))
yieldAll(tech.techUniques.getTriggeredUniques(trigger, stateForConditionals, modifierFilter))
yieldAll(getEra().uniqueMap.getTriggeredUniques (trigger, stateForConditionals, modifierFilter))
yieldAll(gameInfo.ruleset.globalUniques.uniqueMap.getTriggeredUniques(trigger, stateForConditionals, modifierFilter))
yieldAll(religionManager.religion!!.founderBeliefUniqueMap.getTriggeredUniques(trigger, stateForConditionals, triggerFilter))
yieldAll(policies.policyUniques.getTriggeredUniques(trigger, stateForConditionals, triggerFilter))
yieldAll(tech.techUniques.getTriggeredUniques(trigger, stateForConditionals, triggerFilter))
yieldAll(getEra().uniqueMap.getTriggeredUniques (trigger, stateForConditionals, triggerFilter))
yieldAll(gameInfo.ruleset.globalUniques.uniqueMap.getTriggeredUniques(trigger, stateForConditionals, triggerFilter))
}.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)))
UniqueTriggerActivation.triggerUnique(unique, civInfo, triggerNotificationText = triggerNotificationText)
for (unique in civInfo.getTriggeredUniques(UniqueType.TriggerUponAdoptingPolicyOrBelief))
if (unique.getModifiers(UniqueType.TriggerUponAdoptingPolicyOrBelief).any { it.params[0] == policy.name })
UniqueTriggerActivation.triggerUnique(unique, civInfo, triggerNotificationText = triggerNotificationText)
for (unique in civInfo.getTriggeredUniques(UniqueType.TriggerUponAdoptingPolicyOrBelief) {it.params[0] == policy.name})
UniqueTriggerActivation.triggerUnique(unique, civInfo, triggerNotificationText = triggerNotificationText)
civInfo.cache.updateCivResources()

View File

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

View File

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

View File

@ -300,11 +300,11 @@ class MapUnit : IsPartOfGameInfoSerialization {
}
fun getTriggeredUniques(
trigger: UniqueType,
stateForConditionals: StateForConditionals = StateForConditionals(civInfo = civ, unit = this),
modifierFilter: (Unique) -> Boolean = { true }
trigger: UniqueType,
stateForConditionals: StateForConditionals = StateForConditionals(civInfo = civ, unit = this),
triggerFilter: (Unique) -> Boolean = { true }
): 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 */
fun consume() {
for (unique in civ.getTriggeredUniques(UniqueType.TriggerUponExpendingUnit))
if (unique.getModifiers(UniqueType.TriggerUponExpendingUnit).any { matchesFilter(it.params[0]) })
UniqueTriggerActivation.triggerUnique(unique, this,
triggerNotificationText = "due to expending our [${this.name}]")
for (unique in civ.getTriggeredUniques(UniqueType.TriggerUponExpendingUnit){ matchesFilter(it.params[0]) })
UniqueTriggerActivation.triggerUnique(unique, this,
triggerNotificationText = "due to expending our [${this.name}]")
destroy()
}
@ -1041,10 +1040,8 @@ class MapUnit : IsPartOfGameInfoSerialization {
statuses.add(status)
updateUniques()
for (unique in getTriggeredUniques(UniqueType.TriggerUponStatusGain))
if (unique.getModifiers(UniqueType.TriggerUponStatusGain)
.any { it.params[0] == name })
UniqueTriggerActivation.triggerUnique(unique, this)
for (unique in getTriggeredUniques(UniqueType.TriggerUponStatusGain){ it.params[0] == name })
UniqueTriggerActivation.triggerUnique(unique, this)
}
fun removeStatus(name:String){
@ -1053,10 +1050,8 @@ class MapUnit : IsPartOfGameInfoSerialization {
updateUniques()
for (unique in getTriggeredUniques(UniqueType.TriggerUponStatusLoss))
if (unique.getModifiers(UniqueType.TriggerUponStatusLoss)
.any { it.params[0] == name })
UniqueTriggerActivation.triggerUnique(unique, this)
for (unique in getTriggeredUniques(UniqueType.TriggerUponStatusLoss){ it.params[0] == name })
UniqueTriggerActivation.triggerUnique(unique, this)
}

View File

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

View File

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

View File

@ -324,9 +324,9 @@ open class UniqueMap() {
fun getAllUniques() = innerUniqueMap.values.asSequence().flatten()
fun getTriggeredUniques(trigger: UniqueType, stateForConditionals: StateForConditionals,
modifierFilter: (Unique) -> Boolean = { true }): Sequence<Unique> {
triggerFilter: (Unique) -> Boolean = { true }): Sequence<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) }
}