Exemple #1
0
        private bool AddShadow(FovShadow shadow)
        {
            int index;

            for (index = 0; index < shadows.Count; index++)
            {
                // See if we are at the insertion point for this shadow.
                if (shadows[index].Start > shadow.Start)
                {
                    // Break out and handle inserting below.
                    break;
                }
            }

            // The new shadow is going here. See if it overlaps the previous or next.
            var overlapsPrev = ((index > 0) && (shadows[index - 1].End > shadow.Start));
            var overlapsNext = ((index < shadows.Count) && (shadows[index].Start < shadow.End));

            // Insert and unify with overlapping shadows.
            if (overlapsNext)
            {
                if (overlapsPrev)
                {
                    // Overlaps both, so unify one and delete the other.
                    shadows[index - 1].End = Math.Max(shadows[index - 1].End, shadows[index].End);
                    shadows.RemoveAt(index);
                }
                else
                {
                    // Just overlaps the next shadow, so unify it with that.
                    shadows[index].Start = Math.Min(shadows[index].Start, shadow.Start);
                }
            }
            else
            {
                if (overlapsPrev)
                {
                    // Just overlaps the previous shadow, so unify it with that.
                    shadows[index - 1].End = Math.Max(shadows[index - 1].End, shadow.End);
                }
                else
                {
                    // Does not overlap anything, so insert.
                    shadows.Insert(index, shadow);
                }
            }

            // See if we are now shadowing everything.
            return((shadows.Count == 1) && (shadows[0].Start == 0) && (shadows[0].End == 1));
        }
Exemple #2
0
        private int RefreshOctant(VectorBase start, int octant)
        {
            var        numExplored = 0;
            VectorBase rowInc      = null;
            VectorBase colInc      = null;

            // Figure out which direction to increment based on the octant. Octant 0
            // starts at 12 - 2 o'clock, and octants proceed clockwise from there.
            switch (octant)
            {
            case 0:
                rowInc = new VectorBase(0, -1);
                colInc = new VectorBase(1, 0);
                break;

            case 1:
                rowInc = new VectorBase(1, 0);
                colInc = new VectorBase(0, -1);
                break;

            case 2:
                rowInc = new VectorBase(1, 0);
                colInc = new VectorBase(0, 1);
                break;

            case 3:
                rowInc = new VectorBase(0, 1);
                colInc = new VectorBase(1, 0);
                break;

            case 4:
                rowInc = new VectorBase(0, 1);
                colInc = new VectorBase(-1, 0);
                break;

            case 5:
                rowInc = new VectorBase(-1, 0);
                colInc = new VectorBase(0, 1);
                break;

            case 6:
                rowInc = new VectorBase(-1, 0);
                colInc = new VectorBase(0, -1);
                break;

            case 7:
                rowInc = new VectorBase(0, -1);
                colInc = new VectorBase(-1, 0);
                break;
            }

            if (rowInc == null || colInc == null)
            {
                throw new ArgumentNullException();
            }

            shadows = new List <FovShadow>();

            var bounds     = Stage.Bounds();
            var fullShadow = false;

            // Sweep through the rows ('rows' may be vertical or horizontal based on
            // the incrementors). Start at row 1 to skip the center position.
            for (var row = 1;; row++)
            {
                var pos = start + (rowInc * row);

                // If we've traversed out of bounds, bail.
                // Note: this improves performance, but works on the assumption that the
                // starting tile of the FOV is in bounds.
                if (!bounds.Contains(pos))
                {
                    break;
                }

                for (var col = 0; col <= row; col++)
                {
                    var       blocksLight = false;
                    var       visible     = false;
                    FovShadow projection  = null;

                    // If we know the entire row is in shadow, we don't need to be more
                    // specific.
                    if (!fullShadow)
                    {
                        blocksLight = !Stage[pos].IsTransparent;
                        projection  = GetProjection(col, row);
                        visible     = !IsInShadow(projection);
                    }

                    // Set the visibility of this tile.
                    if (Stage[pos].SetVisible(visible))
                    {
                        numExplored++;
                    }

                    // Add any opaque tiles to the shadow map.
                    if (blocksLight)
                    {
                        fullShadow = AddShadow(projection);
                    }

                    // Move to the next column.
                    pos += colInc;

                    // If we've traversed out of bounds, bail on this row.
                    // note: this improves performance, but works on the assumption that
                    // the starting tile of the FOV is in bounds.
                    if (!bounds.Contains(pos))
                    {
                        break;
                    }
                }
            }

            return(numExplored);
        }
Exemple #3
0
 public bool Contains(FovShadow projection)
 {
     return((Start <= projection.Start) && (End >= projection.End));
 }
Exemple #4
0
 private bool IsInShadow(FovShadow projection)
 {
     // Check the shadow list.
     return(shadows.Any(shadow => shadow.Contains(projection)));
 }