Add v2 gameplay queries: walkable / blocks_walk / blocks_sight

Replace the v1 is_walkable stub with a v2-aware version that requires
surface tile present and no blocking wall layer cell. Add blocks_walk
(wall-layer OOB-safe check) and blocks_sight (wall + upper_wall with
per-tile blocks_sight override). v1 path unchanged via schema_version
branch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Axel Meyer
2026-05-21 15:50:59 +02:00
parent 15fd68670e
commit 53c9fe4c0c

View File

@@ -385,10 +385,61 @@ function M.tile_at(a, b, c)
return m.tilemap.tiles[palette_id]
end
-- v2 walkability: surface non-empty AND no blocking wall
function M.is_walkable(a, b, c)
local t = M.tile_at(a, b, c)
local map_id, tx, ty
if c == nil then
map_id, tx, ty = current_map_id, a, b
else
map_id, tx, ty = a, b, c
if map_id == nil then map_id = current_map_id end
end
if not map_id then
error("maps.is_walkable: no current map")
end
local m = map_registry[map_id]
if m.schema_version ~= 2 then
-- v1 fallback: surface-only walkability via legacy tile_at
local t = M.tile_at(map_id, tx, ty)
if t == nil then return false end
return t.walkable == true
end
-- v2: needs surface tile present AND lower_wall/wall absent
local surface = M.tile_at_layer("surface", tx, ty, map_id)
if surface == nil then return false end
if M.cell_gid("lower_wall", tx, ty, map_id) ~= 0 then return false end
if M.cell_gid("wall", tx, ty, map_id) ~= 0 then return false end
return surface.walkable == true
end
function M.blocks_walk(x, y, map_id)
local id = map_id or current_map_id
if not id then error("maps.blocks_walk: no current map") end
local m = map_registry[id]
if x < 0 or x >= m.size.w or y < 0 or y >= m.size.h then return false end
if M.cell_gid("lower_wall", x, y, id) ~= 0 then return true end
if M.cell_gid("wall", x, y, id) ~= 0 then return true end
return false
end
function M.blocks_sight(x, y, map_id)
local id = map_id or current_map_id
if not id then error("maps.blocks_sight: no current map") end
local m = map_registry[id]
if x < 0 or x >= m.size.w or y < 0 or y >= m.size.h then return false end
if M.cell_gid("wall", x, y, id) ~= 0 then return true end
-- upper_wall: per-tile blocks_sight flag in atlas metadata; default true for walls
local up_gid = M.cell_gid("upper_wall", x, y, id)
if up_gid ~= 0 then
local atlas_idx, tile_id, _rot = decode_gid(up_gid)
local atlas = m.atlases[atlas_idx + 1]
local tile = atlas and atlas.tiles[tile_id]
if tile and tile.blocks_sight == false then
return false
end
return true
end
return false
end
function M.tilemap_id(map_id)