// Generate an octant of shadows, and return the FOV area to be redrawn private static List <Cell> ShadowOctant(Level level, Vector2Int origin, int octant) { // Increments based off of octantCoordinates var rowInc = _octantCoords[octant, 0]; var colInc = _octantCoords[octant, 1]; ShadowLine line = new ShadowLine(); bool fullShadow = false; List <Cell> ret = new List <Cell>(); for (int row = 0; row < FOVRadius; row++) { // Record position Vector2Int pos = origin + (rowInc * row); // Stop once going out of bounds if (!level.Contains(pos)) { break; } bool pastMaxDistance = false; for (int col = 0; col <= row; col++) { // Break on this row if going out of bounds if (!level.Contains(pos)) { break; } // Visibility fall off over distance int fallOff = 255; // If entire row is known to be in shadow, set this cell to // be in shadow if (fullShadow || pastMaxDistance) { Cell c = level.GetCell(pos); if (c.SetVisibility(false, fallOff)) { ret.Add(c); } } else { float distance = Vector2.Distance(origin, pos); if (distance > FOVRadius) { fallOff = 255; pastMaxDistance = true; } else { float normalized = distance / FOVRadius; normalized = Mathf.Pow(normalized, 2); fallOff = (int)(normalized * 255); } Shadow projection = ProjectTile(row, col); // Set the visibility of this tile bool visible = !line.IsInShadow(projection); Cell c = level.GetCell(pos); if (c.SetVisibility(visible, fallOff)) { ret.Add(c); } // Add any opaque tiles to the shadow map if (visible && level.GetCell(pos).Opaque) { line.AddShadow(projection); fullShadow = line.IsFullShadow(); } } pos += colInc; if (!level.Contains(pos)) { break; } } } return(ret); }
public bool Contains(Shadow other) => Start <= other.Start && End >= other.End;