mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-22 02:42:16 -04:00
Merge 45d251ce7e3442342bb5eb18ceaefd82a9d528cd into d51ef24c205b6b05330b3c4d7ce79c402db44447
This commit is contained in:
commit
13c200d7f8
@ -183,10 +183,93 @@ object Battle {
|
||||
.firstOrNull { it.text == "Your city [${attacker.getName()}] can bombard the enemy!" }
|
||||
attacker.getCivInfo().notifications.remove(cityCanBombardNotification)
|
||||
}
|
||||
|
||||
|
||||
//Aoe attack
|
||||
if (attacker is MapUnitCombatant && (attacker.unit.hasUnique(UniqueType.AoeDegradeAttack) || attacker.unit.hasUnique(UniqueType.AoeFlatAttack))) {
|
||||
applyAoeAttack(attacker, defender)
|
||||
}
|
||||
|
||||
return damageDealt + interceptDamage
|
||||
}
|
||||
|
||||
//Aoe Logic function
|
||||
fun applyAoeAttack(attacker: MapUnitCombatant, defender: ICombatant) {
|
||||
|
||||
//degrading AOE is used if both AoeDegradeAttack and AoeFlatAttack uniques are present
|
||||
val degradeUnique = attacker.unit.getMatchingUniques(UniqueType.AoeDegradeAttack).firstOrNull()
|
||||
val flatUnique = attacker.unit.getMatchingUniques(UniqueType.AoeFlatAttack).firstOrNull()
|
||||
val aoeUnique = degradeUnique ?: flatUnique ?: return
|
||||
val isDegrade = degradeUnique != null
|
||||
|
||||
val radius = aoeUnique.params.getOrNull(0)?.toIntOrNull() ?: return
|
||||
if (radius <= 0) return
|
||||
|
||||
val includeAllies = attacker.unit.hasUnique(UniqueType.CanDamageAlliesInAOE)
|
||||
val excludeSelf = !attacker.unit.hasUnique(UniqueType.CanDamageSelfInAOE)
|
||||
val receivesCounterDamage = attacker.unit.hasUnique(UniqueType.TakeCounterDamageFromAOE)
|
||||
val centerTile = defender.getTile()
|
||||
val attackerCiv = attacker.getCivInfo()
|
||||
|
||||
for (tile in centerTile.getTilesInDistance(radius)) {
|
||||
val distance = centerTile.aerialDistanceTo(tile)
|
||||
val distanceFactor = if (isDegrade)
|
||||
(1.0 - distance.toDouble() / (radius + 1)).coerceAtLeast(0.0)
|
||||
else 1.0
|
||||
|
||||
for (unit in tile.getUnits()) {
|
||||
if (excludeSelf && unit == attacker.unit) continue
|
||||
if (unit == (defender as? MapUnitCombatant)?.unit && unit != attacker.unit) continue
|
||||
|
||||
val isAlly = !unit.civ.isAtWarWith(attackerCiv)
|
||||
if (!includeAllies && isAlly && unit != attacker.unit) continue
|
||||
|
||||
val aoeDefender = MapUnitCombatant(unit)
|
||||
val damage = (BattleDamage.calculateDamageToDefender(attacker, aoeDefender) * distanceFactor).toInt().coerceAtLeast(1)
|
||||
|
||||
if (aoeDefender.isCivilian() && attacker.isMelee()) {
|
||||
// Capture civilian units if attacker can capture
|
||||
BattleUnitCapture.captureCivilianUnit(attacker, aoeDefender)
|
||||
continue
|
||||
}
|
||||
|
||||
// Apply combat effects but no counter-damage
|
||||
triggerCombatUniques(attacker, aoeDefender, tile)
|
||||
aoeDefender.takeDamage(damage)
|
||||
triggerDamageUniquesForUnit(attacker, aoeDefender, tile, CombatAction.Attack)
|
||||
|
||||
if (aoeDefender.isDefeated() && !aoeDefender.isCivilian()) {
|
||||
// Try to capture first - if successful, skip other defeat effects
|
||||
val captured = BattleUnitCapture.tryCaptureMilitaryUnit(attacker, aoeDefender, tile)
|
||||
if (!captured) {
|
||||
// If not captured, proceed with normal defeat effects
|
||||
triggerPostKillingUniques(aoeDefender, attacker, tile)
|
||||
}
|
||||
}
|
||||
|
||||
if (receivesCounterDamage && !aoeDefender.isCivilian()) {
|
||||
val isMainTarget =
|
||||
(defender is MapUnitCombatant && unit == defender.unit) ||
|
||||
(defender is CityCombatant && unit == defender.city)
|
||||
|
||||
val isSelf = (unit == attacker.unit)
|
||||
|
||||
// Counter damage from every valid target except main defender + self
|
||||
if (!isMainTarget && !isSelf) {
|
||||
val baseCounterDamage = BattleDamage.calculateDamageToAttacker(attacker, aoeDefender)
|
||||
val finalCounterDamage =
|
||||
if (isDegrade) (baseCounterDamage * distanceFactor).toInt().coerceAtLeast(1)
|
||||
else baseCounterDamage
|
||||
|
||||
attacker.takeDamage(finalCounterDamage)
|
||||
|
||||
if (attacker.isDefeated()) return
|
||||
}
|
||||
}
|
||||
if (attacker.isDefeated()) return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun triggerPostKillingUniques(
|
||||
defender: ICombatant,
|
||||
attacker: ICombatant,
|
||||
|
@ -426,6 +426,21 @@ enum class UniqueType(
|
||||
IndirectFire("Ranged attacks may be performed over obstacles", UniqueTarget.Unit, UniqueTarget.Global),
|
||||
NuclearWeapon("Nuclear weapon of Strength [amount]", UniqueTarget.Unit),
|
||||
|
||||
//Aoe Attacks
|
||||
AoeFlatAttack("Attacks also target all units within [positiveAmount] tiles", UniqueTarget.Unit,
|
||||
docDescription = "Performs an attack against every unit in the radius, dealing equal damage. Status effects and on-hit abilities apply to all affected units. " +
|
||||
"If both this and decreasing area attacks are present, only decreasing area attacks will be used."),
|
||||
AoeDegradeAttack("Attacks also target units within [positiveAmount] tiles, with damage decreasing by distance", UniqueTarget.Unit,
|
||||
docDescription = "Performs an attack against every unit in the radius. Status effects and on-hit abilities apply. " +
|
||||
"Damage decreases with distance from the main target. If both this and equal area attacks are present, only this will be used. " +
|
||||
"Damage formula: Damage = (1 - (distance / radius)) * baseDamage"),
|
||||
CanDamageSelfInAOE("Damages self with Aoe attacks", UniqueTarget.Unit,
|
||||
docDescription = "This unit takes damage from its own Aoe attacks, does not mean it will take damage from allied Aoe attacks."),
|
||||
CanDamageAlliesInAOE("Damages allied units with Aoe attacks", UniqueTarget.Unit,
|
||||
docDescription = "This unit damages allied units with Aoe attacks, does not mean it will take damage from its own Aoe attacks unless Damages self with Aoe attacks is also set."),
|
||||
TakeCounterDamageFromAOE("Takes counter damage from each unit hit by its area attacks", UniqueTarget.Unit,
|
||||
docDescription = "Only works for melee units, counter damage does not activate on self if \"Damages self with Aoe attacks\" unique is also present."),
|
||||
|
||||
NoDefensiveTerrainBonus("No defensive terrain bonus", UniqueTarget.Unit, UniqueTarget.Global),
|
||||
NoDefensiveTerrainPenalty("No defensive terrain penalty", UniqueTarget.Unit, UniqueTarget.Global),
|
||||
NoDamagePenaltyWoundedUnits("No damage penalty for wounded units", UniqueTarget.Unit, UniqueTarget.Global),
|
||||
|
Loading…
x
Reference in New Issue
Block a user