Пример #1
0
  /** Computes a list of the valid locations in this cluster. */
  public static List<SceneLocation> getClusterLocs(Cluster cluster) {
    List<SceneLocation> list = Lists.newArrayList();

    // convert our tile coordinates into a cartesian coordinate system
    // with units equal to one fine coordinate in size
    int fx = cluster.x * _metrics.finegran + 1, fy = cluster.y * _metrics.finegran + 1;
    int fwid = cluster.width * _metrics.finegran - 2, fhei = cluster.height * _metrics.finegran - 2;
    int cx = fx + fwid / 2, cy = fy + fhei / 2;

    // if it's a 1x1 cluster, return one location in the center of the
    // cluster
    if (cluster.width == 1) {
      StageLocation loc =
          new StageLocation(
              MisoUtil.toFull(cluster.x, 2),
              MisoUtil.toFull(cluster.y, 2),
              (byte) DirectionCodes.SOUTHWEST);
      list.add(new SceneLocation(loc, 0));
      return list;
    }

    double radius = (double) fwid / 2;
    int clidx = cluster.width - 2;
    if (clidx >= CLUSTER_METRICS.length / 2 || clidx < 0) {
      log.warning("Requested locs from invalid cluster " + cluster + ".", new Exception());
      return list;
    }

    for (double angle = CLUSTER_METRICS[clidx * 2];
        angle < Math.PI * 2;
        angle += CLUSTER_METRICS[clidx * 2 + 1]) {
      int sx = cx + (int) Math.round(Math.cos(angle) * radius);
      int sy = cy + (int) Math.round(Math.sin(angle) * radius);

      // obtain the orientation facing toward the center
      int orient = 2 * (int) (Math.round(angle / (Math.PI / 4)) % 8);
      orient = DirectionUtil.rotateCW(DirectionCodes.SOUTH, orient);
      orient = DirectionUtil.getOpposite(orient);

      // convert them back to full coordinates for the location
      int tx = MathUtil.floorDiv(sx, _metrics.finegran);
      sx = MisoUtil.toFull(tx, sx - (tx * _metrics.finegran));
      int ty = MathUtil.floorDiv(sy, _metrics.finegran);
      sy = MisoUtil.toFull(ty, sy - (ty * _metrics.finegran));
      StageLocation loc = new StageLocation(sx, sy, (byte) orient);
      list.add(new SceneLocation(loc, 0));
    }

    return list;
  }
Пример #2
0
  /**
   * Returns a polygon framing the specified scene footprint.
   *
   * @param x the x tile coordinate of the "upper-left" of the footprint.
   * @param y the y tile coordinate of the "upper-left" of the footprint.
   * @param width the width in tiles of the footprint.
   * @param height the height in tiles of the footprint.
   */
  public static Polygon getFootprintPolygon(
      MisoSceneMetrics metrics, int x, int y, int width, int height) {
    SmartPolygon footprint = new SmartPolygon();
    Point tpos = MisoUtil.tileToScreen(metrics, x, y, new Point());

    // start with top-center point
    int rx = tpos.x + metrics.tilehwid, ry = tpos.y;
    footprint.addPoint(rx, ry);
    // right point
    rx += width * metrics.tilehwid;
    ry += width * metrics.tilehhei;
    footprint.addPoint(rx, ry);
    // bottom-center point
    rx -= height * metrics.tilehwid;
    ry += height * metrics.tilehhei;
    footprint.addPoint(rx, ry);
    // left point
    rx -= width * metrics.tilehwid;
    ry -= width * metrics.tilehhei;
    footprint.addPoint(rx, ry);
    // end with top-center point
    rx += height * metrics.tilehwid;
    ry -= height * metrics.tilehhei;
    footprint.addPoint(rx, ry);

    return footprint;
  }
Пример #3
0
  /**
   * Does the necessary jiggery pokery to figure out where the specified object's associated
   * location is.
   *
   * @param tilemgr a tile manager that can be used to look up the tile information.
   * @param tileId the fully qualified tile id of the object tile.
   * @param tx the object's x tile coordinate.
   * @param ty the object's y tile coordinate.
   * @param orient - the orientation to use in the returned location, or {@link #OBJECT_ORIENTATION}
   *     if the tile's orientation should be used
   */
  public static StageLocation locationForObject(
      TileManager tilemgr, int tileId, int tx, int ty, int orient) {
    try {
      int tsid = TileUtil.getTileSetId(tileId);
      int tidx = TileUtil.getTileIndex(tileId);
      TrimmedObjectTileSet tset = (TrimmedObjectTileSet) tilemgr.getTileSet(tsid);
      if (tset == null || (orient == OBJECT_ORIENTATION && tset.getSpotOrient(tidx) < 0)) {
        return null;
      }
      if (orient == OBJECT_ORIENTATION) {
        orient = tset.getSpotOrient(tidx);
      }

      Point opos =
          MisoUtil.tilePlusFineToFull(
              _metrics, tx, ty, tset.getXSpot(tidx), tset.getYSpot(tidx), new Point());

      //             Log.info("Computed location [set=" + tset.getName() +
      //                      ", tidx=" + tidx + ", tx=" + tx + ", ty=" + ty +
      //                      ", sx=" + tset.getXSpot(tidx) +
      //                      ", sy=" + tset.getYSpot(tidx) +
      //                      ", lx=" + opos.x + ", ly=" + opos.y +
      //                      ", fg=" + _metrics.finegran + "].");
      return new StageLocation(opos.x, opos.y, (byte) orient);

    } catch (Exception e) {
      log.warning("Unable to look up object tile for scene object", "tileId", tileId, e);
    }
    return null;
  }
