Global politics overview screen (#7469)

* getting the data

* finished getting the data

* optimization + separator

* vrtical separators

* more functions

* made it look good

* reverted debug variables

* cleanup

* added icon

* credits

* translations

* removed redundant equalizeColumns

* removed redundant separator

* column headers

* reviews

* removed redundant function

* latest translations

* latest review

* checks 1

* removed space

* removed vars and used DiplomacyManager instead

* combined overview screens

* 2 more translations

* little cleanup and fix
This commit is contained in:
alexban011
2022-09-19 16:12:24 +03:00
committed by GitHub
parent d5134f84cd
commit d980b0d9ff
9 changed files with 385 additions and 194 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -1219,6 +1219,15 @@ Number of your cities celebrating\n'We Love The King Day' thanks\nto access to t
WLTK demand =
WLTK- =
Number of your cities\ndemanding this resource for\n'We Love The King Day' =
Show global politics =
Show diagram =
At war with [enemy] =
Friends with [civName] =
[numberOfTurns] Turns Left =
Denounced [otherCiv] =
Allied with [civName] =
Civilization Info =
Relations =
Trade request =
# Victory

View File

@ -44,6 +44,7 @@ import com.unciv.ui.utils.extensions.toPercent
import com.unciv.ui.utils.extensions.withItem
import com.unciv.ui.victoryscreen.RankingType
import java.util.*
import kotlin.collections.HashMap
import kotlin.math.max
import kotlin.math.min
import kotlin.math.roundToInt

View File

@ -0,0 +1,191 @@
package com.unciv.logic.civilization
import com.badlogic.gdx.graphics.Color
import com.unciv.UncivGame
import com.unciv.logic.city.CityInfo
import com.unciv.logic.map.TileInfo
import com.unciv.models.ruleset.Building
import com.unciv.models.ruleset.Era
import com.unciv.models.ruleset.QuestName
import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.translations.tr
import com.unciv.ui.civilopedia.CivilopediaCategories
class WonderInfo {
val gameInfo = UncivGame.Current.gameInfo!!
val viewingPlayer = gameInfo.getCurrentPlayerCivilization()
val ruleSet = gameInfo.ruleSet
private val hideReligionItems = !gameInfo.isReligionEnabled()
private val viewerEra = viewingPlayer.getEraNumber()
private val startingObsolete = ruleSet.eras[gameInfo.gameParameters.startingEra]!!.startingObsoleteWonders
enum class WonderStatus(val label: String) {
Hidden(""),
Unknown("Unknown"),
Unbuilt("Not built"),
NotFound("Not found"),
Known("Known"),
Owned("Owned")
}
class WonderInfo (
val name: String,
val category: CivilopediaCategories,
val groupName: String,
val groupColor: Color,
val status: WonderStatus,
val civ: CivilizationInfo?,
val city: CityInfo?,
val location: TileInfo?
) {
val viewEntireMapForDebug = UncivGame.Current.viewEntireMapForDebug
fun getImage() = if (status == WonderStatus.Unknown && !viewEntireMapForDebug) null
else category.getImage?.invoke(name, if (category == CivilopediaCategories.Terrain) 50f else 45f)
fun getNameColumn() = when {
viewEntireMapForDebug -> name
status == WonderStatus.Unknown -> status.label
else -> name
}
fun getStatusColumn() = when {
status != WonderStatus.Known -> status.label
civ == null -> status.label
else -> civ.civName
}
fun getLocationColumn() = when {
status <= WonderStatus.NotFound -> ""
location == null -> ""
location.isCityCenter() -> location.getCity()!!.name
location.getCity() != null -> "Near [${location.getCity()!!}]"
city != null -> "Somewhere around [$city]"
viewEntireMapForDebug -> location.position.toString()
else -> "Far away"
}
}
private fun shouldBeDisplayed(wonder: Building, wonderEra: Int) = when {
wonder.hasUnique(UniqueType.HiddenFromCivilopedia) -> false
wonder.hasUnique(UniqueType.HiddenWithoutReligion) && hideReligionItems -> false
wonder.name in startingObsolete -> false
wonder.getMatchingUniques(UniqueType.HiddenWithoutVictoryType)
.any { unique ->
!gameInfo.gameParameters.victoryTypes.contains(unique.params[0])
} -> false
else -> wonderEra <= viewerEra
}
/** Do we know about a natural wonder despite not having found it yet? */
private fun knownFromQuest(name: String): Boolean {
// No, *your* civInfo's QuestManager has no idea about your quests
for (civ in gameInfo.civilizations) {
for (quest in civ.questManager.assignedQuests) {
if (quest.assignee != viewingPlayer.civName) continue
if (quest.questName == QuestName.FindNaturalWonder.value && quest.data1 == name)
return true
}
}
return false
}
fun collectInfo(): Array<WonderInfo> {
val collator = UncivGame.Current.settings.getCollatorFromLocale()
// Maps all World Wonders by name to their era for grouping
val wonderEraMap: Map<String, Era> =
ruleSet.buildings.values.asSequence()
.filter { it.isWonder }
.associate { it.name to (ruleSet.eras[ruleSet.technologies[it.requiredTech]?.era()] ?: viewingPlayer.getEra()) }
// Maps all World Wonders by their position in sort order to their name
val allWonderMap: Map<Int, String> =
ruleSet.buildings.values.asSequence()
.filter { it.isWonder }
.sortedWith(compareBy<Building> { wonderEraMap[it.name]!!.eraNumber }.thenBy(collator) { it.name.tr() })
.withIndex()
.associate { it.index to it.value.name }
val wonderCount = allWonderMap.size
// Inverse of the above
val wonderIndexMap: Map<String, Int> = allWonderMap.map { it.value to it.key }.toMap()
// Maps all Natural Wonders on the map by name to their tile
val allNaturalsMap: Map<String, TileInfo> =
gameInfo.tileMap.values.asSequence()
.filter { it.isNaturalWonder() }
.associateBy { it.naturalWonder!! }
val naturalsCount = allNaturalsMap.size
// Natural Wonders sort order index to name
val naturalsIndexMap: Map<Int, String> = allNaturalsMap.keys
.sortedWith(compareBy(collator) { it.tr() })
.withIndex()
.associate { it.index to it.value }
// Pre-populate result with "Unknown" entries
val wonders = Array(wonderCount + naturalsCount) { index ->
if (index < wonderCount) {
val wonder = ruleSet.buildings[allWonderMap[index]!!]!!
val era = wonderEraMap[wonder.name]!!
val status = if (shouldBeDisplayed(wonder, era.eraNumber)) WonderStatus.Unbuilt else WonderStatus.Hidden
WonderInfo(
allWonderMap[index]!!, CivilopediaCategories.Wonder,
era.name, era.getColor(), status, null, null, null
)
} else {
WonderInfo(
naturalsIndexMap[index - wonderCount]!!,
CivilopediaCategories.Terrain,
"Natural Wonders",
Color.FOREST,
WonderStatus.Unknown,
null,
null,
null
)
}
}
for (city in gameInfo.getCities()) {
for (wonderName in city.cityConstructions.builtBuildings.intersect(wonderIndexMap.keys)) {
val index = wonderIndexMap[wonderName]!!
val status = when {
viewingPlayer == city.civInfo -> WonderStatus.Owned
viewingPlayer.exploredTiles.contains(city.location) -> WonderStatus.Known
else -> WonderStatus.NotFound
}
wonders[index] = WonderInfo(
wonderName, CivilopediaCategories.Wonder,
wonders[index].groupName, wonders[index].groupColor,
status, city.civInfo, city, city.getCenterTile()
)
}
}
for ((index, name) in naturalsIndexMap) {
val tile = allNaturalsMap[name]!!
val civ = tile.getOwner()
val status = when {
civ == viewingPlayer -> WonderStatus.Owned
name in viewingPlayer.naturalWonders -> WonderStatus.Known
else -> WonderStatus.NotFound
}
if (status == WonderStatus.NotFound && !knownFromQuest(name)) continue
val city = if (status == WonderStatus.NotFound) null
else tile.getTilesInDistance(5)
.filter { it.isCityCenter() }
.filter { viewingPlayer.knows(it.getOwner()!!) }
.filter { it.position in viewingPlayer.exploredTiles }
.sortedBy { it.aerialDistanceTo(tile) }
.firstOrNull()?.getCity()
wonders[index + wonderCount] = WonderInfo(
name, CivilopediaCategories.Terrain,
"Natural Wonders", Color.FOREST, status, civ, city, tile
)
}
return wonders
}
}

View File

@ -823,6 +823,7 @@ class DiplomacyManager() : IsPartOfGameInfoSerialization {
otherCivDiplomacy().setModifier(DiplomaticModifiers.DeclarationOfFriendship, 35f)
setFlag(DiplomacyFlags.DeclarationOfFriendship, 30)
otherCivDiplomacy().setFlag(DiplomacyFlags.DeclarationOfFriendship, 30)
if (otherCiv().playerType == PlayerType.Human)
otherCiv().addNotification("[${civInfo.civName}] and [$otherCivName] have signed the Declaration of Friendship!",
civInfo.civName, NotificationIcon.Diplomacy, otherCivName)

View File

@ -40,10 +40,10 @@ enum class EmpireOverviewCategories(
fun (viewingPlayer: CivilizationInfo, overviewScreen: EmpireOverviewScreen, persistedData: EmpireOverviewTabPersistableData?)
= UnitOverviewTab(viewingPlayer, overviewScreen, persistedData),
fun (viewingPlayer: CivilizationInfo) = viewingPlayer.getCivUnits().none().toState()),
Diplomacy("OtherIcons/DiplomacyW", 'D', Align.top,
Politics("OtherIcons/Politics", 'P', Align.top,
fun (viewingPlayer: CivilizationInfo, overviewScreen: EmpireOverviewScreen, persistedData: EmpireOverviewTabPersistableData?)
= DiplomacyOverviewTab(viewingPlayer, overviewScreen, persistedData),
fun (viewingPlayer: CivilizationInfo) = viewingPlayer.diplomacy.isEmpty().toState()),
= GlobalPoliticsOverviewTable(viewingPlayer, overviewScreen, persistedData),
fun (_: CivilizationInfo) = EmpireOverviewTabState.Normal),
Resources("StatIcons/Happiness", 'R', Align.topLeft,
fun (viewingPlayer: CivilizationInfo, overviewScreen: EmpireOverviewScreen, persistedData: EmpireOverviewTabPersistableData?)
= ResourcesOverviewTab(viewingPlayer, overviewScreen, persistedData),

View File

@ -6,13 +6,15 @@ import com.badlogic.gdx.scenes.scene2d.Group
import com.badlogic.gdx.scenes.scene2d.Touchable
import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
import com.badlogic.gdx.scenes.scene2d.ui.TextButton.TextButtonStyle
import com.badlogic.gdx.utils.Align
import com.unciv.Constants
import com.unciv.UncivGame
import com.unciv.logic.HexMath
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.civilization.WonderInfo
import com.unciv.logic.civilization.diplomacy.DiplomacyFlags
import com.unciv.logic.civilization.diplomacy.DiplomaticStatus
import com.unciv.logic.civilization.diplomacy.RelationshipLevel
import com.unciv.ui.images.ImageGetter
import com.unciv.ui.trade.DiplomacyScreen
import com.unciv.ui.utils.AutoScrollPane
@ -20,17 +22,19 @@ import com.unciv.ui.utils.BaseScreen
import com.unciv.ui.utils.UncivTooltip.Companion.addTooltip
import com.unciv.ui.utils.extensions.addBorder
import com.unciv.ui.utils.extensions.addSeparator
import com.unciv.ui.utils.extensions.addSeparatorVertical
import com.unciv.ui.utils.extensions.center
import com.unciv.ui.utils.extensions.onClick
import com.unciv.ui.utils.extensions.toLabel
import com.unciv.ui.utils.extensions.toTextButton
import kotlin.math.roundToInt
class DiplomacyOverviewTab (
class GlobalPoliticsOverviewTable (
viewingPlayer: CivilizationInfo,
overviewScreen: EmpireOverviewScreen,
persistedData: EmpireOverviewTabPersistableData? = null
) : EmpireOverviewTab(viewingPlayer, overviewScreen) {
class DiplomacyTabPersistableData(
var includeCityStates: Boolean = false
) : EmpireOverviewTabPersistableData() {
@ -44,19 +48,6 @@ class DiplomacyOverviewTab (
defaults().pad(5f)
background = ImageGetter.getBackground(Color.BLACK)
}
val toggleCityStatesButton: TextButton = Constants.cityStates.toTextButton().apply {
onClick {
persistableData.includeCityStates = !persistableData.includeCityStates
update()
}
}
private val civTableScroll = AutoScrollPane(civTable).apply {
setOverscroll(false, false)
}
private val floatingTable = Table().apply {
add(toggleCityStatesButton).row()
add(civTableScroll.addBorder(2f, Color.WHITE)).pad(10f)
}
// Reusable sequences for the Civilizations to display
private var undefeatedCivs = sequenceOf<CivilizationInfo>()
@ -66,14 +57,178 @@ class DiplomacyOverviewTab (
private var showDiplomacyGroup = false
private var portraitMode = false
init {
update()
updatePoliticsTable()
}
private fun updatePoliticsTable() {
clear()
getFixedContent().clear()
val diagramButton = TextButton("Show diagram", skin)
diagramButton.onClick { updateDiagram() }
add()
addSeparatorVertical(Color.GRAY)
add("Civilization Info".toLabel())
addSeparatorVertical(Color.GRAY)
add("Social policies".toLabel())
addSeparatorVertical(Color.GRAY)
add("Wonders".toLabel())
addSeparatorVertical(Color.GRAY)
add("Relations".toLabel())
add(diagramButton).pad(10f)
row()
addSeparator(Color.GRAY)
createGlobalPoliticsTable()
}
private fun createGlobalPoliticsTable() {
val civilizations = mutableListOf<CivilizationInfo>()
civilizations.add(viewingPlayer)
civilizations.addAll(viewingPlayer.getKnownCivs())
civilizations.removeAll(civilizations.filter { it.isBarbarian() || it.isCityState() || it.isSpectator() })
for (civ in civilizations) {
// civ image
add(ImageGetter.getNationIndicator(civ.nation, 100f)).pad(20f)
addSeparatorVertical(Color.GRAY)
// info about civ
add(getCivInfoTable(civ)).pad(20f)
addSeparatorVertical(Color.GRAY)
// policies
add(getPoliciesTable(civ)).pad(20f)
addSeparatorVertical(Color.GRAY)
// wonders
add(getWondersOfCivTable(civ)).pad(20f)
addSeparatorVertical(Color.GRAY)
//politics
add(getPoliticsOfCivTable(civ)).pad(20f)
if (civilizations.indexOf(civ) != civilizations.lastIndex)
addSeparator(Color.GRAY)
}
}
private fun getCivInfoTable(civ: CivilizationInfo): Table {
val civInfoTable = Table(skin)
val leaderName = civ.getLeaderDisplayName().removeSuffix(" of " + civ.civName)
civInfoTable.add(leaderName.toLabel(fontSize = 30)).row()
civInfoTable.add(civ.civName.toLabel()).row()
civInfoTable.add(civ.tech.era.name.toLabel()).row()
return civInfoTable
}
private fun getPoliciesTable(civ: CivilizationInfo): Table {
val policiesTable = Table(skin)
for (policy in civ.policies.branchCompletionMap) {
if (policy.value != 0)
policiesTable.add("${policy.key.name}: ${policy.value}".toLabel()).row()
}
return policiesTable
}
private fun getWondersOfCivTable(civ: CivilizationInfo): Table {
val wonderTable = Table(skin)
val wonderInfo = WonderInfo()
val allWorldWonders = wonderInfo.collectInfo()
for (wonder in allWorldWonders) {
if (wonder.civ?.civName == civ.civName) {
val wonderName = wonder.name.toLabel()
if (wonder.location != null) {
wonderName.onClick {
val worldScreen = UncivGame.Current.resetToWorldScreen()
worldScreen.mapHolder.setCenterPosition(wonder.location.position)
}
}
wonderTable.add(wonderName).row()
}
}
return wonderTable
}
private fun getPoliticsOfCivTable(civ: CivilizationInfo): Table {
val politicsTable = Table(skin)
// wars
for (otherCiv in civ.getKnownCivs()) {
if(civ.diplomacy[otherCiv.civName]?.hasFlag(DiplomacyFlags.DeclaredWar) == true) {
val warText = "At war with ${otherCiv.civName}".toLabel()
warText.color = Color.RED
politicsTable.add(warText).row()
}
}
politicsTable.row()
// declaration of friendships
for (otherCiv in civ.getKnownCivs()) {
if(civ.diplomacy[otherCiv.civName]?.hasFlag(DiplomacyFlags.DeclarationOfFriendship) == true) {
val friendtext = "Friends with ${otherCiv.civName} ".toLabel()
friendtext.color = Color.GREEN
val turnsLeftText = "({${civ.diplomacy[otherCiv.civName]?.getFlag(DiplomacyFlags.DeclarationOfFriendship)} Turns Left})".toLabel()
politicsTable.add(friendtext)
politicsTable.add(turnsLeftText).row()
}
}
politicsTable.row()
// denounced civs
for (otherCiv in civ.getKnownCivs()) {
if(civ.diplomacy[otherCiv.civName]?.hasFlag(DiplomacyFlags.Denunciation) == true) {
val denouncedText = "Denounced ${otherCiv.civName} ".toLabel()
denouncedText.color = Color.RED
val turnsLeftText = "({${civ.diplomacy[otherCiv.civName]?.getFlag(DiplomacyFlags.Denunciation)} Turns Left})".toLabel()
politicsTable.add(denouncedText)
politicsTable.add(turnsLeftText).row()
}
}
politicsTable.row()
//allied CS
for (cityState in gameInfo.getAliveCityStates()) {
if (cityState.diplomacy[civ.civName]?.relationshipLevel() == RelationshipLevel.Ally) {
val alliedText = "Allied with ${cityState.civName}".toLabel()
alliedText.color = Color.GREEN
politicsTable.add(alliedText).row()
}
}
return politicsTable
}
override fun getFixedContent() = fixedContent
// Refresh content and determine landscape/portrait layout
private fun update() {
private fun updateDiagram() {
val politicsButton = TextButton("Show global politics", skin).apply { onClick { updatePoliticsTable() } }
val toggleCityStatesButton: TextButton = Constants.cityStates.toTextButton().apply {
onClick {
persistableData.includeCityStates = !persistableData.includeCityStates
updateDiagram()
}
}
val civTableScroll = AutoScrollPane(civTable).apply {
setOverscroll(false, false)
}
val floatingTable = Table().apply {
add(toggleCityStatesButton).pad(10f).row()
add(politicsButton).row()
add(civTableScroll.addBorder(2f, Color.WHITE)).pad(10f)
}
relevantCivsCount = gameInfo.civilizations.count {
!it.isSpectator() && !it.isBarbarian() && (persistableData.includeCityStates || !it.isCityState())
}
@ -111,9 +266,9 @@ class DiplomacyOverviewTab (
table.add(floatingTable)
toggleCityStatesButton.style = if (persistableData.includeCityStates) {
BaseScreen.skin.get("negative", TextButtonStyle::class.java)
BaseScreen.skin.get("negative", TextButton.TextButtonStyle::class.java)
} else {
BaseScreen.skin.get("positive", TextButtonStyle::class.java)
BaseScreen.skin.get("positive", TextButton.TextButtonStyle::class.java)
}
civTableScroll.setScrollingDisabled(portraitMode, portraitMode)
}

View File

@ -1,18 +1,10 @@
package com.unciv.ui.overviewscreen
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.utils.Align
import com.unciv.UncivGame
import com.unciv.logic.city.CityInfo
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.map.TileInfo
import com.unciv.models.ruleset.Building
import com.unciv.models.ruleset.Era
import com.unciv.models.ruleset.QuestName
import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.translations.tr
import com.unciv.ui.civilopedia.CivilopediaCategories
import com.unciv.logic.civilization.WonderInfo
import com.unciv.ui.civilopedia.CivilopediaScreen
import com.unciv.ui.images.ImageGetter
import com.unciv.ui.utils.extensions.onClick
@ -24,58 +16,8 @@ class WonderOverviewTab(
) : EmpireOverviewTab(viewingPlayer, overviewScreen) {
val ruleSet = gameInfo.ruleSet
private val hideReligionItems = !gameInfo.isReligionEnabled()
private val viewerEra = viewingPlayer.getEraNumber()
private val startingObsolete = ruleSet.eras[gameInfo.gameParameters.startingEra]!!.startingObsoleteWonders
private enum class WonderStatus(val label: String) {
Hidden(""),
Unknown("Unknown"),
Unbuilt("Not built"),
NotFound("Not found"),
Known("Known"),
Owned("Owned")
}
private class WonderInfo (
val name: String,
val category: CivilopediaCategories,
val groupName: String,
val groupColor: Color,
val status: WonderStatus,
val civ: CivilizationInfo?,
val city: CityInfo?,
val location: TileInfo?
) {
val viewEntireMapForDebug = UncivGame.Current.viewEntireMapForDebug
fun getImage() = if (status == WonderStatus.Unknown && !viewEntireMapForDebug) null
else category.getImage?.invoke(name, if (category == CivilopediaCategories.Terrain) 50f else 45f)
fun getNameColumn() = when {
viewEntireMapForDebug -> name
status == WonderStatus.Unknown -> status.label
else -> name
}
fun getStatusColumn() = when {
status != WonderStatus.Known -> status.label
civ == null -> status.label
else -> civ.civName
}
fun getLocationColumn() = when {
status <= WonderStatus.NotFound -> ""
location == null -> ""
location.isCityCenter() -> location.getCity()!!.name
location.getCity() != null -> "Near [${location.getCity()!!}]"
city != null -> "Somewhere around [$city]"
viewEntireMapForDebug -> location.position.toString()
else -> "Far away"
}
}
private val wonders: Array<WonderInfo> = collectInfo()
val wonderInfo = WonderInfo()
private val wonders: Array<WonderInfo.WonderInfo> = wonderInfo.collectInfo()
private val fixedContent = Table()
override fun getFixedContent() = fixedContent
@ -101,120 +43,11 @@ class WonderOverviewTab(
equalizeColumns(fixedContent, this)
}
private fun shouldBeDisplayed(wonder: Building, wonderEra: Int) = when {
wonder.hasUnique(UniqueType.HiddenFromCivilopedia) -> false
wonder.hasUnique(UniqueType.HiddenWithoutReligion) && hideReligionItems -> false
wonder.name in startingObsolete -> false
wonder.getMatchingUniques(UniqueType.HiddenWithoutVictoryType)
.any { unique ->
!gameInfo.gameParameters.victoryTypes.contains(unique.params[0])
} -> false
else -> wonderEra <= viewerEra
}
/** Do we know about a natural wonder despite not having found it yet? */
private fun knownFromQuest(name: String): Boolean {
// No, *your* civInfo's QuestManager has no idea about your quests
for (civ in gameInfo.civilizations) {
for (quest in civ.questManager.assignedQuests) {
if (quest.assignee != viewingPlayer.civName) continue
if (quest.questName == QuestName.FindNaturalWonder.value && quest.data1 == name)
return true
}
}
return false
}
private fun collectInfo(): Array<WonderInfo> {
val collator = UncivGame.Current.settings.getCollatorFromLocale()
// Maps all World Wonders by name to their era for grouping
val wonderEraMap: Map<String, Era> =
ruleSet.buildings.values.asSequence()
.filter { it.isWonder }
.associate { it.name to (ruleSet.eras[ruleSet.technologies[it.requiredTech]?.era()] ?: viewingPlayer.getEra()) }
// Maps all World Wonders by their position in sort order to their name
val allWonderMap: Map<Int, String> =
ruleSet.buildings.values.asSequence()
.filter { it.isWonder }
.sortedWith(compareBy<Building> { wonderEraMap[it.name]!!.eraNumber }.thenBy(collator) { it.name.tr() })
.withIndex()
.associate { it.index to it.value.name }
val wonderCount = allWonderMap.size
// Inverse of the above
val wonderIndexMap: Map<String, Int> = allWonderMap.map { it.value to it.key }.toMap()
// Maps all Natural Wonders on the map by name to their tile
val allNaturalsMap: Map<String, TileInfo> =
gameInfo.tileMap.values.asSequence()
.filter { it.isNaturalWonder() }
.associateBy { it.naturalWonder!! }
val naturalsCount = allNaturalsMap.size
// Natural Wonders sort order index to name
val naturalsIndexMap: Map<Int, String> = allNaturalsMap.keys
.sortedWith(compareBy(collator) { it.tr() })
.withIndex()
.associate { it.index to it.value }
// Pre-populate result with "Unknown" entries
val wonders = Array(wonderCount + naturalsCount) { index ->
if (index < wonderCount) {
val wonder = ruleSet.buildings[allWonderMap[index]!!]!!
val era = wonderEraMap[wonder.name]!!
val status = if (shouldBeDisplayed(wonder, era.eraNumber)) WonderStatus.Unbuilt else WonderStatus.Hidden
WonderInfo(allWonderMap[index]!!, CivilopediaCategories.Wonder,
era.name, era.getColor(), status, null, null, null)
} else {
WonderInfo(naturalsIndexMap[index - wonderCount]!!, CivilopediaCategories.Terrain,
"Natural Wonders", Color.FOREST, WonderStatus.Unknown, null, null, null)
}
}
for (city in gameInfo.getCities()) {
for (wonderName in city.cityConstructions.builtBuildings.intersect(wonderIndexMap.keys)) {
val index = wonderIndexMap[wonderName]!!
val status = when {
viewingPlayer == city.civInfo -> WonderStatus.Owned
viewingPlayer.exploredTiles.contains(city.location) -> WonderStatus.Known
else -> WonderStatus.NotFound
}
wonders[index] = WonderInfo(wonderName, CivilopediaCategories.Wonder,
wonders[index].groupName, wonders[index].groupColor,
status, city.civInfo, city, city.getCenterTile())
}
}
for ((index, name) in naturalsIndexMap) {
val tile = allNaturalsMap[name]!!
val civ = tile.getOwner()
val status = when {
civ == viewingPlayer -> WonderStatus.Owned
name in viewingPlayer.naturalWonders -> WonderStatus.Known
else -> WonderStatus.NotFound
}
if (status == WonderStatus.NotFound && !knownFromQuest(name)) continue
val city = if (status == WonderStatus.NotFound) null
else tile.getTilesInDistance(5)
.filter { it.isCityCenter() }
.filter { viewingPlayer.knows(it.getOwner()!!) }
.filter { it.position in viewingPlayer.exploredTiles }
.sortedBy { it.aerialDistanceTo(tile) }
.firstOrNull()?.getCity()
wonders[index + wonderCount] = WonderInfo(name, CivilopediaCategories.Terrain,
"Natural Wonders", Color.FOREST, status, civ, city, tile)
}
return wonders
}
fun createGrid() {
var lastGroup = ""
for (wonder in wonders) {
if (wonder.status == WonderStatus.Hidden) continue
if (wonder.status == WonderInfo.WonderStatus.Hidden) continue
if (wonder.groupName != lastGroup) {
lastGroup = wonder.groupName
val groupRow = Table().apply {

View File

@ -746,6 +746,7 @@ Unless otherwise specified, all the following are from [the Noun Project](https:
- [turn right](https://thenounproject.com/icon/turn-right-1920867/) by Alice Design for Resource Overview
- [Tyrannosaurus Rex](https://thenounproject.com/icon/tyrannosaurus-rex-4130976/) by Amethyst Studio for Civilopedia Eras header
- [Timer](https://www.flaticon.com/free-icons/timer) created by Gregor Cresnar Premium - Flaticon
- [Political Science](https://www.flaticon.com/premium-icon/political-science_5403775) created by Hilmy Abiyyu A. - Flaticon
- [Question](https://thenounproject.com/icon/question-1157126/) created by Aneeque Ahmed for Question Icon
### Main menu