Package megamek.common

Examples of megamek.common.Aero


        if(te instanceof FighterSquadron) {
            FighterSquadron fs = (FighterSquadron)te;
            if(fs.getFighters().size() < 1) {
                return vDesc;
            }
            Aero fighter = fs.getFighter(hit.getLocation());
            HitData new_hit = fighter.rollHitLocation(ToHitData.HIT_NORMAL, ToHitData.SIDE_FRONT);
            new_hit.setBoxCars(hit.rolledBoxCars());
            new_hit.setGeneralDamageType(hit.getGeneralDamageType());
            new_hit.setCapital(hit.isCapital());
            new_hit.setCapMisCritMod(hit.getCapMisCritMod());
            new_hit.setSingleAV(hit.getSingleAV());
            return damageEntity(fighter, new_hit, damage, ammoExplosion, bFrag, damageIS, areaSatArty, throughFront, underWater, nukeS2S);
        }

        // This is good for shields if a shield absorps the hit it shouldn't
        // effect the pilot.
        // TC SRM's that hit the head do external and internal damage but its
        // one hit and shouldn't cause
        // 2 hits to the pilot.
        boolean isHeadHit = (te instanceof Mech) && (((Mech) te).getCockpitType() != Mech.COCKPIT_TORSO_MOUNTED) && (hit.getLocation() == Mech.LOC_HEAD) && ((hit.getEffect() & HitData.EFFECT_NO_CRITICALS) != HitData.EFFECT_NO_CRITICALS);

        // booleans to indicate criticals for AT2
        boolean critSI = false;
        boolean critThresh = false;

        //get the relevant damage for damage thresholding
        int threshDamage = damage;
        //weapon groups only get the damage of one weapon
        if(hit.getSingleAV() > -1) {
            threshDamage = hit.getSingleAV();
        }

        // is this capital-scale damage
        boolean isCapital = hit.isCapital();

        // check capital/standard damage
        if (isCapital && !te.isCapitalScale()) {
            damage = 10 * damage;
            threshDamage = 10 * threshDamage;
        }
        if (!isCapital && te.isCapitalScale()) {
                damage = (int)Math.round(damage / 10.0);
                threshDamage = (int)Math.round(threshDamage / 10.0);
        }

        int damage_orig = damage;

        // show Locations which have rerolled with Edge
        HitData undoneLocation = hit.getUndoneLocation();
        while (undoneLocation != null) {
            r = new Report(6500);
            r.subject = te_n;
            r.indent(2);
            r.newlines = 0;
            r.addDesc(te);
            r.add(te.getLocationAbbr(undoneLocation));
            vDesc.addElement(r);
            undoneLocation = undoneLocation.getUndoneLocation();
        } // while
        // if edge was uses, give at end overview of remainings
        if (hit.getUndoneLocation() != null) {
            r = new Report(6510);
            r.subject = te_n;
            r.indent(2);
            r.newlines = 0;
            r.addDesc(te);
            r.add(te.crew.getOptions().intOption("edge"));
            vDesc.addElement(r);
        } // if

        boolean autoEject = false;
        if (ammoExplosion) {
            if (te instanceof Mech) {
                Mech mech = (Mech) te;
                if (mech.isAutoEject()) {
                    autoEject = true;
                    vDesc.addAll(ejectEntity(te, true));
                }
            }
        }
        boolean isBattleArmor = te instanceof BattleArmor;
        boolean isPlatoon = !isBattleArmor && (te instanceof Infantry);
        boolean isFerroFibrousTarget = false;
        boolean wasDamageIS = false;
        boolean tookInternalDamage = damageIS;
        IHex te_hex = null;

        boolean hardenedArmor = false;
        boolean reflectiveArmor = false;
        boolean reactiveArmor = false;

        if ( ((te instanceof Mech) || (te instanceof Tank)) && (te.getArmorType() == EquipmentType.T_ARMOR_HARDENED)) {
            hardenedArmor = true;
        }

        if (((te instanceof Mech) || (te instanceof Tank)) && (te.getArmorType() == EquipmentType.T_ARMOR_REFLECTIVE)) {
            reflectiveArmor = true;
        }

        if (((te instanceof Mech) || (te instanceof Tank)) && (te.getArmorType() == EquipmentType.T_ARMOR_REACTIVE)) {
            reactiveArmor = true;
        }

        int crits = ((hit.getEffect() & HitData.EFFECT_CRITICAL) == HitData.EFFECT_CRITICAL) && !hardenedArmor ? 1 : 0;
        int specCrits = ((hit.getEffect() & HitData.EFFECT_CRITICAL) == HitData.EFFECT_CRITICAL) && hardenedArmor ? 1 : 0;
        HitData nextHit = null;

        // Some "hits" on a Protomech are actually misses.
        if ((te instanceof Protomech) && (hit.getLocation() == Protomech.LOC_NMISS)) {
            r = new Report(6035);
            r.subject = te_n;
            r.indent(2);
            r.newlines = 0;
            vDesc.addElement(r);
            return vDesc;
        }

        // check for critical hit/miss vs. a BA
        if ((crits > 0) && (te instanceof BattleArmor)) {
            // possible critical miss if the rerolled location isn't alive
            if ((hit.getLocation() >= te.locations()) || (te.getInternal(hit.getLocation()) <= 0)) {
                r = new Report(6037);
                r.add(hit.getLocation());
                r.subject = te_n;
                r.indent(2);
                r.newlines = 0;
                vDesc.addElement(r);
                return vDesc;
            }
            // otherwise critical hit
            r = new Report(6225);
            r.add(te.getLocationAbbr(hit));
            r.subject = te_n;
            r.indent(2);
            r.newlines = 0;
            vDesc.addElement(r);

            crits = 0;
            damage = Math.max(te.getInternal(hit.getLocation()) + te.getArmor(hit.getLocation()), damage);
        }

        if ((te.getArmor(hit) > 0) && ((te.getArmorType() == EquipmentType.T_ARMOR_FERRO_FIBROUS) || (te.getArmorType() == EquipmentType.T_ARMOR_LIGHT_FERRO) || (te.getArmorType() == EquipmentType.T_ARMOR_HEAVY_FERRO))) {
            isFerroFibrousTarget = true;
        }

        // Is the infantry in the open?
        if (isPlatoon && !te.isDestroyed()
                && !te.isDoomed() && (((Infantry) te).getDugIn() != Infantry.DUG_IN_COMPLETE)
                && !te.crew.getOptions().booleanOption("dermal_armor")) {
            te_hex = game.getBoard().getHex(te.getPosition());
            if ((te_hex != null) && !te_hex.containsTerrain(Terrains.WOODS) && !te_hex.containsTerrain(Terrains.JUNGLE) && !te_hex.containsTerrain(Terrains.ROUGH) && !te_hex.containsTerrain(Terrains.RUBBLE) && !te_hex.containsTerrain(Terrains.SWAMP) && !te_hex.containsTerrain(Terrains.BUILDING) && !te_hex.containsTerrain(Terrains.FUEL_TANK) && !te_hex.containsTerrain(Terrains.FORTIFIED) && !ammoExplosion) {
                // PBI. Damage is doubled.
                damage *= 2;
                r = new Report(6040);
                r.subject = te_n;
                r.indent(2);
                r.newlines = 0;
                vDesc.addElement(r);
            }
        }
        // Is the infantry in vacuum?
        if ((isPlatoon || isBattleArmor) && !te.isDestroyed() && !te.isDoomed()
                && game.getPlanetaryConditions().isVacuum()) {
            // PBI. Double damage.
            damage *= 2;
            r = new Report(6041);
            r.subject = te_n;
            r.indent(2);
            r.newlines = 0;
            vDesc.addElement(r);
        }
        // If dealing with fragmentation missiles,
        // it does double damage to infantry...
        // We're actually going to abuse this for AX-head warheads, too, so as
        // to not add another parameter.
        switch (bFrag) {
        case ANTI_INFANTRY:
            if(isPlatoon && te.crew.getOptions().booleanOption("dermal_armor")) {
                int reduce = Math.min(damage - 1, Compute.d6());
                damage -= reduce;
                r = new Report(6042);
                r.subject = te_n;
                r.add(reduce);
                r.add(damage);
                r.indent(2);
                r.newlines = 0;
                vDesc.addElement(r);
            }
            break;
        case FRAGMENTATION:
            if (!isPlatoon) {
                damage = 0;
                r = new Report(6050);
                r.subject = te_n;
                r.indent(2);
                r.newlines = 0;
                vDesc.addElement(r);
            }
            break;
        case FLECHETTE:
            if (!isPlatoon && !isBattleArmor) {
                damage /= 2;
                r = new Report(6060);
                r.subject = te_n;
                r.indent(2);
                r.newlines = 0;
                vDesc.addElement(r);
            } else if (isPlatoon && !isBattleArmor) {
                r = new Report(6055);
                r.subject = te_n;
                r.indent(2);
                r.newlines = 0;
                vDesc.addElement(r);
            }
            break;
        case ACID:
            if (isFerroFibrousTarget) {
                damage = te.getArmor(hit) >= 3 ? 3 : te.getArmor(hit);
                r = new Report(6061);
                r.subject = te_n;
                r.indent(2);
                r.newlines = 0;
                r.add(damage);
                vDesc.addElement(r);
            } else {
                r = new Report(6062);
                r.subject = te_n;
                r.indent(2);
                r.newlines = 0;
                vDesc.addElement(r);
            }
            break;
        case INCENDIARY:
            // Incendiary AC ammo does +2 damage to unarmoured infantry
            if (isPlatoon) {
                damage += 2;
                r = new Report(6064);
                r.subject = te_n;
                r.indent(2);
                r.newlines = 0;
                vDesc.addElement(r);
            }
            break;
        case ANTI_TSM:
            te.hitThisRoundByAntiTSM = true;
        default:
            // We can ignore this.
            break;
        }

        //check for infantry armor
    /*
        if(isPlatoon) {
            damage = (int)Math.ceil(damage / 2.0);
            r = new Report(6043);
            r.subject = te_n;
            r.indent(2);
            r.newlines = 0;
            r.add(damage);
            vDesc.addElement(r);
        }
*/

        // adjust VTOL rotor damage
        if ((te instanceof VTOL) && (hit.getLocation() == VTOL.LOC_ROTOR)) {
            damage = (damage + 9) / 10;
        }

        // save EI status, in case sensors crit destroys it
        final boolean eiStatus = te.hasActiveEiCockpit();
        // BA using EI implants receive +1 damage from attacks
        if (!(te instanceof Mech) && !(te instanceof Protomech) && eiStatus) {
            damage += 1;
        }

        // check for case on Aeros
        if (te instanceof Aero) {
            Aero a = (Aero) te;
            if (ammoExplosion && a.hasCase()) {
                // damage should be reduced by a factor of 2 for ammo explosions
                // according to p. 161, TW
                damage /= 2;
                r = new Report(9010);
                r.subject = te_n;
                r.add(damage);
                r.indent(3);
                r.newlines = 0;
                vDesc.addElement(r);
            }
        }

        // Allocate the damage
        while (damage > 0) {

            // first check for ammo explosions on aeros separately, because it
            // must be done before
            // standard to capital damage conversions
            if ((te instanceof Aero) && (hit.getLocation() == Aero.LOC_AFT) && !damageIS) {
                for (Mounted mAmmo : te.getAmmo()) {
                    if (mAmmo.isDumping() && !mAmmo.isDestroyed()
                            && !mAmmo.isHit() && !(mAmmo.getType() instanceof BombType)) {
                        // doh. explode it
                        vDesc.addAll(explodeEquipment(te, mAmmo.getLocation(), mAmmo));
                        mAmmo.setHit(true);
                    }
                }
            }

            if (te instanceof Aero) {
                // chance of a critical if damage greater than threshold
                Aero a = (Aero) te;
                if ((threshDamage > a.getThresh(hit.getLocation())) && !te.isCapitalFighter()) {
                    critThresh = true;
                    a.setCritThresh(true);
                }

                if ((threshDamage >= 2) && te.isCapitalFighter()) {
                    critThresh = true;
                    a.setCritThresh(true);
                }
            }

            //Capital fighters receive damage differently
            if (te.isCapitalFighter()) {
                Aero a = (Aero)te;
                a.setCurrentDamage(a.getCurrentDamage() + damage);
                a.setCapArmor(a.getCapArmor() - damage);
                r = new Report(9065);
                r.subject = te_n;
                r.indent(2);
                r.newlines = 0;
                r.addDesc(te);
                r.add(damage);
                vDesc.addElement(r);
                r = new Report(6085);
                r.subject = te_n;
                r.newlines = 0;
                r.add(Math.max(a.getCapArmor(), 0));
                vDesc.addElement(r);
                // check to see if this detroyed the entity
                if (a.getCapArmor() <= 0) {
                    vDesc.addAll(destroyEntity(te, "structural integrity collapse"));
                    a.setCapArmor(0);
                }
                damage = 0;
                //check for crits
                checkAeroCrits(vDesc, (Aero)te, hit, damage_orig, critThresh, critSI, ammoExplosion, nukeS2S);
                return vDesc;
            }

            if (!((te instanceof Aero) && ammoExplosion)) {
                // report something different for Aero ammo explosions
                r = new Report(6065);
                r.subject = te_n;
                r.indent(2);
                r.newlines = 0;
                r.addDesc(te);
                r.add(damage);
                if (damageIS) {
                    r.messageId = 6070;
                }
                r.add(te.getLocationAbbr(hit));
                vDesc.addElement(r);
            }

            // was the section destroyed earlier this phase?
            if (te.getInternal(hit) == IArmorState.ARMOR_DOOMED) {
                // cannot transfer a through armor crit if so
                crits = 0;
            }

            // here goes the fun :)
            // Shields take damage first then cowls then armor whee
            // Shield does not protect from ammo explosions or falls.
            if (!ammoExplosion && !hit.isFallDamage() && !damageIS && te.hasShield() && ((hit.getEffect() & HitData.EFFECT_NO_CRITICALS) != HitData.EFFECT_NO_CRITICALS)) {
                Mech me = (Mech) te;
                int damageNew = me.shieldAbsorptionDamage(damage, hit.getLocation(), hit.isRear());
                // if a shield absorbed the damage then lets tell the world
                // about it.
                if (damageNew != damage) {
                    int absorb = damage - damageNew;
                    te.damageThisPhase += absorb;
                    damage = damageNew;

                    r = new Report(3530);
                    r.subject = te_n;
                    r.indent(3);
                    r.newlines = 0;
                    r.add(absorb);
                    vDesc.addElement(r);

                    if (damage <= 0) {
                        crits = 0;
                        specCrits = 0;
                        isHeadHit = false;
                    }
                }
            }

            // Armored Cowl may absorb some damage from hit
            if (te instanceof Mech) {
                Mech me = (Mech) te;
                if (me.hasCowl() && (hit.getLocation() == Mech.LOC_HEAD) && !throughFront) {
                    int damageNew = me.damageCowl(damage);
                    int damageDiff = damage - damageNew;
                    me.damageThisPhase += damageDiff;
                    damage = damageNew;

                    r = new Report(3520);
                    r.subject = te_n;
                    r.indent(3);
                    r.newlines = 0;
                    r.add(damageDiff);
                    vDesc.addElement(r);
                }
            }

            if (!ammoExplosion && !damageIS && ((hit.getEffect() & HitData.EFFECT_NO_CRITICALS) != HitData.EFFECT_NO_CRITICALS)) {
                damage = te.getDamageReductionFromModularArmor(hit.getLocation(), damage, vDesc);
            }

            // Destroy searchlights on 7+ (torso hits on mechs)
            boolean spotlightHittable = false;
            if (te.hasSpotlight()) {
                spotlightHittable = true;
                int loc = hit.getLocation();
                if (te instanceof Mech) {
                    if ((loc != Mech.LOC_CT) && (loc != Mech.LOC_LT) && (loc != Mech.LOC_RT)) {
                        spotlightHittable = false;
                    }
                } else if (te instanceof Tank) {
                    if ((loc != Tank.LOC_FRONT) && (loc != Tank.LOC_RIGHT) && (loc != Tank.LOC_LEFT)) {
                        spotlightHittable = false;
                    }
                }
                if (spotlightHittable) {
                    int spotroll = Compute.d6(2);
                    r = new Report(6072);
                    r.indent(2);
                    r.subject = te_n;
                    r.add(spotroll);
                    vDesc.addElement(r);
                    if (spotroll >= 7) {
                        r = new Report(6071);
                        r.subject = te_n;
                        r.indent(2);
                        vDesc.addElement(r);
                        te.setSpotlightState(false);
                        te.setSpotlight(false);
                    }
                }
            }

            // Does an exterior passenger absorb some of the damage?
            if (!damageIS) {
                int nLoc = hit.getLocation();
                Entity passenger = te.getExteriorUnitAt(nLoc, hit.isRear());
                // Does an exterior passenger absorb some of the damage?
                if (!ammoExplosion && (null != passenger) && (Compute.d6() >= 5) && !passenger.isDoomed() && (bFrag != DamageType.IGNORE_PASSENGER)) {
                    // Yup. Roll up some hit data for that passenger.
                    r = new Report(6075);
                    r.subject = passenger.getId();
                    r.indent(3);
                    r.addDesc(passenger);
                    vDesc.addElement(r);

                    HitData passHit = passenger.getTrooperAtLocation(hit, te);

                    // How much damage will the passenger absorb?
                    int absorb = 0;
                    HitData nextPassHit = passHit;
                    do {
                        if (0 < passenger.getArmor(nextPassHit)) {
                            absorb += passenger.getArmor(nextPassHit);
                        }
                        if (0 < passenger.getInternal(nextPassHit)) {
                            absorb += passenger.getInternal(nextPassHit);
                        }
                        nextPassHit = passenger.getTransferLocation(nextPassHit);
                    } while ((damage > absorb) && (nextPassHit.getLocation() >= 0));

                    // Damage the passenger.
                    vDesc.addAll(damageEntity(passenger, passHit, damage));

                    // Did some damage pass on?
                    if (damage > absorb) {
                        // Yup. Remove the absorbed damage.
                        damage -= absorb;
                        r = new Report(6080);
                        r.subject = te_n;
                        r.indent(1);
                        r.add(damage);
                        r.addDesc(te);
                        vDesc.addElement(r);
                    } else {
                        // Nope. Return our description.
                        return vDesc;
                    }

                } // End nLoc-has-exterior-passenger

                boolean bTorso = (nLoc == Mech.LOC_CT) || (nLoc == Mech.LOC_RT) || (nLoc == Mech.LOC_LT);

                // Does a swarming unit absorb damage?
                int swarmer = te.getSwarmAttackerId();
                if ((!(te instanceof Mech) || bTorso) && (swarmer != Entity.NONE) && ((hit.getEffect() & HitData.EFFECT_CRITICAL) == 0) && (Compute.d6() >= 5) && (bFrag != DamageType.IGNORE_PASSENGER)) {
                    Entity swarm = game.getEntity(swarmer);
                    // Yup. Roll up some hit data for that passenger.
                    r = new Report(6076);
                    r.subject = swarmer;
                    r.indent(3);
                    r.addDesc(swarm);
                    vDesc.addElement(r);

                    HitData passHit = swarm.rollHitLocation(ToHitData.HIT_NORMAL, ToHitData.SIDE_FRONT);

                    // How much damage will the swarm absorb?
                    int absorb = 0;
                    HitData nextPassHit = passHit;
                    do {
                        if (0 < swarm.getArmor(nextPassHit)) {
                            absorb += swarm.getArmor(nextPassHit);
                        }
                        if (0 < swarm.getInternal(nextPassHit)) {
                            absorb += swarm.getInternal(nextPassHit);
                        }
                        nextPassHit = swarm.getTransferLocation(nextPassHit);
                    } while ((damage > absorb) && (nextPassHit.getLocation() >= 0));

                    // Damage the swarm.
                    vDesc.addAll(damageEntity(swarm, passHit, damage));

                    // Did some damage pass on?
                    if (damage > absorb) {
                        // Yup. Remove the absorbed damage.
                        damage -= absorb;
                        r = new Report(6080);
                        r.subject = te_n;
                        r.indent(1);
                        r.add(damage);
                        r.addDesc(te);
                        vDesc.addElement(r);
                    } else {
                        // Nope. Return our description.
                        return vDesc;
                    }
                }

                // is this a mech dumping ammo being hit in the rear torso?
                if (((te instanceof Mech) && hit.isRear() && bTorso) || ((te instanceof Tank) && (hit.getLocation() == Tank.LOC_REAR))) {
                    for (Mounted mAmmo : te.getAmmo()) {
                        if (mAmmo.isDumping() && !mAmmo.isDestroyed() && !mAmmo.isHit()) {
                            // doh. explode it
                            vDesc.addAll(explodeEquipment(te, mAmmo.getLocation(), mAmmo));
                            mAmmo.setHit(true);
                        }
                    }
                }
            }

            // is there armor in the location hit?
            if (!ammoExplosion && (te.getArmor(hit) > 0) && !damageIS) {
                int tmpDamageHold = -1;
                int origDamage = damage;

                // If the target has hardened armor, we need to adjust damage.
                if (hardenedArmor && (hit.getGeneralDamageType() != HitData.DAMAGE_ARMOR_PIERCING) && (hit.getGeneralDamageType() != HitData.DAMAGE_ARMOR_PIERCING_MISSILE)) {
                    tmpDamageHold = damage;
                    damage = (int) Math.ceil(((double) damage) / 2);
                    r = new Report(6069);
                    r.subject = te_n;
                    r.indent(2);
                    r.newlines = 0;
                    r.add(damage);
                    vDesc.addElement(r);
                } else if (isPlatoon) {
                    // infantry armour works differently
                    int armor = te.getArmor(hit);
                    int men = te.getInternal(hit);
                    tmpDamageHold = damage % 2;
                    damage /= 2;
                    if ((tmpDamageHold == 1) && (armor >= men)) {
                        // extra 1 point of damage to armor
                        tmpDamageHold = damage;
                        damage++;
                    } else {
                        // extra 0 or 1 point of damage to men
                        tmpDamageHold += damage;
                    }

                } else if (reflectiveArmor && (hit.getGeneralDamageType() == HitData.DAMAGE_PHYSICAL)) {
                    tmpDamageHold = damage;
                    damage *= 2;
                    r = new Report(6066);
                    r.subject = te_n;
                    r.indent(2);
                    r.newlines = 0;
                    r.add(damage);
                    vDesc.addElement(r);
                } else if (reflectiveArmor && (hit.getGeneralDamageType() == HitData.DAMAGE_ENERGY)) {
                    tmpDamageHold = damage;
                    damage = (int) Math.ceil(((double) damage) / 2);
                    r = new Report(6067);
                    r.subject = te_n;
                    r.indent(2);
                    r.newlines = 0;
                    r.add(damage);
                    vDesc.addElement(r);
                } else if (reactiveArmor && ( (hit.getGeneralDamageType() == HitData.DAMAGE_MISSILE) || (hit.getGeneralDamageType() == HitData.DAMAGE_ARMOR_PIERCING_MISSILE))) {
                    tmpDamageHold = damage;
                    damage = (int) Math.ceil(((double) damage) / 2);
                    r = new Report(6068);
                    r.subject = te_n;
                    r.indent(2);
                    r.newlines = 0;
                    r.add(damage);
                    vDesc.addElement(r);
                }

                if (te.getArmor(hit) >= damage) {

                    // armor absorbs all damage
                    te.setArmor(te.getArmor(hit) - damage, hit);
                    if (tmpDamageHold >= 0) {
                        te.damageThisPhase += tmpDamageHold;
                    } else {
                        te.damageThisPhase += damage;
                    }
                    damage = 0;
                    r = new Report(6085);
                    r.subject = te_n;
                    r.newlines = 0;
                    if (spotlightHittable) {
                        r.indent(3);
                    }
                    r.add(te.getArmor(hit));
                    vDesc.addElement(r);

                    // tele-missiles are destroyed if they lose all armor
                    if ((te instanceof TeleMissile) && (te.getArmor(hit) == damage)) {
                        vDesc.addAll(destroyEntity(te, "damage", false));
                    }

                } else {
                    // damage goes on to internal
                    int absorbed = Math.max(te.getArmor(hit), 0);
                    if (reflectiveArmor && (hit.getGeneralDamageType() == HitData.DAMAGE_PHYSICAL)) {
                        absorbed = (int) Math.round(Math.ceil(absorbed / 2));
                        damage = tmpDamageHold;
                        tmpDamageHold = 0;
                    }
                    te.setArmor(IArmorState.ARMOR_DESTROYED, hit);
                    if (tmpDamageHold >= 0) {
                        te.damageThisPhase += 2 * absorbed;
                    } else {
                        te.damageThisPhase += absorbed;
                    }
                    damage -= absorbed;
                    r = new Report(6090);
                    r.subject = te_n;
                    r.newlines = 0;
                    if (spotlightHittable) {
                        r.indent(3);
                    }
                    vDesc.addElement(r);
                    if (te instanceof GunEmplacement) {
                        // gun emplacements have no internal,
                        // destroy the section
                        te.destroyLocation(hit.getLocation());
                        r = new Report(6115);
                        r.subject = te_n;
                        r.newlines = 0;
                        vDesc.addElement(r);

                        if (te.getTransferLocation(hit).getLocation() == Entity.LOC_DESTROYED) {
                            vDesc.addAll(destroyEntity(te, "damage", false));
                        }
                    }
                }

                // targets with BAR armor get crits, depending on damage and BAR rating
                if (te.hasBARArmor()) {
                    if (origDamage > te.getBARRating()) {
                        if (te.hasArmoredChassis()) {
                            Report.addNewline(vDesc);
                            // crit roll with -1 mod
                            vDesc.addAll(criticalEntity(te, hit.getLocation(), -1));
                        } else {
                            Report.addNewline(vDesc);
                            vDesc.addAll(criticalEntity(te, hit.getLocation(), 0));
                        }
                    }
                }

                // If it has hardened armor, now we need to "correct" any
                // remaining damage.
                if (tmpDamageHold > 0) {
                    if (hardenedArmor) {
                        damage *= 2;
                        damage -= tmpDamageHold % 2;
                    } else if (isPlatoon) {
                        damage = tmpDamageHold;
                    }
                }
            }

            // is there damage remaining?
            if (damage > 0) {

                // if this is an Aero then I need to apply internal damage
                // to the SI after halving it. Return from here to prevent
                // further processing
                if (te instanceof Aero) {
                    Aero a = (Aero) te;

                    //check for overpenetration
                    if(game.getOptions().booleanOption("stratops_over_penetrate")) {
                        int opRoll = Compute.d6(1);
                        if((((te instanceof Jumpship) || (te instanceof SpaceStation)) && !(te instanceof Warship) && (opRoll > 3))
                                || ((te instanceof Dropship) && (opRoll > 4))
                                || ((te instanceof Warship) && (a.get0SI() <= 30) && (opRoll > 5))) {
                            //over-penetration happened
                            r = new Report(9090);
                            r.subject = te_n;
                            r.newlines = 0;
                            vDesc.addElement(r);
                            int new_loc = a.getOppositeLocation(hit.getLocation());
                            damage = Math.min(damage, te.getArmor(new_loc));
                            r = new Report(6065);
                            r.subject = te_n;
                            r.indent(2);
                            r.newlines = 0;
                            r.addDesc(te);
                            r.add(damage);
                            r.add(te.getLocationAbbr(new_loc));
                            vDesc.addElement(r);
                            te.setArmor(te.getArmor(new_loc) - damage, new_loc);
                            if((te instanceof Warship) || (te instanceof Jumpship)) {
                                damage = 1;
                            } else {
                                damage = 0;
                            }
                            //
                        }
                    }

                    // divide damage in half
                    // do not divide by half if it is an ammo exposion
                    if (!ammoExplosion && !nukeS2S) {
                        damage /= 2;
                    }

                    // this should result in a crit
                    // but only if it really did damage after rounding down
                    if (damage > 0) {
                        critSI = true;
                    }

                    // Now apply damage to the structural integrity
                    a.setSI(a.getSI() - damage);
                    te.damageThisPhase += damage;
                    // send the report
                    r = new Report(1210);
                    r.subject = te_n;
                    r.newlines = 0;
                    if (!ammoExplosion) {
                        r.messageId = 9005;
                    } else {
                        r.messageId = 9006;
                    }
                    r.add(damage);
                    r.add(Math.max(a.getSI(), 0));
                    vDesc.addElement(r);
                    damage = 0;
                    // check to see if this would destroy the ASF
                    if (a.getSI() <= 0) {
                        vDesc.addAll(destroyEntity(te, "structural integrity collapse"));
                        a.setSI(0);
                    }
                    checkAeroCrits(vDesc, a, hit, damage_orig, critThresh, critSI, ammoExplosion, nukeS2S);
                    return vDesc;
                }

View Full Code Here


                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) {
View Full Code Here

        } else {
            return false;
        }

        // must be an ASF or Small Craft
        Aero a = new Aero();
        if ((unit instanceof Aero) && !(unit instanceof Dropship) && !(unit instanceof Jumpship)) {
            a = (Aero) unit;
        } else {
            return false;
        }

        Report r;

        // Unload the unit.
        if (!unloader.unload(unit)) {
            return false;
        }

        // The unloaded unit is no longer being carried.
        unit.setTransportId(Entity.NONE);

        // Place the unloaded unit onto the screen.
        unit.setPosition(pos);

        // Units unloaded onto the screen are deployed.
        if (pos != null) {
            unit.setDeployed(true);
        }

        // Point the unloaded unit in the given direction.
        unit.setFacing(facing);
        unit.setSecondaryFacing(facing);

        // the velocity of the unloadd unit is the same as the loader
        a.setCurrentVelocity(velocity);
        a.setNextVelocity(velocity);

        // if using advanced movement then set vectors
        a.setVectors(moveVec);

        unit.setElevation(elevation);

        // it seems that the done button is still being set and I can't figure
        // out where
        unit.setDone(false);

        // if the bonus was greater than zero then too many fighters were
        // launched and they
        // must all make control rolls
        if (bonus > 0) {
            PilotingRollData psr = unit.getBasePilotingRoll();
            psr.addModifier(bonus, "safe launch rate exceeded");
            int ctrlroll = Compute.d6(2);
            r = new Report(9375);
            r.subject = unit.getId();
            r.add(unit.getDisplayName());
            r.add(psr.getValue());
            r.add(ctrlroll);
            r.newlines = 0;
            r.indent(1);
            if (ctrlroll < psr.getValue()) {
                r.choose(false);
                addReport(r);
                // damage the unit
                int damage = 10 * (psr.getValue() - ctrlroll);
                HitData hit = a.rollHitLocation(ToHitData.HIT_NORMAL, ToHitData.SIDE_FRONT);
                addReport(damageEntity(unit, hit, damage));
                // did we destroy the unit?
                if (unit.isDoomed()) {
                    // Clean out the entity.
                    unit.setDestroyed(true);
                    game.moveToGraveyard(unit.getId());
                    send(createRemoveEntityPacket(unit.getId()));
                }
            } else {
                // avoided damage
                r.choose(true);
                addReport(r);
            }
        }

        // launching from an OOC vessel causes damage
        // same thing if faster than 2 velocity in atmosphere
        if ((((Aero) unloader).isOutControlTotal() && !unit.isDoomed()) || ((((Aero) unloader).getCurrentVelocity() > 2) && game.getBoard().inAtmosphere())) {
            int damroll = Compute.d6(2);
            int damage = damroll * 10;
            r = new Report(9385);
            r.subject = unit.getId();
            r.add(unit.getDisplayName());
            r.add(damage);
            addReport(r);
            HitData hit = a.rollHitLocation(ToHitData.HIT_NORMAL, ToHitData.SIDE_FRONT);
            addReport(damageEntity(unit, hit, damage));
            // did we destroy the unit?
            if (unit.isDoomed()) {
                // Clean out the entity.
                unit.setDestroyed(true);
View Full Code Here

        r.add(target.getDisplayName());
        addReport(r);
        int partialroll = Compute.d6(1);
        boolean partial = (partialroll == 6);
        // has the target moved yet this round?
        Aero ta = (Aero) target;
        if ((target.mpUsed < target.getRunMPwithoutMASC()) && !ta.isOutControlTotal() && !target.isImmobile()) {
            // give them a control roll to avoid the collision
            // TODO: I should make this voluntary really
            PilotingRollData psr = target.getBasePilotingRoll();
            psr.addModifier(0, "avoiding collision");
            int ctrlroll = Compute.d6(2);
            r = new Report(9045);
            r.subject = target.getId();
            r.add(target.getDisplayName());
            r.add(ctrlroll);
            r.newlines = 0;
            r.indent(2);
            if (ctrlroll < psr.getValue()) {
                r.choose(false);
                addReport(r);
            } else {
                // avoided collision
                r.choose(true);
                addReport(r);
                // two possibilities:
                // 1) the target already moved, but had MP left - check for
                // control roll conditions
                // 2) the target had not yet moved, move them in straight line
                if (!target.isDone()) {
                    int vel = ta.getCurrentVelocity();
                    MovePath md = new MovePath(game, target);
                    while (vel > 0) {
                        md.addStep(MovePath.STEP_FORWARDS);
                        vel--;
                    }
                    game.removeTurnFor(target);
                    send(createTurnVectorPacket());
                    processMovement(target, md);
                    // for some reason it is not clearing out turn
                } else {
                    // what needs to get checked?
                    // this move puts them at over-thrust
                    target.moved = IEntityMovementType.MOVE_OVER_THRUST;
                    // they may have exceeded SI, only add if they hadn't
                    // exceeded it before
                    if (target.mpUsed <= ta.getSI()) {
                        PilotingRollData rollTarget = ta.checkThrustSITotal(target.getRunMPwithoutMASC(), ta.moved);
                        if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) {
                            game.addControlRoll(new PilotingRollData(ta.getId(), 0, "Thrust spent during turn exceeds SI"));
                        }
                    }
                    target.mpUsed = target.getRunMPwithoutMASC();
                }
                return false;
View Full Code Here

            doMagmaDamage(entity, false);
        }

        // set acceleration used to default
        if (entity instanceof Aero) {
            Aero a = (Aero) entity;
            a.setAccLast(false);
        }

        // iterate through steps
        firstStep = true;
        turnOver = false;
        /* Bug 754610: Revert fix for bug 702735. */
        MoveStep prevStep = null;

        Vector<UnitLocation> movePath = new Vector<UnitLocation>();

        for (final Enumeration<MoveStep> i = md.getSteps(); i.hasMoreElements();) {
            final MoveStep step = i.nextElement();
            wasProne = entity.isProne();
            boolean isPavementStep = step.isPavementStep();
            entity.inReverse = step.isThisStepBackwards();
            boolean entityFellWhileAttemptingToStand = false;

            // stop for illegal movement
            if (step.getMovementType() == IEntityMovementType.MOVE_ILLEGAL) {
                break;
            }

            // stop if the entity already killed itself
            if (entity.isDestroyed() || entity.isDoomed()) {
                break;
            }

            if (firstStep && (entity.getMovementMode() == IEntityMovementMode.WIGE) && (entity.getElevation() == 0)) {
                wigeStartedLanded = true;
            }

            // check for MASC failure on first step
            if (firstStep && (entity instanceof Mech)) {
                HashMap<Integer, CriticalSlot> crits = new HashMap<Integer, CriticalSlot>();
                Vector<Report> vReport = new Vector<Report>();
                if (((Mech) entity).checkForMASCFailure(md, vReport, crits)) {
                    addReport(vReport);
                    for (Integer loc : crits.keySet()) {
                        CriticalSlot cs = crits.get(loc);
                        addReport(applyCriticalHit(entity, loc, cs, true));
                    }
                    // do any PSR immediately
                    addReport(resolvePilotingRolls(entity));
                    game.resetPSRs(entity);
                    // let the player replot their move as MP might be changed
                    md.clear();
                    fellDuringMovement = true; // so they get a new turn
                } else {
                    addReport(vReport);
                }
            }

            // did the entity move?
            didMove = step.getDistance() > distance;

            // check for aero stuff
            if (entity instanceof Aero) {
                Aero a = (Aero) entity;
                j++;

                // TODO: change the way this check is made
                if (!didMove && (md.length() != j)) {
                    thrustUsed += step.getMp();
                } else {
                    // if this was the last move and distance was zero, then add
                    // thrust
                    if (!didMove && (md.length() == j)) {
                        thrustUsed += step.getMp();
                    }
                    // then we moved to a new hex or the last step so check
                    // conditions
                    // structural damage
                    rollTarget = a.checkThrustSI(thrustUsed, overallMoveType);
                    if ((rollTarget.getValue() != TargetRoll.CHECK_FALSE) && !(entity instanceof FighterSquadron) && !game.useVectorMove()) {
                        if (!doSkillCheckInSpace(entity, rollTarget)) {
                            a.setSI(a.getSI() - 1);
                            // check for destruction
                            if (a.getSI() == 0) {
                                destroyEntity(entity, "Structural Integrity Collapse", false);
                            }
                        }
                    }

                    // check for pilot damage
                    int hits = entity.getCrew().getHits();
                    int health = 6 - hits;

                    if ((thrustUsed > (2 * health)) && !game.useVectorMove() && !(entity instanceof TeleMissile)) {
                        int targetroll = 2 + (thrustUsed - 2 * health) + 2 * hits;
                        resistGForce(entity, targetroll);
                    }

                    thrustUsed = 0;
                }

                rollTarget = a.checkRolls(step, overallMoveType);
                if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) {
                    game.addControlRoll(new PilotingRollData(a.getId(), 0, "excess roll"));
                }

                rollTarget = a.checkManeuver(step, overallMoveType);
                if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) {
                    if (!doSkillCheckManeuver(entity, rollTarget)) {
                        a.setFailedManeuver(true);
                        int forward = Math.max(step.getVelocityLeft() / 2, 1);
                        if (forward < step.getVelocityLeft()) {
                            fellDuringMovement = true;
                        }
                        while (forward > 0) {
                            curPos = curPos.translated(step.getFacing());
                            forward--;
                            distance++;
                            // make sure it didn't fly off the map
                            if (!game.getBoard().contains(curPos)) {
                                r = new Report(9370, Report.PUBLIC);
                                r.indent();
                                r.addDesc(entity);
                                addReport(r);
                                game.removeEntity(entity.getId(), IEntityRemovalConditions.REMOVE_PUSHED);
                                send(createRemoveEntityPacket(entity.getId(), IEntityRemovalConditions.REMOVE_PUSHED));
                                forward = 0;
                                fellDuringMovement = false;
                                return;
                                // make sure it didn't crash
                            } else if (game.getBoard().getHex(curPos).ceiling() >= step.getElevation()) {
                                addReport(processCrash(entity, step.getVelocity()));
                                forward = 0;
                                fellDuringMovement = false;
                            }
                        }
                        break;
                    }
                }

                // if out of control, check for possible collision
                if (didMove && a.isOutControlTotal()) {
                    Enumeration<Entity> targets = game.getEntities(step.getPosition());
                    if (targets.hasMoreElements()) {
                        // Somebody here so check to see if there is a collision
                        int checkroll = Compute.d6(2);
                        // TODO: change this to 11 for Large Craft
                        int targetroll = 11;
                        if ((a instanceof Dropship) || (entity instanceof Jumpship)) {
                            targetroll = 10;
                        }
                        if (checkroll >= targetroll) {
                            // this gets complicated, I need to check for each
                            // unit type
                            // by order of movement subphase
                            Vector<Integer> potentialSpaceStation;
                            Vector<Integer> potentialWarship;
                            Vector<Integer> potentialJumpship;
                            Vector<Integer> potentialDropship;
                            Vector<Integer> potentialSmallCraft;
                            Vector<Integer> potentialASF;
                            potentialSpaceStation = new Vector<Integer>();
                            potentialWarship = new Vector<Integer>();
                            potentialJumpship = new Vector<Integer>();
                            potentialDropship = new Vector<Integer>();
                            potentialSmallCraft = new Vector<Integer>();
                            potentialASF = new Vector<Integer>();
                            while (targets.hasMoreElements()) {
                                int id = targets.nextElement().getId();
                                Entity ce = game.getEntity(id);
                                if (ce instanceof SpaceStation) {
                                    potentialSpaceStation.addElement(id);
                                } else if (ce instanceof Warship) {
                                    potentialWarship.addElement(id);
                                } else if (ce instanceof Jumpship) {
                                    potentialJumpship.addElement(id);
                                } else if (ce instanceof Dropship) {
                                    potentialDropship.addElement(id);
                                } else if (ce instanceof SmallCraft) {
                                    potentialSmallCraft.addElement(id);
                                } else {
                                    potentialASF.addElement(id);
                                }
                            }

                            // ok now go through and see if these have anybody
                            // in them
                            if (potentialSpaceStation.size() > 0) {
                                int chosen = Compute.randomInt(potentialSpaceStation.size());
                                Entity target = game.getEntity(potentialSpaceStation.elementAt(chosen));
                                Coords dest = target.getPosition();
                                if (processCollision(entity, target, lastPos)) {
                                    curPos = dest;
                                    break;
                                }
                            } else if (potentialWarship.size() > 0) {
                                int chosen = Compute.randomInt(potentialWarship.size());
                                Entity target = game.getEntity(potentialWarship.elementAt(chosen));
                                Coords dest = target.getPosition();
                                if (processCollision(entity, target, lastPos)) {
                                    curPos = dest;
                                    break;
                                }
                            } else if (potentialJumpship.size() > 0) {
                                int chosen = Compute.randomInt(potentialJumpship.size());
                                Entity target = game.getEntity(potentialJumpship.elementAt(chosen));
                                Coords dest = target.getPosition();
                                if (processCollision(entity, target, lastPos)) {
                                    curPos = dest;
                                    break;
                                }
                            } else if (potentialDropship.size() > 0) {
                                int chosen = Compute.randomInt(potentialDropship.size());
                                Entity target = game.getEntity(potentialDropship.elementAt(chosen));
                                Coords dest = target.getPosition();
                                if (processCollision(entity, target, lastPos)) {
                                    curPos = dest;
                                    break;
                                }
                            } else if (potentialSmallCraft.size() > 0) {
                                int chosen = Compute.randomInt(potentialSmallCraft.size());
                                Entity target = game.getEntity(potentialSmallCraft.elementAt(chosen));
                                Coords dest = target.getPosition();
                                if (processCollision(entity, target, lastPos)) {
                                    curPos = dest;
                                    break;
                                }
                            } else if (potentialASF.size() > 0) {
                                int chosen = Compute.randomInt(potentialASF.size());
                                Entity target = game.getEntity(potentialASF.elementAt(chosen));
                                Coords dest = target.getPosition();
                                if (processCollision(entity, target, lastPos)) {
                                    curPos = dest;
                                    break;
                                }
                            }

                        }
                    }
                }

                // if in the atmosphere, check for a potential crash

                if (game.getBoard().inAtmosphere() && (game.getBoard().getHex(step.getPosition()).ceiling() >= step.getElevation())) {
                    addReport(processCrash(entity, md.getFinalVelocity()));
                    // don't do the rest
                    break;
                }

                // handle fighter launching
                if (step.getType() == MovePath.STEP_LAUNCH) {
                    TreeMap<Integer, Vector<Integer>> launched = step.getLaunched();
                    Set<Integer> bays = launched.keySet();
                    Iterator<Integer> bayIter = bays.iterator();
                    Bay currentBay;
                    while(bayIter.hasNext()) {
                        int bayId = bayIter.next();
                        currentBay = entity.getFighterBays().elementAt(bayId);
                        Vector<Integer> launches = launched.get(bayId);
                        int nLaunched = launches.size();
                        //need to make some decisions about how to handle the distribution
                        //of fighters to doors beyond the launch rate. The most sensible thing
                        //is probably to distribut them evenly.
                        int doors = currentBay.getDoors();
                        int[] distribution = new int[doors];
                        for(int l = 0; l < nLaunched; l++) {
                            distribution[l % doors] = distribution[l % doors] + 1;
                        }
                        //ok, now lets launch them
                        r = new Report(9380);
                        r.add(entity.getDisplayName());
                        r.subject = entity.getId();
                        r.newlines = 0;
                        r.add(nLaunched);
                        addReport(r);
                        int currentDoor = 0;
                        int fighterCount = 0;
                        boolean doorDamage = false;
                        for(int fighterId : launches) {
                            //check to see if we are in the same door
                            fighterCount++;
                            if(fighterCount > distribution[currentDoor]) {
                                //move to a new door
                                currentDoor++;
                                fighterCount = 0;
                                doorDamage = false;
                            }
                            int bonus = Math.max(0, distribution[currentDoor] - 2);
                            //check for door damage
                            if(!doorDamage && (distribution[currentDoor] > 2) && (Compute.d6(2) == 2)) {
                                doorDamage = true;
                                r = new Report(9390);
                                r.subject = entity.getId();
                                r.indent(1);
                                r.newlines = 0;
                                r.add(currentBay.getType());
                                addReport(r);
                                currentBay.destroyDoorNext();
                            }
                            Entity fighter = game.getEntity(fighterId);
                            if (!launchUnit(entity, fighter, curPos, curFacing, step.getVelocity(), step.getElevation(), step.getVectors(), bonus)) {
                                System.err.println("Error! Server was told to unload " + fighter.getDisplayName() + " from " + entity.getDisplayName() + " into " + curPos.getBoardNum());
                            }
                        }
                    }
                    // now apply any damage to bay doors
                    entity.resetBayDoors();
                }

                if (step.getType() == MovePath.STEP_OFF) {
                    //same as flee but different message.
                    //we can't use flee because if the unit is out of control, it needs to go through its
                    //to see if it collides with anything else
                    r = new Report(9370, Report.PUBLIC);
                    r.indent();
                    r.addDesc(entity);
                    addReport(r);
                    Coords pos = entity.getPosition();
                    int fleeDirection;
                    if (pos.x == 0) {
                        fleeDirection = IOffBoardDirections.WEST;
                    } else if (pos.y == 0) {
                        fleeDirection = IOffBoardDirections.SOUTH;
                    } else if (pos.x == game.getBoard().getWidth()) {
                        fleeDirection = IOffBoardDirections.EAST;
                    } else {
                        fleeDirection = IOffBoardDirections.NORTH;
                    }

                    // Is the unit carrying passengers?
                    final Vector<Entity> passengers = entity.getLoadedUnits();
                    if (!passengers.isEmpty()) {
                        for (Entity passenger : passengers) {
                            // Unit has fled the battlefield.
                            r = new Report(2010, Report.PUBLIC);
                            r.indent();
                            r.addDesc(passenger);
                            addReport(r);
                            passenger.setRetreatedDirection(fleeDirection);
                            game.removeEntity(passenger.getId(), IEntityRemovalConditions.REMOVE_IN_RETREAT);
                            send(createRemoveEntityPacket(passenger.getId(), IEntityRemovalConditions.REMOVE_IN_RETREAT));
                        }
                    }

                    // Handle any picked up MechWarriors
                    for (Integer mechWarriorId : entity.getPickedUpMechWarriors()) {
                        Entity mw = game.getEntity(mechWarriorId.intValue());

                        // Is the MechWarrior an enemy?
                        int condition = IEntityRemovalConditions.REMOVE_IN_RETREAT;
                        r = new Report(2010);
                        if (mw.isCaptured()) {
                            r = new Report(2015);
                            condition = IEntityRemovalConditions.REMOVE_CAPTURED;
                        } else {
                            mw.setRetreatedDirection(fleeDirection);
                        }
                        game.removeEntity(mw.getId(), condition);
                        send(createRemoveEntityPacket(mw.getId(), condition));
                        r.addDesc(mw);
                        r.indent();
                        addReport(r);
                    }
                    // Is the unit being swarmed?
                    final int swarmerId = entity.getSwarmAttackerId();
                    if (Entity.NONE != swarmerId) {
                        final Entity swarmer = game.getEntity(swarmerId);

                        // Has the swarmer taken a turn?
                        if (!swarmer.isDone()) {

                            // Dead entities don't take turns.
                            game.removeTurnFor(swarmer);
                            send(createTurnVectorPacket());

                        } // End swarmer-still-to-move

                        // Unit has fled the battlefield.
                        swarmer.setSwarmTargetId(Entity.NONE);
                        entity.setSwarmAttackerId(Entity.NONE);
                        r = new Report(2015, Report.PUBLIC);
                        r.indent();
                        r.addDesc(swarmer);
                        addReport(r);
                        game.removeEntity(swarmerId, IEntityRemovalConditions.REMOVE_CAPTURED);
                        send(createRemoveEntityPacket(swarmerId, IEntityRemovalConditions.REMOVE_CAPTURED));
                    }
                    entity.setRetreatedDirection(fleeDirection);
                    game.removeEntity(entity.getId(), IEntityRemovalConditions.REMOVE_IN_RETREAT);
                    send(createRemoveEntityPacket(entity.getId(), IEntityRemovalConditions.REMOVE_IN_RETREAT));
                    return;
                }
            }

            // check piloting skill for getting up
            rollTarget = entity.checkGetUp(step);

            if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) {
                entity.heatBuildup += 1;
                entity.setProne(false);
                //entity.setHullDown(false);
                wasProne = false;
                game.resetPSRs(entity);
                entityFellWhileAttemptingToStand = !doSkillCheckInPlace(entity, rollTarget);
            }
            // did the entity just fall?
            if (entityFellWhileAttemptingToStand) {
                moveType = step.getMovementType();
                curFacing = entity.getFacing();
                curPos = entity.getPosition();
                mpUsed = step.getMpUsed();
                fellDuringMovement = true;
                if ( !entity.isCarefulStand() ) {
                    break;
                }
            }  else {
                entity.setHullDown(false);
            }

            if (step.getType() == MovePath.STEP_UNJAM_RAC) {
                entity.setUnjammingRAC(true);
                game.addAction(new UnjamAction(entity.getId()));

                // for Aeros this will end movement prematurely
                // if we break
                if (!(entity instanceof Aero)) {
                    break;
                }
            }

            if (step.getType() == MovePath.STEP_LAY_MINE) {
                layMine(entity, step.getMineToLay(), step.getPosition());
                break;
            }

            if (step.getType() == MovePath.STEP_CLEAR_MINEFIELD) {
                ClearMinefieldAction cma = new ClearMinefieldAction(entity.getId(), step.getMinefield());
                entity.setClearingMinefield(true);
                game.addAction(cma);
                break;
            }

            if ((step.getType() == MovePath.STEP_SEARCHLIGHT) && entity.hasSpotlight()) {
                final boolean SearchOn = !entity.isUsingSpotlight();
                entity.setSpotlightState(SearchOn);
                sendServerChat(entity.getDisplayName() + " switched searchlight " + (SearchOn ? "on" : "off") + '.');
            }

            // set most step parameters
            moveType = step.getMovementType();
            distance = step.getDistance();
            mpUsed = step.getMpUsed();

            if (cachedGravityLimit < 0) {
                cachedGravityLimit = IEntityMovementType.MOVE_JUMP == moveType ? entity.getJumpMP(false) : entity.getRunMP(false, false);
            }
            // check for charge
            if (step.getType() == MovePath.STEP_CHARGE) {
                if (entity.canCharge()) {
                    checkExtremeGravityMovement(entity, step, curPos, cachedGravityLimit);
                    Targetable target = step.getTarget(game);
                    ChargeAttackAction caa = new ChargeAttackAction(entity.getId(), target.getTargetType(), target.getTargetId(), target.getPosition());
                    entity.setDisplacementAttack(caa);
                    game.addCharge(caa);
                    charge = caa;
                } else {
                    sendServerChat("Illegal charge!! I don't think " + entity.getDisplayName() + " should be allowed to charge," + " but the client of " + entity.getOwner().getName() + " disagrees.");
                    sendServerChat("Please make sure " + entity.getOwner().getName() + " is running MegaMek " + MegaMek.VERSION + ", or if that is already the case, submit a bug report at http://megamek.sf.net/");
                    return;
                }
                break;
            }

            // check for dfa
            if (step.getType() == MovePath.STEP_DFA) {
                if (entity.canDFA()) {
                    checkExtremeGravityMovement(entity, step, curPos, cachedGravityLimit);
                    Targetable target = step.getTarget(game);
                    DfaAttackAction daa = new DfaAttackAction(entity.getId(), target.getTargetType(), target.getTargetId(), target.getPosition());
                    entity.setDisplacementAttack(daa);
                    game.addCharge(daa);
                    charge = daa;
                } else {
                    sendServerChat("Illegal DFA!! I don't think " + entity.getDisplayName() + " should be allowed to DFA," + " but the client of " + entity.getOwner().getName() + " disagrees.");
                    sendServerChat("Please make sure " + entity.getOwner().getName() + " is running MegaMek " + MegaMek.VERSION + ", or if that is already the case, submit a bug report at http://megamek.sf.net/");
                    return;
                }
                break;
            }

            // check for ram
            if (step.getType() == MovePath.STEP_RAM) {
                if (entity.canRam()) {
                    Targetable target = step.getTarget(game);
                    RamAttackAction raa = new RamAttackAction(entity.getId(), target.getTargetType(), target.getTargetId(), target.getPosition());
                    entity.setRamming(true);
                    game.addRam(raa);
                    ram = raa;
                } else {
                    sendServerChat("Illegal ram!! I don't think " + entity.getDisplayName() + " should be allowed to charge," + " but the client of " + entity.getOwner().getName() + " disagrees.");
                    sendServerChat("Please make sure " + entity.getOwner().getName() + " is running MegaMek " + MegaMek.VERSION + ", or if that is already the case, submit a bug report at http://megamek.sf.net/");
                    return;
                }
                break;
            }

            if ((step.getType() == MovePath.STEP_ACC) || (step.getType() == MovePath.STEP_ACCN)) {
                if (entity instanceof Aero) {
                    Aero a = (Aero) entity;
                    if (step.getType() == MovePath.STEP_ACCN) {
                        a.setAccLast(true);
                        a.setNextVelocity(a.getNextVelocity() + 1);
                    } else {
                        a.setAccDecNow(true);
                        a.setCurrentVelocity(a.getCurrentVelocity() + 1);
                        a.setNextVelocity(a.getNextVelocity() + 1);
                    }
                }
            }

            if ((step.getType() == MovePath.STEP_DEC) || (step.getType() == MovePath.STEP_DECN)) {
                if (entity instanceof Aero) {
                    Aero a = (Aero) entity;
                    if (step.getType() == MovePath.STEP_DECN) {
                        a.setAccLast(true);
                        a.setNextVelocity(a.getNextVelocity() - 1);
                    } else {
                        a.setAccDecNow(true);
                        a.setCurrentVelocity(a.getCurrentVelocity() - 1);
                        a.setNextVelocity(a.getNextVelocity() - 1);
                    }
                }
            }

            if (step.getType() == MovePath.STEP_EVADE) {
                entity.setEvading(true);

            }

            if (step.getType() == MovePath.STEP_STALL) {
                // TODO: check VSTOL status
                r = new Report(9391);
                r.subject = entity.getId();
                r.addDesc(entity);
                r.newlines = 0;
                addReport(r);
                game.addControlRoll(new PilotingRollData(entity.getId(), 0, "stalled out"));
                // check for crash
                if (game.getBoard().getHex(step.getPosition()).ceiling() >= step.getElevation()) {
                    addReport(processCrash(entity, 0));
                    // don't do the rest
                    break;
                }
            }

            if (step.getType() == MovePath.STEP_ROLL) {
                if (entity instanceof Aero) {
                    Aero a = (Aero) entity;
                    if (a.isRolled()) {
                        a.setRolled(false);
                    } else {
                        a.setRolled(true);
                    }

                }
            }

            // check for dig in or fortify
            if (entity instanceof Infantry) {
                Infantry inf = (Infantry) entity;
                if (step.getType() == MovePath.STEP_DIG_IN) {
                    inf.setDugIn(Infantry.DUG_IN_WORKING);
                    continue;
                } else if (step.getType() == MovePath.STEP_FORTIFY) {
                    if (!entity.hasWorkingMisc(MiscType.F_TOOLS, MiscType.S_VIBROSHOVEL)) {
                        sendServerChat(entity.getDisplayName() + " failed to fortify because it is missing suitable equipment");
                    }
                    inf.setDugIn(Infantry.DUG_IN_FORTIFYING1);
                    continue;
                } else if ((step.getType() != MovePath.STEP_TURN_LEFT) && (step.getType() != MovePath.STEP_TURN_RIGHT)) {
                    // other movement clears dug in status
                    inf.setDugIn(Infantry.DUG_IN_NONE);
                }
            }

            // set last step parameters
            curPos = step.getPosition();
            if ((moveType != IEntityMovementType.MOVE_JUMP) || (entity.getJumpType() != Mech.JUMP_BOOSTER)) {
                curFacing = step.getFacing();
            }
            // check if a building PSR will be needed later, before setting the
            // new elevation
            int buildingMove = entity.checkMovementInBuilding(step, prevStep, curPos, lastPos);
            curVTOLElevation = step.getElevation();
            curElevation = step.getElevation();
            // set elevation in case of collapses
            entity.setElevation(step.getElevation());

            IHex curHex = game.getBoard().getHex(curPos);

            // check for automatic unstick
            if (entity.canUnstickByJumping() && entity.isStuck() && (moveType == IEntityMovementType.MOVE_JUMP)) {
                entity.setStuck(false);
                entity.setCanUnstickByJumping(false);
            }

            // Check for skid.
            rollTarget = entity.checkSkid(moveType, prevHex, overallMoveType, prevStep, prevFacing, curFacing, lastPos, curPos, isInfantry, distance-1);
            if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) {
                // Have an entity-meaningful PSR message.
                boolean psrFailed = true;
                if (entity instanceof Mech) {
                    psrFailed = (0 < doSkillCheckWhileMoving(entity, lastPos, lastPos, rollTarget, true));
                } else {
                    psrFailed = (0 < doSkillCheckWhileMoving(entity, lastPos, lastPos, rollTarget, false));
                }
                // Does the entity skid?
                if (psrFailed) {

                    if (entity instanceof Tank) {
                        addReport(vehicleMotiveDamage((Tank) entity, 0));
                    }

                    curPos = lastPos;
                    int skidDistance = (int)Math.round((double)(distance-1)/2);
                    int skidDirection = prevFacing;

                    // All charge damage is based upon
                    // the pre-skid move distance.
                    entity.delta_distance = distance - 1;

                    // Attacks against a skidding target have additional +2.
                    moveType = IEntityMovementType.MOVE_SKID;

                    // What is the first hex in the skid?
                    if (step.isThisStepBackwards()) {
                        skidDirection = (skidDirection + 3) % 6;
                    }

                    if (processSkid(entity, curPos, prevStep.getElevation(), skidDirection, skidDistance, prevStep)) {
                        return;
                    }

                    // set entity parameters
                    curFacing = entity.getFacing();
                    curPos = entity.getPosition();
                    entity.setSecondaryFacing(curFacing);

                    // skid consumes all movement
                    if (md.hasActiveMASC()) {
                        mpUsed = entity.getRunMP();
                    } else {
                        mpUsed = entity.getRunMPwithoutMASC();
                    }

                    entity.moved = moveType;
                    fellDuringMovement = true;
                    turnOver = true;
                    distance = entity.delta_distance;
                    break;

                } // End failed-skid-psr

            } // End need-skid-psr

            // check sideslip
            if ((entity instanceof VTOL) || (entity.getMovementMode() == IEntityMovementMode.HOVER) || (entity.getMovementMode() == IEntityMovementMode.WIGE)) {
                rollTarget = entity.checkSideSlip(moveType, prevHex, overallMoveType, prevStep, prevFacing, curFacing, lastPos, curPos, distance);
                if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) {
                    int MoF = doSkillCheckWhileMoving(entity, lastPos, curPos, rollTarget, false);
                    if (MoF > 0) {
                        // maximum distance is hexes moved / 2
                        int sideslipDistance = Math.min(MoF, distance - 1);
                        if (sideslipDistance > 0) {
                            int skidDirection = prevFacing;
                            // report sideslip
                            sideslipped = true;
                            r = new Report(2100);
                            r.subject = entity.getId();
                            r.addDesc(entity);
                            r.add(sideslipDistance);
                            addReport(r);

                            if (processSkid(entity, lastPos, prevStep.getElevation(), skidDirection, sideslipDistance, prevStep)) {
                                return;
                            }

                            if (!entity.isDestroyed() && !entity.isDoomed() && (mpUsed < entity.getRunMP())) {
                                fellDuringMovement = true; // No, but it should
                                // work...
                            }

                            if ((entity.getElevation() == 0) && ((entity.getMovementMode() == IEntityMovementMode.VTOL) || (entity.getMovementMode() == IEntityMovementMode.WIGE))) {
                                turnOver = true;
                            }
                            // set entity parameters
                            curFacing = step.getFacing();
                            curPos = entity.getPosition();
                            entity.setSecondaryFacing(curFacing);
                            break;
                        }
                    }
                }
            }

            // check if we've moved into rubble
            rollTarget = entity.checkRubbleMove(step, curHex, lastPos, curPos);
            if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) {
                doSkillCheckWhileMoving(entity, lastPos, curPos, rollTarget, true);
            }

            //check if we are using reckless movement
            rollTarget = entity.checkRecklessMove(step, curHex, lastPos, curPos, prevHex);
            if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) {
                if(entity instanceof Mech) {
                    doSkillCheckWhileMoving(entity, lastPos, curPos, rollTarget, true);
                } else if (entity instanceof Tank) {
                    if(0 < doSkillCheckWhileMoving(entity, lastPos, curPos, rollTarget, false)) {
                        //assume VTOLs in flight are always in clear terrain
                        if((0 == curHex.terrainsPresent()) || (step.getElevation() > 0)) {
                            r = new Report(2206);
                            r.addDesc(entity);
                            r.subject = entity.getId();
                            addReport(r);
                            mpUsed = step.getMpUsed() + 1;
                            fellDuringMovement = true;
                            break;
                        } else {
                            r = new Report(2207);
                            r.addDesc(entity);
                            r.subject = entity.getId();
                            addReport(r);
                            //until we get a rules clarification assume that the entity is both giver and taker
                            //for charge damage
                            HitData hit = entity.rollHitLocation(ToHitData.HIT_NORMAL, ToHitData.SIDE_FRONT);
                            addReport(damageEntity(entity, hit, ChargeAttackAction.getDamageTakenBy(entity, entity)));
                            turnOver = true;
                            break;
                        }
                    }
                }
            }

            // check for breaking magma crust
            if ((curHex.terrainLevel(Terrains.MAGMA) == 1) && (step.getElevation() == 0) && (step.getMovementType() != IEntityMovementType.MOVE_JUMP)) {
                int roll = Compute.d6(1);
                r = new Report(2395);
                r.addDesc(entity);
                r.add(roll);
                r.subject = entity.getId();
                addReport(r);
                if (roll == 6) {
                    curHex.removeTerrain(Terrains.MAGMA);
                    curHex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.MAGMA, 2));
                    sendChangedHex(curPos);
                    for (Enumeration<Entity> e = game.getEntities(curPos); e.hasMoreElements();) {
                        Entity en = e.nextElement();
                        if (en != entity) {
                            doMagmaDamage(en, false);
                        }
                    }
                }
            }

            // check for entering liquid magma
            if ((curHex.terrainLevel(Terrains.MAGMA) == 2) && (step.getElevation() == 0) && (step.getMovementType() != IEntityMovementType.MOVE_JUMP)) {
                doMagmaDamage(entity, false);
            }

            // check if we've moved into a swamp
            rollTarget = entity.checkBogDown(step, curHex, lastPos, curPos, lastElevation, isPavementStep);
            if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) {
                if (0 < doSkillCheckWhileMoving(entity, lastPos, curPos, rollTarget, false)) {
                    entity.setStuck(true);
                    entity.setCanUnstickByJumping(true);
                    r = new Report(2081);
                    r.add(entity.getDisplayName());
                    r.subject = entity.getId();
                    addReport(r);
                    //check for quicksand
                    addReport(checkQuickSand(curPos));
                    // check for accidental stacking violation
                    Entity violation = Compute.stackingViolation(game, entity.getId(), curPos);
                    if (violation != null) {
                        // target gets displaced, because of low elevation
                        int direction = lastPos.direction(curPos);
                        Coords targetDest = Compute.getValidDisplacement(game, entity.getId(), curPos, direction);
                        addReport(doEntityDisplacement(violation, curPos, targetDest, new PilotingRollData(violation.getId(), 0, "domino effect")));
                        // Update the violating entity's postion on the client.
                        entityUpdate(violation.getId());
                    }
                    break;
                }
            }

            // check to see if we are a mech and we've moved OUT of fire
            IHex lastHex = game.getBoard().getHex(lastPos);
            if (entity instanceof Mech) {
                if (!lastPos.equals(curPos) && (prevStep != null) && ((lastHex.containsTerrain(Terrains.FIRE) && (prevStep.getElevation() <= 1)) || (lastHex.containsTerrain(Terrains.MAGMA) && (prevStep.getElevation() == 0))) && ((step.getMovementType() != IEntityMovementType.MOVE_JUMP)
                // Bug #828741 -- jumping bypasses fire, but not on the
                        // first step
                        // getMpUsed -- total MP used to this step
                        // getMp -- MP used in this step
                        // the difference will always be 0 on the "first step"
                        // of a jump,
                        // and >0 on a step in the midst of a jump
                        || (0 == step.getMpUsed() - step.getMp()))) {
                    int heat = 0;
                    if (lastHex.containsTerrain(Terrains.FIRE)) {
                        heat += 2;
                    }
                    if (lastHex.terrainLevel(Terrains.MAGMA) == 1) {
                        heat += 2;
                    } else if (lastHex.terrainLevel(Terrains.MAGMA) == 2) {
                        heat += 5;
                    }
                    entity.heatFromExternal += heat;
                    r = new Report(2115);
                    r.subject = entity.getId();
                    r.addDesc(entity);
                    r.add(heat);
                    addReport(r);
                }
            }

            // check to see if we are not a mech and we've moved INTO fire
            if (!(entity instanceof Mech)) {
                if (game.getBoard().getHex(curPos).containsTerrain(Terrains.FIRE) && !lastPos.equals(curPos) && (step.getMovementType() != IEntityMovementType.MOVE_JUMP) && (step.getElevation() <= 1)) {
                    doFlamingDamage(entity);
                }
            }
            // check for extreme gravity movement
            if (!i.hasMoreElements() && !firstStep) {
                checkExtremeGravityMovement(entity, step, curPos, cachedGravityLimit);
            }
            // check for minefields. have to check both new hex and new elevation
            // VTOLs may land and submarines may rise or lower into a minefield
            if (!lastPos.equals(curPos) ||  (lastElevation != curElevation)) {
                boolean boom = false;
                boolean isOnGround = !i.hasMoreElements();
                isOnGround |= step.getMovementType() != IEntityMovementType.MOVE_JUMP;
                isOnGround &= step.getElevation() < 1;
                if(isOnGround) {
                    boom = checkVibrabombs(entity, curPos, false, lastPos, curPos, vPhaseReport);
                }
                if (game.containsMinefield(curPos)) {
                    // set the new position temporarily, because
                    // infantry otherwise would get double damage
                    // when moving from clear into mined woods
                    entity.setPosition(curPos);
                    if(enterMinefield(entity, curPos, step.getElevation(), isOnGround, vPhaseReport)) {
                        //resolve any piloting rolls from damage unless unit was jumping
                        if(step.getMovementType() != IEntityMovementType.MOVE_JUMP) {
                            addReport(resolvePilotingRolls(entity));
                            game.resetPSRs(entity);
                        }
                        boom = true;
                    }
                    if(wasProne || !entity.isProne()) {
                        entity.setPosition(lastPos);
                    }
                }
                //did anything go boom?
                if(boom) {
                    //set fell during movement so that entity will get another chance to move with any motive damage
                    //taken account of (functions the same as MASC failure)
                    //only do this if they had more steps (and they were not jumping
                    if(i.hasMoreElements() && (step.getMovementType() != IEntityMovementType.MOVE_JUMP)) {
                        md.clear();
                        fellDuringMovement = true;
                    }
                    //reset mines if anything detonated
                    resetMines();
                }
            }

            // infantry discovers minefields if they end their move
            // in a minefield.
            if (!lastPos.equals(curPos) && !i.hasMoreElements() && isInfantry) {
                if (game.containsMinefield(curPos)) {
                    Player owner = entity.getOwner();
                    for (Minefield mf : game.getMinefields(curPos)) {
                        if (!owner.containsMinefield(mf)) {
                            r = new Report(2120);
                            r.subject = entity.getId();
                            r.add(entity.getShortName(), true);
                            addReport(r);
                            revealMinefield(game.getTeamForPlayer(owner), mf);
                        }
                    }
                }
            }

            // check if we've moved into water
            rollTarget = entity.checkWaterMove(step, curHex, lastPos, curPos, isPavementStep);
            if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) {
                // Swarmers need special handling.
                final int swarmerId = entity.getSwarmAttackerId();
                boolean swarmerDone = true;
                Entity swarmer = null;
                if (Entity.NONE != swarmerId) {
                    swarmer = game.getEntity(swarmerId);
                    swarmerDone = swarmer.isDone();
                }

                // Now do the skill check.
                doSkillCheckWhileMoving(entity, lastPos, curPos, rollTarget, true);

                // Swarming infantry platoons may drown.
                if (curHex.terrainLevel(Terrains.WATER) > 1) {
                    drownSwarmer(entity, curPos);
                }

                // Do we need to remove a game turn for the swarmer
                if (!swarmerDone && (swarmer != null) && (swarmer.isDoomed() || swarmer.isDestroyed())) {
                    // We have to diddle with the swarmer's
                    // status to get its turn removed.
                    swarmer.setDone(false);
                    swarmer.setUnloaded(false);

                    // Dead entities don't take turns.
                    game.removeTurnFor(swarmer);
                    send(createTurnVectorPacket());

                    // Return the original status.
                    swarmer.setDone(true);
                    swarmer.setUnloaded(true);
                }

                // check for inferno wash-off
                checkForWashedInfernos(entity, curPos);
            }

            // In water, may or may not be a new hex, neccessary to
            // check during movement, for breach damage, and always
            // set dry if appropriate
            // TODO: possibly make the locations local and set later
            addReport(doSetLocationsExposure(entity, curHex, step.getMovementType() == IEntityMovementType.MOVE_JUMP, step.getElevation()));

            // check for breaking ice by breaking through from below
            if ((lastElevation < 0) && (step.getElevation() == 0)
                    && lastHex.containsTerrain(Terrains.ICE) && lastHex.containsTerrain(Terrains.WATER)
                    && (step.getMovementType() != IEntityMovementType.MOVE_JUMP) && !lastPos.equals(curPos)) {
                //need to temporarily reset entity's position so it doesn't fall in the ice
                entity.setPosition(curPos);
                r = new Report(2410);
                r.addDesc(entity);
                addReport(r);
                addReport(resolveIceBroken(lastPos));
                //ok now set back
                entity.setPosition(lastPos);
            }
            // check for breaking ice by stepping on it
            if (curHex.containsTerrain(Terrains.ICE) && curHex.containsTerrain(Terrains.WATER)
                    && (step.getMovementType() != IEntityMovementType.MOVE_JUMP)
                    && !lastPos.equals(curPos)
                    && !(entity instanceof Infantry)
                    && !(step.isPavementStep() && curHex.containsTerrain(Terrains.BRIDGE))) {
                if (step.getElevation() == 0) {
                    int roll = Compute.d6(1);
                    r = new Report(2118);
                    r.addDesc(entity);
                    r.add(roll);
                    r.subject = entity.getId();
                    addReport(r);
                    if (roll == 6) {
                        entity.setPosition(curPos);
                        addReport(resolveIceBroken(curPos));
                        curPos = entity.getPosition();
                    }
                }
                // or intersecting it
                else if (step.getElevation() + entity.height() == 0) {
                    r = new Report(2410);
                    r.addDesc(entity);
                    addReport(r);
                    addReport(resolveIceBroken(curPos));
                }
            }

            // Handle loading units.
            if (step.getType() == MovePath.STEP_LOAD) {

                // Find the unit being loaded.
                Entity loaded = null;
                Enumeration<Entity> entities = game.getEntities(curPos);
                while (entities.hasMoreElements()) {

                    // Is the other unit friendly and not the current entity?
                    loaded = entities.nextElement();
                    if (!entity.isEnemyOf(loaded) && !entity.equals(loaded)) {

                        // The moving unit should be able to load the other
                        // unit and the other should be able to have a turn.
                        if (!entity.canLoad(loaded) || !loaded.isLoadableThisTurn()) {
                            // Something is fishy in Denmark.
                            System.err.println(entity.getShortName() + " can not load " + loaded.getShortName());
                            loaded = null;
                        } else {
                            // Have the deployed unit load the indicated unit.
                            loadUnit(entity, loaded);

                            // Stop looking.
                            break;
                        }

                    } else {
                        // Nope. Discard it.
                        loaded = null;
                    }

                } // Handle the next entity in this hex.

                // We were supposed to find someone to load.
                if (loaded == null) {
                    System.err.println("Could not find unit for " + entity.getShortName() + " to load in " + curPos);
                }

            } // End STEP_LOAD

            // handle fighter recovery
            if (step.getType() == MovePath.STEP_RECOVER) {

                loader = game.getEntity(step.getRecoveryUnit());

                PilotingRollData psr = entity.getBasePilotingRoll(overallMoveType);
                if (loader.mpUsed > 0) {
                    psr.addModifier(5, "carrier used thrust");
                }
                int ctrlroll = Compute.d6(2);
                r = new Report(9381);
                r.subject = entity.getId();
                r.add(entity.getDisplayName());
                r.add(loader.getDisplayName());
                r.add(psr.getValue());
                r.add(ctrlroll);
                r.newlines = 0;
                r.indent(1);
                if (ctrlroll < psr.getValue()) {
                    r.choose(false);
                    addReport(r);
                    // damage unit
                    Aero a = (Aero) entity;
                    HitData hit = a.rollHitLocation(ToHitData.HIT_NORMAL, ToHitData.SIDE_FRONT);
                    addReport(damageEntity(entity, hit, 2 * (psr.getValue() - ctrlroll)));
                } else {
                    r.choose(true);
                    addReport(r);
                    recovered = true;
                }
                // check for door damage
                if (ctrlroll == 2) {
                    loader.damageDoorRecovery(entity);
                    r = new Report(9384);
                    r.subject = entity.getId();
                    r.indent(0);
                    r.add(loader.getDisplayName());
                    addReport(r);
                }
            }

            //handle fighter squadron joining
            if (step.getType() == MovePath.STEP_JOIN) {
                loader = game.getEntity(step.getRecoveryUnit());
                recovered = true;
            }

            // Handle unloading units.
            if (step.getType() == MovePath.STEP_UNLOAD) {
                Targetable unloaded = step.getTarget(game);
                if (!unloadUnit(entity, unloaded, curPos, curFacing, step.getElevation())) {
                    System.err.println("Error! Server was told to unload " + unloaded.getDisplayName() + " from " + entity.getDisplayName() + " into " + curPos.getBoardNum());
                }
            }

            if (((step.getType() == MovePath.STEP_BACKWARDS) || (step.getType() == MovePath.STEP_LATERAL_LEFT_BACKWARDS) || (step.getType() == MovePath.STEP_LATERAL_RIGHT_BACKWARDS)) && (game.getBoard().getHex(lastPos).getElevation() != curHex.getElevation()) && !(entity instanceof VTOL)) {

                PilotingRollData psr = entity.getBasePilotingRoll(overallMoveType);
                int roll = Compute.d6(2);
                if (entity instanceof Tank) {
                    r = new Report(2435);
                } else {
                    r = new Report(2430);
                }
                r.subject = entity.getId();
                r.addDesc(entity);
                r.add(psr.getValue());
                r.add(roll);
                addReport(r);

                if (roll < psr.getValue()) {
                    if (entity instanceof Mech) {
                        if (curHex.getElevation() < game.getBoard().getHex(lastPos).getElevation()) {
                            entity.setElevation(Integer.MIN_VALUE);
                            addReport(doEntityFallsInto(entity, lastPos, curPos, entity.getBasePilotingRoll(overallMoveType), false));
                        } else {
                            // Tac Ops p.22
                            // the change in levels is not taken into
                            // consideration for determining the levels fallen.
                            entity.setElevation(Integer.MIN_VALUE);
                            addReport(doEntityFallsInto(entity, curPos, lastPos, entity.getBasePilotingRoll(overallMoveType), false));
                        }
                    } else if (entity instanceof Tank) {
                        curPos = lastPos;
                    }
                }
            }

            // Handle non-infantry moving into a building.
            if (buildingMove > 0) {

                // Get the building being exited.
                Building bldgExited = null;
                if ((buildingMove & 1) == 1) {
                    bldgExited = game.getBoard().getBuildingAt(lastPos);
                }

                // Get the building being entered.
                Building bldgEntered = null;
                if ((buildingMove & 2) == 2) {
                    bldgEntered = game.getBoard().getBuildingAt(curPos);
                }

                // Get the building being stepped on.
                Building bldgStepped = null;
                if ((buildingMove & 4) == 4) {
                    bldgStepped = game.getBoard().getBuildingAt(curPos);
                }

                boolean collapsed = false;
                // are we passing through a building wall?
                if ((bldgEntered != null)) {
                    // If we're not leaving a building, just handle the
                    // "entered".
                    String reason;
                    if (bldgExited == null) {
                        reason = "entering";
                    }
                    // If we're moving within the same building, just handle
                    // the "within".
                    else if (bldgExited.equals(bldgEntered) && !(entity instanceof Protomech) && !(entity instanceof Infantry)) {
                        reason = "moving in";
                    }
                    // If we have different buildings, roll for each.
                    else {
                        reason = "entering";
                    }
                    collapsed = passBuildingWall(entity, bldgEntered, lastPos, curPos, distance, reason, step.isThisStepBackwards(), step.getParent().getLastStepMovementType());
                    addAffectedBldg(bldgEntered, collapsed);
                }

                // stepping on roof, no PSR just check for over weight
                if (bldgStepped != null) {
                    collapsed = checkBuildingCollapseWhileMoving(bldgStepped, entity, curPos);
                    addAffectedBldg(bldgStepped, collapsed);
                }

                // Clean up the entity if it has been destroyed.
                if (entity.isDoomed()) {
                    entity.setDestroyed(true);
                    game.moveToGraveyard(entity.getId());
                    send(createRemoveEntityPacket(entity.getId()));

                    // The entity's movement is completed.
                    return;
                }

                // TODO: what if a building collapses into rubble?
            }

            // did the entity just fall?
            if (!wasProne && entity.isProne()) {
                curFacing = entity.getFacing();
                curPos = entity.getPosition();
                mpUsed = step.getMpUsed();
                fellDuringMovement = true;
                break;
            }

            // dropping prone intentionally?
            if (step.getType() == MovePath.STEP_GO_PRONE) {
                mpUsed = step.getMpUsed();
                rollTarget = entity.checkDislodgeSwarmers(step);
                if (rollTarget.getValue() == TargetRoll.CHECK_FALSE) {
                    // Not being swarmed
                    entity.setProne(true);
                    // check to see if we washed off infernos
                    checkForWashedInfernos(entity, curPos);
                } else {
                    // Being swarmed
                    entity.setPosition(curPos);
                    if (doDislodgeSwarmerSkillCheck(entity, rollTarget, curPos)) {
                        // Entity falls
                        curFacing = entity.getFacing();
                        curPos = entity.getPosition();
                        fellDuringMovement = true;
                        break;
                    }
                    // roll failed, go prone but don't dislodge swarmers
                    entity.setProne(true);
                    // check to see if we washed off infernos
                    checkForWashedInfernos(entity, curPos);
                    break;
                }
            }

            // going hull down
            if (step.getType() == MovePath.STEP_HULL_DOWN) {
                mpUsed = step.getMpUsed();
                entity.setHullDown(true);
            }

            // Track this step's location.
            movePath.addElement(new UnitLocation(entity.getId(), curPos, curFacing, step.getElevation()));

            // if the lastpos is not the same as the current position
            // then add the current position to the list of places passed
            // through
            if (!curPos.equals(lastPos)) {
                passedThrough.add(curPos);
            }

            // update lastPos, prevStep, prevFacing & prevHex
            lastPos = new Coords(curPos);
            lastElevation = curElevation;
            prevStep = step;
            /*
             * Bug 754610: Revert fix for bug 702735. if (prevHex != null &&
             * !curHex.equals(prevHex)) {
             */
            if (!curHex.equals(prevHex)) {
                prevFacing = curFacing;
            }
            prevHex = curHex;

            firstStep = false;
        }

        // set entity parameters
        entity.setPosition(curPos);
        entity.setFacing(curFacing);
        entity.setSecondaryFacing(curFacing);
        entity.delta_distance = distance;
        entity.moved = moveType;
        entity.mpUsed = mpUsed;
        if (!sideslipped && !fellDuringMovement) {
            entity.setElevation(curVTOLElevation);
        }
        entity.setClimbMode(md.getFinalClimbMode());

        // add a list of places passed through
        entity.setPassedThrough(passedThrough);

        // if we ran with destroyed hip or gyro, we need a psr
        rollTarget = entity.checkRunningWithDamage(overallMoveType);
        if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) {
            doSkillCheckInPlace(entity, rollTarget);
        }

        if (entity instanceof Aero) {

            Aero a = (Aero) entity;
            int thrust = md.getMpUsed();

            // set straight movement
            if (null != md.getLastStep()) {
                a.setStraightMoves(md.getLastStep().getNStraight());
            } else {
                a.setStraightMoves(0);
            }

            // consume fuel
            if (((entity instanceof Aero) && game.getOptions().booleanOption("fuel_consumption")) || (entity instanceof TeleMissile)) {
                int fuelUsed = ((Aero) entity).getFuelUsed(thrust);
                a.useFuel(fuelUsed);
            }

            //jumpships and space stations need to reduce accumulated thrust if they spend some
            if(entity instanceof Jumpship) {
                Jumpship js = (Jumpship)entity;
                double penalty = 0.0;
                //jumpships do not accumulate thrust when they make a turn or change velocity
                if(md.contains(MovePath.STEP_TURN_LEFT) || md.contains(MovePath.STEP_TURN_RIGHT)) {
                    //I need to subtract the station keeping thrust from their accumulated thrust
                    //because they did not actually use it
                    penalty = js.getStationKeepingThrust();
                }
                if(thrust > 0) {
                    penalty = thrust;
                }
                if(penalty > 0.0) {
                    js.setAccumulatedThrust(Math.max(0, js.getAccumulatedThrust() - penalty));
                }
            }

            // check to see if thrust exceeded SI

            rollTarget = a.checkThrustSITotal(thrust, overallMoveType);
            if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) {
                game.addControlRoll(new PilotingRollData(a.getId(), 0, "Thrust spent during turn exceeds SI"));
            }

            if (game.getBoard().inAtmosphere()) {
                rollTarget = a.checkVelocityDouble(md.getFinalVelocity(), overallMoveType);
                if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) {
                    game.addControlRoll(new PilotingRollData(a.getId(), 0, "Velocity greater than 2x safe thrust"));
                }

                rollTarget = a.checkDown(md.getFinalNDown(), overallMoveType);
                if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) {
                    game.addControlRoll(new PilotingRollData(a.getId(), md.getFinalNDown(), "descended more than two altitudes"));
                }

                // check for hovering
                rollTarget = a.checkHover(md);
                if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) {
                    game.addControlRoll(new PilotingRollData(a.getId(), 0, "hovering"));
                }

                // if this is a spheroid then check to see if it loses elevation
                // TODO: I am currently awaiting a rules decision on the forums
                // regarding
                // exactly when this elevation loss occurs. For the moment lets
                // assume it occurs
                // if there was no elevation change during the turn and no hover
                // step
                if ((a.isSpheroid() || game.getPlanetaryConditions().isVacuum()) && (startElevation == curElevation) && !md.contains(MovePath.STEP_HOVER)) {
                    a.setElevation(a.getElevation() - 1);
                    // check for crash
                    if (game.getBoard().getHex(a.getPosition()).ceiling() >= a.getElevation()) {
                        addReport(processCrash(entity, md.getFinalVelocity()));
                    }
                }

            }
