Package megamek.common

Examples of megamek.common.ToHitData


            throw new IllegalStateException("Attacker is null");
        }

        // Due to pretreatment of physical attacks, the target may be null.
        if (target == null) {
            return new ToHitData(TargetRoll.IMPOSSIBLE, "Target is null");
        }

        int targetId = Entity.NONE;
        Entity te = null;
        if (target.getTargetType() == Targetable.TYPE_ENTITY) {
            te = (Entity) target;
            targetId = target.getTargetId();
        }

        if (!game.getOptions().booleanOption("friendly_fire")) {
            // a friendly unit can never be the target of a direct attack.
            if (!skid && (target.getTargetType() == Targetable.TYPE_ENTITY)
                    && ((((Entity)target).getOwnerId() == ae.getOwnerId())
                            || ((((Entity)target).getOwner().getTeam() != Player.TEAM_NONE)
                                    && (ae.getOwner().getTeam() != Player.TEAM_NONE)
                                    && (ae.getOwner().getTeam() == ((Entity)target).getOwner().getTeam())))) {
                return new ToHitData(TargetRoll.IMPOSSIBLE, "A friendly unit can never be the target of a direct attack.");
            }
        }

        IHex attHex = game.getBoard().getHex(src);
        IHex targHex = game.getBoard().getHex(target.getPosition());
        final int attackerElevation = elevation + attHex.getElevation();
        final int attackerHeight = attackerElevation + ae.height();
        final int targetElevation = target.getElevation() + targHex.getElevation();
        final int targetHeight = targetElevation + target.getHeight();
        Building bldg = game.getBoard().getBuildingAt(getTargetPos());
        ToHitData toHit = null;
        boolean targIsBuilding = ((getTargetType() == Targetable.TYPE_FUEL_TANK) || (getTargetType() == Targetable.TYPE_BUILDING));

        boolean inSameBuilding = Compute.isInSameBuilding(game, ae, te);

        // can't target yourself
        if (ae.equals(te)) {
            return new ToHitData(TargetRoll.IMPOSSIBLE, "You can't target yourself");
        }

        // Can't target a transported entity.
        if ((te != null) && (Entity.NONE != te.getTransportId())) {
            return new ToHitData(TargetRoll.IMPOSSIBLE, "Target is a passenger.");
        }

        // Can't target a entity conducting a swarm attack.
        if ((te != null) && (Entity.NONE != te.getSwarmTargetId())) {
            return new ToHitData(TargetRoll.IMPOSSIBLE, "Target is swarming a Mek.");
        }

        // check range
        if (src.distance(target.getPosition()) > 1) {
            return new ToHitData(TargetRoll.IMPOSSIBLE, "Target not in range");
        }

        // mechs can only charge standing mechs
        if ((ae instanceof Mech) && !skid) {
            if ((te != null) && !(te instanceof Mech)) {
                return new ToHitData(TargetRoll.IMPOSSIBLE, "Target is not a mech");
            }
            if ((te != null) && te.isProne()) {
                return new ToHitData(TargetRoll.IMPOSSIBLE, "Target is prone");
            }
        } else if (te instanceof Infantry) {
            // Can't charge infantry.
            return new ToHitData(TargetRoll.IMPOSSIBLE, "Target is infantry");
        } else if (te instanceof Protomech) {
            // Can't charge protomechs.
            return new ToHitData(TargetRoll.IMPOSSIBLE, "Target is protomech");
        }

        // target must be within 1 elevation level
        if ((attackerElevation > targetHeight) || (attackerHeight < targetElevation)) {
            return new ToHitData(TargetRoll.IMPOSSIBLE, "Target must be within 1 elevation level");
        }

        // can't attack mech making a different displacement attack
        if ((te != null) && te.hasDisplacementAttack()) {
            return new ToHitData(TargetRoll.IMPOSSIBLE, "Target is already making a charge/DFA attack");
        }

        // target must have moved already, unless it's a skid charge
        if ((te != null) && !te.isDone() && !skid) {
            return new ToHitData(TargetRoll.IMPOSSIBLE, "Target must be done with movement");
        }

        // can't attack the target of another displacement attack
        if ((te != null) && te.isTargetOfDisplacementAttack() && (te.findTargetedDisplacement().getEntityId() != ae.getId())) {
            return new ToHitData(TargetRoll.IMPOSSIBLE, "Target is the target of another charge/DFA");
        }

        // Can't target units in buildings (from the outside).
        if ((null != bldg) && (!targIsBuilding) && (te != null) && Compute.isInBuilding(game, te)) {
            if (!Compute.isInBuilding(game, ae)) {
                return new ToHitData(TargetRoll.IMPOSSIBLE, "Target is inside building");
            } else if (!game.getBoard().getBuildingAt(ae.getPosition()).equals(bldg)) {
                return new ToHitData(TargetRoll.IMPOSSIBLE, "Target is inside differnt building");
            }
        }

        // Attacks against adjacent buildings automatically hit.
        if ((target.getTargetType() == Targetable.TYPE_BUILDING) || (target.getTargetType() == Targetable.TYPE_FUEL_TANK) || (target instanceof GunEmplacement)) {
            return new ToHitData(TargetRoll.AUTOMATIC_SUCCESS, "Targeting adjacent building.");
        }

        // Can't target woods or ignite a building with a physical.
        if ((target.getTargetType() == Targetable.TYPE_BLDG_IGNITE) || (target.getTargetType() == Targetable.TYPE_HEX_CLEAR) || (target.getTargetType() == Targetable.TYPE_HEX_IGNITE)) {
            return new ToHitData(TargetRoll.IMPOSSIBLE, "Invalid attack");
        }

        // Set the base BTH
        int base = ae.getCrew().getPiloting();

        toHit = new ToHitData(base, "base");

        // attacker movement
        toHit.append(Compute.getAttackerMovementModifier(game, ae.getId(), movement));

        // target movement
        toHit.append(Compute.getTargetMovementModifier(game, targetId));

        // attacker terrain
        toHit.append(Compute.getAttackerTerrainModifier(game, ae.getId()));

        // target terrain
        toHit.append(Compute.getTargetTerrainModifier(game, te, 0, inSameBuilding));

        // attacker is spotting
        if (ae.isSpotting()) {
            toHit.addModifier(+1, "attacker is spotting");
        }

        if (te != null) {
            // piloting skill differential
            if (ae.getCrew().getPiloting() != te.getCrew().getPiloting()) {
                toHit.addModifier(ae.getCrew().getPiloting() - te.getCrew().getPiloting(), "piloting skill differential");
            }

            // target prone
            if (te.isProne()) {
                toHit.addModifier(-2, "target prone and adjacent");
            }

            // water partial cover?
            if ((te.height() > 0) && (te.getElevation() == -1) && (targHex.terrainLevel(Terrains.WATER) == te.height())) {
                toHit.addModifier(1, "target has partial cover");
            }
        }

        // If it has a torso-mounted cockpit and two head sensor hits or three
        // sensor hits...
        // It gets a =4 penalty for being blind!
        if ((ae instanceof Mech) && (((Mech) ae).getCockpitType() == Mech.COCKPIT_TORSO_MOUNTED)) {
            int sensorHits = ae.getBadCriticals(CriticalSlot.TYPE_SYSTEM, Mech.SYSTEM_SENSORS, Mech.LOC_HEAD);
            int sensorHits2 = ae.getBadCriticals(CriticalSlot.TYPE_SYSTEM, Mech.SYSTEM_SENSORS, Mech.LOC_CT);
            if ((sensorHits + sensorHits2) == 3) {
                return new ToHitData(TargetRoll.IMPOSSIBLE, "Sensors Completely Destroyed for Torso-Mounted Cockpit");
            } else if (sensorHits == 2) {
                toHit.addModifier(4, "Head Sensors Destroyed for Torso-Mounted Cockpit");
            }
        }

        // target immobile
        toHit.append(Compute.getImmobileMod(te));

        // skids have a penalty for unintentional charge
        if (skid) {
            toHit.addModifier(3, "unintentional charge");
        }

        Compute.modifyPhysicalBTHForAdvantages(ae, te, toHit, game);

        //evading bonuses (
        if(te.isEvading()) {
            toHit.addModifier(te.getEvasionBonus(), "target is evading");
        }

        // determine hit direction
        toHit.setSideTable(te.sideTable(src));

        // all charges resolved against full-body table, except vehicles
        // and charges against mechs in water partial cover
        if ((targHex.terrainLevel(Terrains.WATER) == te.height()) && (te.getElevation() == -1) && (te.height() > 0)) {
            toHit.setHitTable(ToHitData.HIT_PUNCH);
        } else if (ae.getHeight() < target.getHeight()) {
            toHit.setHitTable(ToHitData.HIT_KICK);
        } else {
            toHit.setHitTable(ToHitData.HIT_NORMAL);
        }

        //Attacking Weight Class Modifier.
        if ( game.getOptions().booleanOption("tacops_attack_physical_psr") ) {
            if ( ae.getWeightClass() == EntityWeightClass.WEIGHT_LIGHT ) {
                toHit.addModifier(-2, "Weight Class Attack Modifier");
            }else if ( ae.getWeightClass() == EntityWeightClass.WEIGHT_MEDIUM ) {
                toHit.addModifier(-1, "Weight Class Attack Modifier");
            }
        }

        if ((ae instanceof Mech) && ((Mech)ae).hasIndustrialTSM()) {
            toHit.addModifier(2, "industrial TSM");
        }

        // done!
        return toHit;
    }
