-- gen_tileset.lua: generate a 16x16 tileset sprite sheet for Honey Village.
-- Produces assets/tilesets/tileset.png : 8 cols x 8 rows = 64 tiles (128x128)
-- Run: aseprite -b --script tools/gen_tileset.lua

local TILE = 16
local COLS = 8
local ROWS = 8

local W = COLS*TILE
local H = ROWS*TILE

app.command.NewFile{ width=W, height=H, colorMode=ColorMode.RGB }
local spr = app.activeSprite
local img = app.activeImage

local C = {
  transparent = app.pixelColor.rgba(0,0,0,0),
  grassL  = app.pixelColor.rgba(126,200,80,255),
  grassD  = app.pixelColor.rgba(96,168,56,255),
  grassS  = app.pixelColor.rgba(150,214,96,255),
  pathL   = app.pixelColor.rgba(214,190,150,255),
  pathD   = app.pixelColor.rgba(180,156,120,255),
  waterL  = app.pixelColor.rgba(108,180,226,255),
  waterD  = app.pixelColor.rgba(74,140,198,255),
  waterF  = app.pixelColor.rgba(170,214,246,255),
  flowerY = app.pixelColor.rgba(255,214,80,255),
  flowerP = app.pixelColor.rgba(255,150,190,255),
  flowerG = app.pixelColor.rgba(120,200,120,255),
  stem    = app.pixelColor.rgba(70,130,50,255),
  berryR  = app.pixelColor.rgba(214,60,80,255),
  berryD  = app.pixelColor.rgba(160,36,56,255),
  leaf    = app.pixelColor.rgba(80,160,60,255),
  trunk   = app.pixelColor.rgba(120,80,40,255),
  leafD   = app.pixelColor.rgba(60,140,50,255),
  leafL   = app.pixelColor.rgba(110,190,70,255),
  wall    = app.pixelColor.rgba(236,216,184,255),
  wallD   = app.pixelColor.rgba(200,176,140,255),
  roof    = app.pixelColor.rgba(240,120,70,255),
  roofD   = app.pixelColor.rgba(200,84,48,255),
  door    = app.pixelColor.rgba(150,96,56,255),
  doorD   = app.pixelColor.rgba(110,70,40,255),
  floor   = app.pixelColor.rgba(230,210,180,255),
  floorD  = app.pixelColor.rgba(204,182,150,255),
  bedF    = app.pixelColor.rgba(120,170,230,255),
  bedD    = app.pixelColor.rgba(86,130,190,255),
  pillow  = app.pixelColor.rgba(240,230,210,255),
  counter = app.pixelColor.rgba(170,120,70,255),
  counterD= app.pixelColor.rgba(130,86,48,255),
  oven    = app.pixelColor.rgba(90,90,100,255),
  ovenD   = app.pixelColor.rgba(60,60,70,255),
  fire    = app.pixelColor.rgba(255,150,60,255),
  shelf   = app.pixelColor.rgba(150,100,60,255),
  shelfD  = app.pixelColor.rgba(110,72,40,255),
  item    = app.pixelColor.rgba(255,210,90,255),
  table   = app.pixelColor.rgba(160,110,64,255),
  chair   = app.pixelColor.rgba(120,84,48,255),
  well    = app.pixelColor.rgba(120,110,110,255),
  wellD   = app.pixelColor.rgba(84,78,78,255),
  wellR   = app.pixelColor.rgba(150,100,60,255),
  wellW   = app.pixelColor.rgba(60,130,180,255),
  fog     = app.pixelColor.rgba(220,226,236,255),
  fogD    = app.pixelColor.rgba(180,190,206,255),
  white   = app.pixelColor.rgba(236,236,236,255),
  grayL   = app.pixelColor.rgba(214,214,214,255),
  grayM   = app.pixelColor.rgba(170,170,170,255),
  grayD   = app.pixelColor.rgba(120,120,120,255),
  black   = app.pixelColor.rgba(40,40,40,255),
  ribbon  = app.pixelColor.rgba(255,100,140,255),
  ribbonD = app.pixelColor.rgba(200,70,110,255),
  picB    = app.pixelColor.rgba(240,200,140,255),
  picR    = app.pixelColor.rgba(200,120,80,255),
  bench   = app.pixelColor.rgba(140,96,56,255),
  sign    = app.pixelColor.rgba(200,170,110,255),
  signD   = app.pixelColor.rgba(150,120,70,255),
  fence   = app.pixelColor.rgba(160,120,70,255),
  fenceD  = app.pixelColor.rgba(120,86,48,255),
  window  = app.pixelColor.rgba(150,200,230,255),
  lamp    = app.pixelColor.rgba(255,230,130,255),
  lampD   = app.pixelColor.rgba(180,150,70,255),
  pot     = app.pixelColor.rgba(180,90,70,255),
  potP    = app.pixelColor.rgba(120,200,120,255),
  barrel  = app.pixelColor.rgba(140,90,50,255),
  crate   = app.pixelColor.rgba(170,120,70,255),
  ink     = app.pixelColor.rgba(60,50,50,255),
  paper   = app.pixelColor.rgba(245,240,225,255),
}