Пример #4
0
 public BlockGlyph(MisoSceneMetrics metrics, int bx, int by) {
   _bpoly = MisoUtil.getTilePolygon(metrics, bx, by);
 }
Пример #5
0
  /**
   * Locates a spot to stand near the supplied rectangular footprint. First a spot will be sought in
   * a tile immediately next to the footprint, then one tile removed, then two, up to the maximum
   * distance specified by <code>dist</code>.
   *
   * @param foot the tile coordinate footprint around which we are attempting to stand.
   * @param dist the maximum number of tiles away from the footprint to search before giving up.
   * @param pred a predicate that will be used to determine whether a particular spot can be stood
   *     upon (we're hijacking the meaning of "traverse" in this case, but the interface is
   *     otherwise so nice).
   * @param traverser the object that will be passed to the traversal predicate.
   * @param nearto a point (in tile coordinates) which will be used to select from among the valid
   *     standing spots, the one nearest to the supplied point will be returned.
   * @param orient if not {@link DirectionCodes#NONE} this orientation will be used to override the
   *     "natural" orientation of the spot which is facing toward the footprint.
   * @return the closest spot to the
   */
  public static StageLocation findStandingSpot(
      Rectangle foot,
      int dist,
      AStarPathUtil.TraversalPred pred,
      Object traverser,
      final Point nearto,
      int orient) {
    // generate a list of the tile coordinates of all squares around
    // this footprint
    SortableArrayList<StageLocation> spots = new SortableArrayList<StageLocation>();

    for (int dd = 1; dd <= dist; dd++) {
      int yy1 = foot.y - dd, yy2 = foot.y + foot.height + dd - 1;
      int xx1 = foot.x - dd, xx2 = foot.x + foot.width + dd - 1;

      // get the corners
      spots.add(new StageLocation(xx1, yy1, (byte) DirectionCodes.SOUTHWEST));
      spots.add(new StageLocation(xx1, yy2, (byte) DirectionCodes.SOUTHEAST));
      spots.add(new StageLocation(xx2, yy1, (byte) DirectionCodes.NORTHWEST));
      spots.add(new StageLocation(xx2, yy2, (byte) DirectionCodes.NORTHEAST));

      // then the sides
      for (int xx = xx1 + 1; xx < xx2; xx++) {
        spots.add(new StageLocation(xx, yy1, (byte) DirectionCodes.WEST));
        spots.add(new StageLocation(xx, yy2, (byte) DirectionCodes.EAST));
      }
      for (int yy = yy1 + 1; yy < yy2; yy++) {
        spots.add(new StageLocation(xx1, yy, (byte) DirectionCodes.SOUTH));
        spots.add(new StageLocation(xx2, yy, (byte) DirectionCodes.NORTH));
      }

      // sort them in order of closeness to the players current
      // coordinate
      spots.sort(
          new Comparator<StageLocation>() {
            public int compare(StageLocation o1, StageLocation o2) {
              return dist(o1) - dist(o2);
            }

            private final int dist(StageLocation l) {
              return Math.round(100 * MathUtil.distance(l.x, l.y, nearto.x, nearto.y));
            }
          });

      // return the first spot that can be "traversed" which we're
      // taking to mean "stood upon"
      for (int ii = 0, ll = spots.size(); ii < ll; ii++) {
        StageLocation loc = spots.get(ii);
        if (pred.canTraverse(traverser, loc.x, loc.y)) {
          // convert to full coordinates
          loc.x = MisoUtil.toFull(loc.x, 2);
          loc.y = MisoUtil.toFull(loc.y, 2);

          // see if we need to override the orientation
          if (DirectionCodes.NONE != orient) {
            loc.orient = (byte) orient;
          }
          return loc;
        }
      }

      // clear this list and try one further out
      spots.clear();
    }

    return null;
  }
Пример #6
0
 /** Converts Cartesian coordinates back to full coordinates. */
 public static void coordsToLocation(int cx, int cy, Point loc) {
   loc.x = MisoUtil.toFull(cx / _metrics.finegran, cx % _metrics.finegran);
   loc.y = MisoUtil.toFull(cy / _metrics.finegran, cy % _metrics.finegran);
 }
Пример #7
0
 /** Converts full coordinates to Cartesian coordinates. */
 public static void locationToCoords(int lx, int ly, Point coords) {
   int tx = MisoUtil.fullToTile(lx), fx = MisoUtil.fullToFine(lx);
   int ty = MisoUtil.fullToTile(ly), fy = MisoUtil.fullToFine(ly);
   coords.x = tx * _metrics.finegran + fx;
   coords.y = ty * _metrics.finegran + fy;
 }