コード例 #1
0
 //TODO: Update this to be individual maps
 public virtual void UpdateLOS()
 {
     this.view = LOS.LosAt(Map.current, location, visionRadius);
 }
コード例 #2
0
    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;
        }
    }