mirror of
https://github.com/yairm210/Unciv.git
synced 2025-01-05 21:11:35 +07:00
Fix buildings/units not triggering and golden age stat updates (#9731)
* Fix buildings not triggering, golden age stat updates, and units not triggering * Forgot import, whoops * uodate resources and city connection when removing a building * Move building triggers to function, added unit notification to translations * Quick edits without android studio sucks * Add unitActionModifier check back to hasTriggerConditional --------- Co-authored-by: Yair Morgenstern <yairm210@hotmail.com>
This commit is contained in:
parent
d2dac66f40
commit
5ea1d5722b
@ -1027,6 +1027,7 @@ due to adopting [policy] =
|
||||
due to discovering [naturalWonder] =
|
||||
due to entering the [eraName] =
|
||||
due to constructing [buildingName] =
|
||||
due to gaining a [unitName] =
|
||||
due to founding a city =
|
||||
due to discovering a Natural Wonder =
|
||||
due to our [unitName] defeating a [otherUnitName] =
|
||||
|
@ -22,6 +22,7 @@ import com.unciv.models.ruleset.unique.LocalUniqueCache
|
||||
import com.unciv.models.ruleset.unique.StateForConditionals
|
||||
import com.unciv.models.ruleset.unique.UniqueMap
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.ruleset.unique.UniqueTriggerActivation
|
||||
import com.unciv.models.ruleset.unit.BaseUnit
|
||||
import com.unciv.models.stats.Stat
|
||||
import com.unciv.models.stats.Stats
|
||||
@ -479,16 +480,75 @@ class CityConstructions : IsPartOfGameInfoSerialization {
|
||||
}
|
||||
|
||||
fun addBuilding(buildingName: String) {
|
||||
val buildingObject = city.getRuleset().buildings[buildingName]!!
|
||||
builtBuildingObjects = builtBuildingObjects.withItem(buildingObject)
|
||||
val building = city.getRuleset().buildings[buildingName]!!
|
||||
val civ = city.civ
|
||||
|
||||
if (building.cityHealth > 0) {
|
||||
// city built a building that increases health so add a portion of this added health that is
|
||||
// proportional to the city's current health
|
||||
city.health += (building.cityHealth.toFloat() * city.health.toFloat() / city.getMaxHealth().toFloat()).toInt()
|
||||
}
|
||||
builtBuildingObjects = builtBuildingObjects.withItem(building)
|
||||
builtBuildings.add(buildingName)
|
||||
|
||||
/** Support for [UniqueType.CreatesOneImprovement] */
|
||||
applyCreateOneImprovement(building)
|
||||
|
||||
addFreeBuildings()
|
||||
|
||||
triggerNewBuildingUniques(building)
|
||||
|
||||
if (building.hasUnique(UniqueType.EnemyUnitsSpendExtraMovement))
|
||||
civ.cache.updateHasActiveEnemyMovementPenalty()
|
||||
|
||||
// Korean unique - apparently gives the same as the research agreement
|
||||
if (building.isStatRelated(Stat.Science) && civ.hasUnique(UniqueType.TechBoostWhenScientificBuildingsBuiltInCapital))
|
||||
civ.tech.addScience(civ.tech.scienceOfLast8Turns.sum() / 8)
|
||||
|
||||
val uniqueTypesModifyingYields = listOf(
|
||||
UniqueType.StatsFromTiles, UniqueType.StatsFromTilesWithout, UniqueType.StatsFromObject,
|
||||
UniqueType.StatPercentFromObject, UniqueType.AllStatsPercentFromObject
|
||||
)
|
||||
|
||||
// Happiness is global, so it could affect all cities
|
||||
if(building.isStatRelated(Stat.Happiness)) {
|
||||
for (city in civ.cities) {
|
||||
city.reassignPopulationDeferred()
|
||||
}
|
||||
}
|
||||
else if(uniqueTypesModifyingYields.any { building.hasUnique(it) })
|
||||
city.reassignPopulationDeferred()
|
||||
|
||||
updateUniques()
|
||||
|
||||
civ.cache.updateCivResources() // this building could be a resource-requiring one
|
||||
civ.cache.updateCitiesConnectedToCapital(false) // could be a connecting building, like a harbor
|
||||
}
|
||||
|
||||
fun triggerNewBuildingUniques(building: Building) {
|
||||
val triggerNotificationText ="due to constructing [${building.name}]"
|
||||
|
||||
for (unique in building.uniqueObjects)
|
||||
if (!unique.hasTriggerConditional())
|
||||
UniqueTriggerActivation.triggerCivwideUnique(unique, city.civ, city, triggerNotificationText = triggerNotificationText)
|
||||
|
||||
for (unique in city.civ.getTriggeredUniques(UniqueType.TriggerUponConstructingBuilding, StateForConditionals(city.civ, city)))
|
||||
if (unique.conditionals.any {it.type == UniqueType.TriggerUponConstructingBuilding && building.matchesFilter(it.params[0])})
|
||||
UniqueTriggerActivation.triggerCivwideUnique(unique, city.civ, city, triggerNotificationText = triggerNotificationText)
|
||||
|
||||
for (unique in city.civ.getTriggeredUniques(UniqueType.TriggerUponConstructingBuildingCityFilter, StateForConditionals(city.civ, city)))
|
||||
if (unique.conditionals.any {it.type == UniqueType.TriggerUponConstructingBuildingCityFilter
|
||||
&& building.matchesFilter(it.params[0])
|
||||
&& city.matchesFilter(it.params[1])})
|
||||
UniqueTriggerActivation.triggerCivwideUnique(unique, city.civ, city, triggerNotificationText = triggerNotificationText)
|
||||
}
|
||||
|
||||
fun removeBuilding(buildingName: String) {
|
||||
val buildingObject = city.getRuleset().buildings[buildingName]!!
|
||||
builtBuildingObjects = builtBuildingObjects.withoutItem(buildingObject)
|
||||
builtBuildings.remove(buildingName)
|
||||
city.civ.cache.updateCivResources() // this building could be a resource-requiring one
|
||||
city.civ.cache.updateCitiesConnectedToCapital(false) // could be a connecting building, like a harbor
|
||||
updateUniques()
|
||||
}
|
||||
|
||||
|
@ -209,7 +209,6 @@ class CityFounder {
|
||||
}
|
||||
|
||||
civInfo.civConstructions.tryAddFreeBuildings()
|
||||
city.cityConstructions.addFreeBuildings()
|
||||
}
|
||||
|
||||
|
||||
|
@ -49,7 +49,9 @@ class GoldenAgeManager : IsPartOfGameInfoSerialization {
|
||||
|
||||
for (unique in civInfo.getTriggeredUniques(UniqueType.TriggerUponEnteringGoldenAge))
|
||||
UniqueTriggerActivation.triggerCivwideUnique(unique, civInfo)
|
||||
civInfo.updateStatsForNextTurn()
|
||||
//Golden Age can happen mid turn with Great Artist effects
|
||||
for (city in civInfo.cities)
|
||||
city.cityStats.update()
|
||||
}
|
||||
|
||||
fun endTurn(happiness: Int) {
|
||||
|
@ -71,9 +71,13 @@ class UnitManager(val civInfo:Civilization) {
|
||||
val unit = civInfo.gameInfo.tileMap.placeUnitNearTile(location, unitName, civInfo)
|
||||
|
||||
if (unit != null) {
|
||||
val triggerNotificationText = "due to gaining a [${unit.name}]"
|
||||
for (unique in unit.getUniques())
|
||||
if (!unique.hasTriggerConditional())
|
||||
UniqueTriggerActivation.triggerUnitwideUnique(unique, unit, triggerNotificationText = triggerNotificationText)
|
||||
for (unique in civInfo.getTriggeredUniques(UniqueType.TriggerUponGainingUnit))
|
||||
if (unit.matchesFilter(unique.params[0]))
|
||||
UniqueTriggerActivation.triggerCivwideUnique(unique, civInfo)
|
||||
UniqueTriggerActivation.triggerCivwideUnique(unique, civInfo, triggerNotificationText = triggerNotificationText)
|
||||
if (unit.baseUnit.getResourceRequirementsPerTurn().isNotEmpty())
|
||||
civInfo.cache.updateCivResources()
|
||||
}
|
||||
|
@ -643,75 +643,14 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction {
|
||||
getRejectionReasons(cityConstructions).none()
|
||||
|
||||
override fun postBuildEvent(cityConstructions: CityConstructions, boughtWith: Stat?): Boolean {
|
||||
val city = cityConstructions.city
|
||||
val civInfo = city.civ
|
||||
|
||||
val civInfo = cityConstructions.city.civ
|
||||
|
||||
if (civInfo.gameInfo.spaceResources.contains(name)) {
|
||||
civInfo.victoryManager.currentsSpaceshipParts.add(name, 1)
|
||||
return true
|
||||
}
|
||||
|
||||
if (cityHealth > 0) {
|
||||
// city built a building that increases health so add a portion of this added health that is
|
||||
// proportional to the city's current health
|
||||
cityConstructions.city.health += (cityHealth.toFloat() * cityConstructions.city.health.toFloat() / cityConstructions.city.getMaxHealth().toFloat()).toInt()
|
||||
}
|
||||
|
||||
cityConstructions.addBuilding(name)
|
||||
|
||||
/** Support for [UniqueType.CreatesOneImprovement] */
|
||||
cityConstructions.applyCreateOneImprovement(this)
|
||||
|
||||
// "Provides a free [buildingName] [cityFilter]"
|
||||
cityConstructions.addFreeBuildings()
|
||||
|
||||
val triggerNotificationText ="due to constructing [$name]"
|
||||
|
||||
for (unique in uniqueObjects)
|
||||
if (!unique.hasTriggerConditional())
|
||||
UniqueTriggerActivation.triggerCivwideUnique(unique, civInfo, cityConstructions.city, triggerNotificationText = triggerNotificationText)
|
||||
|
||||
|
||||
for (unique in civInfo.getTriggeredUniques(UniqueType.TriggerUponConstructingBuilding, StateForConditionals(civInfo, city)))
|
||||
if (unique.conditionals.any {it.type == UniqueType.TriggerUponConstructingBuilding && matchesFilter(it.params[0])})
|
||||
UniqueTriggerActivation.triggerCivwideUnique(unique, city.civ, city, triggerNotificationText = triggerNotificationText)
|
||||
|
||||
for (unique in civInfo.getTriggeredUniques(UniqueType.TriggerUponConstructingBuildingCityFilter, StateForConditionals(city.civ, city)))
|
||||
if (unique.conditionals.any {it.type == UniqueType.TriggerUponConstructingBuildingCityFilter
|
||||
&& matchesFilter(it.params[0])
|
||||
&& city.matchesFilter(it.params[1])})
|
||||
UniqueTriggerActivation.triggerCivwideUnique(unique, city.civ, city, triggerNotificationText = triggerNotificationText)
|
||||
|
||||
if (hasUnique(UniqueType.EnemyUnitsSpendExtraMovement))
|
||||
civInfo.cache.updateHasActiveEnemyMovementPenalty()
|
||||
|
||||
// Korean unique - apparently gives the same as the research agreement
|
||||
if (isStatRelated(Stat.Science) && civInfo.hasUnique(UniqueType.TechBoostWhenScientificBuildingsBuiltInCapital))
|
||||
civInfo.tech.addScience(civInfo.tech.scienceOfLast8Turns.sum() / 8)
|
||||
|
||||
// Happiness change _may_ invalidate best worked tiles (#9238), but if the building
|
||||
// isn't bought (or the AI bought it) then reassignPopulation will run later in startTurn anyway
|
||||
if (boughtWith != null && isStatRelated(Stat.Happiness)) {
|
||||
// Happiness is global, so it could affect all cities
|
||||
Concurrency.runOnNonDaemonThreadPool("reassignPopulationAllCities") {
|
||||
for (city in civInfo.cities)
|
||||
city.reassignPopulationDeferred()
|
||||
}
|
||||
}
|
||||
|
||||
// Buying a building influencing tile yield may change CityFocus decisions
|
||||
val uniqueTypesModifyingYields = listOf(
|
||||
UniqueType.StatsFromTiles, UniqueType.StatsFromTilesWithout, UniqueType.StatsFromObject,
|
||||
UniqueType.StatPercentFromObject, UniqueType.AllStatsPercentFromObject
|
||||
)
|
||||
if (boughtWith != null && uniqueTypesModifyingYields.any { hasUnique(it) }) {
|
||||
cityConstructions.city.reassignPopulationDeferred()
|
||||
}
|
||||
|
||||
cityConstructions.city.cityStats.update() // new building, new stats
|
||||
civInfo.cache.updateCivResources() // this building/unit could be a resource-requiring one
|
||||
civInfo.cache.updateCitiesConnectedToCapital(false) // could be a connecting building, like a harbor
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ class Unique(val text: String, val sourceObjectType: UniqueTarget? = null, val s
|
||||
fun hasTriggerConditional(): Boolean {
|
||||
if(conditionals.none()) return false
|
||||
return conditionals.any{ conditional -> conditional.type?.targetTypes
|
||||
?.any{ it.canAcceptUniqueTarget(UniqueTarget.TriggerCondition) }
|
||||
?.any{ it.canAcceptUniqueTarget(UniqueTarget.TriggerCondition) || it.canAcceptUniqueTarget(UniqueTarget.UnitActionModifier) }
|
||||
?: false
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user