View Full Code Here


        int chargeEl = ae.getElevation();
        MoveStep chargeStep = null;

        // let's just check this
        if (!md.contains(MovePath.STEP_CHARGE)) {
            return new ToHitData(TargetRoll.IMPOSSIBLE, "Charge action not found in movment path");
        }

        // no jumping
        if (md.contains(MovePath.STEP_START_JUMP)) {
            return new ToHitData(TargetRoll.IMPOSSIBLE, "No jumping allowed while charging");
        }

        // no backwards
        if (md.contains(MovePath.STEP_BACKWARDS) || md.contains(MovePath.STEP_LATERAL_LEFT_BACKWARDS) || md.contains(MovePath.STEP_LATERAL_RIGHT_BACKWARDS)) {
            return new ToHitData(TargetRoll.IMPOSSIBLE, "No backwards movement allowed while charging");
        }

        //no evading
        if(md.contains(MovePath.STEP_EVADE)) {
            return new ToHitData(TargetRoll.IMPOSSIBLE, "No evading while charging");
        }

        // determine last valid step
        md.compile(game, ae);
        for (final Enumeration<MoveStep> i = md.getSteps(); i.hasMoreElements();) {
            final MoveStep step = i.nextElement();
            if (step.getMovementType() == IEntityMovementType.MOVE_ILLEGAL) {
                break;
            }
            if (step.getType() == MovePath.STEP_CHARGE) {
                chargeStep = step;
            } else {
                chargeSrc = step.getPosition();
                chargeEl = step.getElevation();
            }
        }

        // need to reach target
        if ((chargeStep == null) || !target.getPosition().equals(chargeStep.getPosition())) {
            return new ToHitData(TargetRoll.IMPOSSIBLE, "Could not reach target with movement");
        }
        if (!md.getSecondLastStep().isLegalEndPos()) {
            return new ToHitData(TargetRoll.IMPOSSIBLE, "Violation of stacking limit in second last step");
        }

        return toHit(game, target, chargeSrc, chargeEl, chargeStep.getMovementType(), false, md.contains(MovePath.STEP_GET_UP) || md.contains(MovePath.STEP_CAREFUL_STAND));
    }
