if (ae.getHeight() < target.getHeight()) {
if (targHex.levelOf(Terrain.WATER) == te.height() && te.height() > 0) { toHit.setHitTable(ToHitData.HIT_PUNCH); } else if (ae.getHeight() < target.getHeight()) {
    public ToHitData toHitCharge(Game game, Targetable target, Coords src, int movement) {        final Entity ae = getEntity(game);        int targetId = Entity.NONE;        Entity te = null;        if (target.getTargetType() == Targetable.TYPE_ENTITY) {            te = (Entity) target;            targetId = target.getTargetId();        }        final int attackerElevation = ae.elevationOccupied(game.board.getHex(src));        final int attackerHeight = attackerElevation + ae.height();        final int targetElevation = target.getElevation();        final int targetHeight = target.absHeight();        final boolean targetInBuilding = Compute.isInBuilding(game, te);        Building bldg = null;        if (targetInBuilding) {            bldg = game.board.getBuildingAt(te.getPosition());        }        ToHitData toHit = null;        // arguments legal?        if (ae == null || target == null) {            throw new IllegalArgumentException("Attacker or target not valid");        }        // can't target yourself        if (ae.equals(te)) {            return new ToHitData(ToHitData.IMPOSSIBLE, "You can't target yourself");        }        // Can't target a transported entity.        if (te != null && Entity.NONE != te.getTransportId()) {            return new ToHitData(ToHitData.IMPOSSIBLE, "Target is a passenger.");        }        // can't make physical attacks while spotting        if (ae.isSpotting()) {            return new ToHitData(ToHitData.IMPOSSIBLE, "Attacker is spotting this turn");        }        // Can't target a entity conducting a swarm attack.        if (te != null && Entity.NONE != te.getSwarmTargetId()) {            return new ToHitData(ToHitData.IMPOSSIBLE, "Target is swarming a Mek.");        }        // check range        if (src.distance(target.getPosition()) > 1) {            return new ToHitData(ToHitData.IMPOSSIBLE, "Target not in range");        }        // mechs can only charge standing mechs        if (ae instanceof Mech) {            if (te != null && !(te instanceof Mech)) {                return new ToHitData(ToHitData.IMPOSSIBLE, "Target is not a mech");            }            if (te != null && te.isProne()) {                return new ToHitData(ToHitData.IMPOSSIBLE, "Target is prone");            }        } else if (te instanceof Infantry) {            // Can't charge infantry.            return new ToHitData(ToHitData.IMPOSSIBLE, "Target is infantry");        }        // target must be within 1 elevation level        if (attackerElevation > targetHeight || attackerHeight < targetElevation) {            return new ToHitData(ToHitData.IMPOSSIBLE, "Target must be within 1 elevation level");        }        // can't charge while prone        if (ae.isProne()) {            return new ToHitData(ToHitData.IMPOSSIBLE, "Attacker is prone");        }        // can't attack mech making a different displacement attack        if (te != null && te.hasDisplacementAttack()) {            return new ToHitData(ToHitData.IMPOSSIBLE, "Target is already making a charge/DFA attack");        }        // target must have moved already        if (te != null && !te.isDone()) {            return new ToHitData(ToHitData.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(ToHitData.IMPOSSIBLE, "Target is the target of another charge/DFA");        }        // Can't target units in buildings (from the outside).        if (targetInBuilding) {            if (!Compute.isInBuilding(game, ae)) {                return new ToHitData(ToHitData.IMPOSSIBLE, "Target is inside building");            } else if (!game.board.getBuildingAt(ae.getPosition()).equals(bldg)) {                return new ToHitData(ToHitData.IMPOSSIBLE, "Target is inside differnt building");            }        }        // Attacks against adjacent buildings automatically hit.        if (target.getTargetType() == Targetable.TYPE_BUILDING) {            return new ToHitData(ToHitData.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(ToHitData.IMPOSSIBLE, "Invalid attack");        }        //Set the base BTH        int base = 5;        if (game.getOptions().booleanOption("maxtech_physical_BTH")) {            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));        // 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?        Hex targHex = game.board.getHex(te.getPosition());        if (te.height() > 0 && targHex.levelOf(Terrain.WATER) == te.height()) {            toHit.addModifier(3, "target has partial cover");        }        // target immobile        toHit.append(Compute.getImmobileMod(te));        Compute.modifyPhysicalBTHForAdvantages(ae, te, toHit, game);        // determine hit direction        toHit.setSideTable(Compute.targetSideTable(src, te.getPosition(), te.getFacing(), te instanceof Tank));        // all charges resolved against full-body table, except vehicles.        if (ae.getHeight() < target.getHeight()) {            toHit.setHitTable(ToHitData.HIT_KICK);        } else {            toHit.setHitTable(ToHitData.HIT_NORMAL);        }        // done!        return toHit;    }