public float ComputeVulnerabilityRatio(ICombatant targetUnit, bool iCanMove) { float hp; Mech targetMech = targetUnit as Mech; AbstractActor targetActor = targetUnit as AbstractActor; if ((!iCanMove) && (targetMech != null)) { // only use armor exposed to us at our current position hp = targetMech.ExpectedRelativeArmorFromAttackerWorldPosition(thisUnit.CurrentPosition, targetMech.CurrentPosition, targetMech.CurrentRotation) + targetMech.GetCurrentStructure(ChassisLocations.Head) + targetMech.GetCurrentStructure(ChassisLocations.CenterTorso); } else { // find the target's weakest armor hp = AttackEvaluator.MinHitPoints(targetUnit); } bool targetIsEvasive = (targetMech != null) && targetMech.IsEvasive; float expectedDamage = GetExpectedDamageForAllWeaponsVsTarget(thisUnit, targetUnit, targetIsEvasive); if ((targetActor != null) && (targetActor.IsVulnerableToCalledShots())) { float multiplier = targetActor.BehaviorTree.GetBehaviorVariableValue(BehaviorVariableName.Float_CalledShotVulnerabilityMultiplier).FloatVal; expectedDamage *= multiplier; } if (hp <= 0) { return(float.MaxValue); } return(expectedDamage / hp); }
static List <Weapon> PartitionWeaponListToKillTarget(AbstractActor attacker, List <Weapon> weapons, ICombatant target, float overkillThresholdFrac) { // evaluate the weapons' damages to the target List <KeyValuePair <Weapon, float> > weaponsWithDamage = new List <KeyValuePair <Weapon, float> >(); for (int wi = 0; wi < weapons.Count; ++wi) { Weapon w = weapons[wi]; Mech targetMech = target as Mech; if (!attacker.Combat.LOFCache.UnitHasLOFToTargetAtTargetPosition( attacker, target, w.MaxRange, attacker.CurrentPosition, attacker.CurrentRotation, target.CurrentPosition, target.CurrentRotation, w.IndirectFireCapable)) { continue; } bool targetIsEvasive = ((targetMech != null) && (targetMech.IsEvasive)); float dmg = GetExpectedDamageForMultiTargetWeapon(attacker, attacker.CurrentPosition, target, target.CurrentPosition, targetIsEvasive, w, attacker.MaxTargets); weaponsWithDamage.Add(new KeyValuePair <Weapon, float>(w, dmg)); } // sort by damage weaponsWithDamage.Sort((x, y) => x.Value.CompareTo(y.Value)); // reverse it to start with big damage weaponsWithDamage.Reverse(); float totalDamage = 0.0f; float targetDamage = AttackEvaluator.MinHitPoints(target) * overkillThresholdFrac; List <Weapon> killList = new List <Weapon>(); for (int wi = 0; wi < weaponsWithDamage.Count; ++wi) { Weapon w = weaponsWithDamage[wi].Key; float dmg = weaponsWithDamage[wi].Value; totalDamage += dmg; killList.Add(w); if (totalDamage >= targetDamage) { return(killList); } } return(null); }
/// <summary> /// Calculate an "overkill" ratio; if the shooter did an alpha strike on the target's weakest location, what's the ratio of damage compared to the amount to blow through. /// </summary> /// <param name="shooterUnit"></param> /// <param name="targetUnit"></param> /// <returns></returns> public float ComputeThreatRatio(ICombatant shooterUnit, AbstractActor targetUnit) { AbstractActor shooterActor = shooterUnit as AbstractActor; if (shooterActor == null) { return(0.0f); } float targetHP = AttackEvaluator.MinHitPoints(targetUnit); float expectedDamageToTarget = GetExpectedDamageForAllWeaponsVsTarget(shooterActor, targetUnit, targetUnit.IsEvasive); if (targetHP < 1.0f) { targetHP = 1.0f; } return(expectedDamageToTarget / targetHP); }