mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-22 19:08:48 -04:00
Fix unit force rankings
This commit is contained in:
parent
c1320357be
commit
c738bc8878
@ -31,6 +31,113 @@ object UnitAutomation {
|
||||
private const val CLOSE_ENEMY_TILES_AWAY_LIMIT = 5
|
||||
private const val CLOSE_ENEMY_TURNS_AWAY_LIMIT = 3f
|
||||
|
||||
fun automateUnitMoves(unit: MapUnit) {
|
||||
check(!unit.civ.isBarbarian) { "Barbarians is not allowed here." }
|
||||
|
||||
// Might die next turn - move!
|
||||
if (unit.getDamageFromTerrain() > 0 && tryHealUnit(unit)) return
|
||||
|
||||
|
||||
if (unit.isCivilian()) {
|
||||
CivilianUnitAutomation.automateCivilianUnit(unit, getDangerousTiles(unit))
|
||||
return
|
||||
}
|
||||
|
||||
while (unit.promotions.canBePromoted() &&
|
||||
// Restrict Human automated units from promotions via setting
|
||||
(UncivGame.Current.settings.automatedUnitsChoosePromotions || unit.civ.isAI())) {
|
||||
val promotions = unit.promotions.getAvailablePromotions()
|
||||
val availablePromotions = if (unit.health <= 60
|
||||
&& promotions.any {it.hasUnique(UniqueType.OneTimeUnitHeal)}
|
||||
&& !(unit.baseUnit.isAirUnit() || unit.hasUnique(UniqueType.CanMoveAfterAttacking))) {
|
||||
promotions.filter { it.hasUnique(UniqueType.OneTimeUnitHeal) }
|
||||
} else promotions.filterNot { it.hasUnique(UniqueType.SkipPromotion) }
|
||||
|
||||
if (availablePromotions.none()) break
|
||||
val freePromotions = availablePromotions.filter { it.hasUnique(UniqueType.FreePromotion) }.toList()
|
||||
val stateForConditionals = unit.cache.state
|
||||
|
||||
val chosenPromotion = if (freePromotions.isNotEmpty()) freePromotions.randomWeighted { it.getWeightForAiDecision(stateForConditionals) }
|
||||
else availablePromotions.toList().randomWeighted { it.getWeightForAiDecision(stateForConditionals) }
|
||||
|
||||
unit.promotions.addPromotion(chosenPromotion.name)
|
||||
}
|
||||
|
||||
// AI upgrades units via UseGoldAutomation in NextTurnAutomation
|
||||
if (unit.civ.isHuman() && tryUpgradeUnit(unit)) return
|
||||
|
||||
//This allows for military units with certain civilian abilities to behave as civilians in peace and soldiers in war
|
||||
if ((unit.hasUnique(UniqueType.BuildImprovements) || unit.hasUnique(UniqueType.FoundCity) ||
|
||||
unit.hasUnique(UniqueType.ReligiousUnit) || unit.hasUnique(UniqueType.CreateWaterImprovements))
|
||||
&& !unit.civ.isAtWar()){
|
||||
CivilianUnitAutomation.automateCivilianUnit(unit, getDangerousTiles(unit))
|
||||
return
|
||||
}
|
||||
|
||||
// Note that not all nukes have to be air units
|
||||
if (unit.isNuclearWeapon()) {
|
||||
return AirUnitAutomation.automateNukes(unit)
|
||||
}
|
||||
|
||||
if (unit.baseUnit.isAirUnit()) {
|
||||
if (unit.canIntercept())
|
||||
return AirUnitAutomation.automateFighter(unit)
|
||||
|
||||
if (unit.hasUnique(UniqueType.SelfDestructs))
|
||||
return AirUnitAutomation.automateMissile(unit)
|
||||
|
||||
return AirUnitAutomation.automateBomber(unit)
|
||||
}
|
||||
|
||||
// Accompany settlers
|
||||
if (tryAccompanySettlerOrGreatPerson(unit)) return
|
||||
|
||||
if (tryGoToRuinAndEncampment(unit) && !unit.hasMovement()) return
|
||||
|
||||
if (unit.health < 50 && (tryRetreat(unit) || tryHealUnit(unit))) return // do nothing but heal
|
||||
|
||||
// If there are no enemies nearby and we can heal here, wait until we are at full health
|
||||
if (unit.health < 100 && canUnitHealInTurnsOnCurrentTile(unit,2, 3)) return
|
||||
|
||||
if (tryHeadTowardsOurSiegedCity(unit)) return
|
||||
|
||||
// if a embarked melee unit can land and attack next turn, do not attack from water.
|
||||
if (BattleHelper.tryDisembarkUnitToAttackPosition(unit)) return
|
||||
|
||||
// if there is an attackable unit in the vicinity, attack!
|
||||
if (tryAttacking(unit)) return
|
||||
|
||||
if (tryTakeBackCapturedCity(unit)) return
|
||||
|
||||
// Focus all units without a specific target on the enemy city closest to one of our cities
|
||||
if (HeadTowardsEnemyCityAutomation.tryHeadTowardsEnemyCity(unit)) return
|
||||
|
||||
if (tryGarrisoningRangedLandUnit(unit)) return
|
||||
|
||||
if (tryStationingMeleeNavalUnit(unit)) return
|
||||
|
||||
if (unit.health < 80 && tryHealUnit(unit)) return
|
||||
|
||||
// move towards the closest reasonably attackable enemy unit within 3 turns of movement (and 5 tiles range)
|
||||
if (tryAdvanceTowardsCloseEnemy(unit)) return
|
||||
|
||||
if (tryHeadTowardsEncampment(unit)) return
|
||||
|
||||
if (unit.health < 100 && tryHealUnit(unit)) return
|
||||
|
||||
if (tryPrepare(unit)) return
|
||||
|
||||
// else, try to go to unreached tiles
|
||||
if (tryExplore(unit)) return
|
||||
|
||||
if (tryFogBust(unit)) return
|
||||
|
||||
// Idle CS units should wander so they don't obstruct players so much
|
||||
if (unit.civ.isCityState)
|
||||
wander(unit, stayInTerritory = true)
|
||||
}
|
||||
|
||||
|
||||
@Readonly
|
||||
private fun isGoodTileToExplore(unit: MapUnit, tile: Tile): Boolean {
|
||||
return (tile.getOwner() == null || !tile.getOwner()!!.isCityState)
|
||||
@ -174,112 +281,6 @@ object UnitAutomation {
|
||||
.filter { !isInvalidUpgradeDestination(it) && unit.upgrade.canUpgrade(it) }
|
||||
}
|
||||
|
||||
fun automateUnitMoves(unit: MapUnit) {
|
||||
check(!unit.civ.isBarbarian) { "Barbarians is not allowed here." }
|
||||
|
||||
// Might die next turn - move!
|
||||
if (unit.getDamageFromTerrain() > 0 && tryHealUnit(unit)) return
|
||||
|
||||
|
||||
if (unit.isCivilian()) {
|
||||
CivilianUnitAutomation.automateCivilianUnit(unit, getDangerousTiles(unit))
|
||||
return
|
||||
}
|
||||
|
||||
while (unit.promotions.canBePromoted() &&
|
||||
// Restrict Human automated units from promotions via setting
|
||||
(UncivGame.Current.settings.automatedUnitsChoosePromotions || unit.civ.isAI())) {
|
||||
val promotions = unit.promotions.getAvailablePromotions()
|
||||
val availablePromotions = if (unit.health <= 60
|
||||
&& promotions.any {it.hasUnique(UniqueType.OneTimeUnitHeal)}
|
||||
&& !(unit.baseUnit.isAirUnit() || unit.hasUnique(UniqueType.CanMoveAfterAttacking))) {
|
||||
promotions.filter { it.hasUnique(UniqueType.OneTimeUnitHeal) }
|
||||
} else promotions.filterNot { it.hasUnique(UniqueType.SkipPromotion) }
|
||||
|
||||
if (availablePromotions.none()) break
|
||||
val freePromotions = availablePromotions.filter { it.hasUnique(UniqueType.FreePromotion) }.toList()
|
||||
val stateForConditionals = unit.cache.state
|
||||
|
||||
val chosenPromotion = if (freePromotions.isNotEmpty()) freePromotions.randomWeighted { it.getWeightForAiDecision(stateForConditionals) }
|
||||
else availablePromotions.toList().randomWeighted { it.getWeightForAiDecision(stateForConditionals) }
|
||||
|
||||
unit.promotions.addPromotion(chosenPromotion.name)
|
||||
}
|
||||
|
||||
// AI upgrades units via UseGoldAutomation in NextTurnAutomation
|
||||
if (unit.civ.isHuman() && tryUpgradeUnit(unit)) return
|
||||
|
||||
//This allows for military units with certain civilian abilities to behave as civilians in peace and soldiers in war
|
||||
if ((unit.hasUnique(UniqueType.BuildImprovements) || unit.hasUnique(UniqueType.FoundCity) ||
|
||||
unit.hasUnique(UniqueType.ReligiousUnit) || unit.hasUnique(UniqueType.CreateWaterImprovements))
|
||||
&& !unit.civ.isAtWar()){
|
||||
CivilianUnitAutomation.automateCivilianUnit(unit, getDangerousTiles(unit))
|
||||
return
|
||||
}
|
||||
|
||||
// Note that not all nukes have to be air units
|
||||
if (unit.isNuclearWeapon()) {
|
||||
return AirUnitAutomation.automateNukes(unit)
|
||||
}
|
||||
|
||||
if (unit.baseUnit.isAirUnit()) {
|
||||
if (unit.canIntercept())
|
||||
return AirUnitAutomation.automateFighter(unit)
|
||||
|
||||
if (unit.hasUnique(UniqueType.SelfDestructs))
|
||||
return AirUnitAutomation.automateMissile(unit)
|
||||
|
||||
return AirUnitAutomation.automateBomber(unit)
|
||||
}
|
||||
|
||||
// Accompany settlers
|
||||
if (tryAccompanySettlerOrGreatPerson(unit)) return
|
||||
|
||||
if (tryGoToRuinAndEncampment(unit) && !unit.hasMovement()) return
|
||||
|
||||
if (unit.health < 50 && (tryRetreat(unit) || tryHealUnit(unit))) return // do nothing but heal
|
||||
|
||||
// If there are no enemies nearby and we can heal here, wait until we are at full health
|
||||
if (unit.health < 100 && canUnitHealInTurnsOnCurrentTile(unit,2, 3)) return
|
||||
|
||||
if (tryHeadTowardsOurSiegedCity(unit)) return
|
||||
|
||||
// if a embarked melee unit can land and attack next turn, do not attack from water.
|
||||
if (BattleHelper.tryDisembarkUnitToAttackPosition(unit)) return
|
||||
|
||||
// if there is an attackable unit in the vicinity, attack!
|
||||
if (tryAttacking(unit)) return
|
||||
|
||||
if (tryTakeBackCapturedCity(unit)) return
|
||||
|
||||
// Focus all units without a specific target on the enemy city closest to one of our cities
|
||||
if (HeadTowardsEnemyCityAutomation.tryHeadTowardsEnemyCity(unit)) return
|
||||
|
||||
if (tryGarrisoningRangedLandUnit(unit)) return
|
||||
|
||||
if (tryStationingMeleeNavalUnit(unit)) return
|
||||
|
||||
if (unit.health < 80 && tryHealUnit(unit)) return
|
||||
|
||||
// move towards the closest reasonably attackable enemy unit within 3 turns of movement (and 5 tiles range)
|
||||
if (tryAdvanceTowardsCloseEnemy(unit)) return
|
||||
|
||||
if (tryHeadTowardsEncampment(unit)) return
|
||||
|
||||
if (unit.health < 100 && tryHealUnit(unit)) return
|
||||
|
||||
if (tryPrepare(unit)) return
|
||||
|
||||
// else, try to go to unreached tiles
|
||||
if (tryExplore(unit)) return
|
||||
|
||||
if (tryFogBust(unit)) return
|
||||
|
||||
// Idle CS units should wander so they don't obstruct players so much
|
||||
if (unit.civ.isCityState)
|
||||
wander(unit, stayInTerritory = true)
|
||||
}
|
||||
|
||||
|
||||
/** @return true only if the unit has 0 movement left */
|
||||
private fun tryAttacking(unit: MapUnit): Boolean {
|
||||
|
@ -578,8 +578,8 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
|
||||
-> power *= (unique.params[0].toInt() * 20f).toPercent()
|
||||
else -> {}
|
||||
}
|
||||
power *= highestConditionalPowerBonus
|
||||
}
|
||||
power *= highestConditionalPowerBonus
|
||||
|
||||
return power.toInt()
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user