34 lines
930 B
Lua
34 lines
930 B
Lua
-- Bresenham line of sight. A shot is clear when no cell strictly between the two
|
|
-- endpoints blocks sight; the endpoints themselves are never treated as blockers
|
|
-- so an actor can fire at something standing in a doorway.
|
|
|
|
local Los = {}
|
|
|
|
function Los.line(x0, y0, x1, y1)
|
|
local cells = {}
|
|
local dx = math.abs(x1 - x0)
|
|
local dy = math.abs(y1 - y0)
|
|
local sx = x0 < x1 and 1 or -1
|
|
local sy = y0 < y1 and 1 or -1
|
|
local err = dx - dy
|
|
local x, y = x0, y0
|
|
while true do
|
|
cells[#cells + 1] = { x = x, y = y }
|
|
if x == x1 and y == y1 then break end
|
|
local e2 = 2 * err
|
|
if e2 > -dy then err = err - dy; x = x + sx end
|
|
if e2 < dx then err = err + dx; y = y + sy end
|
|
end
|
|
return cells
|
|
end
|
|
|
|
function Los.clear(map, x0, y0, x1, y1)
|
|
local cells = Los.line(x0, y0, x1, y1)
|
|
for i = 2, #cells - 1 do
|
|
if map:blocksSight(cells[i].x, cells[i].y) then return false end
|
|
end
|
|
return true
|
|
end
|
|
|
|
return Los
|