mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-28 14:24:43 -04:00
World and Natural Wonders Overview (#5297)
* World and Natural Wonders Overview * World and Natural Wonders Overview - icon * World and Natural Wonders Overview - groups and tuning * World and Natural Wonders Overview - atlas * World and Natural Wonders Overview - lint
This commit is contained in:
parent
8ef84d785e
commit
e9e0f2c55f
BIN
android/Images/OtherIcons/Wonders.png
Normal file
BIN
android/Images/OtherIcons/Wonders.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 1.0 MiB |
@ -872,6 +872,16 @@ Known and defeated ([numberOfCivs]) =
|
|||||||
Tiles =
|
Tiles =
|
||||||
Natural Wonders =
|
Natural Wonders =
|
||||||
Treasury deficit =
|
Treasury deficit =
|
||||||
|
Unknown =
|
||||||
|
Not built =
|
||||||
|
Not found =
|
||||||
|
Known =
|
||||||
|
Owned =
|
||||||
|
Near [city] =
|
||||||
|
Somewhere around [city] =
|
||||||
|
Far away =
|
||||||
|
Status =
|
||||||
|
Location =
|
||||||
|
|
||||||
# Victory
|
# Victory
|
||||||
|
|
||||||
|
@ -33,7 +33,8 @@ class EmpireOverviewScreen(private var viewingPlayer:CivilizationInfo, defaultPa
|
|||||||
Pair("Units", IconAndKey("OtherIcons/Shield", 'U')),
|
Pair("Units", IconAndKey("OtherIcons/Shield", 'U')),
|
||||||
Pair("Diplomacy", IconAndKey("OtherIcons/DiplomacyW", 'D')),
|
Pair("Diplomacy", IconAndKey("OtherIcons/DiplomacyW", 'D')),
|
||||||
Pair("Resources", IconAndKey("StatIcons/Happiness", 'R')),
|
Pair("Resources", IconAndKey("StatIcons/Happiness", 'R')),
|
||||||
Pair("Religion", IconAndKey("StatIcons/Faith", 'F'))
|
Pair("Religion", IconAndKey("StatIcons/Faith", 'F')),
|
||||||
|
Pair("Wonders", IconAndKey("OtherIcons/Wonders", 'W'))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,7 +81,7 @@ class EmpireOverviewScreen(private var viewingPlayer:CivilizationInfo, defaultPa
|
|||||||
|
|
||||||
onBackButtonClicked { game.setWorldScreen() }
|
onBackButtonClicked { game.setWorldScreen() }
|
||||||
|
|
||||||
addCategory("Cities", CityOverviewTable(viewingPlayer, this), viewingPlayer.cities.none())
|
addCategory("Cities", CityOverviewTable(viewingPlayer, this), viewingPlayer.cities.isEmpty())
|
||||||
addCategory("Stats", StatsOverviewTable(viewingPlayer, this))
|
addCategory("Stats", StatsOverviewTable(viewingPlayer, this))
|
||||||
addCategory("Trades", TradesOverviewTable(viewingPlayer, this), viewingPlayer.diplomacy.values.all { it.trades.isEmpty() })
|
addCategory("Trades", TradesOverviewTable(viewingPlayer, this), viewingPlayer.diplomacy.values.all { it.trades.isEmpty() })
|
||||||
addCategory("Units", UnitOverviewTable(viewingPlayer, this), viewingPlayer.getCivUnits().none())
|
addCategory("Units", UnitOverviewTable(viewingPlayer, this), viewingPlayer.getCivUnits().none())
|
||||||
@ -88,6 +89,7 @@ class EmpireOverviewScreen(private var viewingPlayer:CivilizationInfo, defaultPa
|
|||||||
addCategory("Resources", ResourcesOverviewTable(viewingPlayer, this), viewingPlayer.detailedCivResources.isEmpty())
|
addCategory("Resources", ResourcesOverviewTable(viewingPlayer, this), viewingPlayer.detailedCivResources.isEmpty())
|
||||||
if (viewingPlayer.gameInfo.isReligionEnabled())
|
if (viewingPlayer.gameInfo.isReligionEnabled())
|
||||||
addCategory("Religion", ReligionOverviewTable(viewingPlayer, this), viewingPlayer.gameInfo.religions.isEmpty())
|
addCategory("Religion", ReligionOverviewTable(viewingPlayer, this), viewingPlayer.gameInfo.religions.isEmpty())
|
||||||
|
addCategory("Wonders", WonderOverviewTable(viewingPlayer, this), viewingPlayer.naturalWonders.isEmpty() && viewingPlayer.cities.isEmpty())
|
||||||
|
|
||||||
val closeButton = Constants.close.toTextButton().apply {
|
val closeButton = Constants.close.toTextButton().apply {
|
||||||
setColor(0.75f, 0.1f, 0.1f, 1f)
|
setColor(0.75f, 0.1f, 0.1f, 1f)
|
||||||
|
244
core/src/com/unciv/ui/overviewscreen/WonderOverviewTable.kt
Normal file
244
core/src/com/unciv/ui/overviewscreen/WonderOverviewTable.kt
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
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.Constants
|
||||||
|
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.VictoryType
|
||||||
|
import com.unciv.models.translations.tr
|
||||||
|
import com.unciv.ui.civilopedia.CivilopediaCategories
|
||||||
|
import com.unciv.ui.civilopedia.CivilopediaScreen
|
||||||
|
import com.unciv.ui.utils.ImageGetter
|
||||||
|
import com.unciv.ui.utils.onClick
|
||||||
|
import com.unciv.ui.utils.toLabel
|
||||||
|
|
||||||
|
class WonderOverviewTable(
|
||||||
|
private val viewingPlayer: CivilizationInfo,
|
||||||
|
@Suppress("unused") private val overviewScreen: EmpireOverviewScreen
|
||||||
|
): Table() {
|
||||||
|
val gameInfo = viewingPlayer.gameInfo
|
||||||
|
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()
|
||||||
|
|
||||||
|
init {
|
||||||
|
createGrid()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun shouldBeDisplayed(wonder: Building, wonderEra: Int) = when {
|
||||||
|
Constants.hideFromCivilopediaUnique in wonder.uniques -> false
|
||||||
|
Constants.hiddenWithoutReligionUnique in wonder.uniques && hideReligionItems -> false
|
||||||
|
wonder.name in startingObsolete -> false
|
||||||
|
wonder.uniqueObjects.filter { unique ->
|
||||||
|
unique.placeholderText == "Hidden when [] Victory is disabled"
|
||||||
|
}.any { unique ->
|
||||||
|
!gameInfo.gameParameters.victoryTypes.contains(VictoryType.valueOf(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 }
|
||||||
|
.map { it.name to ruleSet.eras[ruleSet.technologies[it.requiredTech]?.era()]!! }
|
||||||
|
.toMap()
|
||||||
|
|
||||||
|
// 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()
|
||||||
|
.map { it.index to it.value.name }
|
||||||
|
.toMap()
|
||||||
|
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() }
|
||||||
|
.map { it.naturalWonder!! to it }
|
||||||
|
.toMap()
|
||||||
|
val naturalsCount = allNaturalsMap.size
|
||||||
|
|
||||||
|
// Natural Wonders sort order index to name
|
||||||
|
val naturalsIndexMap: Map<Int, String> = allNaturalsMap.keys
|
||||||
|
.sortedWith(compareBy(collator, { it.tr() }))
|
||||||
|
.withIndex()
|
||||||
|
.map { it.index to it.value }
|
||||||
|
.toMap()
|
||||||
|
|
||||||
|
// 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.knows(city.civInfo) -> WonderStatus.Known
|
||||||
|
else -> WonderStatus.Unknown
|
||||||
|
}
|
||||||
|
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() {
|
||||||
|
defaults().pad(10f).align(Align.center)
|
||||||
|
add()
|
||||||
|
add("Name".toLabel())
|
||||||
|
add("Status".toLabel())
|
||||||
|
add("Location".toLabel())
|
||||||
|
add().minWidth(30f)
|
||||||
|
row()
|
||||||
|
//addSeparator()
|
||||||
|
var lastGroup = ""
|
||||||
|
|
||||||
|
for (wonder in wonders) {
|
||||||
|
if (wonder.status == WonderStatus.Hidden) continue
|
||||||
|
if (wonder.groupName != lastGroup) {
|
||||||
|
lastGroup = wonder.groupName
|
||||||
|
val groupRow = Table().apply {
|
||||||
|
add(ImageGetter.getDot(wonder.groupColor)).minHeight(2f).growX()
|
||||||
|
add(lastGroup.toLabel(wonder.groupColor).apply { setAlignment(Align.right) }).padLeft(1f).right()
|
||||||
|
}
|
||||||
|
add(groupRow).fillX().colspan(5).padBottom(0f).row()
|
||||||
|
}
|
||||||
|
|
||||||
|
val image = wonder.getImage()
|
||||||
|
image?.onClick {
|
||||||
|
UncivGame.Current.setScreen(CivilopediaScreen(ruleSet, wonder.category, wonder.name))
|
||||||
|
}
|
||||||
|
// Terrain image padding is a bit unpredictable, they need ~5f more. Ensure equal line spacing on name, not image:
|
||||||
|
add(image).pad(0f, 10f, 0f, 10f)
|
||||||
|
|
||||||
|
add(wonder.getNameColumn().toLabel()).pad(15f, 10f, 15f, 10f)
|
||||||
|
add(wonder.getStatusColumn().toLabel())
|
||||||
|
val locationText = wonder.getLocationColumn()
|
||||||
|
if (locationText.isNotEmpty()) {
|
||||||
|
val locationLabel = locationText.toLabel()
|
||||||
|
if (wonder.location != null)
|
||||||
|
locationLabel.onClick{
|
||||||
|
UncivGame.Current.setWorldScreen()
|
||||||
|
UncivGame.Current.worldScreen.mapHolder.setCenterPosition(wonder.location.position)
|
||||||
|
}
|
||||||
|
add(locationLabel).fillY()
|
||||||
|
}
|
||||||
|
row()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user