-- gen_npcs.lua — named NPC sprites (each 48x24: 3 frames = smile / flat / off)
-- plus npc_bird.png (32x24: 2 frames = beak closed / open)
local ROOT = "/Users/leidianyayi/Documents/GitHub/ModelTest20260714/Kimi-K3/"
local H = dofile(ROOT .. "tools/aseprite/helpers.lua")

-- ---- shared expression core ------------------------------------------------
-- eyes at (lx,ly)/(rx,ry); mouth baseline my. ex in {"smile","flat","off"}.
-- "off" = smile mouth but the right eye sits 1px lower (a 1-2px difference).
local function expr(t, ex, lx, ly, rx, ry, my, eyeCol, mouthCol)
  eyeCol = eyeCol or "ink"; mouthCol = mouthCol or "brown_d"
  if ex == "off" then ry = ry + 1 end
  t.pn(lx, ly, eyeCol); t.pn(rx, ry, eyeCol)
  if ex == "flat" then
    t.hln(lx + 1, my, rx - lx - 1, mouthCol)
  else
    t.pn(lx + 1, my, mouthCol); t.pn(lx + 2, my + 1, mouthCol)
    t.pn(rx - 2, my + 1, mouthCol); t.pn(rx - 1, my, mouthCol)
  end
end

local function arms(t, c) t.rectn(2, 12, 2, 5, c); t.rectn(12, 12, 2, 5, c) end
local function feet(t, c) t.rectn(5, 20, 2, 3, c); t.rectn(9, 20, 2, 3, c) end

-- ---- species bodies (face forward, 16x24 local) ---------------------------
local function afu(t, ex) -- 狗村长 dog village head
  t.rectn(1, 3, 3, 6, "brown_d"); t.rectn(12, 3, 3, 6, "brown_d")  -- floppy ears
  t.rectn(1, 3, 3, 2, "brown"); t.rectn(12, 3, 3, 2, "brown")
  t.rectn(3, 3, 10, 9, "brown"); t.rectn(3, 3, 10, 1, "brown_l")
  t.rectn(6, 8, 4, 4, "cream"); t.pn(7, 8, "ink")                  -- muzzle + nose
  t.rectn(4, 12, 8, 7, "brown"); t.rectn(4, 12, 8, 3, "honey")     -- vest
  t.pn(7, 13, "honey_d"); t.pn(8, 13, "honey_d")
  arms(t, "brown"); feet(t, "brown_d")
  expr(t, ex, 5, 6, 10, 6, 10)
end

local function yuanyuan(t, ex) -- 兔面包师 rabbit baker
  t.rectn(4, 0, 2, 5, "cream"); t.rectn(10, 0, 2, 5, "cream")      -- long ears
  t.rectn(5, 1, 1, 3, "pink"); t.rectn(10, 1, 1, 3, "pink")        -- inner ear
  t.rectn(3, 4, 10, 8, "cream"); t.rectn(3, 4, 10, 1, "white")
  t.pn(7, 9, "pink_d")                                             -- bunny nose
  t.rectn(4, 12, 8, 7, "pink")                                     -- dress
  t.rectn(4, 12, 8, 5, "white")                                    -- apron
  t.rectn(4, 12, 8, 1, "cream_d")
  t.pn(6, 14, "cream_d"); t.pn(9, 14, "cream_d")
  arms(t, "cream"); feet(t, "cream_d")
  expr(t, ex, 5, 7, 10, 7, 10)
end

local function dabao(t, ex) -- 熊邮差 bear postman
  t.discn(4, 3, 2, "brown"); t.discn(11, 3, 2, "brown")            -- round ears
  t.discn(4, 3, 1, "brown_d"); t.discn(11, 3, 1, "brown_d")
  t.rectn(2, 3, 12, 9, "brown"); t.rectn(2, 3, 12, 1, "brown_l")   -- big head
  t.rectn(6, 8, 4, 4, "cream"); t.pn(7, 8, "ink")
  t.rectn(3, 12, 10, 7, "brown")                                   -- big body
  t.pn(4, 12, "brown_d"); t.pn(5, 13, "brown_d"); t.pn(6, 14, "brown_d")
  t.pn(7, 15, "brown_d"); t.pn(8, 16, "brown_d")                   -- satchel strap
  t.rectn(9, 15, 4, 4, "yellow_d"); t.framen(9, 15, 4, 4, "brown_d"); t.rectn(9, 15, 4, 1, "yellow")
  t.rectn(1, 12, 2, 5, "brown"); t.rectn(13, 12, 2, 5, "brown")    -- arms (wider)
  feet(t, "brown_d")
  expr(t, ex, 5, 6, 10, 6, 10)
end

