From 4b5bb54b72dbafd7ef519dae464057f72a93bbe8 Mon Sep 17 00:00:00 2001 From: dHannasch Date: Sun, 17 Dec 2023 13:00:45 -0700 Subject: [PATCH] Add BaseUnit.automaticallyUpgradedInProductionToUnitByTech() (#10664) * Update BaseUnit.kt * Update RulesetValidator.kt * Update BasicTests.kt * Update BaseUnit.kt * Update TechManager.kt * Update BaseUnit.kt * Update BaseUnit.kt --- .../unciv/logic/civilization/managers/TechManager.kt | 11 ++++++----- core/src/com/unciv/models/ruleset/unit/BaseUnit.kt | 10 ++++++++++ .../models/ruleset/validation/RulesetValidator.kt | 7 +++++-- tests/src/com/unciv/testing/BasicTests.kt | 3 ++- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/core/src/com/unciv/logic/civilization/managers/TechManager.kt b/core/src/com/unciv/logic/civilization/managers/TechManager.kt index ffb5fe0c66..fe57b18bd7 100644 --- a/core/src/com/unciv/logic/civilization/managers/TechManager.kt +++ b/core/src/com/unciv/logic/civilization/managers/TechManager.kt @@ -346,13 +346,14 @@ class TechManager : IsPartOfGameInfoSerialization { private fun obsoleteOldUnits(techName: String) { // First build a map with obsoleted units to their (nation-specific) upgrade val ruleset = getRuleset() - fun BaseUnit.getEquivalentUpgradeOrNull(): BaseUnit? { - if (upgradesTo !in ruleset.units) return null // also excludes upgradesTo==null - return civInfo.getEquivalentUnit(upgradesTo!!) + fun BaseUnit.getEquivalentUpgradeOrNull(techName: String): BaseUnit? { + val unitUpgradesTo: String? = automaticallyUpgradedInProductionToUnitByTech(techName) + if (unitUpgradesTo == null) + return null + return civInfo.getEquivalentUnit(unitUpgradesTo!!) } val obsoleteUnits = getRuleset().units.asSequence() - .filter { it.value.isObsoletedBy(techName) } - .map { it.key to it.value.getEquivalentUpgradeOrNull() } + .map { it.key to it.value.getEquivalentUpgradeOrNull(techName) } .toMap() if (obsoleteUnits.isEmpty()) return diff --git a/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt b/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt index cdbac2b922..914b71623b 100644 --- a/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt +++ b/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt @@ -49,6 +49,7 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction { var promotions = HashSet() var obsoleteTech: String? = null fun techsThatObsoleteThis(): Sequence = if (obsoleteTech == null) sequenceOf() else sequenceOf(obsoleteTech!!) + fun techsAtWhichAutoUpgradeInProduction(): Sequence = techsThatObsoleteThis() fun techsAtWhichNoLongerAvailable(): Sequence = techsThatObsoleteThis() fun isObsoletedBy(techName: String): Boolean = techsThatObsoleteThis().contains(techName) var upgradesTo: String? = null @@ -228,6 +229,15 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction { return true } + // This returns the name of the unit this tech upgrades this unit to, + // or null if there is no automatic upgrade at that tech. + fun automaticallyUpgradedInProductionToUnitByTech(techName: String): String? { + for (obsoleteTech: String in techsAtWhichAutoUpgradeInProduction()) + if (obsoleteTech != null && obsoleteTech == techName) + return upgradesTo + return null + } + fun addConstructionBonuses(unit: MapUnit, cityConstructions: CityConstructions) { val civInfo = cityConstructions.city.civ diff --git a/core/src/com/unciv/models/ruleset/validation/RulesetValidator.kt b/core/src/com/unciv/models/ruleset/validation/RulesetValidator.kt index 1f4c7d2e7b..2914883bf1 100644 --- a/core/src/com/unciv/models/ruleset/validation/RulesetValidator.kt +++ b/core/src/com/unciv/models/ruleset/validation/RulesetValidator.kt @@ -664,11 +664,14 @@ class RulesetValidator(val ruleset: Ruleset) { for (obsoleteTech: String in unit.techsAtWhichNoLongerAvailable()) if (!ruleset.technologies.containsKey(obsoleteTech)) lines += "${unit.name} obsoletes at tech ${obsoleteTech} which does not exist!" + for (obsoleteTech: String in unit.techsAtWhichAutoUpgradeInProduction()) + if (!ruleset.technologies.containsKey(obsoleteTech)) + lines += "${unit.name} upgrades at tech ${obsoleteTech} which does not exist!" if (unit.upgradesTo != null && !ruleset.units.containsKey(unit.upgradesTo!!)) lines += "${unit.name} upgrades to unit ${unit.upgradesTo} which does not exist!" // Check that we don't obsolete ourselves before we can upgrade - for (obsoleteTech: String in unit.techsThatObsoleteThis()) + for (obsoleteTech: String in unit.techsAtWhichAutoUpgradeInProduction()) if (unit.upgradesTo!=null && ruleset.units.containsKey(unit.upgradesTo!!) && ruleset.technologies.containsKey(obsoleteTech)) { val upgradedUnit = ruleset.units[unit.upgradesTo!!]!! @@ -677,7 +680,7 @@ class RulesetValidator(val ruleset: Ruleset) { && !getPrereqTree(obsoleteTech).contains(requiredTech) ) lines.add( - "${unit.name} obsoletes at tech ${obsoleteTech}," + + "${unit.name} is supposed to automatically upgrade at tech ${obsoleteTech}," + " and therefore ${requiredTech} for its upgrade ${upgradedUnit.name} may not yet be researched!", RulesetErrorSeverity.Warning ) diff --git a/tests/src/com/unciv/testing/BasicTests.kt b/tests/src/com/unciv/testing/BasicTests.kt index 04c8ea3b42..d468cf92a3 100644 --- a/tests/src/com/unciv/testing/BasicTests.kt +++ b/tests/src/com/unciv/testing/BasicTests.kt @@ -63,12 +63,13 @@ class BasicTests { // If there's a unit that obsoletes with no upgrade then when it obsoletes // and we try to work on its upgrade, we'll get an exception - see techManager + // But...Scout obsoletes at Scientific Theory with no upgrade...? @Test fun allObsoletingUnitsHaveUpgrades() { val units: Collection = ruleset.units.values var allObsoletingUnitsHaveUpgrades = true for (unit in units) { - if (unit.techsThatObsoleteThis().any() && unit.upgradesTo == null && unit.name !="Scout" ) { + if (unit.techsAtWhichAutoUpgradeInProduction().any() && unit.upgradesTo == null && unit.name !="Scout" ) { debug("%s obsoletes but has no upgrade", unit.name) allObsoletingUnitsHaveUpgrades = false }