diff --git a/core/src/com/unciv/logic/GameInfo.kt b/core/src/com/unciv/logic/GameInfo.kt index 3ca7883d5c..8fe590ba77 100644 --- a/core/src/com/unciv/logic/GameInfo.kt +++ b/core/src/com/unciv/logic/GameInfo.kt @@ -174,7 +174,11 @@ class GameInfo { } } - for (civInfo in civilizations) civInfo.setTransients() + for (civInfo in civilizations) { + civInfo.setTransients() + for(unit in civInfo.getCivUnits()) + unit.updateViewableTiles() // this needs to be done after all the units are assigned to their civs and all other transients are set + } for (civInfo in civilizations){ for (cityInfo in civInfo.cities) cityInfo.cityStats.update() } diff --git a/core/src/com/unciv/logic/battle/Battle.kt b/core/src/com/unciv/logic/battle/Battle.kt index 3b648a3794..aecbb1a7a4 100644 --- a/core/src/com/unciv/logic/battle/Battle.kt +++ b/core/src/com/unciv/logic/battle/Battle.kt @@ -253,5 +253,6 @@ class Battle(val gameInfo:GameInfo) { capturedUnit.civInfo.removeUnit(capturedUnit) capturedUnit.assignOwner(attacker.getCivInfo()) + capturedUnit.updateViewableTiles() } } diff --git a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt index 5911f451e5..c12b548db7 100644 --- a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt +++ b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt @@ -329,11 +329,11 @@ class CivilizationInfo { fun updateViewableTiles() { val newViewableTiles = HashSet() newViewableTiles.addAll(cities.flatMap { it.getTiles() }.flatMap { it.neighbors }) // tiles adjacent to city tiles - newViewableTiles.addAll(getCivUnits().flatMap { it.getViewableTiles()}) + newViewableTiles.addAll(getCivUnits().flatMap { it.viewableTiles}) viewableTiles = newViewableTiles // to avoid concurrent modification problems val newViewableInvisibleTiles = HashSet() - newViewableInvisibleTiles.addAll(getCivUnits().filter {it.hasUnique("Can attack submarines")}.flatMap {it.getViewableTiles()}) + newViewableInvisibleTiles.addAll(getCivUnits().filter {it.hasUnique("Can attack submarines")}.flatMap {it.viewableTiles}) viewableInvisibleUnitsTiles = newViewableInvisibleTiles // updating the viewable tiles also affects the explored tiles, obvs diff --git a/core/src/com/unciv/logic/map/MapUnit.kt b/core/src/com/unciv/logic/map/MapUnit.kt index 59826b7276..83318400a9 100644 --- a/core/src/com/unciv/logic/map/MapUnit.kt +++ b/core/src/com/unciv/logic/map/MapUnit.kt @@ -23,6 +23,11 @@ class MapUnit { @Transient lateinit var baseUnit: BaseUnit @Transient internal lateinit var currentTile :TileInfo + // This is saved per each unit because if we need to recalculate viewable tiles every time a unit moves, + // and we need to go over ALL the units, that's a lot of time spent on updating information we should already know! + // About 10% of total NextTurn performance time, at the time of this change! + @Transient var viewableTiles = listOf() + // These are for performance improvements to getMovementCostBetweenAdjacentTiles, // a major component of getDistanceToTilesWithinTurn, // which in turn is a component of getShortestPath and canReach @@ -122,7 +127,8 @@ class MapUnit { return getUniques().contains(unique) } - fun getViewableTiles(): MutableList { + // we need to map all the places that this could change: Unit changes locations, owners, gets promotion? + fun updateViewableTiles() { var visibilityRange = 2 visibilityRange += getUniques().count{it=="+1 Visibility Range"} if(hasUnique("Limited Visibility")) visibilityRange-=1 @@ -133,7 +139,9 @@ class MapUnit { visibilityRange += 1 val tile = getTile() if (tile.baseTerrain == Constants.hill && type.isLandUnit()) visibilityRange += 1 - return tile.getViewableTiles(visibilityRange, type.isWaterUnit()) + viewableTiles = tile.getViewableTiles(visibilityRange, type.isWaterUnit()) + + civInfo.updateViewableTiles() // for the civ } fun isFortified(): Boolean { @@ -450,7 +458,8 @@ class MapUnit { currentTile = tile if(tile.improvement=="Ancient ruins" && !civInfo.isBarbarianCivilization()) getAncientRuinBonus() - civInfo.updateViewableTiles() + + updateViewableTiles() } fun disband(){ diff --git a/core/src/com/unciv/logic/map/UnitMovementAlgorithms.kt b/core/src/com/unciv/logic/map/UnitMovementAlgorithms.kt index b6a7e82aa3..01894cbfc0 100644 --- a/core/src/com/unciv/logic/map/UnitMovementAlgorithms.kt +++ b/core/src/com/unciv/logic/map/UnitMovementAlgorithms.kt @@ -56,6 +56,7 @@ class UnitMovementAlgorithms(val unit:MapUnit) { for (tileToCheck in tilesToCheck) for (neighbor in tileToCheck.neighbors) { var totalDistanceToTile:Float + if (!unit.canPassThrough(neighbor)) totalDistanceToTile = unitMovement // Can't go here. // The reason that we don't just "return" is so that when calculating how to reach an enemy, @@ -67,11 +68,14 @@ class UnitMovementAlgorithms(val unit:MapUnit) { totalDistanceToTile = distanceToTiles[tileToCheck]!! + distanceBetweenTiles } - if (!distanceToTiles.containsKey(neighbor) || distanceToTiles[neighbor]!! > totalDistanceToTile) { - if (totalDistanceToTile < unitMovement) + if (!distanceToTiles.containsKey(neighbor) || distanceToTiles[neighbor]!! > totalDistanceToTile) { // this is the new best path + if (totalDistanceToTile < unitMovement) // We can still keep moving from here! updatedTiles += neighbor else totalDistanceToTile = unitMovement + // In Civ V, you can always travel between adjacent tiles, even if you don't technically + // have enough movement points - it simple depletes what you have + distanceToTiles[neighbor] = totalDistanceToTile } } diff --git a/core/src/com/unciv/logic/map/UnitPromotions.kt b/core/src/com/unciv/logic/map/UnitPromotions.kt index 213a85f7ce..d42c652aeb 100644 --- a/core/src/com/unciv/logic/map/UnitPromotions.kt +++ b/core/src/com/unciv/logic/map/UnitPromotions.kt @@ -28,7 +28,7 @@ class UnitPromotions{ else promotions.add(promotionName) unit.updateUniques() - unit.civInfo.updateViewableTiles() // some promotions give the unit bonus sight + unit.updateViewableTiles() // some promotions/uniques give the unit bonus sight } fun getAvailablePromotions(): List { diff --git a/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt b/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt index 56bc071338..6ee8392775 100644 --- a/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt +++ b/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt @@ -102,6 +102,7 @@ class UnitActions { newunit.promotions.addPromotion(promotion,true) newunit.updateUniques() + newunit.updateViewableTiles() newunit.currentMovement = 0f worldScreen.shouldUpdate = true }.sound("upgrade")