for y=0,H-1 do for x=0,W-1 do img:drawPixel(x,y,C.transparent) end end

local function cellOrigin(idx)
  return (idx % COLS) * TILE, math.floor(idx / COLS) * TILE
end
local function rect(ox,oy,w,h,col) for y=oy,oy+h-1 do for x=ox,ox+w-1 do img:drawPixel(x,y,col) end end end
local function px(x,y,col) img:drawPixel(x,y,col) end

-- Tile drawing functions take ox,oy origin
local function grass(ox,oy)
  rect(ox,oy,16,16,C.grassL)
  for _,d in ipairs({{2,3},{5,2},{9,4},{12,6},{3,9},{7,11},{11,9},{14,12},{6,13},{1,7},{13,2},{4,14}}) do px(ox+d[1],oy+d[2],C.grassD) end
  for _,d in ipairs({{6,5},{10,8},{3,12},{12,3},{8,13}}) do px(ox+d[1],oy+d[2],C.grassS) end
end
local function pathPlain(ox,oy)
  rect(ox,oy,16,16,C.pathL)
  for _,d in ipairs({{2,4},{7,3},{11,6},{4,9},{9,11},{13,8},{6,13},{1,11}}) do px(ox+d[1],oy+d[2],C.pathD) end
end
local function water(ox,oy)
  rect(ox,oy,16,16,C.waterL)
  for x=0,15 do if (x%4)<2 then px(ox+x,oy+4,C.waterD) end if (x%4)>=2 then px(ox+x,oy+10,C.waterD) end end
  px(ox+3,oy+7,C.waterF); px(ox+10,oy+7,C.waterF)
end
local function flowers(ox,oy,accent)
  grass(ox,oy)
  for _,s in ipairs({{4,6},{11,9}}) do px(ox+s[1],oy+s[2]+2,C.stem); px(ox+s[1],oy+s[2]+3,C.stem) end
  for _,b in ipairs({{4,6},{11,9}}) do
    px(ox+b[1],oy+b[2],accent); px(ox+b[1]-1,oy+b[2],accent); px(ox+b[1]+1,oy+b[2],accent)
    px(ox+b[1],oy+b[2]-1,accent); px(ox+b[1],oy+b[2]+1,accent)
  end
end
local function berry(ox,oy)
  grass(ox,oy)
  rect(ox+3,oy+5,10,8,C.leaf)
  rect(ox+4,oy+4,8,1,C.leafL)
  rect(ox+3,oy+5,10,1,C.leafD)
  for _,b in ipairs({{5,8},{8,7},{10,9},{6,11},{9,11}}) do
    px(ox+b[1],oy+b[2],C.berryR); px(ox+b[1]+1,oy+b[2],C.berryR); px(ox+b[1],oy+b[2]+1,C.berryD)
  end
end
local function tree(ox,oy)
  grass(ox,oy)
  rect(ox+7,oy+10,2,5,C.trunk)
  rect(ox+4,oy+3,8,8,C.leafD)
  rect(ox+5,oy+2,6,1,C.leafL)
  rect(ox+3,oy+5,1,4,C.leaf); rect(ox+12,oy+5,1,4,C.leaf)
  rect(ox+6,oy+6,4,3,C.leafL)
end
local function birdTree(ox,oy)
  tree(ox,oy)
  px(ox+6,oy+5,C.flowerY); px(ox+9,oy+6,C.flowerY)
end
local function bush(ox,oy)
  grass(ox,oy)
  rect(ox+3,oy+6,10,6,C.leaf); rect(ox+4,oy+5,8,1,C.leafL)
end
local function wall(ox,oy)
  rect(ox,oy,16,16,C.wall)
  for _,d in ipairs({{1,1},{5,1},{9,1},{13,1},{3,5},{7,5},{11,5},{1,9},{5,9},{9,9},{13,9},{3,13},{7,13},{11,13}}) do px(ox+d[1],oy+d[2],C.wallD) end
end
local function wallTop(ox,oy)
  rect(ox,oy,16,16,C.wall); rect(ox,oy,16,2,C.wallD)
  for x=0,15,4 do px(ox+x,oy+4,C.wallD) end
