Spruced up Civilopedia - phase 6 - uniques (#4587)

This commit is contained in:
SomeTroglodyte
2021-07-21 13:40:17 +02:00
committed by GitHub
parent e48ae69927
commit 08954c1bd1
3 changed files with 68 additions and 26 deletions

View File

@ -29,7 +29,7 @@ class Building : NamedStats(), IConstruction, ICivilopediaText {
private var percentStatBonus: Stats? = null
var specialistSlots: Counter<String>? = null
fun newSpecialists(): Counter<String> {
if (specialistSlots == null) return Counter<String>()
if (specialistSlots == null) return Counter()
// Could have old specialist values of "gold", "science" etc - change them to the new specialist names
val counter = Counter<String>()
for ((entry, amount) in specialistSlots!!) {
@ -90,18 +90,24 @@ class Building : NamedStats(), IConstruction, ICivilopediaText {
return infoList.joinToString("; ") { it.tr() }
}
fun getUniquesStrings(): ArrayList<String> {
private fun getUniquesStrings() = sequence {
val tileBonusHashmap = HashMap<String, ArrayList<String>>()
val finalUniques = ArrayList<String>()
for (unique in uniqueObjects)
if (unique.placeholderText == "[] from [] tiles []" && unique.params[2] == "in this city") {
for (unique in uniqueObjects) when {
unique.placeholderText == "[] from [] tiles []" && unique.params[2] == "in this city" -> {
val stats = unique.params[0]
if (!tileBonusHashmap.containsKey(stats)) tileBonusHashmap[stats] = ArrayList()
tileBonusHashmap[stats]!!.add(unique.params[1])
} else if (unique.placeholderText != "Consumes [] []") finalUniques += unique.text
}
unique.placeholderText == "Consumes [] []" -> Unit // skip these,
else -> yield(unique.text)
}
for ((key, value) in tileBonusHashmap)
finalUniques += "[stats] from [tileFilter] tiles in this city".fillPlaceholders(key, value.joinToString { it.tr() })
return finalUniques
yield( "[stats] from [tileFilter] tiles in this city"
.fillPlaceholders( key,
// A single tileFilter will be properly translated later due to being within []
// advantage to not translate prematurely: FormatLine.formatUnique will recognize it
if (value.size == 1) value[0] else value.joinToString { it.tr() }
))
}
fun getDescription(cityInfo: CityInfo?, ruleset: Ruleset): String {
@ -118,7 +124,7 @@ class Building : NamedStats(), IConstruction, ICivilopediaText {
stringBuilder.appendLine("Provides a free [$providesFreeBuilding] in the city".tr())
if (uniques.isNotEmpty()) {
if (replacementTextForUniques != "") stringBuilder.appendLine(replacementTextForUniques)
else stringBuilder.appendLine(getUniquesStrings().asSequence().map { it.tr() }.joinToString("\n"))
else stringBuilder.appendLine(getUniquesStrings().map { it.tr() }.joinToString("\n"))
}
if (!stats.isEmpty())
stringBuilder.appendLine(stats.toString())
@ -180,8 +186,7 @@ class Building : NamedStats(), IConstruction, ICivilopediaText {
fun getStatPercentageBonuses(cityInfo: CityInfo?): Stats {
val stats = if (percentStatBonus == null) Stats() else percentStatBonus!!.clone()
val civInfo = cityInfo?.civInfo
if (civInfo == null) return stats // initial stats
val civInfo = cityInfo?.civInfo ?: return stats // initial stats
val baseBuildingName = getBaseBuilding(civInfo.gameInfo.ruleSet).name
@ -262,7 +267,8 @@ class Building : NamedStats(), IConstruction, ICivilopediaText {
if (replacementTextForUniques.isNotEmpty())
textList += FormattedLine(replacementTextForUniques)
else
for (unique in getUniquesStrings()) textList += FormattedLine(unique)
for (unique in getUniquesStrings())
textList += FormattedLine(Unique(unique))
}
if (!stats.isEmpty()) {
@ -504,8 +510,8 @@ class Building : NamedStats(), IConstruction, ICivilopediaText {
for ((resource, amount) in getResourceRequirements())
if (civInfo.getCivResourcesByName()[resource]!! < amount) {
if (amount == 1) return "Consumes 1 [$resource]" // Again, to preserve existing translations
else return "Consumes [$amount] [$resource]"
return if (amount == 1) "Consumes 1 [$resource]" // Again, to preserve existing translations
else "Consumes [$amount] [$resource]"
}
if (requiredNearbyImprovedResources != null) {
@ -599,14 +605,14 @@ class Building : NamedStats(), IConstruction, ICivilopediaText {
}
fun getBaseBuilding(ruleset: Ruleset): Building {
if (replaces == null) return this
else return ruleset.buildings[replaces!!]!!
return if (replaces == null) this
else ruleset.buildings[replaces!!]!!
}
fun getImprovement(ruleset: Ruleset): TileImprovement? {
val improvementUnique = uniqueObjects
.firstOrNull { it.placeholderText == "Creates a [] improvement on a specific tile" }
if (improvementUnique == null) return null
.firstOrNull { it.placeholderText == "Creates a [] improvement on a specific tile" }
?: return null
return ruleset.tileImprovements[improvementUnique.params[0]]
}

View File

@ -103,14 +103,8 @@ class BaseUnit : INamed, IConstruction, CivilopediaText() {
textList += FormattedLine(replacementTextForUniques)
} else if (uniques.isNotEmpty()) {
textList += FormattedLine()
for (uniqueObject in uniqueObjects.sortedBy { it.text }) {
if (uniqueObject.placeholderText == "Can construct []") {
val improvement = uniqueObject.params[0]
textList += FormattedLine(uniqueObject.text, link="Improvement/$improvement")
} else {
textList += FormattedLine(uniqueObject.text)
}
}
for (uniqueObject in uniqueObjects.sortedBy { it.text })
textList += FormattedLine(uniqueObject)
}
val resourceRequirements = getResourceRequirements()

View File

@ -5,7 +5,9 @@ import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.scenes.scene2d.Actor
import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.utils.Align
import com.unciv.UncivGame
import com.unciv.models.ruleset.Ruleset
import com.unciv.models.ruleset.Unique
import com.unciv.models.stats.INamed
import com.unciv.ui.utils.*
import kotlin.math.max
@ -66,6 +68,9 @@ class FormattedLine (
// from json in the primary constructor parameters above. Everything else should be a fun(),
// 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) : this(unique.text, getUniqueLink(unique))
/** Link types that can be used for [FormattedLine.link] */
enum class LinkType {
None,
@ -133,6 +138,43 @@ class FormattedLine (
const val iconPad = 5f
/** Padding distance per [indent] level */
const val indentPad = 30f
// Helper for constructor(Unique)
private fun getUniqueLink(unique: Unique): String {
for (parameter in unique.params) {
val category = allObjectNamesCategoryMap[parameter] ?: continue
return category.name + "/" + parameter
}
return ""
}
// Cache to quickly match Categories to names. Takes a few ms to build on a slower desktop and will use just a few 10k bytes.
private val allObjectNamesCategoryMap: HashMap<String, CivilopediaCategories> by lazy {
//val startTime = System.nanoTime()
val ruleSet = UncivGame.Current.gameInfo.ruleSet
// order these with the categories that should take precedence in case of name conflicts (e.g. Railroad) _last_
val allObjectMapsSequence = sequence {
yield(CivilopediaCategories.Difficulty to ruleSet.difficulties)
yield(CivilopediaCategories.Promotion to ruleSet.unitPromotions)
yield(CivilopediaCategories.Policy to ruleSet.policies)
yield(CivilopediaCategories.Terrain to ruleSet.terrains)
yield(CivilopediaCategories.Improvement to ruleSet.tileImprovements)
yield(CivilopediaCategories.Resource to ruleSet.tileResources)
yield(CivilopediaCategories.Nation to ruleSet.nations)
yield(CivilopediaCategories.Unit to ruleSet.units)
yield(CivilopediaCategories.Technology to ruleSet.technologies)
yield(CivilopediaCategories.Building to ruleSet.buildings.filter { !it.value.isAnyWonder() })
yield(CivilopediaCategories.Wonder to ruleSet.buildings.filter { it.value.isAnyWonder() })
}
val result = HashMap<String,CivilopediaCategories>()
allObjectMapsSequence.filter { !it.first.hide }
.flatMap { pair -> pair.second.keys.asSequence().map { key -> pair.first to key } }
.forEach {
result[it.second] = it.first
//println(" ${it.second} is a ${it.first}")
}
//println("allObjectNamesCategoryMap took ${System.nanoTime()-startTime}ns to initialize")
result
}
}
/** Extension: determines if a [String] looks like a link understood by the OS */