Barbarians only heal by pillaging, simplified barbarian automation

This commit is contained in:
Yair Morgenstern 2021-03-19 10:39:55 +02:00
parent a08a5a7435
commit ba51222841
4 changed files with 16 additions and 85 deletions

View File

@ -1050,6 +1050,8 @@
"name": "Barbarians",
"outerColor": [0,0,0],
"innerColor": [182,0,0]
"uniques": ["Can only heal by pillaging"],
}
]

View File

@ -1,15 +1,8 @@
package com.unciv.logic.automation
import com.unciv.Constants
import com.unciv.logic.battle.Battle
import com.unciv.logic.battle.BattleDamage
import com.unciv.logic.battle.MapUnitCombatant
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.map.MapUnit
import com.unciv.logic.map.PathsToTilesWithinTurn
import com.unciv.logic.map.TileInfo
import com.unciv.models.AttackableTile
import com.unciv.models.ruleset.unit.UnitType
class BarbarianAutomation(val civInfo: CivilizationInfo) {
@ -21,14 +14,11 @@ class BarbarianAutomation(val civInfo: CivilizationInfo) {
}
private fun automateUnit(unit: MapUnit) {
when {
unit.currentTile.improvement == Constants.barbarianEncampment -> automateEncampment(unit)
unit.type == UnitType.Scout -> automateScout(unit)
else -> automateCombatUnit(unit)
}
if (unit.currentTile.improvement == Constants.barbarianEncampment) automateUnitOnEncampment(unit)
else automateCombatUnit(unit)
}
private fun automateEncampment(unit: MapUnit) {
private fun automateUnitOnEncampment(unit: MapUnit) {
// 1 - trying to upgrade
if (UnitAutomation.tryUpgradeUnit(unit)) return
@ -40,25 +30,8 @@ class BarbarianAutomation(val civInfo: CivilizationInfo) {
}
private fun automateCombatUnit(unit: MapUnit) {
val unitDistanceToTiles = unit.movement.getDistanceToTiles()
val nearEnemyTiles = BattleHelper.getAttackableEnemies(unit, unitDistanceToTiles)
// 1 - heal or fortifying if death is near
if (unit.health < 50) {
val possibleDamage = nearEnemyTiles
.map {
BattleDamage.calculateDamageToAttacker(MapUnitCombatant(unit),
it.tileToAttackFrom,
Battle.getMapCombatantOfTile(it.tileToAttack)!!)
}
.sum()
val possibleHeal = unit.rankTileForHealing(unit.currentTile)
if (possibleDamage > possibleHeal) {
UnitAutomation.runAway(unit)
}
unit.fortifyIfCan()
return
}
// 1 - Try pillaging to restore health (barbs don't auto-heal)
if (unit.health < 50 && UnitAutomation.tryPillageImprovement(unit)) return
// 2 - trying to upgrade
if (UnitAutomation.tryUpgradeUnit(unit)) return
@ -71,55 +44,8 @@ class BarbarianAutomation(val civInfo: CivilizationInfo) {
// 4 - trying to pillage tile or route
if (UnitAutomation.tryPillageImprovement(unit)) return
// 5 - heal the unit if needed
if (unit.health < 100 && UnitAutomation.tryHealUnit(unit)) return
// 6 - wander
UnitAutomation.wander(unit)
}
private fun automateScout(unit: MapUnit) {
val unitDistanceToTiles = unit.movement.getDistanceToTiles()
val nearEnemyTiles = BattleHelper.getAttackableEnemies(unit, unitDistanceToTiles)
// 1 - heal or run if death is near
if (unit.health < 50) {
if (nearEnemyTiles.isNotEmpty()) UnitAutomation.runAway(unit)
unit.fortifyIfCan()
return
}
// 2 - trying to capture someone
// TODO
// 3 - trying to pillage tile or trade route
if (UnitAutomation.tryPillageImprovement(unit)) return
// 4 - heal the unit if needed
if (unit.health < 100 && UnitAutomation.tryHealUnit(unit)) return
// 5 - wander
UnitAutomation.wander(unit)
}
private fun findFurthestTileCanMoveTo(
unit: MapUnit,
unitDistanceToTiles: PathsToTilesWithinTurn,
nearEnemyTiles: List<AttackableTile>
): TileInfo? {
val possibleTiles = unitDistanceToTiles.keys.filter { unit.movement.canMoveTo(it) }
if(possibleTiles.isEmpty()) return null
val enemies = nearEnemyTiles.mapNotNull { it.tileToAttack.militaryUnit }
var furthestTile: Pair<TileInfo, Float> = possibleTiles.random() to 0f
for (enemy in enemies) {
for (tile in possibleTiles) {
val distance = enemy.movement.getMovementCostBetweenAdjacentTiles(enemy.currentTile, tile, enemy.civInfo)
if (distance > furthestTile.second) {
furthestTile = tile to distance
}
}
}
return furthestTile.first
}
}

View File

@ -441,6 +441,8 @@ class MapUnit {
private fun heal() {
if (isEmbarked()) return // embarked units can't heal
if (civInfo.hasUnique("Can only heal by pillaging")) return
var amountToHealBy = rankTileForHealing(getTile())
if (amountToHealBy == 0) return

View File

@ -227,10 +227,10 @@ open class TileInfo {
val tileType = unique.params[1]
if (tileType == improvement) continue // This is added to the calculation in getImprovementStats. we don't want to add it twice
if (matchesUniqueFilter(tileType, observingCiv)
|| (tileType == "Strategic resource" && hasViewableResource(observingCiv) && getTileResource().resourceType == ResourceType.Strategic)
|| (tileType == "Luxury resource" && hasViewableResource(observingCiv) && getTileResource().resourceType == ResourceType.Luxury)
|| (tileType == "Bonus resource" && hasViewableResource(observingCiv) && getTileResource().resourceType == ResourceType.Bonus)
|| (tileType == "Water resource" && isWater && hasViewableResource(observingCiv))
|| tileType == "Strategic resource" && hasViewableResource(observingCiv) && getTileResource().resourceType == ResourceType.Strategic
|| tileType == "Luxury resource" && hasViewableResource(observingCiv) && getTileResource().resourceType == ResourceType.Luxury
|| tileType == "Bonus resource" && hasViewableResource(observingCiv) && getTileResource().resourceType == ResourceType.Bonus
|| tileType == "Water resource" && isWater && hasViewableResource(observingCiv)
) stats.add(unique.stats)
}
}
@ -606,11 +606,12 @@ open class TileInfo {
}
for (terrainFeature in terrainFeatures.toList()) {
if (!ruleset.terrains.containsKey(terrainFeature)) {
val terrainFeatureObject = ruleset.terrains[terrainFeature]
if (terrainFeatureObject == null) {
terrainFeatures.remove(terrainFeature)
continue
}
val terrainFeatureObject = ruleset.terrains[terrainFeature]!!
if (terrainFeatureObject.occursOn.isNotEmpty() && !terrainFeatureObject.occursOn.contains(baseTerrain))
terrainFeatures.remove(terrainFeature)
}