Package megamek.common

Examples of megamek.common.Report


        boolean inHardenedBuilding = (Compute.isInBuilding(game, entity) && (game.getBoard().getHex(entity.getPosition()).terrainLevel(Terrains.BUILDING) == 4));

        // Roll 2d6.
        int roll = Compute.d6(2);

        Report r = new Report(6555);
        r.subject = entity.getId();
        r.add(entity.getDisplayName());
        r.add(roll);

        // If they are in protective structure, add 2 to the roll.
        if (inHardenedBuilding) {
            roll += 2;
            r.add(" + 2 (unit is in hardened building)");
        } else {
            r.add("");
        }

        // Also, if the entity is "hardened" against EMI, it gets a +2.
        // For these purposes, I'm going to hand this off to the Entity itself
        // to tell us.
        // Right now, it IS based purely on class, but I won't rule out the idea
        // of
        // "nuclear hardening" as equipment for a support vehicle, for example.
        if (entity.isNuclearHardened()) {
            roll += 2;
            r.add(" + 2 (unit is hardened against EMI)");
        } else {
            r.add("");
        }

        r.indent(2);
        vDesc.add(r);

        // Now, compare it to the table, and apply the effects.
        if (roll <= 4) {
            // The unit is destroyed.
View Full Code Here


     * @param isCapital
     *            whether it was capital scale damage that caused critical
     */
    public Vector<Report> applyCriticalHit(Entity en, int loc, CriticalSlot cs, boolean secondaryEffects, int damageCaused, boolean isCapital) {
        Vector<Report> vDesc = new Vector<Report>();
        Report r;

        // Handle hits on "critical slots" of tanks.
        if (en instanceof Tank) {
            Tank t = (Tank) en;
            HitData hit;
            switch (cs.getIndex()) {
            case Tank.CRIT_NONE:
                // no effect
                r = new Report(6005);
                r.subject = t.getId();
                vDesc.add(r);
                break;
            case Tank.CRIT_AMMO:
                // ammo explosion
                r = new Report(6610);
                r.subject = t.getId();
                vDesc.add(r);
                int damage = 0;
                for (Mounted m : t.getAmmo()) {
                    m.setHit(true);
                    int tmp = m.getShotsLeft() * ((AmmoType) m.getType()).getDamagePerShot() * ((AmmoType) m.getType()).getRackSize();
                    m.setShotsLeft(0);
                    // non-explosive ammo can't explode
                    if (!m.getType().isExplosive()) {
                        continue;
                    }
                    damage += tmp;
                    r = new Report(6390);
                    r.subject = t.getId();
                    r.add(m.getName());
                    r.add(tmp);
                    r.newlines = 0;
                    vDesc.add(r);
                }
                hit = new HitData(loc);
                vDesc.addAll(damageEntity(t, hit, damage, true));
                break;
            case Tank.CRIT_CARGO:
                // Cargo/infantry damage
                r = new Report(6615);
                r.subject = t.getId();
                vDesc.add(r);
                Vector<Entity> passengers = t.getLoadedUnits();
                Entity target = passengers.get(Compute.randomInt(passengers.size()));
                hit = target.rollHitLocation(ToHitData.HIT_NORMAL, ToHitData.SIDE_FRONT);
                // FIXME should be original weapon damage
                vDesc.addAll(damageEntity(target, hit, 5));
                break;
            case Tank.CRIT_COMMANDER:
                if (en.crew.getOptions().booleanOption("vdni") || en.crew.getOptions().booleanOption("bvdni")) {
                    r = new Report(6191);
                    r.subject = t.getId();
                    vDesc.add(r);
                    vDesc.addAll(damageCrew(en, 1));
                } else {
                    if (en.crew.getOptions().booleanOption("pain_shunt") && !t.isCommanderHitPS()) {
                        r = new Report(6606);
                        r.subject = t.getId();
                        vDesc.add(r);
                        t.setCommanderHitPS(true);
                    } else {
                        r = new Report(6605);
                        r.subject = t.getId();
                        vDesc.add(r);
                        t.setCommanderHit(true);
                    }
                }
                // fall through here, because effects of crew stunned also apply
            case Tank.CRIT_CREW_STUNNED:
                if (en.crew.getOptions().booleanOption("vdni") || en.crew.getOptions().booleanOption("bvdni")) {
                    r = new Report(6191);
                    r.subject = t.getId();
                    vDesc.add(r);
                    vDesc.addAll(damageCrew(en, 1));
                } else {
                    if (en.crew.getOptions().booleanOption("pain_shunt")
                            || en.crew.getOptions().booleanOption("dermal_armor")) {
                        r = new Report(6186);
                        r.subject = t.getId();
                        vDesc.add(r);
                    } else {
                        t.stunCrew();
                        r = new Report(6185);
                        r.add(t.getStunnedTurns() - 1);
                        r.subject = t.getId();
                        vDesc.add(r);
                    }
                }
                break;
            case Tank.CRIT_DRIVER:
                if (en.crew.getOptions().booleanOption("vdni") || en.crew.getOptions().booleanOption("bvdni")) {
                    r = new Report(6191);
                    r.subject = t.getId();
                    vDesc.add(r);
                    vDesc.addAll(damageCrew(en, 1));
                } else {
                    if (en.crew.getOptions().booleanOption("pain_shunt") && !t.isDriverHitPS()) {
                        r = new Report(6601);
                        r.subject = t.getId();
                        vDesc.add(r);
                        t.setDriverHitPS(true);
                    } else {
                        r = new Report(6600);
                        r.subject = t.getId();
                        vDesc.add(r);
                        t.setDriverHit(true);
                    }
                }
                break;
            case Tank.CRIT_CREW_KILLED:
                if (en.crew.getOptions().booleanOption("vdni") || en.crew.getOptions().booleanOption("bvdni")) {
                    r = new Report(6191);
                    r.subject = t.getId();
                    vDesc.add(r);
                    vDesc.addAll(damageCrew(en, 1));
                } else {
                    if (en.crew.getOptions().booleanOption("pain_shunt") && !t.isCrewHitPS()) {
                        r = new Report(6191);
                        r.subject = t.getId();
                        vDesc.add(r);
                        t.setCrewHitPS(true);
                    } else {
                        r = new Report(6190);
                        r.subject = t.getId();
                        vDesc.add(r);
                        t.getCrew().setDoomed(true);
                    }
                }
                break;
            case Tank.CRIT_ENGINE:
                r = new Report(6210);
                r.subject = t.getId();
                vDesc.add(r);
                t.engineHit();
                t.engineHitsThisRound++;
                boolean engineExploded = checkEngineExplosion(t, vDesc, 1);
                if (engineExploded) {
                    vDesc.addAll(destroyEntity(en, "engine destruction", true, true));
                }

                if (t instanceof VTOL) {
                    PilotingRollData psr = t.getBasePilotingRoll();
                    IHex hex = game.getBoard().getHex(t.getPosition());
                    psr.addModifier(4, "forced landing");
                    int elevation = Math.max(hex.terrainLevel(Terrains.BLDG_ELEV), hex.terrainLevel(Terrains.BRIDGE_ELEV));
                    elevation = Math.max(elevation, 0);
                    elevation = Math.min(elevation, t.getElevation());
                    if (t.getElevation() > elevation) {
                        if (!hex.containsTerrain(Terrains.FUEL_TANK) && !hex.containsTerrain(Terrains.JUNGLE) && !hex.containsTerrain(Terrains.MAGMA) && !hex.containsTerrain(Terrains.MUD) && !hex.containsTerrain(Terrains.RUBBLE) && !hex.containsTerrain(Terrains.WATER) && !hex.containsTerrain(Terrains.WOODS)) {
                            r = new Report(2180);
                            r.subject = t.getId();
                            r.addDesc(t);
                            r.add(psr.getLastPlainDesc(), true);
                            vDesc.add(r);

                            // roll
                            final int diceRoll = Compute.d6(2);
                            r = new Report(2185);
                            r.subject = t.getId();
                            r.add(psr.getValueAsString());
                            r.add(psr.getDesc());
                            r.add(diceRoll);
                            if (diceRoll < psr.getValue()) {
                                r.choose(false);
                                vDesc.add(r);
                                vDesc.addAll(crashVTOLorWiGE(t));
                            } else {
                                r.choose(true);
                                vDesc.add(r);
                                t.setElevation(elevation);
                            }
                        } else {
                            vDesc.addAll(crashVTOLorWiGE(t));
                        }
                    }
                }
                break;
            case Tank.CRIT_FUEL_TANK:
                r = new Report(6215);
                r.subject = t.getId();
                vDesc.add(r);
                vDesc.addAll(destroyEntity(t, "fuel explosion", false, false));
                break;
            case Tank.CRIT_SENSOR:
                r = new Report(6620);
                r.subject = t.getId();
                vDesc.add(r);
                t.setSensorHits(t.getSensorHits() + 1);
                break;
            case Tank.CRIT_STABILIZER:
                r = new Report(6625);
                r.subject = t.getId();
                vDesc.add(r);
                t.setStabiliserHit(loc);
                break;
            case Tank.CRIT_TURRET_DESTROYED:
                r = new Report(6630);
                r.subject = t.getId();
                vDesc.add(r);
                t.destroyLocation(Tank.LOC_TURRET);
                vDesc.addAll(destroyEntity(t, "turret blown off", true, true));
                break;
            case Tank.CRIT_TURRET_JAM:
                if (t.isTurretEverJammed()) {
                    r = new Report(6640);
                    r.subject = t.getId();
                    vDesc.add(r);
                    t.lockTurret();
                    break;
                }
                r = new Report(6635);
                r.subject = t.getId();
                vDesc.add(r);
                t.jamTurret();
                break;
            case Tank.CRIT_TURRET_LOCK:
                r = new Report(6640);
                r.subject = t.getId();
                vDesc.add(r);
                t.lockTurret();
                break;
            case Tank.CRIT_WEAPON_DESTROYED: {
                r = new Report(6305);
                r.subject = t.getId();
                ArrayList<Mounted> weapons = new ArrayList<Mounted>();
                for (Mounted weap : t.getWeaponList()) {
                    if ((weap.getLocation() == loc) && !weap.isHit() && !weap.isDestroyed()) {
                        weapons.add(weap);
                    }
                }
                // sort weapons by BV
                Collections.sort(weapons, new WeaponComparator());
                int roll = Compute.d6();
                Mounted weapon;
                if (roll < 4) {
                    // defender should choose, we'll just use the lowest BV
                    // weapon
                    weapon = weapons.get(weapons.size() - 1);
                } else {
                    // attacker chooses, we'll use the highest BV weapon
                    weapon = weapons.get(0);
                }
                weapon.setHit(true);
                r.add(weapon.getName());
                vDesc.add(r);
                // explosive weapons e.g. gauss now explode
                vDesc.addAll(explodeEquipment(t, loc, weapon));
                weapon.setDestroyed(true);
                break;
            }
            case Tank.CRIT_WEAPON_JAM: {
                r = new Report(6645);
                r.subject = t.getId();
                ArrayList<Mounted> weapons = new ArrayList<Mounted>();
                for (Mounted weap : t.getWeaponList()) {
                    if ((weap.getLocation() == loc) && !weap.isJammed() && !weap.isHit() && !weap.isDestroyed()) {
                        weapons.add(weap);
                    }
                }
                Mounted weapon = weapons.get(Compute.randomInt(weapons.size()));
                weapon.setJammed(true);
                t.addJammedWeapon(weapon);
                r.add(weapon.getName());
                vDesc.add(r);
                break;
            }
            case VTOL.CRIT_PILOT:
                r = new Report(6650);
                r.subject = t.getId();
                vDesc.add(r);
                t.setDriverHit(true);
                PilotingRollData psr = t.getBasePilotingRoll();
                psr.addModifier(0, "pilot injury");
                if (!doSkillCheckInPlace(t, psr)) {
                    r = new Report(6675);
                    r.subject = t.getId();
                    r.addDesc(t);
                    vDesc.add(r);
                    boolean crash = true;
                    if (t.canGoDown()) {
                        t.setElevation(t.getElevation() - 1);
                        crash = !t.canGoDown();
                    }
                    if (crash) {
                        vDesc.addAll(crashVTOLorWiGE(t));
                    }
                }
                break;
            case VTOL.CRIT_COPILOT:
                r = new Report(6655);
                r.subject = t.getId();
                vDesc.add(r);
                t.setCommanderHit(true);
                break;
            case VTOL.CRIT_ROTOR_DAMAGE: {
                r = new Report(6660);
                r.subject = t.getId();
                vDesc.add(r);
                int mp = t.getOriginalWalkMP();
                if (mp > 1) {
                    t.setOriginalWalkMP(mp - 1);
                } else if (mp == 1) {
                    t.setOriginalWalkMP(0);
                    vDesc.addAll(crashVTOLorWiGE(t));
                }
                break;
            }
            case VTOL.CRIT_ROTOR_DESTROYED:
                r = new Report(6670);
                r.subject = t.getId();
                vDesc.add(r);
                t.immobilize();
                t.destroyLocation(VTOL.LOC_ROTOR);
                vDesc.addAll(crashVTOLorWiGE(t));
                break;
            case VTOL.CRIT_FLIGHT_STABILIZER:
                r = new Report(6665);
                r.subject = t.getId();
                vDesc.add(r);
                t.setStabiliserHit(VTOL.LOC_ROTOR);
                break;
            }
        } else if (en instanceof Aero) {
            Aero a = (Aero) en;

            Jumpship js = new Jumpship();
            if (en instanceof Jumpship) {
                js = (Jumpship) en;
            } else {
                js = null;
            }

            switch (cs.getIndex()) {
            case Aero.CRIT_NONE:
                // no effect
                r = new Report(6005);
                r.subject = a.getId();
                r.newlines = 0;
                vDesc.add(r);
                break;
            case Aero.CRIT_FCS:
                // Fire control system
                r = new Report(9105);
                r.subject = a.getId();
                r.newlines = 0;
                vDesc.add(r);
                a.setFCSHits(a.getFCSHits() + 1);
                break;
            case Aero.CRIT_SENSOR:
                // sensors
                r = new Report(6620);
                r.subject = a.getId();
                r.newlines = 0;
                vDesc.add(r);
                a.setSensorHits(a.getSensorHits() + 1);
                break;
            case Aero.CRIT_AVIONICS:
                // avionics
                r = new Report(9110);
                r.subject = a.getId();
                r.newlines = 0;
                vDesc.add(r);
                a.setAvionicsHits(a.getAvionicsHits() + 1);
                if(a.isPartOfFighterSquadron()) {
                    game.addControlRoll(new PilotingRollData(a.getTransportId(), 1, "avionics hit"));
                } else if(a.isCapitalFighter()) {
                    game.addControlRoll(new PilotingRollData(a.getId(), 1, "avionics hit"));
                } else {
                    game.addControlRoll(new PilotingRollData(a.getId(), 0, "avionics hit"));
                }
                break;
            case Aero.CRIT_CONTROL:
                // force control roll
                r = new Report(9115);
                r.subject = a.getId();
                r.newlines = 0;
                vDesc.add(r);
                if(a.isPartOfFighterSquadron()) {
                    game.addControlRoll(new PilotingRollData(a.getTransportId(), 1, "critical hit"));
                } else if(a.isCapitalFighter()) {
                    game.addControlRoll(new PilotingRollData(a.getId(), 1, "critical hit"));
                } else {
                    game.addControlRoll(new PilotingRollData(a.getId(), 0, "critical hit"));
                }
                break;
            case Aero.CRIT_FUEL_TANK:
                // fuel tank
                r = new Report(9120);
                r.subject = a.getId();
                r.newlines = 0;
                int boomTarget = 9;
                if(a.isLargeCraft() && a.isClan() && game.getOptions().booleanOption("stratops_harjel")) {
                    boomTarget = 11;
                }
                // check for possible explosion
                int fuelroll = Compute.d6(2);
                if (fuelroll > boomTarget) {
                    r.choose(true);
                    vDesc.add(r);
                    vDesc.addAll(destroyEntity(a, "fuel explosion", false, false));
                } else {
                    r.choose(false);
                    vDesc.add(r);
                }
                break;
            case Aero.CRIT_CREW:
                // pilot hit
                r = new Report(6650);
                if (en.crew.getOptions().booleanOption("dermal_armor")) {
                    r = new Report(6651);
                    r.subject = a.getId();
                    vDesc.add(r);
                    break;
                }
                if ((a instanceof SmallCraft) || (a instanceof Jumpship)) {
                    r = new Report(9197);
                }
                if(a.isLargeCraft() && a.isClan()
                        && game.getOptions().booleanOption("stratops_harjel") && (a.getIgnoredCrewHits() < 2)) {
                    a.setIgnoredCrewHits(a.getIgnoredCrewHits() + 1);
                    r = new Report(9198);
                    r.subject = a.getId();
                    r.newlines = 1;
                    vDesc.add(r);
                    break;
                }
                r.subject = a.getId();
                r.newlines = 1;
                vDesc.add(r);
                vDesc.addAll(damageCrew(a, 1));
                // The pilot may have just expired.
                if ((a.crew.isDead() || a.crew.isDoomed()) && !a.crew.isEjected()) {
                    vDesc.addAll(destroyEntity(a, "pilot death", true, true));
                }
                break;
            case Aero.CRIT_GEAR:
                // landing gear
                r = new Report(9125);
                r.subject = a.getId();
                r.newlines = 0;
                vDesc.add(r);
                a.setGearHit(true);
                break;
            case Aero.CRIT_BOMB:
                // bomb destroyed
                // go through bomb list and choose one
                ArrayList<Mounted> bombs = new ArrayList<Mounted>();
                for (Mounted bomb : a.getBombs()) {
                    if (!bomb.isDestroyed() && bomb.getType().isHittable() && (bomb.getShotsLeft() > 0)) {
                        bombs.add(bomb);
                    }
                }
                if (bombs.size() > 0) {
                    Mounted hitbomb = bombs.get(Compute.randomInt(bombs.size()));
                    hitbomb.setShotsLeft(0);
                    hitbomb.setDestroyed(true);
                    r = new Report(9130);
                    r.subject = a.getId();
                    r.newlines = 0;
                    r.add(hitbomb.getDesc());
                    vDesc.add(r);
                } else {
                    r = new Report(9131);
                    r.subject = a.getId();
                    r.newlines = 0;
                    vDesc.add(r);
                }
                break;
            case Aero.CRIT_HEATSINK:
                // heat sink hit
                int sinksLost = 1;
                if (isCapital) {
                    sinksLost = 10;
                }
                r = new Report(9135);
                r.subject = a.getId();
                r.newlines = 0;
                r.add(sinksLost);
                vDesc.add(r);
                a.setHeatSinks(Math.max(0, a.getHeatSinks() - sinksLost));
                break;
            case Aero.CRIT_WEAPON_BROAD:
                if(a instanceof Warship) {
                    if((loc == Warship.LOC_ALS) || (loc == Warship.LOC_FLS)) {
                        loc = Warship.LOC_LBS;
                    } else if((loc == Warship.LOC_ARS) || (loc == Warship.LOC_FRS)) {
                        loc = Warship.LOC_RBS;
                    }
                }
            case Aero.CRIT_WEAPON:
                if(a.isCapitalFighter()) {
                    boolean destroyAll = false;
                    if((loc == Aero.LOC_NOSE) || (loc == Aero.LOC_AFT)) {
                        destroyAll = true;
                    }
                    if(loc == Aero.LOC_WINGS) {
                        if(a.areWingsHit()) {
                            destroyAll = true;
                        } else {
                            a.setWingsHit(true);
                        }
                    }
                    for (Mounted weap : a.getWeaponList()) {
                        if (weap.getLocation() == loc) {
                            if(destroyAll) {
                                weap.setHit(true);
                                weap.setDestroyed(true);
                            } else {
                                weap.setNWeapons(weap.getNWeapons() / 2);
                            }
                        }
                    }
                    //also destroy any ECM or BAP in this location
                    for(Mounted misc : a.getMisc()) {
                        if(misc.getType().hasFlag(MiscType.F_ECM) || misc.getType().hasFlag(MiscType.F_ANGEL_ECM)
                                || misc.getType().hasFlag(MiscType.F_BAP)) {
                            misc.setHit(true);
                            misc.setDestroyed(true);
                        }
                    }
                    r = new Report(9152);
                    r.subject = a.getId();
                    r.newlines = 0;
                    r.add(a.getLocationName(loc));
                    vDesc.add(r);
                    break;
                }
                r = new Report(9150);
                r.subject = a.getId();
                r.newlines = 0;
                ArrayList<Mounted> weapons = new ArrayList<Mounted>();
                for (Mounted weap : a.getWeaponList()) {
                    if ((weap.getLocation() == loc) && !weap.isDestroyed() && weap.getType().isHittable()) {
                        weapons.add(weap);
                    }
                }
                //add in in hittable misc equipment
                for(Mounted misc : a.getMisc()) {
                    if (misc.getType().isHittable() && (misc.getLocation() == loc) && !misc.isDestroyed()) {
                        weapons.add(misc);
                    }
                }
                if (weapons.size() > 0) {
                    Mounted weapon = weapons.get(Compute.randomInt(weapons.size()));
                    // possibly check for an ammo explosion
                    // don't allow ammo explosions on fighter squadrons
                    if (game.getOptions().booleanOption("ammo_explosions") && !(a instanceof FighterSquadron) && (weapon.getType() instanceof WeaponType)) {
                        // does it use Ammo?
                        WeaponType wtype = (WeaponType) weapon.getType();
                        if (wtype.getAmmoType() != AmmoType.T_NA) {
                            Mounted m = weapon.getLinked();
                            int ammoroll = Compute.d6(2);
                            if (ammoroll >= 10) {
                                r = new Report(9151);
                                r.subject = a.getId();
                                r.add(m.getName());
                                r.newlines = 0;
                                vDesc.add(r);
                                vDesc.addAll(explodeEquipment(a, loc, m));
                                break;
                            }
                        }
                    }
                    weapon.setHit(true);
                    r.add(weapon.getName());
                    vDesc.add(r);
                    // explosive weapons e.g. gauss now explode
                    vDesc.addAll(explodeEquipment(a, loc, weapon));
                    weapon.setDestroyed(true);
                } else {
                    r = new Report(9155);
                    r.subject = a.getId();
                    r.newlines = 0;
                    vDesc.add(r);
                }
                break;
            case Aero.CRIT_ENGINE:
                // engine hit
                r = new Report(9140);
                r.subject = a.getId();
                r.newlines = 0;
                vDesc.add(r);
                a.engineHitsThisRound++;
                boolean engineExploded = checkEngineExplosion(a, vDesc, 1);
                if (((a.getEngineHits() + 1) < a.getMaxEngineHits()) && !engineExploded) {
                    a.setEngineHits(a.getEngineHits() + 1);
                    if ((a instanceof SmallCraft) || (a instanceof Jumpship)) {
                        a.setOriginalWalkMP(Math.max(0, a.getOriginalWalkMP() - 1));
                    } else {
                        a.setOriginalWalkMP(Math.max(0, a.getOriginalWalkMP() - 2));
                    }
                } else {
                    // this engine hit puts the ASF out of commission
                    vDesc.addAll(destroyEntity(a, "engine destruction", true, true));
                }
                break;
            case Aero.CRIT_LEFT_THRUSTER:
                // thruster hit
                r = new Report(9160);
                r.subject = a.getId();
                r.newlines = 0;
                vDesc.add(r);
                a.setLeftThrustHits(a.getLeftThrustHits() + 1);
                break;
            case Aero.CRIT_RIGHT_THRUSTER:
                // thruster hit
                r = new Report(9160);
                r.subject = a.getId();
                r.newlines = 0;
                vDesc.add(r);
                a.setRightThrustHits(a.getRightThrustHits() + 1);
                break;
            case Aero.CRIT_CARGO:
                // cargo hit
                // First what percentage of the cargo did the hit destroy?
                double percentDestroyed = 0.0;
                double mult = 2.0;
                if(a.isLargeCraft() && a.isClan() && game.getOptions().booleanOption("stratops_harjel")) {
                    mult = 4.0;
                }
                if (damageCaused > 0) {
                    percentDestroyed = Math.min(damageCaused / (mult * a.getSI()), 1.0);
                }
                // did it hit cargo or units
                int roll = Compute.d6(1);
                if (roll < 4) {
                    // cargo was hit
                    // just report; no game effect
                    r = new Report(9165);
                    r.subject = a.getId();
                    r.newlines = 0;
                    r.add((int) (percentDestroyed * 100));
                    vDesc.add(r);
                } else {
                    // units were hit
                    // get a list of units
                    Vector<Entity> passengers = en.getBayLoadedUnits();
                    int unitsDestroyed = (int) Math.ceil(percentDestroyed * passengers.size());
                    r = new Report(9166);
                    r.subject = a.getId();
                    r.newlines = 0;
                    r.add(unitsDestroyed);
                    vDesc.add(r);
                    while (unitsDestroyed > 0) {
                        // redraw loaded units to make sure I don't get ones
                        // already destroyed
                        Vector<Entity> units = en.getLoadedUnits();
                        if (units.size() > 0) {
                            Entity target = units.get(Compute.randomInt(units.size()));
                            vDesc.addAll(destroyEntity(target, "cargo damage", false, false));
                        }
                        unitsDestroyed--;
                    }
                }
                break;
            case Aero.CRIT_DOOR:
                // door hit
                // choose a random bay
                String bayType = en.damageBayDoor();
                if (!bayType.equals("none")) {
                    r = new Report(9170);
                    r.subject = a.getId();
                    r.add(bayType);
                    r.newlines = 0;
                    vDesc.add(r);
                } else {
                    r = new Report(9171);
                    r.subject = a.getId();
                    r.newlines = 0;
                    vDesc.add(r);
                }
                break;
            case Aero.CRIT_DOCK_COLLAR:
                // docking collar hit
                // different effect for dropships and jumpships
                if (en instanceof Dropship) {
                    Dropship ds = (Dropship) en;
                    ds.setDamageDockCollar(true);
                    r = new Report(9175);
                    r.subject = a.getId();
                    r.newlines = 0;
                    vDesc.add(r);
                }
                if (en instanceof Jumpship) {
                    // damage the docking collar
                    if (en.damageDockCollar()) {
                        r = new Report(9176);
                        r.subject = a.getId();
                        r.newlines = 0;
                        vDesc.add(r);
                    } else {
                        r = new Report(9177);
                        r.subject = a.getId();
                        r.newlines = 0;
                        vDesc.add(r);
                    }
                }
                break;
            case Aero.CRIT_KF_BOOM:
                // KF boom hit
                // no real effect yet
                r = new Report(9180);
                r.subject = a.getId();
                r.newlines = 0;
                vDesc.add(r);
                break;
            case Aero.CRIT_CIC:
                if (js == null) {
                    break;
                }
                // CIC hit
                r = new Report(9185);
                r.subject = a.getId();
                r.newlines = 0;
                vDesc.add(r);
                js.setCICHits(js.getCICHits() + 1);
                break;
            case Aero.CRIT_KF_DRIVE:
                if (js == null) {
                    break;
                }
                // KF Drive hit
                r = new Report(9190);
                r.subject = a.getId();
                r.newlines = 0;
                vDesc.add(r);
                js.setKFIntegrity(js.getKFIntegrity() - 1);
                break;
            case Aero.CRIT_GRAV_DECK:
                if (js == null) {
                    break;
                }
                // Grave Deck hit
                r = new Report(9195);
                r.subject = a.getId();
                r.newlines = 0;
                vDesc.add(r);
                break;
            case Aero.CRIT_LIFE_SUPPORT:
                // Life Support hit
                a.setLifeSupport(false);
                r = new Report(9196);
                r.subject = a.getId();
                r.newlines = 0;
                vDesc.add(r);
                break;
            }
        } else if (en instanceof BattleArmor) {
            // We might as well handle this here.
            // However, we're considering a crit against BA as a "crew kill".
            BattleArmor ba = (BattleArmor) en;
            r = new Report(6111);
            int randomTrooper = ba.getRandomTrooper();
            ba.destroyLocation(randomTrooper);
            r.add(randomTrooper);
            r.newlines = 1;
            vDesc.add(r);
        } else if (CriticalSlot.TYPE_SYSTEM == cs.getType()) {
            // Handle critical hits on system slots.
            cs.setHit(true);
            if (en instanceof Protomech) {
                int numHit = ((Protomech) en).getCritsHit(loc);
                if ((cs.getIndex() != Protomech.SYSTEM_TORSO_WEAPON_A) && (cs.getIndex() != Protomech.SYSTEM_TORSO_WEAPON_B)) {
                    r = new Report(6225);
                    r.subject = en.getId();
                    r.indent(3);
                    r.newlines = 0;
                    r.add(Protomech.systemNames[cs.getIndex()]);
                    vDesc.addElement(r);
                }
                switch (cs.getIndex()) {
                case Protomech.SYSTEM_HEADCRIT:
                    if (2 == numHit) {
                        r = new Report(6230);
                        r.subject = en.getId();
                        r.newlines = 0;
                        vDesc.addElement(r);
                        en.destroyLocation(loc);
                    }
                    break;
                case Protomech.SYSTEM_ARMCRIT:
                    if (2 == numHit) {
                        r = new Report(6235);
                        r.subject = en.getId();
                        r.newlines = 0;
                        vDesc.addElement(r);
                        en.destroyLocation(loc);
                    }
                    break;
                case Protomech.SYSTEM_LEGCRIT:
                    if (3 == numHit) {
                        r = new Report(6240);
                        r.subject = en.getId();
                        r.newlines = 0;
                        vDesc.addElement(r);
                        en.destroyLocation(loc);
                    }
                    break;
                case Protomech.SYSTEM_TORSOCRIT:
                    if (3 == numHit) {
                        vDesc.addAll(destroyEntity(en, "torso destruction"));
                    }
                    // Torso weapon hits are secondary effects and
                    // do not occur when loading from a scenario.
                    else if (secondaryEffects) {
                        int tweapRoll = Compute.d6(1);
                        CriticalSlot newSlot = null;
                        switch (tweapRoll) {
                        case 1:
                        case 2:
                            newSlot = new CriticalSlot(CriticalSlot.TYPE_SYSTEM, Protomech.SYSTEM_TORSO_WEAPON_A);
                            vDesc.addAll(applyCriticalHit(en, Entity.NONE, newSlot, secondaryEffects));
                            break;
                        case 3:
                        case 4:
                            newSlot = new CriticalSlot(CriticalSlot.TYPE_SYSTEM, Protomech.SYSTEM_TORSO_WEAPON_B);
                            vDesc.addAll(applyCriticalHit(en, Entity.NONE, newSlot, secondaryEffects));
                            break;
                        case 5:
                        case 6:
                            // no effect
                        }
                    }
                    break;
                case Protomech.SYSTEM_TORSO_WEAPON_A:
                    Mounted weaponA = ((Protomech) en).getTorsoWeapon(true);
                    if (null != weaponA) {
                        weaponA.setHit(true);
                        r = new Report(6245);
                        r.subject = en.getId();
                        r.newlines = 0;
                        vDesc.addElement(r);
                    }
                    break;
                case Protomech.SYSTEM_TORSO_WEAPON_B:
                    Mounted weaponB = ((Protomech) en).getTorsoWeapon(false);
                    if (null != weaponB) {
                        weaponB.setHit(true);
                        r = new Report(6250);
                        r.subject = en.getId();
                        r.newlines = 0;
                        vDesc.addElement(r);
                    }
                    break;

                } // End switch( cs.getType() )

                // Shaded hits cause pilot damage.
                if (((Protomech) en).shaded(loc, numHit)) {
                    // Destroyed Protomech sections have
                    // already damaged the pilot.
                    int pHits = Protomech.POSSIBLE_PILOT_DAMAGE[loc] - ((Protomech) en).getPilotDamageTaken(loc);
                    if (Math.min(1, pHits) > 0) {
                        Report.addNewline(vDesc);
                        vDesc.addAll(damageCrew(en, 1));
                        pHits = 1 + ((Protomech) en).getPilotDamageTaken(loc);
                        ((Protomech) en).setPilotDamageTaken(loc, pHits);
                    }
                } // End have-shaded-hit

            } // End entity-is-protomech
            else {
                r = new Report(6225);
                r.subject = en.getId();
                r.indent(3);
                r.add(((Mech) en).getSystemName(cs.getIndex()));
                r.newlines = 0;
                vDesc.addElement(r);
                switch (cs.getIndex()) {
                case Mech.SYSTEM_COCKPIT:
                    // Don't kill a pilot multiple times.
                    if (Pilot.DEATH > en.getCrew().getHits()) {
                        // boink!
                        en.getCrew().setDoomed(true);
                        Report.addNewline(vDesc);
                        vDesc.addAll(destroyEntity(en, "pilot death", true));
                    }
                    break;
                case Mech.SYSTEM_ENGINE:
                    // if the slot is missing, the location was previously
                    // destroyedd and the enginehit was then counted already
                    if (!cs.isMissing()) {
                        en.engineHitsThisRound++;
                    }
                    boolean engineExploded = false;

                    int numEngineHits = 0;
                    numEngineHits += en.getHitCriticals(CriticalSlot.TYPE_SYSTEM, Mech.SYSTEM_ENGINE, Mech.LOC_CT);
                    numEngineHits += en.getHitCriticals(CriticalSlot.TYPE_SYSTEM, Mech.SYSTEM_ENGINE, Mech.LOC_RT);
                    numEngineHits += en.getHitCriticals(CriticalSlot.TYPE_SYSTEM, Mech.SYSTEM_ENGINE, Mech.LOC_LT);

                    engineExploded = checkEngineExplosion(en, vDesc, numEngineHits);
                    if (!engineExploded && (numEngineHits > 2)) {
                        // third engine hit
                        vDesc.addAll(destroyEntity(en, "engine destruction"));
                        if (game.getOptions().booleanOption("auto_abandon_unit")) {
                            vDesc.addAll(abandonEntity(en));
                        }
                    }
                    break;
                case Mech.SYSTEM_GYRO:
                    if (en.getGyroType() != Mech.GYRO_HEAVY_DUTY) {
                        int gyroHits = en.getHitCriticals(CriticalSlot.TYPE_SYSTEM, Mech.SYSTEM_GYRO, loc);
                        // check for < 3 to make sure only one PSR gets
                        // scheduled,
                        // otherwise the avoid pilot damage to-hit is too high
                        // pilot value at 3 so we end up at a total of +6
                        if ((gyroHits > 1) && (gyroHits < 3)) {
                            // gyro destroyed
                            game.addPSR(new PilotingRollData(en.getId(), TargetRoll.AUTOMATIC_FAIL, 3, "gyro destroyed"));
                        } else {
                            // first gyro hit
                            game.addPSR(new PilotingRollData(en.getId(), 3, "gyro hit"));
                        }// No check against HD Gyros.
                    } else {
                        int gyroHits = en.getHitCriticals(CriticalSlot.TYPE_SYSTEM, Mech.SYSTEM_GYRO, loc);
                        // check for < 4 to make sure only one PSR gets
                        // scheduled,
                        // otherwise the avoid pilot damage to-hit is too high
                        // pilot value at 3 so we end up at a total of +6
                        if ((gyroHits > 2) && (gyroHits < 4)) {
                            // gyro destroyed
                            game.addPSR(new PilotingRollData(en.getId(), TargetRoll.AUTOMATIC_FAIL, 1, "gyro destroyed"));
                        } else if (gyroHits == 1) {
                            // first gyro hit
                            game.addPSR(new PilotingRollData(en.getId(), 2, "gyro hit"));
                        } else {
                            // second gyro hit
                            game.addPSR(new PilotingRollData(en.getId(), 3, "gyro hit"));
                        }
                    }
                    break;
                case Mech.ACTUATOR_UPPER_LEG:
                case Mech.ACTUATOR_LOWER_LEG:
                case Mech.ACTUATOR_FOOT:
                    // leg/foot actuator piloting roll
                    game.addPSR(new PilotingRollData(en.getId(), 1, "leg/foot actuator hit"));
                    break;
                case Mech.ACTUATOR_HIP:
                    // hip piloting roll
                    game.addPSR(new PilotingRollData(en.getId(), 2, "hip actuator hit"));
                    break;
                }

            } // End entity-is-mek

        } // End crit-on-system-slot

        // Handle critical hits on equipment slots.
        else if (CriticalSlot.TYPE_EQUIPMENT == cs.getType()) {
            cs.setHit(true);
            Mounted mounted = en.getEquipment(cs.getIndex());
            EquipmentType eqType = mounted.getType();
            boolean hitBefore = mounted.isHit();

            r = new Report(6225);
            r.subject = en.getId();
            r.indent(3);
            r.add(mounted.getDesc());
            r.newlines = 0;
            vDesc.addElement(r);

            // Shield objects are not useless when they take one crit.
            // Shields can be critted and still be usable.
            if ((eqType instanceof MiscType) && ((MiscType) eqType).isShield()) {
                mounted.setHit(false);
            } else {
                mounted.setHit(true);
            }

            if ((eqType instanceof MiscType) && eqType.hasFlag(MiscType.F_HARJEL)) {
                r = new Report(6254);
                r.subject = en.getId();
                r.indent(2);
                vDesc.add(r);
                vDesc.addAll(breachLocation(en, loc, null, true));
            }

            // If the item is the ECM suite of a Mek Stealth system
            // then it's destruction turns off the stealth.
            if (!hitBefore && (eqType instanceof MiscType) && eqType.hasFlag(MiscType.F_ECM) && (mounted.getLinkedBy() != null)) {
                Mounted stealth = mounted.getLinkedBy();
                r = new Report(6255);
                r.subject = en.getId();
                r.indent(2);
                r.add(stealth.getType().getName());
                r.newlines = 0;
                vDesc.addElement(r);
                stealth.setMode("Off");
            }

            // Handle equipment explosions.
            // Equipment explosions are secondary effects and
            // do not occur when loading from a scenario.
            if (((secondaryEffects && eqType.isExplosive()) || mounted.isHotLoaded() || mounted.hasChargedCapacitor()) && !hitBefore) {
                vDesc.addAll(explodeEquipment(en, loc, mounted));
            }

            // Make sure that ammo in this slot is exhaused.
            if (mounted.getShotsLeft() > 0) {
                mounted.setShotsLeft(0);
            }

        } // End crit-on-equipment-slot
        // mechs with TSM hit by anti-tsm missiles this round get another crit
        if ((en instanceof Mech) && en.hitThisRoundByAntiTSM) {
            Mech mech = (Mech) en;
            if (mech.hasTSM()) {
                r = new Report(6430);
                r.subject = en.getId();
                r.indent(2);
                r.addDesc(en);
                r.newlines = 0;
                vDesc.addElement(r);
                vDesc.addAll(oneCriticalEntity(en, Compute.d6(2)));
            }
            en.hitThisRoundByAntiTSM = false;
        }

        // if using buffered VDNI then a possible pilot hit
        if (en.crew.getOptions().booleanOption("bvdni") && !en.crew.getOptions().booleanOption("pain_shunt")) {
            Report.addNewline(vDesc);
            int roll = Compute.d6(2);
            r = new Report(3580);
            r.subject = en.getId();
            r.addDesc(en);
            r.add(7);
            r.add(roll);
            r.choose(roll >= 8);
            r.indent(2);
            vDesc.add(r);
            if (roll >= 7) {
                vDesc.addAll(damageCrew(en, 1));
            }
        }
View Full Code Here

     *            falls
     * @return a <code>Vector<Report></code> of Reports.
     */
    private Vector<Report> crashVTOLorWiGE(Tank en, boolean sideSlipCrash, int hexesMoved, Coords crashPos, int crashElevation, int impactSide) {
        Vector<Report> vDesc = new Vector<Report>();
        Report r;

        // we might be off the board after a DFA, so return then
        if (!game.getBoard().contains(crashPos)) {
            return vDesc;
        }

        if (!sideSlipCrash) {
            // report lost movement and crashing
            r = new Report(6260);
            r.subject = en.getId();
            r.newlines = 0;
            r.addDesc(en);
            vDesc.addElement(r);
            int newElevation = 0;
            IHex fallHex = game.getBoard().getHex(crashPos);

            // May land on roof of building or bridge
            if (fallHex.containsTerrain(Terrains.BLDG_ELEV)) {
                newElevation = fallHex.terrainLevel(Terrains.BLDG_ELEV);
            } else if (fallHex.containsTerrain(Terrains.BRIDGE_ELEV)) {
                newElevation = fallHex.terrainLevel(Terrains.BRIDGE_ELEV);
                if (newElevation > crashElevation) {
                    newElevation = 0; // vtol was under bridge already
                }
            }

            int fall = crashElevation - newElevation;
            if (fall == 0) {
                // already on ground, no harm done
                r = new Report(6265);
                r.subject = en.getId();
                vDesc.addElement(r);
                return vDesc;
            }
            // set elevation 1st to avoid multiple crashes
            en.setElevation(newElevation);

            // plummets to ground
            r = new Report(6270);
            r.subject = en.getId();
            r.add(fall);
            vDesc.addElement(r);

            // facing after fall
            String side;
            int table;
            int facing = Compute.d6();
            switch (facing) {
            case 1:
            case 2:
                side = "right side";
                table = ToHitData.SIDE_RIGHT;
                break;
            case 3:
                side = "rear";
                table = ToHitData.SIDE_REAR;
                break;
            case 4:
            case 5:
                side = "left side";
                table = ToHitData.SIDE_LEFT;
                break;
            case 0:
            default:
                side = "front";
                table = ToHitData.SIDE_FRONT;
            }

            if (newElevation <= 0) {
                boolean waterFall = fallHex.containsTerrain(Terrains.WATER);
                if (waterFall && fallHex.containsTerrain(Terrains.ICE)) {
                    int roll = Compute.d6(1);
                    r = new Report(2119);
                    r.subject = en.getId();
                    r.addDesc(en);
                    r.add(roll);
                    r.subject = en.getId();
                    vDesc.add(r);
                    if (roll > 3) {
                        vDesc.addAll(resolveIceBroken(crashPos));
                    } else {
                        waterFall = false; // saved by ice
                    }
                }
                if (waterFall) {
                    // falls into water and is destroyed
                    r = new Report(6275);
                    r.subject = en.getId();
                    vDesc.addElement(r);
                    vDesc.addAll(destroyEntity(en, "Fell into water", false, false));
                    // not sure, is this salvagable?
                }
            }

            // calculate damage for hitting the surface
            int damage = (int) Math.round(en.getWeight() / 10.0) * (fall + 1);

            // adjust damage for gravity
            damage = Math.round(damage * game.getPlanetaryConditions().getGravity());
            // report falling
            r = new Report(6280);
            r.subject = en.getId();
            r.indent();
            r.addDesc(en);
            r.add(side);
            r.add(damage);
            r.newlines = 0;
            vDesc.addElement(r);

            en.setFacing((en.getFacing() + (facing - 1)) % 6);

            boolean exploded = false;

            // standard damage loop
            while (damage > 0) {
                int cluster = Math.min(5, damage);
                HitData hit = en.rollHitLocation(ToHitData.HIT_NORMAL, table);
                hit.setGeneralDamageType(HitData.DAMAGE_PHYSICAL);
                int ISBefore[] = { en.getInternal(Tank.LOC_FRONT), en.getInternal(Tank.LOC_RIGHT), en.getInternal(Tank.LOC_LEFT), en.getInternal(Tank.LOC_REAR) };// hack?
                vDesc.addAll(damageEntity(en, hit, cluster));
                int ISAfter[] = { en.getInternal(Tank.LOC_FRONT), en.getInternal(Tank.LOC_RIGHT), en.getInternal(Tank.LOC_LEFT), en.getInternal(Tank.LOC_REAR) };
                for (int x = 0; x <= 3; x++) {
                    if (ISBefore[x] != ISAfter[x]) {
                        exploded = true;
                    }
                }
                damage -= cluster;
            }
            if (exploded) {
                r = new Report(6285);
                r.subject = en.getId();
                r.addDesc(en);
                vDesc.addElement(r);
                vDesc.addAll(explodeVTOLorWiGE(en));
            }

            // check for location exposure
            vDesc.addAll(doSetLocationsExposure(en, fallHex, false, newElevation));

        } else {
            en.setElevation(0);// considered landed in the hex.
            // crashes into ground thanks to sideslip
            r = new Report(6290);
            r.subject = en.getId();
            r.addDesc(en);
            vDesc.addElement(r);
            int damage = (int) Math.round(en.getWeight() / 10.0) * (hexesMoved + 1);
            boolean exploded = false;

            // standard damage loop
            while (damage > 0) {
                int cluster = Math.min(5, damage);
                HitData hit = en.rollHitLocation(ToHitData.HIT_NORMAL, impactSide);
                hit.setGeneralDamageType(HitData.DAMAGE_PHYSICAL);
                int ISBefore[] = { en.getInternal(Tank.LOC_FRONT), en.getInternal(Tank.LOC_RIGHT), en.getInternal(Tank.LOC_LEFT), en.getInternal(Tank.LOC_REAR) };// hack?
                vDesc.addAll(damageEntity(en, hit, cluster));
                int ISAfter[] = { en.getInternal(Tank.LOC_FRONT), en.getInternal(Tank.LOC_RIGHT), en.getInternal(Tank.LOC_LEFT), en.getInternal(Tank.LOC_REAR) };
                for (int x = 0; x <= 3; x++) {
                    if (ISBefore[x] != ISAfter[x]) {
                        exploded = true;
                    }
                }
                damage -= cluster;
            }
            if (exploded) {
                r = new Report(6295);
                r.subject = en.getId();
                r.addDesc(en);
                vDesc.addElement(r);
                vDesc.addAll(explodeVTOLorWiGE(en));
            }

        }
View Full Code Here

     *            The <code>VTOL</code> to explode.
     * @return a <code>Vector</code> of reports
     */
    private Vector<Report> explodeVTOLorWiGE(Tank en) {
        Vector<Report> vDesc = new Vector<Report>();
        Report r;

        if (en.getEngine().isFusion()) {
            // fusion engine, no effect
            r = new Report(6300);
            r.subject = en.getId();
            vDesc.addElement(r);
        } else {
            Coords pos = en.getPosition();
            IHex hex = game.getBoard().getHex(pos);
View Full Code Here

     *            the <code>int</code> modifier to the critroll
     * @return a <code>Vector<Report></code> containing the phasereports
     */
    private Vector<Report> criticalTank(Tank t, int loc, int critMod) {
        Vector<Report> vDesc = new Vector<Report>();
        Report r;

        // roll the critical
        r = new Report(6305);
        r.subject = t.getId();
        r.indent(2);
        r.add(t.getLocationAbbr(loc));
        r.newlines = 0;
        vDesc.add(r);
        int roll = Compute.d6(2);
        r = new Report(6310);
        r.subject = t.getId();
        String rollString = "";
        if (critMod != 0) {
            rollString = "(" + roll;
            if (critMod > 0) {
                rollString += "+";
            }
            rollString += critMod + ") = ";
            roll += critMod;
        }
        rollString += roll;
        r.add(rollString);
        r.newlines = 0;
        vDesc.add(r);

        // now look up on vehicle crits table
        int critType = t.getCriticalEffect(roll, loc);
View Full Code Here

     * @return
     */
    private void checkAeroCrits(Vector<Report> vDesc, Aero a, HitData hit, int damage_orig,
                boolean critThresh, boolean critSI, boolean ammoExplosion, boolean nukeS2S) {

        Report r;

        boolean isCapital = hit.isCapital();
        // get any capital missile critical mods
        int CapitalMissile = hit.getCapMisCritMod();

         //check for nuclear critical
        if(nukeS2S) {
            //add a control roll
            PilotingRollData nukePSR = new PilotingRollData( a.getId(), 4, "Nuclear attack", false);
            game.addControlRoll(nukePSR);

            //need some kind of report
            int nukeroll = Compute.d6(2);
            r = new Report(9145);
            r.subject = a.getId();
            r.newlines = 0;
            r.indent(3);
            r.add(CapitalMissile);
            r.add(nukeroll);
            vDesc.add(r);
            if(nukeroll >= CapitalMissile) {
                int nukeDamage = damage_orig;
                a.setSI(a.getSI()-nukeDamage);
                a.damageThisPhase += nukeDamage;
                r = new Report(9146);
                r.subject = a.getId();
                r.newlines = 0;
                r.add(nukeDamage);
                r.add(Math.max(a.getSI(),0));
                vDesc.addElement(r);
                if(a.getSI() <= 0) {
                    vDesc.addAll( destroyEntity(a,"structural integrity collapse"));
                    a.setSI(0);
                } else if(!critSI) {
                    critSI = true;
                }
            } else {
                r = new Report(9147);
                r.subject = a.getId();
                r.newlines = 0;
                vDesc.addElement(r);
            }
        }
View Full Code Here

        }
    }

    private Vector<Report> criticalAero(Aero a, int loc, int critMod, String reason, int target, int damage, boolean isCapital) {
        Vector<Report> vDesc = new Vector<Report>();
        Report r;

        // roll the critical
        r = new Report(9100);
        r.subject = a.getId();
        r.add(reason);
        r.indent(3);
        r.newlines = 0;
        vDesc.add(r);
        int roll = Compute.d6(2);
        r = new Report(9101);
        r.subject = a.getId();
        r.add(target);
        String rollString = "";
        if (critMod != 0) {
            rollString = "(" + roll;
            if (critMod > 0) {
                rollString += "+";
            }
            rollString += critMod + ") = ";
            roll += critMod;
        }
        rollString += roll;
        r.add(rollString);
        r.newlines = 0;
        vDesc.add(r);

        // now look up on vehicle crits table
        int critType = a.getCriticalEffect(roll, target);
View Full Code Here

        if (en instanceof Aero) {
            return criticalAero((Aero) en, loc, critMod, "unknown", 8, -1, isCapital);
        }
        CriticalSlot slot = null;
        Vector<Report> vDesc = new Vector<Report>();
        Report r;
        Coords coords = en.getPosition();
        IHex hex = null;
        int hits;
        if (rollNumber) {
            if (null != coords) {
                hex = game.getBoard().getHex(coords);
            }
            r = new Report(6305);
            r.subject = en.getId();
            r.indent(2);
            r.add(en.getLocationAbbr(loc));
            r.newlines = 0;
            vDesc.addElement(r);
            hits = 0;
            int roll = Compute.d6(2);
            r = new Report(6310);
            r.subject = en.getId();
            String rollString = "";
            // industrials get a +2 bonus on the roll
            if ((en instanceof Mech) && ((Mech)en).isIndustrial()) {
                critMod += 2;
            }
            if (critMod != 0) {
                rollString = "(" + roll;
                if (critMod > 0) {
                    rollString += "+";
                }
                rollString += critMod + ") = ";
                roll += critMod;
            }
            rollString += roll;
            r.add(rollString);
            r.newlines = 0;
            vDesc.addElement(r);
            if (roll <= 7) {
                // no effect
                r = new Report(6005);
                r.subject = en.getId();
                r.newlines = 0;
                vDesc.addElement(r);
                return vDesc;
            } else if ((roll >= 8) && (roll <= 9)) {
                hits = 1;
                r = new Report(6315);
                r.subject = en.getId();
                r.newlines = 0;
                vDesc.addElement(r);
            } else if ((roll >= 10) && (roll <= 11)) {
                hits = 2;
                r = new Report(6320);
                r.subject = en.getId();
                r.newlines = 0;
                vDesc.addElement(r);
            } else if (roll >= 12) {
                if (en instanceof Protomech) {
                    hits = 3;
                    r = new Report(6325);
                    r.subject = en.getId();
                    r.newlines = 0;
                    vDesc.addElement(r);
                } else if (en.locationIsLeg(loc)) {

                    CriticalSlot cs = en.getCritical(loc, 0);
                    if ((cs != null) && cs.isArmored()) {
                        r = new Report(6700);
                        r.subject = en.getId();
                        r.add(en.getLocationName(loc));
                        r.newlines = 0;
                        vDesc.addElement(r);
                        cs.setArmored(false);
                        return vDesc;
                    }
                    // limb blown off
                    r = new Report(6120);
                    r.subject = en.getId();
                    r.add(en.getLocationName(loc));
                    r.newlines = 0;
                    vDesc.addElement(r);
                    if (en.getInternal(loc) > 0) {
                        en.destroyLocation(loc);
                    }
                    if (null != hex) {
                        if (!hex.containsTerrain(Terrains.LEGS)) {
                            hex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.LEGS, 1));
                        } else {
                            hex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.LEGS, hex.terrainLevel(Terrains.LEGS) + 1));
                        }
                    }
                    sendChangedHex(en.getPosition());
                    return vDesc;
                } else if ((loc == Mech.LOC_RARM) || (loc == Mech.LOC_LARM)) {
                    CriticalSlot cs = en.getCritical(loc, 0);
                    if ((cs != null) && cs.isArmored()) {
                        r = new Report(6700);
                        r.subject = en.getId();
                        r.add(en.getLocationName(loc));
                        r.newlines = 0;
                        vDesc.addElement(r);
                        cs.setArmored(false);
                        return vDesc;
                    }

                    // limb blown off
                    r = new Report(6120);
                    r.subject = en.getId();
                    r.add(en.getLocationName(loc));
                    r.newlines = 0;
                    vDesc.addElement(r);
                    en.destroyLocation(loc);
                    if (null != hex) {
                        if (!hex.containsTerrain(Terrains.ARMS)) {
                            hex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.ARMS, 1));
                        } else {
                            hex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.ARMS, hex.terrainLevel(Terrains.ARMS) + 1));
                        }
                    }
                    sendChangedHex(en.getPosition());
                    return vDesc;
                } else if (loc == Mech.LOC_HEAD) {
                    // head blown off
                    r = new Report(6330);
                    r.subject = en.getId();
                    r.add(en.getLocationName(loc));
                    r.newlines = 0;
                    vDesc.addElement(r);
                    en.destroyLocation(loc);
                    if (((Mech) en).getCockpitType() != Mech.COCKPIT_TORSO_MOUNTED) {
                        // Don't kill a pilot multiple times.
                        if (Pilot.DEATH > en.getCrew().getHits()) {
                            en.crew.setDoomed(true);
                            Report.addNewline(vDesc);
                            vDesc.addAll(destroyEntity(en, "pilot death", true));
                        }
                    }
                    return vDesc;
                } else {
                    // torso hit
                    hits = 3;
                    // industrials get 4 crits on a modified result of 14
                    if ((roll >= 14) && (en instanceof Mech) && ((Mech)en).isIndustrial()) {
                        hits = 4;
                    }
                    r = new Report(6325);
                    r.subject = en.getId();
                    r.newlines = 0;
                    vDesc.addElement(r);
                }
            }
        } else {
            hits = 1;
        }

        // transfer criticals, if needed
        while ((hits > 0) && en.canTransferCriticals(loc) && (en.getTransferLocation(loc) != Entity.LOC_DESTROYED) && (en.getTransferLocation(loc) != Entity.LOC_NONE)) {
            loc = en.getTransferLocation(loc);
            r = new Report(6335);
            r.subject = en.getId();
            r.indent(3);
            r.add(en.getLocationAbbr(loc));
            r.newlines = 0;
            vDesc.addElement(r);
        }

        // Roll critical hits in this location.
        while (hits > 0) {

            // Have we hit all available slots in this location?
            if (en.getHittableCriticals(loc) <= 0) {
                r = new Report(6340);
                r.subject = en.getId();
                r.indent(3);
                r.newlines = 0;
                vDesc.addElement(r);
                break;
            }

            // Randomly pick a slot to be hit.
            int slotIndex = Compute.randomInt(en.getNumberOfCriticals(loc));
            slot = en.getCritical(loc, slotIndex);

            // Ignore empty or unhitable slots (this
            // includes all previously hit slots).

            if ((slot != null) && slot.isHittable()) {

                if (slot.isArmored()) {
                    r = new Report(6710);
                    r.subject = en.getId();
                    r.add(en.getLocationName(loc));
                    r.newlines = 0;
                    vDesc.addElement(r);
                    slot.setArmored(false);
                    hits--;
                    continue;
                }
                // if explosive use edge
                if ((en instanceof Mech) && (en.crew.hasEdgeRemaining() && en.crew.getOptions().booleanOption("edge_when_explosion")) && (slot.getType() == CriticalSlot.TYPE_EQUIPMENT) && en.getEquipment(slot.getIndex()).getType().isExplosive()) {
                    en.crew.decreaseEdge();
                    r = new Report(6530);
                    r.subject = en.getId();
                    r.indent(3);
                    r.newlines = 0;
                    r.add(en.crew.getOptions().intOption("edge"));
                    vDesc.addElement(r);
                    continue;
                }

                // check for reactive armor
                if (en.getArmorType() == EquipmentType.T_ARMOR_REACTIVE) {
                    Mounted mount = en.getEquipment(slot.getIndex());
                    if ((mount != null) && (mount.getType() instanceof MiscType) && ((MiscType) mount.getType()).hasFlag(MiscType.F_REACTIVE)) {
                        int roll = Compute.d6(2);
                        r = new Report(6082);
                        r.subject = en.getId();
                        r.indent(3);
                        r.newlines = 0;
                        r.add(roll);
                        vDesc.addElement(r);
                        // big budda boom
                        if (roll == 2) {
                            r = new Report(6083);
                            r.subject = en.getId();
                            r.indent(3);
                            r.newlines = 0;
                            vDesc.addElement(r);
                            vDesc.addElement(r);
                            vDesc.addAll(damageEntity(en, new HitData(loc), en.getArmor(loc)));
                            if (en.hasRearArmor(loc)) {
View Full Code Here

     */
    void doMagmaDamage(Entity en, boolean eruption) {
        if ((((en.getMovementMode() == IEntityMovementMode.VTOL) && (en.getElevation() > 0)) || (en.getMovementMode() == IEntityMovementMode.HOVER) || ((en.getMovementMode() == IEntityMovementMode.WIGE) && (en.getOriginalWalkMP() > 0) && !eruption)) && !en.isImmobile()) {
            return;
        }
        Report r;
        boolean isMech = en instanceof Mech;
        if (isMech) {
            r = new Report(2405);
        } else {
            r = new Report(2400);
        }
        r.addDesc(en);
        r.subject = en.getId();
        addReport(r);
        if (isMech) {
            HitData h;
            for (int i = 0; i < en.locations(); i++) {
View Full Code Here

    /**
     * sink any entities in quicksand in the current hex
     */
    public void doSinkEntity(Entity en) {
        Report r;
        r = new Report(2445);
        r.addDesc(en);
        r.subject = en.getId();
        addReport(r);
        en.setElevation(en.getElevation() - 1);
        //if this means the entity is below the ground, then bye-bye!
        if(Math.abs(en.getElevation()) > en.getHeight()) {
View Full Code Here

TOP

Related Classes of megamek.common.Report

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.