/// <summary> /// Post processing step created based on the algorithm at this website: /// https://sites.google.com/site/jicenospam/visibilitydetermination /// </summary> /// <param name="origin"></param> /// <param name="radius"></param> private static void PostProcessFov(ICellContainer map, Vector2Int origin, int radius) { foreach (ICell cell in MapNavigationUtils.CellsInSquare(map, origin, radius)) { if (cell.position.x > origin.x) { if (cell.position.y > origin.y) { PostProcessFovQuadrant(map, cell, Quadrant.SE); } else if (cell.position.y < origin.y) { PostProcessFovQuadrant(map, cell, Quadrant.NE); } } else if (cell.position.x < origin.x) { if (cell.position.y > origin.y) { PostProcessFovQuadrant(map, cell, Quadrant.SW); } else if (cell.position.y < origin.y) { PostProcessFovQuadrant(map, cell, Quadrant.NW); } } } }
/// <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); }