001package squidpony.squidai;
002
003import squidpony.squidgrid.Radius;
004
005/**
006 * A struct-like class that holds information about targeting rules for actions or other effects that reach from one
007 * square into another one, with certain potential restrictions.
008 *
009 * @see squidpony.squidai.AreaUtils and its verifyReach method
010 * Created by Tommy Ettinger on 12/17/2015.
011 */
012public class Reach {
013
014    /**
015     * The minimum distance in cells that this Reach can target.
016     * Distance will be measured using the {@code metric} field.
017     */
018    public int minDistance;
019
020    /**
021     * The maximum distance in cells that this Reach can target.
022     * Distance will be measured using the {@code metric} field.
023     */
024    public int maxDistance;
025    /**
026     * An AimLimit enum that may be used to determine limitations to targeting cells; defaults to FREE (no limits other
027     * than those from distance), but can also be set to ORTHOGONAL (rook move in chess), DIAGONAL (bishop move in
028     * chess), EIGHT_WAY (queen or king move in chess), or null (which usually)
029     */
030    public AimLimit limit;
031    /**
032     * Determines how distance will be measured. SQUARE or CUBE correspond to 8-way or Chebyshev movement, DIAMOND or
033     * OCTAHEDRON correspond to 4-way or Manhattan movement, and CIRCLE or SPHERE correspond to Euclidean movement.
034     */
035    public Radius metric;
036
037    /**
038     * Constructs a Reach with all fields given default values; maxDistance is set to 1, minDistance is set to 0, limit
039     * is set to AimLimit.FREE, and metric is set to Radius.SQUARE (8-way movement).
040     */
041    public Reach() {
042        minDistance = 0;
043        maxDistance = 1;
044        limit = AimLimit.FREE;
045        metric = Radius.SQUARE;
046    }
047
048    /**
049     * Constructs a Reach with the specified maxDistance, to a minimum of 0. Other fields are given default values;
050     * minDistance is set to 0, limit is set to AimLimit.FREE, and metric is set to Radius.SQUARE (8-way movement).
051     * @param maxDistance the longest distance in cells this Reach can target; will be set to 0 if negative
052     */
053    public Reach(int maxDistance) {
054        minDistance = 0;
055        this.maxDistance = (maxDistance < 0) ? 0 : maxDistance;
056        limit = AimLimit.FREE;
057        metric = Radius.SQUARE;
058    }
059
060    /**
061     * Constructs a Reach with the specified minDistance, to a minimum of 0, and maxDistance, to a minimum equal to
062     * minDistance (after factoring in any change to meet the minimum of 0). Other fields are given default values;
063     * limit is set to AimLimit.FREE, and metric is set to Radius.SQUARE (8-way movement).
064     * @param minDistance the shortest distance in cells this Reach can target; will be set to 0 if negative
065     * @param maxDistance the longest distance in cells this Reach can target; will be set to the final value of
066     *                    minDistance if it is lower than the calculated minDistance
067     */
068    public Reach(int minDistance, int maxDistance) {
069        this.minDistance = (minDistance < 0) ? 0 : minDistance;
070        this.maxDistance = (this.minDistance  > maxDistance) ? this.minDistance : maxDistance;
071        limit = AimLimit.FREE;
072        metric = Radius.SQUARE;
073    }
074
075    /**
076     * Constructs a Reach with the specified minDistance, to a minimum of 0, maxDistance, to a minimum equal to
077     * minDistance (after factoring in any change to meet the minimum of 0), and distance calculation metric as a Radius
078     * enum. Other than that, limit is set to AimLimit.FREE.
079     * @param minDistance the shortest distance in cells this Reach can target; will be set to 0 if negative
080     * @param maxDistance the longest distance in cells this Reach can target; will be set to the final value of
081     *                    minDistance if it is lower than the calculated minDistance
082     * @param metric a Radius enum that determines how distance will be calculated
083     */
084    public Reach(int minDistance, int maxDistance, Radius metric) {
085        this.minDistance = (minDistance < 0) ? 0 : minDistance;
086        this.maxDistance = (this.minDistance  > maxDistance) ? this.minDistance : maxDistance;
087        limit = AimLimit.FREE;
088        this.metric = metric;
089    }
090
091    /**
092     * Constructs a Reach with the specified minDistance, to a minimum of 0, maxDistance, to a minimum equal to
093     * minDistance (after factoring in any change to meet the minimum of 0), and distance calculation metric as a Radius
094     * enum. Other than that, limit is set to AimLimit.FREE.
095     * @param minDistance the shortest distance in cells this Reach can target; will be set to 0 if negative
096     * @param maxDistance the longest distance in cells this Reach can target; will be set to the final value of
097     *                    minDistance if it is lower than the calculated minDistance
098     * @param metric a Radius enum that determines how distance will be calculated
099     * @param limit an AimLimit enum that can be used to limit targeting to specific angles, or not at all (if null or
100     *              equal to AimLimit.FREE)
101     */
102    public Reach(int minDistance, int maxDistance, Radius metric, AimLimit limit) {
103        this.minDistance = (minDistance < 0) ? 0 : minDistance;
104        this.maxDistance = (this.minDistance  > maxDistance) ? this.minDistance : maxDistance;
105        this.limit = limit;
106        this.metric = metric;
107    }
108}