private Dictionary <float, float> CalculateBrightnessLayers(EmberCell centerCell, List <float> layers) { float deductAmount = centerCell.LightProperties.Brightness / layers.Count; float maxBrightness = centerCell.LightProperties.Brightness + deductAmount; return(layers.ToDictionary(a => a, a => maxBrightness -= deductAmount)); }
private void SetLightSource(EmberCell cell) { if (cell.LightProperties.EmitsLight) { var fov = new FOV(GridManager.Grid.FieldOfView); fov.Calculate(cell.Position, cell.LightProperties.LightRadius); var toChangeCells = new List <(EmberCell, float)>(); for (int x = 0; x < GridManager.Grid.GridSizeX; x++) { for (int y = 0; y < GridManager.Grid.GridSizeY; y++) { // If cell is in the field of view of the object if (fov.BooleanFOV[x, y]) { var pos = new Point(x, y); var distanceOfCenter = cell.Position.SquaredDistance(pos); var cellToAdd = GridManager.Grid.GetCell(x, y); if (!cellToAdd.LightProperties.EmitsLight) { if (cellToAdd.LightProperties.LightSources == null) { cellToAdd.LightProperties.LightSources = new List <EmberCell>(); } cellToAdd.LightProperties.LightSources.RemoveAll(a => a.Position == cell.Position); cellToAdd.LightProperties.LightSources.Add(cell); } toChangeCells.Add((cellToAdd, distanceOfCenter)); } } } HandleBrightnessLayers(toChangeCells, cell); } }
public void SetCell(EmberCell cell, bool calculateEntitiesFov = false, bool adjustLights = true) { var originalCell = Cells[cell.Position.Y * GridSizeX + cell.Position.X]; // Update the map fov values if the walkable is changed bool updateFieldOfView = originalCell.CellProperties.BlocksFov != cell.CellProperties.BlocksFov; // Adjust the lights of the tiles if (adjustLights) { LightEngine.AdjustLightSource(cell, originalCell.Clone()); } // Copy the new cell data originalCell.CopyFrom(cell); if (updateFieldOfView) { UpdateFieldOfView(cell.Position.X, cell.Position.Y); if (calculateEntitiesFov) { // Recalculate the fov of all entities EntityManager.RecalculatFieldOfView(); } } }
public void SetCellColors(EmberCell cell, IEntity entity, Color foreground, Color foregroundFov) { // If the cell is in the field of view if (entity == null || (entity.FieldOfViewRadius > 0 && entity.FieldOfView.BooleanFOV[cell.Position])) { if (cell.LightProperties.Brightness > 0f) { cell.Foreground = Color.Lerp(foreground, Color.White, cell.LightProperties.Brightness); } else { cell.Foreground = cell.CellProperties.NormalForeground; } } else { if (cell.LightProperties.Brightness > 0f) { cell.Foreground = Color.Lerp(foregroundFov, Color.White, cell.LightProperties.Brightness); } else { cell.Foreground = cell.CellProperties.ForegroundFov; } } }
public void SetCellColors(EmberCell cell, IEntity entity) { // If the cell is in the field of view if (entity == null || (entity.FieldOfViewRadius > 0 && entity.FieldOfView.BooleanFOV[cell.Position])) { if (cell.LightProperties.Brightness > 0f && cell.LightProperties.LightSources != null) { cell.Foreground = Color.Lerp(cell.GetClosestLightSource().LightProperties.LightColor, Color.White, cell.LightProperties.Brightness); } else { cell.Foreground = cell.CellProperties.NormalForeground; } } else { if (cell.LightProperties.Brightness > 0f && cell.LightProperties.LightSources != null) { cell.Foreground = Color.Lerp(Color.Lerp(cell.GetClosestLightSource().LightProperties.LightColor, Color.Black, .5f), Color.White, cell.LightProperties.Brightness); } else { cell.Foreground = cell.CellProperties.ForegroundFov; } } }
private void RemoveFromCellLightSources(EmberCell cell, EmberCell newCell) { cell.LightProperties.LightSources?.RemoveAll(a => a.Equals(newCell)); if (cell.LightProperties.LightSources != null && !cell.LightProperties.LightSources.Any()) { cell.LightProperties.Brightness = 0f; cell.LightProperties.LightColor = default; cell.LightProperties.LightRadius = 0; cell.LightProperties.LightSources = null; } }
public void SetCellColors(EmberCell cell) { if (cell.LightProperties.Brightness > 0f) { var closestLightSource = cell.GetClosestLightSource(); Color lightSourceColor = closestLightSource?.LightProperties.LightColor ?? Color.White; cell.Foreground = Color.Lerp(cell.CellProperties.NormalForeground, lightSourceColor, cell.LightProperties.Brightness); cell.Background = Color.Lerp(cell.CellProperties.NormalBackground, lightSourceColor, cell.LightProperties.Brightness / 3f); } else { cell.Foreground = cell.CellProperties.ForegroundFov; cell.Background = cell.CellProperties.BackgroundFov; } }
public void AdjustLightSource(EmberCell newCell, EmberCell oldCell) { if (newCell.LightProperties.EmitsLight == oldCell.LightProperties.EmitsLight) { return; } if (newCell.LightProperties.EmitsLight) { SetLightSource(newCell); } else { UnsetLightSource(newCell); } }
public EmberCell[] GetNeighbors(EmberCell cell) { int x = cell.Position.X; int y = cell.Position.Y; var points = new List <Point>(); if (!InBounds(x, y)) { return(Array.Empty <EmberCell>()); } if (InBounds(x + 1, y)) { points.Add(new Point(x + 1, y)); } if (InBounds(x - 1, y)) { points.Add(new Point(x - 1, y)); } if (InBounds(x, y + 1)) { points.Add(new Point(x, y + 1)); } if (InBounds(x, y - 1)) { points.Add(new Point(x, y - 1)); } if (InBounds(x + 1, y + 1)) { points.Add(new Point(x + 1, y + 1)); } if (InBounds(x - 1, y - 1)) { points.Add(new Point(x - 1, y - 1)); } if (InBounds(x + 1, y - 1)) { points.Add(new Point(x + 1, y - 1)); } if (InBounds(x - 1, y + 1)) { points.Add(new Point(x - 1, y + 1)); } return(points.Select(a => GetCell(a)).ToArray()); }
private void UnsetLightSource(EmberCell lightSource) { // Retrieve all cells that were affected by newCell var cells = GetCellsAffectedByLightSource(lightSource); var lightSourcesToRecalculate = new List <EmberCell>(); foreach (var cell in cells) { // Push over our properties because cell is the old state that isn't modified yet if (cell.Equals(lightSource)) { cell.LightProperties = lightSource.LightProperties; cell.CellProperties = lightSource.CellProperties; } // Remove the lightsource from this cell RemoveFromCellLightSources(cell, lightSource); // Add remaining lightsources to be recalculated if (cell.LightProperties.LightSources != null) { lightSourcesToRecalculate.AddRange(cell.LightProperties.LightSources); } // If the cell itself is not a lightsource we reset the brightness and color if (!cell.LightProperties.EmitsLight) { cell.LightProperties.Brightness = 0f; cell.LightProperties.LightColor = default; } GridManager.Grid.SetCellColors(cell); GridManager.Grid.SetCell(cell, false, false); } // Re-set for the remaining light sources foreach (var source in lightSourcesToRecalculate.Distinct()) { SetLightSource(source); } // Make sure we set the new version of newCell's LightProperties incase they have changed during recalculation. lightSource.LightProperties = GridManager.Grid.GetCell(lightSource.Position).LightProperties; }
public void SetCell(EmberCell cell, bool calculateEntitiesFov = false) { var originalCell = Cells[cell.Position.Y * GridSizeX + cell.Position.X]; // Update the map fov values if the walkable is changed bool updateFieldOfView = originalCell.CellProperties.BlocksFov != cell.CellProperties.BlocksFov; // Adjust neighboring cell light levels if this object gives of light LightEngine.AdjustLightLevels(cell, originalCell); // Copy the new cell data originalCell.CopyFrom(cell); if (updateFieldOfView) { UpdateFieldOfView(cell.Position.X, cell.Position.Y); if (calculateEntitiesFov) { // Recalculate the fov of all entities EntityManager.RecalculatFieldOfView(); } } }
public void AdjustLightLevels(EmberCell newCell, EmberCell oldCell) { if (oldCell.LightProperties.EmitsLight == newCell.LightProperties.EmitsLight) { return; } var fov = new FOV(GridManager.Grid.FieldOfView); if (!newCell.LightProperties.EmitsLight) { fov.Calculate(newCell.Position, oldCell.LightProperties.LightRadius); var toChangeCells = new List <EmberCell>(); for (int x = 0; x < GridManager.Grid.GridSizeX; x++) { for (int y = 0; y < GridManager.Grid.GridSizeY; y++) { // If cell is in the field of view of the object if (fov.BooleanFOV[x, y]) { var pos = new Point(x, y); var cellToAdd = newCell.Position == pos ? newCell : GridManager.Grid.GetCell(x, y); cellToAdd.LightProperties.LightSources.Remove(newCell); toChangeCells.Add(cellToAdd); } } } foreach (var cell in toChangeCells) { if (cell.LightProperties.LightSources.Any()) { continue; } cell.LightProperties.LightSources = null; cell.LightProperties.Brightness = 0f; cell.LightProperties.LightRadius = 0; cell.LightProperties.LightColor = default; GridManager.Grid.SetCellColors(cell, Game.Player, cell.CellProperties.NormalForeground, cell.CellProperties.ForegroundFov); if (cell != newCell) // We don't need an infinite loop here :) It's passed by reference. { GridManager.Grid.SetCell(cell); } } return; } var cells = new List <(EmberCell, float)>(); fov.Calculate(newCell.Position, newCell.LightProperties.LightRadius); for (int x = 0; x < GridManager.Grid.GridSizeX; x++) { for (int y = 0; y < GridManager.Grid.GridSizeY; y++) { // If cell is in the field of view of the object if (fov.BooleanFOV[x, y]) { var pos = new Point(x, y); var distanceOfCenter = newCell.Position.SquaredDistance(pos); var cellToAdd = newCell.Position == pos ? newCell : GridManager.Grid.GetCell(x, y); if (cellToAdd.LightProperties.LightSources == null) { cellToAdd.LightProperties.LightSources = new List <EmberCell>(); } cellToAdd.LightProperties.LightSources.Add(newCell); cells.Add((cellToAdd, distanceOfCenter)); } } } var orderedCells = cells.OrderBy(a => a.Item2); var layers = orderedCells.Select(a => a.Item2).Distinct().ToList(); var brightnessLayers = CalculateBrightnessLayers(newCell, layers); foreach (var lightedCell in orderedCells) { var brightness = brightnessLayers[lightedCell.Item2]; if (lightedCell.Item1.LightProperties.Brightness < brightness) { lightedCell.Item1.LightProperties.Brightness = brightness; } GridManager.Grid.SetCellColors(lightedCell.Item1, Game.Player, newCell.LightProperties.LightColor, Color.Lerp(newCell.LightProperties.LightColor, Color.Black, .5f)); if (lightedCell.Item1 != newCell) // We don't need an infinite loop here :) It's passed by reference. { GridManager.Grid.SetCell(lightedCell.Item1); } } }
private List <EmberCell> GetCellsAffectedByLightSource(EmberCell cell) { return(GridManager.Grid .GetCells(a => a.Position == cell.Position || (a.LightProperties.LightSources != null && a.LightProperties.LightSources.Any(a => a.Equals(cell)))) .ToList()); }