public bool IsValid() { bool valid = true; if (pointsRequireLOS) { valid = valid && currentLOS.ValueAtWorld(target); } if (targetingType == TargetType.SINGLE_TARGET_LINES || targetingType == TargetType.SMITE_TARGET) { Monster atTarget = Map.current.GetTile(target).currentlyStanding; valid = valid && (atTarget != null); } return(valid); }
private void BuildRange(Vector2Int point) { switch (areaType) { case AreaType.SINGLE_TARGET: MarkArea(point.x, point.y, true); //Mark us again, just for funsies break; case AreaType.CHEBYSHEV_AREA: //Easy case first for (int i = point.x - radius; i <= point.x + radius; i++) { for (int j = point.y - radius; j <= point.y + radius; j++) { MarkArea(i, j, true); } } break; case AreaType.MANHATTAN_AREA: //Second easiest case for (int i = point.x - radius; i <= point.x + radius; i++) { for (int j = point.y - radius; j <= point.y + radius; j++) { if (Mathf.Abs(point.x - i) + Mathf.Abs(point.y - j) <= radius) { MarkArea(i, j, true); } } } break; case AreaType.EUCLID_AREA: //Most complex for (int i = point.x - radius; i <= point.x + radius; i++) { for (int j = point.y - radius; j <= point.y + radius; j++) { if (Vector2Int.Distance(point, new Vector2Int(i, j)) <= radius) //TODO: Confirm this actually works { MarkArea(i, j, true); } } } break; case AreaType.LOS_AREA: //Most expensive call, but easy to understand LOSData data = LOS.LosAt(Map.current, point, radius); for (int i = point.x - radius; i <= point.x + radius; i++) { for (int j = point.y - radius; j <= point.y + radius; j++) { if (data.ValueAtWorld(i, j)) { MarkArea(i, j, true); } } } break; case AreaType.CONE: //This one is pretty wack. Try some vector fanciness? /* * General Strategy: * Figure out the cosine value we're trying to reach (1/2 degree), and the main direction * Normalize everything down to 1 * Run through every square, and figure out it's direction. Normalize it, dot it with * other direction. Compare to cosine value, and if it's >, return a hit * * This trick works because dot(x, y) = |x||y|cos(theta), so by normalizing we can really * cheaply compute the angle between the vectors */ float cosDeg = Mathf.Cos(Mathf.Deg2Rad * degree / 2); Vector2 dir = ((Vector2)(point - origin)).normalized; //Get a good indicator of our direction for (int i = origin.x - radius; i <= origin.x + radius; i++) { for (int j = origin.y - radius; j <= origin.y + radius; j++) { //Perform checks for in cone Vector2 spot = new Vector2(i - origin.x, j - origin.y); float dist = Mathf.Max(Mathf.Abs(spot.x), Mathf.Abs(spot.y)); if (dist <= radius) //TODO: Should this be < ? { if (Vector2.Dot(dir, spot.normalized) > cosDeg) { MarkArea(i, j, true); } } } } break; } }