end
local function roof(ox,oy)
  rect(ox,oy,16,16,C.roof)
  for y=0,15,2 do rect(ox,oy+y,16,1,C.roofD) end
end
local function roofEdge(ox,oy)
  rect(ox,oy,16,16,C.roof); rect(ox,oy+14,16,2,C.roofD)
  for y=0,12,2 do rect(ox,oy+y,16,1,C.roofD) end
end
local function door(ox,oy)
  wall(ox,oy)
  rect(ox+3,oy+2,10,14,C.door)
  rect(ox+3,oy+2,10,1,C.doorD); rect(ox+3,oy+2,1,14,C.doorD)
  px(ox+11,oy+9,C.signD)
end
local function window(ox,oy)
  wall(ox,oy)
  rect(ox+3,oy+3,10,8,C.window)
  rect(ox+3,oy+3,10,1,C.wallD); rect(ox+3,oy+10,10,1,C.wallD)
  rect(ox+3,oy+3,1,8,C.wallD); rect(ox+12,oy+3,1,8,C.wallD)
  px(ox+7,oy+3,C.wallD); px(ox+7,oy+11,C.wallD)
end
local function floor(ox,oy)
  rect(ox,oy,16,16,C.floor)
  for _,d in ipairs({{2,3},{9,5},{5,11},{12,12}}) do px(ox+d[1],oy+d[2],C.floorD) end
  rect(ox,oy,16,1,C.floorD); rect(ox,oy+8,16,1,C.floorD)
end
local function floorRug(ox,oy)
  floor(ox,oy)
  rect(ox+3,oy+4,10,8,C.flowerP); rect(ox+3,oy+4,10,1,C.ribbonD); rect(ox+3,oy+11,10,1,C.ribbonD)
end
local function bed(ox,oy)
  rect(ox+1,oy+3,14,11,C.bedD); rect(ox+2,oy+4,12,9,C.bedF); rect(ox+3,oy+5,4,3,C.pillow)
end
local function counter(ox,oy)
  rect(ox,oy+5,16,7,C.counter); rect(ox,oy+5,16,1,C.counterD); rect(ox,oy+11,16,1,C.counterD)
end
local function oven(ox,oy)
  rect(ox+2,oy+2,12,13,C.oven); rect(ox+2,oy+2,12,1,C.ovenD)
  rect(ox+4,oy+5,8,6,C.ovenD); rect(ox+5,oy+6,6,4,C.fire)
end
local function shelf(ox,oy)
  rect(ox+1,oy+4,14,1,C.shelf); rect(ox+1,oy+9,14,1,C.shelf)
  rect(ox+1,oy+4,1,10,C.shelf); rect(ox+14,oy+4,1,10,C.shelf)
  rect(ox+1,oy+13,14,1,C.shelfD)
end
local function shelfFull(ox,oy)
  shelf(ox,oy)
  for i=0,4 do rect(ox+2+i*3,oy+5,2,3,C.item) end
  for i=0,4 do rect(ox+2+i*3,oy+10,2,3,C.item) end
end
local function table(ox,oy)
  rect(ox+1,oy+5,14,4,C.table)
  px(ox+2,oy+9,C.table); px(ox+13,oy+9,C.table); px(ox+2,oy+12,C.table); px(ox+13,oy+12,C.table)
end
local function chair(ox,oy)
  rect(ox+4,oy+6,8,1,C.chair); rect(ox+4,oy+6,1,6,C.chair); rect(ox+4,oy+11,9,1,C.chair)
  px(ox+11,oy+11,C.chair); px(ox+11,oy+13,C.chair)
end
local function stool(ox,oy)
  rect(ox+5,oy+7,6,2,C.table); px(ox+5,oy+9,C.table); px(ox+10,oy+9,C.table); px(ox+5,oy+12,C.table); px(ox+10,oy+12,C.table)
end
local function well(ox,oy)
  rect(ox,oy+6,16,7,C.well); rect(ox,oy+6,16,1,C.wellD)
  rect(ox+5,oy+9,6,4,C.wellW)
  px(ox+2,oy+1,C.wellR); px(ox+13,oy+1,C.wellR); rect(ox+2,oy+1,12,1,C.wellR); rect(ox+5,oy+0,6,2,C.wellR)
end
local function fog(ox,oy)
  rect(ox,oy,16,16,C.fog)
  for _,d in ipairs({{2,3},{8,5},{12,9},{4,11},{10,12},{6,7}}) do px(ox+d[1],oy+d[2],C.fogD) end
