diff --git a/core/src/com/unciv/logic/city/CityStats.kt b/core/src/com/unciv/logic/city/CityStats.kt index 6fd96f9d5e..7af4bc0c8c 100644 --- a/core/src/com/unciv/logic/city/CityStats.kt +++ b/core/src/com/unciv/logic/city/CityStats.kt @@ -265,10 +265,10 @@ class CityStats { private fun getStatsFromUniques(uniques: Sequence): Stats { val stats = Stats() - for (unique in uniques) { - if ((unique.placeholderText == "[] in capital" && cityInfo.isCapital()) + for (unique in uniques.toList()) { // Should help mitigate getConstructionButtonDTOs concurrency problems. + if (unique.placeholderText == "[] in capital" && cityInfo.isCapital() || unique.placeholderText == "[] in all cities" - || (unique.placeholderText == "[] in all cities with a garrison" && cityInfo.getCenterTile().militaryUnit != null)) + || unique.placeholderText == "[] in all cities with a garrison" && cityInfo.getCenterTile().militaryUnit != null) stats.add(unique.stats) if (unique.placeholderText == "[] per [] population in all cities") { val amountOfEffects = (cityInfo.population.population / unique.params[1].toInt()).toFloat() @@ -317,8 +317,11 @@ class CityStats { return stats } - private fun getStatPercentBonusesFromUniques(currentConstruction: IConstruction, uniques: Sequence): Stats { + private fun getStatPercentBonusesFromUniques(currentConstruction: IConstruction, uniqueSequence: Sequence): Stats { val stats = Stats() + val uniques = uniqueSequence.toList().asSequence() + // Since this is sometimes run from a different thread (getConstructionButtonDTOs), + // this helps mitigate concurrency problems. if (currentConstruction.name == Constants.settler && cityInfo.isCapital() && uniques.any { it.text == "Training of settlers increased +50% in capital" }) diff --git a/core/src/com/unciv/logic/civilization/CivInfoStats.kt b/core/src/com/unciv/logic/civilization/CivInfoStats.kt index a2a8d0a743..6291ba38d0 100644 --- a/core/src/com/unciv/logic/civilization/CivInfoStats.kt +++ b/core/src/com/unciv/logic/civilization/CivInfoStats.kt @@ -143,11 +143,14 @@ class CivInfoStats(val civInfo: CivilizationInfo){ statMap["Luxury resources"]= civInfo.getCivResources().map { it.resource } .count { it.resourceType === ResourceType.Luxury } * happinessPerUniqueLuxury - for(city in civInfo.cities){ - for(keyvalue in city.cityStats.happinessList){ - if(statMap.containsKey(keyvalue.key)) - statMap[keyvalue.key] = statMap[keyvalue.key]!!+keyvalue.value - else statMap[keyvalue.key] = keyvalue.value + for(city in civInfo.cities) { + // There appears to be a concurrency problem? In concurrent thread in ConstructionsTable.getConstructionButtonDTOs + // Literally no idea how, since happinessList is ONLY replaced, NEVER altered. + // Oh well, toList() should solve the problem, wherever it may come from. + for ((key, value) in city.cityStats.happinessList.toList()) { + if (statMap.containsKey(key)) + statMap[key] = statMap[key]!! + value + else statMap[key] = value } }