mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-27 05:46:43 -04:00
When pathfinding, only consider ZOC for the *current* turn since things will likely change next turn! This gives a massive performance boost by removing a possible wrong check entirely :)
This commit is contained in:
parent
dcdb0ca892
commit
86450c54eb
@ -387,16 +387,16 @@ object UnitAutomation {
|
|||||||
private fun tryHeadTowardsEnemyCity(unit: MapUnit): Boolean {
|
private fun tryHeadTowardsEnemyCity(unit: MapUnit): Boolean {
|
||||||
if (unit.civInfo.cities.isEmpty()) return false
|
if (unit.civInfo.cities.isEmpty()) return false
|
||||||
|
|
||||||
var enemyCities = unit.civInfo.gameInfo.civilizations
|
var enemyCities = unit.civInfo.gameInfo.civilizations.asSequence()
|
||||||
.filter { unit.civInfo.isAtWarWith(it) }
|
.filter { unit.civInfo.isAtWarWith(it) }
|
||||||
.flatMap { it.cities }.asSequence()
|
.flatMap { it.cities }
|
||||||
.filter { it.location in unit.civInfo.exploredTiles }
|
.filter { it.location in unit.civInfo.exploredTiles }
|
||||||
|
|
||||||
if (unit.baseUnit.isRanged()) // ranged units don't harm capturable cities, waste of a turn
|
if (unit.baseUnit.isRanged()) // ranged units don't harm capturable cities, waste of a turn
|
||||||
enemyCities = enemyCities.filterNot { it.health == 1 }
|
enemyCities = enemyCities.filterNot { it.health == 1 }
|
||||||
|
|
||||||
val closestReachableEnemyCity = enemyCities
|
val closestReachableEnemyCity = enemyCities
|
||||||
.asSequence().map { it.getCenterTile() }
|
.map { it.getCenterTile() }
|
||||||
.sortedBy { cityCenterTile ->
|
.sortedBy { cityCenterTile ->
|
||||||
// sort enemy cities by closeness to our cities, and only then choose the first reachable - checking canReach is comparatively very time-intensive!
|
// sort enemy cities by closeness to our cities, and only then choose the first reachable - checking canReach is comparatively very time-intensive!
|
||||||
unit.civInfo.cities.asSequence()
|
unit.civInfo.cities.asSequence()
|
||||||
|
@ -82,6 +82,16 @@ class UnitMovementAlgorithms(val unit:MapUnit) {
|
|||||||
return terrainCost + extraCost // no road or other movement cost reduction
|
return terrainCost + extraCost // no road or other movement cost reduction
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getTilesExertingZoneOfControl(tileInfo: TileInfo, civInfo: CivilizationInfo): Sequence<TileInfo> {
|
||||||
|
return tileInfo.neighbors.filter {
|
||||||
|
it.isCityCenter() && civInfo.isAtWarWith(it.getOwner()!!)
|
||||||
|
||
|
||||||
|
it.militaryUnit != null &&
|
||||||
|
civInfo.isAtWarWith(it.militaryUnit!!.civInfo) &&
|
||||||
|
(it.militaryUnit!!.type.isWaterUnit() || (!it.militaryUnit!!.isEmbarked() && unit.type.isLandUnit()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns whether the movement between the adjacent tiles [from] and [to] is affected by Zone of Control */
|
/** Returns whether the movement between the adjacent tiles [from] and [to] is affected by Zone of Control */
|
||||||
private fun isMovementAffectedByZoneOfControl(from: TileInfo, to: TileInfo, civInfo: CivilizationInfo): Boolean {
|
private fun isMovementAffectedByZoneOfControl(from: TileInfo, to: TileInfo, civInfo: CivilizationInfo): Boolean {
|
||||||
// Sources:
|
// Sources:
|
||||||
@ -100,22 +110,8 @@ class UnitMovementAlgorithms(val unit:MapUnit) {
|
|||||||
// these two tiles can perhaps be optimized. Using a hex-math-based "commonAdjacentTiles"
|
// these two tiles can perhaps be optimized. Using a hex-math-based "commonAdjacentTiles"
|
||||||
// function is surprisingly less efficient than the current neighbor-intersection approach.
|
// function is surprisingly less efficient than the current neighbor-intersection approach.
|
||||||
// See #4085 for more details.
|
// See #4085 for more details.
|
||||||
if (from.neighbors.none{
|
val tilesExertingZoneOfControl = getTilesExertingZoneOfControl(from, civInfo)
|
||||||
(
|
if (tilesExertingZoneOfControl.none { to.neighbors.contains(it)})
|
||||||
(
|
|
||||||
it.isCityCenter() &&
|
|
||||||
civInfo.isAtWarWith(it.getOwner()!!)
|
|
||||||
)
|
|
||||||
||
|
|
||||||
(
|
|
||||||
it.militaryUnit != null &&
|
|
||||||
civInfo.isAtWarWith(it.militaryUnit!!.civInfo) &&
|
|
||||||
(it.militaryUnit!!.type.isWaterUnit() || (!it.militaryUnit!!.isEmbarked() && unit.type.isLandUnit()))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
&&
|
|
||||||
to.neighbors.contains(it)
|
|
||||||
})
|
|
||||||
return false
|
return false
|
||||||
|
|
||||||
// Even though this is a very fast check, we perform it last. This is because very few units
|
// Even though this is a very fast check, we perform it last. This is because very few units
|
||||||
@ -203,13 +199,16 @@ class UnitMovementAlgorithms(val unit:MapUnit) {
|
|||||||
var distance = 1
|
var distance = 1
|
||||||
val newTilesToCheck = ArrayList<TileInfo>()
|
val newTilesToCheck = ArrayList<TileInfo>()
|
||||||
val distanceToDestination = HashMap<TileInfo, Float>()
|
val distanceToDestination = HashMap<TileInfo, Float>()
|
||||||
|
var considerZoneOfControl = true // only for first distance!
|
||||||
while (true) {
|
while (true) {
|
||||||
if (distance == 2) // only set this once after distance > 1
|
if (distance == 2) { // only set this once after distance > 1
|
||||||
movementThisTurn = unit.getMaxMovement().toFloat()
|
movementThisTurn = unit.getMaxMovement().toFloat()
|
||||||
|
considerZoneOfControl = false // by then units would have moved around, we don't need to consider untenable futures when it harms performance!
|
||||||
|
}
|
||||||
newTilesToCheck.clear()
|
newTilesToCheck.clear()
|
||||||
distanceToDestination.clear()
|
distanceToDestination.clear()
|
||||||
for (tileToCheck in tilesToCheck) {
|
for (tileToCheck in tilesToCheck) {
|
||||||
val distanceToTilesThisTurn = getDistanceToTilesWithinTurn(tileToCheck.position, movementThisTurn)
|
val distanceToTilesThisTurn = getDistanceToTilesWithinTurn(tileToCheck.position, movementThisTurn, considerZoneOfControl)
|
||||||
for (reachableTile in distanceToTilesThisTurn.keys) {
|
for (reachableTile in distanceToTilesThisTurn.keys) {
|
||||||
// Avoid damaging terrain on first pass
|
// Avoid damaging terrain on first pass
|
||||||
if (avoidDamagingTerrain && unit.getDamageFromTerrain(reachableTile) > 0)
|
if (avoidDamagingTerrain && unit.getDamageFromTerrain(reachableTile) > 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user