FSO.SimAntics.VMArchitecture.RaycastWall C# (CSharp) Method

RaycastWall() public method

Checks if there is a wall between two (Full Tile) points.
public RaycastWall ( Point p1, Point p2, sbyte level ) : bool
p1 Point Start Position (Full Tile Pos)
p2 Point End Position (Full Tile Pos)
level sbyte Level for both points
return bool
        public bool RaycastWall(Point p1, Point p2, sbyte level)
        {
            //Bresenham's line algorithm, modified to check walls
            //http://lifc.univ-fcomte.fr/home/~ededu/projects/bresenham/

            int i, ystep, xstep, error, errorprev, ddy, ddx,
                y = p1.Y,
                x = p1.X,
                dx = p2.X - x,
                dy = p2.Y - y;

            if (dy < 0)
            {
                ystep = -1;
                dy = -dy;
            }
            else
                ystep = 1;

            if (dx < 0)
            {
                xstep = -1;
                dx = -dx;
            }
            else
                xstep = 1;

            ddy = dy * 2;
            ddx = dx * 2;

            int xAOff = (xstep > 0) ? 1 : 0;
            int yAOff = (ystep > 0) ? 1 : 0;

            if (ddx >= ddy)
            {
                errorprev = error = dx;
                for (i = 0; i < dx; i++)
                {
                    int oldx = x;
                    int oldy = y;
                    x += xstep;
                    error += ddy;
                    if (error > ddx)
                    {
                        y += ystep;
                        error -= ddx;

                        //extra steps
                        if (error + errorprev < ddx)
                        {
                            //moved into x before y
                            if (GetWall((short)(oldx+xAOff), (short)(oldy), level).TopLeftSolid) return true;
                            if (GetWall((short)(x), (short)(oldy + yAOff), level).TopRightSolid) return true;
                        }
                        else
                        {
                            //moved into y before x
                            if (GetWall((short)(oldx), (short)(oldy + yAOff), level).TopRightSolid) return true;
                            if (GetWall((short)(oldx + xAOff), (short)(y), level).TopLeftSolid) return true;
                        }
                    }
                    else
                    {
                        //only move into x
                        if (GetWall((short)(oldx+xAOff), (short)(oldy), level).TopLeftSolid) return true;
                    }
                    errorprev = error;
                }
            }
            else
            {
                errorprev = error = dy;
                for (i = 0; i < dy; i++)
                {
                    int oldx = x;
                    int oldy = y;
                    y += ystep;
                    error += ddx;
                    if (error > ddy)
                    {
                        x += xstep;
                        error -= ddy;

                        //extra steps
                        if (error + errorprev < ddy)
                        {
                            //moved into y before x
                            if (GetWall((short)(oldx), (short)(oldy + yAOff), level).TopRightSolid) return true;
                            if (GetWall((short)(oldx+xAOff), (short)(y), level).TopLeftSolid) return true;
                        }
                        else
                        {
                            //moved into x before y
                            if (GetWall((short)(oldx+xAOff), (short)(oldy), level).TopLeftSolid) return true;
                            if (GetWall((short)(x), (short)(oldy + yAOff), level).TopRightSolid) return true;
                        }
                    }
                    else
                    {
                        //only move into y
                        if (GetWall((short)(oldx), (short)(oldy+yAOff), level).TopRightSolid) return true;
                    }

                    errorprev = error;
                }
            }
            return false;
        }