in = Compute.toLineOrder(in, ae.getPosition());
  public int[] getModifiers(final Entity te) {    //set them at the appropriate positions    final Entity ae = this.entity;        int attHeight = ae.isProne() ? 0 : 1;    int targHeight = te.isProne() ? 0 : 1;    int attEl = 0;    int targEl = 0;    attEl = ae.elevation() + attHeight;    targEl = te.elevation() + targHeight;    int ilw = 0;  // intervening light woods    int ihw = 0;  // intervening heavy woods    Coords in[] = Compute.intervening(this.curPos, te.getPosition());        boolean pc = false;    boolean apc = false;        //get all relevent modifiers    ToHitData toHita = new ToHitData();    ToHitData toHitd = new ToHitData();        toHita.append(Compute.getAttackerMovementModifier(game, ae.getId()));    //this.offensive_mod = Compute.getAttackerMovementModifier(game, ae.getId()).getValue();    toHita.append(Compute.getTargetMovementModifier(game, te.getId()));    toHita.append(Compute.getTargetTerrainModifier(game, te.getId()));    toHita.append(Compute.getAttackerTerrainModifier(game, ae.getId()));        toHitd.append(Compute.getAttackerMovementModifier(game, te.getId()));    toHitd.append(Compute.getTargetMovementModifier(game, ae.getId()));    //this.defensive_mod = Compute.getTargetMovementModifier(game, ae.getId()).getValue();    if (!(this.isPhysical && this.isJumping)) {      toHitd.append(Compute.getTargetTerrainModifier(game, ae.getId()));      //this.defensive_mod += Compute.getTargetTerrainModifier(game, ae.getId()).getValue();    }    toHitd.append(Compute.getAttackerTerrainModifier(game, te.getId()));        Hex attHex = game.board.getHex(ae.getPosition());    if (attHex.contains(Terrain.WATER) && attHex.surface() > attEl) {      toHita.addModifier(ToHitData.IMPOSSIBLE, "Attacker in depth 2+ water");      toHitd.addModifier(ToHitData.IMPOSSIBLE, "Defender in depth 2+ water");    } else if (attHex.surface() == attEl && ae.height() > 0) {      apc = true;    }    Hex targHex = game.board.getHex(te.getPosition());    if (targHex.contains(Terrain.WATER)) {      if (targHex.surface() == targEl && te.height() > 0) {        pc = true;      } else if (targHex.surface() > targEl) {        toHita.addModifier(ToHitData.IMPOSSIBLE, "Attacker in depth 2+ water");        toHitd.addModifier(ToHitData.IMPOSSIBLE, "Defender in depth 2+ water");      }    }        double degree = ae.getPosition().degree(te.getPosition());    if (degree > 180) degree = (degree + 180)%360;    if (degree == 30 || degree == 90 || degree == 150) {      Vector result = new Vector();      in = Compute.toLineOrder(in, ae.getPosition());      result.addElement(in[0]); //attacker spot      int w_total = 0;      for (int i = 1; i < in.length - 2 && toHita.getValue() != ToHitData.IMPOSSIBLE; i+=3) {        Coords c1 = in[i];        Coords c2 = in[i+1];        result.addElement(in[i+2]);        if (!game.board.contains(c1)) {          result.addElement(c2);        } else if (!game.board.contains(c2)) {          result.addElement(c1);        } else {          final Hex h = game.board.getHex(c1);          final int hexEl = h.floor();          final Hex h1 = game.board.getHex(c2);          final int hexEl1 = h1.floor();          int w = 0;          int w1 = 0;          if ((hexEl > attEl && hexEl > targEl)          || (i == 1 && hexEl > attEl)          || (i == in.length - 3 && hexEl > targEl)) {            toHita.addModifier(ToHitData.IMPOSSIBLE, "");            toHitd.addModifier(ToHitData.IMPOSSIBLE, "");          } else if ((hexEl1 > attEl && hexEl1 > targEl)          || (i == 1 && hexEl1 > attEl)          || (i == in.length - 3 && hexEl1 > targEl)) {            toHita.addModifier(ToHitData.IMPOSSIBLE, "");            toHitd.addModifier(ToHitData.IMPOSSIBLE, "");          } else {            if (h.levelOf(Terrain.WOODS) > 0) {              if ((hexEl + 2 > attEl && hexEl + 2 > targEl)              || (i == 1 && hexEl + 2 > attEl)              || (i == in.length - 3 && hexEl + 2 > targEl)) {                w = (h.levelOf(Terrain.WOODS) == 1)?1:2;              }            }            if (h1.levelOf(Terrain.WOODS) > 0) {              if ((hexEl1 + 2 > attEl && hexEl1 + 2 > targEl)              || (i == 1 && hexEl1 + 2 > attEl)              || (i == in.length - 3 && hexEl1 + 2 > targEl)) {                w1 = (h1.levelOf(Terrain.WOODS)==1)?1:2;              }            }            if (i == in.length -3) {              if (w1 + w_total > 2) {                result.addElement(c2);                toHita.addModifier(ToHitData.IMPOSSIBLE, "");                toHitd.addModifier(ToHitData.IMPOSSIBLE, "");                continue;              } else if (w + w_total > 2) {                result.addElement(c1);                toHita.addModifier(ToHitData.IMPOSSIBLE, "");                toHitd.addModifier(ToHitData.IMPOSSIBLE, "");                continue;              } else if (hexEl == targEl && attEl <= targEl && te.height() > 0) {                result.addElement(c1);                continue;              } else if (hexEl1 == targEl && attEl <= targEl && te.height() > 0) {                result.addElement(c2);                continue;              }            }            if (w1 > w) {              result.addElement(c2);              w_total += w1;            } else {              result.addElement(c1);              w_total += w;            }          }        }      }      in = new Coords[result.size()];      result.copyInto(in);    }       for (int i = 0; i < in.length && toHita.getValue() != ToHitData.IMPOSSIBLE; i++) {      // don't count attacker or target hexes      if (in[i].equals(this.curPos) || in[i].equals(te.getPosition())) {        continue;      }      final Hex h = game.board.getHex(in[i]);      if (h == null) continue;      final int hexEl = h.getElevation();      // check for block by terrain      if ((hexEl > attEl && hexEl > targEl)      || (hexEl > attEl && this.curPos.distance(in[i]) <= 1)      || (hexEl > targEl && te.getPosition().distance(in[i]) <= 1)) {        toHita.addModifier(ToHitData.IMPOSSIBLE, "Terrain");        toHitd.addModifier(ToHitData.IMPOSSIBLE, "Terrain");      }      // determine number of woods hexes in the way      if (h.levelOf(Terrain.WOODS) > 0) {        if ((hexEl + 2 > attEl && hexEl + 2 > targEl)        || (hexEl + 2 > attEl && ae.getPosition().distance(in[i]) <= 1)        || (hexEl + 2 > targEl && te.getPosition().distance(in[i]) <= 1)) {          ilw += (h.levelOf(Terrain.WOODS) == 1 ? 1 : 0);          ihw += (h.levelOf(Terrain.WOODS) > 1 ? 1 : 0);        }      }      // check for partial cover      if (te.getPosition().distance(in[i]) <= 1 && hexEl == targEl && attEl <= targEl && targHeight > 0) {        pc = true;      }      // check for attacker partial cover      if (this.curPos.distance(in[i]) <= 1 && hexEl == attEl && attEl >= targEl && attHeight > 0) {        apc = true;      }    }    // more than 1 heavy woods or more than two light woods block LOS    if (ilw + ihw * 2 >= 3) {      toHita.addModifier(ToHitData.IMPOSSIBLE, "Terrain");      toHitd.addModifier(ToHitData.IMPOSSIBLE, "Terrain");    }    // partial cover    if (pc) {      toHita.addModifier(3, "target has partial cover");    }    if (apc) {      toHitd.addModifier(3, "attacker has partial cover");    }    // intervening terrain    if (ilw > 0) {      toHita.addModifier(ilw, ilw + " light woods intervening");      toHitd.addModifier(ilw, ilw + " light woods intervening");    }    if (ihw > 0) {      toHita.addModifier(ihw * 2, ihw + " heavy woods intervening");      toHitd.addModifier(ihw * 2, ihw + " heavy woods intervening");    }    // heatBuildup    if (ae.getHeatFiringModifier() != 0) {      toHita.addModifier(ae.getHeatFiringModifier(), "heatBuildup");      //this.offensive_mod += ae.getHeatFiringModifier();    }    if (te.getHeatFiringModifier() != 0) {      toHitd.addModifier(te.getHeatFiringModifier(), "heatBuildup");    }    // target immobile    if (te.isImmobile()) {      toHita.addModifier(-4, "target immobile");    }    if (ae.isImmobile()) {      toHitd.addModifier(-4, "target immobile");      //this.defensive_mod -= 4;    }    final int range = ae.getPosition().distance(te.getPosition());    // target prone    if (te.isProne()) {      // easier when point-blank      if (range == 1) {        toHita.addModifier(-2, "target prone and adjacent");      }      // harder at range      if (range > 1) {        toHita.addModifier(1, "target prone and at range");      }    }    if (ae.isProne()) {      // easier when point-blank      if (range == 1) {        toHitd.addModifier(-2, "target prone and adjacent");      }      // harder at range      if (range > 1) {        toHitd.addModifier(1, "target prone and at range");      }    }    return new int[] {toHita.getValue(), toHitd.getValue(), apc?1:0, pc?1:0};  }