phaseReport.append("    Death from above cancelled as the target has been destroyed.\n");
phaseReport.append("    Death from above deals no damage as the target has been destroyed.\n");
    private void resolveDfaAttack(DfaAttackAction daa, int lastEntityId) {        final Entity ae = game.getEntity(daa.getEntityId());        final Entity te = game.getEntity(daa.getTargetId());                // is the attacker dead?  because that sure messes up the calculations        if (ae == null) {            return;        }                final int direction = ae.getFacing();                if (lastEntityId != daa.getEntityId()) {            phaseReport.append("\nPhysical attacks for " + ae.getDisplayName() + "\n");        }                // entity isn't charging any more        ae.setDisplacementAttack(null);                // should we even bother?        if (te == null || te.isDestroyed() || te.isDoomed() || te.crew.isDead()) {            phaseReport.append("    Death from above cancelled as the target has been destroyed.\n");            if (ae.isProne()) {                // attacker prone during weapons phase                doEntityFall(ae, daa.getTargetPos(), 2, 3, Compute.getBasePilotingRoll(game, ae.getId()));            } else {                // same effect as successful DFA                doEntityDisplacement(ae, ae.getPosition(), daa.getTargetPos(), new PilotingRollData(ae.getId(), 4, "executed death from above"));            }            return;        }                phaseReport.append("    Attempting death from above on " + te.getDisplayName());                // target still in the same position?        if (!te.getPosition().equals(daa.getTargetPos())) {            phaseReport.append(" but the target has moved.\n");            return;        }                // compute to-hit        ToHitData toHit = Compute.toHitDfa(game, daa);                // hack: if the attacker's prone, or incapacitated, fudge the roll        int roll;        if (ae.isProne() || !ae.isActive()) {            roll = -12;            phaseReport.append(" but the attacker is prone or incapacitated : ");        } else if (toHit.getValue() == ToHitData.IMPOSSIBLE) {            roll = -12;            phaseReport.append(" but the attack is impossible (" + toHit.getDesc() + ") : ");        } else {            // roll            roll = Compute.d6(2);            phaseReport.append("; needs " + toHit.getValue() + ", ");            phaseReport.append("rolls " + roll + " : ");        }                // do we hit?        if (roll < toHit.getValue()) {            Coords src = ae.getPosition();            Coords dest = te.getPosition();            Coords targetDest = Compute.getPreferredDisplacement(game, te.getId(), dest, direction);            phaseReport.append("misses.\n");            if (targetDest != null) {                // move target to preferred hex                doEntityDisplacement(te, dest, targetDest, null);                // attacker falls into destination hex                phaseReport.append(ae.getDisplayName() + " falls into hex " + dest.getBoardNum() + ".\n");                doEntityFall(ae, dest, 2, 3, Compute.getBasePilotingRoll(game, ae.getId()));            } else {                // attacker destroyed                phaseReport.append(destroyEntity(ae, "impossible displacement", false));            }            return;        }                // we hit...        int damage = Compute.getDfaDamageFor(ae);        int damageTaken = Compute.getDfaDamageTakenBy(ae);                phaseReport.append("hits.");                phaseReport.append("\n  Defender takes " + damage + " damage" + toHit.getTableDesc() + ".");        while (damage > 0) {            int cluster = Math.min(5, damage);            HitData hit = te.rollHitLocation(toHit.getHitTable(), toHit.getSideTable());            phaseReport.append(damageEntity(te, hit, cluster));            damage -= cluster;        }        phaseReport.append("\n  Attacker takes " + damageTaken + " damage.");        while (damageTaken > 0) {            int cluster = Math.min(5, damageTaken);            HitData hit = ae.rollHitLocation(ToHitData.HIT_KICK, toHit.SIDE_FRONT);            phaseReport.append(damageEntity(ae, hit, cluster));            damageTaken -= cluster;        }        phaseReport.append("\n");                // defender pushed away or destroyed        Coords src = ae.getPosition();        Coords dest = te.getPosition();        Coords targetDest = Compute.getValidDisplacement(game, te.getId(), dest, direction);        if (game.getOptions().booleanOption("push_off_board") && !game.board.contains(dest.translated(direction))) {            game.moveToGraveyard(te.getId());            send(createRemoveEntityPacket(te.getId()));            phaseReport.append("\n*** " + te.getDisplayName() + " target has been forced from the field. ***\n");        } else {            if (targetDest != null) {                doEntityDisplacement(te, dest, targetDest, new PilotingRollData(te.getId(), 2, "hit by death from above"));            } else {                // ack!  automatic death!                phaseReport.append(destroyEntity(te, "impossible displacement", false));            }        }        // HACK: to avoid automatic falls, displace from dest to dest        doEntityDisplacement(ae, dest, dest, new PilotingRollData(ae.getId(), 4, "executed death from above"));    }