View Full Code Here

        // update target panel
        final int weaponId = clientgui.mechD.wPan.getSelectedWeaponNum();
        if ((target != null) && (target.getPosition() != null) && (weaponId != -1)
                && (ce() != null)) {
            ToHitData toHit;
            if (ash.inAimingMode()) {
                Mounted weapon = ce().getEquipment(weaponId);
                boolean aiming = ash.isAimingAtLocation()
                        && ash.allowAimedShotWith(weapon);
                ash.setEnableAll(aiming);
                if (aiming) {
                    toHit = WeaponAttackAction.toHit(client.game, cen, target,
                            weaponId, ash.getAimingAt(), ash.getAimingMode());
                    clientgui.mechD.wPan.wTargetR.setText(target
                            .getDisplayName()
                            + " (" + ash.getAimingLocation() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
                } else {
                    toHit = WeaponAttackAction.toHit(client.game, cen, target,
                            weaponId, Entity.LOC_NONE,
                            IAimingModes.AIM_MODE_NONE);
                    clientgui.mechD.wPan.wTargetR.setText(target
                            .getDisplayName());
                }
                ash.setPartialCover(toHit.getCover());
            } else {
                toHit = WeaponAttackAction.toHit(client.game, cen, target,
                        weaponId, Entity.LOC_NONE, IAimingModes.AIM_MODE_NONE);
                clientgui.mechD.wPan.wTargetR.setText(target.getDisplayName());
            }
            clientgui.mechD.wPan.wRangeR
                    .setText("" + ce().getPosition().distance(target.getPosition())); //$NON-NLS-1$
            if((ce() instanceof Aero) && (target instanceof Aero) && client.game.getBoard().inAtmosphere()) {
                //add altitude difference
                int altdiff = Math.abs(ce().getElevation()-target.getElevation());
                clientgui.mechD.wPan.wRangeR.setText("" + ce().getPosition().distance(target.getPosition()) + " + " + altdiff + " altitude difference"); //$NON-NLS-1$
            }

            Mounted m = ce().getEquipment(weaponId);
            if (m.isUsedThisRound()) {
                clientgui.mechD.wPan.wToHitR.setText(Messages
                        .getString("FiringDisplay.alreadyFired")); //$NON-NLS-1$
                setFireEnabled(false);
            } else if (m.getType().hasFlag(WeaponType.F_AUTO_TARGET)) {
                clientgui.mechD.wPan.wToHitR.setText(Messages
                        .getString("FiringDisplay.autoFiringWeapon")); //$NON-NLS-1$
                setFireEnabled(false);
            } else if (toHit.getValue() == TargetRoll.IMPOSSIBLE) {
                clientgui.mechD.wPan.wToHitR.setText(toHit.getValueAsString());
                setFireEnabled(false);
            } else if (toHit.getValue() == TargetRoll.AUTOMATIC_FAIL) {
                clientgui.mechD.wPan.wToHitR.setText(toHit.getValueAsString());
                setFireEnabled(true);
            } else {
                clientgui.mechD.wPan.wToHitR.setText(toHit.getValueAsString()
                        + " (" + Compute.oddsAbove(toHit.getValue()) + "%)"); //$NON-NLS-1$ //$NON-NLS-2$
                setFireEnabled(true);
            }
            clientgui.mechD.wPan.toHitText.setText(toHit.getDesc());
            setSkipEnabled(true);
        } else {
            clientgui.mechD.wPan.wTargetR.setText("---"); //$NON-NLS-1$
            clientgui.mechD.wPan.wRangeR.setText("---"); //$NON-NLS-1$
            clientgui.mechD.wPan.wToHitR.setText("---"); //$NON-NLS-1$
View Full Code Here

            int sensorHits = ae.getBadCriticals(CriticalSlot.TYPE_SYSTEM,
                    Mech.SYSTEM_SENSORS, Mech.LOC_HEAD);
            int sensorHits2 = ae.getBadCriticals(CriticalSlot.TYPE_SYSTEM,
                    Mech.SYSTEM_SENSORS, Mech.LOC_CT);
            if ((sensorHits + sensorHits2) == 3) {
                toHit = new ToHitData(TargetRoll.IMPOSSIBLE,
                        "Sensors Completely Destroyed for Torso-Mounted Cockpit");
                return;
            } else if (sensorHits == 2) {
                toHit.addModifier(4,
                        "Head Sensors Destroyed for Torso-Mounted Cockpit");
View Full Code Here

        // update target panel
        final int weaponId = clientgui.mechD.wPan.getSelectedWeaponNum();
        if ((target != null) && (target.getPosition() != null) && (weaponId != -1)
                && (ce() != null)) {
            ToHitData toHit;
            if (ash.inAimingMode()) {
                Mounted weapon = ce().getEquipment(weaponId);
                boolean aiming = ash.isAimingAtLocation()
                        && ash.allowAimedShotWith(weapon);
                ash.setEnableAll(aiming);
                if (aiming) {
                    toHit = WeaponAttackAction.toHit(client.game, cen, target,
                            weaponId, ash.getAimingAt(), ash.getAimingMode());
                    clientgui.mechD.wPan.wTargetR.setText(target
                            .getDisplayName()
                            + " (" + ash.getAimingLocation() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
                } else {
                    toHit = WeaponAttackAction.toHit(client.game, cen, target,
                            weaponId, Entity.LOC_NONE,
                            IAimingModes.AIM_MODE_NONE);
                    clientgui.mechD.wPan.wTargetR.setText(target
                            .getDisplayName());
                }
                ash.setPartialCover(toHit.getCover());
            } else {
                toHit = WeaponAttackAction.toHit(client.game, cen, target,
                        weaponId, Entity.LOC_NONE, IAimingModes.AIM_MODE_NONE);
                clientgui.mechD.wPan.wTargetR.setText(target.getDisplayName());
            }
            clientgui.mechD.wPan.wRangeR
                    .setText("" + ce().getPosition().distance(target.getPosition())); //$NON-NLS-1$
            if ((ce() instanceof Aero) && (target instanceof Aero)
                    && client.game.getBoard().inAtmosphere()) {
                // add altitude difference
                int altdiff = Math.abs(ce().getElevation()
                        - target.getElevation());
                clientgui.mechD.wPan.wRangeR
                        .setText("" + ce().getPosition().distance(target.getPosition()) + " + " + altdiff + " altitude"); //$NON-NLS-1$
            }

            Mounted m = ce().getEquipment(weaponId);
            if (m.isUsedThisRound()) {
                clientgui.mechD.wPan.wToHitR.setText(Messages
                        .getString("FiringDisplay.alreadyFired")); //$NON-NLS-1$
                setFireEnabled(false);
            } else if (m.getType().hasFlag(WeaponType.F_AUTO_TARGET)) {
                clientgui.mechD.wPan.wToHitR.setText(Messages
                        .getString("FiringDisplay.autoFiringWeapon")); //$NON-NLS-1$
                setFireEnabled(false);
            } else if (toHit.getValue() == TargetRoll.IMPOSSIBLE) {
                clientgui.mechD.wPan.wToHitR.setText(toHit.getValueAsString());
                setFireEnabled(false);
            } else if (toHit.getValue() == TargetRoll.AUTOMATIC_FAIL) {
                clientgui.mechD.wPan.wToHitR.setText(toHit.getValueAsString());
                setFireEnabled(true);
            } else {
                clientgui.mechD.wPan.wToHitR.setText(toHit.getValueAsString()
                        + " (" + Compute.oddsAbove(toHit.getValue()) + "%)"); //$NON-NLS-1$ //$NON-NLS-2$
                setFireEnabled(true);
            }
            clientgui.mechD.wPan.toHitText.setText(toHit.getDesc());
            setSkipEnabled(true);
        } else {
            clientgui.mechD.wPan.wTargetR.setText("---"); //$NON-NLS-1$
            clientgui.mechD.wPan.wRangeR.setText("---"); //$NON-NLS-1$
            clientgui.mechD.wPan.wToHitR.setText("---"); //$NON-NLS-1$
View Full Code Here

        Report r;

        // get damage, ToHitData and roll from the PhysicalResult
        int damage = pr.damage;
        final ToHitData toHit = pr.toHit;
        int roll = pr.roll;
        final boolean targetInBuilding = Compute.isInBuilding(game, te);
        final boolean glancing = game.getOptions().booleanOption("tacops_glancing_blows") && (roll == toHit.getValue());

        // Set Margin of Success/Failure.
        toHit.setMoS(roll - Math.max(2, toHit.getValue()));
        final boolean directBlow = game.getOptions().booleanOption("tacops_direct_blow") && ((toHit.getMoS() / 3) >= 1);

        // Which building takes the damage?
        Building bldg = game.getBoard().getBuildingAt(target.getPosition());

        if (lastEntityId != ae.getId()) {
            // who is making the attacks
            r = new Report(4005);
            r.subject = ae.getId();
            r.addDesc(ae);
            addReport(r);
        }

        r = new Report(4290);
        r.subject = ae.getId();
        r.indent();
        r.add(legName);
        r.add(target.getDisplayName());
        r.newlines = 0;
        addReport(r);

        if (toHit.getValue() == TargetRoll.IMPOSSIBLE) {
            r = new Report(4075);
            r.subject = ae.getId();
            r.add(toHit.getDesc());
            addReport(r);
            return;
        } else if (toHit.getValue() == TargetRoll.AUTOMATIC_SUCCESS) {
            r = new Report(4080);
            r.subject = ae.getId();
            r.add(toHit.getDesc());
            r.newlines = 0;
            addReport(r);
            roll = Integer.MAX_VALUE;
        } else {
            r = new Report(4025);
            r.subject = ae.getId();
            r.add(toHit.getValue());
            r.add(roll);
            r.newlines = 0;
            addReport(r);
            if (glancing) {
                r = new Report(4030);
                r.subject = ae.getId();
                r.newlines = 0;
                addReport(r);
            }
            if (directBlow) {
                r = new Report(4032);
                r.subject = ae.getId();
                r.newlines = 0;
                addReport(r);
            }

        }

        // do we hit?
        if (roll < toHit.getValue()) {
            // miss
            r = new Report(4035);
            r.subject = ae.getId();
            addReport(r);

            // If the target is in a building, the building absorbs the damage.
            if (targetInBuilding && (bldg != null)) {

                damage += pr.damageRight;
                // Only report if damage was done to the building.
                if (damage > 0) {
                    Vector<Report> buildingReport = damageBuilding(bldg, damage, target.getPosition());
                    for (Report report : buildingReport) {
                        report.subject = ae.getId();
                    }
                    addReport(buildingReport);
                }

            }
            return;
        }

        // Targeting a building.
        if ((target.getTargetType() == Targetable.TYPE_BUILDING) || (target.getTargetType() == Targetable.TYPE_FUEL_TANK)) {
            damage += pr.damageRight;
            // The building takes the full brunt of the attack.
            r = new Report(4040);
            r.subject = ae.getId();
            addReport(r);
            Vector<Report> buildingReport = damageBuilding(bldg, damage, target.getPosition());
            for (Report report : buildingReport) {
                report.subject = ae.getId();
            }
            addReport(buildingReport);

            // Damage any infantry in the hex.
            damageInfantryIn(bldg, damage, target.getPosition());

            // And we're done!
            return;
        }

        r = new Report(4040);
        r.subject = ae.getId();
        r.newlines = 0;
        addReport(r);

        for (int leg = 0; leg < 2; leg++) {
            if (leg == 1) {
                damage = pr.damageRight;
                if (damage == 0) {
                    break;
                }
            }
            HitData hit = te.rollHitLocation(toHit.getHitTable(), toHit.getSideTable());
            hit.setGeneralDamageType(HitData.DAMAGE_ENERGY);

            // The building shields all units from a certain amount of damage.
            // The amount is based upon the building's CF at the phase's start.
            if (targetInBuilding && (bldg != null)) {
                int bldgAbsorbs = (int) Math.ceil(bldg.getPhaseCF(target.getPosition()) / 10.0);
                int toBldg = Math.min(bldgAbsorbs, damage);
                damage -= toBldg;
                addNewLines();
                Vector<Report> buildingReport = damageBuilding(bldg, damage, target.getPosition());
                for (Report report : buildingReport) {
                    report.subject = ae.getId();
                }
                addReport(buildingReport);
            }

            // A building may absorb the entire shot.
            if (damage == 0) {
                r = new Report(4050);
                r.subject = ae.getId();
                r.add(te.getShortName());
                r.add(te.getOwner().getName());
                r.newlines = 0;
                addReport(r);
            } else {
                if (glancing) {
                    damage = (int) Math.floor(damage / 2.0);
                }
                if (directBlow) {
                    damage += toHit.getMoS() / 3;
                    hit.makeDirectBlow(toHit.getMoS() / 3);
                }
                addReport(damageEntity(te, hit, damage, false, DamageType.NONE, false, false, throughFront));
            }
        }
View Full Code Here

    private void resolveProtoAttack(PhysicalResult pr, int lastEntityId) {
        final ProtomechPhysicalAttackAction ppaa = (ProtomechPhysicalAttackAction) pr.aaa;
        final Entity ae = game.getEntity(ppaa.getEntityId());
        // get damage, ToHitData and roll from the PhysicalResult
        int damage = pr.damage;
        final ToHitData toHit = pr.toHit;
        int roll = pr.roll;
        final Targetable target = game.getTarget(ppaa.getTargetType(), ppaa.getTargetId());
        Entity te = null;
        if (target.getTargetType() == Targetable.TYPE_ENTITY) {
            te = (Entity) target;
        }
        boolean throughFront = true;
        if (te != null) {
            throughFront = Compute.isThroughFrontHex(game, ae.getPosition(), te);
        }
        final boolean targetInBuilding = Compute.isInBuilding(game, te);
        final boolean glancing = game.getOptions().booleanOption("tacops_glancing_blows") && (roll == toHit.getValue());
        // Set Margin of Success/Failure.
        toHit.setMoS(roll - Math.max(2, toHit.getValue()));
        final boolean directBlow = game.getOptions().booleanOption("tacops_direct_blow") && ((toHit.getMoS() / 3) >= 1);

        Report r;

        // Which building takes the damage?
        Building bldg = game.getBoard().getBuildingAt(target.getPosition());

        if (lastEntityId != ae.getId()) {
            // who is making the attacks
            r = new Report(4005);
            r.subject = ae.getId();
            r.addDesc(ae);
            addReport(r);
        }

        r = new Report(4070);
        r.subject = ae.getId();
        r.indent();
        r.add(target.getDisplayName());
        r.newlines = 0;
        addReport(r);

        if (toHit.getValue() == TargetRoll.IMPOSSIBLE) {
            r = new Report(4075);
            r.subject = ae.getId();
            r.add(toHit.getDesc());
            addReport(r);
            return;
        } else if (toHit.getValue() == TargetRoll.AUTOMATIC_SUCCESS) {
            r = new Report(4080);
            r.subject = ae.getId();
            r.add(toHit.getDesc());
            r.newlines = 0;
            addReport(r);
            roll = Integer.MAX_VALUE;
        } else {
            // report the roll
            r = new Report(4025);
            r.subject = ae.getId();
            r.add(toHit.getValue());
            r.add(roll);
            r.newlines = 0;
            addReport(r);
            if (glancing) {
                r = new Report(4030);
                r.subject = ae.getId();
                r.newlines = 0;
                addReport(r);
            }
            if (directBlow) {
                r = new Report(4032);
                r.subject = ae.getId();
                r.newlines = 0;
                addReport(r);
            }

        }

        // do we hit?
        if (roll < toHit.getValue()) {
            // miss
            r = new Report(4035);
            r.subject = ae.getId();
            addReport(r);

            // If the target is in a building, the building absorbs the damage.
            if (targetInBuilding && (bldg != null)) {

                // Only report if damage was done to the building.
                if (damage > 0) {
                    Vector<Report> buildingReport = damageBuilding(bldg, damage, target.getPosition());
                    for (Report report : buildingReport) {
                        report.subject = ae.getId();
                    }
                    addReport(buildingReport);
                }

            }
            return;
        }

        // Targeting a building.
        if ((target.getTargetType() == Targetable.TYPE_BUILDING) || (target.getTargetType() == Targetable.TYPE_FUEL_TANK)) {
            // The building takes the full brunt of the attack.
            r = new Report(4040);
            r.subject = ae.getId();
            addReport(r);
            Vector<Report> buildingReport = damageBuilding(bldg, damage, target.getPosition());
            for (Report report : buildingReport) {
                report.subject = ae.getId();
            }
            addReport(buildingReport);

            // Damage any infantry in the hex.
            damageInfantryIn(bldg, damage, target.getPosition());

            // And we're done!
            return;
        }

        HitData hit = te.rollHitLocation(toHit.getHitTable(), toHit.getSideTable());
        hit.setGeneralDamageType(HitData.DAMAGE_PHYSICAL);

        r = new Report(4045);
        r.subject = ae.getId();
        r.add(toHit.getTableDesc());
        r.add(te.getLocationAbbr(hit));
        r.newlines = 0;
        addReport(r);

        // The building shields all units from a certain amount of damage.
        // The amount is based upon the building's CF at the phase's start.
        if (targetInBuilding && (bldg != null)) {
            int bldgAbsorbs = (int) Math.ceil(bldg.getPhaseCF(target.getPosition()) / 10.0);
            int toBldg = Math.min(bldgAbsorbs, damage);
            damage -= toBldg;
            addNewLines();
            Vector<Report> buildingReport = damageBuilding(bldg, damage, target.getPosition());
            for (Report report : buildingReport) {
                report.subject = ae.getId();
            }
            addReport(buildingReport);
        }

        // A building may absorb the entire shot.
        if (damage == 0) {
            r = new Report(4050);
            r.subject = ae.getId();
            r.add(te.getShortName());
            r.add(te.getOwner().getName());
            r.newlines = 0;
            addReport(r);
        } else {
            if (glancing) {
                damage = (int) Math.floor(damage / 2.0);
            }
            if (directBlow) {
                damage += toHit.getMoS() / 3;
                hit.makeDirectBlow(toHit.getMoS() / 3);
            }
            addReport(damageEntity(te, hit, damage, false, DamageType.NONE, false, false, throughFront));
        }

        addNewLines();
View Full Code Here

        }

        // get damage, ToHitData and roll from the PhysicalResult
        // ASSUMPTION: buildings can't absorb *this* damage.
        int damage = baa.getArm() == BrushOffAttackAction.LEFT ? pr.damage : pr.damageRight;
        final ToHitData toHit = baa.getArm() == BrushOffAttackAction.LEFT ? pr.toHit : pr.toHitRight;
        int roll = baa.getArm() == BrushOffAttackAction.LEFT ? pr.roll : pr.rollRight;

        if (lastEntityId != baa.getEntityId()) {
            // who is making the attacks
            r = new Report(4005);
            r.subject = ae.getId();
            r.addDesc(ae);
            addReport(r);
        }

        r = new Report(4085);
        r.subject = ae.getId();
        r.indent();
        r.add(target.getDisplayName());
        r.add(armName);
        r.newlines = 0;
        addReport(r);

        if (toHit.getValue() == TargetRoll.IMPOSSIBLE) {
            r = new Report(4090);
            r.subject = ae.getId();
            r.add(toHit.getDesc());
            addReport(r);
            return;
        }

        // report the roll
        r = new Report(4025);
        r.subject = ae.getId();
        r.add(toHit.getValue());
        r.add(roll);
        r.newlines = 0;
        addReport(r);

        // do we hit?
        if (roll < toHit.getValue()) {
            // miss
            r = new Report(4035);
            r.subject = ae.getId();
            addReport(r);

            // Missed Brush Off attacks cause punch damage to the attacker.
            toHit.setHitTable(ToHitData.HIT_PUNCH);
            toHit.setSideTable(ToHitData.SIDE_FRONT);
            HitData hit = ae.rollHitLocation(toHit.getHitTable(), toHit.getSideTable());
            hit.setGeneralDamageType(HitData.DAMAGE_PHYSICAL);
            r = new Report(4095);
            r.subject = ae.getId();
            r.addDesc(ae);
            r.add(ae.getLocationAbbr(hit));
            r.newlines = 0;
            addReport(r);
            addReport(damageEntity(ae, hit, damage));
            addNewLines();
            //if this is an industrial mech, it needs to check for crits
            //at the end of turn
            if ((ae instanceof Mech) && ((Mech)ae).isIndustrial()) {
                ((Mech)ae).setCheckForCrit(true);
            }
            return;
        }

        // Different target types get different handling.
        switch (target.getTargetType()) {
        case Targetable.TYPE_ENTITY:
            // Handle Entity targets.
            HitData hit = te.rollHitLocation(toHit.getHitTable(), toHit.getSideTable());
            hit.setGeneralDamageType(HitData.DAMAGE_PHYSICAL);
            r = new Report(4045);
            r.subject = ae.getId();
            r.add(toHit.getTableDesc());
            r.add(te.getLocationAbbr(hit));
            r.newlines = 0;
            addReport(r);
            addReport(damageEntity(te, hit, damage));
            addNewLines();
View Full Code Here

        final ThrashAttackAction taa = (ThrashAttackAction) pr.aaa;
        final Entity ae = game.getEntity(taa.getEntityId());

        // get damage, ToHitData and roll from the PhysicalResult
        int hits = pr.damage;
        final ToHitData toHit = pr.toHit;
        int roll = pr.roll;
        final boolean glancing = game.getOptions().booleanOption("tacops_glancing_blows") && (roll == toHit.getValue());

        // Set Margin of Success/Failure.
        toHit.setMoS(roll - Math.max(2, toHit.getValue()));
        final boolean directBlow = game.getOptions().booleanOption("tacops_direct_blow") && ((toHit.getMoS() / 3) >= 1);

        // PLEASE NOTE: buildings are *never* the target of a "thrash".
        final Entity te = game.getEntity(taa.getTargetId());
        Report r;

        if (lastEntityId != taa.getEntityId()) {
            // who is making the attacks
            r = new Report(4005);
            r.subject = ae.getId();
            r.addDesc(ae);
            addReport(r);
        }

        r = new Report(4110);
        r.subject = ae.getId();
        r.indent();
        r.addDesc(te);
        r.newlines = 0;
        addReport(r);

        if (toHit.getValue() == TargetRoll.IMPOSSIBLE) {
            r = new Report(4115);
            r.subject = ae.getId();
            r.add(toHit.getDesc());
            addReport(r);
            return;
        }

        // Thrash attack may hit automatically
        if (toHit.getValue() == TargetRoll.AUTOMATIC_SUCCESS) {
            r = new Report(4120);
            r.subject = ae.getId();
            r.newlines = 0;
            addReport(r);
        } else {
            // report the roll
            r = new Report(4025);
            r.subject = ae.getId();
            r.add(toHit.getValue());
            r.add(roll);
            r.newlines = 0;
            addReport(r);

            // do we hit?
            if (roll < toHit.getValue()) {
                // miss
                r = new Report(4035);
                r.subject = ae.getId();
                addReport(r);
                return;
            }
            r = new Report(4125);
            r.subject = ae.getId();
            r.newlines = 0;
            addReport(r);
        }

        // Standard damage loop in 5 point clusters.
        if (glancing) {
            hits = (int) Math.floor(hits / 2.0);
        }
        if (directBlow) {
            hits += toHit.getMoS() / 3;
        }

        r = new Report(4130);
        r.subject = ae.getId();
        r.add(hits);
        r.newlines = 0;
        addReport(r);
        if (glancing) {
            r = new Report(4030);
            r.subject = ae.getId();
            r.newlines = 0;
            addReport(r);
        }
        if (directBlow) {
            r = new Report(4032);
            r.subject = ae.getId();
            r.newlines = 0;
            addReport(r);
        }

        while (hits > 0) {
            int damage = Math.min(5, hits);
            hits -= damage;
            HitData hit = te.rollHitLocation(toHit.getHitTable(), toHit.getSideTable());
            hit.setGeneralDamageType(HitData.DAMAGE_PHYSICAL);
            r = new Report(4135);
            r.subject = ae.getId();
            r.add(te.getLocationAbbr(hit));
            r.newlines = 0;
View Full Code Here

        final BAVibroClawAttackAction bvaa = (BAVibroClawAttackAction) pr.aaa;
        final Entity ae = game.getEntity(bvaa.getEntityId());

        // get damage, ToHitData and roll from the PhysicalResult
        int hits = pr.damage;
        final ToHitData toHit = pr.toHit;
        int roll = pr.roll;
        final boolean glancing = game.getOptions().booleanOption("tacops_glancing_blows") && (roll == toHit.getValue());

        // Set Margin of Success/Failure.
        toHit.setMoS(roll - Math.max(2, toHit.getValue()));
        final boolean directBlow = game.getOptions().booleanOption("tacops_direct_blow") && ((toHit.getMoS() / 3) >= 1);

        // PLEASE NOTE: buildings are *never* the target of a BA vibroclaw attack.
        final Entity te = game.getEntity(bvaa.getTargetId());
        Report r;

        if (lastEntityId != bvaa.getEntityId()) {
            // who is making the attacks
            r = new Report(4005);
            r.subject = ae.getId();
            r.addDesc(ae);
            addReport(r);
        }

        r = new Report(4146);
        r.subject = ae.getId();
        r.indent();
        r.addDesc(te);
        r.newlines = 0;
        addReport(r);

        if (toHit.getValue() == TargetRoll.IMPOSSIBLE) {
            r = new Report(4147);
            r.subject = ae.getId();
            r.add(toHit.getDesc());
            addReport(r);
            return;
        }

        // we may hit automatically
        if (toHit.getValue() == TargetRoll.AUTOMATIC_SUCCESS) {
            r = new Report(4120);
            r.subject = ae.getId();
            r.newlines = 0;
            addReport(r);
        } else {
            // report the roll
            r = new Report(4025);
            r.subject = ae.getId();
            r.add(toHit.getValue());
            r.add(roll);
            r.newlines = 0;
            addReport(r);

            // do we hit?
            if (roll < toHit.getValue()) {
                // miss
                r = new Report(4035);
                r.subject = ae.getId();
                addReport(r);
                return;
            }
        }

        // Standard damage loop
        if (glancing) {
            hits = (int) Math.floor(hits / 2.0);
        }
        if (directBlow) {
            hits += toHit.getMoS() / 3;
        }
        if ((te instanceof Infantry) && !(te instanceof BattleArmor)) {
            r = new Report(4149);
            r.subject = ae.getId();
        } else {
            r = new Report(4148);
            r.subject = ae.getId();
            r.add(hits);
            r.add(ae.getVibroClaws());
        }
        r.newlines = 0;
        addReport(r);
        if (glancing) {
            r = new Report(4030);
            r.subject = ae.getId();
            r.newlines = 0;
            addReport(r);
        }
        if (directBlow) {
            r = new Report(4032);
            r.subject = ae.getId();
            r.newlines = 0;
            addReport(r);
        }
        while (hits > 0) {
            // BA get hit seperately by each attacking BA trooper
            int damage = Math.min(ae.getVibroClaws(), hits);
            // conv infantry get hit in one lump
            if ((te instanceof Infantry) && !(te instanceof BattleArmor)) {
                damage = hits;
            }
            hits -= damage;
            HitData hit = te.rollHitLocation(toHit.getHitTable(), toHit.getSideTable());
            hit.setGeneralDamageType(HitData.DAMAGE_PHYSICAL);
            r = new Report(4135);
            r.subject = ae.getId();
            r.add(te.getLocationAbbr(hit));
            r.newlines = 0;
View Full Code Here

TOP

Related Classes of megamek.common.ToHitData

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.