View Full Code Here

        dataFile = bb;
    }

    public Entity getEntity() throws EntityLoadingException {

        Aero a = new Aero();

        if (!dataFile.exists("Name")) {
            throw new EntityLoadingException("Could not find name block.");
        }
        a.setChassis(dataFile.getDataAsString("Name")[0]);
        if (dataFile.exists("Model") && dataFile.getDataAsString("Model")[0] != null) {
            a.setModel(dataFile.getDataAsString("Model")[0]);
        } else {
            a.setModel("");
        }

        setTechLevel(a);

        if (!dataFile.exists("tonnage")) {
            throw new EntityLoadingException("Could not find weight block.");
        }
        a.setWeight(dataFile.getDataAsFloat("tonnage")[0]);

        // how many bombs can it carry
        a.autoSetMaxBombPoints();

        // get a movement mode - lets try Aerodyne
        int nMotion = 16;
        a.setMovementMode(nMotion);

        // figure out heat
        if (!dataFile.exists("heatsinks")) {
            throw new EntityLoadingException("Could not find weight block.");
        }
        a.setHeatSinks(dataFile.getDataAsInt("heatsinks")[0]);
        if (!dataFile.exists("sink_type")) {
            throw new EntityLoadingException("Could not find weight block.");
        }
        a.setHeatType(dataFile.getDataAsInt("sink_type")[0]);

        // figure out fuel
        if (!dataFile.exists("fuel")) {
            throw new EntityLoadingException("Could not find fuel block.");
        }
        a.setFuel(dataFile.getDataAsInt("fuel")[0]);

        // figure out engine stuff
        int engineCode = BLKFile.FUSION;
        if (dataFile.exists("engine_type")) {
            engineCode = dataFile.getDataAsInt("engine_type")[0];
        }
        int engineFlags = Engine.TANK_ENGINE;
        if (a.isClan()) {
            engineFlags |= Engine.CLAN_ENGINE;
        }
        if (!dataFile.exists("SafeThrust")) {
            throw new EntityLoadingException("Could not find SafeThrust block.");
        }
        int engineRating = (dataFile.getDataAsInt("SafeThrust")[0] - 2) * (int) a.getWeight();
        a.setEngine(new Engine(engineRating, BLKFile.translateEngineCode(engineCode), engineFlags));

        if (dataFile.exists("armor_type")) {
            a.setArmorType(dataFile.getDataAsInt("armor_type")[0]);
        }
        if (dataFile.exists("armor_tech")) {
            a.setArmorTechLevel(dataFile.getDataAsInt("armor_tech")[0]);
        }
        if (dataFile.exists("internal_type")) {
            a.setStructureType(dataFile.getDataAsInt("internal_type")[0]);
        }

        if (!dataFile.exists("armor")) {
            throw new EntityLoadingException("Could not find armor block.");
        }

        int[] armor = dataFile.getDataAsInt("armor");

        if (armor.length != 4) {
            throw new EntityLoadingException("Incorrect armor array length");
        }

        // set cockpit type if not default
        if (dataFile.exists("cockpit_type")) {
            a.setCockpitType(dataFile.getDataAsInt("cockpit_type")[0]);
        }

        if (dataFile.exists("source")) {
            a.setSource(dataFile.getDataAsString("source")[0]);
        }

        a.initializeArmor(armor[BLKAeroFile.NOSE], Aero.LOC_NOSE);
        a.initializeArmor(armor[BLKAeroFile.RW], Aero.LOC_RWING);
        a.initializeArmor(armor[BLKAeroFile.LW], Aero.LOC_LWING);
        a.initializeArmor(armor[BLKAeroFile.AFT], Aero.LOC_AFT);
        a.initializeArmor(0, Aero.LOC_WINGS);

        a.autoSetCapArmor();
        a.autoSetFatalThresh();

        a.autoSetInternal();
        a.autoSetSI();
        // This is not working right for arrays for some reason
        a.autoSetThresh();

        loadEquipment(a, "Nose", Aero.LOC_NOSE);
        loadEquipment(a, "Right Wing", Aero.LOC_RWING);
        loadEquipment(a, "Left Wing", Aero.LOC_LWING);
        loadEquipment(a, "Aft", Aero.LOC_AFT);

        // now organize the weapons into groups for capital fighters
        a.updateWeaponGroups();

        if (dataFile.exists("omni")) {
            a.setOmni(true);
        }

        if (a.isClan()) {
            a.addClanCase();
        }

        return a;
    }
