Beispiel #1
0
        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));
        }
Beispiel #2
0
        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);
            }
        }
Beispiel #3
0
        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();
                }
            }
        }
Beispiel #4
0
 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;
         }
     }
 }
Beispiel #5
0
 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;
         }
     }
 }
Beispiel #6
0
 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;
     }
 }
Beispiel #7
0
 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;
     }
 }
Beispiel #8
0
        public void AdjustLightSource(EmberCell newCell, EmberCell oldCell)
        {
            if (newCell.LightProperties.EmitsLight == oldCell.LightProperties.EmitsLight)
            {
                return;
            }

            if (newCell.LightProperties.EmitsLight)
            {
                SetLightSource(newCell);
            }
            else
            {
                UnsetLightSource(newCell);
            }
        }
Beispiel #9
0
        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());
        }
Beispiel #10
0
        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;
        }
Beispiel #11
0
        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();
                }
            }
        }
Beispiel #12
0
        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);
                }
            }
        }
Beispiel #13
0
 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());
 }