if ((attacker.getPosition() != null) && (g.getEntity(waa.getTargetId()).getPosition() != null)){ if (wt.getAmmoType() == AmmoType.T_GAUSS_HEAVY){ fDamage = 25.0f; int rtt = attacker.getPosition().distance(g.getEntity(waa.getTargetId()).getPosition()); if (rtt > 6){ fDamage = 20.0f; } if (rtt > 13){ fDamage = 10.0f; } } }
    public static float getExpectedDamage(IGame g, WeaponAttackAction waa) {        boolean use_table = false;        AmmoType loaded_ammo = new AmmoType();        Entity attacker = g.getEntity(waa.getEntityId());        Infantry inf_attacker = new Infantry();        BattleArmor ba_attacker = new BattleArmor();        Mounted weapon = attacker.getEquipment(waa.getWeaponId());        Mounted lnk_guide;        ToHitData hitData = waa.toHit(g);        if (attacker instanceof BattleArmor) {            ba_attacker = (BattleArmor) g.getEntity(waa.getEntityId());        }        if ((attacker instanceof Infantry)                && !(attacker instanceof BattleArmor)) {            inf_attacker = (Infantry) g.getEntity(waa.getEntityId());        }        float fDamage = 0.0f;        WeaponType wt = (WeaponType) weapon.getType();        if (hitData.getValue() == ToHitData.IMPOSSIBLE                || hitData.getValue() == ToHitData.AUTOMATIC_FAIL) {            return 0.0f;        }        float fChance = 0.0f;        if (hitData.getValue() == ToHitData.AUTOMATIC_SUCCESS) {            fChance = 1.0f;        } else {            fChance = (float) oddsAbove(hitData.getValue()) / 100.0f;        }        // Missiles, LBX cluster rounds, and ultra/rotary cannons (when spun up)        // use the missile hits table        if (wt.getDamage() == WeaponType.DAMAGE_MISSILE) {            use_table = true;        }        if ((wt.getAmmoType() == AmmoType.T_AC_LBX)                || (wt.getAmmoType() == AmmoType.T_AC_LBX_THB)) {            loaded_ammo = (AmmoType) weapon.getLinked().getType();            if (((loaded_ammo.getAmmoType() == AmmoType.T_AC_LBX) || (loaded_ammo                    .getAmmoType() == AmmoType.T_AC_LBX_THB))                    && loaded_ammo.getMunitionType() == AmmoType.M_CLUSTER) {                use_table = true;            }        }        if ((wt.getAmmoType() == AmmoType.T_AC_ULTRA)                || (wt.getAmmoType() == AmmoType.T_AC_ULTRA_THB)                || (wt.getAmmoType() == AmmoType.T_AC_ROTARY)) {            if ((weapon.curMode().getName() == "Ultra")                    || (weapon.curMode().getName() == "2-shot")                    || (weapon.curMode().getName() == "4-shot")                    || (weapon.curMode().getName() == "6-shot")) {                use_table = true;            }        }        // Kinda cheap, but lets use the missile hits table for Battle armor        // weapons too        if (attacker instanceof BattleArmor) {            if ((wt.getInternalName() != Infantry.SWARM_MEK)                    && (wt.getInternalName() != Infantry.LEG_ATTACK)) {                use_table = true;            }        }        if (use_table == true) {            if (!(attacker instanceof BattleArmor)) {                if (weapon.getLinked() == null)                    return 0.0f;            }            AmmoType at = null;            if (weapon.getLinked() != null) {                at = (AmmoType) weapon.getLinked().getType();                fDamage = at.getDamagePerShot();            }            float fHits = 0.0f;            if (wt.getRackSize() != 40 && wt.getRackSize() != 30) {                fHits = expectedHitsByRackSize[wt.getRackSize()];            } else {                fHits = 2.0f * expectedHitsByRackSize[wt.getRackSize() / 2];            }            if ((wt.getAmmoType() == AmmoType.T_SRM_STREAK)                    || (wt.getAmmoType() == AmmoType.T_LRM_STREAK)                    && !Compute.isAffectedByAngelECM(attacker, attacker                            .getPosition(), waa.getTarget(g).getPosition())) {                fHits = wt.getRackSize();            }            if ((wt.getAmmoType() == AmmoType.T_AC_ULTRA)                    || (wt.getAmmoType() == AmmoType.T_AC_ULTRA_THB)                    || (wt.getAmmoType() == AmmoType.T_AC_ROTARY)) {                if ((weapon.curMode().getName() == "Ultra")                        || (weapon.curMode().getName() == "2-shot")) {                    fHits = expectedHitsByRackSize[2];                }                if (weapon.curMode().getName() == "4-shot") {                    fHits = expectedHitsByRackSize[4];                }                if (weapon.curMode().getName() == "6-shot") {                    fHits = expectedHitsByRackSize[6];                }            }            // Most Battle Armor units have a weapon per trooper, plus their            // weapons do odd things when mounting multiples            if (attacker instanceof BattleArmor) {                // The number of troopers hitting                fHits = expectedHitsByRackSize[ba_attacker                        .getShootingStrength()];                if (wt.getDamage() == WeaponType.DAMAGE_MISSILE) {                    fHits *= expectedHitsByRackSize[wt.getRackSize()];                }                if (wt.getDamage() != WeaponType.DAMAGE_MISSILE) {                    if (wt.getDamage() != WeaponType.DAMAGE_VARIABLE) {                        fDamage = wt.getDamage();                    } else {                        fDamage = wt.getRackSize();                    }                }                if (wt.hasFlag(WeaponType.F_DOUBLE_HITS)) {                    fHits *= 2;                }                if (wt.hasFlag(WeaponType.F_MISSILE_HITS)) {                    fHits *= expectedHitsByRackSize[wt.getRackSize()];                }            }            // If there is no ECM coverage to the target, guidance systems are            // good for another 1.20x damage on missile weapons            if ((!isAffectedByECM(attacker, attacker.getPosition(), g                    .getEntity(waa.getTargetId()).getPosition()))                    && (wt.getDamage() == WeaponType.DAMAGE_MISSILE)) {                // Check for linked artemis guidance system                if (wt.getAmmoType() == AmmoType.T_LRM                        || wt.getAmmoType() == AmmoType.T_SRM) {                    lnk_guide = weapon.getLinkedBy();                    if (lnk_guide != null                            && lnk_guide.getType() instanceof MiscType                            && !lnk_guide.isDestroyed()                            && !lnk_guide.isMissing()                            && !lnk_guide.isBreached()                            && lnk_guide.getType().hasFlag(MiscType.F_ARTEMIS)) {                        // Don't use artemis if this is indirect fire                        // -> Hook for Artemis V Level 3 Clan tech here; use                        // 1.30f multiplier when implemented                        if ((weapon.curMode() == null || !weapon.curMode()                                .equals("Indirect"))                                && at.getMunitionType() == AmmoType.M_ARTEMIS_CAPABLE) {                            fHits *= 1.2f;                        }                    }                }                // Check for ATMs, which have built in Artemis                if (wt.getAmmoType() == AmmoType.T_ATM) {                    fHits *= 1.2f;                }                // Check for target with attached Narc or iNarc homing pod from                // friendly unit                if (g.getEntity(waa.getTargetId()).isNarcedBy(                        attacker.getOwner().getTeam())                        || g.getEntity(waa.getTargetId()).isINarcedBy(                                attacker.getOwner().getTeam())) {                    if (((at.getAmmoType() == AmmoType.T_LRM) || (at                            .getAmmoType() == AmmoType.T_SRM))                            && at.getMunitionType() == AmmoType.M_NARC_CAPABLE) {                        fHits *= 1.2f;                    }                }            }            // adjust for previous AMS            if (wt.getDamage() == WeaponType.DAMAGE_MISSILE) {                Vector vCounters = waa.getCounterEquipment();                if (vCounters != null) {                    for (int x = 0; x < vCounters.size(); x++) {                        Mounted counter = (Mounted) vCounters.elementAt(x);                        if (counter.getType() instanceof WeaponType                                && counter.getType().hasFlag(WeaponType.F_AMS)) {                            float fAMS = 3.5f * ((WeaponType) counter.getType())                                    .getDamage();                            fHits = Math.max(0.0f, fHits - fAMS);                        }                    }                }            }            fDamage *= fHits;            if ((wt.getAmmoType() == AmmoType.T_AC_ULTRA)                    || (wt.getAmmoType() == AmmoType.T_AC_ULTRA_THB)                    || (wt.getAmmoType() == AmmoType.T_AC_ROTARY)) {                fDamage = fHits * wt.getDamage();            }        } else {            // Direct fire weapons (and LBX slug rounds) just do a single shot            // so they don't use the missile hits table            fDamage = wt.getDamage();            // Infantry follow some special rules, but do fixed amounts of            // damage            // Anti-mek attacks are weapon-like in nature, so include them here            // as well            if (attacker instanceof Infantry) {                if (wt.getInternalName() == Infantry.LEG_ATTACK) {                    fDamage = 10.0f; // Actually 5, but the chance of crits                    // deserves a boost                }                if (inf_attacker.isPlatoon()) {                    if (wt.getInternalName() == Infantry.SWARM_MEK) {                        // If the target is a Mek that is not swarmed, this is a                        // good thing                        if ((g.getEntity(waa.getTargetId())                                .getSwarmAttackerId() == Entity.NONE)                                && (g.getEntity(waa.getTargetId()) instanceof Mech)) {                            fDamage = 1.5f * inf_attacker                                    .getDamage(inf_attacker                                            .getShootingStrength());                        }                        // Otherwise, call it 0 damage                        else {                            fDamage = 0.0f;                        }                    }                    else {                        // conventional weapons; field guns should be handled                        // under the standard weapons section                        fDamage = inf_attacker.getDamage(inf_attacker                                .getShootingStrength());                    }                } else {                    // Battle armor units conducting swarm attack                    if (wt.getInternalName() == Infantry.SWARM_MEK) {                        // If the target is a Mek that is not swarmed, this is a                        // good thing                        if ((g.getEntity(waa.getTargetId())                                .getSwarmAttackerId() == Entity.NONE)                                && (g.getEntity(waa.getTargetId()) instanceof Mech)) {                            // Overestimated, but the chance at crits and head                            // shots deserves a boost                            fDamage = 5.0f * ba_attacker.getShootingStrength();                        }                        // Otherwise, call it 0 damage                        else {                            fDamage = 0.0f;                        }                    }                }            }        }        fDamage *= fChance;        // Conventional infantry take double damage in the open        if ((g.getEntity(waa.getTargetId()) instanceof Infantry)                && !(g.getEntity(waa.getTargetId()) instanceof BattleArmor)) {            IHex e_hex = g.getBoard().getHex(                    g.getEntity(waa.getTargetId()).getPosition().x,                    g.getEntity(waa.getTargetId()).getPosition().y);            if (!e_hex.containsTerrain(Terrains.WOODS)                    && !e_hex.containsTerrain(Terrains.BUILDING)) {                fDamage *= 2.0f;            }        }        return fDamage;    }