Beispiel #1
0
        /// <summary>
        /// Get an IEnumerable of outermost border Cells in a square area around the center Cell up to the specified distance
        /// Taken from: https://github.com/FaronBracy/RogueSharp/blob/master/RogueSharp/Map.cs
        /// </summary>
        /// <param name="center">center Cell</param>
        /// <param name="distance">The number of Cells to get in each direction from the center Cell</param>
        /// <returns>IEnumerable of outermost border Cells in a square area around the center Cell</returns>
        public static IEnumerable <ICell> BorderCellsInSquare(ICellContainer map, Vector2Int center, int distance)
        {
            Vector2Int min = new Vector2Int(
                Math.Max(0, center.x - distance),
                Math.Max(0, center.y - distance)
                );
            Vector2Int max = new Vector2Int(
                Math.Min(map.Width - 1, center.x + distance),
                Math.Min(map.Height - 1, center.y + distance)
                );
            List <ICell> borderCells = new List <ICell>();

            for (int x = min.x; x <= max.x; x++)
            {
                borderCells.Add(map.CellAt(x, min.y));
                borderCells.Add(map.CellAt(x, max.y));
            }
            for (int y = min.y + 1; y <= max.y - 1; y++)
            {
                borderCells.Add(map.CellAt(min.x, y));
                borderCells.Add(map.CellAt(max.x, y));
            }

            ICell centerCell = map.CellAt(center);

            borderCells.Remove(centerCell);

            return(borderCells);
        }
Beispiel #2
0
 /// <summary>
 /// Compute field of view in the given map
 /// </summary>
 /// <param name="map">map that will receive the fov settings</param>
 /// <param name="origin">fov origin</param>
 /// <param name="radius">fov radius</param>
 public static void Compute(ICellContainer map, Vector2Int origin, int radius)
 {
     ClearFovInCells(map);
     foreach (ICell borderCell in MapNavigationUtils.BorderCellsInSquare(map, origin, radius))
     {
         foreach (ICell cell in MapNavigationUtils.CellsAlongLine(map, origin, borderCell.position))
         {
             if (Math.Abs(Vector2Int.Distance(cell.position, origin)) > radius)
             {
                 break;
             }
             if (!cell.isSightBlocked)
             {
                 map.CellAt(cell.position).isInFov = true;
             }
             else
             {
                 // light walls
                 map.CellAt(cell.position).isInFov = true;
                 break;
             }
         }
     }
     PostProcessFov(map, origin, radius);
 }
Beispiel #3
0
        private static void PostProcessFovQuadrant(ICellContainer map, ICell cell, Quadrant quadrant)
        {
            ICell c1, c2;

            switch (quadrant)
            {
            case Quadrant.NE:
            {
                c1 = map.CellAt(cell.position + Vector2Int.up);
                c2 = map.CellAt(cell.position + Vector2Int.left);
                break;
            }

            case Quadrant.SE:
            {
                c1 = map.CellAt(cell.position + Vector2Int.down);
                c2 = map.CellAt(cell.position + Vector2Int.left);
                break;
            }

            case Quadrant.SW:
            {
                c1 = map.CellAt(cell.position + Vector2Int.down);
                c2 = map.CellAt(cell.position + Vector2Int.right);
                break;
            }

            case Quadrant.NW:
            {
                c1 = map.CellAt(cell.position + Vector2Int.up);
                c2 = map.CellAt(cell.position + Vector2Int.right);
                break;
            }

            default:
                throw new Exception("Unexpected quadrant");
            }
            ICell cx = map.CellAt(c2.position.x, c1.position.y);

            if (!cell.isInFov && cell.isSightBlocked)
            {
                if ((!c1.isSightBlocked && c1.isInFov) || (!c2.isSightBlocked && c2.isInFov) ||
                    (!cx.isSightBlocked && cx.isInFov))
                {
                    cell.isInFov = true;
                }
            }
        }
Beispiel #4
0
 private static void ClearFovInCells(ICellContainer map)
 {
     for (int x = 0; x < map.Width; x++)
     {
         for (int y = 0; y < map.Height; y++)
         {
             map.CellAt(x, y).isInFov = false;
         }
     }
 }
Beispiel #5
0
        /// <summary>
        /// Get an IEnumerable of Cells in a square area around the center Cell up to the specified distance
        /// </summary>
        /// <param name="center">location of the center Cell</param>
        /// <param name="distance">The number of Cells to get in each direction from the center Cell</param>
        /// <returns>IEnumerable of Cells in a square area around the center Cell</returns>
        public static IEnumerable <ICell> CellsInSquare(ICellContainer map, Vector2Int center, int distance)
        {
            Vector2Int min = new Vector2Int(
                Math.Max(0, center.x - distance),
                Math.Max(0, center.y - distance)
                );
            Vector2Int max = new Vector2Int(
                Math.Min(map.Width - 1, center.x + distance),
                Math.Min(map.Height - 1, center.y + distance)
                );

            for (int x = min.x; x <= max.x; x++)
            {
                for (int y = min.y; y <= max.y; y++)
                {
                    yield return(map.CellAt(x, y));
                }
            }
        }
Beispiel #6
0
        /// <summary>
        /// Get an IEnumerable of Cells in a line from the Origin Cell to the Destination Cell
        /// The resulting IEnumerable includes the Origin and Destination Cells
        /// Uses Bresenham's line algorithm to determine which Cells are in the closest approximation to a straight line between the two Cells
        /// </summary>
        /// <param name="origin">location of the Origin Cell at the start of the line</param>
        /// <param name="destination">location of the Destination Cell at the end of the line</param>
        /// <returns>IEnumerable of Cells in a line from the Origin Cell to the Destination Cell which includes the Origin and Destination Cells</returns>
        public static IEnumerable <ICell> CellsAlongLine(ICellContainer map, Vector2Int origin, Vector2Int destination)
        {
            Vector2Int maxPosition = new Vector2Int(map.Width - 1, map.Height - 1);

            origin.Clamp(Vector2Int.zero, maxPosition);
            destination.Clamp(Vector2Int.zero, maxPosition);

            Vector2Int d = new Vector2Int(
                Math.Abs(destination.x - origin.x),
                Math.Abs(destination.y - origin.y)
                );
            Vector2Int s = new Vector2Int(
                origin.x < destination.x ? 1 : -1,
                origin.y < destination.y ? 1 : -1
                );
            int err = d.x - d.y;

            while (true)
            {
                yield return(map.CellAt(origin));

                if (origin == destination)
                {
                    break;
                }
                int e2 = 2 * err;
                if (e2 > -d.y)
                {
                    err       = err - d.y;
                    origin.x += s.x;
                }
                if (e2 < d.x)
                {
                    err       = err + d.x;
                    origin.y += s.y;
                }
            }
        }