fix couch man

This commit is contained in:
DramaticShape
2026-07-29 15:44:52 -04:00
parent 3c1781f6b1
commit 60d5362c89
3 changed files with 40 additions and 20 deletions
+17 -10
View File
@@ -735,14 +735,21 @@ return {
-- floor the artist had already drawn. So the couch keeps its
-- polygonal box and he stands on top of it, at NPC scale.
--
-- The mask keeps the couch's east rule (column 7) wherever it is
-- drawn dark, because that is where his hair crosses the tile seam
-- -- without it the overhang would float free of his head. The
-- cushion wedge under his legs and the two floor pixels above his
-- head are the only interior pixels it gives back.
-- The mask keeps ALL of column 7, the couch's east edge. Where that
-- column is drawn dark it is the couch's own rule -- but it is also
-- where his hair crosses the tile seam, so dropping it floats the
-- overhang free of his head. And where it is drawn WHITE it is the
-- right side of his face, so dropping it opens a slit down his cheek
-- (rows 5-8, which is exactly what the first cut did). Keeping the
-- rule twice costs nothing: tile 39 redraws it on the couch beneath
-- him either way. The background corners around his head and the
-- cushion wedge under his legs are the only pixels given back.
figures = {
{
class = "billboard",
-- the `cutout` pool: one voxel, a flat card -- the same thing
-- the walking NPCs are, so the man reads as a person and not
-- as a ten-voxel wedge of furniture
class = "cutout",
w = 2,
tiles = { 37, 57,
53, 60 },
@@ -754,10 +761,10 @@ return {
"XXXXXXXXX.......",
"XXXXXXXXXX......",
"XXXXXXXXXX......",
"XXXXXXX.X.......",
"XXXXXXX.X.......",
"XXXXXXX.X.......",
"XXXXXXX.X.......",
"XXXXXXXXX.......",
"XXXXXXXXX.......",
"XXXXXXXXX.......",
"XXXXXXXXX.......",
"XXXXXXXX........",
"XXXXXXXX........",
"XXXXXXXX........",
+8 -8
View File
@@ -2165,9 +2165,14 @@ local function buildFigure(S, map, fig, tx, ty, perRow)
baseY, support = bs.h, bs
end
-- He stands in the depth band of the tile row he is DRAWN in, centred.
-- No south shift: buildObject nudges a supported prop one row back
-- because a monitor is drawn in the rows ABOVE the desk it stands on,
-- so its drawn row is not its standing row. A figure's mask already
-- says exactly which row is his -- shifting it walked him off his own
-- cell and onto the couch's southern half.
local depth = PINNED_DEPTH[fig.class] or PINNED_DEPTH.billboard
local z0 = ty * 8 + math.floor(lowY / 8) * 8
+ (support and 8 or 0) + (8 - depth) / 2
local z0 = ty * 8 + math.floor(lowY / 8) * 8 + (8 - depth) / 2
local z1 = z0 + depth
-- ONE object by construction: the figure keeps its drawn proportions
@@ -2234,8 +2239,6 @@ end
-- own tiles, so a match can never fire twice on the same drawing.
function Structures.buildFigures(S, map, x0, x1, y0, y1)
local figures = TileShape.figures(map.tileset.id)
print("[fig] map", map.id, "tileset", map.tileset.id, "figures",
figures and #figures or "nil")
if not figures then return end
local perRow = map.tileset.tilesPerRow or 16
for _, fig in ipairs(figures) do
@@ -2250,10 +2253,7 @@ function Structures.buildFigures(S, map, x0, x1, y0, y1)
break
end
end
if hit then
print("[fig] MATCH at", tx, ty)
buildFigure(S, map, fig, tx, ty, perRow)
end
if hit then buildFigure(S, map, fig, tx, ty, perRow) end
end
end
end
+15 -2
View File
@@ -57,7 +57,14 @@ T.check(type(figs) == "table" and #figs == 1,
local fig = figs[1]
T.eq(fig.w, 2, "the figure is two tiles across")
T.eq(fig.h, 2, "the figure is two tiles tall")
T.eq(fig.n, 124, "the mask claims 124 pixels of the 256 it spans")
T.eq(fig.n, 128, "the mask claims 128 pixels of the 256 it spans")
-- no holes in him: his tiles' column 7 is the couch's east rule AND the
-- right side of his face, and masking it out by shade slit his cheek open
for ly = 5, 8 do
T.check(fig.mask[ly * (fig.w * 8) + 7] == true,
"his cheek is solid at row " .. ly .. " (the column-7 slit)")
end
T.eq(fig.tiles[1], 37, "it starts at the tile his head is drawn in")
T.eq(fig.under[1], 39, "which wears the couch's own cushion once he is off")
T.eq(fig.under[2], 1, "and the floor tiles wear the clean art (57 -> 1)")
@@ -160,7 +167,13 @@ T.eq(minY, 8, "his feet are on the couch's top face, not the floor")
T.eq(maxY, 24, "and he stands his drawn 16px tall from there")
T.eq(minX, 8, "he starts at the tile column he is drawn in")
T.eq(maxX, 18, "and reaches his hair's overhang, two pixels east of it")
T.eq(maxZ - minZ, 10, "a billboard-pool standee, ten voxels of body")
T.eq(maxZ - minZ, 1, "a flat card, one voxel deep, like the walking NPCs")
-- and he stands in the depth band of the row he is DRAWN in -- the couch's
-- northern cell (tile row 9 spans z 72..80), not shifted onto its southern
-- half the way a supported prop is
T.check(minZ >= 72 and maxZ <= 80,
"he stands on his own cell, not the couch's southern half")
-- the cushion wedge under his legs stayed with the couch: his lowest row
-- is his foot alone, not the whole tile width