Files

879 lines
31 KiB
Lua

-- gen_tileset.lua — public/assets/tileset.png (256x128, 16x16 tiles, id = row*16+col)
local ROOT = "/Users/leidianyayi/Documents/GitHub/ModelTest20260714/Kimi-K3/"
local H = dofile(ROOT .. "tools/aseprite/helpers.lua")
local spr, img = H.new(256, 128)
local tiles = {}
-- ---- shared sub-draws ------------------------------------------------------
local function grassBase(t)
t.rectn(0, 0, 16, 16, "grass")
t.pn(3, 2, "grass_l"); t.pn(11, 5, "grass_l"); t.pn(6, 9, "grass_l")
t.pn(13, 12, "grass_l"); t.pn(1, 13, "grass_l"); t.pn(9, 3, "grass_l")
t.pn(5, 4, "grass_d"); t.pn(6, 4, "grass_d"); t.pn(6, 5, "grass_d")
t.pn(10, 11, "grass_d"); t.pn(11, 11, "grass_d"); t.pn(2, 8, "grass_d")
t.pn(14, 3, "grass_d"); t.pn(9, 14, "grass_d"); t.pn(12, 8, "grass_d")
end
local function roof(t, base, d, l, edge)
t.rectn(0, 0, 16, 16, base)
t.hln(0, 4, 16, d); t.hln(0, 9, 16, d); t.hln(0, 14, 16, d)
for x = 2, 15, 4 do t.vln(x, 5, 4, d) end
for x = 0, 15, 4 do t.vln(x, 10, 4, d) end
t.hln(0, 0, 16, l)
t.hln(0, 15, 16, d)
if edge == "L" then t.vln(0, 0, 16, d); t.vln(1, 0, 16, base) end
if edge == "R" then t.vln(15, 0, 16, d); t.vln(14, 0, 16, base) end
end
-- ===========================================================================
-- ROW 0 (ids 0-15) : ground / water / flowerbeds
-- ===========================================================================
tiles[0] = function(t) grassBase(t) end
tiles[1] = function(t)
grassBase(t)
H.flower(t, 8, 7, "pink", "yellow")
H.flower(t, 4, 11, "white", "yellow")
t.pn(12, 4, "pink"); t.pn(12, 5, "pink"); t.pn(11, 4, "pink")
end
tiles[2] = function(t)
grassBase(t)
H.flower(t, 6, 6, "yellow", "honey_d")
H.flower(t, 11, 10, "red", "yellow")
t.pn(3, 5, "white"); t.pn(4, 5, "white")
end
tiles[3] = function(t)
t.rectn(0, 0, 16, 16, "grass_d")
t.pn(3, 3, "grass"); t.pn(10, 6, "grass"); t.pn(6, 11, "grass"); t.pn(13, 13, "grass")
t.pn(5, 5, "grass_dd"); t.pn(6, 5, "grass_dd"); t.pn(11, 11, "grass_dd")
t.pn(2, 9, "grass_dd"); t.pn(14, 4, "grass_dd"); t.pn(9, 14, "grass_dd")
end
tiles[4] = function(t) -- dirt road
t.rectn(0, 0, 16, 16, "dirt")
t.pn(3, 3, "dirt_d"); t.pn(4, 3, "dirt_d"); t.pn(11, 6, "dirt_d")
t.pn(7, 10, "dirt_d"); t.pn(13, 12, "dirt_d"); t.pn(2, 13, "dirt_d")
t.pn(6, 4, "dirt_l"); t.pn(12, 8, "dirt_l"); t.pn(9, 13, "dirt_l"); t.pn(1, 6, "dirt_l")
end
tiles[5] = function(t) -- stone road
t.rectn(0, 0, 16, 16, "stone")
t.hln(0, 0, 16, "stone_d"); t.hln(0, 8, 16, "stone_d")
t.vln(0, 0, 8, "stone_d"); t.vln(8, 0, 8, "stone_d")
t.vln(4, 8, 8, "stone_d"); t.vln(12, 8, 8, "stone_d")
t.pn(2, 3, "stone_l"); t.pn(10, 3, "stone_l"); t.pn(6, 11, "stone_l"); t.pn(13, 12, "stone_l")
end
tiles[6] = function(t) -- stone road alt
t.rectn(0, 0, 16, 16, "stone")
t.hln(0, 0, 16, "stone_dd"); t.hln(0, 8, 16, "stone_dd")
t.vln(5, 0, 8, "stone_dd"); t.vln(13, 0, 8, "stone_dd")
t.vln(1, 8, 8, "stone_dd"); t.vln(9, 8, 8, "stone_dd")
t.pn(3, 3, "stone_l"); t.pn(11, 4, "stone_l"); t.pn(4, 11, "stone_l"); t.pn(12, 12, "stone_l")
t.pn(8, 2, "stone_d"); t.pn(7, 12, "stone_d")
end
tiles[7] = function(t) -- plaza brick
t.rectn(0, 0, 16, 16, "stone_l")
t.hln(0, 0, 16, "stone_d"); t.hln(0, 8, 16, "stone_d")
t.vln(0, 0, 16, "stone_d"); t.vln(8, 0, 16, "stone_d")
t.pn(1, 1, "stone_dd"); t.pn(9, 1, "stone_dd"); t.pn(1, 9, "stone_dd"); t.pn(9, 9, "stone_dd")
end
tiles[8] = function(t) -- lake water A
t.rectn(0, 0, 16, 16, "water")
t.hln(2, 4, 3, "water_l"); t.hln(9, 4, 3, "water_l")
t.hln(5, 11, 3, "water_l"); t.hln(12, 11, 2, "water_l")
t.pn(7, 7, "water_d"); t.pn(13, 2, "water_d"); t.pn(3, 13, "water_d")
end
tiles[9] = function(t) -- lake water B
t.rectn(0, 0, 16, 16, "water_d")
t.hln(3, 5, 3, "water"); t.hln(10, 5, 3, "water")
t.hln(6, 12, 3, "water"); t.hln(12, 12, 2, "water")
t.pn(8, 8, "water_dd"); t.pn(2, 3, "water_dd"); t.pn(13, 13, "water_dd")
end
-- water banks (shore toward the named direction)
local function bankH(t, shoreTop)
t.rectn(0, 0, 16, 16, "water")
local by = { 6, 6, 7, 7, 6, 6, 5, 6, 6, 7, 7, 6, 6, 5, 6, 6 }
for x = 0, 15 do
local b = by[x + 1]
if shoreTop then
t.rectn(x, 0, 1, b, "stone_l")
t.pn(x, b, "cream_d")
t.pn(x, b + 1, "water_l")
else
t.rectn(x, 16 - b, 1, b, "stone_l")
t.pn(x, 15 - b, "cream_d")
t.pn(x, 14 - b, "water_l")
end
end
end
local function bankV(t, shoreLeft)
t.rectn(0, 0, 16, 16, "water")
local bx = { 6, 6, 7, 7, 6, 6, 5, 6, 6, 7, 7, 6, 6, 5, 6, 6 }
for y = 0, 15 do
local b = bx[y + 1]
if shoreLeft then
t.rectn(0, y, b, 1, "stone_l")
t.pn(b, y, "cream_d")
t.pn(b + 1, y, "water_l")
else
t.rectn(16 - b, y, b, 1, "stone_l")
t.pn(15 - b, y, "cream_d")
t.pn(14 - b, y, "water_l")
end
end
end
tiles[10] = function(t) bankH(t, true) end -- 水岸北 (shore north/top)
tiles[11] = function(t) bankH(t, false) end -- 水岸南
tiles[12] = function(t) bankV(t, true) end -- 水岸西
tiles[13] = function(t) bankV(t, false) end -- 水岸东
local function flowerbed(t, c1, c2)
t.rectn(0, 0, 16, 16, "dirt_d")
t.rectn(0, 0, 16, 16, "dirt")
t.framen(0, 0, 16, 16, "dirt_d")
t.pn(3, 6, "leaf"); t.pn(10, 7, "leaf"); t.pn(7, 11, "leaf"); t.pn(13, 5, "leaf"); t.pn(5, 12, "leaf")
H.flower(t, 4, 5, c1, "yellow")
H.flower(t, 10, 4, c1, "yellow")
H.flower(t, 7, 10, c2, "yellow")
H.flower(t, 13, 9, c1, "yellow")
H.flower(t, 3, 12, c2, "yellow")
end
tiles[14] = function(t) flowerbed(t, "pink", "pink_l") end
tiles[15] = function(t) flowerbed(t, "yellow", "yellow_l") end
-- ===========================================================================
-- ROW 1 (ids 16-31) : bushes / tree / fence / lamp / bunting
-- ===========================================================================
local function bush(t, berries)
t.ellipsen(8, 14, 6, 2, "grass_dd")
t.discn(8, 8, 6, "leaf")
t.discn(6, 6, 3, "leaf_l")
t.discn(10, 10, 3, "leaf_d")
t.discn(8, 11, 3, "leaf_d")
if berries then
t.pn(6, 7, "berry"); t.pn(9, 5, "berry"); t.pn(11, 9, "berry")
t.pn(7, 10, "berry"); t.pn(10, 11, "berry"); t.pn(5, 9, "berry"); t.pn(9, 8, "berry_d")
end
end
tiles[16] = function(t) bush(t, true) end
tiles[17] = function(t) bush(t, false) end
-- tree (18-21) drawn once across its 2x2 block (origin of tile 18)
local function drawTree(img)
local tr = H.at(img, (18 % 16) * 16, math.floor(18 / 16) * 16)
tr.ellipsen(16, 31, 8, 1, "grass_dd")
tr.rectn(14, 21, 4, 11, "brown")
tr.vln(14, 21, 11, "brown_l"); tr.vln(17, 21, 11, "brown_d")
tr.discn(16, 12, 13, "leaf")
tr.discn(16, 16, 6, "leaf_d")
tr.discn(21, 15, 5, "leaf_d")
tr.discn(12, 8, 6, "leaf_l")
tr.discn(9, 13, 3, "leaf")
tr.discn(23, 11, 3, "leaf")
end
tiles[22] = function(t) -- round bush
t.ellipsen(8, 14, 5, 2, "grass_dd")
t.discn(8, 9, 5, "leaf")
t.discn(6, 7, 2, "leaf_l")
t.discn(10, 11, 2, "leaf_d")
end
tiles[23] = function(t) -- tree stump
t.ellipsen(8, 14, 6, 2, "brown_d")
t.rectn(4, 7, 8, 7, "brown")
t.vln(4, 7, 7, "brown_d"); t.vln(11, 7, 7, "brown_dd")
t.ellipsen(8, 7, 4, 2, "wood_l")
t.ellipsen(8, 7, 2, 1, "wood_d")
t.pn(8, 7, "brown_dd")
end
tiles[24] = function(t) -- rock
t.ellipsen(8, 13, 7, 2, "grey_d")
t.ellipsen(8, 9, 6, 4, "grey")
t.ellipsen(6, 8, 3, 2, "grey_l")
t.ellipsen(10, 11, 3, 2, "grey_d")
end
tiles[25] = function(t) -- signpost
t.rectn(7, 9, 2, 7, "brown_d")
t.rectn(3, 3, 10, 6, "wood")
t.framen(3, 3, 10, 6, "brown_d")
t.hln(4, 5, 8, "brown_d"); t.hln(4, 7, 6, "brown_d")
t.pn(12, 4, "brown_dd")
end
tiles[26] = function(t) -- fence horizontal
t.rectn(1, 4, 3, 11, "brown"); t.rectn(12, 4, 3, 11, "brown")
t.pn(1, 4, "brown_l"); t.pn(12, 4, "brown_l")
t.hln(0, 7, 16, "wood"); t.hln(0, 8, 16, "wood_d")
t.hln(0, 11, 16, "wood"); t.hln(0, 12, 16, "wood_d")
t.vln(1, 4, 11, "brown_d"); t.vln(12, 4, 11, "brown_d")
end
tiles[27] = function(t) -- fence vertical
t.rectn(4, 0, 3, 16, "wood"); t.rectn(9, 0, 3, 16, "wood")
t.vln(4, 0, 16, "wood_d"); t.vln(9, 0, 16, "wood_d")
t.rectn(2, 6, 12, 3, "brown")
t.hln(2, 6, 12, "brown_l"); t.hln(2, 8, 12, "brown_d")
end
tiles[28] = function(t) -- street lamp
t.rectn(7, 6, 2, 10, "grey_d")
t.rectn(6, 15, 4, 1, "grey")
t.rectn(5, 3, 6, 4, "metal")
t.framen(5, 3, 6, 4, "grey_d")
t.rectn(6, 4, 4, 2, "yellow_l")
t.pn(7, 2, "yellow"); t.pn(8, 2, "yellow")
t.pn(6, 8, "grey")
end
local function bunting(t, c)
t.hln(0, 3, 16, "brown_d")
t.hln(4, 4, 8, c)
t.hln(5, 5, 6, c)
t.hln(6, 6, 4, c)
t.hln(7, 7, 2, c)
t.pn(8, 8, c)
end
tiles[29] = function(t) bunting(t, "red") end
tiles[30] = function(t) bunting(t, "yellow") end
tiles[31] = function(t) bunting(t, "blue") end
-- ===========================================================================
-- ROW 2 (ids 32-47) : buildings / well / mailbox / noticeboard
-- ===========================================================================
local function creamWall(t)
t.rectn(0, 0, 16, 16, "cream")
t.hln(0, 0, 16, "cream_d"); t.hln(0, 8, 16, "cream_d")
t.vln(0, 0, 8, "cream_d"); t.vln(8, 0, 8, "cream_d")
t.vln(4, 8, 8, "cream_d"); t.vln(12, 8, 8, "cream_d")
t.pn(2, 4, "cream_dd"); t.pn(10, 12, "cream_dd")
end
tiles[32] = function(t) creamWall(t) end
tiles[33] = function(t)
creamWall(t)
t.rectn(4, 3, 8, 9, "cream") -- clear brick under window
H.window(t, 4, 3, 8, 9, "sky")
end
tiles[34] = function(t) -- wood plank wall
t.rectn(0, 0, 16, 16, "wood")
for y = 0, 15, 4 do
t.hln(0, y, 16, "wood_d"); t.hln(0, y + 1, 16, "wood_l")
end
t.pn(2, 3, "wood_dd"); t.pn(13, 3, "wood_dd"); t.pn(2, 7, "wood_dd")
t.pn(13, 7, "wood_dd"); t.pn(2, 11, "wood_dd"); t.pn(13, 11, "wood_dd"); t.pn(2, 15, "wood_dd")
end
tiles[35] = function(t) roof(t, "honey", "honey_d", "honey_l", "L") end
tiles[36] = function(t) roof(t, "honey", "honey_d", "honey_l", nil) end
tiles[37] = function(t) roof(t, "honey", "honey_d", "honey_l", "R") end
tiles[38] = function(t) -- door (lower)(两侧补墙色:室内门放在 ground 层,透明边会露黑底)
t.rectn(0, 0, 3, 16, "cream"); t.rectn(13, 0, 3, 16, "cream")
t.vln(3, 0, 16, "brown_d"); t.vln(12, 0, 16, "brown_d")
t.rectn(4, 0, 8, 16, "wood")
t.rectn(5, 2, 6, 5, "wood_d"); t.rectn(5, 9, 6, 5, "wood_d")
t.vln(5, 0, 16, "wood_l")
t.pn(10, 7, "yellow"); t.pn(10, 8, "yellow_d")
t.hln(4, 15, 8, "wood_d")
end
tiles[39] = function(t) -- door frame top (arch), sits above tile 38
t.vln(3, 4, 12, "brown_d"); t.vln(12, 4, 12, "brown_d")
t.rectn(4, 6, 8, 10, "wood")
t.vln(5, 6, 10, "wood_l")
-- arch
t.discn(8, 6, 5, "brown_d")
t.discn(8, 6, 4, "sky")
t.rectn(4, 6, 8, 3, "sky")
t.discn(8, 6, 3, "sky")
t.pn(6, 5, "sky_d"); t.pn(9, 4, "sky_d")
t.hln(4, 6, 8, "brown_d")
end
tiles[40] = function(t) -- standalone window (transparent surround)
H.window(t, 3, 4, 10, 8, "sky")
t.pn(4, 5, "white")
end
tiles[41] = function(t) -- chimney
t.rectn(5, 3, 6, 13, "swall_d")
t.hln(5, 6, 6, "swall_dd"); t.hln(5, 9, 6, "swall_dd"); t.hln(5, 12, 6, "swall_dd")
t.vln(7, 3, 3, "swall_dd"); t.vln(6, 6, 3, "swall_dd"); t.vln(8, 9, 3, "swall_dd")
t.rectn(4, 2, 8, 2, "swall")
t.hln(4, 2, 8, "swall_l")
t.discn(6, 1, 1, "w_mid"); t.discn(9, 0, 1, "w_lo")
end
-- well (42-45) drawn once across its 2x2 block (origin of tile 42)
local function drawWell(img)
local w = H.at(img, (42 % 16) * 16, math.floor(42 / 16) * 16)
w.ellipsen(16, 28, 12, 3, "swall_dd")
w.discn(16, 16, 12, "swall")
w.discn(16, 14, 11, "swall_l")
w.discn(16, 19, 10, "swall_d")
w.discn(16, 15, 7, "swall_dd")
w.discn(16, 16, 6, "black")
w.discn(16, 17, 4, "water_d")
w.rectn(3, 9, 26, 2, "wood_d")
w.hln(3, 9, 26, "wood")
w.vln(16, 11, 7, "brown_dd")
w.rectn(14, 17, 5, 4, "wood")
w.framen(14, 17, 5, 4, "wood_d")
end
tiles[46] = function(t) -- mailbox
t.rectn(6, 9, 2, 7, "brown_d")
t.rectn(2, 15, 6, 1, "brown_dd")
t.rectn(3, 3, 10, 6, "red")
t.framen(3, 3, 10, 6, "red_d")
t.rectn(3, 3, 10, 2, "red_l")
t.pn(7, 6, "yellow"); t.pn(8, 6, "yellow")
t.rectn(5, 8, 6, 1, "red_d")
end
tiles[47] = function(t) -- notice board
t.rectn(3, 12, 2, 4, "brown_d"); t.rectn(11, 12, 2, 4, "brown_d")
t.rectn(1, 1, 14, 2, "brown_d")
t.rectn(2, 2, 12, 10, "wood")
t.framen(2, 2, 12, 10, "brown_d")
t.rectn(4, 4, 3, 4, "cream"); t.rectn(8, 4, 4, 3, "cream")
t.rectn(4, 8, 6, 3, "cream_d")
t.pn(5, 5, "ink"); t.pn(6, 5, "ink"); t.pn(9, 5, "ink"); t.pn(10, 5, "ink"); t.pn(5, 9, "ink"); t.pn(7, 9, "ink")
end
-- ===========================================================================
-- ROW 3 (ids 48-63) : interior floor / walls / furniture
-- ===========================================================================
tiles[48] = function(t) -- wood floor A (horizontal planks)
t.rectn(0, 0, 16, 16, "wood_l")
for y = 0, 15, 4 do t.hln(0, y, 16, "wood") end
t.pn(3, 2, "wood"); t.pn(10, 6, "wood"); t.pn(6, 10, "wood"); t.pn(13, 14, "wood")
end
tiles[49] = function(t) -- wood floor B (vertical planks)
t.rectn(0, 0, 16, 16, "wood_l")
for x = 0, 15, 4 do t.vln(x, 0, 16, "wood") end
t.pn(2, 3, "wood"); t.pn(6, 9, "wood"); t.pn(10, 5, "wood"); t.pn(14, 12, "wood")
end
local function indoorWall(t)
t.rectn(0, 0, 16, 16, "cream")
t.hln(0, 12, 16, "cream_d")
t.rectn(0, 13, 16, 3, "wood_d")
t.hln(0, 13, 16, "wood_l")
end
tiles[50] = function(t) indoorWall(t) end
tiles[51] = function(t)
t.rectn(0, 0, 16, 16, "cream")
H.window(t, 4, 2, 8, 8, "sky")
t.hln(0, 12, 16, "cream_d")
t.rectn(0, 13, 16, 3, "wood_d")
t.hln(0, 13, 16, "wood_l")
end
-- bed (52-55) drawn once across 2x2 (origin of tile 52)
local function drawBed(img)
local b = H.at(img, (52 % 16) * 16, math.floor(52 / 16) * 16)
b.rectn(1, 2, 30, 29, "wood_d")
b.framen(1, 2, 30, 29, "brown_dd")
b.rectn(1, 2, 30, 5, "wood")
b.framen(1, 2, 30, 5, "wood_d")
b.rectn(3, 7, 26, 22, "cream")
b.rectn(4, 8, 24, 6, "white"); b.framen(4, 8, 24, 6, "cream_d")
b.rectn(3, 16, 26, 13, "blue")
b.framen(3, 16, 26, 13, "blue_d")
b.rectn(3, 16, 26, 2, "blue_l")
b.rectn(1, 28, 30, 3, "wood")
end
local function counter(t)
t.rectn(0, 0, 16, 3, "cream")
t.hln(0, 2, 16, "cream_d")
t.rectn(0, 3, 16, 13, "wood")
t.vln(0, 3, 13, "wood_d"); t.vln(8, 3, 13, "wood_d")
t.rectn(2, 8, 12, 5, "wood_d"); t.framen(2, 8, 12, 5, "wood_dd")
t.hln(0, 3, 16, "wood_l")
end
tiles[56] = function(t) counter(t) end
tiles[57] = function(t)
counter(t)
t.rectn(9, 0, 5, 2, "honey") -- a little bread/register on the right half
t.pn(10, 0, "honey_d"); t.pn(12, 0, "honey_d")
end
tiles[58] = function(t) -- oven
t.rectn(1, 2, 14, 14, "swall_d")
t.framen(1, 2, 14, 14, "swall_dd")
t.hln(1, 5, 14, "swall_dd"); t.hln(1, 13, 14, "swall_dd")
t.discn(8, 9, 5, "swall_dd")
t.rectn(3, 9, 10, 6, "black"); t.discn(8, 9, 5, "black")
t.discn(8, 11, 3, "flame_d"); t.discn(8, 11, 2, "flame")
t.rectn(1, 2, 14, 2, "swall")
end
local function shelf(t, full)
t.rectn(1, 2, 14, 14, "wood")
t.framen(1, 2, 14, 14, "brown_d")
t.rectn(2, 3, 12, 12, "wood_d")
t.hln(2, 7, 12, "brown_d"); t.hln(2, 11, 12, "brown_d")
if full then
t.rectn(3, 4, 2, 3, "honey"); t.rectn(6, 4, 2, 3, "pink"); t.rectn(9, 4, 3, 3, "sky")
t.rectn(3, 8, 3, 3, "red"); t.rectn(7, 8, 2, 3, "yellow"); t.rectn(10, 8, 3, 3, "leaf")
t.rectn(4, 12, 2, 3, "brown_l"); t.rectn(8, 12, 4, 3, "honey_d")
end
end
tiles[59] = function(t) shelf(t, false) end
tiles[60] = function(t) shelf(t, true) end
tiles[61] = function(t) -- table
t.rectn(1, 4, 14, 4, "wood")
t.hln(1, 4, 14, "wood_l"); t.hln(1, 7, 14, "wood_d")
t.rectn(2, 8, 2, 7, "wood_d"); t.rectn(12, 8, 2, 7, "wood_d")
t.hln(2, 12, 12, "wood_d")
end
tiles[62] = function(t) -- chair
t.rectn(4, 2, 8, 2, "wood"); t.hln(4, 2, 8, "wood_l")
t.rectn(4, 2, 2, 8, "wood_d")
t.rectn(4, 7, 8, 3, "wood"); t.hln(4, 9, 8, "wood_d")
t.rectn(4, 10, 2, 5, "wood_d"); t.rectn(10, 10, 2, 5, "wood_d")
end
tiles[63] = function(t) -- rug(烘焙木地板底:放在 ground 层,透明边会露黑底)
t.rectn(0, 0, 16, 16, "wood_l")
for y = 0, 15, 4 do t.hln(0, y, 16, "wood") end
t.rectn(1, 3, 14, 10, "pink")
t.framen(1, 3, 14, 10, "pink_d")
t.framen(3, 5, 10, 6, "cream")
t.discn(8, 8, 2, "honey"); t.pn(8, 8, "honey_d")
end
-- ===========================================================================
-- ROW 4 (ids 64-79) : papers / picnic / bench / appliances
-- ===========================================================================
tiles[64] = function(t) -- calendar
t.rectn(4, 2, 8, 11, "white"); t.framen(4, 2, 8, 11, "grey_d")
t.rectn(4, 2, 8, 2, "red"); t.pn(6, 3, "white"); t.pn(7, 3, "white")
t.hln(5, 6, 6, "grey"); t.hln(5, 8, 6, "grey"); t.hln(5, 10, 6, "grey")
t.vln(7, 5, 6, "grey"); t.vln(9, 5, 6, "grey")
t.pn(6, 9, "red"); t.pn(6, 10, "red")
end
tiles[65] = function(t) -- recipe paper
t.rectn(4, 3, 8, 10, "cream"); t.framen(4, 3, 8, 10, "cream_d")
t.hln(5, 5, 6, "brown_d"); t.hln(5, 7, 6, "brown_d"); t.hln(5, 9, 4, "brown_d"); t.hln(5, 11, 5, "brown_d")
t.pn(10, 11, "honey"); t.pn(11, 10, "honey_d")
end
tiles[66] = function(t) -- document paper
t.rectn(4, 2, 8, 12, "white"); t.framen(4, 2, 8, 12, "grey")
for y = 4, 9, 2 do t.hln(5, y, 6, "grey_d") end
t.discn(9, 11, 2, "red"); t.pn(9, 11, "white")
end
-- picnic mat (67-70) drawn once across 2x2 (origin of tile 67)
local function drawPicnic(img)
local m = H.at(img, (67 % 16) * 16, math.floor(67 / 16) * 16)
for y = 0, 31, 4 do
for x = 0, 31, 4 do
local c = (((x / 4) + (y / 4)) % 2 == 0) and "red" or "white"
m.rectn(x, y, 4, 4, c)
end
end
m.framen(0, 0, 32, 32, "red_d")
m.framen(1, 1, 30, 30, "red_l")
end
local function bench(t)
t.rectn(0, 2, 16, 2, "wood"); t.hln(0, 2, 16, "wood_l")
t.rectn(0, 5, 16, 2, "wood")
t.rectn(0, 9, 16, 3, "wood_l"); t.hln(0, 11, 16, "wood_d")
t.rectn(1, 12, 2, 4, "wood_d"); t.rectn(13, 12, 2, 4, "wood_d")
t.vln(1, 2, 3, "wood_d"); t.vln(14, 2, 3, "wood_d")
end
tiles[71] = function(t) bench(t) end
tiles[72] = function(t) bench(t) end
tiles[73] = function(t) -- stool
t.rectn(4, 6, 8, 3, "wood"); t.hln(4, 6, 8, "wood_l"); t.hln(4, 8, 8, "wood_d")
t.rectn(5, 9, 2, 6, "wood_d"); t.rectn(9, 9, 2, 6, "wood_d")
t.hln(5, 12, 6, "wood_d")
end
tiles[74] = function(t) -- cabinet
t.rectn(2, 2, 12, 14, "wood"); t.framen(2, 2, 12, 14, "brown_d")
t.vln(8, 3, 12, "brown_d")
t.rectn(3, 4, 4, 5, "wood_d"); t.rectn(9, 4, 4, 5, "wood_d")
t.pn(7, 10, "yellow"); t.pn(9, 10, "yellow")
t.hln(2, 2, 12, "wood_l")
end
tiles[75] = function(t) -- fridge
t.rectn(3, 1, 10, 15, "white"); t.framen(3, 1, 10, 15, "grey")
t.hln(3, 6, 10, "grey")
t.rectn(11, 2, 1, 4, "grey_d"); t.rectn(11, 7, 1, 8, "grey_d")
t.hln(4, 2, 8, "grey_l")
end
tiles[76] = function(t) -- sink
t.rectn(1, 6, 14, 10, "metal"); t.framen(1, 6, 14, 10, "metal_d")
t.rectn(3, 8, 10, 5, "grey_d")
t.rectn(4, 9, 8, 3, "water_l"); t.hln(4, 9, 8, "water")
t.rectn(7, 3, 2, 4, "metal_d"); t.pn(7, 3, "metal"); t.pn(6, 3, "metal")
t.hln(2, 7, 12, "grey_l")
end
tiles[77] = function(t) -- potted plant
t.discn(8, 6, 4, "leaf"); t.discn(7, 5, 2, "leaf_l"); t.discn(9, 7, 2, "leaf_d"); t.pn(8, 3, "leaf")
t.rectn(5, 10, 6, 6, "brown"); t.framen(5, 10, 6, 6, "brown_d"); t.hln(5, 10, 6, "brown_l")
end
tiles[78] = function(t) -- barrel
t.ellipsen(8, 8, 6, 7, "wood")
t.rectn(2, 1, 12, 14, "wood"); t.ellipsen(8, 8, 6, 7, "wood")
t.hln(3, 4, 10, "wood_d"); t.hln(3, 11, 10, "wood_d")
t.vln(8, 2, 12, "wood_d")
t.framen(2, 1, 12, 14, "wood_d")
t.hln(4, 2, 8, "wood_l")
end
tiles[79] = function(t) -- crate
t.rectn(2, 3, 12, 11, "wood"); t.framen(2, 3, 12, 11, "wood_d")
t.vln(8, 3, 11, "wood_d"); t.hln(2, 8, 12, "wood_d")
t.pn(3, 4, "wood_dd"); t.pn(12, 4, "wood_dd"); t.pn(3, 12, "wood_dd"); t.pn(12, 12, "wood_dd")
t.hln(3, 4, 10, "wood_l")
end
-- ===========================================================================
-- ROW 5 (ids 80-95) : fog / white-layer
-- ===========================================================================
local function fog(t, seed)
local a1, a2 = 150, 110
if seed == 0 then
t.ellipse(8, 8, 7, 3, H.col("w_hi", a1))
t.ellipse(5, 6, 4, 2, H.col("w_mid", a2))
t.ellipse(11, 10, 4, 2, H.col("w_mid", a2))
elseif seed == 1 then
t.ellipse(7, 9, 6, 3, H.col("w_hi", a1))
t.ellipse(11, 7, 4, 2, H.col("w_mid", a2))
t.ellipse(4, 11, 3, 2, H.col("w_mid", a2))
else
t.ellipse(9, 7, 7, 3, H.col("w_hi", a1))
t.ellipse(5, 9, 4, 2, H.col("w_mid", a2))
t.ellipse(12, 11, 3, 2, H.col("w_mid", a2))
end
end
tiles[80] = function(t) fog(t, 0) end
tiles[81] = function(t) fog(t, 1) end
tiles[82] = function(t) fog(t, 2) end
tiles[83] = function(t) -- white floor
t.rectn(0, 0, 16, 16, "w_hi")
t.hln(0, 0, 16, "w_mid"); t.hln(0, 8, 16, "w_mid")
t.vln(0, 0, 16, "w_mid"); t.vln(8, 0, 16, "w_mid")
t.pn(4, 4, "w_lo"); t.pn(12, 12, "w_lo"); t.pn(12, 4, "w_lo"); t.pn(4, 12, "w_lo")
end
tiles[84] = function(t) -- white wall
t.rectn(0, 0, 16, 16, "w_hi")
t.hln(0, 0, 16, "w_lo"); t.hln(0, 8, 16, "w_lo")
t.vln(0, 0, 16, "w_lo"); t.vln(8, 0, 16, "w_lo")
t.rectn(0, 14, 16, 2, "w_mid"); t.hln(0, 14, 16, "w_hi")
end
tiles[85] = function(t) -- white wall panel
t.rectn(0, 0, 16, 16, "w_hi")
t.framen(2, 2, 12, 11, "w_lo")
t.vln(8, 2, 11, "w_mid")
t.rectn(0, 14, 16, 2, "w_mid")
end
tiles[86] = function(t) -- white door
t.rectn(0, 0, 16, 16, "w_hi")
t.rectn(3, 1, 10, 15, "w_mid"); t.framen(3, 1, 10, 15, "w_lo")
t.rectn(4, 2, 8, 6, "w_hi"); t.framen(4, 2, 8, 6, "w_lo")
t.rectn(4, 9, 8, 6, "w_hi"); t.framen(4, 9, 8, 6, "w_lo")
t.pn(11, 8, "w_dk"); t.pn(11, 9, "w_dk")
end
-- white hospital bed (87-90) across 2x2 (origin of tile 87)
local function drawWhiteBed(img)
local b = H.at(img, (87 % 16) * 16, math.floor(87 / 16) * 16)
b.rectn(1, 2, 30, 27, "metal_d")
b.rectn(3, 4, 26, 23, "white"); b.framen(3, 4, 26, 23, "w_lo")
b.rectn(4, 6, 24, 6, "w_hi"); b.framen(4, 6, 24, 6, "w_mid")
b.rectn(3, 17, 26, 2, "w_mid")
b.rectn(1, 2, 30, 3, "metal"); b.rectn(1, 26, 30, 3, "metal")
b.rectn(1, 2, 2, 27, "metal"); b.rectn(29, 2, 2, 27, "metal")
b.rectn(2, 29, 3, 2, "w_dk"); b.rectn(27, 29, 3, 2, "w_dk")
end
tiles[91] = function(t) -- white cabinet
t.rectn(2, 2, 12, 14, "w_mid"); t.framen(2, 2, 12, 14, "w_lo")
t.vln(8, 3, 12, "w_lo")
t.rectn(3, 4, 4, 4, "w_hi"); t.rectn(9, 4, 4, 4, "w_hi")
t.pn(7, 10, "w_dk"); t.pn(9, 10, "w_dk")
t.hln(2, 2, 12, "w_hi")
end
tiles[92] = function(t) -- white monitor (medical)
t.rectn(3, 3, 10, 7, "w_lo"); t.framen(3, 3, 10, 7, "w_dk")
t.rectn(4, 4, 8, 5, "screen")
t.pn(4, 6, "screen_l"); t.pn(5, 6, "screen_l"); t.pn(6, 5, "screen_l")
t.pn(7, 7, "screen_l"); t.pn(8, 6, "screen_l"); t.pn(9, 6, "screen_l"); t.pn(10, 6, "screen_l")
t.rectn(7, 10, 2, 3, "w_dk"); t.rectn(5, 13, 6, 2, "w_lo"); t.hln(5, 14, 6, "w_dk")
end
tiles[93] = function(t) -- white curtain
t.rectn(2, 1, 12, 14, "w_hi")
t.vln(4, 1, 14, "w_mid"); t.vln(7, 1, 14, "w_mid"); t.vln(10, 1, 14, "w_mid"); t.vln(12, 1, 14, "w_lo")
t.rectn(2, 1, 12, 1, "w_lo")
t.hln(2, 14, 12, "w_mid")
end
tiles[94] = function(t) -- white floor alt
t.rectn(0, 0, 16, 16, "w_hi")
for y = 0, 15, 4 do
for x = 0, 15, 4 do
t.pn((x + 2) % 16, (y + 2) % 16, "w_lo")
end
end
t.pn(2, 2, "w_mid"); t.pn(10, 10, "w_mid")
end
tiles[95] = function(t) -- white ceiling light
t.rectn(2, 6, 12, 4, "white"); t.framen(2, 6, 12, 4, "w_lo")
t.rectn(3, 7, 10, 2, "w_hi")
t.pn(7, 8, "white")
end
-- ===========================================================================
-- ROW 6 (ids 96-111) : ladder / bridge / props
-- ===========================================================================
tiles[96] = function(t) -- ladder
t.vln(4, 0, 16, "wood_d"); t.vln(11, 0, 16, "wood_d")
for y = 2, 14, 3 do t.hln(4, y, 8, "wood"); t.hln(4, y, 8, "wood_l") end
end
tiles[97] = function(t) -- bridge horizontal
for y = 3, 12, 3 do
t.rectn(0, y, 16, 2, "wood"); t.hln(0, y, 16, "wood_l"); t.hln(0, y + 1, 16, "wood_d")
end
t.rectn(0, 1, 16, 1, "wood_d"); t.rectn(0, 14, 16, 1, "wood_d")
t.vln(0, 1, 14, "wood_d"); t.vln(15, 1, 14, "wood_d")
end
tiles[98] = function(t) -- bridge vertical
for x = 3, 12, 3 do
t.rectn(x, 0, 2, 16, "wood"); t.vln(x, 0, 16, "wood_l"); t.vln(x + 1, 0, 16, "wood_d")
end
t.rectn(1, 0, 1, 16, "wood_d"); t.rectn(14, 0, 1, 16, "wood_d")
t.hln(1, 0, 14, "wood_d"); t.hln(1, 15, 14, "wood_d")
end
tiles[99] = function(t) -- mushroom(烘焙草地底:放在 ground 层,透明区会露黑底)
grassBase(t)
t.rectn(7, 8, 2, 6, "cream"); t.vln(7, 8, 6, "cream_d")
t.discn(8, 6, 5, "red"); t.rectn(3, 6, 10, 2, "red")
t.discn(8, 5, 4, "red_l")
t.pn(6, 5, "white"); t.pn(9, 4, "white"); t.pn(10, 7, "white"); t.pn(5, 7, "white")
end
local function bigflower(t, c)
grassBase(t) -- 烘焙草地底:该瓦片放在 ground 层,透明区会露出黑底
t.vln(8, 9, 6, "leaf"); t.pn(6, 12, "leaf"); t.pn(10, 11, "leaf"); t.pn(7, 13, "leaf_d")
t.discn(8, 6, 3, c)
t.discn(8, 6, 1, "yellow")
t.pn(8, 6, "honey_d")
end
tiles[100] = function(t) bigflower(t, "red") end
tiles[101] = function(t) bigflower(t, "yellow") end
tiles[102] = function(t) bigflower(t, "blue") end
tiles[103] = function(t) -- honey jar
t.rectn(5, 4, 6, 10, "honey"); t.framen(5, 4, 6, 10, "honey_d")
t.rectn(5, 4, 6, 2, "honey_l")
t.rectn(4, 2, 8, 2, "brown_d"); t.hln(4, 2, 8, "brown")
t.rectn(6, 8, 4, 4, "honey_l"); t.pn(8, 10, "honey_dd")
end
tiles[104] = function(t) -- bread
t.ellipsen(8, 10, 7, 4, "honey")
t.ellipsen(8, 9, 6, 3, "honey_l")
t.pn(5, 9, "honey_d"); t.pn(8, 8, "honey_d"); t.pn(11, 9, "honey_d")
t.hln(3, 12, 10, "honey_d")
end
tiles[105] = function(t) -- letter
t.rectn(3, 5, 10, 7, "cream"); t.framen(3, 5, 10, 7, "cream_d")
for i = 0, 4 do t.pn(4 + i, 5 + i, "cream_d"); t.pn(11 - i, 5 + i, "cream_d") end
t.pn(8, 9, "red")
end
tiles[106] = function(t) -- book
t.rectn(3, 4, 10, 9, "red"); t.framen(3, 4, 10, 9, "red_d")
t.vln(8, 4, 9, "red_d"); t.hln(3, 4, 10, "red_l")
t.rectn(4, 6, 3, 5, "red_d"); t.pn(5, 8, "yellow")
end
tiles[107] = function(t) -- candle
t.rectn(6, 6, 4, 9, "cream"); t.framen(6, 6, 4, 9, "cream_d")
t.rectn(6, 6, 4, 1, "cream_d")
t.pn(8, 5, "brown_d")
t.discn(8, 3, 2, "flame"); t.pn(8, 2, "flame_d"); t.pn(8, 4, "flame_d")
end
tiles[108] = function(t) -- basket
t.rectn(3, 7, 10, 7, "wood"); t.framen(3, 7, 10, 7, "wood_d")
t.hln(3, 9, 10, "wood_d"); t.hln(3, 11, 10, "wood_d")
t.vln(6, 7, 7, "wood_d"); t.vln(9, 7, 7, "wood_d")
t.vln(3, 4, 4, "wood_d"); t.vln(12, 4, 4, "wood_d"); t.hln(3, 4, 10, "wood_d")
t.rectn(4, 5, 8, 2, "wood")
end
tiles[109] = function(t) -- bucket
t.rectn(4, 6, 8, 9, "metal"); t.framen(4, 6, 8, 9, "metal_d")
t.rectn(4, 6, 8, 2, "water_l"); t.hln(4, 6, 8, "water")
t.vln(4, 4, 3, "metal_d"); t.vln(11, 4, 3, "metal_d"); t.hln(4, 4, 8, "metal_d")
t.hln(5, 10, 6, "metal_d")
end
tiles[110] = function(t) -- broom
t.vln(10, 1, 8, "wood_d"); t.vln(9, 1, 8, "wood")
t.rectn(4, 9, 7, 6, "yellow_d"); t.framen(4, 9, 7, 6, "honey_d")
t.hln(4, 9, 7, "brown_d")
t.pn(3, 14, "yellow_d"); t.pn(11, 14, "yellow_d"); t.pn(4, 15, "honey_d"); t.pn(10, 15, "honey_d")
end
tiles[111] = function(t) -- cake
t.rectn(3, 8, 10, 6, "pink"); t.framen(3, 8, 10, 6, "pink_d")
t.rectn(3, 8, 10, 2, "white")
t.pn(4, 10, "pink_d"); t.pn(7, 10, "pink_d"); t.pn(10, 10, "pink_d")
t.rectn(3, 14, 10, 1, "cream_d")
t.vln(6, 5, 3, "red"); t.vln(9, 5, 3, "blue")
t.pn(6, 4, "flame"); t.pn(9, 4, "flame")
end
-- ===========================================================================
-- ROW 7 (ids 112-127) : colored roofs / walls / misc
-- ===========================================================================
tiles[112] = function(t) roof(t, "red", "red_d", "red_l", "L") end
tiles[113] = function(t) roof(t, "red", "red_d", "red_l", nil) end
tiles[114] = function(t) roof(t, "red", "red_d", "red_l", "R") end
tiles[115] = function(t) roof(t, "blue", "blue_d", "blue_l", "L") end
tiles[116] = function(t) roof(t, "blue", "blue_d", "blue_l", nil) end
tiles[117] = function(t) roof(t, "blue", "blue_d", "blue_l", "R") end
local function pinkWall(t)
t.rectn(0, 0, 16, 16, "pink")
t.hln(0, 0, 16, "pink_d"); t.hln(0, 8, 16, "pink_d")
t.vln(0, 0, 8, "pink_d"); t.vln(8, 0, 8, "pink_d")
t.vln(4, 8, 8, "pink_d"); t.vln(12, 8, 8, "pink_d")
t.pn(2, 4, "pink_l"); t.pn(10, 12, "pink_l")
end
tiles[118] = function(t) pinkWall(t) end
tiles[119] = function(t)
pinkWall(t)
t.rectn(4, 3, 8, 9, "pink")
H.window(t, 4, 3, 8, 9, "sky")
end
local function stoneWall(t)
t.rectn(0, 0, 16, 16, "swall")
t.hln(0, 0, 16, "swall_d"); t.hln(0, 5, 16, "swall_d"); t.hln(0, 10, 16, "swall_d")
t.vln(0, 0, 5, "swall_d"); t.vln(8, 0, 5, "swall_d")
t.vln(4, 5, 5, "swall_d"); t.vln(12, 5, 5, "swall_d")
t.vln(0, 10, 6, "swall_d"); t.vln(8, 10, 6, "swall_d")
t.pn(3, 2, "swall_l"); t.pn(10, 7, "swall_l"); t.pn(6, 12, "swall_l")
end
tiles[120] = function(t) stoneWall(t) end
tiles[121] = function(t)
stoneWall(t)
t.rectn(4, 3, 8, 9, "swall")
H.window(t, 4, 3, 8, 9, "sky")
end
tiles[122] = function(t) -- awning
for x = 0, 15 do
local c = (math.floor(x / 2) % 2 == 0) and "red" or "white"
t.vln(x, 0, 6, c)
end
t.hln(0, 6, 16, "red_d")
for x = 0, 15 do if x % 4 < 2 then t.pn(x, 7, "red") else t.pn(x, 7, "red_d") end end
t.hln(0, 0, 16, "red_l")
end
tiles[123] = function(t) -- clock
t.discn(8, 8, 6, "brown_d"); t.discn(8, 8, 5, "cream")
t.pn(8, 3, "brown_d"); t.pn(8, 13, "brown_d"); t.pn(3, 8, "brown_d"); t.pn(13, 8, "brown_d")
t.vln(8, 4, 4, "ink"); t.hln(8, 8, 3, "ink"); t.pn(8, 8, "ink")
end
tiles[124] = function(t) -- flag
t.vln(3, 1, 15, "grey_d")
t.rectn(4, 2, 9, 6, "red"); t.rectn(4, 2, 9, 2, "red_l")
t.pn(13, 3, "red"); t.pn(13, 4, "red")
t.rectn(2, 15, 3, 1, "grey")
t.pn(4, 4, "yellow")
end
tiles[125] = function(t) -- garland corner
for x = 1, 12 do
t.pn(x, 2, "leaf"); t.pn(x, 3, "leaf_d")
if x % 3 == 0 then H.flower(t, x, 2, "pink", "yellow") end
end
for y = 1, 12 do
t.pn(2, y, "leaf"); t.pn(3, y, "leaf_d")
if y % 3 == 1 then H.flower(t, 2, y, "yellow", "honey") end
end
end
tiles[126] = function(t) -- garland mid (horizontal, tileable)
for x = 0, 15 do t.pn(x, 4, "leaf"); t.pn(x, 5, "leaf_d") end
H.flower(t, 3, 3, "pink", "yellow")
H.flower(t, 8, 4, "red", "yellow")
H.flower(t, 13, 3, "yellow", "honey")
end
-- tile 127 intentionally left transparent (empty)
-- ===========================================================================
-- render
-- ===========================================================================
-- 2x2 拼块的自然落点是 id、id+1、id+16、id+17,但 G 表/地图引用连续 4 个 id
-- (id..id+3)。故每画完一块,立即把下半两个象限复制到 id+2、id+3;
-- 自然落点 id+16/id+17 的残留随后被 tiles 循环里已定义的瓦片重绘覆盖。
local function copyBlock(img, tlId)
local ox = (tlId % 16) * 16
local oy = math.floor(tlId / 16) * 16
for dy = 0, 15 do
for dx = 0, 15 do
img:putPixel(ox + 32 + dx, oy + dy, img:getPixel(ox + dx, oy + 16 + dy)) -- 自然 BL → 槽位 id+2
img:putPixel(ox + 48 + dx, oy + dy, img:getPixel(ox + 16 + dx, oy + 16 + dy)) -- 自然 BR → 槽位 id+3
end
end
end
drawTree(img); copyBlock(img, 18)
drawWell(img); copyBlock(img, 42)
drawBed(img); copyBlock(img, 52) -- 须在 drawPicnic 之前复制:二者自然落点都覆盖 68/69
drawPicnic(img); copyBlock(img, 67)
drawWhiteBed(img); copyBlock(img, 87)
for id = 0, 127 do
if tiles[id] then tiles[id](H.tile(img, id)) end
end
spr:saveAs(ROOT .. "public/assets/tileset.png")
print("tileset.png done")