コード例 #1
0
ファイル: Fov.cs プロジェクト: RogueCollab/RogueEssence
        private static void CastPartialLight(Loc rectStart, Loc rectSize, Loc start, Grid.LocTest checkBlock, LightOperation lightOp, int startColumn, int startSlope, int endSlope, Dir8 dir)
        {
            // Set true if the previous cell we encountered was blocked.
            bool prevBlocked = false;

            int savedRightSlope = -SLOPE_GRANULARITY;

            int colVal = OctantTransform[(int)dir, 0] != 0 ? OctantTransform[(int)dir, 0] : OctantTransform[(int)dir, 2];

            Loc colDiff = new Loc();

            if (colVal > 0)
            {
                colDiff = rectStart + rectSize - start - new Loc(1);
            }
            else
            {
                colDiff = start - rectStart;
            }

            int maxCol = OctantTransform[(int)dir, 0] != 0 ? colDiff.X : colDiff.Y;

            int rowVal  = OctantTransform[(int)dir, 3] != 0 ? OctantTransform[(int)dir, 3] : OctantTransform[(int)dir, 1];
            Loc rowDiff = new Loc();

            if (rowVal > 0)
            {
                rowDiff = rectStart + rectSize - start - new Loc(1);
            }
            else
            {
                rowDiff = start - rectStart;
            }
            int maxRow = OctantTransform[(int)dir, 3] != 0 ? rowDiff.Y : rowDiff.X;

            for (int currentCol = startColumn; currentCol <= maxCol; currentCol++)
            {
                int xc = currentCol;

                for (int yc = Math.Min(maxRow, currentCol); yc >= 0; yc--)
                {
                    int gridX = start.X + xc * OctantTransform[(int)dir, 0] + yc * OctantTransform[(int)dir, 1];
                    int gridY = start.Y + xc * OctantTransform[(int)dir, 2] + yc * OctantTransform[(int)dir, 3];

                    //due to safeguards, this block should never be hit
                    if (!Collision.InBounds(rectStart, rectSize, new Loc(gridX, gridY)))
                    {
                        continue;
                    }

                    int leftBlockSlope  = (yc * SLOPE_GRANULARITY + SLOPE_GRANULARITY / 2) * 2 / (xc * 2 - 1);
                    int rightBlockSlope = (yc * SLOPE_GRANULARITY - SLOPE_GRANULARITY / 2) * 2 / (xc * 2 + 1);

                    if (rightBlockSlope > startSlope) // Block is above the left edge of our view area; skip.
                    {
                        continue;
                    }
                    else if (leftBlockSlope < endSlope) // Block is below the right edge of our view area; we're done.
                    {
                        break;
                    }

                    float lighting = 1f;
                    if (leftBlockSlope > startSlope) // Block is above the left edge of our view area; skip.
                    {
                        lighting = 0.5f;
                    }
                    else if (rightBlockSlope < endSlope) // Block is below the right edge of our view area; we're done.
                    {
                        lighting = 0.5f;
                    }

                    if (((int)dir % 2 == 0 || yc != 0) && ((int)dir % 2 == 1 || yc != currentCol))
                    {
                        lightOp(gridX, gridY, lighting);
                    }

                    bool curBlocked = checkBlock(new Loc(gridX, gridY));

                    if (prevBlocked)
                    {
                        if (curBlocked)
                        {
                            savedRightSlope = rightBlockSlope;
                        }
                        else
                        {
                            prevBlocked = false;
                            startSlope  = savedRightSlope;
                        }
                    }
                    else
                    {
                        if (curBlocked)
                        {
                            if (leftBlockSlope <= startSlope)
                            {
                                CastPartialLight(rectStart, rectSize, start, checkBlock, lightOp, currentCol + 1, startSlope, leftBlockSlope, dir);
                            }

                            prevBlocked     = true;
                            savedRightSlope = rightBlockSlope;
                        }
                    }
                }

                if (prevBlocked)
                {
                    break;
                }
            }
        }
コード例 #2
0
ファイル: Fov.cs プロジェクト: RogueCollab/RogueEssence
        public static void CalculateAnalogFOV(Loc rectStart, Loc rectSize, Loc start, Grid.LocTest checkBlock, LightOperation lightOp)
        {
            // Viewer's cell is always visible.
            if (Collision.InBounds(rectStart, rectSize, start))
            {
                lightOp(start.X, start.Y, 1f);
            }

            for (int dir = 0; dir < DirExt.DIR8_COUNT; dir++)
            {
                CastPartialLight(rectStart, rectSize, start, checkBlock, lightOp, 1, 3 * SLOPE_GRANULARITY, -SLOPE_GRANULARITY, (Dir8)dir);
            }
        }