mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-27 05:46:43 -04:00
Civilopedia Phase X (#5003)
* Civilopedia Phase X - Show Policies * Civilopedia Phase X - Show City States * Civilopedia - Loop-driven init and Cleanup * Civilopedia - City States * Civilopedia Phase X - Remove spurious comments
This commit is contained in:
parent
30e5ac3665
commit
bf2ee91b67
@ -161,7 +161,6 @@ Declare Protection of [cityStateName]? =
|
|||||||
Build [improvementName] on [resourceName] (200 Gold) =
|
Build [improvementName] on [resourceName] (200 Gold) =
|
||||||
Gift Improvement =
|
Gift Improvement =
|
||||||
|
|
||||||
|
|
||||||
Cultured =
|
Cultured =
|
||||||
Maritime =
|
Maritime =
|
||||||
Mercantile =
|
Mercantile =
|
||||||
@ -175,9 +174,12 @@ Personality =
|
|||||||
Influence =
|
Influence =
|
||||||
Reach 30 for friendship. =
|
Reach 30 for friendship. =
|
||||||
Reach highest influence above 60 for alliance. =
|
Reach highest influence above 60 for alliance. =
|
||||||
|
When Friends: =
|
||||||
|
When Allies: =
|
||||||
|
The unique luxury is one of: =
|
||||||
|
|
||||||
# Trades
|
# Trades
|
||||||
|
|
||||||
Trade =
|
Trade =
|
||||||
Offer trade =
|
Offer trade =
|
||||||
Retract offer =
|
Retract offer =
|
||||||
@ -989,9 +991,10 @@ Adopt free policy =
|
|||||||
Unlocked at =
|
Unlocked at =
|
||||||
Gain 2 free technologies =
|
Gain 2 free technologies =
|
||||||
All policies adopted =
|
All policies adopted =
|
||||||
|
Policy branch: [branchName] =
|
||||||
# Religions
|
|
||||||
|
# Religions
|
||||||
|
|
||||||
Choose an Icon and name for your Religion =
|
Choose an Icon and name for your Religion =
|
||||||
Choose a [beliefType] belief! =
|
Choose a [beliefType] belief! =
|
||||||
Found [religionName] =
|
Found [religionName] =
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package com.unciv.logic.civilization
|
package com.unciv.logic.civilization
|
||||||
|
|
||||||
enum class CityStateType {
|
enum class CityStateType(val color: String = "") {
|
||||||
Cultured,
|
Cultured("#8b60ff"),
|
||||||
Maritime,
|
Maritime("#38ff70"),
|
||||||
Mercantile,
|
Mercantile("#ffd800"),
|
||||||
Militaristic
|
Militaristic("#ff0000")
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class CityStatePersonality {
|
enum class CityStatePersonality {
|
||||||
|
@ -2,6 +2,7 @@ package com.unciv.logic.civilization
|
|||||||
|
|
||||||
import com.unciv.logic.civilization.diplomacy.RelationshipLevel
|
import com.unciv.logic.civilization.diplomacy.RelationshipLevel
|
||||||
import com.unciv.models.metadata.BASE_GAME_DURATION_TURNS
|
import com.unciv.models.metadata.BASE_GAME_DURATION_TURNS
|
||||||
|
import com.unciv.models.ruleset.Policy
|
||||||
import com.unciv.models.ruleset.tile.ResourceType
|
import com.unciv.models.ruleset.tile.ResourceType
|
||||||
import com.unciv.models.stats.Stat
|
import com.unciv.models.stats.Stat
|
||||||
import com.unciv.models.stats.StatMap
|
import com.unciv.models.stats.StatMap
|
||||||
@ -221,7 +222,7 @@ class CivInfoStats(val civInfo: CivilizationInfo) {
|
|||||||
if (civInfo.hasUnique("Provides 1 happiness per 2 additional social policies adopted")) {
|
if (civInfo.hasUnique("Provides 1 happiness per 2 additional social policies adopted")) {
|
||||||
if (!statMap.containsKey("Policies")) statMap["Policies"] = 0f
|
if (!statMap.containsKey("Policies")) statMap["Policies"] = 0f
|
||||||
statMap["Policies"] = statMap["Policies"]!! +
|
statMap["Policies"] = statMap["Policies"]!! +
|
||||||
civInfo.policies.getAdoptedPolicies().count { !it.endsWith("Complete") } / 2
|
civInfo.policies.getAdoptedPolicies().count { !Policy.isBranchCompleteByName(it) } / 2
|
||||||
}
|
}
|
||||||
|
|
||||||
var happinessPerNaturalWonder = 1f
|
var happinessPerNaturalWonder = 1f
|
||||||
|
@ -204,7 +204,7 @@ class CivilizationInfo {
|
|||||||
fun isAlive(): Boolean = !isDefeated()
|
fun isAlive(): Boolean = !isDefeated()
|
||||||
fun hasEverBeenFriendWith(otherCiv: CivilizationInfo): Boolean = getDiplomacyManager(otherCiv).everBeenFriends()
|
fun hasEverBeenFriendWith(otherCiv: CivilizationInfo): Boolean = getDiplomacyManager(otherCiv).everBeenFriends()
|
||||||
fun hasMetCivTerritory(otherCiv: CivilizationInfo): Boolean = otherCiv.getCivTerritory().any { it in exploredTiles }
|
fun hasMetCivTerritory(otherCiv: CivilizationInfo): Boolean = otherCiv.getCivTerritory().any { it in exploredTiles }
|
||||||
fun getCompletedPolicyBranchesCount(): Int = policies.adoptedPolicies.count { it.endsWith("Complete") }
|
fun getCompletedPolicyBranchesCount(): Int = policies.adoptedPolicies.count { Policy.isBranchCompleteByName(it) }
|
||||||
private fun getCivTerritory() = cities.asSequence().flatMap { it.tiles.asSequence() }
|
private fun getCivTerritory() = cities.asSequence().flatMap { it.tiles.asSequence() }
|
||||||
|
|
||||||
fun victoryType(): VictoryType {
|
fun victoryType(): VictoryType {
|
||||||
@ -490,7 +490,7 @@ class CivilizationInfo {
|
|||||||
RankingType.Force -> units.sumBy { it.baseUnit.strength }
|
RankingType.Force -> units.sumBy { it.baseUnit.strength }
|
||||||
RankingType.Happiness -> getHappiness()
|
RankingType.Happiness -> getHappiness()
|
||||||
RankingType.Technologies -> tech.researchedTechnologies.size
|
RankingType.Technologies -> tech.researchedTechnologies.size
|
||||||
RankingType.Culture -> policies.adoptedPolicies.count { !it.endsWith("Complete") }
|
RankingType.Culture -> policies.adoptedPolicies.count { !Policy.isBranchCompleteByName(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -520,7 +520,7 @@ class CivilizationInfo {
|
|||||||
|
|
||||||
policies.civInfo = this
|
policies.civInfo = this
|
||||||
if (policies.adoptedPolicies.size > 0 && policies.numberOfAdoptedPolicies == 0)
|
if (policies.adoptedPolicies.size > 0 && policies.numberOfAdoptedPolicies == 0)
|
||||||
policies.numberOfAdoptedPolicies = policies.adoptedPolicies.count { !it.endsWith("Complete") }
|
policies.numberOfAdoptedPolicies = policies.adoptedPolicies.count { !Policy.isBranchCompleteByName(it) }
|
||||||
policies.setTransients()
|
policies.setTransients()
|
||||||
|
|
||||||
questManager.civInfo = this
|
questManager.civInfo = this
|
||||||
|
@ -2,6 +2,7 @@ package com.unciv.logic.civilization
|
|||||||
|
|
||||||
import com.unciv.logic.map.MapSize
|
import com.unciv.logic.map.MapSize
|
||||||
import com.unciv.models.ruleset.Policy
|
import com.unciv.models.ruleset.Policy
|
||||||
|
import com.unciv.models.ruleset.Policy.PolicyBranchType
|
||||||
import com.unciv.models.ruleset.UniqueMap
|
import com.unciv.models.ruleset.UniqueMap
|
||||||
import com.unciv.models.ruleset.UniqueTriggerActivation
|
import com.unciv.models.ruleset.UniqueTriggerActivation
|
||||||
import com.unciv.models.translations.equalsPlaceholderText
|
import com.unciv.models.translations.equalsPlaceholderText
|
||||||
@ -124,7 +125,7 @@ class PolicyManager {
|
|||||||
*/
|
*/
|
||||||
fun isAdoptable(policy: Policy, checkEra: Boolean = true): Boolean {
|
fun isAdoptable(policy: Policy, checkEra: Boolean = true): Boolean {
|
||||||
if (isAdopted(policy.name)) return false
|
if (isAdopted(policy.name)) return false
|
||||||
if (policy.name.endsWith("Complete")) return false
|
if (policy.policyBranchType == PolicyBranchType.BranchComplete) return false
|
||||||
if (!getAdoptedPolicies().containsAll(policy.requires!!)) return false
|
if (!getAdoptedPolicies().containsAll(policy.requires!!)) return false
|
||||||
if (checkEra && civInfo.gameInfo.ruleSet.getEraNumber(policy.branch.era) > civInfo.getEraNumber()) return false
|
if (checkEra && civInfo.gameInfo.ruleSet.getEraNumber(policy.branch.era) > civInfo.getEraNumber()) return false
|
||||||
if (policy.uniqueObjects.any { it.placeholderText == "Incompatible with []" && adoptedPolicies.contains(it.params[0]) }) return false
|
if (policy.uniqueObjects.any { it.placeholderText == "Incompatible with []" && adoptedPolicies.contains(it.params[0]) }) return false
|
||||||
|
@ -2,8 +2,10 @@ package com.unciv.models.ruleset
|
|||||||
|
|
||||||
import com.unciv.UncivGame
|
import com.unciv.UncivGame
|
||||||
import com.unciv.models.stats.INamed
|
import com.unciv.models.stats.INamed
|
||||||
|
import com.unciv.models.translations.tr
|
||||||
import com.unciv.ui.civilopedia.FormattedLine
|
import com.unciv.ui.civilopedia.FormattedLine
|
||||||
import com.unciv.ui.civilopedia.ICivilopediaText
|
import com.unciv.ui.civilopedia.ICivilopediaText
|
||||||
|
import java.text.Collator
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
|
|
||||||
class Belief : INamed, ICivilopediaText, IHasUniques {
|
class Belief : INamed, ICivilopediaText, IHasUniques {
|
||||||
@ -15,12 +17,16 @@ class Belief : INamed, ICivilopediaText, IHasUniques {
|
|||||||
override var civilopediaText = listOf<FormattedLine>()
|
override var civilopediaText = listOf<FormattedLine>()
|
||||||
|
|
||||||
override fun makeLink() = "Belief/$name"
|
override fun makeLink() = "Belief/$name"
|
||||||
|
override fun getCivilopediaTextHeader() = FormattedLine(name, icon = makeLink(), header = 2, color = if (type == BeliefType.None) "#e34a2b" else "")
|
||||||
override fun replacesCivilopediaDescription() = true
|
override fun replacesCivilopediaDescription() = true
|
||||||
override fun hasCivilopediaTextLines() = true
|
override fun hasCivilopediaTextLines() = true
|
||||||
|
override fun getSortGroup(ruleset: Ruleset) = type.ordinal
|
||||||
|
override fun getIconName() = if (type == BeliefType.None) "Religion" else type.name
|
||||||
|
|
||||||
override fun getCivilopediaTextLines(ruleset: Ruleset): List<FormattedLine> {
|
override fun getCivilopediaTextLines(ruleset: Ruleset): List<FormattedLine> {
|
||||||
val textList = ArrayList<FormattedLine>()
|
val textList = ArrayList<FormattedLine>()
|
||||||
textList += FormattedLine("{Type}: $type", color=type.color )
|
if (type != BeliefType.None)
|
||||||
|
textList += FormattedLine("{Type}: $type", color = type.color )
|
||||||
uniqueObjects.forEach {
|
uniqueObjects.forEach {
|
||||||
textList += FormattedLine(it)
|
textList += FormattedLine(it)
|
||||||
}
|
}
|
||||||
@ -49,7 +55,17 @@ class Belief : INamed, ICivilopediaText, IHasUniques {
|
|||||||
val matchingBeliefs = getBeliefsMatching(name, ruleset)
|
val matchingBeliefs = getBeliefsMatching(name, ruleset)
|
||||||
if (matchingBeliefs.none()) return@sequence
|
if (matchingBeliefs.none()) return@sequence
|
||||||
if (withSeeAlso) { yield(FormattedLine()); yield(FormattedLine("{See also}:")) }
|
if (withSeeAlso) { yield(FormattedLine()); yield(FormattedLine("{See also}:")) }
|
||||||
yieldAll(matchingBeliefs.map { FormattedLine(it.name, link=it.makeLink(), indent = 1) })
|
yieldAll(matchingBeliefs.map { FormattedLine(it.name, link = it.makeLink(), indent = 1) })
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getCivilopediaReligionEntry(ruleset: Ruleset) = Belief().apply {
|
||||||
|
name = "Religions"
|
||||||
|
val lines = ArrayList<FormattedLine>()
|
||||||
|
lines += FormattedLine(separator = true)
|
||||||
|
ruleset.religions.sortedWith(compareBy(Collator.getInstance(), { it.tr() })).forEach {
|
||||||
|
lines += FormattedLine(it, icon = "Belief/$it")
|
||||||
|
}
|
||||||
|
civilopediaText = lines
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,9 +31,27 @@ class Era : INamed {
|
|||||||
repeat(startingMilitaryUnitCount) {startingUnits.add(startingMilitaryUnit)}
|
repeat(startingMilitaryUnitCount) {startingUnits.add(startingMilitaryUnit)}
|
||||||
return startingUnits
|
return startingUnits
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getColor(): Color {
|
fun getColor(): Color {
|
||||||
if (iconRGB == null) return Color.WHITE.cpy()
|
if (iconRGB == null) return Color.WHITE.cpy()
|
||||||
return colorFromRGB(iconRGB!![0], iconRGB!![1], iconRGB!![2])
|
return colorFromRGB(iconRGB!![0], iconRGB!![1], iconRGB!![2])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getHexColor() = "#" + getColor().toString().substring(0,6)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
// User for CS bonuses in case the Eras file is missing (legacy mods)
|
||||||
|
fun getLegacyCityStateBonusEra(eraNumber: Int) = Era().apply {
|
||||||
|
val cultureBonus = if(eraNumber in 0..1) 3 else if (eraNumber in 2..3) 6 else 13
|
||||||
|
val happinessBonus = if(eraNumber in 0..1) 2 else 3
|
||||||
|
friendBonus[CityStateType.Militaristic.name] = arrayListOf("Provides military units every [20] turns")
|
||||||
|
friendBonus[CityStateType.Cultured.name] = arrayListOf("Provides [$cultureBonus] [Culture] per turn")
|
||||||
|
friendBonus[CityStateType.Mercantile.name] = arrayListOf("Provides [$happinessBonus] Happiness")
|
||||||
|
friendBonus[CityStateType.Maritime.name] = arrayListOf("Provides [2] [Food] [in capital]")
|
||||||
|
allyBonus[CityStateType.Militaristic.name] = arrayListOf("Provides military units every [17] turns")
|
||||||
|
allyBonus[CityStateType.Cultured.name] = arrayListOf("Provides [${cultureBonus*2}] [Culture] per turn")
|
||||||
|
allyBonus[CityStateType.Mercantile.name] = arrayListOf("Provides [$happinessBonus] Happiness", "Provides a unique luxury")
|
||||||
|
allyBonus[CityStateType.Maritime.name] = arrayListOf("Provides [2] [Food] [in capital]", "Provides [1] [Food] [in all cities]")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.unciv.Constants
|
import com.unciv.Constants
|
||||||
|
import com.unciv.UncivGame
|
||||||
import com.unciv.logic.civilization.CityStateType
|
import com.unciv.logic.civilization.CityStateType
|
||||||
import com.unciv.models.stats.INamed
|
import com.unciv.models.stats.INamed
|
||||||
import com.unciv.models.translations.squareBraceRegex
|
import com.unciv.models.translations.squareBraceRegex
|
||||||
@ -195,8 +196,15 @@ class Nation : INamed, ICivilopediaText, IHasUniques {
|
|||||||
override fun makeLink() = "Nation/$name"
|
override fun makeLink() = "Nation/$name"
|
||||||
override fun replacesCivilopediaDescription() = true
|
override fun replacesCivilopediaDescription() = true
|
||||||
override fun hasCivilopediaTextLines() = true
|
override fun hasCivilopediaTextLines() = true
|
||||||
|
override fun getSortGroup(ruleset: Ruleset) = when {
|
||||||
|
isCityState() -> 1
|
||||||
|
isBarbarian() -> 9
|
||||||
|
else -> 0
|
||||||
|
}
|
||||||
|
|
||||||
override fun getCivilopediaTextLines(ruleset: Ruleset): List<FormattedLine> {
|
override fun getCivilopediaTextLines(ruleset: Ruleset): List<FormattedLine> {
|
||||||
|
if (isCityState()) return getCityStateInfo(ruleset)
|
||||||
|
|
||||||
val textList = ArrayList<FormattedLine>()
|
val textList = ArrayList<FormattedLine>()
|
||||||
|
|
||||||
if (leaderName.isNotEmpty()) {
|
if (leaderName.isNotEmpty()) {
|
||||||
@ -235,6 +243,50 @@ class Nation : INamed, ICivilopediaText, IHasUniques {
|
|||||||
return textList
|
return textList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getCityStateInfo(ruleset: Ruleset): List<FormattedLine> {
|
||||||
|
val textList = ArrayList<FormattedLine>()
|
||||||
|
|
||||||
|
textList += FormattedLine("Type: [$cityStateType]", header = 4, color = cityStateType!!.color)
|
||||||
|
val viewingCiv = UncivGame.Current.gameInfo.currentPlayerCiv
|
||||||
|
val era = viewingCiv.getEraObject() ?: Era.getLegacyCityStateBonusEra(viewingCiv.getEraNumber())
|
||||||
|
var showResources = false
|
||||||
|
|
||||||
|
val friendBonus = era.friendBonus[cityStateType!!.name]
|
||||||
|
if (friendBonus != null && friendBonus.isNotEmpty()) {
|
||||||
|
textList += FormattedLine()
|
||||||
|
textList += FormattedLine("When Friends: ")
|
||||||
|
friendBonus.forEach {
|
||||||
|
textList += FormattedLine(Unique(it), indent = 1)
|
||||||
|
if (it == "Provides a unique luxury") showResources = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val allyBonus = era.allyBonus[cityStateType!!.name]
|
||||||
|
if (allyBonus != null && allyBonus.isNotEmpty()) {
|
||||||
|
textList += FormattedLine()
|
||||||
|
textList += FormattedLine("When Allies: ")
|
||||||
|
allyBonus.forEach {
|
||||||
|
textList += FormattedLine(Unique(it), indent = 1)
|
||||||
|
if (it == "Provides a unique luxury") showResources = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showResources) {
|
||||||
|
val allMercantileResources = ruleset.tileResources.values
|
||||||
|
.filter { it.unique == "Can only be created by Mercantile City-States" }
|
||||||
|
if (allMercantileResources.isNotEmpty()) {
|
||||||
|
textList += FormattedLine()
|
||||||
|
textList += FormattedLine("The unique luxury is one of:")
|
||||||
|
allMercantileResources.forEach {
|
||||||
|
textList += FormattedLine(it.name, it.makeLink(), indent = 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// personality is not a nation property, it gets assigned to the civ randomly
|
||||||
|
return textList
|
||||||
|
}
|
||||||
|
|
||||||
@JvmName("addUniqueBuildingsText1") // These overloads are too similar - but I hope to remove the other one soon
|
@JvmName("addUniqueBuildingsText1") // These overloads are too similar - but I hope to remove the other one soon
|
||||||
private fun addUniqueBuildingsText(textList: ArrayList<FormattedLine>, ruleset: Ruleset) {
|
private fun addUniqueBuildingsText(textList: ArrayList<FormattedLine>, ruleset: Ruleset) {
|
||||||
for (building in ruleset.buildings.values) {
|
for (building in ruleset.buildings.values) {
|
||||||
@ -305,10 +357,10 @@ class Nation : INamed, ICivilopediaText, IHasUniques {
|
|||||||
link = "Promotion/$promotion", indent = 1 )
|
link = "Promotion/$promotion", indent = 1 )
|
||||||
}
|
}
|
||||||
} else if (unit.replaces != null) {
|
} else if (unit.replaces != null) {
|
||||||
textList += FormattedLine("Replaces [${unit.replaces}], which is not found in the ruleset!", indent=1)
|
textList += FormattedLine("Replaces [${unit.replaces}], which is not found in the ruleset!", indent = 1)
|
||||||
} else {
|
} else {
|
||||||
textList += unit.getCivilopediaTextLines(ruleset).map {
|
textList += unit.getCivilopediaTextLines(ruleset).map {
|
||||||
FormattedLine(it.text, link=it.link, indent = it.indent + 1, color=it.color)
|
FormattedLine(it.text, link = it.link, indent = it.indent + 1, color = it.color)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,16 +373,16 @@ class Nation : INamed, ICivilopediaText, IHasUniques {
|
|||||||
for (improvement in ruleset.tileImprovements.values) {
|
for (improvement in ruleset.tileImprovements.values) {
|
||||||
if (improvement.uniqueTo != name ) continue
|
if (improvement.uniqueTo != name ) continue
|
||||||
|
|
||||||
textList += FormattedLine(improvement.name, link="Improvement/${improvement.name}")
|
textList += FormattedLine(improvement.name, link = "Improvement/${improvement.name}")
|
||||||
textList += FormattedLine(improvement.clone().toString(), indent=1) // = (improvement as Stats).toString minus import plus copy overhead
|
textList += FormattedLine(improvement.clone().toString(), indent = 1) // = (improvement as Stats).toString minus import plus copy overhead
|
||||||
if (improvement.terrainsCanBeBuiltOn.isNotEmpty()) {
|
if (improvement.terrainsCanBeBuiltOn.isNotEmpty()) {
|
||||||
improvement.terrainsCanBeBuiltOn.withIndex().forEach {
|
improvement.terrainsCanBeBuiltOn.withIndex().forEach {
|
||||||
textList += FormattedLine(if (it.index == 0) "{Can be built on} {${it.value}}" else "or [${it.value}]",
|
textList += FormattedLine(if (it.index == 0) "{Can be built on} {${it.value}}" else "or [${it.value}]",
|
||||||
link="Terrain/${it.value}", indent=if (it.index == 0) 1 else 2)
|
link = "Terrain/${it.value}", indent = if (it.index == 0) 1 else 2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (unique in improvement.uniques)
|
for (unique in improvement.uniques)
|
||||||
textList += FormattedLine(unique, indent=1)
|
textList += FormattedLine(unique, indent = 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
package com.unciv.models.ruleset
|
package com.unciv.models.ruleset
|
||||||
|
|
||||||
import com.unciv.models.stats.INamed
|
import com.unciv.models.stats.INamed
|
||||||
|
import com.unciv.models.translations.tr
|
||||||
|
import com.unciv.ui.civilopedia.FormattedLine
|
||||||
|
import com.unciv.ui.civilopedia.ICivilopediaText
|
||||||
|
|
||||||
open class Policy : INamed, IHasUniques {
|
open class Policy : INamed, IHasUniques, ICivilopediaText {
|
||||||
lateinit var branch: PolicyBranch // not in json - added in gameBasics
|
lateinit var branch: PolicyBranch // not in json - added in gameBasics
|
||||||
|
|
||||||
override lateinit var name: String
|
override lateinit var name: String
|
||||||
@ -12,6 +15,94 @@ open class Policy : INamed, IHasUniques {
|
|||||||
var column: Int = 0
|
var column: Int = 0
|
||||||
var requires: ArrayList<String>? = null
|
var requires: ArrayList<String>? = null
|
||||||
|
|
||||||
|
override var civilopediaText = listOf<FormattedLine>()
|
||||||
|
|
||||||
|
/** 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.
|
||||||
|
* To keep the hardcoding in one place, this is public and should be used instead of duplicating it.
|
||||||
|
*/
|
||||||
|
fun isBranchCompleteByName(name: String) = name.endsWith(branchCompleteSuffix)
|
||||||
|
}
|
||||||
|
|
||||||
override fun toString() = name
|
override fun toString() = name
|
||||||
|
|
||||||
|
/** Used in PolicyPickerScreen to display Policy properties */
|
||||||
|
fun getDescription(): String {
|
||||||
|
val policyText = ArrayList<String>()
|
||||||
|
policyText += name
|
||||||
|
policyText += uniques
|
||||||
|
|
||||||
|
if (policyBranchType != PolicyBranchType.BranchComplete) {
|
||||||
|
policyText += if (requires!!.isNotEmpty())
|
||||||
|
"Requires [" + requires!!.joinToString { it.tr() } + "]"
|
||||||
|
else
|
||||||
|
"{Unlocked at} {${branch.era}}"
|
||||||
|
}
|
||||||
|
return policyText.joinToString("\n") { it.tr() }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun makeLink() = "Policy/$name"
|
||||||
|
override fun replacesCivilopediaDescription() = true
|
||||||
|
override fun hasCivilopediaTextLines() = true
|
||||||
|
override fun getSortGroup(ruleset: Ruleset) =
|
||||||
|
ruleset.getEraNumber(branch.era) * 10000 +
|
||||||
|
ruleset.policyBranches.keys.indexOf(branch.name) * 100 +
|
||||||
|
policyBranchType.ordinal
|
||||||
|
|
||||||
|
override fun getCivilopediaTextLines(ruleset: Ruleset): List<FormattedLine> {
|
||||||
|
val lineList = ArrayList<FormattedLine>()
|
||||||
|
|
||||||
|
lineList += if (this is PolicyBranch) {
|
||||||
|
val eraColor = ruleset.eras[era]?.getHexColor() ?: ""
|
||||||
|
FormattedLine("{Unlocked at} {${branch.era}}", header = 4, color = eraColor)
|
||||||
|
} else {
|
||||||
|
FormattedLine("Policy branch: [${branch.name}]", link = branch.makeLink())
|
||||||
|
}
|
||||||
|
|
||||||
|
if (policyBranchType != PolicyBranchType.BranchComplete && requires != null && requires!!.isNotEmpty()) {
|
||||||
|
lineList += FormattedLine()
|
||||||
|
if (requires!!.size == 1)
|
||||||
|
requires!!.first().let { lineList += FormattedLine("Requires: [$it]", link = "Policy/$it") }
|
||||||
|
else {
|
||||||
|
lineList += FormattedLine("Requires all of the following:")
|
||||||
|
requires!!.forEach {
|
||||||
|
lineList += FormattedLine(it, link = "Policy/$it")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val leadsTo = ruleset.policies.values.filter {
|
||||||
|
it.requires != null && name in it.requires!!
|
||||||
|
&& it.policyBranchType != PolicyBranchType.BranchComplete
|
||||||
|
}
|
||||||
|
if (leadsTo.isNotEmpty()) {
|
||||||
|
lineList += FormattedLine()
|
||||||
|
if (leadsTo.size == 1)
|
||||||
|
leadsTo.first().let { lineList += FormattedLine("Leads to [${it.name}]", link = it.makeLink()) }
|
||||||
|
else {
|
||||||
|
lineList += FormattedLine("Leads to:")
|
||||||
|
leadsTo.forEach {
|
||||||
|
lineList += FormattedLine(it.name, link = it.makeLink(), indent = 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uniques.isNotEmpty()) {
|
||||||
|
lineList += FormattedLine()
|
||||||
|
for (unique in uniqueObjects) lineList += FormattedLine(unique)
|
||||||
|
}
|
||||||
|
|
||||||
|
return lineList
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,12 +4,12 @@ import com.unciv.models.stats.INamed
|
|||||||
import com.unciv.ui.civilopedia.FormattedLine
|
import com.unciv.ui.civilopedia.FormattedLine
|
||||||
import com.unciv.ui.civilopedia.ICivilopediaText
|
import com.unciv.ui.civilopedia.ICivilopediaText
|
||||||
|
|
||||||
class RuinReward : INamed, ICivilopediaText {
|
class RuinReward : INamed, ICivilopediaText, IHasUniques {
|
||||||
override lateinit var name: String // Displayed in Civilopedia!
|
override lateinit var name: String // Displayed in Civilopedia!
|
||||||
val notification: String = ""
|
val notification: String = ""
|
||||||
val uniques: List<String> = listOf()
|
override var uniques = ArrayList<String>()
|
||||||
@delegate:Transient // Defense in depth against mad modders
|
@delegate:Transient // Defense in depth against mad modders
|
||||||
val uniqueObjects: List<Unique> by lazy { uniques.map { Unique(it) } }
|
override val uniqueObjects: List<Unique> by lazy { uniques.map { Unique(it) } }
|
||||||
val excludedDifficulties: List<String> = listOf()
|
val excludedDifficulties: List<String> = listOf()
|
||||||
val weight: Int = 1
|
val weight: Int = 1
|
||||||
val color: String = "" // For Civilopedia
|
val color: String = "" // For Civilopedia
|
||||||
|
@ -206,7 +206,7 @@ class Ruleset {
|
|||||||
if (policy.requires == null) policy.requires = arrayListOf(branch.name)
|
if (policy.requires == null) policy.requires = arrayListOf(branch.name)
|
||||||
policies[policy.name] = policy
|
policies[policy.name] = policy
|
||||||
}
|
}
|
||||||
branch.policies.last().name = branch.name + " Complete"
|
branch.policies.last().name = branch.name + Policy.branchCompleteSuffix
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +150,8 @@ class Technology: INamed, ICivilopediaText, IHasUniques {
|
|||||||
override fun getCivilopediaTextLines(ruleset: Ruleset): List<FormattedLine> {
|
override fun getCivilopediaTextLines(ruleset: Ruleset): List<FormattedLine> {
|
||||||
val lineList = ArrayList<FormattedLine>()
|
val lineList = ArrayList<FormattedLine>()
|
||||||
|
|
||||||
lineList += FormattedLine(era(), header = 3, color = "#8080ff")
|
val eraColor = ruleset.eras[era()]?.getHexColor() ?: ""
|
||||||
|
lineList += FormattedLine(era(), header = 3, color = eraColor)
|
||||||
lineList += FormattedLine()
|
lineList += FormattedLine()
|
||||||
lineList += FormattedLine("{Cost}: $cost${Fonts.science}")
|
lineList += FormattedLine("{Cost}: $cost${Fonts.science}")
|
||||||
|
|
||||||
|
@ -127,21 +127,12 @@ class Terrain : NamedStats(), ICivilopediaText {
|
|||||||
if (defenceBonus != 0f)
|
if (defenceBonus != 0f)
|
||||||
textList += FormattedLine("{Defence bonus}: ${(defenceBonus * 100).toInt()}%")
|
textList += FormattedLine("{Defence bonus}: ${(defenceBonus * 100).toInt()}%")
|
||||||
|
|
||||||
val seeAlso = (
|
val seeAlso = (ruleset.buildings.values.asSequence() + ruleset.units.values.asSequence())
|
||||||
//todo: Could vastly be simplified using upcoming INonPerpetualConstruction
|
.filter {
|
||||||
ruleset.buildings.values.asSequence()
|
construction -> construction.uniqueObjects.any {
|
||||||
.filter {
|
unique -> unique.params.any { it == name }
|
||||||
building -> building.uniqueObjects.any {
|
|
||||||
unique -> unique.params.any { it == name }
|
|
||||||
}
|
|
||||||
} +
|
|
||||||
ruleset.units.values.asSequence()
|
|
||||||
.filter {
|
|
||||||
unit -> unit.uniqueObjects.any {
|
|
||||||
unique -> unique.params.any { it == name }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
).map { FormattedLine(it.name, it.makeLink(), indent=1) } +
|
}.map { FormattedLine(it.name, it.makeLink(), indent=1) } +
|
||||||
Belief.getCivilopediaTextMatching(name, ruleset, false)
|
Belief.getCivilopediaTextMatching(name, ruleset, false)
|
||||||
if (seeAlso.any()) {
|
if (seeAlso.any()) {
|
||||||
textList += FormattedLine()
|
textList += FormattedLine()
|
||||||
|
@ -3,7 +3,6 @@ package com.unciv.models.ruleset.tile
|
|||||||
import com.unciv.Constants
|
import com.unciv.Constants
|
||||||
import com.unciv.UncivGame
|
import com.unciv.UncivGame
|
||||||
import com.unciv.logic.civilization.CivilizationInfo
|
import com.unciv.logic.civilization.CivilizationInfo
|
||||||
import com.unciv.logic.civilization.RuinsManager.RuinsManager
|
|
||||||
import com.unciv.models.ruleset.Belief
|
import com.unciv.models.ruleset.Belief
|
||||||
import com.unciv.logic.map.RoadStatus
|
import com.unciv.logic.map.RoadStatus
|
||||||
import com.unciv.models.ruleset.IHasUniques
|
import com.unciv.models.ruleset.IHasUniques
|
||||||
|
@ -200,10 +200,10 @@ class BaseUnit : INamed, INonPerpetualConstruction, ICivilopediaText {
|
|||||||
var productionCost = cost.toFloat()
|
var productionCost = cost.toFloat()
|
||||||
if (civInfo.isCityState())
|
if (civInfo.isCityState())
|
||||||
productionCost *= 1.5f
|
productionCost *= 1.5f
|
||||||
if (civInfo.isPlayerCivilization())
|
productionCost *= if (civInfo.isPlayerCivilization())
|
||||||
productionCost *= civInfo.getDifficulty().unitCostModifier
|
civInfo.getDifficulty().unitCostModifier
|
||||||
else
|
else
|
||||||
productionCost *= civInfo.gameInfo.getDifficulty().aiUnitCostModifier
|
civInfo.gameInfo.getDifficulty().aiUnitCostModifier
|
||||||
productionCost *= civInfo.gameInfo.gameParameters.gameSpeed.modifier
|
productionCost *= civInfo.gameInfo.gameParameters.gameSpeed.modifier
|
||||||
return productionCost.toInt()
|
return productionCost.toInt()
|
||||||
}
|
}
|
||||||
@ -298,8 +298,8 @@ class BaseUnit : INamed, INonPerpetualConstruction, ICivilopediaText {
|
|||||||
|
|
||||||
for ((resource, amount) in getResourceRequirements())
|
for ((resource, amount) in getResourceRequirements())
|
||||||
if (civInfo.getCivResourcesByName()[resource]!! < amount) {
|
if (civInfo.getCivResourcesByName()[resource]!! < amount) {
|
||||||
if (amount == 1) return "Consumes 1 [$resource]" // Again, to preserve existing translations
|
return if (amount == 1) "Consumes 1 [$resource]" // Again, to preserve existing translations
|
||||||
else return "Consumes [$amount] [$resource]"
|
else "Consumes [$amount] [$resource]"
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uniques.contains(Constants.settlerUnique) && civInfo.isCityState()) return "No settler for city-states"
|
if (uniques.contains(Constants.settlerUnique) && civInfo.isCityState()) return "No settler for city-states"
|
||||||
@ -322,7 +322,7 @@ class BaseUnit : INamed, INonPerpetualConstruction, ICivilopediaText {
|
|||||||
override fun postBuildEvent(cityConstructions: CityConstructions, wasBought: Boolean): Boolean {
|
override fun postBuildEvent(cityConstructions: CityConstructions, wasBought: Boolean): Boolean {
|
||||||
val civInfo = cityConstructions.cityInfo.civInfo
|
val civInfo = cityConstructions.cityInfo.civInfo
|
||||||
val unit = civInfo.placeUnitNearTile(cityConstructions.cityInfo.location, name)
|
val unit = civInfo.placeUnitNearTile(cityConstructions.cityInfo.location, name)
|
||||||
if (unit == null) return false // couldn't place the unit, so there's actually no unit =(
|
?: return false // couldn't place the unit, so there's actually no unit =(
|
||||||
|
|
||||||
//movement penalty
|
//movement penalty
|
||||||
if (wasBought && !civInfo.gameInfo.gameParameters.godMode && !unit.hasUnique("Can move immediately once bought"))
|
if (wasBought && !civInfo.gameInfo.gameParameters.godMode && !unit.hasUnique("Can move immediately once bought"))
|
||||||
|
@ -16,7 +16,7 @@ enum class Stat(
|
|||||||
Culture(NotificationIcon.Culture, UncivSound.Paper, Fonts.culture),
|
Culture(NotificationIcon.Culture, UncivSound.Paper, Fonts.culture),
|
||||||
Happiness(NotificationIcon.Happiness, UncivSound.Click, Fonts.happiness),
|
Happiness(NotificationIcon.Happiness, UncivSound.Click, Fonts.happiness),
|
||||||
Faith(NotificationIcon.Faith, UncivSound.Choir, Fonts.faith);
|
Faith(NotificationIcon.Faith, UncivSound.Choir, Fonts.faith);
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val statsUsableToBuy = listOf(Gold, Food, Science, Culture, Faith)
|
val statsUsableToBuy = listOf(Gold, Food, Science, Culture, Faith)
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ import java.io.File
|
|||||||
/** Encapsulates the knowledge on how to get an icon for each of the Civilopedia categories */
|
/** Encapsulates the knowledge on how to get an icon for each of the Civilopedia categories */
|
||||||
object CivilopediaImageGetters {
|
object CivilopediaImageGetters {
|
||||||
private const val policyIconFolder = "PolicyIcons"
|
private const val policyIconFolder = "PolicyIcons"
|
||||||
|
private const val policyInnerSize = 0.25f
|
||||||
|
|
||||||
// Todo: potential synergy with map editor
|
// Todo: potential synergy with map editor
|
||||||
fun terrainImage(terrain: Terrain, ruleset: Ruleset, imageSize: Float): Actor {
|
fun terrainImage(terrain: Terrain, ruleset: Ruleset, imageSize: Float): Actor {
|
||||||
@ -48,7 +49,7 @@ object CivilopediaImageGetters {
|
|||||||
|
|
||||||
val construction = { name: String, size: Float ->
|
val construction = { name: String, size: Float ->
|
||||||
ImageGetter.getConstructionImage(name)
|
ImageGetter.getConstructionImage(name)
|
||||||
.surroundWithCircle(size, color = Color.WHITE)
|
.surroundWithCircle(size)
|
||||||
}
|
}
|
||||||
val improvement = { name: String, size: Float ->
|
val improvement = { name: String, size: Float ->
|
||||||
ImageGetter.getImprovementIcon(name, size)
|
ImageGetter.getImprovementIcon(name, size)
|
||||||
@ -59,8 +60,16 @@ object CivilopediaImageGetters {
|
|||||||
else ImageGetter.getNationIndicator(nation, size)
|
else ImageGetter.getNationIndicator(nation, size)
|
||||||
}
|
}
|
||||||
val policy = { name: String, size: Float ->
|
val policy = { name: String, size: Float ->
|
||||||
ImageGetter.getImage(policyIconFolder + File.separator + name)
|
// policy branch start and complete have no icons but are linked -> nonexistence must be passed down
|
||||||
.apply { setSize(size,size) }
|
val fileName = policyIconFolder + File.separator + name
|
||||||
|
if (ImageGetter.imageExists(fileName))
|
||||||
|
ImageGetter.getImage(fileName)
|
||||||
|
.apply {
|
||||||
|
setSize(size * policyInnerSize,size * policyInnerSize)
|
||||||
|
color = Color.BROWN
|
||||||
|
}
|
||||||
|
.surroundWithCircle(size)
|
||||||
|
else null
|
||||||
}
|
}
|
||||||
val resource = { name: String, size: Float ->
|
val resource = { name: String, size: Float ->
|
||||||
ImageGetter.getResourceImage(name, size)
|
ImageGetter.getResourceImage(name, size)
|
||||||
@ -97,6 +106,7 @@ object CivilopediaImageGetters {
|
|||||||
/** Enum used as keys for Civilopedia "pages" (categories).
|
/** Enum used as keys for Civilopedia "pages" (categories).
|
||||||
*
|
*
|
||||||
* Note names are singular on purpose - a "link" allows both key and label
|
* Note names are singular on purpose - a "link" allows both key and label
|
||||||
|
* Order of values determines ordering of the categories in the Civilopedia top bar
|
||||||
*
|
*
|
||||||
* @param label Translatable caption for the Civilopedia button
|
* @param label Translatable caption for the Civilopedia button
|
||||||
*/
|
*/
|
||||||
@ -114,10 +124,10 @@ enum class CivilopediaCategories (
|
|||||||
Nation ("Nations", false, CivilopediaImageGetters.nation ),
|
Nation ("Nations", false, CivilopediaImageGetters.nation ),
|
||||||
Technology ("Technologies", false, CivilopediaImageGetters.technology ),
|
Technology ("Technologies", false, CivilopediaImageGetters.technology ),
|
||||||
Promotion ("Promotions", false, CivilopediaImageGetters.promotion ),
|
Promotion ("Promotions", false, CivilopediaImageGetters.promotion ),
|
||||||
Policy ("Policies", true, CivilopediaImageGetters.policy ),
|
Policy ("Policies", false, CivilopediaImageGetters.policy ),
|
||||||
|
Belief("Religions and Beliefs", false, CivilopediaImageGetters.belief ),
|
||||||
Tutorial ("Tutorials", false, null ),
|
Tutorial ("Tutorials", false, null ),
|
||||||
Difficulty ("Difficulty levels", false, null ),
|
Difficulty ("Difficulty levels", false, null ),
|
||||||
Belief("Religions and Beliefs", false, CivilopediaImageGetters.belief)
|
|
||||||
;
|
;
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -6,6 +6,7 @@ import com.badlogic.gdx.scenes.scene2d.Touchable
|
|||||||
import com.badlogic.gdx.scenes.scene2d.ui.*
|
import com.badlogic.gdx.scenes.scene2d.ui.*
|
||||||
import com.unciv.Constants
|
import com.unciv.Constants
|
||||||
import com.unciv.UncivGame
|
import com.unciv.UncivGame
|
||||||
|
import com.unciv.models.ruleset.Belief
|
||||||
import com.unciv.models.ruleset.Ruleset
|
import com.unciv.models.ruleset.Ruleset
|
||||||
import com.unciv.models.ruleset.Unique
|
import com.unciv.models.ruleset.Unique
|
||||||
import com.unciv.models.ruleset.VictoryType
|
import com.unciv.models.ruleset.VictoryType
|
||||||
@ -77,7 +78,7 @@ class CivilopediaScreen(
|
|||||||
/** Select a specified category
|
/** Select a specified category
|
||||||
* @param name Category name or label
|
* @param name Category name or label
|
||||||
*/
|
*/
|
||||||
fun selectCategory(name: String) {
|
private fun selectCategory(name: String) {
|
||||||
val category = CivilopediaCategories.fromLink(name)
|
val category = CivilopediaCategories.fromLink(name)
|
||||||
?: return // silently ignore unknown category names in links
|
?: return // silently ignore unknown category names in links
|
||||||
selectCategory(category)
|
selectCategory(category)
|
||||||
@ -86,7 +87,7 @@ class CivilopediaScreen(
|
|||||||
/** Select a specified category - unselects entry, rebuilds left side buttons.
|
/** Select a specified category - unselects entry, rebuilds left side buttons.
|
||||||
* @param category Category key
|
* @param category Category key
|
||||||
*/
|
*/
|
||||||
fun selectCategory(category: CivilopediaCategories) {
|
private fun selectCategory(category: CivilopediaCategories) {
|
||||||
currentCategory = category
|
currentCategory = category
|
||||||
entrySelectTable.clear()
|
entrySelectTable.clear()
|
||||||
entryIndex.clear()
|
entryIndex.clear()
|
||||||
@ -173,139 +174,53 @@ class CivilopediaScreen(
|
|||||||
onBackButtonClicked { UncivGame.Current.setWorldScreen() }
|
onBackButtonClicked { UncivGame.Current.setWorldScreen() }
|
||||||
|
|
||||||
val hideReligionItems = !game.gameInfo.hasReligionEnabled()
|
val hideReligionItems = !game.gameInfo.hasReligionEnabled()
|
||||||
|
val noCulturalVictory = VictoryType.Cultural !in game.gameInfo.gameParameters.victoryTypes
|
||||||
|
|
||||||
categoryToEntries[CivilopediaCategories.Building] = ruleset.buildings.values
|
fun shouldBeDisplayed(uniqueObjects: List<Unique>): Boolean {
|
||||||
.filter { shouldBeDisplayed(it.uniqueObjects)
|
val uniques = uniqueObjects.map { it.placeholderText }
|
||||||
&& !it.isAnyWonder() }
|
|
||||||
.map {
|
|
||||||
CivilopediaEntry(
|
|
||||||
it.name,
|
|
||||||
"",
|
|
||||||
CivilopediaCategories.Building.getImage?.invoke(it.name, imageSize),
|
|
||||||
(it as? ICivilopediaText).takeUnless { ct -> ct==null || ct.isCivilopediaTextEmpty() }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
categoryToEntries[CivilopediaCategories.Wonder] = ruleset.buildings.values
|
|
||||||
.filter { shouldBeDisplayed(it.uniqueObjects)
|
|
||||||
&& it.isAnyWonder() }
|
|
||||||
.map {
|
|
||||||
CivilopediaEntry(
|
|
||||||
it.name,
|
|
||||||
"",
|
|
||||||
CivilopediaCategories.Wonder.getImage?.invoke(it.name, imageSize),
|
|
||||||
(it as? ICivilopediaText).takeUnless { ct -> ct==null || ct.isCivilopediaTextEmpty() }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
categoryToEntries[CivilopediaCategories.Resource] = ruleset.tileResources.values
|
|
||||||
.map {
|
|
||||||
CivilopediaEntry(
|
|
||||||
it.name,
|
|
||||||
"",
|
|
||||||
CivilopediaCategories.Resource.getImage?.invoke(it.name, imageSize),
|
|
||||||
(it as? ICivilopediaText).takeUnless { ct -> ct==null || ct.isCivilopediaTextEmpty() }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
categoryToEntries[CivilopediaCategories.Terrain] = ruleset.terrains.values
|
|
||||||
.filter { shouldBeDisplayed(it.uniqueObjects) }
|
|
||||||
.map {
|
|
||||||
CivilopediaEntry(
|
|
||||||
it.name,
|
|
||||||
"",
|
|
||||||
CivilopediaCategories.Terrain.getImage?.invoke(it.name, imageSize),
|
|
||||||
(it as? ICivilopediaText).takeUnless { ct -> ct==null || ct.isCivilopediaTextEmpty() }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
categoryToEntries[CivilopediaCategories.Improvement] = ruleset.tileImprovements.values
|
|
||||||
.filter { shouldBeDisplayed(it.uniqueObjects) }
|
|
||||||
.map {
|
|
||||||
CivilopediaEntry(
|
|
||||||
it.name,
|
|
||||||
"",
|
|
||||||
CivilopediaCategories.Improvement.getImage?.invoke(it.name, imageSize),
|
|
||||||
(it as? ICivilopediaText).takeUnless { ct -> ct==null || ct.isCivilopediaTextEmpty() }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
categoryToEntries[CivilopediaCategories.Unit] = ruleset.units.values
|
|
||||||
.filter { shouldBeDisplayed(it.uniqueObjects) }
|
|
||||||
.map {
|
|
||||||
CivilopediaEntry(
|
|
||||||
it.name,
|
|
||||||
"",
|
|
||||||
CivilopediaCategories.Unit.getImage?.invoke(it.name, imageSize),
|
|
||||||
(it as? ICivilopediaText).takeUnless { ct -> ct==null || ct.isCivilopediaTextEmpty() }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
categoryToEntries[CivilopediaCategories.Nation] = ruleset.nations.values
|
|
||||||
.filter { shouldBeDisplayed(it.uniqueObjects) && it.isMajorCiv() }
|
|
||||||
.map {
|
|
||||||
CivilopediaEntry(
|
|
||||||
it.name,
|
|
||||||
"",
|
|
||||||
CivilopediaCategories.Nation.getImage?.invoke(it.name, imageSize),
|
|
||||||
(it as? ICivilopediaText).takeUnless { ct -> ct==null || ct.isCivilopediaTextEmpty() }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
categoryToEntries[CivilopediaCategories.Technology] = ruleset.technologies.values
|
|
||||||
.filter { shouldBeDisplayed(it.uniqueObjects) }
|
|
||||||
.map {
|
|
||||||
CivilopediaEntry(
|
|
||||||
it.name,
|
|
||||||
"",
|
|
||||||
CivilopediaCategories.Technology.getImage?.invoke(it.name, imageSize),
|
|
||||||
(it as? ICivilopediaText).takeUnless { ct -> ct==null || ct.isCivilopediaTextEmpty() }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
categoryToEntries[CivilopediaCategories.Promotion] = ruleset.unitPromotions.values
|
|
||||||
.filter { shouldBeDisplayed(it.uniqueObjects) }
|
|
||||||
.map {
|
|
||||||
CivilopediaEntry(
|
|
||||||
it.name,
|
|
||||||
"",
|
|
||||||
CivilopediaCategories.Promotion.getImage?.invoke(it.name, imageSize),
|
|
||||||
(it as? ICivilopediaText).takeUnless { ct -> ct==null || ct.isCivilopediaTextEmpty() }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
categoryToEntries[CivilopediaCategories.Tutorial] = tutorialController.getCivilopediaTutorials()
|
return Constants.hideFromCivilopediaUnique !in uniques
|
||||||
.map {
|
&& !(hideReligionItems && Constants.hiddenWithoutReligionUnique in uniques)
|
||||||
CivilopediaEntry(
|
&& !(uniqueObjects.filter { unique -> unique.placeholderText == "Hidden when [] Victory is disabled"}.any {
|
||||||
it.name,
|
unique -> !game.gameInfo.gameParameters.victoryTypes.contains(VictoryType.valueOf(unique.params[0] ))
|
||||||
"",
|
})
|
||||||
// CivilopediaCategories.Tutorial.getImage?.invoke(it.name, imageSize)
|
// Deprecated since 3.15.14
|
||||||
flavour = it
|
&& !(noCulturalVictory && "Hidden when cultural victory is disabled" in uniques)
|
||||||
)
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
categoryToEntries[CivilopediaCategories.Difficulty] = ruleset.difficulties.values
|
fun getCategoryIterator(category: CivilopediaCategories): Collection<ICivilopediaText> =
|
||||||
.map {
|
when (category) {
|
||||||
CivilopediaEntry(
|
CivilopediaCategories.Building -> ruleset.buildings.values.filter { !it.isAnyWonder() }
|
||||||
it.name,
|
CivilopediaCategories.Wonder -> ruleset.buildings.values.filter { it.isAnyWonder() }
|
||||||
"",
|
CivilopediaCategories.Resource -> ruleset.tileResources.values
|
||||||
// CivilopediaCategories.Difficulty.getImage?.invoke(it.name, imageSize)
|
CivilopediaCategories.Terrain -> ruleset.terrains.values
|
||||||
flavour = (it as? ICivilopediaText)
|
CivilopediaCategories.Improvement -> ruleset.tileImprovements.values
|
||||||
)
|
CivilopediaCategories.Unit -> ruleset.units.values
|
||||||
}
|
CivilopediaCategories.Nation -> ruleset.nations.values.filter { !it.isSpectator() }
|
||||||
|
CivilopediaCategories.Technology -> ruleset.technologies.values
|
||||||
|
CivilopediaCategories.Promotion -> ruleset.unitPromotions.values
|
||||||
|
CivilopediaCategories.Policy -> ruleset.policies.values
|
||||||
|
CivilopediaCategories.Tutorial -> tutorialController.getCivilopediaTutorials()
|
||||||
|
CivilopediaCategories.Difficulty -> ruleset.difficulties.values
|
||||||
|
CivilopediaCategories.Belief -> (ruleset.beliefs.values.asSequence() +
|
||||||
|
Belief.getCivilopediaReligionEntry(ruleset)).toList()
|
||||||
|
}
|
||||||
|
|
||||||
|
for (loopCategory in CivilopediaCategories.values()) {
|
||||||
|
if (loopCategory.hide) continue
|
||||||
|
if (hideReligionItems && loopCategory == CivilopediaCategories.Belief) continue
|
||||||
|
categoryToEntries[loopCategory] =
|
||||||
|
getCategoryIterator(loopCategory)
|
||||||
|
.filter { it.getUniquesAsObjects()?.let { uniques -> shouldBeDisplayed(uniques) } ?: true }
|
||||||
|
.map { CivilopediaEntry(
|
||||||
|
(it as INamed).name, "",
|
||||||
|
loopCategory.getImage?.invoke(it.getIconName(), imageSize),
|
||||||
|
it.takeUnless { ct -> ct.isCivilopediaTextEmpty() },
|
||||||
|
sortBy = it.getSortGroup(ruleset)
|
||||||
|
) }
|
||||||
|
}
|
||||||
|
|
||||||
if (!hideReligionItems)
|
|
||||||
categoryToEntries[CivilopediaCategories.Belief] = (
|
|
||||||
ruleset.beliefs.values.asSequence()
|
|
||||||
.map {
|
|
||||||
CivilopediaEntry(
|
|
||||||
it.name,
|
|
||||||
"",
|
|
||||||
CivilopediaCategories.Belief.getImage?.invoke(it.type.name, imageSize),
|
|
||||||
(it as? ICivilopediaText).takeUnless { ct -> ct==null || ct.isCivilopediaTextEmpty() },
|
|
||||||
sortBy = it.type.ordinal
|
|
||||||
)
|
|
||||||
} + CivilopediaEntry(
|
|
||||||
"Religions",
|
|
||||||
"",
|
|
||||||
CivilopediaCategories.Belief.getImage?.invoke("Religion", imageSize),
|
|
||||||
getReligionText(),
|
|
||||||
sortBy = -1
|
|
||||||
)
|
|
||||||
).toList()
|
|
||||||
|
|
||||||
val buttonTable = Table()
|
val buttonTable = Table()
|
||||||
buttonTable.pad(15f)
|
buttonTable.pad(15f)
|
||||||
buttonTable.defaults().pad(10f)
|
buttonTable.defaults().pad(10f)
|
||||||
@ -364,31 +279,6 @@ class CivilopediaScreen(
|
|||||||
selectEntry(link, noScrollAnimation = true)
|
selectEntry(link, noScrollAnimation = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getReligionText(): ICivilopediaText {
|
|
||||||
val lines = ArrayList<FormattedLine>()
|
|
||||||
lines += FormattedLine("Religions", header=2, color="#e34a2b")
|
|
||||||
lines += FormattedLine(separator=true)
|
|
||||||
ruleset.religions.sortedWith(compareBy(Collator.getInstance(), { it.tr() })).forEach {
|
|
||||||
lines += FormattedLine(it, icon="Belief/$it")
|
|
||||||
}
|
|
||||||
return SimpleCivilopediaText(lines, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun shouldBeDisplayed(uniqueObjects: List<Unique>): Boolean {
|
|
||||||
val uniques = uniqueObjects.map { it.placeholderText }
|
|
||||||
val hideReligionItems = !game.gameInfo.hasReligionEnabled()
|
|
||||||
val noCulturalVictory = VictoryType.Cultural !in game.gameInfo.gameParameters.victoryTypes
|
|
||||||
|
|
||||||
return Constants.hideFromCivilopediaUnique !in uniques
|
|
||||||
&& !(hideReligionItems && Constants.hiddenWithoutReligionUnique in uniques)
|
|
||||||
&& !(uniqueObjects.filter { unique -> unique.placeholderText == "Hidden when [] Victory is disabled"}.any {
|
|
||||||
unique -> !game.gameInfo.gameParameters.victoryTypes.contains(VictoryType.valueOf(unique.params[0] ))
|
|
||||||
})
|
|
||||||
// Deprecated since 3.15.14
|
|
||||||
&& !(noCulturalVictory && "Hidden when cultural victory is disabled" in uniques)
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun resize(width: Int, height: Int) {
|
override fun resize(width: Int, height: Int) {
|
||||||
if (stage.viewport.screenWidth != width || stage.viewport.screenHeight != height) {
|
if (stage.viewport.screenWidth != width || stage.viewport.screenHeight != height) {
|
||||||
game.setScreen(CivilopediaScreen(game.worldScreen.gameInfo.ruleSet, currentCategory, currentEntry))
|
game.setScreen(CivilopediaScreen(game.worldScreen.gameInfo.ruleSet, currentCategory, currentEntry))
|
||||||
|
@ -7,6 +7,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table
|
|||||||
import com.badlogic.gdx.utils.Align
|
import com.badlogic.gdx.utils.Align
|
||||||
import com.unciv.UncivGame
|
import com.unciv.UncivGame
|
||||||
import com.unciv.models.metadata.BaseRuleset
|
import com.unciv.models.metadata.BaseRuleset
|
||||||
|
import com.unciv.models.ruleset.IHasUniques
|
||||||
import com.unciv.models.ruleset.Ruleset
|
import com.unciv.models.ruleset.Ruleset
|
||||||
import com.unciv.models.ruleset.RulesetCache
|
import com.unciv.models.ruleset.RulesetCache
|
||||||
import com.unciv.models.ruleset.Unique
|
import com.unciv.models.ruleset.Unique
|
||||||
@ -141,7 +142,7 @@ class FormattedLine (
|
|||||||
/** Padding distance per [indent] level */
|
/** Padding distance per [indent] level */
|
||||||
const val indentPad = 30f
|
const val indentPad = 30f
|
||||||
/** Where indent==1 will be, measured as icon count */
|
/** Where indent==1 will be, measured as icon count */
|
||||||
const val indentOneAtNumIcons = 3
|
const val indentOneAtNumIcons = 2
|
||||||
|
|
||||||
private var rulesetCachedInNameMap: Ruleset? = null
|
private var rulesetCachedInNameMap: Ruleset? = null
|
||||||
// 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.
|
// 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.
|
||||||
@ -378,11 +379,6 @@ object MarkupRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Storage class for interface [ICivilopediaText] for use as base class */
|
|
||||||
@Deprecated("As of 3.16.1, use ICivilopediaText directly please")
|
|
||||||
abstract class CivilopediaText : ICivilopediaText {
|
|
||||||
override var civilopediaText = listOf<FormattedLine>()
|
|
||||||
}
|
|
||||||
/** Storage class for instantiation of the simplest form containing only the lines collection */
|
/** Storage class for instantiation of the simplest form containing only the lines collection */
|
||||||
open class SimpleCivilopediaText(
|
open class SimpleCivilopediaText(
|
||||||
override var civilopediaText: List<FormattedLine>,
|
override var civilopediaText: List<FormattedLine>,
|
||||||
@ -401,7 +397,7 @@ open class SimpleCivilopediaText(
|
|||||||
/** Addon common to most ruleset game objects managing civilopedia display
|
/** Addon common to most ruleset game objects managing civilopedia display
|
||||||
*
|
*
|
||||||
* ### Usage:
|
* ### Usage:
|
||||||
* 1. Let [Ruleset] object implement this (e.g. by inheriting class [CivilopediaText] or adding var [civilopediaText] itself)
|
* 1. Let [Ruleset] object implement this (by inheriting and implementing class [ICivilopediaText])
|
||||||
* 2. Add `"civilopediaText": ["",…],` in the json for these objects
|
* 2. Add `"civilopediaText": ["",…],` in the json for these objects
|
||||||
* 3. Optionally override [getCivilopediaTextHeader] to supply a different header line
|
* 3. Optionally override [getCivilopediaTextHeader] to supply a different header line
|
||||||
* 4. Optionally override [getCivilopediaTextLines] to supply automatic stuff like tech prerequisites, uniques, etc.
|
* 4. Optionally override [getCivilopediaTextLines] to supply automatic stuff like tech prerequisites, uniques, etc.
|
||||||
@ -484,4 +480,20 @@ interface ICivilopediaText {
|
|||||||
|
|
||||||
/** Create the correct string for a Civilopedia link */
|
/** Create the correct string for a Civilopedia link */
|
||||||
fun makeLink(): String
|
fun makeLink(): String
|
||||||
|
|
||||||
|
/** This just marshals access to the uniques so they can be queried as part of the ICivilopediaText interface.
|
||||||
|
* Used exclusively by CivilopediaScreen, named to avoid JVM signature confusion
|
||||||
|
* (a getUniqueObjects exists in IHasUniques and most civilopedia objects will implement that interface)
|
||||||
|
*/
|
||||||
|
fun getUniquesAsObjects() = (this as? IHasUniques)?.uniqueObjects
|
||||||
|
|
||||||
|
/** Overrides alphabetical sorting in Civilopedia
|
||||||
|
* @param ruleset The current ruleset in case the function needs to do lookups
|
||||||
|
*/
|
||||||
|
fun getSortGroup(ruleset: Ruleset): Int = 0
|
||||||
|
|
||||||
|
/** Overrides Icon used for Civilopedia entry list (where you select the instance)
|
||||||
|
* This will still be passed to the category-specific image getter.
|
||||||
|
*/
|
||||||
|
fun getIconName() = if (this is INamed) name else ""
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import com.unciv.models.Tutorial
|
|||||||
import com.unciv.models.UncivSound
|
import com.unciv.models.UncivSound
|
||||||
import com.unciv.models.ruleset.Policy
|
import com.unciv.models.ruleset.Policy
|
||||||
import com.unciv.models.ruleset.PolicyBranch
|
import com.unciv.models.ruleset.PolicyBranch
|
||||||
|
import com.unciv.models.ruleset.Policy.PolicyBranchType
|
||||||
import com.unciv.models.translations.tr
|
import com.unciv.models.translations.tr
|
||||||
import com.unciv.ui.utils.*
|
import com.unciv.ui.utils.*
|
||||||
import com.unciv.ui.worldscreen.WorldScreen
|
import com.unciv.ui.worldscreen.WorldScreen
|
||||||
@ -110,7 +111,7 @@ class PolicyPickerScreen(val worldScreen: WorldScreen, civInfo: CivilizationInfo
|
|||||||
|| worldScreen.viewingCiv.isSpectator() // viewingCiv var points to selectedCiv in case of spectator
|
|| worldScreen.viewingCiv.isSpectator() // viewingCiv var points to selectedCiv in case of spectator
|
||||||
|| viewingCiv.isDefeated()
|
|| viewingCiv.isDefeated()
|
||||||
|| viewingCiv.policies.isAdopted(policy.name)
|
|| viewingCiv.policies.isAdopted(policy.name)
|
||||||
|| policy.name.endsWith("Complete")
|
|| policy.policyBranchType == PolicyBranchType.BranchComplete
|
||||||
|| !viewingCiv.policies.isAdoptable(policy)
|
|| !viewingCiv.policies.isAdoptable(policy)
|
||||||
|| !viewingCiv.policies.canAdoptPolicy()) {
|
|| !viewingCiv.policies.canAdoptPolicy()) {
|
||||||
rightSideButton.disable()
|
rightSideButton.disable()
|
||||||
@ -123,17 +124,8 @@ class PolicyPickerScreen(val worldScreen: WorldScreen, civInfo: CivilizationInfo
|
|||||||
game.setScreen(PolicyPickerScreen(worldScreen))
|
game.setScreen(PolicyPickerScreen(worldScreen))
|
||||||
}
|
}
|
||||||
pickedPolicy = policy
|
pickedPolicy = policy
|
||||||
val policyText = mutableListOf<String>()
|
|
||||||
policyText += policy.name
|
descriptionLabel.setText(policy.getDescription())
|
||||||
policyText += policy.uniques
|
|
||||||
|
|
||||||
if (!policy.name.endsWith("Complete")) {
|
|
||||||
if (policy.requires!!.isNotEmpty())
|
|
||||||
policyText += "Requires [" + policy.requires!!.joinToString { it.tr() } + "]"
|
|
||||||
else
|
|
||||||
policyText += "{Unlocked at} {" + policy.branch.era + "}"
|
|
||||||
}
|
|
||||||
descriptionLabel.setText(policyText.joinToString("\n") { it.tr() })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -151,7 +143,7 @@ class PolicyPickerScreen(val worldScreen: WorldScreen, civInfo: CivilizationInfo
|
|||||||
var currentColumn = 1
|
var currentColumn = 1
|
||||||
val branchTable = Table()
|
val branchTable = Table()
|
||||||
for (policy in branch.policies) {
|
for (policy in branch.policies) {
|
||||||
if (policy.name.endsWith("Complete")) continue
|
if (policy.policyBranchType == PolicyBranchType.BranchComplete) continue
|
||||||
if (policy.row > currentRow) {
|
if (policy.row > currentRow) {
|
||||||
branchTable.row().pad(2.5f)
|
branchTable.row().pad(2.5f)
|
||||||
currentRow++
|
currentRow++
|
||||||
|
@ -16,6 +16,7 @@ import com.unciv.logic.civilization.diplomacy.RelationshipLevel
|
|||||||
import com.unciv.logic.trade.TradeLogic
|
import com.unciv.logic.trade.TradeLogic
|
||||||
import com.unciv.logic.trade.TradeOffer
|
import com.unciv.logic.trade.TradeOffer
|
||||||
import com.unciv.logic.trade.TradeType
|
import com.unciv.logic.trade.TradeType
|
||||||
|
import com.unciv.models.ruleset.Era
|
||||||
import com.unciv.models.ruleset.ModOptionsConstants
|
import com.unciv.models.ruleset.ModOptionsConstants
|
||||||
import com.unciv.models.ruleset.Quest
|
import com.unciv.models.ruleset.Quest
|
||||||
import com.unciv.models.ruleset.tile.ResourceType
|
import com.unciv.models.ruleset.tile.ResourceType
|
||||||
@ -158,67 +159,38 @@ class DiplomacyScreen(val viewingCiv:CivilizationInfo):CameraStageBaseScreen() {
|
|||||||
else -> "Reach highest influence above 60 for alliance."
|
else -> "Reach highest influence above 60 for alliance."
|
||||||
}
|
}
|
||||||
diplomacyTable.add(getRelationshipTable(otherCivDiplomacyManager)).row()
|
diplomacyTable.add(getRelationshipTable(otherCivDiplomacyManager)).row()
|
||||||
if (nextLevelString != "") {
|
if (nextLevelString.isNotEmpty()) {
|
||||||
diplomacyTable.add(nextLevelString.toLabel()).row()
|
diplomacyTable.add(nextLevelString.toLabel()).row()
|
||||||
}
|
}
|
||||||
|
|
||||||
var friendBonusText = "When Friends: ".tr()
|
val eraInfo = viewingCiv.getEraObject() ?: Era.getLegacyCityStateBonusEra(viewingCiv.getEraNumber())
|
||||||
val eraInfo = viewingCiv.getEraObject()
|
|
||||||
val friendBonuses =
|
|
||||||
if (eraInfo == null) null
|
|
||||||
else eraInfo.friendBonus[otherCiv.cityStateType.name]
|
|
||||||
friendBonusText +=
|
|
||||||
if (friendBonuses != null) {
|
|
||||||
friendBonuses.joinToString(separator = ", ") { it.tr() }
|
|
||||||
} else {
|
|
||||||
// Deprecated, assume Civ V values for compatibility
|
|
||||||
val cultureBonus = if(viewingCiv.getEraNumber() in 0..1) "3" else if (viewingCiv.getEraNumber() in 2..3) "6" else "13"
|
|
||||||
val happinessBonus = if(viewingCiv.getEraNumber() in 0..1) "2" else "3"
|
|
||||||
when (otherCiv.cityStateType) {
|
|
||||||
CityStateType.Militaristic -> "Provides military units every [20] turns".tr()
|
|
||||||
CityStateType.Cultured -> ("Provides [" + cultureBonus + "] [Culture] per turn").tr()
|
|
||||||
CityStateType.Mercantile -> ("Provides [" + happinessBonus + "] Happiness").tr()
|
|
||||||
CityStateType.Maritime -> "Provides [2] [Food] [in capital]".tr()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
var friendBonusText = "{When Friends:} ".tr()
|
||||||
|
val friendBonuses = eraInfo.friendBonus[otherCiv.cityStateType.name]
|
||||||
|
friendBonusText += friendBonuses?.joinToString(separator = ", ") { it.tr() } ?: ""
|
||||||
|
|
||||||
var allyBonusText = "When Allies: "
|
var allyBonusText = "{When Allies:} ".tr()
|
||||||
val allyBonuses =
|
val allyBonuses = eraInfo.allyBonus[otherCiv.cityStateType.name]
|
||||||
if (eraInfo == null) null
|
allyBonusText += allyBonuses?.joinToString(separator = ", ") { it.tr() } ?: ""
|
||||||
else eraInfo.allyBonus[otherCiv.cityStateType.name]
|
|
||||||
if (allyBonuses != null) {
|
|
||||||
allyBonusText += allyBonuses.joinToString(separator = ", ") { it.tr() }
|
|
||||||
} else {
|
|
||||||
// Deprecated, assume Civ V values for compatibility
|
|
||||||
val cultureBonus = if(viewingCiv.getEraNumber() in 0..1) "6" else if (viewingCiv.getEraNumber() in 2..3) "12" else "26"
|
|
||||||
val happinessBonus = if(viewingCiv.getEraNumber() in 0..1) "2" else "3"
|
|
||||||
allyBonusText += when (otherCiv.cityStateType) {
|
|
||||||
CityStateType.Militaristic -> "Provides military units every [20] turns".tr()
|
|
||||||
CityStateType.Cultured -> ("Provides [" + cultureBonus + "] [Culture] per turn").tr()
|
|
||||||
CityStateType.Mercantile -> ("Provides [" + happinessBonus + "] Happiness").tr() + ", " + "Provides a unique luxury".tr()
|
|
||||||
CityStateType.Maritime -> "Provides [2] [Food] [in capital]".tr() + ", " + "Provides [1] [Food] [in all cities]".tr()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val friendBonusLabelColor: Color
|
val relationLevel = otherCivDiplomacyManager.relationshipLevel()
|
||||||
if (otherCivDiplomacyManager.relationshipLevel() >= RelationshipLevel.Friend) {
|
if (relationLevel >= RelationshipLevel.Friend) {
|
||||||
friendBonusLabelColor = Color.GREEN
|
|
||||||
// RelationshipChange = Ally -> Friend or Friend -> Favorable
|
// RelationshipChange = Ally -> Friend or Friend -> Favorable
|
||||||
val turnsToRelationshipChange = otherCivDiplomacyManager.getTurnsToRelationshipChange()
|
val turnsToRelationshipChange = otherCivDiplomacyManager.getTurnsToRelationshipChange()
|
||||||
diplomacyTable.add("Relationship changes in another [$turnsToRelationshipChange] turns".toLabel())
|
diplomacyTable.add("Relationship changes in another [$turnsToRelationshipChange] turns".toLabel())
|
||||||
.row()
|
.row()
|
||||||
} else
|
}
|
||||||
friendBonusLabelColor = Color.GRAY
|
|
||||||
|
|
||||||
|
val friendBonusLabelColor = if (relationLevel >= RelationshipLevel.Friend) Color.GREEN else Color.GRAY
|
||||||
val friendBonusLabel = friendBonusText.toLabel(friendBonusLabelColor)
|
val friendBonusLabel = friendBonusText.toLabel(friendBonusLabelColor)
|
||||||
.apply { setAlignment(Align.center) }
|
.apply { setAlignment(Align.center) }
|
||||||
diplomacyTable.add(friendBonusLabel).row()
|
diplomacyTable.add(friendBonusLabel).row()
|
||||||
val allyBonusLabelColor = if (otherCivDiplomacyManager.relationshipLevel() == RelationshipLevel.Ally) Color.GREEN else Color.GRAY
|
|
||||||
|
val allyBonusLabelColor = if (relationLevel == RelationshipLevel.Ally) Color.GREEN else Color.GRAY
|
||||||
val allyBonusLabel = allyBonusText.toLabel(allyBonusLabelColor)
|
val allyBonusLabel = allyBonusText.toLabel(allyBonusLabelColor)
|
||||||
.apply { setAlignment(Align.center) }
|
.apply { setAlignment(Align.center) }
|
||||||
diplomacyTable.add(allyBonusLabel).row()
|
diplomacyTable.add(allyBonusLabel).row()
|
||||||
|
|
||||||
return diplomacyTable
|
return diplomacyTable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table
|
|||||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
|
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
|
||||||
import com.badlogic.gdx.utils.Align
|
import com.badlogic.gdx.utils.Align
|
||||||
import com.unciv.logic.civilization.CivilizationInfo
|
import com.unciv.logic.civilization.CivilizationInfo
|
||||||
|
import com.unciv.models.ruleset.Policy
|
||||||
import com.unciv.models.ruleset.VictoryType
|
import com.unciv.models.ruleset.VictoryType
|
||||||
import com.unciv.models.translations.getPlaceholderParameters
|
import com.unciv.models.translations.getPlaceholderParameters
|
||||||
import com.unciv.models.translations.tr
|
import com.unciv.models.translations.tr
|
||||||
@ -202,11 +203,11 @@ class VictoryScreen(val worldScreen: WorldScreen) : PickerScreen() {
|
|||||||
policyVictoryColumn.add("Branches completed".toLabel()).row()
|
policyVictoryColumn.add("Branches completed".toLabel()).row()
|
||||||
policyVictoryColumn.addSeparator()
|
policyVictoryColumn.addSeparator()
|
||||||
|
|
||||||
data class civToBranchesCompleted(val civ: CivilizationInfo, val branchesCompleted: Int)
|
data class CivToBranchesCompleted(val civ: CivilizationInfo, val branchesCompleted: Int)
|
||||||
|
|
||||||
val civsToBranchesCompleted =
|
val civsToBranchesCompleted = majorCivs.map {
|
||||||
majorCivs.map { civToBranchesCompleted(it, it.policies.adoptedPolicies.count { pol -> pol.endsWith("Complete") }) }
|
CivToBranchesCompleted(it, it.policies.adoptedPolicies.count { pol -> Policy.isBranchCompleteByName(pol) })
|
||||||
.sortedByDescending { it.branchesCompleted }
|
}.sortedByDescending { it.branchesCompleted }
|
||||||
|
|
||||||
for (entry in civsToBranchesCompleted) {
|
for (entry in civsToBranchesCompleted) {
|
||||||
val civToBranchesHaveCompleted = EmpireOverviewScreen.getCivGroup(entry.civ, " - " + entry.branchesCompleted, playerCivInfo)
|
val civToBranchesHaveCompleted = EmpireOverviewScreen.getCivGroup(entry.civ, " - " + entry.branchesCompleted, playerCivInfo)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user