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;
}