From ef7fc36c80d27c7335d9c5c042952bb0d18e7034 Mon Sep 17 00:00:00 2001 From: SomeTroglodyte <63000004+SomeTroglodyte@users.noreply.github.com> Date: Sat, 28 Aug 2021 21:26:00 +0200 Subject: [PATCH] Harden automateImprovementPlacer and detect Mod problems with these (#5010) --- .../logic/automation/SpecificUnitAutomation.kt | 6 ++++-- core/src/com/unciv/models/ruleset/Ruleset.kt | 14 ++++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/core/src/com/unciv/logic/automation/SpecificUnitAutomation.kt b/core/src/com/unciv/logic/automation/SpecificUnitAutomation.kt index cd88c0adc0..291618b9c5 100644 --- a/core/src/com/unciv/logic/automation/SpecificUnitAutomation.kt +++ b/core/src/com/unciv/logic/automation/SpecificUnitAutomation.kt @@ -9,6 +9,7 @@ import com.unciv.logic.map.MapUnit import com.unciv.logic.map.TileInfo import com.unciv.models.ruleset.tile.ResourceType import com.unciv.models.ruleset.tile.TileResource +import com.unciv.models.stats.Stat import com.unciv.models.stats.Stats import com.unciv.ui.worldscreen.unit.UnitActions @@ -217,8 +218,9 @@ object SpecificUnitAutomation { fun automateImprovementPlacer(unit: MapUnit) { val improvementName = unit.getMatchingUniques("Can construct []").first().params[0] - val improvement = unit.civInfo.gameInfo.ruleSet.tileImprovements[improvementName]!! - val relatedStat = improvement.maxByOrNull { it.value }!!.key + val improvement = unit.civInfo.gameInfo.ruleSet.tileImprovements[improvementName] + ?: return + val relatedStat = improvement.maxByOrNull { it.value }?.key ?: Stat.Culture val citiesByStatBoost = unit.civInfo.cities.sortedByDescending { val stats = Stats() diff --git a/core/src/com/unciv/models/ruleset/Ruleset.kt b/core/src/com/unciv/models/ruleset/Ruleset.kt index 18fcbb5bcc..7e3a945e78 100644 --- a/core/src/com/unciv/models/ruleset/Ruleset.kt +++ b/core/src/com/unciv/models/ruleset/Ruleset.kt @@ -299,7 +299,7 @@ class Ruleset { val lines = ArrayList() var warningCount = 0 - // Checks for all mods + // Checks for all mods - only those that can succeed without loading a base ruleset for (unit in units.values) { if (unit.upgradesTo == unit.name) lines += "${unit.name} upgrades to itself!" @@ -327,9 +327,10 @@ class Ruleset { } } + // Quit here when no base ruleset is loaded - references cannot be checked if (!modOptions.isBaseRuleset) return CheckModLinksResult(warningCount, lines) - val baseRuleset = RulesetCache.getBaseRuleset() + val baseRuleset = RulesetCache.getBaseRuleset() // for UnitTypes fallback for (unit in units.values) { if (unit.requiredTech != null && !technologies.containsKey(unit.requiredTech!!)) @@ -348,6 +349,15 @@ class Ruleset { lines += "${unit.name} contains promotion $promotion which does not exist!" if (!unitTypes.containsKey(unit.unitType) && !baseRuleset.unitTypes.containsKey(unit.unitType)) lines += "${unit.name} is of type ${unit.unitType}, which does not exist!" + for (unique in unit.getMatchingUniques("Can construct []")) { + val improvementName = unique.params[0] + if (improvementName !in tileImprovements) + lines += "${unit.name} can place improvement $improvementName which does not exist!" + else if (tileImprovements[improvementName]!!.firstOrNull() == null && !unit.hasUnique("Bonus for units in 2 tile radius 15%")) { + lines += "${unit.name} can place improvement $improvementName which has no stats, preventing unit automation!" + warningCount++ + } + } } for (building in buildings.values) {