Added hasExplored function to civinfo to mask exploredTiles

This commit is contained in:
Yair Morgenstern 2022-11-28 09:22:13 +02:00
parent 166b8ff2bf
commit da5948364e
25 changed files with 81 additions and 45 deletions

View File

@ -156,7 +156,7 @@ class BarbarianManager : IsPartOfGameInfoSerialization {
private fun notifyCivsOfBarbarianEncampment(tile: TileInfo) { private fun notifyCivsOfBarbarianEncampment(tile: TileInfo) {
gameInfo.civilizations.filter { gameInfo.civilizations.filter {
it.hasUnique(UniqueType.NotifiedOfBarbarianEncampments) it.hasUnique(UniqueType.NotifiedOfBarbarianEncampments)
&& it.exploredTiles.contains(tile.position) && it.hasExplored(tile)
} }
.forEach { .forEach {
it.addNotification("A new barbarian encampment has spawned!", tile.position, NotificationIcon.War) it.addNotification("A new barbarian encampment has spawned!", tile.position, NotificationIcon.War)

View File

@ -402,7 +402,7 @@ class GameInfo : IsPartOfGameInfoSerialization, HasGameInfoSerializationVersion
} }
val exploredRevealInfo = exploredRevealTiles val exploredRevealInfo = exploredRevealTiles
.filter { it.position in civInfo.exploredTiles } .filter { civInfo.hasExplored(it.position) }
.flatMap { tile -> .flatMap { tile ->
civInfo.cities.asSequence() civInfo.cities.asSequence()
.map { .map {

View File

@ -713,7 +713,7 @@ object NextTurnAutomation {
val enemyCivs = civInfo.getKnownCivs() val enemyCivs = civInfo.getKnownCivs()
.filterNot { .filterNot {
it == civInfo || it.cities.isEmpty() || !civInfo.getDiplomacyManager(it).canDeclareWar() it == civInfo || it.cities.isEmpty() || !civInfo.getDiplomacyManager(it).canDeclareWar()
|| it.cities.none { city -> civInfo.exploredTiles.contains(city.location) } || it.cities.none { city -> civInfo.hasExplored(city.location) }
} }
// If the AI declares war on a civ without knowing the location of any cities, it'll just keep amassing an army and not sending it anywhere, // If the AI declares war on a civ without knowing the location of any cities, it'll just keep amassing an army and not sending it anywhere,
// and end up at a massive disadvantage // and end up at a massive disadvantage

View File

@ -24,7 +24,7 @@ object UnitAutomation {
private fun isGoodTileToExplore(unit: MapUnit, tile: TileInfo): Boolean { private fun isGoodTileToExplore(unit: MapUnit, tile: TileInfo): Boolean {
return unit.movement.canMoveTo(tile) return unit.movement.canMoveTo(tile)
&& (tile.getOwner() == null || !tile.getOwner()!!.isCityState()) && (tile.getOwner() == null || !tile.getOwner()!!.isCityState())
&& tile.neighbors.any { it.position !in unit.civInfo.exploredTiles } && tile.neighbors.any { !unit.civInfo.hasExplored(it) }
&& (!unit.civInfo.isCityState() || tile.neighbors.any { it.getOwner() == unit.civInfo }) // Don't want city-states exploring far outside their borders && (!unit.civInfo.isCityState() || tile.neighbors.any { it.getOwner() == unit.civInfo }) // Don't want city-states exploring far outside their borders
&& unit.getDamageFromTerrain(tile) <= 0 // Don't take unnecessary damage && unit.getDamageFromTerrain(tile) <= 0 // Don't take unnecessary damage
&& tile.getTilesInDistance(3) // don't walk in range of enemy units && tile.getTilesInDistance(3) // don't walk in range of enemy units
@ -93,7 +93,7 @@ object UnitAutomation {
return unit.movement.canMoveTo(tile) return unit.movement.canMoveTo(tile)
&& tile.getOwner() == null && tile.getOwner() == null
&& tile.neighbors.all { it.getOwner() == null } && tile.neighbors.all { it.getOwner() == null }
&& tile.position in unit.civInfo.exploredTiles && unit.civInfo.hasExplored(tile)
&& tile.getTilesInDistance(2).any { it.getOwner() == unit.civInfo } && tile.getTilesInDistance(2).any { it.getOwner() == unit.civInfo }
&& unit.getDamageFromTerrain(tile) <= 0 && unit.getDamageFromTerrain(tile) <= 0
&& unit.movement.canReach(tile) // expensive, evaluate last && unit.movement.canReach(tile) // expensive, evaluate last
@ -267,7 +267,7 @@ object UnitAutomation {
private fun tryHeadTowardsEncampment(unit: MapUnit): Boolean { private fun tryHeadTowardsEncampment(unit: MapUnit): Boolean {
if (unit.hasUnique(UniqueType.SelfDestructs)) return false // don't use single-use units against barbarians... if (unit.hasUnique(UniqueType.SelfDestructs)) return false // don't use single-use units against barbarians...
val knownEncampments = unit.civInfo.gameInfo.tileMap.values.asSequence() val knownEncampments = unit.civInfo.gameInfo.tileMap.values.asSequence()
.filter { it.improvement == Constants.barbarianEncampment && unit.civInfo.exploredTiles.contains(it.position) } .filter { it.improvement == Constants.barbarianEncampment && unit.civInfo.hasExplored(it) }
val cities = unit.civInfo.cities val cities = unit.civInfo.cities
val encampmentsCloseToCities = knownEncampments.filter { cities.any { city -> city.getCenterTile().aerialDistanceTo(it) < 6 } } val encampmentsCloseToCities = knownEncampments.filter { cities.any { city -> city.getCenterTile().aerialDistanceTo(it) < 6 } }
.sortedBy { it.aerialDistanceTo(unit.currentTile) } .sortedBy { it.aerialDistanceTo(unit.currentTile) }

View File

@ -389,10 +389,10 @@ class CityConstructions : IsPartOfGameInfoSerialization {
for (otherCiv in cityInfo.civInfo.gameInfo.civilizations) { for (otherCiv in cityInfo.civInfo.gameInfo.civilizations) {
if (otherCiv == cityInfo.civInfo) continue if (otherCiv == cityInfo.civInfo) continue
when { when {
(otherCiv.exploredTiles.contains(cityInfo.location) && otherCiv != cityInfo.civInfo) -> otherCiv.hasExplored(cityInfo.location) ->
otherCiv.addNotification("The city of [${cityInfo.name}] has started constructing [${construction.name}]!", otherCiv.addNotification("The city of [${cityInfo.name}] has started constructing [${construction.name}]!",
cityInfo.location, NotificationIcon.Construction, buildingIcon) cityInfo.location, NotificationIcon.Construction, buildingIcon)
(otherCiv.knows(cityInfo.civInfo)) -> otherCiv.knows(cityInfo.civInfo) ->
otherCiv.addNotification("[${cityInfo.civInfo.civName}] has started constructing [${construction.name}]!", otherCiv.addNotification("[${cityInfo.civInfo.civName}] has started constructing [${construction.name}]!",
NotificationIcon.Construction, buildingIcon) NotificationIcon.Construction, buildingIcon)
else -> otherCiv.addNotification("An unknown civilization has started constructing [${construction.name}]!", else -> otherCiv.addNotification("An unknown civilization has started constructing [${construction.name}]!",
@ -414,7 +414,7 @@ class CityConstructions : IsPartOfGameInfoSerialization {
if (construction is Building && construction.isWonder) { if (construction is Building && construction.isWonder) {
cityInfo.civInfo.popupAlerts.add(PopupAlert(AlertType.WonderBuilt, construction.name)) cityInfo.civInfo.popupAlerts.add(PopupAlert(AlertType.WonderBuilt, construction.name))
for (civ in cityInfo.civInfo.gameInfo.civilizations) { for (civ in cityInfo.civInfo.gameInfo.civilizations) {
if (civ.exploredTiles.contains(cityInfo.location)) if (civ.hasExplored(cityInfo.location))
civ.addNotification("[${construction.name}] has been built in [${cityInfo.name}]", civ.addNotification("[${construction.name}] has been built in [${cityInfo.name}]",
cityInfo.location, NotificationIcon.Construction, buildingIcon) cityInfo.location, NotificationIcon.Construction, buildingIcon)
else else

View File

@ -13,18 +13,15 @@ import com.unciv.logic.map.TileInfo
import com.unciv.logic.map.TileMap import com.unciv.logic.map.TileMap
import com.unciv.models.Counter import com.unciv.models.Counter
import com.unciv.models.ruleset.Nation import com.unciv.models.ruleset.Nation
import com.unciv.models.ruleset.unique.Unique
import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.ruleset.tile.ResourceSupplyList import com.unciv.models.ruleset.tile.ResourceSupplyList
import com.unciv.models.ruleset.tile.ResourceType import com.unciv.models.ruleset.tile.ResourceType
import com.unciv.models.ruleset.unique.StateForConditionals import com.unciv.models.ruleset.unique.StateForConditionals
import com.unciv.models.ruleset.unique.Unique
import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.ruleset.unit.BaseUnit import com.unciv.models.ruleset.unit.BaseUnit
import com.unciv.models.stats.Stat import com.unciv.models.stats.Stat
import com.unciv.models.stats.Stats import com.unciv.models.stats.Stats
import java.util.* import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
import kotlin.collections.HashSet
import kotlin.math.ceil import kotlin.math.ceil
import kotlin.math.min import kotlin.math.min
import kotlin.math.pow import kotlin.math.pow
@ -887,7 +884,7 @@ class CityInfo : IsPartOfGameInfoSerialization {
citiesWithin6Tiles citiesWithin6Tiles
.map { it.civInfo } .map { it.civInfo }
.distinct() .distinct()
.filter { it.knows(civInfo) && it.exploredTiles.contains(location) } .filter { it.knows(civInfo) && it.hasExplored(location) }
for (otherCiv in civsWithCloseCities) for (otherCiv in civsWithCloseCities)
otherCiv.getDiplomacyManager(civInfo).setFlag(DiplomacyFlags.SettledCitiesNearUs, 30) otherCiv.getDiplomacyManager(civInfo).setFlag(DiplomacyFlags.SettledCitiesNearUs, 30)
} }

View File

@ -121,7 +121,7 @@ class CityReligionManager : IsPartOfGameInfoSerialization {
for ((key, value) in statsGranted) for ((key, value) in statsGranted)
religionOwningCiv.addStat(key, value.toInt()) religionOwningCiv.addStat(key, value.toInt())
if (cityInfo.location in religionOwningCiv.exploredTiles) if (religionOwningCiv.hasExplored(cityInfo.location))
religionOwningCiv.addNotification( religionOwningCiv.addNotification(
"You gained [$statsGranted] as your religion was spread to [${cityInfo.name}]", "You gained [$statsGranted] as your religion was spread to [${cityInfo.name}]",
cityInfo.location, cityInfo.location,

View File

@ -23,7 +23,6 @@ class CivInfoTransientUpdater(val civInfo: CivilizationInfo) {
// and we never actually iterate on the explored tiles (only check contains()), // and we never actually iterate on the explored tiles (only check contains()),
// so there's no fear of concurrency problems. // so there's no fear of concurrency problems.
val newlyExploredTiles = civInfo.viewableTiles.asSequence().map { it.position } val newlyExploredTiles = civInfo.viewableTiles.asSequence().map { it.position }
.filterNot { civInfo.exploredTiles.contains(it) }
civInfo.exploredTiles.addAll(newlyExploredTiles) civInfo.exploredTiles.addAll(newlyExploredTiles)

View File

@ -196,6 +196,9 @@ class CivilizationInfo : IsPartOfGameInfoSerialization {
var citiesCreated = 0 var citiesCreated = 0
var exploredTiles = HashSet<Vector2>() var exploredTiles = HashSet<Vector2>()
fun hasExplored(position: Vector2) = exploredTiles.contains(position)
fun hasExplored(tileInfo: TileInfo) = hasExplored(tileInfo.position)
var lastSeenImprovement = HashMapVector2<String>() var lastSeenImprovement = HashMapVector2<String>()
// To correctly determine "game over" condition as clarified in #4707 // To correctly determine "game over" condition as clarified in #4707
@ -351,7 +354,7 @@ class CivilizationInfo : IsPartOfGameInfoSerialization {
fun isMajorCiv() = nation.isMajorCiv() fun isMajorCiv() = nation.isMajorCiv()
fun isAlive(): Boolean = !isDefeated() fun isAlive(): Boolean = !isDefeated()
fun hasMetCivTerritory(otherCiv: CivilizationInfo): Boolean = otherCiv.getCivTerritory().any { it in exploredTiles } fun hasMetCivTerritory(otherCiv: CivilizationInfo): Boolean = otherCiv.getCivTerritory().any { hasExplored(it) }
fun getCompletedPolicyBranchesCount(): Int = policies.adoptedPolicies.count { Policy.isBranchCompleteByName(it) } fun getCompletedPolicyBranchesCount(): Int = policies.adoptedPolicies.count { Policy.isBranchCompleteByName(it) }
fun originalMajorCapitalsOwned(): Int = cities.count { it.isOriginalCapital && it.foundingCiv != "" && gameInfo.getCivilization(it.foundingCiv).isMajorCiv() } fun originalMajorCapitalsOwned(): Int = cities.count { it.isOriginalCapital && it.foundingCiv != "" && gameInfo.getCivilization(it.foundingCiv).isMajorCiv() }
private fun getCivTerritory() = cities.asSequence().flatMap { it.tiles.asSequence() } private fun getCivTerritory() = cities.asSequence().flatMap { it.tiles.asSequence() }

View File

@ -153,7 +153,7 @@ class WonderInfo {
val index = wonderIndexMap[wonderName]!! val index = wonderIndexMap[wonderName]!!
val status = when { val status = when {
viewingPlayer == city.civInfo -> WonderStatus.Owned viewingPlayer == city.civInfo -> WonderStatus.Owned
viewingPlayer.exploredTiles.contains(city.location) -> WonderStatus.Known viewingPlayer.hasExplored(city.location) -> WonderStatus.Known
else -> WonderStatus.NotFound else -> WonderStatus.NotFound
} }
wonders[index] = WonderInfo( wonders[index] = WonderInfo(
@ -177,7 +177,7 @@ class WonderInfo {
else tile.getTilesInDistance(5) else tile.getTilesInDistance(5)
.filter { it.isCityCenter() } .filter { it.isCityCenter() }
.filter { viewingPlayer.knows(it.getOwner()!!) } .filter { viewingPlayer.knows(it.getOwner()!!) }
.filter { it.position in viewingPlayer.exploredTiles } .filter { viewingPlayer.hasExplored(it) }
.sortedBy { it.aerialDistanceTo(tile) } .sortedBy { it.aerialDistanceTo(tile) }
.firstOrNull()?.getCity() .firstOrNull()?.getCity()
wonders[index + wonderCount] = WonderInfo( wonders[index + wonderCount] = WonderInfo(

View File

@ -132,7 +132,7 @@ class UnitMovementAlgorithms(val unit: MapUnit) {
class ParentTileAndTotalDistance(val parentTile: TileInfo, val totalDistance: Float) class ParentTileAndTotalDistance(val parentTile: TileInfo, val totalDistance: Float)
fun isUnknownTileWeShouldAssumeToBePassable(tileInfo: TileInfo) = !unit.civInfo.exploredTiles.contains(tileInfo.position) fun isUnknownTileWeShouldAssumeToBePassable(tileInfo: TileInfo) = !unit.civInfo.hasExplored(tileInfo)
/** /**
* Does not consider if tiles can actually be entered, use canMoveTo for that. * Does not consider if tiles can actually be entered, use canMoveTo for that.
@ -154,7 +154,7 @@ class UnitMovementAlgorithms(val unit: MapUnit) {
for (neighbor in tileToCheck.neighbors) { for (neighbor in tileToCheck.neighbors) {
if (tilesToIgnore?.contains(neighbor) == true) continue // ignore this tile if (tilesToIgnore?.contains(neighbor) == true) continue // ignore this tile
var totalDistanceToTile: Float = when { var totalDistanceToTile: Float = when {
!unit.civInfo.exploredTiles.contains(neighbor.position) -> !unit.civInfo.hasExplored(neighbor) ->
distanceToTiles[tileToCheck]!!.totalDistance + 1f // If we don't know then we just guess it to be 1. distanceToTiles[tileToCheck]!!.totalDistance + 1f // If we don't know then we just guess it to be 1.
!canPassThrough(neighbor) -> unitMovement // Can't go here. !canPassThrough(neighbor) -> unitMovement // Can't go here.
// The reason that we don't just "return" is so that when calculating how to reach an enemy, // The reason that we don't just "return" is so that when calculating how to reach an enemy,

View File

@ -217,7 +217,7 @@ class Milestone(val uniqueDescription: String, private val parentVictory: Victor
val originalCapitals = civInfo.gameInfo.getCities().filter { it.isOriginalCapital } val originalCapitals = civInfo.gameInfo.getCities().filter { it.isOriginalCapital }
for (city in originalCapitals) { for (city in originalCapitals) {
val milestoneText = val milestoneText =
if (civInfo.exploredTiles.contains(city.location)) "Capture [${city.name}]" if (civInfo.hasExplored(city.location)) "Capture [${city.name}]"
else "Capture [${Constants.unknownCityName}]" else "Capture [${Constants.unknownCityName}]"
buttons.add(getMilestoneButton(milestoneText, city.civInfo == civInfo)) buttons.add(getMilestoneButton(milestoneText, city.civInfo == civInfo))
} }

View File

@ -3,12 +3,51 @@ package com.unciv.models.ruleset.unique
import com.badlogic.gdx.math.Vector2 import com.badlogic.gdx.math.Vector2
import com.unciv.Constants import com.unciv.Constants
import com.unciv.logic.city.CityInfo import com.unciv.logic.city.CityInfo
import com.unciv.logic.civilization.* import com.unciv.logic.civilization.CivFlags
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.civilization.LocationAction
import com.unciv.logic.civilization.MayaLongCountAction
import com.unciv.logic.civilization.NotificationIcon
import com.unciv.logic.civilization.ReligionState
import com.unciv.logic.map.MapUnit import com.unciv.logic.map.MapUnit
import com.unciv.logic.map.TileInfo import com.unciv.logic.map.TileInfo
import com.unciv.models.ruleset.BeliefType import com.unciv.models.ruleset.BeliefType
import com.unciv.models.ruleset.Victory import com.unciv.models.ruleset.Victory
import com.unciv.models.ruleset.unique.UniqueType.* import com.unciv.models.ruleset.unique.UniqueType.CityStateCanGiftGreatPeople
import com.unciv.models.ruleset.unique.UniqueType.ConditionalTimedUnique
import com.unciv.models.ruleset.unique.UniqueType.FoundCity
import com.unciv.models.ruleset.unique.UniqueType.FreeSpecificBuildings
import com.unciv.models.ruleset.unique.UniqueType.FreeStatBuildings
import com.unciv.models.ruleset.unique.UniqueType.MayanGainGreatPerson
import com.unciv.models.ruleset.unique.UniqueType.OneTimeAmountFreePolicies
import com.unciv.models.ruleset.unique.UniqueType.OneTimeAmountFreeTechs
import com.unciv.models.ruleset.unique.UniqueType.OneTimeAmountFreeUnits
import com.unciv.models.ruleset.unique.UniqueType.OneTimeEnterGoldenAge
import com.unciv.models.ruleset.unique.UniqueType.OneTimeFreeBelief
import com.unciv.models.ruleset.unique.UniqueType.OneTimeFreeGreatPerson
import com.unciv.models.ruleset.unique.UniqueType.OneTimeFreePolicy
import com.unciv.models.ruleset.unique.UniqueType.OneTimeFreeTech
import com.unciv.models.ruleset.unique.UniqueType.OneTimeFreeTechRuins
import com.unciv.models.ruleset.unique.UniqueType.OneTimeFreeUnit
import com.unciv.models.ruleset.unique.UniqueType.OneTimeFreeUnitRuins
import com.unciv.models.ruleset.unique.UniqueType.OneTimeGainPantheon
import com.unciv.models.ruleset.unique.UniqueType.OneTimeGainPopulation
import com.unciv.models.ruleset.unique.UniqueType.OneTimeGainPopulationRandomCity
import com.unciv.models.ruleset.unique.UniqueType.OneTimeGainProphet
import com.unciv.models.ruleset.unique.UniqueType.OneTimeGainStat
import com.unciv.models.ruleset.unique.UniqueType.OneTimeGainStatRange
import com.unciv.models.ruleset.unique.UniqueType.OneTimeGlobalSpiesWhenEnteringEra
import com.unciv.models.ruleset.unique.UniqueType.OneTimeRevealCrudeMap
import com.unciv.models.ruleset.unique.UniqueType.OneTimeRevealEntireMap
import com.unciv.models.ruleset.unique.UniqueType.OneTimeRevealSpecificMapTiles
import com.unciv.models.ruleset.unique.UniqueType.OneTimeTriggerVoting
import com.unciv.models.ruleset.unique.UniqueType.OneTimeUnitGainPromotion
import com.unciv.models.ruleset.unique.UniqueType.OneTimeUnitGainXP
import com.unciv.models.ruleset.unique.UniqueType.OneTimeUnitHeal
import com.unciv.models.ruleset.unique.UniqueType.OneTimeUnitSpecialUpgrade
import com.unciv.models.ruleset.unique.UniqueType.OneTimeUnitUpgrade
import com.unciv.models.ruleset.unique.UniqueType.StrategicResourcesIncrease
import com.unciv.models.ruleset.unique.UniqueType.UnitsGainPromotion
import com.unciv.models.stats.Stat import com.unciv.models.stats.Stat
import com.unciv.models.translations.fillPlaceholders import com.unciv.models.translations.fillPlaceholders
import com.unciv.models.translations.hasPlaceholderParameters import com.unciv.models.translations.hasPlaceholderParameters
@ -412,7 +451,7 @@ object UniqueTriggerActivation {
val nearbyRevealableTiles = tile val nearbyRevealableTiles = tile
.getTilesInDistance(unique.params[2].toInt()) .getTilesInDistance(unique.params[2].toInt())
.filter { .filter {
!civInfo.exploredTiles.contains(it.position) && !civInfo.hasExplored(it) &&
it.matchesFilter(unique.params[1]) it.matchesFilter(unique.params[1])
} }
.map { it.position } .map { it.position }
@ -446,7 +485,7 @@ object UniqueTriggerActivation {
OneTimeRevealCrudeMap -> { OneTimeRevealCrudeMap -> {
if (tile == null) return false if (tile == null) return false
val revealCenter = tile.getTilesAtDistance(unique.params[0].toInt()) val revealCenter = tile.getTilesAtDistance(unique.params[0].toInt())
.filter { it.position !in civInfo.exploredTiles } .filter { !civInfo.hasExplored(it) }
.toList() .toList()
.randomOrNull(tileBasedRandom) .randomOrNull(tileBasedRandom)
?: return false ?: return false

View File

@ -312,7 +312,7 @@ class CityScreen(
val tileSetStrings = TileSetStrings() val tileSetStrings = TileSetStrings()
val cityTileGroups = cityInfo.getCenterTile().getTilesInDistance(5) val cityTileGroups = cityInfo.getCenterTile().getTilesInDistance(5)
.filter { cityInfo.civInfo.exploredTiles.contains(it.position) } .filter { cityInfo.civInfo.hasExplored(it) }
.map { CityTileGroup(cityInfo, it, tileSetStrings) } .map { CityTileGroup(cityInfo, it, tileSetStrings) }
for (tileGroup in cityTileGroups) { for (tileGroup in cityTileGroups) {

View File

@ -16,7 +16,6 @@ import com.unciv.ui.pickerscreens.PickerScreen
import com.unciv.ui.utils.AutoScrollPane import com.unciv.ui.utils.AutoScrollPane
import com.unciv.ui.utils.Fonts import com.unciv.ui.utils.Fonts
import com.unciv.ui.utils.KeyCharAndCode import com.unciv.ui.utils.KeyCharAndCode
import com.unciv.ui.utils.extensions.addSeparator
import com.unciv.ui.utils.extensions.addSeparatorVertical import com.unciv.ui.utils.extensions.addSeparatorVertical
import com.unciv.ui.utils.extensions.keyShortcuts import com.unciv.ui.utils.extensions.keyShortcuts
import com.unciv.ui.utils.extensions.onActivation import com.unciv.ui.utils.extensions.onActivation
@ -122,7 +121,7 @@ class EspionageOverviewScreen(val civInfo: CivilizationInfo) : PickerScreen(true
// Then add all cities // Then add all cities
val sortedCities = civInfo.gameInfo.getCities() val sortedCities = civInfo.gameInfo.getCities()
.filter { it.getCenterTile().position in civInfo.exploredTiles } .filter { civInfo.hasExplored(it.location) }
.sortedWith( .sortedWith(
compareBy<CityInfo> { compareBy<CityInfo> {
it.civInfo != civInfo it.civInfo != civInfo

View File

@ -8,7 +8,6 @@ import com.badlogic.gdx.utils.Align
import com.unciv.Constants import com.unciv.Constants
import com.unciv.UncivGame import com.unciv.UncivGame
import com.unciv.logic.civilization.CivilizationInfo import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.civilization.ReligionState
import com.unciv.models.Religion import com.unciv.models.Religion
import com.unciv.models.ruleset.Belief import com.unciv.models.ruleset.Belief
import com.unciv.models.translations.fillPlaceholders import com.unciv.models.translations.fillPlaceholders
@ -146,7 +145,7 @@ class ReligionOverviewTab(
if (holyCity != null) { if (holyCity != null) {
statsTable.add("Holy City:".toLabel()) statsTable.add("Holy City:".toLabel())
val cityName = val cityName =
if (viewingPlayer.exploredTiles.contains(holyCity.getCenterTile().position)) if (viewingPlayer.hasExplored(holyCity.location))
holyCity.name holyCity.name
else Constants.unknownNationName else Constants.unknownNationName
statsTable.add(cityName.toLabel()).right().row() statsTable.add(cityName.toLabel()).right().row()

View File

@ -344,7 +344,7 @@ open class TileGroup(
|| viewingCiv.isSpectator() || viewingCiv.isSpectator()
fun isExplored(viewingCiv: CivilizationInfo) = showEntireMap fun isExplored(viewingCiv: CivilizationInfo) = showEntireMap
|| viewingCiv.exploredTiles.contains(tileInfo.position) || viewingCiv.hasExplored(tileInfo)
|| viewingCiv.isSpectator() || viewingCiv.isSpectator()
open fun update(viewingCiv: CivilizationInfo? = null, showResourcesAndImprovements: Boolean = true, showTileYields: Boolean = true) { open fun update(viewingCiv: CivilizationInfo? = null, showResourcesAndImprovements: Boolean = true, showTileYields: Boolean = true) {
@ -373,7 +373,7 @@ open class TileGroup(
for (group in allGroups) group.isVisible = true for (group in allGroups) group.isVisible = true
if (viewingCiv != null && !isExplored(viewingCiv)) { if (viewingCiv != null && !isExplored(viewingCiv)) {
if (tileInfo.neighbors.any { it.position in viewingCiv.exploredTiles }) if (tileInfo.neighbors.any { viewingCiv.hasExplored(it) })
clearUnexploredTiles() clearUnexploredTiles()
else for (group in allGroups) group.isVisible = false else for (group in allGroups) group.isVisible = false
return return

View File

@ -32,7 +32,7 @@ class WorldTileGroup(internal val worldScreen: WorldScreen, tileInfo: TileInfo,
icons.addPopulationIcon() icons.addPopulationIcon()
// update city buttons in explored tiles or entire map // update city buttons in explored tiles or entire map
if (showEntireMap if (showEntireMap
|| viewingCiv.exploredTiles.contains(tileInfo.position) || viewingCiv.hasExplored(tileInfo)
|| viewingCiv.isSpectator() || viewingCiv.isSpectator()
|| (worldScreen.viewingCiv.isSpectator() && !worldScreen.fogOfWar)) { || (worldScreen.viewingCiv.isSpectator() && !worldScreen.fogOfWar)) {
updateCityButton(city, tileIsViewable || showEntireMap) // needs to be before the update so the units will be above the city button updateCityButton(city, tileIsViewable || showEntireMap) // needs to be before the update so the units will be above the city button

View File

@ -358,7 +358,7 @@ class DiplomacyScreen(
else diplomacyTable.add(getDeclareWarButton(diplomacyManager, otherCiv)).row() else diplomacyTable.add(getDeclareWarButton(diplomacyManager, otherCiv)).row()
} }
if (otherCiv.cities.isNotEmpty() && otherCiv.getCapital() != null && otherCiv.getCapital()!!.location in viewingCiv.exploredTiles) if (otherCiv.cities.isNotEmpty() && otherCiv.getCapital() != null && viewingCiv.hasExplored(otherCiv.getCapital()!!.location))
diplomacyTable.add(getGoToOnMapButton(otherCiv)).row() diplomacyTable.add(getGoToOnMapButton(otherCiv)).row()
val diplomaticMarriageButton = getDiplomaticMarriageButton(otherCiv) val diplomaticMarriageButton = getDiplomaticMarriageButton(otherCiv)
@ -717,7 +717,7 @@ class DiplomacyScreen(
diplomacyTable.add(demandsButton).row() diplomacyTable.add(demandsButton).row()
if (isNotPlayersTurn()) demandsButton.disable() if (isNotPlayersTurn()) demandsButton.disable()
if (otherCiv.cities.isNotEmpty() && otherCiv.getCapital() != null && otherCiv.getCapital()!!.location in viewingCiv.exploredTiles) if (otherCiv.cities.isNotEmpty() && otherCiv.getCapital() != null && viewingCiv.hasExplored(otherCiv.getCapital()!!.location))
diplomacyTable.add(getGoToOnMapButton(otherCiv)).row() diplomacyTable.add(getGoToOnMapButton(otherCiv)).row()
if (!otherCiv.isPlayerCivilization()) { // human players make their own choices if (!otherCiv.isPlayerCivilization()) { // human players make their own choices

View File

@ -171,8 +171,8 @@ class WorldMapHolder(
private fun onTileClicked(tileInfo: TileInfo) { private fun onTileClicked(tileInfo: TileInfo) {
if (tileInfo.position !in worldScreen.viewingCiv.exploredTiles if (!worldScreen.viewingCiv.hasExplored(tileInfo)
&& tileInfo.neighbors.all { it.position !in worldScreen.viewingCiv.exploredTiles }) && tileInfo.neighbors.all { worldScreen.viewingCiv.hasExplored(it) })
return // This tile doesn't exist for you return // This tile doesn't exist for you
removeUnitActionOverlay() removeUnitActionOverlay()
@ -578,7 +578,7 @@ class WorldMapHolder(
if (tileGroup.tileInfo.getShownImprovement(viewingCiv) == Constants.barbarianEncampment if (tileGroup.tileInfo.getShownImprovement(viewingCiv) == Constants.barbarianEncampment
&& tileGroup.tileInfo.position in viewingCiv.exploredTiles) && viewingCiv.hasExplored(tileGroup.tileInfo))
tileGroup.showHighlight(Color.RED) tileGroup.showHighlight(Color.RED)
val unitsInTile = tileGroup.tileInfo.getUnits() val unitsInTile = tileGroup.tileInfo.getUnits()

View File

@ -821,7 +821,7 @@ class WorldScreen(
displayTutorial(TutorialTrigger.StrategicResource) { resources.any { it.resource.resourceType == ResourceType.Strategic } } displayTutorial(TutorialTrigger.StrategicResource) { resources.any { it.resource.resourceType == ResourceType.Strategic } }
displayTutorial(TutorialTrigger.EnemyCity) { displayTutorial(TutorialTrigger.EnemyCity) {
viewingCiv.getKnownCivs().asSequence().filter { viewingCiv.isAtWarWith(it) } viewingCiv.getKnownCivs().asSequence().filter { viewingCiv.isAtWarWith(it) }
.flatMap { it.cities.asSequence() }.any { viewingCiv.exploredTiles.contains(it.location) } .flatMap { it.cities.asSequence() }.any { viewingCiv.hasExplored(it.location) }
} }
displayTutorial(TutorialTrigger.ApolloProgram) { viewingCiv.hasUnique(UniqueType.EnablesConstructionOfSpaceshipParts) } displayTutorial(TutorialTrigger.ApolloProgram) { viewingCiv.hasUnique(UniqueType.EnablesConstructionOfSpaceshipParts) }
displayTutorial(TutorialTrigger.SiegeUnits) { viewingCiv.getCivUnits().any { it.baseUnit.isProbablySiegeUnit() } } displayTutorial(TutorialTrigger.SiegeUnits) { viewingCiv.getCivUnits().any { it.baseUnit.isProbablySiegeUnit() } }

View File

@ -106,7 +106,7 @@ class BattleTable(val worldScreen: WorldScreen): Table() {
else { else {
when { when {
defender.isInvisible(attackerCiv) -> attackerCiv.viewableInvisibleUnitsTiles.contains(selectedTile) defender.isInvisible(attackerCiv) -> attackerCiv.viewableInvisibleUnitsTiles.contains(selectedTile)
defender.isCity() -> attackerCiv.exploredTiles.contains(selectedTile.position) defender.isCity() -> attackerCiv.hasExplored(selectedTile)
else -> attackerCiv.viewableTiles.contains(selectedTile) else -> attackerCiv.viewableTiles.contains(selectedTile)
} }
} }

View File

@ -26,7 +26,7 @@ class TileInfoTable(private val viewingCiv :CivilizationInfo) : Table(BaseScreen
internal fun updateTileTable(tile: TileInfo?) { internal fun updateTileTable(tile: TileInfo?) {
clearChildren() clearChildren()
if (tile != null && (UncivGame.Current.viewEntireMapForDebug || viewingCiv.exploredTiles.contains(tile.position)) ) { if (tile != null && (UncivGame.Current.viewEntireMapForDebug || viewingCiv.hasExplored(tile)) ) {
add(getStatsTable(tile)) add(getStatsTable(tile))
add( MarkupRenderer.render(tile.toMarkup(viewingCiv), padding = 0f, iconDisplay = IconDisplay.None) { add( MarkupRenderer.render(tile.toMarkup(viewingCiv), padding = 0f, iconDisplay = IconDisplay.None) {
UncivGame.Current.pushScreen(CivilopediaScreen(viewingCiv.gameInfo.ruleSet, link = it)) UncivGame.Current.pushScreen(CivilopediaScreen(viewingCiv.gameInfo.ruleSet, link = it))

View File

@ -133,7 +133,7 @@ class Minimap(val mapHolder: WorldMapHolder, minimapSize: Int) : Group() {
minimapTile.owningCiv = tileInfo.getOwner() minimapTile.owningCiv = tileInfo.getOwner()
} }
val shouldBeUnrevealed = tileInfo.position !in viewingCiv.exploredTiles && !viewingCiv.isSpectator() val shouldBeUnrevealed = !viewingCiv.hasExplored(tileInfo) && !viewingCiv.isSpectator()
val revealStatusChanged = minimapTile.isUnrevealed != shouldBeUnrevealed val revealStatusChanged = minimapTile.isUnrevealed != shouldBeUnrevealed
if (revealStatusChanged || ownerChanged) { if (revealStatusChanged || ownerChanged) {
minimapTile.updateColor(shouldBeUnrevealed) minimapTile.updateColor(shouldBeUnrevealed)

View File

@ -228,7 +228,7 @@ object UnitActions {
if (diplomacyManager.hasFlag(DiplomacyFlags.AgreedToNotSettleNearUs)) { if (diplomacyManager.hasFlag(DiplomacyFlags.AgreedToNotSettleNearUs)) {
val citiesWithin6Tiles = otherCiv.cities val citiesWithin6Tiles = otherCiv.cities
.filter { it.getCenterTile().aerialDistanceTo(tile) <= 6 } .filter { it.getCenterTile().aerialDistanceTo(tile) <= 6 }
.filter { otherCiv.exploredTiles.contains(it.location) } .filter { otherCiv.hasExplored(it.location) }
if (citiesWithin6Tiles.isNotEmpty()) brokenPromises += otherCiv.getLeaderDisplayName() if (citiesWithin6Tiles.isNotEmpty()) brokenPromises += otherCiv.getLeaderDisplayName()
} }
} }