Package megamek.common

Examples of megamek.common.ToHitData


    private void resolveClubAttack(PhysicalResult pr, int lastEntityId) {
        final ClubAttackAction caa = (ClubAttackAction) pr.aaa;
        final Entity ae = game.getEntity(caa.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(caa.getTargetType(), caa.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());

        // restore club attack
        caa.getClub().restore();

        // Shield bash causes 1 point of damage to the shield
        if (((MiscType) caa.getClub().getType()).isShield()) {
            ((Mech) ae).shieldAbsorptionDamage(1, caa.getClub().getLocation(), false);
        }

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

        r = new Report(4145);
        r.subject = ae.getId();
        r.indent();
        r.add(caa.getClub().getName());
        r.add(target.getDisplayName());
        r.newlines = 0;
        addReport(r);

        // Flail/Wrecking Ball auto misses on a 2 and hits themself.
        if ((((MiscType) caa.getClub().getType()).hasSubType(MiscType.S_FLAIL)
                || ((MiscType) caa.getClub().getType()).hasSubType(MiscType.S_WRECKING_BALL))
                && (roll == 2)) {
            // miss
            r = new Report(4035);
            r.subject = ae.getId();
            addReport(r);
            ToHitData newToHit = new ToHitData(TargetRoll.AUTOMATIC_SUCCESS, "hit with own flail/wrecking ball");
            pr.damage /= 2;
            newToHit.setHitTable(ToHitData.HIT_NORMAL);
            newToHit.setSideTable(ToHitData.SIDE_FRONT);
            pr.toHit = newToHit;
            pr.aaa.setTargetId(ae.getId());
            pr.aaa.setTargetType(Targetable.TYPE_ENTITY);
            pr.roll = Integer.MAX_VALUE;
            resolveClubAttack(pr, ae.getId());
            game.addPSR(new PilotingRollData(ae.getId(), 0, "missed a flail/wrecking ball attack"));
            return;
        }

        // Need to compute 2d6 damage. and add +3 heat build up.
        if (((MiscType) (caa.getClub().getType())).hasSubType(MiscType.S_BUZZSAW)) {

            damage = Compute.d6(2);
            ae.heatBuildup += 3;

            // Buzzsaw's blade will shatter on a roll of 2.
            if (roll == 2) {

                Mounted club = caa.getClub();

                for (Mounted eq : ae.getWeaponList()) {
                    if ((eq.getLocation() == club.getLocation()) && (eq.getType() instanceof MiscType) && ((MiscType) eq.getType()).hasFlag(MiscType.F_CLUB) && ((MiscType) eq.getType()).hasSubType(MiscType.S_BUZZSAW)) {
                        eq.setDestroyed(true);
                        break;
                    }
                }
                r = new Report(4037);
                r.subject = ae.getId();
                addReport(r);
                damage = 0;
                return;
            }
        }

        if (toHit.getValue() == TargetRoll.IMPOSSIBLE) {
            r = new Report(4075);
            r.subject = ae.getId();
            r.add(toHit.getDesc());
            addReport(r);
            if (((MiscType) caa.getClub().getType()).hasSubType(MiscType.S_MACE_THB)) {
                game.addPSR(new PilotingRollData(ae.getId(), 0, "missed a mace attack"));
            }
            if (((MiscType) caa.getClub().getType()).hasSubType(MiscType.S_MACE)) {
                game.addPSR(new PilotingRollData(ae.getId(), 2, "missed a mace attack"));
            }
            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 (((MiscType) caa.getClub().getType()).hasSubType(MiscType.S_MACE_THB)) {
                game.addPSR(new PilotingRollData(ae.getId(), 0, "missed a mace attack"));
            }
            if (((MiscType) caa.getClub().getType()).hasSubType(MiscType.S_MACE)) {
                game.addPSR(new PilotingRollData(ae.getId(), 2, "missed a mace attack"));
            }

            // 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);
            }

            /*if (damage >= 1 && te.hasWorkingMisc(MiscType.F_SPIKES, -1, hit.getLocation())) {
                r = new Report(4330);
                r.indent(2);
                r.newlines = 0;
                r.subject = ae.getId();
                addReport(r);
                checkBreakSpikes(te, hit.getLocation());
                damage = Math.max(1, damage - 4);
                int loc = caa.getClub().getLocation();
                if (loc == Entity.LOC_NONE) {
                    addReport(damageEntity(ae, new HitData(Mech.LOC_LARM), 1, false, DamageType.NONE, false, false, false));
                    addReport(damageEntity(ae, new HitData(Mech.LOC_RARM), 1, false, DamageType.NONE, false, false, false));
                } else {
                    addReport(damageEntity(ae, new HitData(loc), 2, false, DamageType.NONE, false, false, false));
                }
            }*/
            DamageType damageType = DamageType.NONE;
            addReport(damageEntity(te, hit, damage, false, damageType, false, false, throughFront));
            if (target instanceof VTOL) {
                // destroy rotor
                addReport(applyCriticalHit(te, VTOL.LOC_ROTOR, new CriticalSlot(CriticalSlot.TYPE_SYSTEM, VTOL.CRIT_ROTOR_DESTROYED), false));
            }
        }

        // On a roll of 10+ a lance hitting a mech/Vehicle can cause 1 point of
        // internal damage
        if (((MiscType) caa.getClub().getType()).hasSubType(MiscType.S_LANCE) && (te.getArmor(hit) > 0) && (te.getArmorType() != EquipmentType.T_ARMOR_HARDENED)) {
            roll = Compute.d6(2);
            // Pierce checking report
            r = new Report(4021);
            r.indent(2);
            r.subject = ae.getId();
            r.add(te.getLocationAbbr(hit));
            r.add(roll);
            r.newlines = 1;
            addReport(r);
            if (roll >= 10) {
                hit.makeGlancingBlow();
                addReport(damageEntity(te, hit, 1, false, DamageType.NONE, true, false, throughFront));
            }
        }

        if (((MiscType) caa.getClub().getType()).hasSubType(MiscType.S_CHAIN_WHIP)
                && (te instanceof Mech)) {
            addNewLines();

            int loc = hit.getLocation();
            int toHitNumber = toHit.getValue();

            if ( ((loc == Mech.LOC_LLEG) || (loc == Mech.LOC_RLEG)) && (!te.hasActiveShield(loc) && !te.hasPassiveShield(loc))) {

                roll = Compute.d6(2);

                if ( (((Mech)ae).hasTSM() && (ae.heat >= 9))
                        && (!((Mech)te).hasTSM() || ((((Mech)te).hasTSM()) && (te.heat < 9))) ) {
                    toHitNumber -= 2;
                }

                r = new Report(4450);
                r.subject = ae.getId();
                r.add(ae.getShortName());
                r.add(te.getShortName());
                r.add(toHitNumber);
                r.add(roll);
                r.indent(2);
                r.newlines = 0;
                addReport(r);

                if ( roll >= toHit.getValue() ) {
                    r = new Report(2270);
                    r.subject = ae.getId();
                    r.newlines = 0;
                    addReport(r);

                    game.addPSR(new PilotingRollData(te.getId(),3,"Snared by chain whip"));
                }else {
                    r = new Report(2357);
                    r.subject = ae.getId();
                    r.newlines = 0;
                    addReport(r);
                }
            } else if ( ((loc == Mech.LOC_RARM) || (loc == Mech.LOC_LARM))
                    && (!te.hasActiveShield(loc) && !te.hasPassiveShield(loc) && !te.hasNoDefenseShield(loc)) ) {
                GrappleAttackAction gaa = new GrappleAttackAction(ae.getId(),te.getId());
                ToHitData grappleHit = GrappleAttackAction.toHit(game, ae.getId(), target);
                PhysicalResult grappleResult = new PhysicalResult();
                grappleResult.aaa = gaa;
                grappleResult.toHit = grappleHit;
                grappleResult.roll = Compute.d6(2);
                resolveGrappleAttack(grappleResult, lastEntityId, hit.getLocation() == Mech.LOC_RARM ? Entity.GRAPPLE_RIGHT : Entity.GRAPPLE_LEFT );
View Full Code Here


        final Entity ae = game.getEntity(paa.getEntityId());
        // PLEASE NOTE: buildings are *never* the target of a "push".
        final Entity te = game.getEntity(paa.getTargetId());
        // get roll and ToHitData from the PhysicalResult
        int roll = pr.roll;
        final ToHitData toHit = pr.toHit;
        Report r;

        // was this push resolved earlier?
        if (pr.pushBackResolved) {
            return;
        }
        // don't try this one again
        pr.pushBackResolved = true;

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

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

        if (toHit.getValue() == TargetRoll.IMPOSSIBLE) {
            r = new Report(4160);
            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);

        // check if our target has a push against us, too, and get it
        PhysicalResult targetPushResult = null;
        for (PhysicalResult tpr : physicalResults) {
            if ((tpr.aaa.getEntityId() == te.getId()) && (tpr.aaa instanceof PushAttackAction) && (tpr.aaa.getTargetId() == ae.getId())) {
                targetPushResult = tpr;
            }
        }
        // if our target has a push against us,
        // and we are hitting, we need to resolve both now
        if ((targetPushResult != null) && !targetPushResult.pushBackResolved && (roll >= toHit.getValue())) {
            targetPushResult.pushBackResolved = true;
            // do they hit?
            if (targetPushResult.roll >= targetPushResult.toHit.getValue()) {
                r = new Report(4165);
                r.subject = ae.getId();
                r.addDesc(te);
                r.addDesc(te);
                r.addDesc(ae);
                r.add(targetPushResult.toHit.getValue());
                r.add(targetPushResult.roll);
                r.addDesc(ae);
                addReport(r);
                PilotingRollData targetPushPRD = getKickPushPSR(te, ae, te, "was pushed");
                PilotingRollData pushPRD = getKickPushPSR(ae, ae, te, "was pushed");
                game.addPSR(pushPRD);
                game.addPSR(targetPushPRD);
                return;
            }
            // report the miss
            r = new Report(4166);
            r.subject = ae.getId();
            r.addDesc(te);
            r.addDesc(ae);
            r.add(targetPushResult.toHit.getValue());
            r.add(targetPushResult.roll);
            addReport(r);
        }

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

        final Entity ae = game.getEntity(paa.getEntityId());
        // PLEASE NOTE: buildings are *never* the target of a "trip".
        final Entity te = game.getEntity(paa.getTargetId());
        // get roll and ToHitData from the PhysicalResult
        int roll = pr.roll;
        final ToHitData toHit = pr.toHit;
        Report r;

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

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

        if (toHit.getValue() == TargetRoll.IMPOSSIBLE) {
            r = new Report(4285);
            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);
            return;
View Full Code Here

        final Entity ae = game.getEntity(paa.getEntityId());
        // PLEASE NOTE: buildings are *never* the target of a "push".
        final Entity te = game.getEntity(paa.getTargetId());
        // get roll and ToHitData from the PhysicalResult
        int roll = pr.roll;
        final ToHitData toHit = pr.toHit;
        Report r;

        // same method as push, for counterattacks
        if (pr.pushBackResolved) {
            return;
        }

        if ((te.getGrappled() != Entity.NONE) || (ae.getGrappled() != Entity.NONE)) {
            toHit.addModifier(TargetRoll.IMPOSSIBLE, "Already Grappled");
        }

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

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

        if (toHit.getValue() == TargetRoll.IMPOSSIBLE) {
            r = new Report(4300);
            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);
            return;
View Full Code Here

        final Entity ae = game.getEntity(paa.getEntityId());
        // PLEASE NOTE: buildings are *never* the target of a "push".
        final Entity te = game.getEntity(paa.getTargetId());
        // get roll and ToHitData from the PhysicalResult
        int roll = pr.roll;
        final ToHitData toHit = pr.toHit;
        Report r;

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

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

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

        if (toHit.getValue() == TargetRoll.AUTOMATIC_SUCCESS) {
            r = new Report(4320);
            r.subject = ae.getId();
            r.add(toHit.getDesc());
            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;
            }

            // hit
            r = new Report(4040);
            r.subject = ae.getId();
            addReport(r);
        }

        // is there a counterattack?
        PhysicalResult targetGrappleResult = null;
        for (PhysicalResult tpr : physicalResults) {
            if ((tpr.aaa.getEntityId() == te.getId()) && (tpr.aaa instanceof GrappleAttackAction) && (tpr.aaa.getTargetId() == ae.getId())) {
                targetGrappleResult = tpr;
                break;
            }
        }

        if (targetGrappleResult != null) {
            targetGrappleResult.pushBackResolved = true;
            // counterattack
            r = new Report(4315);
            r.subject = te.getId();
            r.newlines = 0;
            r.addDesc(te);
            addReport(r);

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

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

            throughFront = Compute.isThroughFrontHex(game, ae.getPosition(), te);
        }
        final String armName = paa.getArm() == PunchAttackAction.LEFT ? "Left Arm" : "Right Arm";
        // get damage, ToHitData and roll from the PhysicalResult
        int damage = paa.getArm() == PunchAttackAction.LEFT ? pr.damage : pr.damageRight;
        final ToHitData toHit = paa.getArm() == PunchAttackAction.LEFT ? pr.toHit : pr.toHitRight;
        int roll = paa.getArm() == PunchAttackAction.LEFT ? pr.roll : pr.rollRight;
        final boolean targetInBuilding = Compute.isInBuilding(game, te);
        final boolean glancing = game.getOptions().booleanOption("tacops_glancing_blows") && (roll == toHit.getValue());

        Report r;
        // 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 != paa.getEntityId()) {
            // report who is making the attacks
            r = new Report(4005);
            r.subject = ae.getId();
            r.addDesc(ae);
            addReport(r);
        }

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

        if (toHit.getValue() == TargetRoll.IMPOSSIBLE) {
            r = new Report(4015);
            r.subject = ae.getId();
            r.add(toHit.getDesc());
            addReport(r);
            return;
        } else if (toHit.getValue() == TargetRoll.AUTOMATIC_SUCCESS) {
            r = new Report(4020);
            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()) {
            // nope
            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, toBldg, 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);
            }

            if ((damage >= 1) && te.hasWorkingMisc(MiscType.F_SPIKES, -1, hit.getLocation())) {
                r = new Report(4330);
                r.indent(2);
View Full Code Here

        legName.concat("leg");
        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(4055);
        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(4060);
            r.subject = ae.getId();
            r.add(toHit.getDesc());
            addReport(r);
            game.addPSR(new PilotingRollData(ae.getId(), 0, "missed a kick"));
            return;
        } else if (toHit.getValue() == TargetRoll.AUTOMATIC_SUCCESS) {
            r = new Report(4065);
            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);
            game.addPSR(new PilotingRollData(ae.getId(), 0, "missed a kick"));

            // 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);
            }

            if ((damage >= 1) && te.hasWorkingMisc(MiscType.F_SPIKES, -1, hit.getLocation())) {
                r = new Report(4330);
                r.indent(2);
View Full Code Here

     */
    private PhysicalResult preTreatPhysicalAttack(AbstractAttackAction aaa) {
        final Entity ae = game.getEntity(aaa.getEntityId());
        int damage = 0;
        PhysicalResult pr = new PhysicalResult();
        ToHitData toHit = new ToHitData();
        pr.roll = Compute.d6(2);
        pr.aaa = aaa;
        if (aaa instanceof BrushOffAttackAction) {
            BrushOffAttackAction baa = (BrushOffAttackAction) aaa;
            int arm = baa.getArm();
            baa.setArm(BrushOffAttackAction.LEFT);
            toHit = BrushOffAttackAction.toHit(game, aaa.getEntityId(), aaa.getTarget(game), BrushOffAttackAction.LEFT);
            baa.setArm(BrushOffAttackAction.RIGHT);
            pr.toHitRight = BrushOffAttackAction.toHit(game, aaa.getEntityId(), aaa.getTarget(game), BrushOffAttackAction.RIGHT);
            damage = BrushOffAttackAction.getDamageFor(ae, BrushOffAttackAction.LEFT);
            pr.damageRight = BrushOffAttackAction.getDamageFor(ae, BrushOffAttackAction.RIGHT);
            baa.setArm(arm);
            pr.rollRight = Compute.d6(2);
        } else if (aaa instanceof ChargeAttackAction) {
            ChargeAttackAction caa = (ChargeAttackAction) aaa;
            toHit = caa.toHit(game);
            if (caa.getTarget(game) instanceof Entity) {
                Entity target = (Entity) caa.getTarget(game);
                damage = ChargeAttackAction.getDamageFor(ae, target, game.getOptions().booleanOption("tacops_charge_damage"), toHit.getMoS());
            } else {
                damage = ChargeAttackAction.getDamageFor(ae);
            }
        } else if (aaa instanceof ClubAttackAction) {
            ClubAttackAction caa = (ClubAttackAction) aaa;
            toHit = caa.toHit(game);
            damage = ClubAttackAction.getDamageFor(ae, caa.getClub(), (caa.getTarget(game) instanceof Infantry) && !(caa.getTarget(game) instanceof BattleArmor));
        } else if (aaa instanceof DfaAttackAction) {
            DfaAttackAction daa = (DfaAttackAction) aaa;
            toHit = daa.toHit(game);
            damage = DfaAttackAction.getDamageFor(ae, (daa.getTarget(game) instanceof Infantry) && !(daa.getTarget(game) instanceof BattleArmor));
        } else if (aaa instanceof KickAttackAction) {
            KickAttackAction kaa = (KickAttackAction) aaa;
            toHit = kaa.toHit(game);
            damage = KickAttackAction.getDamageFor(ae, kaa.getLeg(), (kaa.getTarget(game) instanceof Infantry) && !(kaa.getTarget(game) instanceof BattleArmor));
        } else if (aaa instanceof ProtomechPhysicalAttackAction) {
            ProtomechPhysicalAttackAction paa = (ProtomechPhysicalAttackAction) aaa;
            toHit = paa.toHit(game);
            damage = ProtomechPhysicalAttackAction.getDamageFor(ae);
        } else if (aaa instanceof PunchAttackAction) {
            PunchAttackAction paa = (PunchAttackAction) aaa;
            int arm = paa.getArm();
            int damageRight = 0;
            paa.setArm(PunchAttackAction.LEFT);
            toHit = paa.toHit(game);
            paa.setArm(PunchAttackAction.RIGHT);
            ToHitData toHitRight = paa.toHit(game);
            damage = PunchAttackAction.getDamageFor(ae, PunchAttackAction.LEFT, (paa.getTarget(game) instanceof Infantry) && !(paa.getTarget(game) instanceof BattleArmor));
            damageRight = PunchAttackAction.getDamageFor(ae, PunchAttackAction.RIGHT, (paa.getTarget(game) instanceof Infantry) && !(paa.getTarget(game) instanceof BattleArmor));
            paa.setArm(arm);
            // If we're punching while prone (at a Tank,
            // duh), then we can only use one arm.
            if (ae.isProne()) {
                double oddsLeft = Compute.oddsAbove(toHit.getValue());
                double oddsRight = Compute.oddsAbove(toHitRight.getValue());
                // Use the best attack.
                if (oddsLeft * damage > oddsRight * damageRight) {
                    paa.setArm(PunchAttackAction.LEFT);
                } else {
                    paa.setArm(PunchAttackAction.RIGHT);
View Full Code Here

        // get units in hex
        for (Enumeration<Entity> impactHexHits = game.getEntities(coords); impactHexHits.hasMoreElements();) {
            Entity entity = impactHexHits.nextElement();
            int hits = damage;
            ToHitData toHit = new ToHitData();
            int cluster = 5;

            // Check: is entity excluded?
            if (entity == exclude) {
                continue;
            }

            // Check: is entity inside building?
            if ((bldg != null) && (bldgAbsorbs > 0) && (entity.getElevation() < hex.terrainLevel(Terrains.BLDG_ELEV))) {
                cluster -= bldgAbsorbs;
                if (entity instanceof Infantry) {
                    continue; // took its damage already from building damage
                } else if (cluster <= 0) {
                    // entity takes no damage
                    r = new Report(6426);
                    r.subject = subjectId;
                    r.addDesc(entity);
                    vPhaseReport.add(r);
                    continue;
                } else {
                    r = new Report(6425);
                    r.subject = subjectId;
                    r.add(bldgAbsorbs);
                    vPhaseReport.add(r);
                }
            }

            if (flak) {
                // Check: is entity not a VTOL in flight
                if (!((entity instanceof VTOL) || (entity.getMovementMode() == IEntityMovementMode.VTOL))) {
                    continue;
                }
                // Check: is entity at correct elevation?
                if (entity.getElevation() != flakElevation) {
                    continue;
                }
            } else {
                // Check: is entity a VTOL in flight?
                if ((entity instanceof VTOL) || (entity.getMovementMode() == IEntityMovementMode.VTOL)) {
                    // VTOLs take no damage from normal artillery unless landed
                    if ((entity.getElevation() != 0) && (entity.getElevation() != hex.terrainLevel(Terrains.BLDG_ELEV)) && (entity.getElevation() != hex.terrainLevel(Terrains.BRIDGE_ELEV))) {
                        continue;
                    }
                }
            }

            // Work out hit table to use
            if (attackSource != null) {
                toHit.setSideTable(entity.sideTable(attackSource));
                if ((ammo != null) && (ammo.getMunitionType() == AmmoType.M_CLUSTER) && attackSource.equals(coords)) {
                    if (entity instanceof Mech) {
                        toHit.setHitTable(ToHitData.HIT_ABOVE);
                    } else if (entity instanceof Tank) {
                        toHit.setSideTable(ToHitData.SIDE_FRONT);
                        toHit.addModifier(2, "cluster artillery hitting a Tank");
                    }
                }
            }

            // convention infantry take x2 damage from AE weapons
            if ((entity instanceof Infantry) && !(entity instanceof BattleArmor)) {
                hits *= 2;
            }

            // Entity/ammo specific damage modifiers
            if (ammo != null) {
                if (ammo.getMunitionType() == AmmoType.M_CLUSTER) {
                    if (hex.containsTerrain(Terrains.FORTIFIED) && (entity instanceof Infantry) && !(entity instanceof BattleArmor)) {
                        hits *= 2;
                    }
                } else if (ammo.getMunitionType() == AmmoType.M_FLECHETTE) {
                    // wheeled and hover tanks take movement critical
                    if ((entity instanceof Tank) && ((entity.getMovementMode() == IEntityMovementMode.WHEELED) || (entity.getMovementMode() == IEntityMovementMode.HOVER))) {
                        r = new Report(6480);
                        r.subject = entity.getId();
                        r.addDesc(entity);
                        r.add(toHit.getTableDesc());
                        r.add(0);
                        vPhaseReport.add(r);
                        vPhaseReport.addAll(vehicleMotiveDamage((Tank) entity, 0));
                        continue;
                    }
                    // only infantry and support vees with bar < 5 are affected
                    if ((entity instanceof BattleArmor) || (entity.getBARRating() > 4)) {
                        continue;
                    }
                    if (entity instanceof Infantry) {
                        hits = Compute.d6(damage);
                        hits *= 2;
                    }
                    if (entity.getBARRating() < 5) {
                        switch (ammo.getAmmoType()) {
                        case AmmoType.T_LONG_TOM:
                            // hack: check if damage is still at 4, so we're in the
                            // center hex. otherwise, do no damage
                            if (damage == 4) {
                                damage = (5 - entity.getBARRating()) * 5;
                            } else {
                                continue;
                            }
                            break;
                        case AmmoType.T_SNIPER:
                            // hack: check if damage is still at 2, so we're in the
                            // center hex. otherwise, do no damage
                            if (damage == 2) {
                                damage = (5 - entity.getBARRating()) * 3;
                            } else {
                                continue;
                            }
                            break;
                        case AmmoType.T_THUMPER:
                            // no need to check for damage, because falloff = damage for the thumper
                            damage = 5 - entity.getBARRating();
                            break;
                        }
                    }
                }
            }

            // Do the damage
            r = new Report(6480);
            r.subject = entity.getId();
            r.addDesc(entity);
            r.add(toHit.getTableDesc());
            r.add(hits);
            vPhaseReport.add(r);
            if (entity instanceof BattleArmor) {
                // BA take full damage to each trooper, ouch!
                for (int loc = 0; loc < entity.locations(); loc++) {
                    if (entity.getInternal(loc) > 0) {
                        HitData hit = new HitData(loc);
                        vPhaseReport.addAll(damageEntity(entity, hit, hits, false, DamageType.NONE, false, true, false));
                    }
                }
            } else {
                while (hits > 0) {
                    HitData hit = entity.rollHitLocation(toHit.getHitTable(), toHit.getSideTable());

                    vPhaseReport.addAll(damageEntity(entity, hit, Math.min(cluster, hits), false, DamageType.NONE, false, true, false));
                    hits -= Math.min(5, hits);
                }
            }
View Full Code Here

                    // Mechs and vehicles get charged,
                    // but need to make a to-hit roll
                    if ((target instanceof Mech) || (target instanceof Tank)) {
                        ChargeAttackAction caa = new ChargeAttackAction(entity.getId(), target.getTargetType(), target.getTargetId(), target.getPosition());
                        ToHitData toHit = caa.toHit(game, true);

                        // roll
                        int roll = Compute.d6(2);
                        // Update report.
                        r = new Report(2050);
                        r.subject = entity.getId();
                        r.indent();
                        r.add(target.getShortName(), true);
                        r.add(nextPos.getBoardNum(), true);
                        r.newlines = 0;
                        addReport(r);
                        if (toHit.getValue() == TargetRoll.IMPOSSIBLE) {
                            roll = -12;
                            r = new Report(2055);
                            r.subject = entity.getId();
                            r.add(toHit.getDesc());
                            r.newlines = 0;
                            addReport(r);
                        } else if (toHit.getValue() == TargetRoll.AUTOMATIC_SUCCESS) {
                            r = new Report(2060);
                            r.subject = entity.getId();
                            r.add(toHit.getDesc());
                            r.newlines = 0;
                            addReport(r);
                            roll = Integer.MAX_VALUE;
                        } else {
                            // report the roll
                            r = new Report(2065);
                            r.subject = entity.getId();
                            r.add(toHit.getValue());
                            r.add(roll);
                            r.newlines = 0;
                            addReport(r);
                        }

                        // Resolve a charge against the target.
                        // ASSUMPTION: buildings block damage for
                        // *EACH* entity charged.
                        if (roll < toHit.getValue()) {
                            r = new Report(2070);
                            r.subject = entity.getId();
                            addReport(r);
                        } else {
                            // Resolve the charge.
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.