mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-09 07:18:57 +07:00
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:
BIN
android/Images/OtherIcons/Politics.png
Normal file
BIN
android/Images/OtherIcons/Politics.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
@ -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
|
||||
|
@ -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
|
||||
|
191
core/src/com/unciv/logic/civilization/WonderInfo.kt
Normal file
191
core/src/com/unciv/logic/civilization/WonderInfo.kt
Normal 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
|
||||
}
|
||||
}
|
@ -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)
|
||||
|
@ -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),
|
||||
|
@ -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)
|
||||
}
|
@ -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 {
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user