end
local function fogThick(ox,oy)
  rect(ox,oy,16,16,C.fog)
  for y=0,15 do for x=0,15 do if (x+y)%2==0 then px(ox+x,oy+y,C.fogD) end end end
  rect(ox,oy,16,16,C.fog)
end
local function whiteWall(ox,oy)
  rect(ox,oy,16,16,C.white); rect(ox,oy+15,16,1,C.grayM); px(ox,oy,C.grayL); px(ox+15,oy,C.grayL)
end
local function whiteFloor(ox,oy)
  rect(ox,oy,16,16,C.grayL); rect(ox,oy+8,16,1,C.grayM); px(ox,oy,C.grayM)
end
local function whiteDoor(ox,oy)
  rect(ox,oy,16,16,C.white); rect(ox+3,oy+1,10,14,C.grayM); rect(ox+3,oy+1,10,1,C.grayD); rect(ox+3,oy+1,1,14,C.grayD)
  px(ox+11,oy+9,C.grayD)
end
local function whiteBed(ox,oy)
  rect(ox+1,oy+3,14,11,C.grayM); rect(ox+2,oy+4,12,9,C.grayL); rect(ox+3,oy+5,4,3,C.white)
end
local function whiteMonitor(ox,oy)
  rect(ox+1,oy+2,14,1,C.grayD); rect(ox+3,oy+1,10,3,C.grayM); px(ox+7,oy+4,C.grayD); px(ox+8,oy+4,C.grayD)
  rect(ox+4,oy+4,8,3,C.wellW)
end
local function whiteTable(ox,oy)
  rect(ox+1,oy+6,14,2,C.grayM); px(ox+2,oy+8,C.grayM); px(ox+13,oy+8,C.grayM)
end
local function ribbon(ox,oy)
  rect(ox+1,oy+6,14,3,C.ribbon); rect(ox+1,oy+6,14,1,C.ribbonD)
  rect(ox+7,oy+3,2,10,C.ribbonD)
end
local function ribbon2(ox,oy)
  rect(ox+1,oy+5,14,4,C.ribbon); rect(ox+1,oy+8,14,1,C.ribbonD)
  rect(ox+4,oy+2,2,12,C.flowerP); rect(ox+10,oy+2,2,12,C.flowerY)
end
local function picnic(ox,oy)
  rect(ox,oy+4,16,9,C.picB)
  for i=0,7 do rect(ox+i*2,oy+4,1,9,C.picR) end
end
local function bench(ox,oy)
  rect(ox+1,oy+5,14,3,C.bench); px(ox+2,oy+8,C.bench); px(ox+13,oy+8,C.bench); px(ox+2,oy+12,C.bench); px(ox+13,oy+12,C.bench)
end
local function sign(ox,oy)
  rect(ox+1,oy+6,14,6,C.sign); rect(ox+1,oy+6,14,1,C.signD); rect(ox+1,oy+11,14,1,C.signD)
  rect(ox+1,oy+6,1,6,C.signD); rect(ox+14,oy+6,1,6,C.signD)
  px(ox+6,oy+12,C.signD); px(ox+9,oy+12,C.signD); px(ox+6,oy+15,C.signD); px(ox+9,oy+15,C.signD)
end
local function calendar(ox,oy)
  rect(ox+2,oy+2,12,12,C.paper); rect(ox+2,oy+2,12,1,C.signD); rect(ox+2,oy+2,1,12,C.signD); rect(ox+13,oy+2,1,12,C.signD)
  rect(ox+2,oy+5,12,1,C.signD)
  -- date digits "7/14" stylized
  rect(ox+4,oy+7,1,4,C.ink); rect(ox+7,oy+7,2,1,C.ink); rect(ox+9,oy+8,1,2,C.ink); rect(ox+7,oy+9,2,1,C.ink)
  rect(ox+11,oy+7,1,4,C.ink); px(ox+12,oy+8,C.ink); px(ox+11,oy+9,C.ink); px(ox+12,oy+10,C.ink)
  px(ox+3,oy+3,C.ink); px(ox+3,oy+4,C.ink)
end
local function paperSheet(ox,oy)
  rect(ox+2,oy+3,12,11,C.paper); rect(ox+2,oy+3,12,1,C.signD)
  for y=6,12,2 do rect(ox+3,oy+y,8,1,C.ink) end
end
local function chart(ox,oy)
  rect(ox+1,oy+2,14,12,C.paper); rect(ox+1,oy+2,14,1,C.signD); rect(ox+1,oy+2,1,12,C.signD); rect(ox+14,oy+2,1,12,C.signD)
  for y=5,12,2 do rect(ox+2,oy+y,12,1,C.ink) end
  -- redacted bars
  rect(ox+2,oy+5,5,1,C.black); rect(ox+8,oy+7,6,1,C.black)
