More informative exceptions, to try and catch the "invalid city ID on trade" crash

This commit is contained in:
yairm210 2021-12-03 11:12:48 +02:00
parent 69db686101
commit 7169458943
2 changed files with 18 additions and 9 deletions

View File

@ -135,7 +135,8 @@ class TradeEvaluation {
} }
} }
TradeType.City -> { 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 stats = city.cityStats.currentCityStats
val surrounded: Int = surroundedByOurCities(city, civInfo) val surrounded: Int = surroundedByOurCities(city, civInfo)
if (civInfo.getHappiness() + city.cityStats.happinessList.values.sum() < 0) if (civInfo.getHappiness() + city.cityStats.happinessList.values.sum() < 0)
@ -175,23 +176,27 @@ class TradeEvaluation {
return when { return when {
civInfo.getCivResourcesByName()[offer.name]!! > 1 -> 250 // fair price civInfo.getCivResourcesByName()[offer.name]!! > 1 -> 250 // fair price
civInfo.hasUnique(UniqueType.RetainHappinessFromLuxury) -> // If we retain 50% happiness, value at 375 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?! else -> 500 // you want to take away our last lux of this type?!
} }
} }
TradeType.Strategic_Resource -> { TradeType.Strategic_Resource -> {
if (civInfo.gameInfo.spaceResources.contains(offer.name) && if (civInfo.gameInfo.spaceResources.contains(offer.name) &&
(civInfo.hasUnique("Enables construction of Spaceship parts") || (civInfo.hasUnique("Enables construction of Spaceship parts") ||
tradePartner.hasUnique("Enables construction of Spaceship parts"))) tradePartner.hasUnique("Enables construction of Spaceship parts"))
return 10000 // We'd rather win the game, thanks )
return 10000 // We'd rather win the game, thanks
if (!civInfo.isAtWar()) return 50 * offer.amount if (!civInfo.isAtWar()) return 50 * offer.amount
val canUseForUnits = civInfo.gameInfo.ruleSet.units.values 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 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 // 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 // That is to say, if I have 4 and you take one away, that's 200
@ -224,11 +229,14 @@ class TradeEvaluation {
} }
TradeType.City -> { 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 capitalcity = civInfo.getCapital()
val distanceCost = distanceCityTradeModifier(civInfo, capitalcity, city) val distanceCost = distanceCityTradeModifier(civInfo, capitalcity, city)
val stats = city.cityStats.currentCityStats 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 return sumOfStats.toInt() * 100
} }
TradeType.Agreement -> { TradeType.Agreement -> {
@ -245,6 +253,7 @@ class TradeEvaluation {
} }
} }
} }
fun distanceCityTradeModifier(civInfo: CivilizationInfo, capitalcity: CityInfo, city: CityInfo): Int{ fun distanceCityTradeModifier(civInfo: CivilizationInfo, capitalcity: CityInfo, city: CityInfo): Int{
val distanceBetweenCities = capitalcity.getCenterTile().aerialDistanceTo(city.getCenterTile()) val distanceBetweenCities = capitalcity.getCenterTile().aerialDistanceTo(city.getCenterTile())

View File

@ -167,7 +167,7 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction {
if (maintenance != 0 && !isFree) lines += "{Maintenance cost}: $maintenance {Gold}" if (maintenance != 0 && !isFree) lines += "{Maintenance cost}: $maintenance {Gold}"
if (!missingcities.isEmpty()) { if (!missingcities.isEmpty()) {
// Could be red. But IMO that should be done by enabling GDX's ColorMarkupLanguage globally instead of adding a separate label. // 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. // 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() return lines.joinToString("\n") { it.tr() }.trim()