View Full Code Here

         * See forum answers on OOC
         * http://forums.classicbattletech.com/index.php/topic,20424.0.html
         */

        if (e instanceof Aero) {
            Aero a = (Aero) e;

            // they should get a shot at a recovery roll at the end of all this
            // if they are already out of control
            boolean canRecover = a.isOutControl();

            // if the unit already is moving randomly then it can't get any
            // worse
            if (!a.isRandomMove()) {

                // find control rolls and make them
                Vector<PilotingRollData> rolls = new Vector<PilotingRollData>();
                StringBuffer reasons = new StringBuffer();
                PilotingRollData base = e.getBasePilotingRoll();
                for (Enumeration<PilotingRollData> j = game.getControlRolls(); j.hasMoreElements();) {
                    final PilotingRollData modifier = j.nextElement();
                    if (modifier.getEntityId() != e.getId()) {
                        continue;
                    }
                    // found a roll, add it
                    rolls.addElement(modifier);
                    if (reasons.length() > 0) {
                        reasons.append("; ");
                    }
                    reasons.append(modifier.getCumulativePlainDesc());
                    base.append(modifier);
                }
                // any rolls needed?
                if (rolls.size() > 0) {
                    // loop thru rolls we do have to make...
                    r = new Report(9310);
                    r.subject = e.getId();
                    r.addDesc(e);
                    r.add(rolls.size());
                    r.add(reasons.toString()); // international issue
                    vReport.add(r);
                    r = new Report(2285);
                    r.subject = e.getId();
                    r.add(base.getValueAsString());
                    r.add(base.getDesc()); // international issue
                    vReport.add(r);
                    for (int j = 0; j < rolls.size(); j++) {
                        PilotingRollData modifier = rolls.elementAt(j);
                        PilotingRollData target = base;
                        r = new Report(2290);
                        r.subject = e.getId();
                        r.indent();
                        r.newlines = 0;
                        r.add(j + 1);
                        r.add(modifier.getPlainDesc()); // international issue
                        vReport.add(r);
                        int diceRoll = Compute.d6(2);
                        // different reports depending on out-of-control status
                        if (a.isOutControl()) {
                            r = new Report(9360);
                            r.subject = e.getId();
                            r.add(target.getValueAsString());
                            r.add(diceRoll);
                            if (diceRoll < (target.getValue() - 5)) {
                                r.choose(false);
                                vReport.add(r);
                                a.setRandomMove(true);
                            } else {
                                r.choose(true);
                                vReport.add(r);
                            }
                        } else {
                            r = new Report(9315);
                            r.subject = e.getId();
                            r.add(target.getValueAsString());
                            r.add(diceRoll);
                            r.newlines = 1;
                            if (diceRoll < target.getValue()) {
                                r.choose(false);
                                vReport.add(r);
                                a.setOutControl(true);
                                // do we have random movement?
                                if ((target.getValue() - diceRoll) > 5) {
                                    r = new Report(9365);
                                    r.newlines = 0;
                                    r.subject = e.getId();
                                    vReport.add(r);
                                    a.setRandomMove(true);
                                }
                                // if on the atmospheric map, then lose altitude
                                // and check
                                // for crash
                                if (game.getBoard().inAtmosphere()) {
                                    int loss = Compute.d6(1);
                                    r = new Report(9366);
                                    r.newlines = 0;
                                    r.subject = e.getId();
                                    r.addDesc(e);
                                    r.add(loss);
                                    vReport.add(r);
                                    // check for crash
                                    if ((a.getElevation() - loss) <= game.getBoard().getHex(a.getPosition()).ceiling()) {
                                        a.setElevation(game.getBoard().getHex(a.getPosition()).surface());
                                        vReport.addAll(processCrash(e, a.getCurrentVelocity()));
                                    } else {
                                        a.setElevation(a.getElevation() - loss);
                                    }
                                }
                            } else {
                                r.choose(true);
                                vReport.add(r);
                            }
                        }
                    }
                }
            }

            // if they were out-of-control to start with, give them a chance to
            // regain control
            if (canRecover) {
                PilotingRollData base = e.getBasePilotingRoll();
                // is our base roll impossible?
                if ((base.getValue() == TargetRoll.AUTOMATIC_FAIL) || (base.getValue() == TargetRoll.IMPOSSIBLE)) {
                    // report something
                    r = new Report(9340);
                    r.subject = e.getId();
                    r.addDesc(e);
                    r.add(base.getDesc()); // international issue
                    vReport.add(r);
                    return vReport;
                }
                r = new Report(9345);
                r.subject = e.getId();
                r.addDesc(e);
                r.add(base.getDesc()); // international issue
                vReport.add(r);
                int diceRoll = Compute.d6(2);
                r = new Report(9350);
                r.subject = e.getId();
                r.add(base.getValueAsString());
                r.add(diceRoll);
                if (diceRoll < base.getValue()) {
                    r.choose(false);
                    vReport.add(r);
                } else {
                    r.choose(true);
                    vReport.add(r);
                    a.setOutControl(false);
                    a.setOutCtrlHeat(false);
                    a.setRandomMove(false);
                }
            }

        }
        return vReport;
