mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-15 02:09:21 +07:00
Improvements fog of war (#5504)
* fog of war for improvements * fix spectator mode * unnecessary imports * getShownImprovement
This commit is contained in:
@ -153,7 +153,10 @@ class BarbarianManager {
|
|||||||
it.hasUnique("Notified of new Barbarian encampments")
|
it.hasUnique("Notified of new Barbarian encampments")
|
||||||
&& it.exploredTiles.contains(tile.position)
|
&& it.exploredTiles.contains(tile.position)
|
||||||
}
|
}
|
||||||
.forEach { it.addNotification("A new barbarian encampment has spawned!", tile.position, NotificationIcon.War) }
|
.forEach {
|
||||||
|
it.addNotification("A new barbarian encampment has spawned!", tile.position, NotificationIcon.War)
|
||||||
|
it.lastSeenImprovement[tile.position] = Constants.barbarianEncampment
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.unciv.logic.civilization
|
package com.unciv.logic.civilization
|
||||||
|
|
||||||
|
import com.unciv.UncivGame
|
||||||
import com.unciv.logic.map.TileInfo
|
import com.unciv.logic.map.TileInfo
|
||||||
import com.unciv.models.ruleset.tile.ResourceSupplyList
|
import com.unciv.models.ruleset.tile.ResourceSupplyList
|
||||||
import com.unciv.models.ruleset.unique.UniqueType
|
import com.unciv.models.ruleset.unique.UniqueType
|
||||||
@ -13,6 +14,7 @@ class CivInfoTransientUpdater(val civInfo: CivilizationInfo) {
|
|||||||
|
|
||||||
updateViewableInvisibleTiles()
|
updateViewableInvisibleTiles()
|
||||||
|
|
||||||
|
updateLastSeenImprovements()
|
||||||
|
|
||||||
// updating the viewable tiles also affects the explored tiles, obviously.
|
// updating the viewable tiles also affects the explored tiles, obviously.
|
||||||
// So why don't we play switcharoo with the explored tiles as well?
|
// So why don't we play switcharoo with the explored tiles as well?
|
||||||
@ -65,7 +67,7 @@ class CivInfoTransientUpdater(val civInfo: CivilizationInfo) {
|
|||||||
val newViewableTiles = HashSet<TileInfo>()
|
val newViewableTiles = HashSet<TileInfo>()
|
||||||
|
|
||||||
// while spectating all map is visible
|
// while spectating all map is visible
|
||||||
if (civInfo.isSpectator()) {
|
if (civInfo.isSpectator() || UncivGame.Current.viewEntireMapForDebug) {
|
||||||
val allTiles = civInfo.gameInfo.tileMap.values.toSet()
|
val allTiles = civInfo.gameInfo.tileMap.values.toSet()
|
||||||
civInfo.viewableTiles = allTiles
|
civInfo.viewableTiles = allTiles
|
||||||
civInfo.viewableInvisibleUnitsTiles = allTiles
|
civInfo.viewableInvisibleUnitsTiles = allTiles
|
||||||
@ -92,6 +94,18 @@ class CivInfoTransientUpdater(val civInfo: CivilizationInfo) {
|
|||||||
civInfo.viewableTiles = newViewableTiles // to avoid concurrent modification problems
|
civInfo.viewableTiles = newViewableTiles // to avoid concurrent modification problems
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun updateLastSeenImprovements() {
|
||||||
|
if (civInfo.playerType == PlayerType.AI) return // don't bother for AI, they don't really use the info anyway
|
||||||
|
|
||||||
|
for (tile in civInfo.viewableTiles) {
|
||||||
|
val before = civInfo.lastSeenImprovement[tile.position]
|
||||||
|
if (tile.improvement == null)
|
||||||
|
civInfo.lastSeenImprovement.remove(tile.position)
|
||||||
|
else
|
||||||
|
civInfo.lastSeenImprovement[tile.position] = tile.improvement!!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun discoverNaturalWonders() {
|
private fun discoverNaturalWonders() {
|
||||||
val newlyViewedNaturalWonders = HashSet<TileInfo>()
|
val newlyViewedNaturalWonders = HashSet<TileInfo>()
|
||||||
for (tile in civInfo.viewableTiles) {
|
for (tile in civInfo.viewableTiles) {
|
||||||
|
@ -160,6 +160,14 @@ class CivilizationInfo {
|
|||||||
var citiesCreated = 0
|
var citiesCreated = 0
|
||||||
var exploredTiles = HashSet<Vector2>()
|
var exploredTiles = HashSet<Vector2>()
|
||||||
|
|
||||||
|
// This double construction because for some reason the game wants to load a
|
||||||
|
// map<Vector2, String> as a map<String, String> causing all sorts of type problems.
|
||||||
|
// So we let the game have its map<String, String> and remap it in setTransients,
|
||||||
|
// everyone's happy. Sort of.
|
||||||
|
var lastSeenImprovementSaved = HashMap<String, String>()
|
||||||
|
@Transient
|
||||||
|
var lastSeenImprovement = HashMap<Vector2, String>()
|
||||||
|
|
||||||
// To correctly determine "game over" condition as clarified in #4707
|
// To correctly determine "game over" condition as clarified in #4707
|
||||||
// Nullable type meant to be deprecated and converted to non-nullable,
|
// Nullable type meant to be deprecated and converted to non-nullable,
|
||||||
// default false once we no longer want legacy save-game compatibility
|
// default false once we no longer want legacy save-game compatibility
|
||||||
@ -207,6 +215,7 @@ class CivilizationInfo {
|
|||||||
// Cloning it by-pointer is a horrific move, since the serialization would go over it ANYWAY and still lead to concurrency problems.
|
// Cloning it by-pointer is a horrific move, since the serialization would go over it ANYWAY and still lead to concurrency problems.
|
||||||
// Cloning it by iterating on the tilemap values may seem ridiculous, but it's a perfectly thread-safe way to go about it, unlike the other solutions.
|
// Cloning it by iterating on the tilemap values may seem ridiculous, but it's a perfectly thread-safe way to go about it, unlike the other solutions.
|
||||||
toReturn.exploredTiles.addAll(gameInfo.tileMap.values.asSequence().map { it.position }.filter { it in exploredTiles })
|
toReturn.exploredTiles.addAll(gameInfo.tileMap.values.asSequence().map { it.position }.filter { it in exploredTiles })
|
||||||
|
toReturn.lastSeenImprovementSaved.putAll(lastSeenImprovement.mapKeys { it.key.toString() })
|
||||||
toReturn.notifications.addAll(notifications)
|
toReturn.notifications.addAll(notifications)
|
||||||
toReturn.citiesCreated = citiesCreated
|
toReturn.citiesCreated = citiesCreated
|
||||||
toReturn.popupAlerts.addAll(popupAlerts)
|
toReturn.popupAlerts.addAll(popupAlerts)
|
||||||
@ -730,6 +739,8 @@ class CivilizationInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
hasLongCountDisplayUnique = hasUnique(UniqueType.MayanCalendarDisplay)
|
hasLongCountDisplayUnique = hasUnique(UniqueType.MayanCalendarDisplay)
|
||||||
|
|
||||||
|
lastSeenImprovement.putAll(lastSeenImprovementSaved.mapKeys { Vector2().fromString(it.key) })
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateSightAndResources() {
|
fun updateSightAndResources() {
|
||||||
|
@ -6,6 +6,7 @@ import com.unciv.UncivGame
|
|||||||
import com.unciv.logic.HexMath
|
import com.unciv.logic.HexMath
|
||||||
import com.unciv.logic.city.CityInfo
|
import com.unciv.logic.city.CityInfo
|
||||||
import com.unciv.logic.civilization.CivilizationInfo
|
import com.unciv.logic.civilization.CivilizationInfo
|
||||||
|
import com.unciv.logic.civilization.PlayerType
|
||||||
import com.unciv.models.ruleset.Ruleset
|
import com.unciv.models.ruleset.Ruleset
|
||||||
import com.unciv.models.ruleset.unique.UniqueType
|
import com.unciv.models.ruleset.unique.UniqueType
|
||||||
import com.unciv.models.ruleset.tile.*
|
import com.unciv.models.ruleset.tile.*
|
||||||
@ -153,6 +154,13 @@ open class TileInfo {
|
|||||||
fun getTileImprovement(): TileImprovement? = if (improvement == null) null else ruleset.tileImprovements[improvement!!]
|
fun getTileImprovement(): TileImprovement? = if (improvement == null) null else ruleset.tileImprovements[improvement!!]
|
||||||
fun getTileImprovementInProgress(): TileImprovement? = if (improvementInProgress == null) null else ruleset.tileImprovements[improvementInProgress!!]
|
fun getTileImprovementInProgress(): TileImprovement? = if (improvementInProgress == null) null else ruleset.tileImprovements[improvementInProgress!!]
|
||||||
|
|
||||||
|
fun getShownImprovement(viewingCiv: CivilizationInfo?): String? {
|
||||||
|
return if (viewingCiv == null || viewingCiv.playerType == PlayerType.AI)
|
||||||
|
improvement
|
||||||
|
else
|
||||||
|
viewingCiv.lastSeenImprovement[position]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// This is for performance - since we access the neighbors of a tile ALL THE TIME,
|
// This is for performance - since we access the neighbors of a tile ALL THE TIME,
|
||||||
// and the neighbors of a tile never change, it's much more efficient to save the list once and for all!
|
// and the neighbors of a tile never change, it's much more efficient to save the list once and for all!
|
||||||
@ -648,8 +656,9 @@ open class TileInfo {
|
|||||||
lineList += FormattedLine(naturalWonder!!, link="Terrain/$naturalWonder")
|
lineList += FormattedLine(naturalWonder!!, link="Terrain/$naturalWonder")
|
||||||
if (roadStatus !== RoadStatus.None && !isCityCenter())
|
if (roadStatus !== RoadStatus.None && !isCityCenter())
|
||||||
lineList += FormattedLine(roadStatus.name, link="Improvement/${roadStatus.name}")
|
lineList += FormattedLine(roadStatus.name, link="Improvement/${roadStatus.name}")
|
||||||
if (improvement != null)
|
val shownImprovement = getShownImprovement(viewingCiv)
|
||||||
lineList += FormattedLine(improvement!!, link="Improvement/$improvement")
|
if (shownImprovement != null)
|
||||||
|
lineList += FormattedLine(shownImprovement, link="Improvement/$shownImprovement")
|
||||||
if (improvementInProgress != null && isViewableToPlayer) {
|
if (improvementInProgress != null && isViewableToPlayer) {
|
||||||
val line = "{$improvementInProgress}" +
|
val line = "{$improvementInProgress}" +
|
||||||
if (turnsToImprovement > 0) " - $turnsToImprovement${Fonts.turn}" else " ({Under construction})"
|
if (turnsToImprovement > 0) " - $turnsToImprovement${Fonts.turn}" else " ({Under construction})"
|
||||||
|
@ -180,14 +180,15 @@ open class TileGroup(var tileInfo: TileInfo, var tileSetStrings:TileSetStrings,
|
|||||||
if (viewingCiv == null && !showEntireMap) return listOf(tileSetStrings.hexagon)
|
if (viewingCiv == null && !showEntireMap) return listOf(tileSetStrings.hexagon)
|
||||||
if (tileInfo.naturalWonder != null) return listOf(tileSetStrings.getTile(tileInfo.naturalWonder!!))
|
if (tileInfo.naturalWonder != null) return listOf(tileSetStrings.getTile(tileInfo.naturalWonder!!))
|
||||||
|
|
||||||
val shouldShowImprovement = tileInfo.improvement != null && UncivGame.Current.settings.showPixelImprovements
|
val shownImprovement = tileInfo.getShownImprovement(viewingCiv)
|
||||||
|
val shouldShowImprovement = (shownImprovement != null && UncivGame.Current.settings.showPixelImprovements)
|
||||||
|
|
||||||
val shouldShowResource = UncivGame.Current.settings.showPixelImprovements && tileInfo.resource != null &&
|
val shouldShowResource = UncivGame.Current.settings.showPixelImprovements && tileInfo.resource != null &&
|
||||||
(showEntireMap || viewingCiv == null || tileInfo.hasViewableResource(viewingCiv))
|
(showEntireMap || viewingCiv == null || tileInfo.hasViewableResource(viewingCiv))
|
||||||
|
|
||||||
var resourceAndImprovementSequence = sequenceOf<String?>()
|
var resourceAndImprovementSequence = sequenceOf<String?>()
|
||||||
if (shouldShowResource) resourceAndImprovementSequence += sequenceOf(tileInfo.resource)
|
if (shouldShowResource) resourceAndImprovementSequence += sequenceOf(tileInfo.resource)
|
||||||
if (shouldShowImprovement) resourceAndImprovementSequence += sequenceOf(tileInfo.improvement)
|
if (shouldShowImprovement) resourceAndImprovementSequence += sequenceOf(shownImprovement)
|
||||||
resourceAndImprovementSequence = resourceAndImprovementSequence.filterNotNull()
|
resourceAndImprovementSequence = resourceAndImprovementSequence.filterNotNull()
|
||||||
|
|
||||||
val terrainImages = (sequenceOf(tileInfo.baseTerrain) + tileInfo.terrainFeatures.asSequence()).filterNotNull()
|
val terrainImages = (sequenceOf(tileInfo.baseTerrain) + tileInfo.terrainFeatures.asSequence()).filterNotNull()
|
||||||
|
@ -23,7 +23,7 @@ class TileGroupIcons(val tileGroup: TileGroup) {
|
|||||||
|
|
||||||
fun update(showResourcesAndImprovements: Boolean, showTileYields: Boolean, tileIsViewable: Boolean, showMilitaryUnit: Boolean, viewingCiv: CivilizationInfo?) {
|
fun update(showResourcesAndImprovements: Boolean, showTileYields: Boolean, tileIsViewable: Boolean, showMilitaryUnit: Boolean, viewingCiv: CivilizationInfo?) {
|
||||||
updateResourceIcon(showResourcesAndImprovements)
|
updateResourceIcon(showResourcesAndImprovements)
|
||||||
updateImprovementIcon(showResourcesAndImprovements)
|
updateImprovementIcon(showResourcesAndImprovements, viewingCiv)
|
||||||
updateStartingLocationIcon(showResourcesAndImprovements)
|
updateStartingLocationIcon(showResourcesAndImprovements)
|
||||||
|
|
||||||
if (viewingCiv != null) updateYieldIcon(showTileYields, viewingCiv)
|
if (viewingCiv != null) updateYieldIcon(showTileYields, viewingCiv)
|
||||||
@ -104,12 +104,13 @@ class TileGroupIcons(val tileGroup: TileGroup) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun updateImprovementIcon(showResourcesAndImprovements: Boolean) {
|
private fun updateImprovementIcon(showResourcesAndImprovements: Boolean, viewingCiv: CivilizationInfo?) {
|
||||||
improvementIcon?.remove()
|
improvementIcon?.remove()
|
||||||
improvementIcon = null
|
improvementIcon = null
|
||||||
if (tileGroup.tileInfo.improvement == null || !showResourcesAndImprovements) return
|
val shownImprovement = tileGroup.tileInfo.getShownImprovement(viewingCiv)
|
||||||
|
if (shownImprovement == null || !showResourcesAndImprovements) return
|
||||||
|
|
||||||
val newImprovementImage = ImageGetter.getImprovementIcon(tileGroup.tileInfo.improvement!!)
|
val newImprovementImage = ImageGetter.getImprovementIcon(shownImprovement)
|
||||||
tileGroup.miscLayerGroup.addActor(newImprovementImage)
|
tileGroup.miscLayerGroup.addActor(newImprovementImage)
|
||||||
newImprovementImage.run {
|
newImprovementImage.run {
|
||||||
setSize(20f, 20f)
|
setSize(20f, 20f)
|
||||||
|
@ -21,6 +21,7 @@ import com.unciv.logic.battle.Battle
|
|||||||
import com.unciv.logic.battle.MapUnitCombatant
|
import com.unciv.logic.battle.MapUnitCombatant
|
||||||
import com.unciv.logic.city.CityInfo
|
import com.unciv.logic.city.CityInfo
|
||||||
import com.unciv.logic.civilization.CivilizationInfo
|
import com.unciv.logic.civilization.CivilizationInfo
|
||||||
|
import com.unciv.logic.civilization.PlayerType
|
||||||
import com.unciv.logic.map.*
|
import com.unciv.logic.map.*
|
||||||
import com.unciv.models.AttackableTile
|
import com.unciv.models.AttackableTile
|
||||||
import com.unciv.models.UncivSound
|
import com.unciv.models.UncivSound
|
||||||
@ -445,7 +446,8 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap
|
|||||||
for (tileGroup in allWorldTileGroups) {
|
for (tileGroup in allWorldTileGroups) {
|
||||||
tileGroup.update(viewingCiv)
|
tileGroup.update(viewingCiv)
|
||||||
|
|
||||||
if (tileGroup.tileInfo.improvement == Constants.barbarianEncampment
|
|
||||||
|
if (tileGroup.tileInfo.getShownImprovement(viewingCiv) == Constants.barbarianEncampment
|
||||||
&& tileGroup.tileInfo.position in viewingCiv.exploredTiles)
|
&& tileGroup.tileInfo.position in viewingCiv.exploredTiles)
|
||||||
tileGroup.showCircle(Color.RED)
|
tileGroup.showCircle(Color.RED)
|
||||||
|
|
||||||
@ -494,8 +496,11 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap
|
|||||||
else 0.5f
|
else 0.5f
|
||||||
for (tile in allWorldTileGroups) {
|
for (tile in allWorldTileGroups) {
|
||||||
if (tile.icons.populationIcon != null) tile.icons.populationIcon!!.color.a = fadeout
|
if (tile.icons.populationIcon != null) tile.icons.populationIcon!!.color.a = fadeout
|
||||||
if (tile.icons.improvementIcon != null && tile.tileInfo.improvement != Constants.barbarianEncampment
|
|
||||||
&& tile.tileInfo.getTileImprovement()!!.isAncientRuinsEquivalent())
|
val shownImprovement = unit.civInfo.lastSeenImprovement[tile.tileInfo.position]
|
||||||
|
if (tile.icons.improvementIcon != null
|
||||||
|
&& shownImprovement != null && shownImprovement != Constants.barbarianEncampment
|
||||||
|
&& unit.civInfo.gameInfo.ruleSet.tileImprovements[shownImprovement]!!.isAncientRuinsEquivalent())
|
||||||
tile.icons.improvementIcon!!.color.a = fadeout
|
tile.icons.improvementIcon!!.color.a = fadeout
|
||||||
if (tile.resourceImage != null) tile.resourceImage!!.color.a = fadeout
|
if (tile.resourceImage != null) tile.resourceImage!!.color.a = fadeout
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user