Ejemplo n.º 1
0
    public bool BeginTargetting(Vector2Int startPosition, LOSData los)
    {
        origin = startPosition;
        target = startPosition;

        currentLOS = los;
        points.Clear();
        isFinished = false;



        int maxEffectSize = range + radius;

        offset = maxEffectSize;
        length = maxEffectSize * 2 + 1;

        //Fix 2D problems
        if (area == null || area.Length != length)
        {
            area = new bool[length, length];
        }

        affected     = new List <Monster>();
        tempAffected = new List <Monster>();

        isValid = IsValid();


        return(!CanSkip()); //Returns true if we should open targetting, false if we can skip
    }
Ejemplo n.º 2
0
    public static bool IsFloor(Vector2Int tile, Row r, LOSData l)
    {
        if (tile.x == -1 && tile.y == -1)
        {
            return(false);
        }

        return(!l.getAt(tile.y, tile.x, r.quad.dir));
    }
Ejemplo n.º 3
0
    public static bool IsWall(Vector2Int tile, Row r, LOSData l)
    {
        if (tile.x == -1 && tile.y == -1)
        {
            //Special case for starting tile
            return(false);
        }

        return(l.getAt(tile.y, tile.x, r.quad.dir));
    }
Ejemplo n.º 4
0
    public static LOSData GeneratePlayerLOS(Map map, Vector2Int location, int radius)
    {
        if (lastCall != null)
        {
            lastCall.Deprint(Map.current);
        }

        lastCall = LosAt(map, location, radius);
        lastCall.Imprint(Map.current);
        return(lastCall);
    }
Ejemplo n.º 5
0
    public static LOSData LosAt(Map map, Vector2Int position, int distance)
    {
        if (distance <= 0)
        {
            return(new LOSData(0, position));
        }
        LOSData toReturn = new LOSData(distance, position);

        toReturn.PrecalculateValues();
        toReturn.setAt(0, 0, Direction.NORTH, true);
        for (int d = 0; d < 4; d++)
        {
            Quadrant q = new Quadrant((Direction)d, position);

            Row firstRow = new Row(1, new fraction(-1, 1), new fraction(1, 1), q);
            Scan(firstRow, toReturn);
        }

        toReturn.CollectEntities(map);

        return(toReturn);
    }
Ejemplo n.º 6
0
    public static void Scan(Row r, LOSData l)
    {
        Vector2Int previous = -1 * Vector2Int.one;

        foreach (Vector2Int tile in r.tiles())
        {
            if (IsWall(tile, r, l) || IsSymmetric(r, tile))
            {
                Reveal(tile, l, r.quad.dir);
            }

            if (IsWall(previous, r, l) && IsFloor(tile, r, l))
            {
                r.startSlope = Slope(tile);
            }

            if (IsFloor(previous, r, l) && IsWall(tile, r, l))
            {
                if (r.depth != l.radius)
                {
                    Row next_row = r.next();
                    next_row.endSlope = Slope(tile);
                    Scan(next_row, l);
                }
            }

            previous = tile;
        }

        if (IsFloor(previous, r, l))
        {
            if (r.depth != l.radius)
            {
                Scan(r.next(), l);
            }
        }
    }
Ejemplo n.º 7
0
 //TODO: Update this to be individual maps
 public virtual void UpdateLOS()
 {
     this.view = LOS.LosAt(Map.current, location, visionRadius);
 }
Ejemplo n.º 8
0
 public static void Reveal(Vector2Int tile, LOSData l, Direction d)
 {
     l.setAt(tile.y, tile.x, d, true);
 }
Ejemplo n.º 9
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;
        }
    }