chore(purity): TileImprovement

This commit is contained in:
yairm210 2025-07-31 18:21:04 +03:00
parent f45fe20ab0
commit 01a4025287
3 changed files with 12 additions and 3 deletions

View File

@ -69,6 +69,7 @@ allprojects {
"kotlin.Array.get", "kotlin.Array.get",
"kotlin.collections.mutableSetOf", "kotlin.collections.mutableSetOf",
"kotlin.collections.withIndex", // applicable to sequence as well "kotlin.collections.withIndex", // applicable to sequence as well
"kotlin.collections.intersect",
) )
wellKnownPureClasses = setOf( wellKnownPureClasses = setOf(
"java.util.Locale", // moved "java.util.Locale", // moved

View File

@ -14,6 +14,7 @@ import com.unciv.models.ruleset.unit.BaseUnit
import com.unciv.ui.components.extensions.toPercent import com.unciv.ui.components.extensions.toPercent
import com.unciv.ui.objectdescriptions.ImprovementDescriptions import com.unciv.ui.objectdescriptions.ImprovementDescriptions
import com.unciv.ui.screens.civilopediascreen.FormattedLine import com.unciv.ui.screens.civilopediascreen.FormattedLine
import yairm210.purity.annotations.LocalState
import yairm210.purity.annotations.Readonly import yairm210.purity.annotations.Readonly
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -30,6 +31,7 @@ class TileImprovement : RulesetStatsObject() {
override fun legacyRequiredTechs() = if (techRequired == null) emptySequence() else sequenceOf(techRequired!!) override fun legacyRequiredTechs() = if (techRequired == null) emptySequence() else sequenceOf(techRequired!!)
@Readonly
fun getTurnsToBuild(civInfo: Civilization, unit: MapUnit): Int { fun getTurnsToBuild(civInfo: Civilization, unit: MapUnit): Int {
val state = GameContext(civInfo, unit = unit) val state = GameContext(civInfo, unit = unit)
@ -103,6 +105,7 @@ class TileImprovement : RulesetStatsObject() {
override fun getCivilopediaTextLines(ruleset: Ruleset): List<FormattedLine> = override fun getCivilopediaTextLines(ruleset: Ruleset): List<FormattedLine> =
ImprovementDescriptions.getCivilopediaTextLines(this, ruleset) ImprovementDescriptions.getCivilopediaTextLines(this, ruleset)
@Readonly
fun getConstructorUnits(ruleset: Ruleset): List<BaseUnit> { fun getConstructorUnits(ruleset: Ruleset): List<BaseUnit> {
//todo Why does this have to be so complicated? A unit's "Can build [Land] improvements on tiles" //todo Why does this have to be so complicated? A unit's "Can build [Land] improvements on tiles"
// creates the _justified_ expectation that an improvement it can build _will_ have // creates the _justified_ expectation that an improvement it can build _will_ have
@ -112,10 +115,11 @@ class TileImprovement : RulesetStatsObject() {
val canOnlyFilters = getMatchingUniques(UniqueType.CanOnlyBeBuiltOnTile) val canOnlyFilters = getMatchingUniques(UniqueType.CanOnlyBeBuiltOnTile)
.map { it.params[0].run { if (this == "Coastal") "Land" else this } }.toSet() .map { it.params[0].run { if (this == "Coastal") "Land" else this } }.toSet()
val cannotFilters = getMatchingUniques(UniqueType.CannotBuildOnTile).map { it.params[0] }.toSet() val cannotFilters = getMatchingUniques(UniqueType.CannotBuildOnTile).map { it.params[0] }.toSet()
val resourcesImprovedByThis = ruleset.tileResources.values.filter { it.isImprovedBy(name) } val resourcesImprovedByThis = ruleset.tileResources.values.filter { it.isImprovedBy(name) }
val expandedTerrainsCanBeBuiltOn = sequence { @LocalState val expandedTerrainsCanBeBuiltOn = sequence {
yieldAll(terrainsCanBeBuiltOn) yieldAll(terrainsCanBeBuiltOn)
yieldAll(terrainsCanBeBuiltOn.asSequence().mapNotNull { ruleset.terrains[it] }.flatMap { it.occursOn.asSequence() }) yieldAll(terrainsCanBeBuiltOn.asSequence().mapNotNull { ruleset.terrains[it] }.flatMap { it.occursOn.asSequence() })
if (hasUnique(UniqueType.CanOnlyImproveResource)) if (hasUnique(UniqueType.CanOnlyImproveResource))
@ -127,7 +131,7 @@ class TileImprovement : RulesetStatsObject() {
} }
}.filter { it !in cannotFilters }.toMutableSet() }.filter { it !in cannotFilters }.toMutableSet()
val terrainsCanBeBuiltOnTypes = sequence { @LocalState val terrainsCanBeBuiltOnTypes = sequence {
yieldAll(expandedTerrainsCanBeBuiltOn.asSequence() yieldAll(expandedTerrainsCanBeBuiltOn.asSequence()
.mapNotNull { ruleset.terrains[it]?.type }) .mapNotNull { ruleset.terrains[it]?.type })
yieldAll( yieldAll(
@ -135,12 +139,14 @@ class TileImprovement : RulesetStatsObject() {
.filter { it.name in expandedTerrainsCanBeBuiltOn }) .filter { it.name in expandedTerrainsCanBeBuiltOn })
}.filter { it.name !in cannotFilters }.toMutableSet() }.filter { it.name !in cannotFilters }.toMutableSet()
if (canOnlyFilters.isNotEmpty() && canOnlyFilters.intersect(expandedTerrainsCanBeBuiltOn).isEmpty()) { if (canOnlyFilters.isNotEmpty() && canOnlyFilters.intersect(expandedTerrainsCanBeBuiltOn).isEmpty()) {
expandedTerrainsCanBeBuiltOn.clear() expandedTerrainsCanBeBuiltOn.clear()
if (terrainsCanBeBuiltOnTypes.none { it.name in canOnlyFilters }) if (terrainsCanBeBuiltOnTypes.none { it.name in canOnlyFilters })
terrainsCanBeBuiltOnTypes.clear() terrainsCanBeBuiltOnTypes.clear()
} }
@Readonly
fun matchesBuildImprovementsFilter(filter: String) = fun matchesBuildImprovementsFilter(filter: String) =
matchesFilter(filter) || matchesFilter(filter) ||
filter in expandedTerrainsCanBeBuiltOn || filter in expandedTerrainsCanBeBuiltOn ||
@ -156,6 +162,7 @@ class TileImprovement : RulesetStatsObject() {
}.toList() }.toList()
} }
@Readonly
fun getCreatingUnits(ruleset: Ruleset): List<BaseUnit> { fun getCreatingUnits(ruleset: Ruleset): List<BaseUnit> {
return ruleset.units.values.asSequence() return ruleset.units.values.asSequence()
.filter { unit -> .filter { unit ->

View File

@ -7,6 +7,7 @@ import com.unciv.models.ruleset.Ruleset
import com.unciv.models.ruleset.RulesetObject import com.unciv.models.ruleset.RulesetObject
import com.unciv.models.stats.INamed import com.unciv.models.stats.INamed
import com.unciv.ui.objectdescriptions.uniquesToCivilopediaTextLines import com.unciv.ui.objectdescriptions.uniquesToCivilopediaTextLines
import yairm210.purity.annotations.Readonly
/** Addon common to most ruleset game objects managing civilopedia display /** Addon common to most ruleset game objects managing civilopedia display
* *
@ -100,7 +101,7 @@ interface ICivilopediaText {
* the correct [CivilopediaCategories] member. `entryname` must equal the * the correct [CivilopediaCategories] member. `entryname` must equal the
* [ruleset object name][RulesetObject] as defined by the [INamed] interface. * [ruleset object name][RulesetObject] as defined by the [INamed] interface.
*/ */
fun makeLink(): String @Readonly fun makeLink(): String
/** Overrides alphabetical sorting in Civilopedia /** Overrides alphabetical sorting in Civilopedia
* @param ruleset The current ruleset in case the function needs to do lookups * @param ruleset The current ruleset in case the function needs to do lookups