From 819541838ca89afdb034cbb8d3e11ce324a527d3 Mon Sep 17 00:00:00 2001 From: Oskar Niesen Date: Sun, 28 Jan 2024 03:06:32 -0600 Subject: [PATCH] Ranged units capture civilian (#11012) * Ranged units don't shoot civilian units, they prioritise capturing instead * Cities don't bombard capturable civilian units --- .../unciv/logic/automation/unit/BattleHelper.kt | 14 +++++++++++--- .../unciv/logic/automation/unit/UnitAutomation.kt | 1 + 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/core/src/com/unciv/logic/automation/unit/BattleHelper.kt b/core/src/com/unciv/logic/automation/unit/BattleHelper.kt index 8f57f7a6e9..ce1586e5fe 100644 --- a/core/src/com/unciv/logic/automation/unit/BattleHelper.kt +++ b/core/src/com/unciv/logic/automation/unit/BattleHelper.kt @@ -26,7 +26,13 @@ object BattleHelper { val enemyTileToAttack = chooseAttackTarget(unit, attackableEnemies) if (enemyTileToAttack != null) { - Battle.moveAndAttack(MapUnitCombatant(unit), enemyTileToAttack) + if (enemyTileToAttack.tileToAttack.militaryUnit == null && unit.baseUnit.isRanged() + && unit.movement.canMoveTo(enemyTileToAttack.tileToAttack)) { + // Ranged units should move to caputre a civilian unit instead of attacking it + unit.movement.moveToTile(enemyTileToAttack.tileToAttack) + } else { + Battle.moveAndAttack(MapUnitCombatant(unit), enemyTileToAttack) + } } return unit.currentMovement == 0f } @@ -148,12 +154,14 @@ object BattleHelper { else attackValue -= (attacksToKill * 5).toInt() } else if (civilianUnit != null) { attackValue = 50 - // Only melee units should really attack/capture civilian units, ranged units take more than one turn - if (attacker.baseUnit.isMelee()) { + // Only melee units should really attack/capture civilian units, ranged units may be able to capture by moving + if (attacker.baseUnit.isMelee() || attacker.movement.canReachInCurrentTurn(attackTile.tileToAttack)) { if (civilianUnit.isGreatPerson()) { attackValue += 150 } if (civilianUnit.hasUnique(UniqueType.FoundCity)) attackValue += 60 + } else if (attacker.baseUnit.isRanged() && !civilianUnit.hasUnique(UniqueType.Uncapturable)) { + return 10 // Don't shoot civilians that we can capture! } } // Prioritise closer units as they are generally more threatening to this unit diff --git a/core/src/com/unciv/logic/automation/unit/UnitAutomation.kt b/core/src/com/unciv/logic/automation/unit/UnitAutomation.kt index 88a886abc8..eb65a65a81 100644 --- a/core/src/com/unciv/logic/automation/unit/UnitAutomation.kt +++ b/core/src/com/unciv/logic/automation/unit/UnitAutomation.kt @@ -496,6 +496,7 @@ object UnitAutomation { private fun chooseBombardTarget(city: City): ICombatant? { var targets = TargetHelper.getBombardableTiles(city).map { Battle.getMapCombatantOfTile(it)!! } + .filterNot { it.isCivilian() && !it.getUnitType().hasUnique(UniqueType.Uncapturable) } // Don't bombard capturable civilians if (targets.none()) return null val siegeUnits = targets