you want to calculate if the person can see a given object based on range of view (distance) and feild of view (angle) and if the object is hidden behind walls
first distance use hypotenuse theorem to check if object is too far
adjacent = x2 - x1
opposite = y2 - y1
distance = sqrt(adjacent*adjacent + opposite*opposite)
The feild of view can be defined as a triangle with the persons position at one point and the extreme left or right of view making up the other two points. use cross product to check if object is beyond one of the extremes of vision
crossproduct = (x1-x2)*(y3-y2) - (x3-x2)*(y1-y2)
//where x2,y2 is the objects position
// and x1,y1 is the persons position
// and x3,y3 is any point that lies along one extreme of vision
// if left side returns < 0 object is not visible
// if right side returns > 0 object is not visible
now if you got this far you cast a single ray between the person and the object and if that ray reaches a wall you definately cannot see the object otherwise the object can be seen
putting it all together you get something like this :
// preparation for the function call
px = posX(ai)
py = posY(ai)
lx = cos(rotZ(ai) - fov) + px
ly = sin(rotZ(ai) - fov) + py
rx = cos(rotZ(ai) + fov) + px
ry = sin(rotZ(ai) + fov) + py
lc = cos(rotZ(ai) - fov + pi/2)*radi
ls = sin(rotZ(ai) - fov + pi/2)*radi
rc = cos(rotZ(ai) + fov - pi/2)*radi
rs = sin(rotZ(ai) + fov - pi/2)*radi
the subroutine :
sub visi(px,py, lx,ly,rx,ry, nx,ny, lc,ls,rc,rs)
local adj, opp, hyp
adj = nx - px
opp = ny - py
hyp = adj*adj + opp*opp
// is object too far?
if (hyp > range*range) return 0
// is object to far to left side?
if ((px-nx-lc)*(ly-ny-ls)-(lx-nx-lc)*(py-ny-ls) < 0) return 0
// is object too far to right side?
if ((px-nx-rc)*(ry-ny-rs)-(rx-nx-rc)*(py-ny-rs) > 0) return 0
// cast ray to see if any obstacles are in the way:
local cs,sn, mx,my, tx,ty, xs,ys, sx,sy, dx,dy
hyp = 1 / sqrt(hyp)
cs = adj*hyp
sn = opp*hyp
mx = int(px)
my = int(py)
tx = int(nx)
ty = int(ny)
xs = 0.5 * (1-sig(cs))
ys = 0.5 * (1-sig(sn))
sx = sqrt((sn*sn) / (cs*cs) + 1)
sy = sqrt((cs*cs) / (sn*sn) + 1)
if (cs < 0) then
dx = (px-mx)*sx
else
dx = (mx+1-px)*sx
endif
if (sn < 0) then
dy = (py-my)*sy
else
dy = (my+1-py)*sy
endif
repeat
if (dx < dy) then
dx = dx + sx
mx = mx + sig(cs)
else
dy = dy + sy
my = my + sig(sn)
endif
// I can see you ...
if (mx = tx) and (my = ty) return 1
until (grid(mx, my) > 0)
// I could see you but a wall is in my way
return 0
end sub