From a485510fafe66d486b04652c7db67298d242213b Mon Sep 17 00:00:00 2001 From: SomeTroglodyte <63000004+SomeTroglodyte@users.noreply.github.com> Date: Sat, 11 May 2024 20:36:17 +0200 Subject: [PATCH] Resource Overview: Info on unavailable strategic and unimproved by allies (#11571) * Resource Overview: Info on unavailable strategic and unimproved by allies * Update tutorial --- android/assets/jsons/Tutorials.json | 2 +- core/src/com/unciv/logic/GameInfo.kt | 17 +++++--- .../overviewscreen/ResourcesOverviewTab.kt | 42 +++++++++++++++---- 3 files changed, 46 insertions(+), 15 deletions(-) diff --git a/android/assets/jsons/Tutorials.json b/android/assets/jsons/Tutorials.json index 918db91647..572e3d5ba7 100644 --- a/android/assets/jsons/Tutorials.json +++ b/android/assets/jsons/Tutorials.json @@ -504,7 +504,7 @@ {}, {"text":"Reveal known resources on world screen","header":5,"color":"#fa0"}, {"text":"In the Resources overview, click on a resource icon to center the world screen on tiles already discovered and providing this resource."}, - {"text":"Alternatively, click on the \"Unimproved\" number to center the world screen only on owned tiles where the resource is not improved."}, + {"text":"Alternatively, click on the \"Unimproved\" number to center the world screen only on owned (by you or your allied City-states) tiles where the resource is not improved."}, {"text":"If more than one tile is available, click repeatedly on the notification to cycle through all of them."}, {}, {"text":"Show diagram line colors","header":5,"color":"#fa0"}, diff --git a/core/src/com/unciv/logic/GameInfo.kt b/core/src/com/unciv/logic/GameInfo.kt index d13214a78a..49382355cb 100644 --- a/core/src/com/unciv/logic/GameInfo.kt +++ b/core/src/com/unciv/logic/GameInfo.kt @@ -539,13 +539,20 @@ class GameInfo : IsPartOfGameInfoSerialization, HasGameInfoSerializationVersion * @see notifyExploredResources */ fun getExploredResourcesNotification( - civInfo: Civilization, + civ: Civilization, resourceName: String, maxDistance: Int = Int.MAX_VALUE, filter: (Tile) -> Boolean = { true } ): Notification? { data class CityTileAndDistance(val city: City, val tile: Tile, val distance: Int) + // Include your city-state allies' cities with your own for the purpose of showing the closest city + val relevantCities: Sequence = civ.cities.asSequence() + + civ.getKnownCivs() + .filter { it.isCityState() && it.getAllyCiv() == civ.civName } + .flatMap { it.cities } + + // All sources of the resource on the map, using a city-state's capital center tile for the CityStateOnlyResource types val exploredRevealTiles: Sequence = if (ruleset.tileResources[resourceName]!!.hasUnique(UniqueType.CityStateOnlyResource)) { // Look for matching mercantile CS centers @@ -559,15 +566,15 @@ class GameInfo : IsPartOfGameInfoSerialization, HasGameInfoSerializationVersion .filter { it.resource == resourceName } } + // Apply all filters to the above collection and sort them by distance to closest city val exploredRevealInfo = exploredRevealTiles - .filter { civInfo.hasExplored(it) } + .filter { civ.hasExplored(it) } .flatMap { tile -> - civInfo.cities.asSequence() - .map { + relevantCities + .map { city -> // build a full cross join all revealed tiles * civ's cities (should rarely surpass a few hundred) // cache distance for each pair as sort will call it ~ 2n log n times // should still be cheaper than looking up 'the' closest city per reveal tile before sorting - city -> CityTileAndDistance(city, tile, tile.aerialDistanceTo(city.getCenterTile())) } } diff --git a/core/src/com/unciv/ui/screens/overviewscreen/ResourcesOverviewTab.kt b/core/src/com/unciv/ui/screens/overviewscreen/ResourcesOverviewTab.kt index f68e35ee0c..77607cc78b 100644 --- a/core/src/com/unciv/ui/screens/overviewscreen/ResourcesOverviewTab.kt +++ b/core/src/com/unciv/ui/screens/overviewscreen/ResourcesOverviewTab.kt @@ -5,6 +5,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Label import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.utils.Align import com.unciv.UncivGame +import com.unciv.logic.city.City import com.unciv.logic.civilization.Civilization import com.unciv.logic.map.tile.Tile import com.unciv.logic.trade.TradeType @@ -76,14 +77,17 @@ class ResourcesOverviewTab( .mapNotNull { ExtraInfoOrigin.safeValueOf(it.origin) }.distinct().toList() private fun ResourceSupplyList.getLabel(resource: TileResource, origin: String): Label? { + fun isAlliedAndUnimproved(tile: Tile): Boolean { + val owner = tile.getOwner() ?: return false + if (owner != viewingPlayer && !(owner.isCityState() && owner.getAllyCiv() == viewingPlayer.civName)) return false + return tile.countAsUnimproved() + } val amount = get(resource, origin)?.amount ?: return null val label = if (resource.isStockpiled() && amount > 0) "+$amount".toLabel() else amount.toLabel() if (origin == ExtraInfoOrigin.Unimproved.name) label.onClick { overviewScreen.showOneTimeNotification( - gameInfo.getExploredResourcesNotification(viewingPlayer, resource.name) { - it.getOwner() == viewingPlayer && it.countAsUnimproved() - } + gameInfo.getExploredResourcesNotification(viewingPlayer, resource.name, filter = ::isAlliedAndUnimproved) ) } return label } @@ -244,7 +248,15 @@ class ResourcesOverviewTab( !providesResources(viewingPlayer) private fun getExtraDrilldown(): ResourceSupplyList { - val newResourceSupplyList = ResourceSupplyList() + val newResourceSupplyList = ResourceSupplyList(keepZeroAmounts = true) + + fun City.addUnimproved() { + for (tile in getTiles()) + if (tile.countAsUnimproved()) + newResourceSupplyList.add(tile.tileResource, ExtraInfoOrigin.Unimproved.name) + } + + // Show resources relevant to WTLK day and/or needing improvement for (city in viewingPlayer.cities) { if (city.demandedResource.isNotEmpty()) { val wltkResource = gameInfo.ruleset.tileResources[city.demandedResource]!! @@ -254,16 +266,28 @@ class ResourcesOverviewTab( newResourceSupplyList.add(wltkResource, ExtraInfoOrigin.DemandingWLTK.name) } } - for (tile in city.getTiles()) - if (tile.countAsUnimproved()) - newResourceSupplyList.add(tile.tileResource, ExtraInfoOrigin.Unimproved.name) + city.addUnimproved() } - for (otherCiv in viewingPlayer.getKnownCivs()) + for (otherCiv in viewingPlayer.getKnownCivs()) { + // Show resources received through trade for (trade in otherCiv.tradeRequests.filter { it.requestingCiv == viewingPlayer.civName }) - for (offer in trade.trade.theirOffers.filter{it.type == TradeType.Strategic_Resource || it.type == TradeType.Luxury_Resource}) + for (offer in trade.trade.theirOffers.filter { it.type == TradeType.Strategic_Resource || it.type == TradeType.Luxury_Resource }) newResourceSupplyList.add(gameInfo.ruleset.tileResources[offer.name]!!, ExtraInfoOrigin.TradeOffer.name, offer.amount) + // Show resources your city-state allies have left unimproved + if (!otherCiv.isCityState() || otherCiv.getAllyCiv() != viewingPlayer.civName) continue + for (city in otherCiv.cities) + city.addUnimproved() + } + + /** Show unlocked **strategic** resources even if you have no access at all */ + for (resource in viewingPlayer.gameInfo.ruleset.tileResources.values) { + if (resource.resourceType != ResourceType.Strategic) continue + if (resource.revealedBy == null || viewingPlayer.tech.isResearched(resource.revealedBy!!)) + newResourceSupplyList.add(resource, "No source", 0) + } + return newResourceSupplyList } }