end
local function fenceH(ox,oy)
  rect(ox,oy+6,16,1,C.fenceD)
  for x=0,15,4 do rect(ox+x,oy+5,1,5,C.fence) end
  rect(ox,oy+9,16,1,C.fence)
end
local function fenceV(ox,oy)
  rect(ox+6,oy,4,16,C.fence)
  rect(ox+6,oy+5,4,1,C.fenceD); rect(ox+6,oy+10,4,1,C.fenceD)
end
local function lamp(ox,oy)
  rect(ox+7,oy+4,2,12,C.lampD)
  rect(ox+5,oy+2,6,3,C.lamp); rect(ox+5,oy+2,6,1,C.lampD)
  px(ox+8,oy+5,C.lamp)
end
local function potPlant(ox,oy)
  rect(ox+4,oy+8,8,6,C.pot); rect(ox+4,oy+8,8,1,C.signD)
  rect(ox+5,oy+5,6,3,C.potP); px(ox+7,oy+3,C.potP); px(ox+9,oy+4,C.potP)
end
local function barrel(ox,oy)
  rect(ox+3,oy+2,10,13,C.barrel); rect(ox+3,oy+2,10,1,C.fenceD); rect(ox+3,oy+7,10,1,C.fenceD); rect(ox+3,oy+12,10,1,C.fenceD)
  px(ox+3,oy+2,C.fenceD); px(ox+12,oy+2,C.fenceD)
end
local function crate(ox,oy)
  rect(ox+2,oy+3,12,12,C.crate); rect(ox+2,oy+3,12,1,C.signD); rect(ox+2,oy+14,12,1,C.signD)
  rect(ox+2,oy+3,1,12,C.signD); rect(ox+13,oy+3,1,12,C.signD)
  -- X
  for i=0,10 do px(ox+3+i,oy+4+i,C.signD) end
  for i=0,10 do px(ox+3+i,oy+14-i,C.signD) end
end

-- Tile index assignment (must stay stable; maps reference these):
-- 0 grass, 1 path, 2 water, 3 flowersY, 4 flowersP, 5 flowersG, 6 berry, 7 tree
-- 8 birdTree, 9 bush, 10 wall, 11 wallTop, 12 roof, 13 roofEdge, 14 door, 15 window
-- 16 floor, 17 floorRug, 18 bed, 19 counter, 20 oven, 21 shelf, 22 shelfFull, 23 table
-- 24 chair, 25 stool, 26 well, 27 fog, 28 fogThick, 29 whiteWall, 30 whiteFloor, 31 whiteDoor
-- 32 whiteBed, 33 whiteMonitor, 34 whiteTable, 35 ribbon, 36 ribbon2, 37 picnic, 38 bench, 39 sign
-- 40 calendar, 41 paper, 42 chart, 43 fenceH, 44 fenceV, 45 lamp, 46 potPlant, 47 barrel
-- 48 crate, 49 grassAlt, 50 pathH, 51 pathV, 52 pathCross, 53 waterEdge, 54 grassDark, 55 pathCorner
-- 56 flowerMix, 57 berryEmpty, 58 fogBand, 59 whitePillar, 60 floorEdge, 61 wallTrim, 62 grassPath, 63 transparent

local tiles = {
  [0]=grass, grass, pathPlain, water, function(o,s) flowers(o,s,C.flowerY) end,
  function(o,s) flowers(o,s,C.flowerP) end, function(o,s) flowers(o,s,C.flowerG) end, berry,
  tree, birdTree, bush, wall, wallTop, roof, roofEdge, door,
  window, floor, floorRug, bed, counter, oven, shelf, shelfFull,
  table, chair, stool, well, fog, fogThick, whiteWall, whiteFloor,
  whiteDoor, whiteBed, whiteMonitor, whiteTable, ribbon, ribbon2, picnic, bench,
  sign, calendar, paperSheet, chart, fenceH, fenceV, lamp, potPlant,
  barrel, crate, grass, pathPlain, pathPlain, pathPlain, water, grass,
  pathPlain, flowers, berry, fog, whiteWall, floor, wall, pathPlain,
}
-- fill remaining with grass/transparent
for i=0,63 do
  local ox,oy = cellOrigin(i)
  if tiles[i] then
    tiles[i](ox,oy)
  end
end

local out = "assets/tilesets/tileset.png"
spr:saveCopyAs(out)
print("Saved " .. out .. " (64 tiles, 128x128)")
app.exit()
