Resources UI (#6596)

* More info for Resources in Civilopedia

* Remove duplicates for Resource requirements in Civilopedia

* Resource overview link resource label to Civilopedia

* Resource overview stay if clicking can't notify (resources not existing on map)

* Resource overview display of resources produced by buildings
This commit is contained in:
SomeTroglodyte
2022-04-27 08:15:49 +02:00
committed by GitHub
parent 933e769d8e
commit 8891883998
7 changed files with 88 additions and 28 deletions

View File

@ -1159,6 +1159,8 @@ Can be found on =
Improved by [improvement] =
Bonus stats for improvement =
Buildings that consume this resource =
Buildings that provide this resource =
Improvements that provide this resource =
Buildings that require this resource worked near the city =
Units that consume this resource =
Can be built on =

View File

@ -320,8 +320,18 @@ class GameInfo {
}
}
fun notifyExploredResources(civInfo: CivilizationInfo, resourceName: String, maxDistance: Int, showForeign: Boolean) {
// Calling with `maxDistance = 0` removes distance limitation.
/** Generate a notification pointing out resources.
* Used by [addTechnology][TechManager.addTechnology] and [ResourcesOverviewTab][com.unciv.ui.overviewscreen.ResourcesOverviewTab]
* @param maxDistance from next City, 0 removes distance limitation.
* @param showForeign Disables filter to exclude foreign territory.
* @return `false` if no resources were found and no notification was added.
*/
fun notifyExploredResources(
civInfo: CivilizationInfo,
resourceName: String,
maxDistance: Int,
showForeign: Boolean
): Boolean {
data class CityTileAndDistance(val city: CityInfo, val tile: TileInfo, val distance: Int)
val exploredRevealTiles: Sequence<TileInfo> =
@ -351,7 +361,7 @@ class GameInfo {
.sortedWith ( compareBy { it.distance } )
.distinctBy { it.tile }
val chosenCity = exploredRevealInfo.firstOrNull()?.city ?: return
val chosenCity = exploredRevealInfo.firstOrNull()?.city ?: return false
val positions = exploredRevealInfo
// re-sort to a more pleasant display order
.sortedWith(compareBy{ it.tile.aerialDistanceTo(chosenCity.getCenterTile()) })
@ -368,6 +378,7 @@ class GameInfo {
LocationAction(positions),
"ResourceIcons/$resourceName"
)
return true
}
// All cross-game data which needs to be altered (e.g. when removing or changing a name of a building/tech)

View File

@ -390,7 +390,7 @@ class CityInfo {
cityResources.add(
resource,
unique.params[0].toInt() * civInfo.getResourceModifier(resource),
"Tiles"
"Buildings+"
)
}
}

View File

@ -247,14 +247,14 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction {
if (uniques.isNotEmpty() || !stats.isEmpty() || !percentStats.isEmpty() || this.greatPersonPoints.isNotEmpty() || specialists.isNotEmpty())
textList += FormattedLine()
if (uniques.isNotEmpty()) {
if (replacementTextForUniques.isNotEmpty())
textList += FormattedLine(replacementTextForUniques)
else
uniqueObjects.forEach {
if (!it.hasFlag(UniqueFlag.HiddenToUsers))
textList += FormattedLine(it)
}
if (replacementTextForUniques.isNotEmpty()) {
textList += FormattedLine(replacementTextForUniques)
} else if (uniques.isNotEmpty()) {
for (unique in uniqueObjects.sortedBy { it.text }) {
if (unique.hasFlag(UniqueFlag.HiddenToUsers)) continue
if (unique.type == UniqueType.ConsumesResources) continue // already shown from getResourceRequirements
textList += FormattedLine(unique)
}
}
if (!stats.isEmpty()) {
@ -268,7 +268,7 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction {
}
}
for((greatPersonName, value) in greatPersonPoints) {
for ((greatPersonName, value) in greatPersonPoints) {
textList += FormattedLine(
"+$value " + "[$greatPersonName] points".tr(),
link = "Unit/$greatPersonName"
@ -296,7 +296,7 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction {
val seeAlso = ArrayList<FormattedLine>()
for (building in ruleset.buildings.values) {
if (building.replaces == name
|| building.uniqueObjects.any { unique -> unique.params.any { it ==name } })
|| building.uniqueObjects.any { unique -> unique.params.any { it == name } })
seeAlso += FormattedLine(building.name, link=building.makeLink(), indent=1)
}
seeAlso += Belief.getCivilopediaTextMatching(name, ruleset, false)

View File

@ -4,6 +4,7 @@ import com.unciv.models.ruleset.Belief
import com.unciv.models.ruleset.Ruleset
import com.unciv.models.ruleset.RulesetStatsObject
import com.unciv.models.ruleset.unique.UniqueTarget
import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.stats.Stats
import com.unciv.ui.civilopedia.FormattedLine
@ -51,6 +52,34 @@ class TileResource : RulesetStatsObject() {
textList += FormattedLine("{Bonus stats for improvement}: " + improvementStats.toString())
}
val improvementsThatProvideThis = ruleset.tileImprovements.values
.filter { improvement ->
improvement.uniqueObjects.any { unique ->
unique.type == UniqueType.ProvidesResources && unique.params[1] == name
}
}
if (improvementsThatProvideThis.isNotEmpty()) {
textList += FormattedLine()
textList += FormattedLine("{Improvements that provide this resource}:")
improvementsThatProvideThis.forEach {
textList += FormattedLine(it.name, link = it.makeLink(), indent = 1)
}
}
val buildingsThatProvideThis = ruleset.buildings.values
.filter { building ->
building.uniqueObjects.any { unique ->
unique.type == UniqueType.ProvidesResources && unique.params[1] == name
}
}
if (buildingsThatProvideThis.isNotEmpty()) {
textList += FormattedLine()
textList += FormattedLine("{Buildings that provide this resource}:")
buildingsThatProvideThis.forEach {
textList += FormattedLine(it.name, link = it.makeLink(), indent = 1)
}
}
val buildingsThatConsumeThis = ruleset.buildings.values.filter { it.getResourceRequirements().containsKey(name) }
if (buildingsThatConsumeThis.isNotEmpty()) {
textList += FormattedLine()
@ -84,7 +113,7 @@ class TileResource : RulesetStatsObject() {
return textList
}
class DepositAmount {
var sparse: Int = 1
var default: Int = 2
@ -94,7 +123,7 @@ class TileResource : RulesetStatsObject() {
}
data class ResourceSupply(val resource:TileResource,var amount:Int, val origin:String)
data class ResourceSupply(val resource:TileResource, var amount:Int, val origin:String)
class ResourceSupplyList:ArrayList<ResourceSupply>() {
fun add(resource: TileResource, amount: Int, origin: String) {

View File

@ -127,14 +127,15 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
textList += FormattedLine(stats.joinToString(", ", "{Cost}: "))
}
if (replacementTextForUniques != "") {
if (replacementTextForUniques.isNotEmpty()) {
textList += FormattedLine()
textList += FormattedLine(replacementTextForUniques)
} else if (uniques.isNotEmpty()) {
textList += FormattedLine()
uniqueObjects.sortedBy { it.text }.forEach {
if (!it.hasFlag(UniqueFlag.HiddenToUsers))
textList += FormattedLine(it)
for (unique in uniqueObjects.sortedBy { it.text }) {
if (unique.hasFlag(UniqueFlag.HiddenToUsers)) continue
if (unique.type == UniqueType.ConsumesResources) continue // already shown from getResourceRequirements
textList += FormattedLine(unique)
}
}

View File

@ -10,6 +10,8 @@ import com.unciv.models.ruleset.tile.ResourceSupplyList
import com.unciv.models.ruleset.tile.ResourceType
import com.unciv.models.ruleset.tile.TileResource
import com.unciv.models.translations.tr
import com.unciv.ui.civilopedia.CivilopediaCategories
import com.unciv.ui.civilopedia.CivilopediaScreen
import com.unciv.ui.images.ImageGetter
import com.unciv.ui.utils.*
import com.unciv.ui.utils.UncivTooltip.Companion.addTooltip
@ -71,10 +73,15 @@ class ResourcesOverviewTab(
private fun getResourceImage(name: String) =
ImageGetter.getResourceImage(name, iconSize).apply {
onClick {
viewingPlayer.gameInfo.notifyExploredResources(viewingPlayer, name, 0, true)
overviewScreen.game.setWorldScreen()
if (viewingPlayer.gameInfo.notifyExploredResources(viewingPlayer, name, 0, true))
overviewScreen.game.setWorldScreen()
}
}
private fun TileResource.getLabel() = name.toLabel().apply {
onClick {
overviewScreen.game.setScreen(CivilopediaScreen(gameInfo.ruleSet, overviewScreen, CivilopediaCategories.Resource, this@getLabel.name))
}
}
private enum class ExtraInfoOrigin(
val horizontalCaption: String,
@ -131,7 +138,7 @@ class ResourcesOverviewTab(
// One detail row per origin
for (origin in origins) {
add(origin.toLabel()).left()
add(origin.removeSuffix("+").toLabel()).left()
for (resource in resources) {
add(resourceDrilldown.getLabel(resource, origin))
}
@ -159,13 +166,16 @@ class ResourcesOverviewTab(
}
private fun updateVertical() {
val groupedOrigins = origins
.groupBy { it.removeSuffix("+") }
// First row of table has all the origin labels
fixedContent.apply {
add(turnImageV).size(iconSize)
add()
addSeparatorVertical(Color.GRAY).pad(0f)
for (origin in origins) {
add(origin.toLabel())
for (origin in groupedOrigins) {
add(origin.key.toLabel())
}
add("Total".toLabel())
addSeparatorVertical(Color.GRAY).pad(0f)
@ -180,10 +190,17 @@ class ResourcesOverviewTab(
// One detail row per resource
for (resource in resources) {
add(getResourceImage(resource.name))
add(resource.name.toLabel())
add(resource.getLabel())
addSeparatorVertical(Color.GRAY).pad(0f)
for (origin in origins) {
add(resourceDrilldown.getLabel(resource, origin))
for (groupedOrigin in groupedOrigins) {
if (groupedOrigin.value.size == 1)
add(resourceDrilldown.getLabel(resource, groupedOrigin.key))
else
add(Table().apply {
for (origin in groupedOrigin.value.withIndex())
add(resourceDrilldown.getLabel(resource, origin.value))
.padLeft(if (origin.index == 0) 0f else defaultPad)
})
}
add(resourceDrilldown.getTotalLabel(resource))
addSeparatorVertical(Color.GRAY).pad(0f)