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;