コード例 #1
0
 /// <summary>
 /// Constructor. Takes an existing grid view to create a view from, and getter/setter
 /// functions taking a map value and its corresponding position.
 /// </summary>
 /// <param name="baseGrid">Your underlying grid data.</param>
 /// <param name="getter">The TranslateGet implementation.</param>
 /// <param name="setter">The TranslateSet implementation.</param>
 public LambdaSettableTranslationGridView(ISettableGridView <T1> baseGrid, Func <Point, T1, T2> getter,
                                          Func <Point, T2, T1> setter)
     : base(baseGrid)
 {
     _getter = getter ?? throw new ArgumentNullException(nameof(getter));
     _setter = setter ?? throw new ArgumentNullException(nameof(setter));
 }
コード例 #2
0
        /// <inheritdoc />
        public Area CreateTunnel(ISettableGridView <bool> map, Point start, Point end)
        {
            var lineAlgorithm = _adjacencyRule == AdjacencyRule.Cardinals
                ? Lines.Algorithm.Orthogonal
                : Lines.Algorithm.Bresenham;
            var area = new Area();

            var previous = Point.None;

            foreach (var pos in Lines.Get(start, end, lineAlgorithm))
            {
                map[pos] = true;
                area.Add(pos);
                // Previous cell, and we're going vertical, go 2 wide so it looks nicer Make sure not
                // to break rectangles (less than last index)!
                if (_doubleWideVertical && previous != Point.None && pos.Y != previous.Y && pos.X + 1 < map.Width - 1)
                {
                    var wideningPos = pos + (1, 0);
                    map[wideningPos] = true;
                    area.Add(wideningPos);
                }

                previous = pos;
            }

            return(area);
        }
