diff --git a/build.gradle.kts b/build.gradle.kts index 90a21d0fbb..a5e8a3ddba 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -38,7 +38,7 @@ plugins { // This is *with* gradle 8.2 downloaded according the project specs, no idea what that's about kotlin("multiplatform") version "1.9.24" kotlin("plugin.serialization") version "1.9.24" - id("io.github.yairm210.purity-plugin") version "1.1.0" apply(false) + id("io.github.yairm210.purity-plugin") version "1.1.1" apply(false) } allprojects { @@ -68,6 +68,8 @@ allprojects { "kotlin.collections.sortBy", // moved "kotlin.Throwable.getStackTrace", // moved + + "kotlin.collections.random", ) wellKnownPureClasses = setOf( "java.lang.StackTraceElement" // moved diff --git a/core/src/com/unciv/logic/automation/Automation.kt b/core/src/com/unciv/logic/automation/Automation.kt index d1d6a30289..2b25c0d84f 100644 --- a/core/src/com/unciv/logic/automation/Automation.kt +++ b/core/src/com/unciv/logic/automation/Automation.kt @@ -20,6 +20,7 @@ import com.unciv.models.ruleset.unit.BaseUnit import com.unciv.models.stats.Stat import com.unciv.models.stats.Stats import com.unciv.ui.screens.victoryscreen.RankingType +import yairm210.purity.annotations.LocalState import yairm210.purity.annotations.Readonly import kotlin.math.min @@ -46,6 +47,7 @@ object Automation { } // More complicated logic to properly weigh Food vs other Stats (esp Production) + @Readonly private fun getFoodModWeight(city: City, surplusFood: Float): Float { val speed = city.civ.gameInfo.speed.modifier // Zero out Growth if close to Unhappiness limit @@ -66,11 +68,11 @@ object Automation { return 1f } - + + @Readonly fun rankStatsForCityWork(stats: Stats, city: City, areWeRankingSpecialist: Boolean, localUniqueCache: LocalUniqueCache): Float { val cityAIFocus = city.getCityFocus() - val yieldStats = stats.clone() - val civPersonality = city.civ.getPersonality() + @LocalState val yieldStats = stats.clone() val cityStatsObj = city.cityStats val civInfo = city.civ val allTechsAreResearched = civInfo.tech.allTechsAreResearched() @@ -168,7 +170,12 @@ object Automation { } // Apply City focus - cityAIFocus.applyWeightTo(yieldStats) + for (stat in cityAIFocus.statValuesForFocus) { + val currentStat = yieldStats[stat] + if (currentStat == 0f) continue + val statMultiplier = cityAIFocus.getStatMultiplier(stat) + yieldStats[stat] = currentStat * statMultiplier + } return yieldStats.values.sum() } @@ -206,6 +213,7 @@ object Automation { return totalCarriableUnits < totalCarryingSlots } + @Readonly fun chooseMilitaryUnit(city: City, availableUnits: Sequence): String? { val currentChoice = city.cityConstructions.getCurrentConstruction() if (currentChoice is BaseUnit && !currentChoice.isCivilian()) return city.cityConstructions.currentConstructionFromQueue @@ -313,6 +321,7 @@ object Automation { /** Checks both feasibility of Buildings with a CreatesOneImprovement unique * and resource scarcity making a construction undesirable. */ + @Readonly fun allowAutomatedConstruction( civInfo: Civilization, city: City, @@ -325,6 +334,7 @@ object Automation { @Suppress("MemberVisibilityCanBePrivate") /** Checks both feasibility of Buildings with a [UniqueType.CreatesOneImprovement] unique (appropriate tile available). * Constructions without pass uncontested. */ + @Readonly fun allowCreateImprovementBuildings( civInfo: Civilization, city: City, diff --git a/core/src/com/unciv/logic/city/CityFocus.kt b/core/src/com/unciv/logic/city/CityFocus.kt index 4db6915cce..d363216574 100644 --- a/core/src/com/unciv/logic/city/CityFocus.kt +++ b/core/src/com/unciv/logic/city/CityFocus.kt @@ -69,19 +69,10 @@ enum class CityFocus( else -> 1f } - private val statValuesForFocus: List by lazy { + val statValuesForFocus: List by lazy { Stat.entries.filter { getStatMultiplier(it) != 1f } } - fun applyWeightTo(stats: Stats) { - for (stat in statValuesForFocus) { - val currentStat = stats[stat] - if (currentStat == 0f) continue - val statMultiplier = getStatMultiplier(stat) - stats[stat] = currentStat * statMultiplier - } - } - companion object { @Pure fun safeValueOf(stat: Stat): CityFocus = entries.firstOrNull { it.stat == stat } ?: NoFocus diff --git a/core/src/com/unciv/logic/city/CityStats.kt b/core/src/com/unciv/logic/city/CityStats.kt index b53ebbfde2..f7ccb54a2a 100644 --- a/core/src/com/unciv/logic/city/CityStats.kt +++ b/core/src/com/unciv/logic/city/CityStats.kt @@ -155,6 +155,7 @@ class CityStats(val city: City) { return Stats(science = -25f, culture = -25f) } + @Readonly fun getGrowthBonus(totalFood: Float): StatMap { val growthSources = StatMap() val stateForConditionals = city.state diff --git a/core/src/com/unciv/models/stats/Stats.kt b/core/src/com/unciv/models/stats/Stats.kt index baf4903a95..0d0f9bdaf8 100644 --- a/core/src/com/unciv/models/stats/Stats.kt +++ b/core/src/com/unciv/models/stats/Stats.kt @@ -283,6 +283,7 @@ open class Stats( } } +@InternalState class StatMap : LinkedHashMap() { fun add(source: String, stats: Stats) { // We always clone to avoid touching the mutable stats of uniques