mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-04 07:17:50 +07:00
AI always uses great prophets if it has one & fixes them standing around in enemy land tiles (#7040)
This commit is contained in:

committed by
GitHub

parent
22c8b033c9
commit
14f85e7c33
@ -239,7 +239,11 @@ object SpecificUnitAutomation {
|
||||
}
|
||||
|
||||
fun automateImprovementPlacer(unit: MapUnit) {
|
||||
val improvementName = unit.getMatchingUniques(UniqueType.ConstructImprovementConsumingUnit).first().params[0]
|
||||
var improvementBuildingUniques = unit.getMatchingUniques(UniqueType.ConstructImprovementConsumingUnit)
|
||||
if (unit.religiousActionsUnitCanDo().all { unit.abilityUsesLeft[it] == unit.maxAbilityUses[it] })
|
||||
improvementBuildingUniques += unit.getMatchingUniques(UniqueType.CanConstructIfNoOtherActions)
|
||||
|
||||
val improvementName = improvementBuildingUniques.first().params[0]
|
||||
val improvement = unit.civInfo.gameInfo.ruleSet.tileImprovements[improvementName]
|
||||
?: return
|
||||
val relatedStat = improvement.maxByOrNull { it.value }?.key ?: Stat.Culture
|
||||
@ -293,22 +297,22 @@ object SpecificUnitAutomation {
|
||||
if (unit.religion != unit.civInfo.religionManager.religion?.name)
|
||||
return unit.destroy()
|
||||
|
||||
val cities = unit.civInfo.gameInfo.getCities().asSequence()
|
||||
val city = unit.civInfo.gameInfo.getCities().asSequence()
|
||||
.filter { it.religion.getMajorityReligion()?.name != unit.getReligionDisplayName() }
|
||||
.filterNot { it.civInfo.isAtWarWith(unit.civInfo) }
|
||||
.minByOrNull { it.getCenterTile().aerialDistanceTo(unit.currentTile) } ?: return
|
||||
|
||||
|
||||
val destination = cities.getTiles().asSequence()
|
||||
.filterNot { unit.getTile().owningCity == it.owningCity } // to prevent the ai from moving around randomly
|
||||
.filter { unit.movement.canMoveTo(it) }
|
||||
val destination = city.getTiles().asSequence()
|
||||
.filter { unit.movement.canMoveTo(it) || it == unit.getTile() }
|
||||
.sortedBy { it.aerialDistanceTo(unit.currentTile) }
|
||||
.firstOrNull { unit.movement.canReach(it) } ?: return
|
||||
|
||||
unit.movement.headTowards(destination)
|
||||
|
||||
if (unit.currentTile.owningCity?.religion?.getMajorityReligion()?.name != unit.religion)
|
||||
if (unit.civInfo.religionManager.maySpreadReligionNow(unit)) {
|
||||
doReligiousAction(unit, unit.getTile())
|
||||
}
|
||||
}
|
||||
|
||||
fun automateInquisitor(unit: MapUnit) {
|
||||
@ -326,16 +330,14 @@ object SpecificUnitAutomation {
|
||||
|
||||
if (cityToProtect != null) {
|
||||
destination = cityToProtect.getCenterTile().neighbors.asSequence()
|
||||
.filterNot { unit.getTile().owningCity == it.owningCity } // to prevent the ai from moving around randomly
|
||||
.filter { unit.movement.canMoveTo(it) }
|
||||
.filter { unit.movement.canMoveTo(it) || it == unit.getTile() }
|
||||
.sortedBy { it.aerialDistanceTo(unit.currentTile) }
|
||||
.firstOrNull { unit.movement.canReach(it) }
|
||||
}
|
||||
if (destination == null) {
|
||||
if (cityToConvert == null) return
|
||||
destination = cityToConvert.getCenterTile().neighbors.asSequence()
|
||||
.filterNot { unit.getTile().owningCity == it.owningCity } // to prevent the ai from moving around randomly
|
||||
.filter { unit.movement.canMoveTo(it) }
|
||||
.filter { unit.movement.canMoveTo(it) || it == unit.getTile() }
|
||||
.sortedBy { it.aerialDistanceTo(unit.currentTile) }
|
||||
.firstOrNull { unit.movement.canReach(it) }
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ object UnitAutomation {
|
||||
val tileWithRuinOrEncampment = unitDistanceToTiles.keys
|
||||
.firstOrNull {
|
||||
(
|
||||
(it.improvement != null && it.getTileImprovement()!!.isAncientRuinsEquivalent())
|
||||
(it.improvement != null && it.getTileImprovement()!!.isAncientRuinsEquivalent())
|
||||
|| it.improvement == Constants.barbarianEncampment
|
||||
)
|
||||
&& unit.movement.canMoveTo(it)
|
||||
@ -131,7 +131,7 @@ object UnitAutomation {
|
||||
|
||||
if (unit.isCivilian()) {
|
||||
if (tryRunAwayIfNeccessary(unit)) return
|
||||
|
||||
|
||||
if (unit.hasUnique(UniqueType.FoundCity))
|
||||
return SpecificUnitAutomation.automateSettlerActions(unit)
|
||||
|
||||
@ -167,19 +167,22 @@ object UnitAutomation {
|
||||
if (unit.hasCitadelPlacementUnique || unit.hasStrengthBonusInRadiusUnique)
|
||||
return SpecificUnitAutomation.automateGreatGeneralFallback(unit)
|
||||
|
||||
if (unit.hasUnique(UniqueType.ConstructImprovementConsumingUnit))
|
||||
return SpecificUnitAutomation.automateImprovementPlacer(unit) // includes great people plus moddable units
|
||||
|
||||
if (unit.getMatchingUniques(UniqueType.CanActionSeveralTimes).any{ it.params[0] == "Spread Religion" })
|
||||
if (unit.getMatchingUniques(UniqueType.CanActionSeveralTimes).any{ it.params[0] == "Spread Religion" }
|
||||
&& unit.civInfo.religionManager.maySpreadReligionAtAll(unit))
|
||||
return SpecificUnitAutomation.automateMissionary(unit)
|
||||
|
||||
if (unit.hasUnique(UniqueType.PreventSpreadingReligion))
|
||||
return SpecificUnitAutomation.automateInquisitor(unit)
|
||||
|
||||
if (unit.hasUnique(UniqueType.ConstructImprovementConsumingUnit)
|
||||
|| (unit.hasUnique(UniqueType.CanConstructIfNoOtherActions)
|
||||
&& unit.religiousActionsUnitCanDo().all { unit.abilityUsesLeft[it] == unit.maxAbilityUses[it] }))
|
||||
// catch great prophet for civs who can't found/enhance/spread religion
|
||||
return SpecificUnitAutomation.automateImprovementPlacer(unit) // includes great people plus moddable units
|
||||
|
||||
|
||||
// ToDo: automation of great people skills (may speed up construction, provides a science boost, etc.)
|
||||
|
||||
|
||||
return // The AI doesn't know how to handle unknown civilian units
|
||||
}
|
||||
|
||||
@ -191,7 +194,7 @@ object UnitAutomation {
|
||||
|
||||
if (unit.baseUnit.isNuclearWeapon())
|
||||
return SpecificUnitAutomation.automateNukes(unit)
|
||||
|
||||
|
||||
if (unit.hasUnique(UniqueType.SelfDestructs))
|
||||
return SpecificUnitAutomation.automateMissile(unit)
|
||||
|
||||
@ -301,7 +304,7 @@ object UnitAutomation {
|
||||
.map { it.getCenterTile() }
|
||||
.filter { unit.movement.canMoveTo(it) }
|
||||
if (emptyCities.none()) return false // Nowhere to move to heal
|
||||
|
||||
|
||||
val nextTileToMove = unitDistanceToTiles.keys
|
||||
.filter { unit.movement.canMoveTo(it) }
|
||||
.minByOrNull { tile ->
|
||||
@ -309,7 +312,7 @@ object UnitAutomation {
|
||||
city.aerialDistanceTo(tile)
|
||||
}
|
||||
} ?: return false
|
||||
|
||||
|
||||
unit.movement.moveToTile(nextTileToMove)
|
||||
return true
|
||||
}
|
||||
@ -445,7 +448,7 @@ object UnitAutomation {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
|
||||
private fun headTowardsEnemyCity(unit: MapUnit, closestReachableEnemyCity: TileInfo): Boolean {
|
||||
val unitDistanceToTiles = unit.movement.getDistanceToTiles()
|
||||
@ -491,14 +494,14 @@ object UnitAutomation {
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
fun tryEnterOwnClosestCity(unit: MapUnit): Boolean {
|
||||
val closestCity = unit.civInfo.cities
|
||||
.asSequence()
|
||||
.sortedBy { it.getCenterTile().aerialDistanceTo(unit.getTile()) }
|
||||
.firstOrNull { unit.movement.canReach(it.getCenterTile()) }
|
||||
?: return false // Panic!
|
||||
|
||||
|
||||
unit.movement.headTowards(closestCity.getCenterTile())
|
||||
return true
|
||||
}
|
||||
@ -596,7 +599,7 @@ object UnitAutomation {
|
||||
unit.civInfo.addNotification("${unit.shortDisplayName()} finished exploring.", unit.currentTile.position, unit.name, "OtherIcons/Sleep")
|
||||
unit.action = null
|
||||
}
|
||||
|
||||
|
||||
/** Returns whether the civilian spends its turn hiding and not moving */
|
||||
private fun tryRunAwayIfNeccessary(unit: MapUnit): Boolean {
|
||||
// This is a little 'Bugblatter Beast of Traal': Run if we can attack an enemy
|
||||
@ -608,10 +611,10 @@ object UnitAutomation {
|
||||
if (enemyUnitsInWalkingDistance.isNotEmpty() && !unit.baseUnit.isMilitary()) {
|
||||
if (unit.getTile().militaryUnit == null && !unit.getTile().isCityCenter())
|
||||
runAway(unit)
|
||||
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@ -624,8 +627,8 @@ object UnitAutomation {
|
||||
return
|
||||
}
|
||||
val defensiveUnit = reachableTiles.keys
|
||||
.firstOrNull {
|
||||
it.militaryUnit != null && it.militaryUnit!!.civInfo == unit.civInfo && it.civilianUnit == null
|
||||
.firstOrNull {
|
||||
it.militaryUnit != null && it.militaryUnit!!.civInfo == unit.civInfo && it.civilianUnit == null
|
||||
}
|
||||
if (defensiveUnit != null) {
|
||||
unit.movement.moveToTile(defensiveUnit)
|
||||
@ -646,7 +649,7 @@ object UnitAutomation {
|
||||
return 4
|
||||
}
|
||||
|
||||
private fun containsEnemyMilitaryUnit(unit: MapUnit, tileInfo: TileInfo) =
|
||||
private fun containsEnemyMilitaryUnit(unit: MapUnit, tileInfo: TileInfo) =
|
||||
tileInfo.militaryUnit != null
|
||||
&& tileInfo.militaryUnit!!.civInfo.isAtWarWith(unit.civInfo)
|
||||
|
||||
|
@ -319,6 +319,23 @@ class ReligionManager {
|
||||
religionState = ReligionState.EnhancedReligion
|
||||
}
|
||||
|
||||
fun maySpreadReligionAtAll(missionary: MapUnit): Boolean {
|
||||
if (!civInfo.gameInfo.isReligionEnabled()) return false // No religion, no spreading
|
||||
if (religion == null) return false // need a religion
|
||||
if (religionState < ReligionState.Religion) return false // First found an actual religion
|
||||
if (!civInfo.isMajorCiv()) return false // Only major civs
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
fun maySpreadReligionNow(missionary: MapUnit): Boolean {
|
||||
if (!maySpreadReligionAtAll(missionary)) return false
|
||||
if (missionary.getTile().getOwner() == null) return false
|
||||
if (missionary.currentTile.owningCity?.religion?.getMajorityReligion()?.name == missionary.religion)
|
||||
return false
|
||||
return true
|
||||
}
|
||||
|
||||
fun numberOfCitiesFollowingThisReligion(): Int {
|
||||
if (religion == null) return 0
|
||||
return civInfo.gameInfo.getCities()
|
||||
|
Reference in New Issue
Block a user