View Full Code Here

        for (Enumeration<Entity> e = game.getEntities(); e.hasMoreElements();) {
            Entity en = e.nextElement();
            if (!en.isCapitalFighter() ||  (cen == Entity.NONE)) {
                continue;
            }
            Aero ship = (Aero) en;
            int damage = ship.getCurrentDamage();
            if (damage >= ship.getFatalThresh()) {
                int roll = Compute.d6(2) + (int)Math.floor((damage - ship.getFatalThresh())/2.0);
                if(roll > 9) {
                    vDesc.addAll(destroyEntity(ship, "fatal damage threshold"));
                }
            }
            ship.setCurrentDamage(0);

        }
        return vDesc;
    }
View Full Code Here

    private void drawConditionStrings(Graphics graph, Entity entity, int x,
            int y) {

//      out of control conditions for ASF
        if(entity instanceof Aero) {
            Aero a = (Aero)entity;


            //draw altitude if Aero in atmosphere
            if(clientgui.getClient().game.getBoard().inAtmosphere()) {
                graph.setColor(Color.darkGray);
                graph.drawString(Integer.toString(a.getElevation()), x + 36, y + 15);
                graph.setColor(Color.PINK);
                graph.drawString(Integer.toString(a.getElevation()), x + 35, y + 14);
            }

            if(a.isRolled()) {
                // draw "rolled"
                graph.setColor(Color.darkGray);
                graph.drawString(Messages.getString("BoardView1.ROLLED"), x + 11, y+29); //$NON-NLS-1$
                graph.setColor(Color.red);
                graph.drawString(Messages.getString("BoardView1.ROLLED"), x + 10, y+28); //$NON-NLS-1$
            }

            if(a.isOutControlTotal() && a.isRandomMove()) {
                graph.setColor(Color.darkGray);
                graph.drawString(Messages.getString("UnitOverview.RANDOM"), x + 11, y + 24); //$NON-NLS-1$
                graph.setColor(Color.red);
                graph.drawString(Messages.getString("UnitOverview.RANDOM"), x + 10, y + 23); //$NON-NLS-1$
            } else if(a.isOutControlTotal()) {
                // draw "CONTROL"
                graph.setColor(Color.darkGray);
                graph.drawString(Messages.getString("UnitOverview.CONTROL"), x + 11, y + 24); //$NON-NLS-1$
                graph.setColor(Color.red);
                graph.drawString(Messages.getString("UnitOverview.CONTROL"), x + 10, y + 23); //$NON-NLS-1$
            }

            //is the unit evading? - can't evade and be out of control so just draw on top
            if(a.isEvading()) {
                //draw evasion
                graph.setColor(Color.darkGray);
                graph.drawString(Messages.getString("UnitOverview.EVADE"), x +11, y + 24); //$NON-NLS-1$
                graph.setColor(Color.red);
                graph.drawString(Messages.getString("UnitOverview.EVADE"), x + 10, y + 23); //$NON-NLS-1$
View Full Code Here

    private void drawConditionStrings(Graphics graph, Entity entity, int x,
            int y) {

        //out of control conditions for ASF
        if(entity instanceof Aero) {
            Aero a = (Aero)entity;


            //draw altitude if Aero in atmosphere
            if(clientgui.getClient().game.getBoard().inAtmosphere()) {
                graph.setColor(Color.darkGray);
                graph.drawString(Integer.toString(a.getElevation()), x + 36, y + 15);
                graph.setColor(Color.PINK);
                graph.drawString(Integer.toString(a.getElevation()), x + 35, y + 14);
            }

            if(a.isRolled()) {
                // draw "rolled"
                graph.setColor(Color.darkGray);
                graph.drawString(Messages.getString("BoardView1.ROLLED"), x + 11, y+29); //$NON-NLS-1$
                graph.setColor(Color.red);
                graph.drawString(Messages.getString("BoardView1.ROLLED"), x + 10, y+28); //$NON-NLS-1$
            }

            if(a.isOutControlTotal() && a.isRandomMove()) {
                graph.setColor(Color.darkGray);
                graph.drawString(Messages.getString("UnitOverview.RANDOM"), x + 11, y + 24); //$NON-NLS-1$
                graph.setColor(Color.red);
                graph.drawString(Messages.getString("UnitOverview.RANDOM"), x + 10, y + 23); //$NON-NLS-1$
            } else if(a.isOutControlTotal()) {
                // draw "CONTROL"
                graph.setColor(Color.darkGray);
                graph.drawString(Messages.getString("UnitOverview.CONTROL"), x + 11, y + 24); //$NON-NLS-1$
                graph.setColor(Color.red);
                graph.drawString(Messages.getString("UnitOverview.CONTROL"), x + 10, y + 23); //$NON-NLS-1$
            }

            //is the unit evading? - can't evade and be out of control so just draw on top
            if(a.isEvading()) {
                //draw evasion
                graph.setColor(Color.darkGray);
                graph.drawString(Messages.getString("UnitOverview.EVADE"), x +11, y + 24); //$NON-NLS-1$
                graph.setColor(Color.red);
                graph.drawString(Messages.getString("UnitOverview.EVADE"), x + 10, y + 23); //$NON-NLS-1$
View Full Code Here

TOP

Related Classes of megamek.common.Aero

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.