コード例 #3
0
        public void IndexerAccessGridViewTest()
        {
            var grid = new ArrayView <bool>(_width, _height);
            ISettableGridView <bool> setGridView = grid;
            IGridView <bool>         gridView    = grid;

            bool[] array = grid;

            // Set last entry via indexer syntax (via the ArrayView, to prove implicit implementations
            // work at all levels)
            grid[^ 1] = true;
コード例 #4
0
        /// <summary>
        /// Constructor. Takes an existing grid view to create a view from, and getter/setter
        /// functions taking only a value from the underlying representation.
        /// </summary>
        /// <remarks>
        /// If a position is also needed to perform the translation, an overload is provided taking
        /// corresponding functions.
        /// </remarks>
        /// <param name="baseGrid">Your underlying grid data.</param>
        /// <param name="getter">The TranslateGet implementation.</param>
        /// <param name="setter">The TranslateSet implementation.</param>
        public LambdaSettableTranslationGridView(ISettableGridView <T1> baseGrid, Func <T1, T2> getter, Func <T2, T1> setter)
            : base(baseGrid)
        {
            if (getter == null)
            {
                throw new ArgumentNullException(nameof(getter));
            }
            if (setter == null)
            {
                throw new ArgumentNullException(nameof(setter));
            }

            _getter = (pos, t1) => getter(t1);
            _setter = (pos, t2) => setter(t2);
        }
コード例 #5
0
        /// <summary>
        /// Sets all the values of the current grid view to be equal to the corresponding values from
        /// the grid view you pass in.
        /// </summary>
        /// <typeparam name="T" />
        /// <param name="self" />
        /// <param name="overlay">
        /// The data apply to the view. Must have identical dimensions to the current view.
        /// </param>
        public static void ApplyOverlay <T>(this ISettableGridView <T> self, IGridView <T> overlay)
        {
            if (self.Height != overlay.Height || self.Width != overlay.Width)
            {
                throw new ArgumentException("Overlay size must match current grid view size.");
            }

            for (var y = 0; y < self.Height; ++y)
            {
                for (var x = 0; x < self.Width; ++x)
                {
                    self[x, y] = overlay[x, y];
                }
            }
        }
コード例 #6
0
        private static void CellAutoSmoothingAlgo(ISettableGridView <bool> map, ArrayView <bool> oldMap, bool bigAreaFill)
        {
            // Record current state of the map so we can compare to it to determine nearest walls
            oldMap.ApplyOverlay(map);

            // Iterate over inner square only to avoid messing with outer walls
            foreach (var pos in map.Bounds().Expand(-1, -1).Positions())
            {
                if (CountWallsNear(oldMap, pos, 1) >= 5 || bigAreaFill && CountWallsNear(oldMap, pos, 2) <= 2)
                {
                    map[pos] = false;
                }
                else
                {
                    map[pos] = true;
                }
            }
        }
コード例 #7
0
 /// <summary>
 /// Constructor. Takes an existing grid view to create a view from and applies view data to it.
 /// </summary>
 /// <param name="baseGrid">Your underlying grid data.</param>
 /// <param name="overlay">
 /// The view data to apply to the underlying representation. Must have identical dimensions to
 /// <paramref name="baseGrid" />.
 /// </param>
 /// <param name="getter">The TranslateGet implementation.</param>
 /// <param name="setter">The TranslateSet implementation.</param>
 public LambdaSettableTranslationGridView(ISettableGridView <T1> baseGrid, ISettableGridView <T2> overlay,
コード例 #8
0
 /// <inheritdoc />
 protected override void SetInitialMapValues(ISettableGridView <MapGenTileState> map)
 => map.Fill(MapGenTileState.Wall);
コード例 #9
0
 /// <summary>
 /// Constructor. Takes an existing grid view to create a view from.
 /// </summary>
 /// <param name="baseGrid">A grid view exposing your underlying map data.</param>
 protected SettableTranslationGridView(ISettableGridView <T1> baseGrid) => BaseGrid = baseGrid;
コード例 #10
0
 /// <summary>
 /// Constructor. Takes the map view to represent. The viewport will represent the entire given map view.
 /// </summary>
 /// <param name="gridView">The map view to represent.</param>
 public SettableViewport(ISettableGridView <T> gridView)
     : base(gridView)
 {
 }
コード例 #11
0
ファイル: FOVBase.cs プロジェクト: Chris3606/GoRogue
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="transparencyView">
 /// The values used to calculate field of view. Values of true are considered
 /// non-blocking (transparent) to line of sight, while false values are considered
 /// to be blocking.
 /// </param>
 /// <param name="resultView">The view in which FOV calculations are stored.</param>
 protected FOVBase(IGridView <bool> transparencyView, ISettableGridView <double> resultView)
 {
     ResultView        = resultView;
     TransparencyView  = transparencyView;
     BooleanResultView = new LambdaTranslationGridView <double, bool>(ResultView, val => val > 0.0);
 }
コード例 #12
0
 /// <inheritdoc />
 public Area CreateTunnel(ISettableGridView <bool> map, int startX, int startY, int endX, int endY)
 => CreateTunnel(map, new Point(startX, startY), new Point(endX, endY));
コード例 #13
0
 /// <summary>
 /// Sets the values for each location of the current grid view to be equal to the value returned from the given
 /// function when given that position.
 /// </summary>
 /// <typeparam name="T" />
 /// <param name="self" />
 /// <param name="valueFunc">
 /// Function returning data for each location in the grid view.
 /// </param>
 public static void ApplyOverlay <T>(this ISettableGridView <T> self, Func <Point, T> valueFunc)
 => self.ApplyOverlay(new LambdaGridView <T>(self.Width, self.Height, valueFunc));
コード例 #14
0
 /// <summary>
 /// Sets each location in the grid view to the value specified.
 /// </summary>
 /// <typeparam name="T" />
 /// <param name="self" />
 /// <param name="value">Value to fill the grid view with.</param>
 public static void Fill <T>(this ISettableGridView <T> self, T value)
 => self.ApplyOverlay(_ => value);
コード例 #15
0
        private static void ShadowCast(int row, double start, double end, int xx, int xy, int yx, int yy,
                                       double radius, int startX, int startY, double decay, ISettableGridView <double> lightMap,
                                       HashSet <Point> fovSet,
                                       IGridView <bool> map, Distance distanceStrategy)
        {
            double newStart = 0;

            if (start < end)
            {
                return;
            }

            var blocked = false;

            for (var distance = row; distance <= radius && distance < map.Width + map.Height && !blocked; distance++)
            {
                var deltaY = -distance;
                for (var deltaX = -distance; deltaX <= 0; deltaX++)
                {
                    var    currentX   = startX + deltaX * xx + deltaY * xy;
                    var    currentY   = startY + deltaX * yx + deltaY * yy;
                    double leftSlope  = (deltaX - 0.5f) / (deltaY + 0.5f);
                    double rightSlope = (deltaX + 0.5f) / (deltaY - 0.5f);

                    if (!(currentX >= 0 && currentY >= 0 && currentX < map.Width && currentY < map.Height) ||
                        start < rightSlope)
                    {
                        continue;
                    }
                    if (end > leftSlope)
                    {
                        break;
                    }

                    var deltaRadius = distanceStrategy.Calculate(deltaX, deltaY);
                    // If within lightable area, light if needed
                    if (deltaRadius <= radius)
                    {
                        var bright = 1 - decay * deltaRadius;
                        if (bright > lightMap[currentX, currentY])
                        {
                            lightMap[currentX, currentY] = bright;
                            fovSet.Add(new Point(currentX, currentY));
                        }
                    }

                    if (blocked)                      // Previous cell was blocked
                    {
                        if (!map[currentX, currentY]) // Hit a wall...
                        {
                            newStart = rightSlope;
                        }
                        else
                        {
                            blocked = false;
                            start   = newStart;
                        }
                    }
                    else
                    {
                        if (map[currentX, currentY] || !(distance < radius))
                        {
                            continue;
                        }

                        blocked = true;
                        ShadowCast(distance + 1, start, leftSlope, xx, xy, yx, yy, radius, startX, startY, decay,
                                   lightMap, fovSet, map, distanceStrategy);
                        newStart = rightSlope;
                    }
                }
            }
        }
コード例 #16
0
        private static void ShadowCastLimited(int row, double start, double end, int xx, int xy, int yx, int yy,
                                              double radius, int startX, int startY, double decay,
                                              ISettableGridView <double> lightMap, HashSet <Point> fovSet, IGridView <bool> map,
                                              Distance distanceStrategy, double angle, double span)
        {
            double newStart = 0;

            if (start < end)
            {
                return;
            }

            var blocked = false;

            for (var distance = row; distance <= radius && distance < map.Width + map.Height && !blocked; distance++)
            {
                var deltaY = -distance;
                for (var deltaX = -distance; deltaX <= 0; deltaX++)
                {
                    var    currentX   = startX + deltaX * xx + deltaY * xy;
                    var    currentY   = startY + deltaX * yx + deltaY * yy;
                    double leftSlope  = (deltaX - 0.5f) / (deltaY + 0.5f);
                    double rightSlope = (deltaX + 0.5f) / (deltaY - 0.5f);

                    if (!(currentX >= 0 && currentY >= 0 && currentX < map.Width && currentY < map.Height) ||
                        start < rightSlope)
                    {
                        continue;
                    }
                    if (end > leftSlope)
                    {
                        break;
                    }

                    var deltaRadius = distanceStrategy.Calculate(deltaX, deltaY);
                    var at2         = Math.Abs(angle - MathHelpers.ScaledAtan2Approx(currentY - startY, currentX - startX));

                    // Check if within lightable area, light if needed
                    if (deltaRadius <= radius && (at2 <= span * 0.5 || at2 >= 1.0 - span * 0.5))
                    {
                        var bright = 1 - decay * deltaRadius;
                        if (bright > lightMap[currentX, currentY])
                        {
                            lightMap[currentX, currentY] = bright;
                            fovSet.Add(new Point(currentX, currentY));
                        }
                    }

                    if (blocked)                      // Previous cell was blocking
                    {
                        if (!map[currentX, currentY]) // We hit a wall...
                        {
                            newStart = rightSlope;
                        }
                        else
                        {
                            blocked = false;
                            start   = newStart;
                        }
                    }
                    else if (!map[currentX, currentY] && distance < radius) // Wall within line of sight
                    {
                        blocked = true;
                        ShadowCastLimited(distance + 1, start, leftSlope, xx, xy, yx, yy, radius, startX, startY, decay,
                                          lightMap, fovSet, map, distanceStrategy, angle, span);
                        newStart = rightSlope;
                    }
                }
            }
        }
コード例 #17
0
 /// <summary>
 /// Constructor. Takes the parent map view, and the initial subsection of that map view to represent.
 /// </summary>
 /// <param name="gridView">The map view being represented.</param>
 /// <param name="viewArea">The initial subsection of that map to represent.</param>
 public SettableViewport(ISettableGridView <T> gridView, Rectangle viewArea)
     : base(gridView, viewArea)
 {
 }