mirror of
https://github.com/yairm210/Unciv.git
synced 2025-03-03 22:22:51 +07:00
Fix obsoleted units replace in construction queues for Nation-unique upgrades (#9044)
This commit is contained in:
parent
d3305e680a
commit
13f4dd0756
@ -334,70 +334,53 @@ class TechManager : IsPartOfGameInfoSerialization {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun obsoleteOldUnits(techName: String) {
|
private fun obsoleteOldUnits(techName: String) {
|
||||||
val obsoleteUnits =
|
// First build a map with obsoleted units to their (nation-specific) upgrade
|
||||||
getRuleset().units.values.filter { it.obsoleteTech == techName }.map { it.name }
|
val ruleset = getRuleset()
|
||||||
val unitUpgrades = HashMap<String, HashSet<City>>()
|
fun BaseUnit.getEquivalentUpgradeOrNull(): BaseUnit? {
|
||||||
for (city in civInfo.cities) {
|
if (upgradesTo !in ruleset.units) return null // also excludes upgradesTo==null
|
||||||
// Do not use replaceAll - that's a Java 8 feature and will fail on older phones!
|
return civInfo.getEquivalentUnit(upgradesTo!!)
|
||||||
val oldQueue =
|
|
||||||
city.cityConstructions.constructionQueue.toList() // copy, since we're changing the queue
|
|
||||||
city.cityConstructions.constructionQueue.clear()
|
|
||||||
for (constructionName in oldQueue) {
|
|
||||||
if (constructionName in obsoleteUnits) {
|
|
||||||
if (constructionName !in unitUpgrades.keys) {
|
|
||||||
unitUpgrades[constructionName] = hashSetOf()
|
|
||||||
}
|
|
||||||
unitUpgrades[constructionName]?.add(city)
|
|
||||||
val construction = city.cityConstructions.getConstruction(constructionName)
|
|
||||||
if (construction is BaseUnit && construction.upgradesTo != null) {
|
|
||||||
city.cityConstructions.constructionQueue.add(construction.upgradesTo!!)
|
|
||||||
}
|
|
||||||
} else city.cityConstructions.constructionQueue.add(constructionName)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
val obsoleteUnits = getRuleset().units.asSequence()
|
||||||
|
.filter { it.value.obsoleteTech == techName }
|
||||||
|
.map { it.key to it.value.getEquivalentUpgradeOrNull() }
|
||||||
|
.toMap()
|
||||||
|
if (obsoleteUnits.isEmpty()) return
|
||||||
|
|
||||||
|
// Apply each to all cities - and remember which cities had which obsoleted unit
|
||||||
|
// in their construction queues in this Map<String, MutableSet<City>>:
|
||||||
|
val unitUpgrades = obsoleteUnits.keys.associateWith { mutableSetOf<City>() }
|
||||||
|
fun transformConstruction(old: String, city: City): String? {
|
||||||
|
val entry = unitUpgrades[old] ?: return old // Entry OK, not obsolete
|
||||||
|
entry.add(city) // Remember city has updated its queue
|
||||||
|
return obsoleteUnits[old]?.name // Replacement, or pass through null to remove from queue
|
||||||
|
}
|
||||||
|
for (city in civInfo.cities) {
|
||||||
|
// Replace queue - the sequence iteration and finalization happens before the result
|
||||||
|
// is reassigned, therefore no concurrent modification worries
|
||||||
|
city.cityConstructions.constructionQueue =
|
||||||
|
city.cityConstructions.constructionQueue
|
||||||
|
.asSequence()
|
||||||
|
.mapNotNull { transformConstruction(it, city) }
|
||||||
|
.toMutableList()
|
||||||
|
}
|
||||||
|
|
||||||
|
// As long as TurnManager does cities after tech, we don't need to clean up
|
||||||
|
// inProgressConstructions - CityConstructions.validateInProgressConstructions does it.
|
||||||
|
|
||||||
// Add notifications for obsolete units/constructions
|
// Add notifications for obsolete units/constructions
|
||||||
for ((unit, cities) in unitUpgrades) {
|
for ((unit, cities) in unitUpgrades) {
|
||||||
val construction = cities.first().cityConstructions.getConstruction(unit)
|
if (cities.isEmpty()) continue
|
||||||
if (cities.size == 1) {
|
val locationAction = LocationAction(cities.mapTo(ArrayList(cities.size)) { it.location })
|
||||||
val city = cities.first()
|
val cityText = if (cities.size == 1) "[${cities.first().name}]"
|
||||||
if (construction is BaseUnit && construction.upgradesTo != null) {
|
else "[${cities.size}] cities"
|
||||||
val text =
|
val newUnit = obsoleteUnits[unit]?.name
|
||||||
"[${city.name}] changed production from [$unit] to [${construction.upgradesTo!!}]"
|
val text = if (newUnit == null)
|
||||||
civInfo.addNotification(
|
"[$unit] has become obsolete and was removed from the queue in $cityText!"
|
||||||
text, city.location,
|
else "$cityText changed production from [$unit] to [$newUnit]"
|
||||||
NotificationCategory.Production, unit,
|
val icons = if (newUnit == null)
|
||||||
NotificationIcon.Construction, construction.upgradesTo!!
|
arrayOf(NotificationIcon.Construction)
|
||||||
)
|
else arrayOf(unit, NotificationIcon.Construction, newUnit)
|
||||||
} else {
|
civInfo.addNotification(text, locationAction, NotificationCategory.Production, *icons)
|
||||||
val text =
|
|
||||||
"[$unit] has become obsolete and was removed from the queue in [${city.name}]!"
|
|
||||||
civInfo.addNotification(
|
|
||||||
text, city.location,
|
|
||||||
NotificationCategory.Production,
|
|
||||||
NotificationIcon.Construction
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
val locationAction = LocationAction(cities.asSequence().map { it.location })
|
|
||||||
if (construction is BaseUnit && construction.upgradesTo != null) {
|
|
||||||
val text =
|
|
||||||
"[${cities.size}] cities changed production from [$unit] to [${construction.upgradesTo!!}]"
|
|
||||||
civInfo.addNotification(
|
|
||||||
text, locationAction,
|
|
||||||
NotificationCategory.Production, unit,
|
|
||||||
NotificationIcon.Construction, construction.upgradesTo!!
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
val text =
|
|
||||||
"[$unit] has become obsolete and was removed from the queue in [${cities.size}] cities!"
|
|
||||||
civInfo.addNotification(
|
|
||||||
text, locationAction,
|
|
||||||
NotificationCategory.Production,
|
|
||||||
NotificationIcon.Construction
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user