desc.append( "\n*** " ) .append( en.getDisplayName() ) .append( " PILOT KILLED! ***" );
desc.append( "\n" ) .append( destroyEntity(en, "pilot death", true) );
    public String applyCriticalHit( Entity en, int loc, CriticalSlot cs,                                    boolean secondaryEffects ) {        StringBuffer desc = new StringBuffer();        // Handle hits on "critical slots" of tanks.        if ( en instanceof Tank ) {            Tank tank = (Tank)en;            switch ( cs.getIndex() ) {                case 1 :                    desc.append( "\n            <<<CRITICAL HIT>>> " )                        .append( "Crew stunned for 3 turns" );                    // Carried units can't unload from a stunned transport.                    // Units that escape a transport don't need to un-stun.                    tank.stunCrew();                    break;                case 2 :                    // this one's ridiculous.  the 'main weapon' jams.                    Mounted mWeap = tank.getMainWeapon();                    if (mWeap == null) {                        desc.append( "\n            No main weapon crit, " )                            .append( "because no main weapon!" );                    }                    else {                        desc.append( "\n            <<<CRITICAL HIT>>> " )                            .append( mWeap.getName() );                        int jamTurns = tank.getJammedTurns() + 1;                        if ( jamTurns > 1 ) {                            desc.append( " jams for 1 more turn (" )                                .append( jamTurns )                                 .append( " turns total)." );                        } else {                            desc.append( " jams for 1 turn." );                        }                        tank.setJammedTurns( jamTurns );                    }                    break;                case 3 :                    desc.append( "\n            <<<CRITICAL HIT>>> " )                        .append( "Engine destroyed.  Immobile." );                    tank.immobilize();                    // Does the hovercraft sink?                    // Sinking immobile hovercraft is a secondary effect                    // and does not occur when loading from a scenario.                    if ( secondaryEffects ) {                        Hex te_hex = game.board.getHex( en.getPosition() );                        if ( en.getMovementType() == Entity.MovementType.HOVER                             && te_hex.levelOf(Terrain.WATER) > 0 ) {                            desc.append( destroyEntity                                         (en, "a watery grave", false) );                        }                    }                    break;                case 4 :                    desc.append( "\n            <<<CRITICAL HIT>>> " )                        .append( "Crew killed" );                    desc.append( destroyEntity(en, "crew death", true) );                    en.getCrew().setDoomed(true);                    break;                case 5 :                    desc.append( "\n            <<<CRITICAL HIT>>> " )                        .append( "Fuel Tank / Engine Shielding Hit " )                        .append( "(Vehicle Explodes)" );                    desc.append( destroyEntity                                 (en, "fuel tank explosion", false, false) );                    en.getCrew().setDoomed(true);                    break;                case 6 :                    desc.append( "\n            <<<CRITICAL HIT>>> " )                        .append( "Power plant hit.  BOOM!" );                    desc.append( destroyEntity                                 (en, "power plant destruction",                                  false, false) );                    en.getCrew().setDoomed(true);                    break;                }        } // End entity-is-tank        // Handle critical hits on system slots.        else if ( CriticalSlot.TYPE_SYSTEM == cs.getType() ) {            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 ) {                    desc.append( "\n            <<<CRITICAL HIT>>> on " )                        .append( Protomech.systemNames[cs.getIndex()] )                        .append( "." );                }                switch (cs.getIndex()) {                case Protomech.SYSTEM_HEADCRIT:                    if (2==numHit) {                        desc.append( "\n <<<HEAD DESTROYED>>>" );                        destroyLocation(en, loc);                    }                    break;                case Protomech.SYSTEM_ARMCRIT:                    if (2==numHit) {                        desc.append( "\n <<<ARM DESTROYED>>>" );                        destroyLocation(en,loc);                    }                    break;                case Protomech.SYSTEM_LEGCRIT:                    if (3==numHit) {                        desc.append( "\n <<<LEGS DESTROYED>>>" );                        destroyLocation(en,loc);                    }                    break;                case Protomech.SYSTEM_TORSOCRIT:                    if (3==numHit) {                        desc.append( 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 );                            desc.append( applyCriticalHit(en, Entity.NONE,                                                          newSlot,                                                          secondaryEffects) );                        case 3:                        case 4:                            newSlot = new CriticalSlot                                ( CriticalSlot.TYPE_SYSTEM,                                  Protomech.SYSTEM_TORSO_WEAPON_B );                            desc.append( applyCriticalHit(en, Entity.NONE,                                                          newSlot,                                                          secondaryEffects) );                        }                    }                    break;                case Protomech.SYSTEM_TORSO_WEAPON_A:                    Mounted weaponA =( (Protomech) en ).getTorsoWeapon(true);                    if ( null != weaponA ) {                        weaponA.setHit(true);                        desc.append("\n Torso A weapon destroyed");                    }                    break;                case Protomech.SYSTEM_TORSO_WEAPON_B:                    Mounted weaponB = ( (Protomech) en ).getTorsoWeapon(false);                    if ( null != weaponB ) {                        weaponB.setHit(true);                        desc.append("\n Torso B weapon destroyed");                    }                    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 ) {                        desc.append( "\n" )                            .append( damageCrew(en, 1) );                        pHits = 1 + ((Protomech)en)                            .getPilotDamageTaken( loc );                        ((Protomech)en).setPilotDamageTaken                            ( loc, pHits );                    }                } // End have-shaded-hit            } // End entity-is-protomech            else {                desc.append( "\n            <<<CRITICAL HIT>>> on " )                    .append( Mech.systemNames[cs.getIndex()] )                    .append( "." );                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);                        desc.append( "\n*** " )                            .append( en.getDisplayName() )                            .append( " PILOT KILLED! ***" );                    }                    break;                case Mech.SYSTEM_ENGINE :                    en.engineHitsThisRound++;                    boolean engineExploded = false;                    StringBuffer descBuffer = new StringBuffer();                    if ( en.engineHitsThisRound >= 2 ) {                        engineExploded = checkEngineExplosion                            (en, descBuffer);                    }                    desc.append( descBuffer.toString() );                    if ( !engineExploded ) {                        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);                        if ( numEngineHits > 2 ) {                            // third engine hit                            desc.append( destroyEntity                                         (en, "engine destruction") );                        }                    }                    break;                case Mech.SYSTEM_GYRO :                    if (en.getHitCriticals(CriticalSlot.TYPE_SYSTEM,                                           Mech.SYSTEM_GYRO, loc) > 1) {                                // gyro destroyed                        game.addPSR( new PilotingRollData                            (en.getId(), PilotingRollData.AUTOMATIC_FAIL,                             3, "gyro destroyed") );                    } else {                                // first 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();            desc.append( "\n            <<<CRITICAL HIT>>> on " )                .append( mounted.getDesc() )                .append( "." );            mounted.setHit(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();                desc.append( "\n       " )                    .append( stealth.getType().getName() )                    .append( " will stop functioning at end of turn." );                stealth.setMode( "Off" );            }            // Handle equipment explosions.            // Equipment explosions are secondary effects and            // do not occur when loading from a scenario.            if ( secondaryEffects && eqType.isExplosive() && !hitBefore ) {                desc.append( 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        // Return the results of the damage.        return desc.toString();    }