final Hex srcHex = game.board.getHex(src); final Hex destHex = game.board.getHex(dest); final int fallElevation = Math.abs(destHex.floor() - srcHex.floor()); int direction = src.direction(dest);  Entity violation = Compute.stackingViolation(game, entity.getId(), dest);  if (violation != null && !Compute.isValidDisplacement(game, violation.getId(), src, dest)) {   Coords temp = dest; dest = src; src = temp; violation = Compute.stackingViolation(game, entity.getId(), dest); }   phaseReport.append(entity.getDisplayName() ).append( " falls " ).append( fallElevation ).append( " level(s) into hex " ).append( dest.getBoardNum() ).append( ".\n");         if (violation == null) { doEntityFall(entity, dest, fallElevation, roll); return; }   if (fallElevation >= 2) {  phaseReport.append(entity.getDisplayName() ).append( " falls " ).append( fallElevation ).append( " levels into hex " ).append( dest.getBoardNum() ).append( ", violating stacking with " ).append( violation.getDisplayName() ).append( ".\n");   ToHitData toHit = new ToHitData(7, "base"); toHit.append(Compute.getTargetMovementModifier(game, violation.getId())); toHit.append(Compute.getTargetTerrainModifier(game, violation));   final int diceRoll = Compute.d6(2); phaseReport.append("Collision occurs on a " ).append( toHit.getValue() ).append( " or greater.  Rolls " ).append( diceRoll); if (diceRoll >= toHit.getValue()) { phaseReport.append(", hits!\n");  int damage = Compute.getAffaDamageFor(entity); phaseReport.append(violation.getDisplayName() ).append( " takes " ).append( damage ).append( " from the collision."); while (damage > 0) { int cluster = Math.min(5, damage); HitData hit = violation.rollHitLocation(ToHitData.HIT_PUNCH, ToHitData.SIDE_FRONT); phaseReport.append(damageEntity(violation, hit, cluster)); damage -= cluster; } phaseReport.append("\n");    PilotingRollData pilotRoll = entity.getBasePilotingRoll(); pilotRoll.append(roll); doEntityFall(entity, dest, fallElevation, 3, pilotRoll); doEntityDisplacementMinefieldCheck(entity, src, dest);   Coords targetDest = Compute.getValidDisplacement(game, violation.getId(), dest, direction); if (targetDest != null) { doEntityDisplacement(violation, dest, targetDest, new PilotingRollData(violation.getId(), 2, "fallen on"));  entityUpdate( violation.getId() ); } else {    phaseReport.append(destroyEntity(violation, "impossible displacement", (violation instanceof Mech), (violation instanceof Mech))); } } else { phaseReport.append(", misses.\n");  Coords targetDest = Compute.getValidDisplacement(game, entity.getId(), dest, direction); if (targetDest != null) { doEntityDisplacement(entity, src, targetDest, new PilotingRollData(entity.getId(), PilotingRollData.IMPOSSIBLE, "pushed off a cliff"));  entityUpdate( entity.getId() ); } else {    phaseReport.append(destroyEntity(entity, "impossible displacement", (entity instanceof Mech), (entity instanceof Mech))); } } return; } else {  doEntityFall(entity, dest, fallElevation, roll);  doEntityDisplacement(violation, dest, dest.translated(direction), new PilotingRollData(violation.getId(), 0, "domino effect"));  entityUpdate( violation.getId() ); }
doEntityFallsInto(entity, src, dest, roll, true);
    private void doEntityFallsInto(Entity entity, Coords src, Coords dest, PilotingRollData roll) {        final Hex srcHex = game.board.getHex(src);        final Hex destHex = game.board.getHex(dest);        final int fallElevation = Math.abs(destHex.floor() - srcHex.floor());        int direction = src.direction(dest);        // check entity in target hex        Entity violation = Compute.stackingViolation(game, entity.getId(), dest);        // check if we can fall in that hex        if (violation != null        && !Compute.isValidDisplacement(game, violation.getId(), src, dest)) {            // if target can't be displaced, fall in source hex.            // NOTE: source hex should never contain a non-displacable entity            Coords temp = dest;            dest = src;            src = temp;            violation = Compute.stackingViolation(game, entity.getId(), dest);        }        // falling mech falls        phaseReport.append(entity.getDisplayName() ).append( " falls "        ).append( fallElevation ).append( " level(s) into hex "        ).append( dest.getBoardNum() ).append( ".\n");        // if hex was empty, deal damage and we're done        // TODO: Check if there's a protomech or tank in the target hex,        // if so, the latest BMRr errata says we should make an        // Accidental fall from above.        // if multiple targets, determine randomly which to hit        // vehicles are automatic misses, protos are treated as        // battlemechs.        if (violation == null) {            doEntityFall(entity, dest, fallElevation, roll);            return;        }        // hmmm... somebody there... problems.        if (fallElevation >= 2) {            // accidental fall from above: havoc!            phaseReport.append(entity.getDisplayName() ).append( " falls "            ).append( fallElevation ).append( " levels into hex "            ).append( dest.getBoardNum() ).append( ", violating stacking with "            ).append( violation.getDisplayName() ).append( ".\n");            // determine to-hit number            ToHitData toHit = new ToHitData(7, "base");            toHit.append(Compute.getTargetMovementModifier(game, violation.getId()));            toHit.append(Compute.getTargetTerrainModifier(game, violation));            // roll dice            final int diceRoll = Compute.d6(2);            phaseReport.append("Collision occurs on a " ).append( toHit.getValue()            ).append( " or greater.  Rolls " ).append( diceRoll);            if (diceRoll >= toHit.getValue()) {                phaseReport.append(", hits!\n");                // deal damage to target                int damage = Compute.getAffaDamageFor(entity);                phaseReport.append(violation.getDisplayName() ).append( " takes "                ).append( damage ).append( " from the collision.");                while (damage > 0) {                    int cluster = Math.min(5, damage);                    HitData hit = violation.rollHitLocation(ToHitData.HIT_PUNCH, ToHitData.SIDE_FRONT);                    phaseReport.append(damageEntity(violation, hit, cluster));                    damage -= cluster;                }                phaseReport.append("\n");                // attacker falls as normal, on his back                // only given a modifier, so flesh out into a full piloting roll                PilotingRollData pilotRoll = entity.getBasePilotingRoll();                pilotRoll.append(roll);                doEntityFall(entity, dest, fallElevation, 3, pilotRoll);                doEntityDisplacementMinefieldCheck(entity, src, dest);                // defender pushed away, or destroyed                Coords targetDest = Compute.getValidDisplacement(game, violation.getId(), dest, direction);                if (targetDest != null) {                    doEntityDisplacement(violation, dest, targetDest, new PilotingRollData(violation.getId(), 2, "fallen on"));                    // Update the violating entity's postion on the client.                    entityUpdate( violation.getId() );                } else {                    // ack!  automatic death!  Tanks                    // suffer an ammo/power plant hit.                    // TODO : a Mech suffers a Head Blown Off crit.                    phaseReport.append(destroyEntity(violation, "impossible displacement", (violation instanceof Mech), (violation instanceof Mech)));                }            } else {                phaseReport.append(", misses.\n");                //TODO: this is not quite how the rules go                Coords targetDest = Compute.getValidDisplacement(game, entity.getId(), dest, direction);                if (targetDest != null) {                    doEntityDisplacement(entity, src, targetDest, new PilotingRollData(entity.getId(), PilotingRollData.IMPOSSIBLE, "pushed off a cliff"));                    // Update the entity's postion on the client.                    entityUpdate( entity.getId() );                } else {                    // ack!  automatic death!  Tanks                    // suffer an ammo/power plant hit.                    // TODO : a Mech suffers a Head Blown Off crit.                    phaseReport.append(destroyEntity(entity, "impossible displacement", (entity instanceof Mech), (entity instanceof Mech)));                }            }               return;        } else {            // damage as normal            doEntityFall(entity, dest, fallElevation, roll);            // target gets displaced            doEntityDisplacement(violation, dest, dest.translated(direction), new PilotingRollData(violation.getId(), 0, "domino effect"));            // Update the violating entity's postion on the client.            entityUpdate( violation.getId() );        }    }