local function mimi(t, ex) -- 猫店主 cat shopkeeper
  t.rectn(3, 2, 2, 3, "honey"); t.rectn(11, 2, 2, 3, "honey")      -- pointy ears
  t.pn(3, 2, "honey_d"); t.pn(12, 2, "honey_d")
  t.pn(3, 3, "pink"); t.pn(12, 3, "pink")
  t.rectn(3, 4, 10, 8, "honey"); t.rectn(3, 4, 10, 1, "honey_l")
  t.pn(4, 4, "honey_d"); t.pn(7, 4, "honey_d"); t.pn(10, 4, "honey_d") -- stripes
  t.pn(7, 9, "pink_d")                                             -- nose
  t.rectn(4, 12, 8, 7, "cream")
  t.rectn(4, 12, 8, 4, "sky"); t.rectn(4, 12, 8, 1, "sky_d")       -- apron
  arms(t, "honey"); feet(t, "honey_d")
  t.pn(1, 8, "honey_d"); t.pn(14, 8, "honey_d")                    -- whiskers
  expr(t, ex, 5, 7, 10, 7, 10)
end

local function fuyisheng(t, ex) -- 鹿医生 deer doctor
  t.vln(4, 0, 3, "brown_d"); t.pn(3, 1, "brown_d"); t.pn(5, 1, "brown_d")   -- antlers
  t.vln(11, 0, 3, "brown_d"); t.pn(10, 1, "brown_d"); t.pn(12, 1, "brown_d")
  t.rectn(2, 4, 2, 3, "cream_d"); t.rectn(12, 4, 2, 3, "cream_d")  -- ears
  t.rectn(3, 3, 10, 9, "cream_d"); t.rectn(3, 3, 10, 1, "skin")
  t.rectn(6, 8, 4, 4, "cream"); t.pn(7, 8, "ink")                  -- muzzle
  t.rectn(3, 12, 10, 7, "white"); t.framen(3, 12, 10, 7, "w_lo")   -- white coat
  t.vln(8, 12, 7, "w_lo")
  t.rectn(5, 12, 6, 2, "skin")
  t.pn(11, 14, "red"); t.pn(11, 15, "red")                          -- red cross hint
  arms(t, "white"); feet(t, "brown_d")
  expr(t, ex, 5, 6, 10, 6, 10)
end

local function guiyeye(t, ex) -- 龟老者 turtle elder
  t.rectn(6, 4, 6, 5, "leaf_l"); t.rectn(6, 4, 6, 1, "cream")      -- head
  t.rectn(6, 8, 6, 2, "white")                                     -- beard
  t.discn(8, 14, 6, "leaf_d")                                      -- shell
  t.discn(8, 13, 5, "leaf")
  t.discn(6, 12, 2, "leaf_l")
  t.pn(8, 12, "leaf_dd"); t.pn(6, 14, "leaf_dd"); t.pn(10, 14, "leaf_dd"); t.pn(8, 16, "leaf_dd")
  t.rectn(4, 20, 3, 3, "leaf_d"); t.rectn(9, 20, 3, 3, "leaf_d")   -- feet
  t.vln(13, 12, 9, "brown_d"); t.pn(13, 11, "brown")               -- cane
  expr(t, ex, 7, 6, 10, 6, 8, "ink", "brown_d")
end

-- ---- build the 6 three-frame NPC sprites ----------------------------------
local npcs = {
  { "afu", afu }, { "yuanyuan", yuanyuan }, { "dabao", dabao },
  { "mimi", mimi }, { "fuyisheng", fuyisheng }, { "guiyeye", guiyeye },
}
for _, n in ipairs(npcs) do
  local spr, img = H.new(48, 24)
  for i, ex in ipairs({ "smile", "flat", "off" }) do
    n[2](H.at(img, (i - 1) * 16, 0), ex)
  end
  spr:saveAs(ROOT .. "public/assets/sprites/npc_" .. n[1] .. ".png")
  print("npc_" .. n[1] .. ".png done")
end

-- ---- twin birds (32x24, 2 frames = beak closed / open) ---------------------
local function bird(t, open)
  t.rectn(0, 18, 16, 2, "brown_d")                                 -- branch
  -- bird A (faces right)
  t.discn(4, 11, 4, "blue"); t.discn(4, 8, 3, "blue")
  t.discn(3, 10, 2, "blue_l")
  t.discn(5, 11, 2, "blue_d")                                      -- wing
  t.pn(1, 12, "blue_d"); t.pn(0, 13, "blue_d")                     -- tail
  t.pn(3, 7, "ink")                                                -- eye
  if open then t.pn(6, 8, "yellow"); t.pn(6, 9, "yellow_d") else t.pn(6, 8, "yellow") end
  t.vln(3, 15, 3, "honey_d"); t.vln(5, 15, 3, "honey_d")
  -- bird B (faces left), slightly lower
  t.discn(11, 13, 4, "blue"); t.discn(11, 10, 3, "blue")
  t.discn(12, 12, 2, "blue_l")
  t.discn(10, 13, 2, "blue_d")
  t.pn(14, 14, "blue_d"); t.pn(15, 15, "blue_d")
  t.pn(12, 9, "ink")
  if open then t.pn(9, 10, "yellow"); t.pn(9, 11, "yellow_d") else t.pn(9, 10, "yellow") end
  t.vln(10, 16, 2, "honey_d"); t.vln(12, 16, 2, "honey_d")
end
local bspr, bimg = H.new(32, 24)
bird(H.at(bimg, 0, 0), false)
bird(H.at(bimg, 16, 0), true)
bspr:saveAs(ROOT .. "public/assets/sprites/npc_bird.png")
print("npc_bird.png done")
