Resolves #11772 - Allow hidden conditionals (#11778)

* Allow hidden conditionals

* SomeTrog fixes

* We sure display uniques to users A LOT
This commit is contained in:
Yair Morgenstern 2024-06-19 17:28:53 +03:00 committed by GitHub
parent dff8133a7a
commit 4e5ec53d64
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 26 additions and 21 deletions

View File

@ -77,7 +77,7 @@ class TileStatFunctions(val tile: Tile) {
for (unique in statsFromTilesUniques + statsFromObjectsUniques + statsFromTilesWithoutUniques) {
val tileType = unique.params[1]
if (tile.matchesFilter(tileType, observingCiv, true))
listOfStats.add("{${unique.sourceObjectName}} ({${unique.text}})" to unique.stats)
listOfStats.add("{${unique.sourceObjectName}} ({${unique.getDisplayText()}})" to unique.stats)
else if (improvement != null && improvement.matchesFilter(tileType))
improvementStats.add(unique.stats)
else if (road != null && road.matchesFilter(tileType))
@ -147,7 +147,7 @@ class TileStatFunctions(val tile: Tile) {
val list = arrayListOf(terrain.name to (terrain as Stats))
for (unique in terrain.getMatchingUniques(UniqueType.Stats, stateForConditionals)) {
list.add(terrain.name+": "+unique.text to unique.stats)
list.add(terrain.name+": "+unique.getDisplayText() to unique.stats)
}
return list
}

View File

@ -11,6 +11,7 @@ import com.unciv.models.stats.Stats
import com.unciv.models.translations.getConditionals
import com.unciv.models.translations.getPlaceholderParameters
import com.unciv.models.translations.getPlaceholderText
import com.unciv.models.translations.removeConditionals
class Unique(val text: String, val sourceObjectType: UniqueTarget? = null, val sourceObjectName: String? = null) {
@ -177,6 +178,8 @@ class Unique(val text: String, val sourceObjectType: UniqueTarget? = null, val s
override fun toString() = if (type == null) "\"$text\"" else "$type (\"$text\")"
fun getDisplayText(): String = if (conditionals.none { it.isHiddenToUsers() }) text
else text.removeConditionals() + " " + conditionals.filter { !it.isHiddenToUsers() }.joinToString(" ") { "<${it.text}>" }
}
/** Used to cache results of getMatchingUniques

View File

@ -188,7 +188,7 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
for (unique in getMatchingUniques(UniqueType.RequiresPopulation))
if (unique.params[0].toInt() > cityConstructions.city.population.population)
yield(RejectionReasonType.PopulationRequirement.toInstance(unique.text))
yield(RejectionReasonType.PopulationRequirement.toInstance(unique.getDisplayText()))
yieldAll(getRejectionReasons(civInfo, cityConstructions.city))
@ -252,7 +252,7 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
it.type == UniqueType.ConditionalBelowHappiness || it.type == UniqueType.ConditionalBetweenHappiness
}
if (hasHappinessCondition)
yield(RejectionReasonType.CannotBeBuiltUnhappiness.toInstance(unique.text))
yield(RejectionReasonType.CannotBeBuiltUnhappiness.toInstance(unique.getDisplayText()))
else yield(RejectionReasonType.CannotBeBuilt.toInstance())
}
}
@ -295,7 +295,7 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
}
else -> {
if (built)
yield(RejectionReasonType.CanOnlyBeBuiltInSpecificCities.toInstance(unique.text))
yield(RejectionReasonType.CanOnlyBeBuiltInSpecificCities.toInstance(unique.getDisplayText()))
else
yield(RejectionReasonType.ShouldNotBeDisplayed.toInstance())
}

View File

@ -293,11 +293,10 @@ object BaseUnitDescriptions {
// Need double translation of the "ability" here - unique texts may contain nuts - pardon, square brackets
yield("Lost ability (vs [${originalUnit.name}]): [${unique.text.tr()}]" to null)
}
for (promotion in betterUnit.promotions.filter { it !in originalUnit.promotions }) {
// Needs tr for **individual** translations (no bracket nesting), default separator would have extra blank
val effects = ruleset.unitPromotions[promotion]!!.uniques
.joinToString() { it.tr() }
yield("{$promotion} ($effects)" to "Promotion/$promotion")
for (promotionName in betterUnit.promotions.filter { it !in originalUnit.promotions }) {
val promotion = ruleset.unitPromotions[promotionName]!!
val effects = promotion.uniquesToDescription().joinToString()
yield("{$promotionName} ($effects)" to promotion.makeLink())
}
}

View File

@ -143,7 +143,7 @@ object BuildingDescriptions {
} else {
val newAbilityPredicate: (Unique)->Boolean = { it.text in originalBuilding.uniques || it.isHiddenToUsers() }
for (unique in replacementBuilding.uniqueObjects.filterNot(newAbilityPredicate))
yield(FormattedLine(unique.text, indent=1)) // FormattedLine(unique) would look worse - no indent and autolinking could distract
yield(FormattedLine(unique.getDisplayText(), indent=1)) // FormattedLine(unique) would look worse - no indent and autolinking could distract
}
val lostAbilityPredicate: (Unique)->Boolean = { it.text in replacementBuilding.uniques || it.isHiddenToUsers() }

View File

@ -10,17 +10,20 @@ import com.unciv.ui.screens.civilopediascreen.FormattedLine
* Appends user-visible Uniques as translated text to a [line collection][lineList].
*
* Follows json order.
* @param lineList Target collection, will be mutated. Defaults to an empty List for easier use with consumer-only client code.
* @param exclude Predicate that can exclude Uniques by returning `true` (defaults to return `false`).
* @return the [lineList] with added, translated info on [this.uniques] - for chaining
*/
fun IHasUniques.uniquesToDescription(
lineList: MutableCollection<String>,
lineList: MutableCollection<String> = mutableListOf(),
exclude: Unique.() -> Boolean = {false}
): Unit {
): MutableCollection<String> {
for (unique in uniqueObjects) {
if (unique.isHiddenToUsers()) continue
if (unique.exclude()) continue
lineList += unique.text.tr()
lineList += unique.getDisplayText().tr()
}
return lineList
}
/**
@ -48,7 +51,7 @@ fun IHasUniques.uniquesToCivilopediaTextLines(
// (the other constructor guesses the first object by name in the Unique parameters).
yield(
if (colorConsumesResources && unique.type == UniqueType.ConsumesResources)
FormattedLine(unique.text, link = "Resources/${unique.params[1]}", color = "#F42")
FormattedLine(unique.getDisplayText(), link = "Resources/${unique.params[1]}", color = "#F42")
else FormattedLine(unique)
)
}

View File

@ -37,12 +37,12 @@ object ImprovementDescriptions {
val newAbilityPredicate: (Unique)->Boolean = { it.text in originalImprovement.uniques || it.isHiddenToUsers() }
for (unique in replacementImprovement.uniqueObjects.filterNot(newAbilityPredicate))
yield(FormattedLine(unique.text, indent=1)) // FormattedLine(unique) would look worse - no indent and auto-linking could distract
yield(FormattedLine(unique.getDisplayText(), indent=1)) // FormattedLine(unique) would look worse - no indent and auto-linking could distract
val lostAbilityPredicate: (Unique)->Boolean = { it.text in replacementImprovement.uniques || it.isHiddenToUsers() }
for (unique in originalImprovement.uniqueObjects.filterNot(lostAbilityPredicate)) {
// Need double translation of the "ability" here - unique texts may contain square brackets
yield(FormattedLine("Lost ability (vs [${originalImprovement.name}]): [${unique.text.tr()}]", indent=1))
yield(FormattedLine("Lost ability (vs [${originalImprovement.name}]): [${unique.getDisplayText().tr()}]", indent=1))
}
}

View File

@ -84,7 +84,7 @@ class FormattedLine (
// have no backing field, be `by lazy` or use @Transient, Thank you.
/** Looks for linkable ruleset objects in [Unique] parameters and returns a linked [FormattedLine] if successful, a plain one otherwise */
constructor(unique: Unique, indent: Int = 0) : this(unique.text, getUniqueLink(unique), indent = indent)
constructor(unique: Unique, indent: Int = 0) : this(unique.getDisplayText(), getUniqueLink(unique), indent = indent)
/** Link types that can be used for [FormattedLine.link] */
enum class LinkType {

View File

@ -179,7 +179,7 @@ class CityStateDiplomacyTable(private val diplomacyScreen: DiplomacyScreen) {
.getCityStateBonuses(otherCiv.cityStateType, level)
.filterNot { it.isHiddenToUsers() }
if (bonuses.none()) return ""
return (sequenceOf(header) + bonuses.map { it.text }).joinToString(separator = "\n") { it.tr() }
return (sequenceOf(header) + bonuses.map { it.getDisplayText() }).joinToString(separator = "\n") { it.tr() }
}
fun addBonusLabel(header: String, bonusLevel: RelationshipLevel, relationLevel: RelationshipLevel) {
val bonusLabelColor = if (relationLevel == bonusLevel) Color.GREEN else Color.GRAY

View File

@ -84,7 +84,7 @@ abstract class ReligionPickerScreenCommon(
add(belief.type.name.toLabel(fontColor = Color.valueOf(belief.type.color))).row()
val nameLabel = WrappableLabel(belief.name, labelWidth, fontSize = Constants.headingFontSize)
add(nameLabel.apply { wrap = true }).row()
val effectLabel = WrappableLabel(belief.uniqueObjects.filter { !it.isHiddenToUsers() }.map { it.text }
val effectLabel = WrappableLabel(belief.uniqueObjects.filter { !it.isHiddenToUsers() }.map { it.getDisplayText() }
.joinToString("\n") { it.tr() }, labelWidth)
add(effectLabel.apply { wrap = true })
}

View File

@ -410,7 +410,7 @@ class TechPickerScreen(
for (requiredTech in pathToTech) {
for (unique in requiredTech.uniqueObjects
.filter { it.type == UniqueType.OnlyAvailable && !it.conditionalsApply(civInfo) }) {
rightSideButton.setText(unique.text.tr())
rightSideButton.setText(unique.getDisplayText().tr())
rightSideButton.disable()
return
}