Unique flags (#5625)

* Add flags to UniqueTypes, implement HideInCivilopedia

* hasFlag function
This commit is contained in:
SimonCeder 2021-11-02 16:23:40 +01:00 committed by GitHub
parent d15e01d5e8
commit 15a2a51a99
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 59 additions and 29 deletions

View File

@ -2,6 +2,7 @@ package com.unciv.models.ruleset
import com.unciv.UncivGame import com.unciv.UncivGame
import com.unciv.models.ruleset.unique.Unique import com.unciv.models.ruleset.unique.Unique
import com.unciv.models.ruleset.unique.UniqueFlag
import com.unciv.models.ruleset.unique.UniqueTarget import com.unciv.models.ruleset.unique.UniqueTarget
import com.unciv.models.stats.INamed import com.unciv.models.stats.INamed
import com.unciv.models.translations.tr import com.unciv.models.translations.tr
@ -30,6 +31,7 @@ class Belief : RulesetObject() {
if (type != BeliefType.None) if (type != BeliefType.None)
textList += FormattedLine("{Type}: $type", color = type.color, centered = centerType) textList += FormattedLine("{Type}: $type", color = type.color, centered = centerType)
uniqueObjects.forEach { uniqueObjects.forEach {
if (!it.hasFlag(UniqueFlag.HideInCivilopedia))
textList += FormattedLine(it) textList += FormattedLine(it)
} }
return textList return textList

View File

@ -259,8 +259,10 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction {
if (replacementTextForUniques.isNotEmpty()) if (replacementTextForUniques.isNotEmpty())
textList += FormattedLine(replacementTextForUniques) textList += FormattedLine(replacementTextForUniques)
else else
for (unique in getUniquesStrings()) uniqueObjects.forEach {
textList += FormattedLine(Unique(unique)) if (!it.hasFlag(UniqueFlag.HideInCivilopedia))
textList += FormattedLine(it)
}
} }
if (!stats.isEmpty()) { if (!stats.isEmpty()) {

View File

@ -5,6 +5,7 @@ import com.unciv.Constants
import com.unciv.UncivGame import com.unciv.UncivGame
import com.unciv.logic.civilization.CityStateType import com.unciv.logic.civilization.CityStateType
import com.unciv.models.ruleset.unique.Unique import com.unciv.models.ruleset.unique.Unique
import com.unciv.models.ruleset.unique.UniqueFlag
import com.unciv.models.ruleset.unique.UniqueTarget import com.unciv.models.ruleset.unique.UniqueTarget
import com.unciv.models.ruleset.unique.UniqueType import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.translations.squareBraceRegex import com.unciv.models.translations.squareBraceRegex
@ -117,6 +118,7 @@ class Nation : RulesetObject() {
textList += FormattedLine(uniqueText, indent = 1) textList += FormattedLine(uniqueText, indent = 1)
} else { } else {
uniqueObjects.forEach { uniqueObjects.forEach {
if (!it.hasFlag(UniqueFlag.HideInCivilopedia))
textList += FormattedLine(it) textList += FormattedLine(it)
} }
textList += FormattedLine() textList += FormattedLine()
@ -246,11 +248,14 @@ class Nation : RulesetObject() {
// This does not use the auto-linking FormattedLine(Unique) for two reasons: // This does not use the auto-linking FormattedLine(Unique) for two reasons:
// would look a little chaotic as unit uniques unlike most uniques are a HashSet and thus do not preserve order // would look a little chaotic as unit uniques unlike most uniques are a HashSet and thus do not preserve order
// No .copy() factory on FormattedLine and no FormattedLine(Unique, all other val's) constructor either // No .copy() factory on FormattedLine and no FormattedLine(Unique, all other val's) constructor either
for (unique in unit.uniques.filterNot { it in originalUnit.uniques }) for (unique in unit.uniqueObjects.filterNot { it.text in originalUnit.uniques || it.hasFlag(UniqueFlag.HideInCivilopedia) }) {
textList += FormattedLine(unique, indent=1)
for (unique in originalUnit.uniques.filterNot { it in unit.uniques }) textList += FormattedLine(unique.text.tr(), indent = 1)
}
for (unique in originalUnit.uniqueObjects.filterNot { it.text in unit.uniques || it.hasFlag(UniqueFlag.HideInCivilopedia) }) {
textList += FormattedLine("Lost ability".tr() + " (" + "vs [${originalUnit.name}]".tr() + "): " + textList += FormattedLine("Lost ability".tr() + " (" + "vs [${originalUnit.name}]".tr() + "): " +
unique.tr(), indent=1) unique.text.tr(), indent = 1)
}
for (promotion in unit.promotions.filter { it !in originalUnit.promotions }) { for (promotion in unit.promotions.filter { it !in originalUnit.promotions }) {
val effect = ruleset.unitPromotions[promotion]!!.uniquesWithEffect() val effect = ruleset.unitPromotions[promotion]!!.uniquesWithEffect()
// "{$promotion} ({$effect})" won't work as effect may contain [] and tr() does not support that kind of nesting // "{$promotion} ({$effect})" won't work as effect may contain [] and tr() does not support that kind of nesting

View File

@ -1,5 +1,6 @@
package com.unciv.models.ruleset package com.unciv.models.ruleset
import com.unciv.models.ruleset.unique.UniqueFlag
import com.unciv.models.ruleset.unique.UniqueTarget import com.unciv.models.ruleset.unique.UniqueTarget
import com.unciv.models.translations.tr import com.unciv.models.translations.tr
import com.unciv.ui.civilopedia.FormattedLine import com.unciv.ui.civilopedia.FormattedLine
@ -89,7 +90,10 @@ open class Policy : RulesetObject() {
if (uniques.isNotEmpty()) { if (uniques.isNotEmpty()) {
lineList += FormattedLine() lineList += FormattedLine()
for (unique in uniqueObjects) lineList += FormattedLine(unique) uniqueObjects.forEach {
if (!it.hasFlag(UniqueFlag.HideInCivilopedia))
lineList += FormattedLine(it)
}
} }
return lineList return lineList

View File

@ -6,6 +6,7 @@ import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.models.ruleset.Building import com.unciv.models.ruleset.Building
import com.unciv.models.ruleset.Ruleset import com.unciv.models.ruleset.Ruleset
import com.unciv.models.ruleset.RulesetObject 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.UniqueTarget
import com.unciv.models.ruleset.unique.UniqueType import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.ruleset.unit.BaseUnit import com.unciv.models.ruleset.unit.BaseUnit
@ -198,7 +199,10 @@ class Technology: RulesetObject() {
if (uniques.isNotEmpty()) { if (uniques.isNotEmpty()) {
lineList += FormattedLine() lineList += FormattedLine()
for (unique in uniqueObjects) lineList += FormattedLine(unique) uniqueObjects.forEach {
if (!it.hasFlag(UniqueFlag.HideInCivilopedia))
lineList += FormattedLine(it)
}
} }
var wantEmpty = true var wantEmpty = true

View File

@ -5,6 +5,7 @@ import com.unciv.Constants
import com.unciv.models.ruleset.Belief import com.unciv.models.ruleset.Belief
import com.unciv.models.ruleset.Ruleset import com.unciv.models.ruleset.Ruleset
import com.unciv.models.ruleset.RulesetStatsObject 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.UniqueTarget
import com.unciv.models.ruleset.unique.UniqueType import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.ui.civilopedia.FormattedLine import com.unciv.ui.civilopedia.FormattedLine
@ -115,6 +116,7 @@ class Terrain : RulesetStatsObject() {
if (turnsInto == null && displayAs(TerrainType.Land, ruleset) && !isRough()) if (turnsInto == null && displayAs(TerrainType.Land, ruleset) && !isRough())
textList += FormattedLine("Open terrain") // Rough is in uniques textList += FormattedLine("Open terrain") // Rough is in uniques
uniqueObjects.forEach { uniqueObjects.forEach {
if (!it.hasFlag(UniqueFlag.HideInCivilopedia))
textList += FormattedLine(it) textList += FormattedLine(it)
} }

View File

@ -29,6 +29,8 @@ class Unique(val text: String, val sourceObjectType: UniqueTarget? = null, val s
val isLocalEffect = params.contains("in this city") val isLocalEffect = params.contains("in this city")
val isAntiLocalEffect = params.contains("in other cities") val isAntiLocalEffect = params.contains("in other cities")
fun hasFlag(flag: UniqueFlag) = type != null && type.flags.contains(flag)
fun isOfType(uniqueType: UniqueType) = uniqueType == type fun isOfType(uniqueType: UniqueType) = uniqueType == type
fun conditionalsApply(civInfo: CivilizationInfo? = null, city: CityInfo? = null): Boolean { fun conditionalsApply(civInfo: CivilizationInfo? = null, city: CityInfo? = null): Boolean {

View File

@ -55,7 +55,11 @@ enum class UniqueTarget(val inheritsFrom:UniqueTarget?=null) {
} }
} }
enum class UniqueType(val text:String, vararg targets: UniqueTarget) { enum class UniqueFlag {
HideInCivilopedia,
}
enum class UniqueType(val text:String, vararg targets: UniqueTarget, val flags: List<UniqueFlag> = emptyList()) {
//////////////////////////////////////// GLOBAL UNIQUES //////////////////////////////////////// //////////////////////////////////////// GLOBAL UNIQUES ////////////////////////////////////////
@ -275,21 +279,21 @@ enum class UniqueType(val text:String, vararg targets: UniqueTarget) {
CanEnterIceTiles("Can enter ice tiles", UniqueTarget.Unit), CanEnterIceTiles("Can enter ice tiles", UniqueTarget.Unit),
CannotEnterOcean("Cannot enter ocean tiles", UniqueTarget.Unit), CannotEnterOcean("Cannot enter ocean tiles", UniqueTarget.Unit),
CannotEnterOceanUntilAstronomy("Cannot enter ocean tiles until Astronomy", UniqueTarget.Unit), CannotEnterOceanUntilAstronomy("Cannot enter ocean tiles until Astronomy", UniqueTarget.Unit),
CannotBeBarbarian("Never appears as a Barbarian unit", UniqueTarget.Unit), CannotBeBarbarian("Never appears as a Barbarian unit", UniqueTarget.Unit, flags = listOf(UniqueFlag.HideInCivilopedia)),
///////////////////////////////////////// TILE UNIQUES ///////////////////////////////////////// ///////////////////////////////////////// TILE UNIQUES /////////////////////////////////////////
NaturalWonderNeighborCount("Must be adjacent to [amount] [simpleTerrain] tiles", UniqueTarget.Terrain), NaturalWonderNeighborCount("Must be adjacent to [amount] [simpleTerrain] tiles", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
NaturalWonderNeighborsRange("Must be adjacent to [amount] to [amount] [simpleTerrain] tiles", UniqueTarget.Terrain), NaturalWonderNeighborsRange("Must be adjacent to [amount] to [amount] [simpleTerrain] tiles", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
NaturalWonderSmallerLandmass("Must not be on [amount] largest landmasses", UniqueTarget.Terrain), NaturalWonderSmallerLandmass("Must not be on [amount] largest landmasses", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
NaturalWonderLargerLandmass("Must be on [amount] largest landmasses", UniqueTarget.Terrain), NaturalWonderLargerLandmass("Must be on [amount] largest landmasses", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
NaturalWonderLatitude("Occurs on latitudes from [amount] to [amount] percent of distance equator to pole", UniqueTarget.Terrain), NaturalWonderLatitude("Occurs on latitudes from [amount] to [amount] percent of distance equator to pole", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
NaturalWonderGroups("Occurs in groups of [amount] to [amount] tiles", UniqueTarget.Terrain), NaturalWonderGroups("Occurs in groups of [amount] to [amount] tiles", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
NaturalWonderConvertNeighbors("Neighboring tiles will convert to [baseTerrain]", UniqueTarget.Terrain), NaturalWonderConvertNeighbors("Neighboring tiles will convert to [baseTerrain]", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
// The "Except [terrainFilter]" could theoretically be implemented with a conditional // The "Except [terrainFilter]" could theoretically be implemented with a conditional
NaturalWonderConvertNeighborsExcept("Neighboring tiles except [baseTerrain] will convert to [baseTerrain]", UniqueTarget.Terrain), NaturalWonderConvertNeighborsExcept("Neighboring tiles except [baseTerrain] will convert to [baseTerrain]", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
DamagesContainingUnits("Units ending their turn on this terrain take [amount] damage", UniqueTarget.Terrain), DamagesContainingUnits("Units ending their turn on this terrain take [amount] damage", UniqueTarget.Terrain),
TerrainGrantsPromotion("Grants [promotion] ([comment]) to adjacent [mapUnitFilter] units for the rest of the game", UniqueTarget.Terrain), TerrainGrantsPromotion("Grants [promotion] ([comment]) to adjacent [mapUnitFilter] units for the rest of the game", UniqueTarget.Terrain),
@ -303,10 +307,10 @@ enum class UniqueType(val text:String, vararg targets: UniqueTarget) {
BlocksLineOfSightAtSameElevation("Blocks line-of-sight from tiles at same elevation", UniqueTarget.Terrain), BlocksLineOfSightAtSameElevation("Blocks line-of-sight from tiles at same elevation", UniqueTarget.Terrain),
VisibilityElevation("Has an elevation of [amount] for visibility calculations", UniqueTarget.Terrain), VisibilityElevation("Has an elevation of [amount] for visibility calculations", UniqueTarget.Terrain),
NoNaturalGeneration("Doesn't generate naturally", UniqueTarget.Terrain), NoNaturalGeneration("Doesn't generate naturally", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
TileGenerationConditions("Occurs at temperature between [amount] and [amount] and humidity between [amount] and [amount]", UniqueTarget.Terrain), TileGenerationConditions("Occurs at temperature between [amount] and [amount] and humidity between [amount] and [amount]", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
OccursInChains("Occurs in chains at high elevations", UniqueTarget.Terrain), OccursInChains("Occurs in chains at high elevations", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
OccursInGroups("Occurs in groups around high elevations", UniqueTarget.Terrain), OccursInGroups("Occurs in groups around high elevations", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
RareFeature("Rare feature", UniqueTarget.Terrain), RareFeature("Rare feature", UniqueTarget.Terrain),
ResistsNukes("Resistant to nukes", UniqueTarget.Terrain), ResistsNukes("Resistant to nukes", UniqueTarget.Terrain),

View File

@ -7,6 +7,7 @@ import com.unciv.logic.map.MapUnit
import com.unciv.models.ruleset.Ruleset import com.unciv.models.ruleset.Ruleset
import com.unciv.models.ruleset.RulesetObject import com.unciv.models.ruleset.RulesetObject
import com.unciv.models.ruleset.unique.StateForConditionals 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.UniqueTarget
import com.unciv.models.ruleset.unique.UniqueType import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.stats.Stat import com.unciv.models.stats.Stat
@ -133,8 +134,10 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
textList += FormattedLine(replacementTextForUniques) textList += FormattedLine(replacementTextForUniques)
} else if (uniques.isNotEmpty()) { } else if (uniques.isNotEmpty()) {
textList += FormattedLine() textList += FormattedLine()
for (uniqueObject in uniqueObjects.sortedBy { it.text }) uniqueObjects.sortedBy { it.text }.forEach {
textList += FormattedLine(uniqueObject) if (!it.hasFlag(UniqueFlag.HideInCivilopedia))
textList += FormattedLine(it)
}
} }
val resourceRequirements = getResourceRequirements() val resourceRequirements = getResourceRequirements()

View File

@ -2,6 +2,7 @@ package com.unciv.models.ruleset.unit
import com.unciv.models.ruleset.Ruleset import com.unciv.models.ruleset.Ruleset
import com.unciv.models.ruleset.RulesetObject 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.UniqueTarget
import com.unciv.models.ruleset.unique.UniqueType import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.translations.tr import com.unciv.models.translations.tr
@ -47,8 +48,9 @@ class Promotion : RulesetObject() {
override fun getCivilopediaTextLines(ruleset: Ruleset): List<FormattedLine> { override fun getCivilopediaTextLines(ruleset: Ruleset): List<FormattedLine> {
val textList = ArrayList<FormattedLine>() val textList = ArrayList<FormattedLine>()
for (unique in uniqueObjects) { uniqueObjects.forEach {
textList += FormattedLine(unique) if (!it.hasFlag(UniqueFlag.HideInCivilopedia))
textList += FormattedLine(it)
} }
val filteredPrerequisites = prerequisites.mapNotNull { val filteredPrerequisites = prerequisites.mapNotNull {