mirror of
https://github.com/yairm210/Unciv.git
synced 2025-02-21 20:18:28 +07:00
Allow modders to hide individual Uniques from Civilopedia (#10394)
* Allow hiding individual Uniques from Civilopedia via a conditional-type modifier * Fix oversight * Fix another oversight
This commit is contained in:
parent
25aed40686
commit
9970549543
@ -2,9 +2,9 @@ package com.unciv.models.ruleset
|
||||
|
||||
import com.unciv.Constants
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.models.ruleset.unique.UniqueFlag
|
||||
import com.unciv.models.ruleset.unique.UniqueTarget
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.objectdescriptions.uniquesToCivilopediaTextLines
|
||||
import com.unciv.ui.screens.civilopediascreen.CivilopediaScreen.Companion.showReligionInCivilopedia
|
||||
import com.unciv.ui.screens.civilopediascreen.FormattedLine
|
||||
|
||||
@ -27,6 +27,7 @@ class Belief() : RulesetObject() {
|
||||
return getCivilopediaTextLines(false)
|
||||
}
|
||||
|
||||
// This special overload is called from Religion overview and Religion picker
|
||||
fun getCivilopediaTextLines(withHeader: Boolean): List<FormattedLine> {
|
||||
val textList = ArrayList<FormattedLine>()
|
||||
if (withHeader) {
|
||||
@ -35,10 +36,7 @@ class Belief() : RulesetObject() {
|
||||
}
|
||||
if (type != BeliefType.None)
|
||||
textList += FormattedLine("{Type}: {$type}", color = type.color, centered = withHeader)
|
||||
uniqueObjects.forEach {
|
||||
if (!it.hasFlag(UniqueFlag.HiddenToUsers))
|
||||
textList += FormattedLine(it)
|
||||
}
|
||||
uniquesToCivilopediaTextLines(textList, leadingSeparator = null)
|
||||
return textList
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,6 @@ import com.unciv.models.ruleset.tile.TileImprovement
|
||||
import com.unciv.models.ruleset.unique.LocalUniqueCache
|
||||
import com.unciv.models.ruleset.unique.StateForConditionals
|
||||
import com.unciv.models.ruleset.unique.Unique
|
||||
import com.unciv.models.ruleset.unique.UniqueFlag
|
||||
import com.unciv.models.ruleset.unique.UniqueParameterType
|
||||
import com.unciv.models.ruleset.unique.UniqueTarget
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
@ -21,6 +20,7 @@ import com.unciv.ui.components.extensions.getConsumesAmountString
|
||||
import com.unciv.ui.components.extensions.getNeedMoreAmountString
|
||||
import com.unciv.ui.components.extensions.toPercent
|
||||
import com.unciv.ui.components.fonts.Fonts
|
||||
import com.unciv.ui.objectdescriptions.uniquesToCivilopediaTextLines
|
||||
import com.unciv.ui.screens.civilopediascreen.FormattedLine
|
||||
|
||||
|
||||
@ -100,7 +100,7 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction {
|
||||
* @param filterUniques If provided, include only uniques for which this function returns true.
|
||||
*/
|
||||
private fun getUniquesStringsWithoutDisablers(filterUniques: ((Unique) -> Boolean)? = null) = getUniquesStrings {
|
||||
!it.hasFlag(UniqueFlag.HiddenToUsers)
|
||||
!it.isHiddenToUsers()
|
||||
&& filterUniques?.invoke(it) ?: true
|
||||
}
|
||||
|
||||
@ -262,15 +262,8 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction {
|
||||
|
||||
if (replacementTextForUniques.isNotEmpty()) {
|
||||
textList += FormattedLine(replacementTextForUniques)
|
||||
} else if (uniques.isNotEmpty()) {
|
||||
for (unique in uniqueObjects) {
|
||||
if (unique.hasFlag(UniqueFlag.HiddenToUsers)) continue
|
||||
if (unique.type == UniqueType.ConsumesResources) {
|
||||
textList += FormattedLine(unique.text, link = "Resources/${unique.params[1]}", color = "#F42")
|
||||
continue
|
||||
}
|
||||
textList += FormattedLine(unique)
|
||||
}
|
||||
} else {
|
||||
uniquesToCivilopediaTextLines(textList, colorConsumesResources = true)
|
||||
}
|
||||
|
||||
if (!stats.isEmpty()) {
|
||||
|
@ -1,11 +1,10 @@
|
||||
package com.unciv.models.ruleset
|
||||
|
||||
import com.unciv.models.ruleset.unique.StateForConditionals
|
||||
import com.unciv.models.ruleset.unique.UniqueFlag
|
||||
import com.unciv.models.ruleset.unique.UniqueTarget
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.translations.getPlaceholderText
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.objectdescriptions.uniquesToCivilopediaTextLines
|
||||
import com.unciv.ui.screens.civilopediascreen.FormattedLine
|
||||
|
||||
open class Policy : RulesetObject() {
|
||||
@ -18,12 +17,14 @@ open class Policy : RulesetObject() {
|
||||
|
||||
/** Indicates whether a [Policy] is a [PolicyBranch] starting policy, a normal one, or the branch completion */
|
||||
enum class PolicyBranchType {BranchStart, Member, BranchComplete}
|
||||
|
||||
/** Indicates whether this [Policy] is a [PolicyBranch] starting policy, a normal one, or the branch completion */
|
||||
val policyBranchType: PolicyBranchType by lazy { when {
|
||||
this is PolicyBranch -> PolicyBranchType.BranchStart
|
||||
isBranchCompleteByName(name) -> PolicyBranchType.BranchComplete
|
||||
else -> PolicyBranchType.Member
|
||||
} }
|
||||
|
||||
companion object {
|
||||
const val branchCompleteSuffix = " Complete"
|
||||
/** Some tests to count policies by completion or not use only the String collection without instantiating them.
|
||||
@ -34,16 +35,13 @@ open class Policy : RulesetObject() {
|
||||
|
||||
/** Used in PolicyPickerScreen to display Policy properties */
|
||||
fun getDescription(): String {
|
||||
var text = uniques
|
||||
.filter {
|
||||
!it.getPlaceholderText().contains(UniqueType.OnlyAvailableWhen.placeholderText) &&
|
||||
!it.getPlaceholderText().contains(UniqueType.OneTimeGlobalAlert.placeholderText)
|
||||
return (if (policyBranchType == PolicyBranchType.Member) name.tr() + "\n" else "") +
|
||||
uniqueObjects.filterNot {
|
||||
it.isHiddenToUsers()
|
||||
|| it.isOfType(UniqueType.OnlyAvailableWhen)
|
||||
|| it.isOfType(UniqueType.OneTimeGlobalAlert)
|
||||
}
|
||||
.joinToString("\n", transform = { "• ${it.tr()}" })
|
||||
if (policyBranchType != PolicyBranchType.BranchStart
|
||||
&& policyBranchType != PolicyBranchType.BranchComplete)
|
||||
text = name.tr() + "\n" + text
|
||||
return text
|
||||
.joinToString("\n") { "• ${it.text.tr()}" }
|
||||
}
|
||||
|
||||
override fun makeLink() = "Policy/$name"
|
||||
@ -126,17 +124,9 @@ open class Policy : RulesetObject() {
|
||||
lineList += FormattedLine(unit.name, link = unit.makeLink(), indent = 1)
|
||||
}
|
||||
|
||||
|
||||
if (uniques.isNotEmpty()) {
|
||||
lineList += FormattedLine()
|
||||
uniqueObjects.forEach {
|
||||
if (!it.hasFlag(UniqueFlag.HiddenToUsers))
|
||||
lineList += FormattedLine(it)
|
||||
}
|
||||
}
|
||||
uniquesToCivilopediaTextLines(lineList)
|
||||
|
||||
return lineList
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -54,6 +54,7 @@ class Speed : RulesetObject(), IsPartOfGameInfoSerialization {
|
||||
const val DEFAULTFORSIMULATION: String = "Standard"
|
||||
}
|
||||
|
||||
// Note: Speed is IHasUniques, but no implementation reads them, thus no UniqueType accepts this target
|
||||
override fun getUniqueTarget(): UniqueTarget = UniqueTarget.Speed
|
||||
|
||||
override fun makeLink(): String = "Speed/$name"
|
||||
|
@ -4,15 +4,15 @@ import com.badlogic.gdx.graphics.Color
|
||||
import com.unciv.Constants
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.ruleset.RulesetObject
|
||||
import com.unciv.models.ruleset.unique.UniqueFlag
|
||||
import com.unciv.models.ruleset.unique.UniqueTarget
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.translations.squareBraceRegex
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.components.extensions.colorFromRGB
|
||||
import com.unciv.ui.objectdescriptions.BaseUnitDescriptions
|
||||
import com.unciv.ui.objectdescriptions.uniquesToCivilopediaTextLines
|
||||
import com.unciv.ui.screens.civilopediascreen.CivilopediaScreen.Companion.showReligionInCivilopedia
|
||||
import com.unciv.ui.screens.civilopediascreen.FormattedLine
|
||||
import com.unciv.ui.objectdescriptions.BaseUnitDescriptions
|
||||
import kotlin.math.pow
|
||||
|
||||
class Nation : RulesetObject() {
|
||||
@ -111,12 +111,9 @@ class Nation : RulesetObject() {
|
||||
if (uniqueText != "") {
|
||||
textList += FormattedLine(uniqueText, indent = 1)
|
||||
} else {
|
||||
uniqueObjects.forEach {
|
||||
if (!it.hasFlag(UniqueFlag.HiddenToUsers))
|
||||
textList += FormattedLine(it)
|
||||
}
|
||||
textList += FormattedLine()
|
||||
uniquesToCivilopediaTextLines(textList, leadingSeparator = null)
|
||||
}
|
||||
textList += FormattedLine()
|
||||
|
||||
if (startBias.isNotEmpty()) {
|
||||
startBias.withIndex().forEach {
|
||||
|
@ -10,6 +10,7 @@ import com.unciv.models.ruleset.unique.UniqueTarget
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.ui.components.extensions.colorFromRGB
|
||||
import com.unciv.ui.components.fonts.Fonts
|
||||
import com.unciv.ui.objectdescriptions.uniquesToCivilopediaTextLines
|
||||
import com.unciv.ui.screens.civilopediascreen.FormattedLine
|
||||
|
||||
class Era : RulesetObject() {
|
||||
@ -53,8 +54,7 @@ class Era : RulesetObject() {
|
||||
.filter { it.era() == name }
|
||||
.map { FormattedLine(it.name, it.makeLink()) })
|
||||
|
||||
if (uniques.isNotEmpty()) yield(FormattedLine())
|
||||
yieldAll(uniqueObjects.asSequence().map { FormattedLine(it) })
|
||||
yieldAll(uniquesToCivilopediaTextLines())
|
||||
|
||||
val eraGatedObjects = getEraGatedObjects(ruleset).toList()
|
||||
if (eraGatedObjects.isEmpty()) return@sequence
|
||||
|
@ -5,11 +5,11 @@ import com.unciv.Constants
|
||||
import com.unciv.models.ruleset.Belief
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.ruleset.RulesetStatsObject
|
||||
import com.unciv.models.ruleset.unique.UniqueFlag
|
||||
import com.unciv.models.ruleset.unique.UniqueTarget
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.ui.screens.civilopediascreen.FormattedLine
|
||||
import com.unciv.ui.components.extensions.colorFromRGB
|
||||
import com.unciv.ui.objectdescriptions.uniquesToCivilopediaTextLines
|
||||
import com.unciv.ui.screens.civilopediascreen.FormattedLine
|
||||
|
||||
class Terrain : RulesetStatsObject() {
|
||||
|
||||
@ -118,10 +118,7 @@ class Terrain : RulesetStatsObject() {
|
||||
// For now, natural wonders show no "open terrain" - may change later
|
||||
if (turnsInto == null && displayAs(TerrainType.Land, ruleset) && !isRough())
|
||||
textList += FormattedLine("Open terrain") // Rough is in uniques
|
||||
uniqueObjects.forEach {
|
||||
if (!it.hasFlag(UniqueFlag.HiddenToUsers))
|
||||
textList += FormattedLine(it)
|
||||
}
|
||||
uniquesToCivilopediaTextLines(textList, leadingSeparator = null)
|
||||
|
||||
textList += FormattedLine()
|
||||
textList += if (impassable) FormattedLine(Constants.impassable, color="#A00")
|
||||
|
@ -14,6 +14,8 @@ import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.ruleset.unit.BaseUnit
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.components.extensions.toPercent
|
||||
import com.unciv.ui.objectdescriptions.uniquesToCivilopediaTextLines
|
||||
import com.unciv.ui.objectdescriptions.uniquesToDescription
|
||||
import com.unciv.ui.screens.civilopediascreen.CivilopediaScreen.Companion.showReligionInCivilopedia
|
||||
import com.unciv.ui.screens.civilopediascreen.FormattedLine
|
||||
import kotlin.math.roundToInt
|
||||
@ -58,8 +60,7 @@ class TileImprovement : RulesetStatsObject() {
|
||||
}
|
||||
if (techRequired != null) lines += "Required tech: [$techRequired]".tr()
|
||||
|
||||
for (unique in uniques)
|
||||
lines += unique.tr()
|
||||
uniquesToDescription(lines)
|
||||
|
||||
return lines.joinToString("\n")
|
||||
}
|
||||
@ -145,11 +146,7 @@ class TileImprovement : RulesetStatsObject() {
|
||||
textList += FormattedLine("Required tech: [$techRequired]", link="Technology/$techRequired")
|
||||
}
|
||||
|
||||
if (uniques.isNotEmpty()) {
|
||||
textList += FormattedLine()
|
||||
for (unique in uniqueObjects)
|
||||
textList += FormattedLine(unique)
|
||||
}
|
||||
uniquesToCivilopediaTextLines(textList)
|
||||
|
||||
// Be clearer when one needs to chop down a Forest first... A "Can be built on Plains" is clear enough,
|
||||
// but a "Can be built on Land" is not - how is the user to know Forest is _not_ Land?
|
||||
|
@ -6,10 +6,10 @@ import com.unciv.models.ruleset.Belief
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.ruleset.RulesetStatsObject
|
||||
import com.unciv.models.ruleset.unique.StateForConditionals
|
||||
import com.unciv.models.ruleset.unique.UniqueFlag
|
||||
import com.unciv.models.ruleset.unique.UniqueTarget
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.stats.Stats
|
||||
import com.unciv.ui.objectdescriptions.uniquesToCivilopediaTextLines
|
||||
import com.unciv.ui.screens.civilopediascreen.FormattedLine
|
||||
|
||||
class TileResource : RulesetStatsObject() {
|
||||
@ -43,13 +43,7 @@ class TileResource : RulesetStatsObject() {
|
||||
textList += FormattedLine("${resourceType.name} resource", header = 4, color = resourceType.color)
|
||||
textList += FormattedLine()
|
||||
|
||||
if (uniques.any()){
|
||||
textList += FormattedLine()
|
||||
for (unique in uniqueObjects.sortedBy { it.text }) {
|
||||
if (unique.hasFlag(UniqueFlag.HiddenToUsers)) continue
|
||||
textList += FormattedLine(unique)
|
||||
}
|
||||
}
|
||||
uniquesToCivilopediaTextLines(textList, sorted = true)
|
||||
|
||||
textList += FormattedLine(cloneStats().toString())
|
||||
|
||||
|
@ -44,6 +44,7 @@ class Unique(val text: String, val sourceObjectType: UniqueTarget? = null, val s
|
||||
val isLocalEffect = params.contains("in this city") || conditionals.any { it.type == UniqueType.ConditionalInThisCity }
|
||||
|
||||
fun hasFlag(flag: UniqueFlag) = type != null && type.flags.contains(flag)
|
||||
fun isHiddenToUsers() = hasFlag(UniqueFlag.HiddenToUsers) || conditionals.any { it.type == UniqueType.ConditionalHideUniqueFromUsers }
|
||||
|
||||
fun hasTriggerConditional(): Boolean {
|
||||
if (conditionals.none()) return false
|
||||
@ -204,6 +205,7 @@ class Unique(val text: String, val sourceObjectType: UniqueTarget? = null, val s
|
||||
return when (condition.type) {
|
||||
// These are 'what to do' and not 'when to do' conditionals
|
||||
UniqueType.ConditionalTimedUnique -> true
|
||||
UniqueType.ConditionalHideUniqueFromUsers -> true // allowed to be attached to any Unique to hide it, no-op otherwise
|
||||
|
||||
UniqueType.ConditionalChance -> stateBasedRandom.nextFloat() < condition.params[0].toFloat() / 100f
|
||||
UniqueType.ConditionalBeforeTurns -> checkOnCiv { gameInfo.turns < condition.params[0].toInt() }
|
||||
|
@ -777,6 +777,7 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
||||
UniqueTarget.Unit, UniqueTarget.UnitType, UniqueTarget.Improvement, UniqueTarget.Tech,
|
||||
UniqueTarget.Terrain, UniqueTarget.Resource, UniqueTarget.Policy, UniqueTarget.Promotion,
|
||||
UniqueTarget.Nation, UniqueTarget.Ruins, flags = UniqueFlag.setOfHiddenToUsers),
|
||||
ConditionalHideUniqueFromUsers("hidden from users", UniqueTarget.Conditional),
|
||||
|
||||
// Declarative Mod compatibility (so far rudimentary):
|
||||
ModIncompatibleWith("Mod is incompatible with [modFilter]", UniqueTarget.ModOptions),
|
||||
|
@ -61,6 +61,7 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
|
||||
lateinit var ruleset: Ruleset
|
||||
|
||||
|
||||
/** Generate short description as comma-separated string for Technology description "Units enabled" and GreatPersonPickerScreen */
|
||||
fun getShortDescription() = BaseUnitDescriptions.getShortDescription(this)
|
||||
|
||||
/** Generate description as multi-line string for CityScreen addSelectedConstructionTable
|
||||
|
@ -2,10 +2,11 @@ package com.unciv.models.ruleset.unit
|
||||
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.ruleset.RulesetObject
|
||||
import com.unciv.models.ruleset.unique.UniqueFlag
|
||||
import com.unciv.models.ruleset.unique.UniqueTarget
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.objectdescriptions.uniquesToCivilopediaTextLines
|
||||
import com.unciv.ui.objectdescriptions.uniquesToDescription
|
||||
import com.unciv.ui.screens.civilopediascreen.FormattedLine
|
||||
import com.unciv.ui.screens.pickerscreens.PromotionPickerScreen
|
||||
|
||||
@ -45,9 +46,7 @@ class Promotion : RulesetObject() {
|
||||
fun getDescription(promotionsForUnitType: Collection<Promotion>):String {
|
||||
val textList = ArrayList<String>()
|
||||
|
||||
for (unique in uniques) {
|
||||
textList += unique.tr()
|
||||
}
|
||||
uniquesToDescription(textList)
|
||||
|
||||
if (prerequisites.isNotEmpty()) {
|
||||
val prerequisitesString: ArrayList<String> = arrayListOf()
|
||||
@ -64,10 +63,7 @@ class Promotion : RulesetObject() {
|
||||
override fun getCivilopediaTextLines(ruleset: Ruleset): List<FormattedLine> {
|
||||
val textList = ArrayList<FormattedLine>()
|
||||
|
||||
uniqueObjects.forEach {
|
||||
if (!it.hasFlag(UniqueFlag.HiddenToUsers))
|
||||
textList += FormattedLine(it)
|
||||
}
|
||||
uniquesToCivilopediaTextLines(textList, leadingSeparator = null)
|
||||
|
||||
val filteredPrerequisites = prerequisites.mapNotNull {
|
||||
ruleset.unitPromotions[it]
|
||||
|
@ -349,7 +349,7 @@ object TranslationFileWriter {
|
||||
}
|
||||
|
||||
fun submitString(string: String, unique: Unique) {
|
||||
if (unique.hasFlag(UniqueFlag.HiddenToUsers))
|
||||
if (unique.isHiddenToUsers())
|
||||
return // We don't need to translate this at all, not user-visible
|
||||
|
||||
val stringToTranslate = string.removeConditionals()
|
||||
|
@ -9,7 +9,6 @@ import com.unciv.models.ruleset.IRulesetObject
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.ruleset.unique.StateForConditionals
|
||||
import com.unciv.models.ruleset.unique.Unique
|
||||
import com.unciv.models.ruleset.unique.UniqueFlag
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.ruleset.unit.BaseUnit
|
||||
import com.unciv.models.ruleset.unit.UnitMovementType
|
||||
@ -25,6 +24,7 @@ import com.unciv.ui.screens.civilopediascreen.MarkupRenderer
|
||||
|
||||
object BaseUnitDescriptions {
|
||||
|
||||
/** Generate short description as comma-separated string for Technology description "Units enabled" and GreatPersonPickerScreen */
|
||||
fun getShortDescription(baseUnit: BaseUnit): String {
|
||||
val infoList = mutableListOf<String>()
|
||||
if (baseUnit.strength != 0) infoList += "${baseUnit.strength}${Fonts.strength}"
|
||||
@ -33,8 +33,7 @@ object BaseUnitDescriptions {
|
||||
for (promotion in baseUnit.promotions)
|
||||
infoList += promotion.tr()
|
||||
if (baseUnit.replacementTextForUniques != "") infoList += baseUnit.replacementTextForUniques
|
||||
else for (unique in baseUnit.uniqueObjects) if (!unique.hasFlag(UniqueFlag.HiddenToUsers))
|
||||
infoList += unique.text.tr()
|
||||
else baseUnit.uniquesToDescription(infoList)
|
||||
return infoList.joinToString()
|
||||
}
|
||||
|
||||
@ -59,11 +58,7 @@ object BaseUnitDescriptions {
|
||||
lines += "$strengthLine${baseUnit.movement}${Fonts.movement}"
|
||||
|
||||
if (baseUnit.replacementTextForUniques != "") lines += baseUnit.replacementTextForUniques
|
||||
else for (unique in baseUnit.uniqueObjects.filterNot {
|
||||
it.type == UniqueType.Unbuildable
|
||||
|| it.type?.flags?.contains(UniqueFlag.HiddenToUsers) == true
|
||||
})
|
||||
lines += unique.text.tr()
|
||||
else baseUnit.uniquesToDescription(lines) { isOfType(UniqueType.Unbuildable) }
|
||||
|
||||
if (baseUnit.promotions.isNotEmpty()) {
|
||||
val prefix = "Free promotion${if (baseUnit.promotions.size == 1) "" else "s"}:".tr() + " "
|
||||
@ -106,16 +101,8 @@ object BaseUnitDescriptions {
|
||||
if (baseUnit.replacementTextForUniques.isNotEmpty()) {
|
||||
textList += FormattedLine()
|
||||
textList += FormattedLine(baseUnit.replacementTextForUniques)
|
||||
} else if (baseUnit.uniques.isNotEmpty()) {
|
||||
textList += FormattedLine()
|
||||
for (unique in baseUnit.uniqueObjects.sortedBy { it.text }) {
|
||||
if (unique.hasFlag(UniqueFlag.HiddenToUsers)) continue
|
||||
if (unique.type == UniqueType.ConsumesResources) {
|
||||
textList += FormattedLine(unique.text, link = "Resources/${unique.params[1]}", color = "#F42")
|
||||
continue
|
||||
}
|
||||
textList += FormattedLine(unique)
|
||||
}
|
||||
} else {
|
||||
baseUnit.uniquesToCivilopediaTextLines(textList, sorted = true, colorConsumesResources = true)
|
||||
}
|
||||
|
||||
if (baseUnit.requiredResource != null) {
|
||||
@ -252,13 +239,8 @@ object BaseUnitDescriptions {
|
||||
for (promotion in relevantPromotions)
|
||||
yield(FormattedLine(promotion.name, promotion.makeLink()))
|
||||
}
|
||||
if (uniqueObjects.isNotEmpty()) {
|
||||
yield(FormattedLine(separator = true))
|
||||
for (unique in uniqueObjects) {
|
||||
if (unique.hasFlag(UniqueFlag.HiddenToUsers)) continue
|
||||
yield(FormattedLine(unique))
|
||||
}
|
||||
}
|
||||
|
||||
yieldAll(uniquesToCivilopediaTextLines(leadingSeparator = true))
|
||||
}
|
||||
return (if (name.startsWith("Domain: ")) getDomainLines() else getUnitTypeLines()).toList()
|
||||
}
|
||||
@ -303,12 +285,12 @@ object BaseUnitDescriptions {
|
||||
if (betterUnit.replacementTextForUniques.isNotEmpty()) {
|
||||
yield(betterUnit.replacementTextForUniques to null)
|
||||
} else {
|
||||
val newAbilityPredicate: (Unique)->Boolean = { it.text in originalUnit.uniques || it.hasFlag(UniqueFlag.HiddenToUsers) }
|
||||
val newAbilityPredicate: (Unique)->Boolean = { it.text in originalUnit.uniques || it.isHiddenToUsers() }
|
||||
for (unique in betterUnit.uniqueObjects.filterNot(newAbilityPredicate))
|
||||
yield(unique.text to null)
|
||||
}
|
||||
|
||||
val lostAbilityPredicate: (Unique)->Boolean = { it.text in betterUnit.uniques || it.hasFlag(UniqueFlag.HiddenToUsers) }
|
||||
val lostAbilityPredicate: (Unique)->Boolean = { it.text in betterUnit.uniques || it.isHiddenToUsers() }
|
||||
for (unique in originalUnit.uniqueObjects.filterNot(lostAbilityPredicate)) {
|
||||
yield("Lost ability (vs [${originalUnit.name}]): [${unique.text}]" to null)
|
||||
}
|
||||
|
@ -0,0 +1,74 @@
|
||||
package com.unciv.ui.objectdescriptions
|
||||
|
||||
import com.unciv.models.ruleset.unique.IHasUniques
|
||||
import com.unciv.models.ruleset.unique.Unique
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.screens.civilopediascreen.FormattedLine
|
||||
|
||||
/**
|
||||
* Appends user-visible Uniques as translated text to a [line collection][lineList].
|
||||
*
|
||||
* Follows json order.
|
||||
* @param exclude Predicate that can exclude Uniques by returning `true` (defaults to return `false`).
|
||||
*/
|
||||
fun IHasUniques.uniquesToDescription(
|
||||
lineList: MutableCollection<String>,
|
||||
exclude: Unique.() -> Boolean = {false}
|
||||
) {
|
||||
for (unique in uniqueObjects) {
|
||||
if (unique.isHiddenToUsers()) continue
|
||||
if (unique.exclude()) continue
|
||||
lineList += unique.text.tr()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A Sequence of user-visible Uniques as [FormattedLine]s.
|
||||
*
|
||||
* @param leadingSeparator Tristate: If there are lines to display and this parameter is not `null`, a leading line is output, as separator or empty line.
|
||||
* @param sorted If set, sorts alphabetically (**not** using a locale-specific Collator). Otherwise lists in json order.
|
||||
* @param colorConsumesResources If set, ConsumesResources Uniques get a reddish color.
|
||||
* @param exclude Predicate that can exclude Uniques by returning `true` (defaults to return `false`).
|
||||
*/
|
||||
fun IHasUniques.uniquesToCivilopediaTextLines(
|
||||
leadingSeparator: Boolean? = false,
|
||||
sorted: Boolean = false,
|
||||
colorConsumesResources: Boolean = false,
|
||||
exclude: Unique.() -> Boolean = {false}
|
||||
) = sequence {
|
||||
var orderedUniques = uniqueObjects.asSequence()
|
||||
.filterNot { it.isHiddenToUsers() || it.exclude() }
|
||||
if (sorted) orderedUniques = orderedUniques.sortedBy { it.text }
|
||||
|
||||
for ((index, unique) in orderedUniques.withIndex()) {
|
||||
if (leadingSeparator != null && index == 0)
|
||||
yield(FormattedLine(separator = leadingSeparator))
|
||||
// Optionally special-case ConsumesResources to give it a reddish color. Also ensures link always points to the resource
|
||||
// (the other constructor guesses the first object by name in the Unique parameters).
|
||||
yield(
|
||||
if (colorConsumesResources && unique.isOfType(UniqueType.ConsumesResources))
|
||||
FormattedLine(unique.text, link = "Resources/${unique.params[1]}", color = "#F42")
|
||||
else FormattedLine(unique)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends user-visible Uniques as [FormattedLine]s to [lineList].
|
||||
*
|
||||
* @param leadingSeparator Tristate: If there are lines to display and this parameter is not `null`, a leading line is output, as separator or empty line.
|
||||
* @param sorted If set, sorts alphabetically (**not** using a locale-specific Collator). Otherwise lists in json order.
|
||||
* @param colorConsumesResources If set, ConsumesResources Uniques get a reddish color.
|
||||
* @param exclude Predicate that can exclude Uniques by returning `true` (defaults to return `false`).
|
||||
*/
|
||||
fun IHasUniques.uniquesToCivilopediaTextLines(
|
||||
lineList: MutableCollection<FormattedLine>,
|
||||
leadingSeparator: Boolean? = false,
|
||||
sorted: Boolean = false,
|
||||
colorConsumesResources: Boolean = false,
|
||||
exclude: Unique.() -> Boolean = {false}
|
||||
) {
|
||||
uniquesToCivilopediaTextLines(leadingSeparator, sorted, colorConsumesResources, exclude)
|
||||
.toCollection(lineList)
|
||||
}
|
@ -8,7 +8,6 @@ import com.unciv.models.ruleset.tech.Technology
|
||||
import com.unciv.models.ruleset.tile.TileImprovement
|
||||
import com.unciv.models.ruleset.tile.TileResource
|
||||
import com.unciv.models.ruleset.unique.Unique
|
||||
import com.unciv.models.ruleset.unique.UniqueFlag
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.ruleset.unit.BaseUnit
|
||||
import com.unciv.models.translations.tr
|
||||
@ -38,7 +37,8 @@ object TechnologyDescriptions {
|
||||
if (pediaText.text.isEmpty() || pediaText.header != 0) continue
|
||||
lineList += pediaText.text
|
||||
}
|
||||
for (unique in uniques) lineList += unique
|
||||
|
||||
uniquesToDescription(lineList)
|
||||
|
||||
lineList.addAll(
|
||||
getAffectedImprovements(name, ruleset)
|
||||
@ -191,13 +191,7 @@ object TechnologyDescriptions {
|
||||
}
|
||||
}
|
||||
|
||||
if (uniques.isNotEmpty()) {
|
||||
lineList += FormattedLine()
|
||||
uniqueObjects.forEach {
|
||||
if (!it.hasFlag(UniqueFlag.HiddenToUsers))
|
||||
lineList += FormattedLine(it)
|
||||
}
|
||||
}
|
||||
uniquesToCivilopediaTextLines(lineList)
|
||||
|
||||
val affectedImprovements = getAffectedImprovements(name, ruleset)
|
||||
if (affectedImprovements.any()) {
|
||||
|
@ -6,6 +6,7 @@ import com.unciv.models.ruleset.IRulesetObject
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.ruleset.RulesetObject
|
||||
import com.unciv.models.stats.INamed
|
||||
import com.unciv.ui.objectdescriptions.uniquesToCivilopediaTextLines
|
||||
|
||||
/** Addon common to most ruleset game objects managing civilopedia display
|
||||
*
|
||||
@ -39,6 +40,7 @@ interface ICivilopediaText {
|
||||
* (And the info displayed should be about the **ruleset**, not the player situation)
|
||||
*
|
||||
* Default implementation is empty - no need to call super in overrides.
|
||||
* Note that for inclusion of Uniques, two helpers named [uniquesToCivilopediaTextLines] exist (for Sequence or MutableCollection context).
|
||||
*
|
||||
* @param ruleset The current ruleset for the Civilopedia viewer
|
||||
* @return A list of [FormattedLine]s that will be inserted before
|
||||
|
@ -2028,6 +2028,9 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
|
||||
|
||||
Applicable to: Conditional
|
||||
|
||||
??? example "<hidden from users>"
|
||||
Applicable to: Conditional
|
||||
|
||||
## TriggerCondition uniques
|
||||
!!! note ""
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user