Iterate layers in z-order with entity-slot split; multi-layer draw_map
Adds LAYER_ORDER_PRE/POST_ENTITIES constants, iterate_layers_pre/post_entities helpers, draw_layer and draw_v1_legacy locals, and draw_map_pre/post_entities public functions. draw_map becomes a backward-compat wrapper over both. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
158
init.lua
158
init.lua
@@ -99,6 +99,10 @@ end
|
||||
-- Schema-v2 Layer-Whitelist + Validation
|
||||
-- =====================================================================
|
||||
|
||||
-- Layer z-order (back-to-front) split at entity slot
|
||||
local LAYER_ORDER_PRE_ENTITIES = { "foundation", "subsurface", "surface", "topsurface" }
|
||||
local LAYER_ORDER_POST_ENTITIES = { "lower_wall", "wall", "upper_wall", "canopy" }
|
||||
|
||||
local VALID_LAYER_NAMES = {
|
||||
foundation = true,
|
||||
subsurface = true,
|
||||
@@ -289,6 +293,80 @@ local function build_map_v2(t_map, resolved_atlases)
|
||||
}
|
||||
end
|
||||
|
||||
-- =====================================================================
|
||||
-- Internal render helpers (draw_layer, draw_v1_legacy)
|
||||
-- These must be declared before the public draw_map* functions that call them.
|
||||
-- =====================================================================
|
||||
|
||||
local function draw_layer(m, layer_name)
|
||||
local layer = m.layers[layer_name]
|
||||
if not layer then return end
|
||||
local sz = m.size
|
||||
local ts = m.tile_size
|
||||
for y = 0, sz.h - 1 do
|
||||
for x = 0, sz.w - 1 do
|
||||
local idx = y * sz.w + x + 1
|
||||
local gid = layer.tiles[idx] or 0
|
||||
if gid ~= 0 then
|
||||
local atlas_idx, tile_id, rot_quad = decode_gid(gid)
|
||||
local atlas = m.atlases[atlas_idx + 1]
|
||||
if atlas then
|
||||
local tile = atlas.tiles[tile_id]
|
||||
if tile then
|
||||
local px = x * ts
|
||||
local py = y * ts
|
||||
local rot_deg = rot_quad * 90.0
|
||||
if tile.texture_handle then
|
||||
engine.render.draw_sprite_transform(
|
||||
tile.texture_handle,
|
||||
px + ts / 2, py + ts / 2,
|
||||
math.rad(rot_deg),
|
||||
1.0, 1.0,
|
||||
ts / 2, ts / 2,
|
||||
0xFFFFFFFF
|
||||
)
|
||||
else
|
||||
local c = tile.color or { 100, 100, 100 }
|
||||
engine.render.draw_rect(px, py, ts, ts,
|
||||
engine.render.rgb(c[1], c[2], c[3]))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function draw_v1_legacy(m)
|
||||
local tm = m.tilemap
|
||||
if not tm then return end
|
||||
local ts = tm.tile_size
|
||||
for y = 0, m.size.h - 1 do
|
||||
for x = 0, m.size.w - 1 do
|
||||
local idx = y * m.size.w + x + 1
|
||||
local tile_id = m.tiles[idx]
|
||||
local tile = tm.tiles[tile_id]
|
||||
local rot_deg = (m.tile_rotations and m.tile_rotations[idx]) or 0
|
||||
local px = x * ts
|
||||
local py = y * ts
|
||||
if tile.texture_handle then
|
||||
engine.render.draw_sprite_transform(
|
||||
tile.texture_handle,
|
||||
px + ts / 2, py + ts / 2,
|
||||
math.rad(rot_deg),
|
||||
1.0, 1.0,
|
||||
ts / 2, ts / 2,
|
||||
0xFFFFFFFF
|
||||
)
|
||||
else
|
||||
local c = tile.color or { 100, 100, 100 }
|
||||
engine.render.draw_rect(px, py, ts, ts,
|
||||
engine.render.rgb(c[1], c[2], c[3]))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- =====================================================================
|
||||
-- Public API
|
||||
-- =====================================================================
|
||||
@@ -549,37 +627,57 @@ function M.load_textures(asset_aliases)
|
||||
end
|
||||
end
|
||||
|
||||
function M.iterate_layers_pre_entities(fn, map_id)
|
||||
local id = map_id or current_map_id
|
||||
if not id then error("maps.iterate_layers_pre_entities: no current map") end
|
||||
local m = map_registry[id]
|
||||
if m.schema_version ~= 2 then
|
||||
-- v1 (legacy): only surface conceptually
|
||||
fn("surface")
|
||||
return
|
||||
end
|
||||
for _, name in ipairs(LAYER_ORDER_PRE_ENTITIES) do
|
||||
if m.layers[name] then fn(name) end
|
||||
end
|
||||
end
|
||||
|
||||
function M.iterate_layers_post_entities(fn, map_id)
|
||||
local id = map_id or current_map_id
|
||||
if not id then error("maps.iterate_layers_post_entities: no current map") end
|
||||
local m = map_registry[id]
|
||||
if m.schema_version ~= 2 then return end -- v1 has nothing post
|
||||
for _, name in ipairs(LAYER_ORDER_POST_ENTITIES) do
|
||||
if m.layers[name] then fn(name) end
|
||||
end
|
||||
end
|
||||
|
||||
function M.draw_map_pre_entities()
|
||||
local id = current_map_id
|
||||
if id == nil then return end
|
||||
local m = map_registry[id]
|
||||
if m.schema_version ~= 2 then
|
||||
draw_v1_legacy(m)
|
||||
return
|
||||
end
|
||||
for _, name in ipairs(LAYER_ORDER_PRE_ENTITIES) do
|
||||
if m.layers[name] then draw_layer(m, name) end
|
||||
end
|
||||
end
|
||||
|
||||
function M.draw_map_post_entities()
|
||||
local id = current_map_id
|
||||
if id == nil then return end
|
||||
local m = map_registry[id]
|
||||
if m.schema_version ~= 2 then return end
|
||||
for _, name in ipairs(LAYER_ORDER_POST_ENTITIES) do
|
||||
if m.layers[name] then draw_layer(m, name) end
|
||||
end
|
||||
end
|
||||
|
||||
-- Backward-compat: draw_map renders everything (pre + post, no entity slot)
|
||||
function M.draw_map()
|
||||
local map_id = M.current()
|
||||
if map_id == nil then return end
|
||||
local m = map_registry[map_id]
|
||||
local tm = m.tilemap
|
||||
local ts = tm.tile_size
|
||||
for y = 0, m.size.h - 1 do
|
||||
for x = 0, m.size.w - 1 do
|
||||
local idx = y * m.size.w + x + 1
|
||||
local tile_id = m.tiles[idx]
|
||||
local tile = tm.tiles[tile_id]
|
||||
local rot_deg = (m.tile_rotations and m.tile_rotations[idx]) or 0
|
||||
local px = x * ts
|
||||
local py = y * ts
|
||||
if tile.texture_handle then
|
||||
-- Sprite mode: draw_sprite_transform with rotation about tile center.
|
||||
engine.render.draw_sprite_transform(
|
||||
tile.texture_handle,
|
||||
px + ts / 2, py + ts / 2,
|
||||
math.rad(rot_deg),
|
||||
1.0, 1.0,
|
||||
ts / 2, ts / 2,
|
||||
0xFFFFFFFF
|
||||
)
|
||||
else
|
||||
-- Color fallback (Phase 1 mode).
|
||||
local c = tile.color or { 100, 100, 100 }
|
||||
engine.render.draw_rect(px, py, ts, ts, engine.render.rgb(c[1], c[2], c[3]))
|
||||
end
|
||||
end
|
||||
end
|
||||
M.draw_map_pre_entities()
|
||||
M.draw_map_post_entities()
|
||||
end
|
||||
|
||||
-- Forward-compat stubs (DEPRECATED-MVP — implemented in later slices)
|
||||
|
||||
Reference in New Issue
Block a user