From 71694589433775846af1e9b2c3c31841698bc201 Mon Sep 17 00:00:00 2001 From: yairm210 Date: Fri, 3 Dec 2021 11:12:48 +0200 Subject: [PATCH] More informative exceptions, to try and catch the "invalid city ID on trade" crash --- .../com/unciv/logic/trade/TradeEvaluation.kt | 25 +++++++++++++------ core/src/com/unciv/models/ruleset/Building.kt | 2 +- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/core/src/com/unciv/logic/trade/TradeEvaluation.kt b/core/src/com/unciv/logic/trade/TradeEvaluation.kt index 1295573ed6..52448a454a 100644 --- a/core/src/com/unciv/logic/trade/TradeEvaluation.kt +++ b/core/src/com/unciv/logic/trade/TradeEvaluation.kt @@ -135,7 +135,8 @@ class TradeEvaluation { } } TradeType.City -> { - val city = tradePartner.cities.first { it.id == offer.name } + val city = tradePartner.cities.firstOrNull { it.id == offer.name } + ?: throw Exception("Got an offer for city id "+offer.name+" which does't seem to exist for this civ!") val stats = city.cityStats.currentCityStats val surrounded: Int = surroundedByOurCities(city, civInfo) if (civInfo.getHappiness() + city.cityStats.happinessList.values.sum() < 0) @@ -175,23 +176,27 @@ class TradeEvaluation { return when { civInfo.getCivResourcesByName()[offer.name]!! > 1 -> 250 // fair price civInfo.hasUnique(UniqueType.RetainHappinessFromLuxury) -> // If we retain 50% happiness, value at 375 - 750 - (civInfo.getMatchingUniques(UniqueType.RetainHappinessFromLuxury).first().params[0].toPercent() * 250).toInt() + 750 - (civInfo.getMatchingUniques(UniqueType.RetainHappinessFromLuxury) + .first().params[0].toPercent() * 250).toInt() else -> 500 // you want to take away our last lux of this type?! } } TradeType.Strategic_Resource -> { if (civInfo.gameInfo.spaceResources.contains(offer.name) && (civInfo.hasUnique("Enables construction of Spaceship parts") || - tradePartner.hasUnique("Enables construction of Spaceship parts"))) - return 10000 // We'd rather win the game, thanks + tradePartner.hasUnique("Enables construction of Spaceship parts")) + ) + return 10000 // We'd rather win the game, thanks if (!civInfo.isAtWar()) return 50 * offer.amount val canUseForUnits = civInfo.gameInfo.ruleSet.units.values - .any { it.getResourceRequirements().containsKey(offer.name) && it.isBuildable(civInfo) } + .any { it.getResourceRequirements().containsKey(offer.name) + && it.isBuildable(civInfo) } if (!canUseForUnits) return 50 * offer.amount - val amountLeft = civInfo.getCivResourcesByName()[offer.name]!! + val amountLeft = civInfo.getCivResourcesByName()[offer.name] + ?: throw Exception("Got a strategic resource offer but the the resource doesn't exist in this ruleset!") // Each strategic resource starts costing 100 more when we ass the 5 resources baseline // That is to say, if I have 4 and you take one away, that's 200 @@ -224,11 +229,14 @@ class TradeEvaluation { } TradeType.City -> { - val city = civInfo.cities.first { it.id == offer.name } + val city = civInfo.cities.firstOrNull { it.id == offer.name } + ?: throw Exception("Got an offer to sell city id " + offer.name + " which does't seem to exist for this civ!") + val capitalcity = civInfo.getCapital() val distanceCost = distanceCityTradeModifier(civInfo, capitalcity, city) val stats = city.cityStats.currentCityStats - val sumOfStats = stats.culture + stats.gold + stats.science + stats.production + stats.happiness + stats.food - distanceCost + val sumOfStats = + stats.culture + stats.gold + stats.science + stats.production + stats.happiness + stats.food - distanceCost return sumOfStats.toInt() * 100 } TradeType.Agreement -> { @@ -245,6 +253,7 @@ class TradeEvaluation { } } } + fun distanceCityTradeModifier(civInfo: CivilizationInfo, capitalcity: CityInfo, city: CityInfo): Int{ val distanceBetweenCities = capitalcity.getCenterTile().aerialDistanceTo(city.getCenterTile()) diff --git a/core/src/com/unciv/models/ruleset/Building.kt b/core/src/com/unciv/models/ruleset/Building.kt index 48f4b517be..080e582c4a 100644 --- a/core/src/com/unciv/models/ruleset/Building.kt +++ b/core/src/com/unciv/models/ruleset/Building.kt @@ -167,7 +167,7 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { if (maintenance != 0 && !isFree) lines += "{Maintenance cost}: $maintenance {Gold}" if (!missingcities.isEmpty()) { // Could be red. But IMO that should be done by enabling GDX's ColorMarkupLanguage globally instead of adding a separate label. - lines += "\n" + "[${cityInfo?.civInfo?.getEquivalentBuilding(missingunique!!.params!![0])}] required:".tr() + " " + missingcities.map{ "{${it.name}}" }.joinToString(", ") + lines += "\n" + "[${cityInfo?.civInfo?.getEquivalentBuilding(missingunique!!.params[0])}] required:".tr() + " " + missingcities.map{ "{${it.name}}" }.joinToString(", ") // Can't nest square bracket placeholders inside curlies, and don't see any way to define wildcard placeholders. So run translation explicitly on base text. } return lines.joinToString("\n") { it.tr() }.trim()