示例#1
0
/*
 * ====================
 * =
 * = P_TraverseIntercepts
 * =
 * = Returns true if the traverser function returns true for all lines
 * ====================
 */

        public static bool P_TraverseIntercepts(P_PathTraverse_delegate func, int maxfrac)
        {
            int count;
            int dist;

            p_local.intercept_t scan, in_;

            count = intercept_p;
            in_   = null;               // shut up compiler warning

            while ((count--) != 0)
            {
                dist = DoomDef.MAXINT;
                for (int i = 0; i < intercept_p; ++i)
                {
                    scan = intercepts[i];
                    if (scan.frac < dist)
                    {
                        dist = scan.frac;
                        in_  = scan;
                    }
                }

                if (dist > maxfrac)
                {
                    return(true);                       // checked everything in range
                }
                if (!func.function(in_))
                {
                    return(false);                      // don't bother going farther
                }
                in_.frac = DoomDef.MAXINT;
            }

            return(true);       // everything was traversed
        }
示例#2
0
        public static bool P_PathTraverse(int x1, int y1, int x2, int y2,
                                          int flags, P_PathTraverse_delegate trav)
        {
            int xt1, yt1, xt2, yt2;
            int xstep, ystep;
            int partial;
            int xintercept, yintercept;
            int mapx, mapy, mapxstep, mapystep;
            int count;

            earlyout = (flags & p_local.PT_EARLYOUT) != 0;

            r_main.validcount++;
            intercept_p = 0;

            if (((x1 - p_setup.bmaporgx) & (p_local.MAPBLOCKSIZE - 1)) == 0)
            {
                x1 += DoomDef.FRACUNIT;                                         // don't side exactly on a line
            }
            if (((y1 - p_setup.bmaporgy) & (p_local.MAPBLOCKSIZE - 1)) == 0)
            {
                y1 += DoomDef.FRACUNIT;                                         // don't side exactly on a line
            }
            trace.x  = x1;
            trace.y  = y1;
            trace.dx = x2 - x1;
            trace.dy = y2 - y1;

            x1 -= p_setup.bmaporgx;
            y1 -= p_setup.bmaporgy;
            xt1 = x1 >> p_local.MAPBLOCKSHIFT;
            yt1 = y1 >> p_local.MAPBLOCKSHIFT;

            x2 -= p_setup.bmaporgx;
            y2 -= p_setup.bmaporgy;
            xt2 = x2 >> p_local.MAPBLOCKSHIFT;
            yt2 = y2 >> p_local.MAPBLOCKSHIFT;

            if (xt2 > xt1)
            {
                mapxstep = 1;
                partial  = DoomDef.FRACUNIT - ((x1 >> p_local.MAPBTOFRAC) & (DoomDef.FRACUNIT - 1));
                ystep    = d_main.FixedDiv(y2 - y1, Math.Abs(x2 - x1));
            }
            else if (xt2 < xt1)
            {
                mapxstep = -1;
                partial  = (x1 >> p_local.MAPBTOFRAC) & (DoomDef.FRACUNIT - 1);
                ystep    = d_main.FixedDiv(y2 - y1, Math.Abs(x2 - x1));
            }
            else
            {
                mapxstep = 0;
                partial  = DoomDef.FRACUNIT;
                ystep    = 256 * DoomDef.FRACUNIT;
            }
            yintercept = (y1 >> p_local.MAPBTOFRAC) + DoomDef.FixedMul(partial, ystep);


            if (yt2 > yt1)
            {
                mapystep = 1;
                partial  = DoomDef.FRACUNIT - ((y1 >> p_local.MAPBTOFRAC) & (DoomDef.FRACUNIT - 1));
                xstep    = d_main.FixedDiv(x2 - x1, Math.Abs(y2 - y1));
            }
            else if (yt2 < yt1)
            {
                mapystep = -1;
                partial  = (y1 >> p_local.MAPBTOFRAC) & (DoomDef.FRACUNIT - 1);
                xstep    = d_main.FixedDiv(x2 - x1, Math.Abs(y2 - y1));
            }
            else
            {
                mapystep = 0;
                partial  = DoomDef.FRACUNIT;
                xstep    = 256 * DoomDef.FRACUNIT;
            }
            xintercept = (x1 >> p_local.MAPBTOFRAC) + DoomDef.FixedMul(partial, xstep);


            //
            // step through map blocks
            // Count is present to prevent a round off error from skipping the break
            mapx = xt1;
            mapy = yt1;

            for (count = 0; count < 64; count++)
            {
                if ((flags & p_local.PT_ADDLINES) != 0)
                {
                    if (!P_BlockLinesIterator(mapx, mapy, PIT_AddLineIntercepts))
                    {
                        return(false);                          // early out
                    }
                }
                if ((flags & p_local.PT_ADDTHINGS) != 0)
                {
                    if (!P_BlockThingsIterator(mapx, mapy, PIT_AddThingIntercepts))
                    {
                        return(false);                          // early out
                    }
                }

                if (mapx == xt2 && mapy == yt2)
                {
                    break;
                }

                if ((yintercept >> DoomDef.FRACBITS) == mapy)
                {
                    yintercept += ystep;
                    mapx       += mapxstep;
                }
                else if ((xintercept >> DoomDef.FRACBITS) == mapx)
                {
                    xintercept += xstep;
                    mapy       += mapystep;
                }
            }


            //
            // go through the sorted list
            //
            return(p_maputl.P_TraverseIntercepts(trav, DoomDef.FRACUNIT));
        }