コード例 #1
0
 ///<summary>Returns true if cell is lit from any direction.</summary>
 public bool IsLit(Point cell)
 {
     if (MagicalLightState == MagicalLightState.MagicalLight)
     {
         return(true);
     }
     else if (MagicalLightState == MagicalLightState.MagicalDarkness)
     {
         return(false);
     }
     else
     {
         if (TileDefinition.IsOpaque(Map.Tiles[cell]))
         {
             foreach (Point neighbor in cell.EnumeratePointsAtChebyshevDistance(1, false, false))
             {
                 if (!neighbor.ExistsBetweenMapEdges())
                 {
                     continue;
                 }
                 if (cellBrightness[neighbor] > 0 && !TileDefinition.IsOpaque(Map.Tiles[neighbor]))
                 {
                     return(true);
                 }
             }
             return(false);
         }
         else
         {
             return(cellBrightness[cell] > 0);
         }
     }
 }
コード例 #2
0
        public bool CellIsOpaque(Point p)
        {
            TileType type = Tiles[p];

            if (TileDefinition.IsOpaque(type))
            {
                return(true);
            }
            if (Features[p].IsOpaque())
            {
                return(true);
            }
            return(false);
        }
コード例 #3
0
 private void UpdateBrightnessWithinRadius(Point sourceCell, int radius, int increment)
 {
     for (int i = sourceCell.Y - radius; i <= sourceCell.Y + radius; ++i)
     {
         for (int j = sourceCell.X - radius; j <= sourceCell.X + radius; ++j)
         {
             Point p = new Point(j, i);
             if (!p.ExistsBetweenMapEdges())
             {
                 continue;
             }
             if (!TileDefinition.IsOpaque(Map.Tiles[p]) && sourceCell.CheckReciprocalBresenhamLineOfSight(p, Map.Tiles))
             {
                 cellBrightness[p] += increment;
             }
         }
     }
 }
コード例 #4
0
 ///<summary>Returns true if cell is lit AND (for opaque cells) if the observer is on the right side to see the light.</summary>
 public bool CellAppearsLitToObserver(Point cell, Point observer)
 {
     if (MagicalLightState == MagicalLightState.MagicalLight)
     {
         return(true);
     }
     else if (!IsLit(cell))
     {
         return(false);                              // If it isn't lit at all, stop here.
     }
     else
     {
         if (TileDefinition.IsOpaque(Map.Tiles[cell]))
         {
             // Light for opaque cells must be done carefully so light sources aren't visible through walls.
             // If the observer has LOS to any adjacent lit nonopaque cell, that observer knows this wall is lit.
             for (int i = 0; i < 8; ++i)
             {
                 Dir8  dir      = EightDirections.Eight[i];
                 Point neighbor = cell.PointInDir(dir);
                 if (!neighbor.ExistsBetweenMapEdges())
                 {
                     continue;
                 }
                 if (cellBrightness[neighbor] == 0)
                 {
                     continue;
                 }
                 if (observer.CheckReciprocalBresenhamLineOfSight(neighbor, Map.Tiles))
                 {
                     return(true);
                 }
             }
             return(false);
         }
         else
         {
             return(true);                    // Cell is lit and not opaque, so it appears lit from anywhere.
         }
     }
 }
コード例 #5
0
 public static bool HasLOS(this Point source, Point destination, PointArray <TileType> map)         //todo, move this, to use NeverInLOS from DungeonMap
 {
     if (TileDefinition.IsOpaque(map[destination]))
     {
         Point[] neighbors = GetNeighborsBetween(destination, source);
         for (int i = 0; i < neighbors.Length; ++i)
         {
             if (TileDefinition.IsOpaque(map[neighbors[i]]))
             {
                 continue;
             }
             if (CheckReciprocalBresenhamLineOfSight(source, neighbors[i], map))
             {
                 return(true);
             }
         }
         return(false);
     }
     else
     {
         return(CheckReciprocalBresenhamLineOfSight(source, destination, map));
     }
 }
コード例 #6
0
        public static bool CheckReciprocalBresenhamLineOfSight(this Point source, Point destination, PointArray <TileType> map)         //todo, what to do with map?
        {
            int x1         = source.X;
            int y1         = source.Y;
            int x2         = destination.X;
            int y2         = destination.Y;
            int dx         = Math.Abs(x2 - x1);
            int dy         = Math.Abs(y2 - y1);
            int incrementX = x1 == x2? 0 : x1 < x2? 1 : -1;
            int incrementY = y1 == y2? 0 : y1 < y2? 1 : -1;

            if (dx <= 1 && dy <= 1)
            {
                return(true);                               // Automatically pass the check for anything in the same or adjacent cells.
            }
            // Next, handle simple cases that don't need Bresenham at all. These cases correspond to straight lines in the 8 directions:
            if (dx == 0 || dy == 0 || (y1 + x1 == y2 + x2) || (y1 - x1 == y2 - x2))     // (if slope is undefined, 0, -1, or 1)
            {
                do
                {
                    x1 += incrementX;                     // Increment first, so that the opacity of 'source' is ignored.
                    y1 += incrementY;
                    if (TileDefinition.IsOpaque(map[x1, y1]))
                    {
                        return(false);
                    }
                } while(x1 != x2 || y1 != y2);
                return(true);
            }
            // If it wasn't a simple case, move on to reciprocal Bresenham:
            bool xMajor   = (dx > dy);
            int  er       = 0;      // error accumulator
            bool blockedA = false;  // These 2 are used to track whether each of the 2 possible paths per line is blocked or not.
            bool blockedB = false;  // (The result is equivalent to calculating 2 regular Bresenham lines, source->dest and dest->source.)

            if (xMajor)
            {
                do
                {
                    x1 += incrementX;
                    er += dy;
                    if (er << 1 > dx)
                    {
                        y1 += incrementY;
                        er -= dx;
                    }
                    if (TileDefinition.IsOpaque(map[x1, y1]))
                    {
                        if (blockedB || er << 1 != dx)
                        {
                            return(false);
                        }
                        blockedA = true;
                    }
                    if (er << 1 == dx)                   // This is the part that makes this reciprocal, by checking both options while crossing a corner.
                    {
                        y1 += incrementY;                // Increment Y, then check the new position:
                        if (TileDefinition.IsOpaque(map[x1, y1]))
                        {
                            if (blockedA || er << 1 != dx)
                            {
                                return(false);
                            }
                            blockedB = true;
                        }
                        er -= dx;
                    }
                } while(x1 != x2);
            }
            else              // Y-major
            {
                do
                {
                    y1 += incrementY;
                    er += dx;
                    if (er << 1 > dy)
                    {
                        x1 += incrementX;
                        er -= dy;
                    }
                    if (TileDefinition.IsOpaque(map[x1, y1]))
                    {
                        if (blockedB || er << 1 != dy)
                        {
                            return(false);
                        }
                        blockedA = true;
                    }
                    if (er << 1 == dy)
                    {
                        x1 += incrementX;
                        if (TileDefinition.IsOpaque(map[x1, y1]))
                        {
                            if (blockedA || er << 1 != dy)
                            {
                                return(false);
                            }
                            blockedB = true;
                        }
                        er -= dy;
                    }
                } while(y1 != y2);
            }
            return(true);
        }